Passed
Pull Request — master (#21)
by Matt
03:47 queued 01:54
created

Fixture.__init__()   A

Complexity

Conditions 2

Size

Total Lines 15
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 15
nop 11
dl 0
loc 15
rs 9.65
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
"""
2
 *  PyDMXControl: A Python 3 module to control DMX using uDMX.
3
 *                Featuring fixture profiles, built-in effects and a web control panel.
4
 *  <https://github.com/MattIPv4/PyDMXControl/>
5
 *  Copyright (C) 2018 Matt Cowley (MattIPv4) ([email protected])
6
"""
7
8
from math import floor
9
from typing import Union, List, Tuple
10
11
import pygame
12
13
from ._Part import Part
14
from ._Text import Text
15
from .data import load
16
from .._screen import Screen
17
18
19
class Fixture(Part):
20
21
    def __init__(self, x: Union[int, float], y: Union[int, float], name: str = "", rotation: Union[int, float] = 0, *,
22
                 outline_color: Union[List[int], Tuple[int, int, int]] = (0, 0, 0),
23
                 fill_color: Union[List[int], Tuple[int, int, int]] = (255, 255, 255),
24
                 label: str = "", scale: float = 1, align_left: bool = False):
25
        super().__init__()
26
        self.__rotation = rotation
27
        self.__name = name
28
        self.__data = load(name)
29
        self.__outline = outline_color
30
        self.__fill = fill_color
31
        self.__label = Text(0, 0, label, scale=scale) if label else None
32
        self.__scale = scale
33
        self.__size = 0.06 * self.__scale
34
        self.__left = align_left
35
        self.set_pos(x, y)
36
37
    def design_render(self, screen: Screen) -> Tuple[int, int, pygame.Surface]:
38
        # Get points from fixture else rectangle
39
        raw_points = self.__data[2] if self.__data else [[0, 0, 0], [30, 0, 1], [30, 10, 1], [0, 10, 1]]
40
41
        # Get largest x/y
42
        maxx = max([f[0] for f in raw_points])
43
        maxy = max([f[1] for f in raw_points])
44
45
        # Split the points up into their line groups
46
        pen = 6
47
        points = []
48
        for point in raw_points:
49
            if point[2] == 0:
50
                points.append([])
51
            points[-1].append([point[0] + pen, point[1] + pen])
52
53
        # Generate the surface
54
        surface = pygame.Surface((maxx + (pen * 2), maxy + (pen * 2)), pygame.SRCALPHA, 32)
55
        surface = surface.convert_alpha()
56
57
        # Draw each line group filled
58
        for point_set in points:
59
            if len(point_set) > 2:
60
                pygame.draw.polygon(surface, self.__fill, point_set)
61
62
        # Draw each line group outline
63
        for point_set in points:
64
            if len(point_set) > 1:
65
                pygame.draw.lines(surface, self.__outline, True, point_set, pen)
66
67
        # Resize
68
        """max_size = self.__size
69
        x, y = surface.get_size()
70
        if x > y:
71
            y = y * (max_size / x)
72
            x = max_size
73
        else:
74
            x = x * (max_size / y)
75
            y = max_size
76
        x, y = int(x), int(y)
77
        surface = pygame.transform.scale(surface, (x * screen.block_size, y * screen.block_size))"""
78
        x, y = surface.get_size()
79
        surface = pygame.transform.scale(surface, (
80
            int(x * self.__size * screen.block_size), int(y * self.__size * screen.block_size)))
81
82
        # Rotate
83
        surface = pygame.transform.rotate(surface, int(self.__rotation))
84
85
        # Calc pos
86
        x, y = surface.get_size()
87
        x = int((self._x * screen.block_size) - floor(x / 2))
88
        y = int((self._y * screen.block_size) - floor(y / 2))
89
        if self.__left:
90
            x = int(self._x * screen.block_size)
91
92
        # Text label
93
        if self.__label is not None:
94
            # Generate text
95
            text = self.__label.design_render(screen)[2]
96
97
            # Add to full
98
            tx, ty = text.get_size()
99
            fx, fy = surface.get_size()
100
            new_surface = pygame.Surface((max(fx, tx + fx * (3 / 4)), max(ty, fy + ty)), pygame.SRCALPHA, 32)
101
            new_surface = new_surface.convert_alpha()
102
            new_surface.blit(surface, (0, new_surface.get_height() - fy))
103
            new_surface.blit(text, (fx * (3 / 4), 0))
104
105
            # Update pos
106
            y -= (new_surface.get_height() - fy)
107
        else:
108
            new_surface = surface
109
110
        # Render
111
        return x, y, new_surface
112