diff options
author | Ismaël Bouya <ismael.bouya@normalesup.org> | 2016-06-25 23:37:49 +0200 |
---|---|---|
committer | Ismaël Bouya <ismael.bouya@normalesup.org> | 2016-06-25 23:40:51 +0200 |
commit | 4b2d79ca27dcbb85465829595ad81cec5fc63983 (patch) | |
tree | 683b3a9b19aa01de53b0dccc3ac143d876dcf088 /helpers/key.py | |
parent | 8612c5f8bb0fc9529bc489a6719654d4474db6d5 (diff) | |
download | MusicSampler-4b2d79ca27dcbb85465829595ad81cec5fc63983.tar.gz MusicSampler-4b2d79ca27dcbb85465829595ad81cec5fc63983.tar.zst MusicSampler-4b2d79ca27dcbb85465829595ad81cec5fc63983.zip |
Migrate to kivy
Diffstat (limited to 'helpers/key.py')
-rw-r--r-- | helpers/key.py | 202 |
1 files changed, 67 insertions, 135 deletions
diff --git a/helpers/key.py b/helpers/key.py index d923b1d..658c17f 100644 --- a/helpers/key.py +++ b/helpers/key.py | |||
@@ -1,169 +1,101 @@ | |||
1 | from .rounded_rect import * | 1 | from kivy.uix.widget import Widget |
2 | from kivy.properties import AliasProperty, BooleanProperty, ListProperty, StringProperty | ||
3 | from kivy.clock import Clock | ||
4 | from kivy.uix.behaviors import ButtonBehavior | ||
5 | |||
2 | from .action import * | 6 | from .action import * |
3 | from .font import font | ||
4 | import time | 7 | import time |
5 | import sys | 8 | |
6 | import pygame | 9 | class Key(ButtonBehavior, Widget): |
7 | 10 | key_sym = StringProperty(None) | |
8 | class Key: | 11 | custom_color = ListProperty([0, 1, 0, 1]) |
9 | default_outer_color = (120, 120, 120) | 12 | custom_unready_color = ListProperty([0, 1, 0, 100/255]) |
10 | lighter_outer_color = (200, 200, 200) | 13 | description_title = StringProperty("") |
11 | default_inner_color = (255, 255, 255) | 14 | description = ListProperty([]) |
12 | mapped_inner_color = ( 0, 255, 0) | 15 | is_key_ready = BooleanProperty(True) |
13 | mapped_unready_inner_color = ( 0, 255, 0, 100) | 16 | |
14 | 17 | def get_color(self): | |
15 | def __init__(self, mapping, draw_lock, key_name, key_sym, top, left, width = 48, height = 48, disabled = False): | 18 | if not self.has_actions: |
16 | self.draw_lock = draw_lock | 19 | return [1, 1, 1, 1] |
17 | self.mapping = mapping | 20 | elif self.all_actions_ready: |
18 | self.key_name = key_name | 21 | return self.custom_color |
19 | self.key_sym = key_sym | ||
20 | |||
21 | self.top = top | ||
22 | self.left = left | ||
23 | self.width = width | ||
24 | self.height = height | ||
25 | |||
26 | self.bottom = self.top + self.height | ||
27 | self.right = self.left + self.width | ||
28 | |||
29 | self.rect = (self.left, self.top, self.right, self.bottom) | ||
30 | self.position = (self.left, self.top) | ||
31 | self.disabled = disabled | ||
32 | |||
33 | if disabled: | ||
34 | self.outer_color = self.lighter_outer_color | ||
35 | self.linewidth = 1 | ||
36 | else: | 22 | else: |
37 | self.outer_color = self.default_outer_color | 23 | return self.custom_unready_color |
38 | self.linewidth = 3 | 24 | def set_color(self): |
25 | pass | ||
26 | |||
27 | color = AliasProperty(get_color, set_color, bind=['is_key_ready']) | ||
39 | 28 | ||
40 | self.inner_color = self.default_inner_color | 29 | def __init__(self, **kwargs): |
30 | super(Key, self).__init__(**kwargs) | ||
41 | self.actions = [] | 31 | self.actions = [] |
42 | self.description = [] | ||
43 | self.custom_color = self.mapped_inner_color | ||
44 | self.custom_unready_color = self.mapped_unready_inner_color | ||
45 | |||
46 | def square(self, all_actions_ready): | ||
47 | if self.has_actions(): | ||
48 | if all_actions_ready: | ||
49 | self.inner_color = self.custom_color | ||
50 | else: | ||
51 | self.inner_color = self.custom_unready_color | ||
52 | 32 | ||
53 | return RoundedRect((0, 0, self.width, self.height), | 33 | def on_key_sym(self, key, key_sym): |
54 | self.outer_color, self.inner_color, self.linewidth) | 34 | if key_sym in self.parent.key_config: |
35 | self.is_key_ready = False | ||
36 | |||
37 | self.config = self.parent.key_config[key_sym] | ||
55 | 38 | ||
56 | def collidepoint(self, position): | 39 | self.actions = [] |
57 | return self.surface.get_rect().collidepoint( | 40 | for key_action in self.config['actions']: |
58 | position[0] - self.position[0], | 41 | self.add_action(key_action[0], **key_action[1]) |
59 | position[1] - self.position[1] | 42 | |
60 | ) | 43 | if 'description' in self.config['properties']: |
44 | key.set_description(self.config['properties']['description']) | ||
45 | if 'color' in self.config['properties']: | ||
46 | key.set_color(self.config['properties']['color']) | ||
47 | |||
48 | Clock.schedule_interval(self.check_all_active, 1) | ||
49 | |||
50 | def check_all_active(self, dt): | ||
51 | if self.all_actions_ready: | ||
52 | self.is_key_ready = True | ||
53 | return False | ||
61 | 54 | ||
62 | def set_description(self, description): | 55 | def set_description(self, description): |
63 | for desc in description: | 56 | if description[0] is not None: |
57 | self.description_title = str(description[0]) | ||
58 | for desc in description[1:]: | ||
64 | if desc is None: | 59 | if desc is None: |
65 | self.description.append("") | 60 | self.description.append("") |
66 | else: | 61 | else: |
67 | self.description.append(str(desc)) | 62 | self.description.append(str(desc).replace(" ", " ")) |
68 | 63 | ||
69 | def set_color(self, color): | 64 | def set_color(self, color): |
70 | self.custom_color = tuple(color) | 65 | color = [x / 255 for x in color] |
71 | color.append(100) | 66 | color.append(1) |
67 | self.custom_color = color | ||
68 | color[3] = 100 / 255 | ||
72 | self.custom_unready_color = tuple(color) | 69 | self.custom_unready_color = tuple(color) |
73 | 70 | ||
74 | def draw(self, background_surface): | 71 | @property |
75 | self.draw_lock.acquire() | ||
76 | all_actions_ready = self.all_actions_ready() | ||
77 | |||
78 | self.surface = self.square(all_actions_ready).surface() | ||
79 | |||
80 | police = font(14) | ||
81 | text_police = font(10) | ||
82 | |||
83 | police.set_bold(True) | ||
84 | text = police.render(self.key_sym, True, (0,0,0)) | ||
85 | self.surface.blit(text, (5,5)) | ||
86 | |||
87 | is_first_line = True | ||
88 | offset = 11 + text_police.get_linesize() - 4 | ||
89 | first_line_offset = 18 | ||
90 | for description in self.description: | ||
91 | text = text_police.render(description, True, (0,0,0)) | ||
92 | if is_first_line: | ||
93 | self.surface.blit(text, (first_line_offset, 9)) | ||
94 | is_first_line = False | ||
95 | else: | ||
96 | self.surface.blit(text, (3, offset)) | ||
97 | offset += text_police.get_linesize() - 4 | ||
98 | |||
99 | background_surface.blit(self.surface, self.position) | ||
100 | self.draw_lock.release() | ||
101 | |||
102 | return not all_actions_ready | ||
103 | |||
104 | def poll_redraw(self, background): | ||
105 | while True: | ||
106 | time.sleep(1) | ||
107 | if self.all_actions_ready(): | ||
108 | self.draw(background) | ||
109 | self.mapping.blit() | ||
110 | break | ||
111 | |||
112 | def has_actions(self): | 72 | def has_actions(self): |
113 | return len(self.actions) > 0 | 73 | return len(self.actions) > 0 |
114 | 74 | ||
75 | @property | ||
115 | def all_actions_ready(self): | 76 | def all_actions_ready(self): |
116 | return all(action.ready() for action in self.actions) | 77 | return all(action.ready() for action in self.actions) |
117 | 78 | ||
118 | def add_action(self, action_name, **arguments): | 79 | def add_action(self, action_name, **arguments): |
119 | self.actions.append(Action(action_name, self, **arguments)) | 80 | self.actions.append(Action(action_name, self, **arguments)) |
120 | 81 | ||
121 | def do_actions(self, screen): | 82 | def do_actions(self): |
122 | print("running actions for {}".format(self.key_sym)) | 83 | print("running actions for {}".format(self.key_sym)) |
123 | start_time = time.time() | 84 | start_time = time.time() |
124 | self.mapping.start_running(self, start_time) | 85 | self.parent.start_running(self, start_time) |
125 | action_number = 0 | 86 | action_number = 0 |
126 | for action in self.actions: | 87 | for action in self.actions: |
127 | if self.mapping.keep_running(self, start_time): | 88 | if self.parent.keep_running(self, start_time): |
128 | self.list_actions(screen, action_number = action_number + 0.5) | 89 | self.list_actions(action_number = action_number + 0.5) |
129 | action.run() | 90 | action.run() |
130 | action_number += 1 | 91 | action_number += 1 |
131 | self.list_actions(screen, action_number = action_number) | 92 | self.list_actions(action_number = action_number) |
132 | |||
133 | self.mapping.finished_running(self, start_time) | ||
134 | |||
135 | def list_actions(self, screen, action_number = 0): | ||
136 | action_descriptions = [action.description() for action in self.actions] | ||
137 | #print("actions linked to key {}:".format(self.key_sym)) | ||
138 | #print("\t" + "\n\t".join(action_descriptions)) | ||
139 | self.draw_lock.acquire() | ||
140 | surface = pygame.Surface((690, 250)).convert() | ||
141 | surface.fill((250, 250, 250)) | ||
142 | police = font(14) | ||
143 | |||
144 | offset = 0 | ||
145 | police.set_bold(True) | ||
146 | text = police.render("actions linked to key {}:".format(self.key_sym), True, (0,0,0)) | ||
147 | surface.blit(text, (0, offset)) | ||
148 | offset += police.get_linesize() | ||
149 | |||
150 | police.set_bold(False) | ||
151 | icon_police = font(14, font = "Symbola") | ||
152 | for index, description in enumerate(action_descriptions): | ||
153 | if index < int(action_number): | ||
154 | icon = icon_police.render("✓", True, (0,0,0)) | ||
155 | elif index + 0.5 == action_number: | ||
156 | icon = icon_police.render("✅", True, (0,0,0)) | ||
157 | else: | ||
158 | icon = icon_police.render(" ", True, (0,0,0)) | ||
159 | |||
160 | text = police.render(description, True, (0,0,0)) | ||
161 | surface.blit(icon, (0, offset)) | ||
162 | surface.blit(text, (10, offset)) | ||
163 | offset += police.get_linesize() | ||
164 | 93 | ||
165 | screen.blit(surface, (5, 308)) | 94 | self.parent.finished_running(self, start_time) |
166 | pygame.display.flip() | ||
167 | self.draw_lock.release() | ||
168 | 95 | ||
96 | def list_actions(self, action_number = 0): | ||
97 | self.parent.parent.ids['ActionList'].update_list(self, action_number) | ||
169 | 98 | ||
99 | def on_press(self): | ||
100 | self.list_actions() | ||
101 | pass | ||