aboutsummaryrefslogtreecommitdiff
path: root/helpers/key.py
diff options
context:
space:
mode:
authorIsmaël Bouya <ismael.bouya@normalesup.org>2016-06-25 23:37:49 +0200
committerIsmaël Bouya <ismael.bouya@normalesup.org>2016-06-25 23:40:51 +0200
commit4b2d79ca27dcbb85465829595ad81cec5fc63983 (patch)
tree683b3a9b19aa01de53b0dccc3ac143d876dcf088 /helpers/key.py
parent8612c5f8bb0fc9529bc489a6719654d4474db6d5 (diff)
downloadMusicSampler-4b2d79ca27dcbb85465829595ad81cec5fc63983.tar.gz
MusicSampler-4b2d79ca27dcbb85465829595ad81cec5fc63983.tar.zst
MusicSampler-4b2d79ca27dcbb85465829595ad81cec5fc63983.zip
Migrate to kivy
Diffstat (limited to 'helpers/key.py')
-rw-r--r--helpers/key.py202
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 @@
1from .rounded_rect import * 1from kivy.uix.widget import Widget
2from kivy.properties import AliasProperty, BooleanProperty, ListProperty, StringProperty
3from kivy.clock import Clock
4from kivy.uix.behaviors import ButtonBehavior
5
2from .action import * 6from .action import *
3from .font import font
4import time 7import time
5import sys 8
6import pygame 9class Key(ButtonBehavior, Widget):
7 10 key_sym = StringProperty(None)
8class 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