Passed
Push — design ( 238665...79d5ba )
by Matt
03:11 queued 01:36
created

Fixture.design_render()   C

Complexity

Conditions 9

Size

Total Lines 73
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 36
nop 2
dl 0
loc 73
rs 6.6666
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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: int, y: int, name: str = "", rotation: int = 0, *,
22
                 outline_color: Union[List[int], Tuple[int]] = (0, 0, 0),
23
                 fill_color: Union[List[int], Tuple[int]] = (255, 255, 255),
24
                 label: str = "", scale: float = 1):
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.08 * self.__scale
34
        self.set_pos(x, y)
35
36
    def design_render(self, screen: Screen) -> Tuple[int, int, pygame.Surface]:
37
        # Get points from fixture else rectangle
38
        raw_points = self.__data[2] if self.__data else [[0, 0, 0], [30, 0, 1], [30, 10, 1], [0, 10, 1]]
39
40
        # Get largest x/y
41
        maxx = max([f[0] for f in raw_points])
42
        maxy = max([f[1] for f in raw_points])
43
44
        # Split the points up into their line groups
45
        pen = 6
46
        points = []
47
        for point in raw_points:
48
            if point[2] == 0:
49
                points.append([])
50
            points[-1].append([point[0] + pen, point[1] + pen])
51
52
        # Generate the surface
53
        surface = pygame.Surface((maxx + (pen * 2), maxy + (pen * 2)), pygame.SRCALPHA, 32)
54
        surface = surface.convert_alpha()
55
56
        # Draw each line group filled
57
        for point_set in points:
58
            if len(point_set) > 2:
59
                pygame.draw.polygon(surface, self.__fill, point_set)
60
61
        # Draw each line group outline
62
        for point_set in points:
63
            if len(point_set) > 1:
64
                pygame.draw.lines(surface, self.__outline, True, point_set, pen)
65
66
        # Resize
67
        """max_size = self.__size
68
        x, y = surface.get_size()
69
        if x > y:
70
            y = y * (max_size / x)
71
            x = max_size
72
        else:
73
            x = x * (max_size / y)
74
            y = max_size
75
        x, y = int(x), int(y)
76
        surface = pygame.transform.scale(surface, (x * screen.block_size, y * screen.block_size))"""
77
        x, y = surface.get_size()
78
        surface = pygame.transform.scale(surface, (
79
        int(x * self.__size * screen.block_size), int(y * self.__size * screen.block_size)))
80
81
        # Rotate
82
        surface = pygame.transform.rotate(surface, self.__rotation)
83
84
        # Calc pos
85
        x, y = surface.get_size()
86
        x = int((self._x * screen.block_size) - floor(x / 2))
87
        y = int((self._y * screen.block_size) - floor(y / 2))
88
89
        # Text label
90
        if self.__label is not None:
91
            # Generate text
92
            text = self.__label.design_render(screen)[2]
93
94
            # Add to full
95
            tx, ty = text.get_size()
96
            fx, fy = surface.get_size()
97
            new_surface = pygame.Surface((tx + fx + 3, max(ty, fy + ty / 2)), pygame.SRCALPHA, 32)
98
            new_surface = new_surface.convert_alpha()
99
            new_surface.blit(surface, (0, new_surface.get_height() - fy))
100
            new_surface.blit(text, (fx + 3, 0))
101
102
            # Update pos
103
            y -= (new_surface.get_height() - fy)
104
        else:
105
            new_surface = surface
106
107
        # Render
108
        return x, y, new_surface
109