]> git.immae.eu Git - perso/Immae/Projets/Python/MusicSampler.git/blob - helpers/key.py
Fix channels and description with blank lines
[perso/Immae/Projets/Python/MusicSampler.git] / helpers / key.py
1 from .rounded_rect import *
2 from .action import *
3 import time
4 import sys
5 import pygame
6
7 class Key:
8 row_positions = {
9 'first': 0,
10 'second': 50,
11 'third': 100,
12 'fourth': 150,
13 'fifth': 200,
14 'sixth': 250,
15 }
16
17 default_outer_color = (120, 120, 120)
18 lighter_outer_color = (200, 200, 200)
19 default_inner_color = (255, 255, 255)
20 mapped_inner_color = ( 0, 255, 0)
21 mapped_unready_inner_color = ( 0, 255, 0, 100)
22 #mapped_unready_inner_color = (255, 165, 0)
23
24 def __init__(self, mapping, draw_lock, key_name, key_sym, top, left, width = 48, height = 48, disabled = False):
25 self.draw_lock = draw_lock
26 self.mapping = mapping
27 self.key_name = key_name
28 self.key_sym = key_sym
29
30 if isinstance(top, str):
31 self.top = self.row_positions[top]
32 else:
33 self.top = top
34
35 self.left = left
36 self.width = width
37 self.height = height
38
39 self.bottom = self.top + self.height
40 self.right = self.left + self.width
41
42 self.rect = (self.left, self.top, self.right, self.bottom)
43 self.position = (self.left, self.top)
44
45 if disabled:
46 self.outer_color = self.lighter_outer_color
47 self.linewidth = 1
48 else:
49 self.outer_color = self.default_outer_color
50 self.linewidth = 3
51
52 self.inner_color = self.default_inner_color
53 self.actions = []
54 self.description = []
55 self.custom_color = None
56 self.custom_unready_color = None
57
58 def square(self, all_actions_ready):
59 if self.has_actions():
60 if all_actions_ready:
61 self.inner_color = self.custom_color or self.mapped_inner_color
62 else:
63 self.inner_color = self.custom_unready_color or self.mapped_unready_inner_color
64
65 return RoundedRect((0, 0, self.width, self.height),
66 self.outer_color, self.inner_color, self.linewidth)
67
68 def collidepoint(self, position):
69 return self.surface.get_rect().collidepoint(
70 position[0] - self.position[0],
71 position[1] - self.position[1]
72 )
73
74 def set_description(self, description):
75 for desc in description:
76 if desc is None:
77 self.description.append("")
78 else:
79 self.description.append(str(desc))
80
81 def set_color(self, color):
82 self.custom_color = tuple(color)
83 color.append(100)
84 self.custom_unready_color = tuple(color)
85
86 def draw(self, background_surface):
87 self.draw_lock.acquire()
88 all_actions_ready = self.all_actions_ready()
89
90 self.surface = self.square(all_actions_ready).surface()
91
92 if getattr(sys, 'frozen', False):
93 police = pygame.font.Font(sys._MEIPASS + "/Ubuntu-Regular.ttf", 14)
94 text_police = pygame.font.Font(sys._MEIPASS + "/Ubuntu-Regular.ttf", 10)
95 else:
96 police = pygame.font.Font("Ubuntu-Regular.ttf", 14)
97 text_police = pygame.font.Font("Ubuntu-Regular.ttf", 10)
98
99 police.set_bold(True)
100 text = police.render(self.key_sym, True, (0,0,0))
101 self.surface.blit(text, (5,5))
102
103 is_first_line = True
104 offset = 11 + text_police.get_linesize() - 4
105 first_line_offset = 18
106 for description in self.description:
107 text = text_police.render(description, True, (0,0,0))
108 if is_first_line:
109 self.surface.blit(text, (first_line_offset, 9))
110 is_first_line = False
111 else:
112 self.surface.blit(text, (3, offset))
113 offset += text_police.get_linesize() - 4
114
115 background_surface.blit(self.surface, self.position)
116 self.draw_lock.release()
117
118 return not all_actions_ready
119
120 def poll_redraw(self, background):
121 while True:
122 time.sleep(1)
123 if self.all_actions_ready():
124 self.draw(background)
125 self.mapping.blit()
126 break
127
128 def has_actions(self):
129 return len(self.actions) > 0
130
131 def all_actions_ready(self):
132 return all(action.ready() for action in self.actions)
133
134 def add_action(self, action_name, **arguments):
135 self.actions.append(Action(action_name, self, **arguments))
136
137 def do_actions(self):
138 print("running actions for {}".format(self.key_sym))
139 start_time = time.time()
140 self.mapping.start_running(self, start_time)
141 for action in self.actions:
142 if self.mapping.keep_running(self, start_time):
143 action.run()
144
145 self.mapping.finished_running(self, start_time)
146
147 def list_actions(self, screen):
148 action_descriptions = [action.description() for action in self.actions]
149 #print("actions linked to key {}:".format(self.key_sym))
150 #print("\t" + "\n\t".join(action_descriptions))
151 self.draw_lock.acquire()
152 surface = pygame.Surface((800, 250)).convert()
153 surface.fill((250, 250, 250))
154 if getattr(sys, 'frozen', False):
155 police = pygame.font.Font(sys._MEIPASS + "/Ubuntu-Regular.ttf", 14)
156 else:
157 police = pygame.font.Font("Ubuntu-Regular.ttf", 14)
158
159 offset = 0
160 police.set_bold(True)
161 text = police.render("actions linked to key {}:".format(self.key_sym), True, (0,0,0))
162 surface.blit(text, (0, offset))
163 offset += police.get_linesize()
164
165 police.set_bold(False)
166 for description in action_descriptions:
167 text = police.render(description, True, (0,0,0))
168 surface.blit(text, (0, offset))
169 offset += police.get_linesize()
170
171 screen.blit(surface, (10, 330))
172 pygame.display.flip()
173 self.draw_lock.release()
174
175