Passed
Push — design ( fcd95c...f28e51 )
by Matt
01:17
created

PyDMXControl.design._screen   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 174
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 107
dl 0
loc 174
rs 10
c 0
b 0
f 0
wmc 23

9 Methods

Rating   Name   Duplication   Size   Complexity  
A Screen.__draw_bg() 0 24 5
A Screen.add_part() 0 2 1
A Screen.__events() 0 5 4
A Screen.__start() 0 22 3
A Screen.__draw_mouse() 0 27 1
A Screen.__draw_parts() 0 21 4
A Screen.__draw() 0 24 3
A Screen.render() 0 4 1
A Screen.__init__() 0 20 1
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
import os.path  # User files
9
from datetime import datetime  # Dates
10
from math import ceil, floor  # Rounding
11
12
import pygame  # PyGame
13
14
15
class Screen:
16
17
    def __init__(self):
18
        self.__thread = None
19
        self.__running = False
20
        self.__grid = False
21
        self.__parts = []
22
        self.__bg = (245, 245, 245)
23
        self.block_size = 19
24
25
        # Init pygame
26
        pygame.init()
27
28
        # Get font
29
        self.__font = pygame.font.SysFont("monospace", 15)
30
31
        # Create pygame screen
32
        display_info = pygame.display.Info()
33
        self.parts_render = None
34
        self.last_render = None
35
        self.screen = pygame.display.set_mode((display_info.current_w - 20, display_info.current_h - 70))
36
        pygame.display.set_caption("PyDMXControl Design")
37
38
    def add_part(self, part: 'Part'):
39
        self.__parts.append(part)
40
41
    def __events(self):
42
        for e in pygame.event.get():
43
            if e.type == pygame.KEYDOWN:
44
                if e.key == pygame.K_g:
45
                    self.__grid = not self.__grid
46
47
    def __draw_parts(self):
48
        # Get render of each
49
        parts = []
50
        for part in self.__parts:
51
            try:
52
                parts.append(part.design_render(self))
53
            except:
54
                pass
55
56
        # Generate size
57
        maxx = max([f[0] + f[2].get_width() for f in parts])
58
        maxy = max([f[1] + f[2].get_height() for f in parts])
59
        surface = pygame.Surface((maxx, maxy), pygame.SRCALPHA, 32)
60
        surface.convert_alpha()
61
62
        # Render
63
        for part in parts:
64
            surface.blit(part[2], (part[0], part[1]))
65
66
        # Save full res
67
        self.parts_render = surface
68
69
    def __draw_bg(self):
70
        # New surface
71
        sx, sy = self.parts_render.get_size()
72
        surface = pygame.Surface((sx, sy), pygame.SRCALPHA, 32)
73
        surface.convert_alpha()
74
        surface.fill(self.__bg)
75
76
        # Draw grid
77
        if self.__grid:
78
            w, h = pygame.display.get_surface().get_size()
79
            w = ceil(w / self.block_size)
80
            h = ceil(h / self.block_size)
81
            for y in range(h):
82
                for x in range(w):
83
                    invert = ((x + (y % 2)) % 2 == 0)
84
                    color = [200] * 3 if invert else [250] * 3
85
                    rect = pygame.Rect(x * self.block_size, y * self.block_size, self.block_size, self.block_size)
86
                    pygame.draw.rect(surface, color, rect)
87
88
        # Add parts
89
        surface.blit(self.parts_render, (0, 0))
90
91
        # Save full res
92
        self.last_render = surface
93
94
    def __draw_mouse(self):
95
        # Generate text
96
        mx, my = pygame.mouse.get_pos()
97
        text = self.__font.render("x: {:,} y: {:,}".format(
98
            floor(mx / self.block_size),
99
            floor(my / self.block_size),
100
        ), True, (0, 0, 0))
101
102
        # Generate background
103
        padding = 5
104
        x, y = text.get_size()
105
        surface = pygame.Surface((x + padding * 2, y + padding * 2), pygame.SRCALPHA, 32)
106
        surface = surface.convert_alpha()
107
        surface.fill((225, 225, 225, 128))
108
109
        # Add text
110
        surface.blit(text, (padding, padding))
111
112
        # Add border
113
        x, y = surface.get_size()
114
        rectv = pygame.Rect(0, y / 4 * 3, int(floor(padding / 2)), y / 4)
115
        pygame.draw.rect(surface, (0, 0, 0), rectv)
116
        recth = pygame.Rect(0, y - int(floor(padding / 2)), y / 4, int(floor(padding / 2)))
117
        pygame.draw.rect(surface, (0, 0, 0), recth)
118
119
        # Render
120
        self.screen.blit(surface, (mx, my - y))
121
122
    def __draw(self):
123
        # Draw parts
124
        self.__draw_parts()
125
126
        # Draw base
127
        self.__draw_bg()
128
129
        # Draw mouse
130
        # self.__draw_mouse()
131
132
        # Resize if bigger than screen
133
        mx, my = self.last_render.get_size()
134
        sx, sy = self.screen.get_size()
135
        if mx > sx:
136
            my = my * (sx / mx)
137
            mx = sx
138
        if my > sy:
139
            mx = mx * (sy / my)
140
            my = sy
141
        surface = pygame.transform.scale(self.last_render, (floor(mx), floor(my)))
142
143
        # Render
144
        self.screen.fill(self.__bg)
145
        self.screen.blit(surface, (0, 0))
146
147
    def __start(self):
148
        self.clock = pygame.time.Clock()
149
150
        # Draw to screen
151
        self.__draw()
152
        redraw = 0
153
154
        while self.__running:
155
            # Handle events
156
            self.__events()
157
158
            # Draw to screen (every 10 cycles)
159
            if redraw == 10:
160
                redraw = 0
161
                self.__draw()
162
            redraw += 1
163
164
            # Update display
165
            self.clock.tick(60)
166
            pygame.display.flip()
167
168
        pygame.quit()
169
170
    def render(self):
171
        self.__running = True
172
        self.__start()
173
        quit()
174