17
17
from adafruit_hid .consumer_control_code import ConsumerControlCode
18
18
from adafruit_hid .mouse import Mouse
19
19
20
- from utils .utils import to_chunks
21
20
from utils .devices import Encoder , Key
22
21
from utils .system import System
23
22
@@ -88,21 +87,24 @@ class MacroApp():
88
87
""" Main Class """
89
88
def __init__ (self ) -> None :
90
89
self .macropad = MacroPad (layout_class = KeyboardLayout , rotation = 180 if SETTINGS ["fliprotation" ] else 0 )
90
+
91
91
self .macropad .display .auto_refresh = False
92
92
self .macropad .display .brightness = SETTINGS ["brightness" ]
93
+ self .macropad .display .root_group = displayio .Group ()
94
+
93
95
self .macropad .pixels .auto_write = False
94
96
self .macropad .pixels .brightness = SETTINGS ["brightness" ]
95
97
96
98
self .readonly = storage .getmount ('/' ).readonly
97
99
self .serial_data = usb_cdc .data
98
100
self .serial_last_state = False
99
-
100
- self .macros = self ._init_macros ()
101
+
102
+ self .macroStack = [ self ._init_macros ()]
101
103
self .keys = self ._init_keys ()
102
- self .toolbar = self ._init_toolbar ()
104
+ self .group_label = self ._init_group_label ()
103
105
self .encoder = Encoder (self .macropad )
104
106
105
- self .show_homescreen ()
107
+ self ._init_group ()
106
108
107
109
def _save_settings (self , new_settings ) -> None :
108
110
""" store the new settings in the settingsfile
@@ -119,18 +121,19 @@ def _init_macros(self) -> list[dict]:
119
121
Returns:
120
122
dict: the json file as dict
121
123
"""
124
+ rootLabel = "Macros"
122
125
try :
123
126
with open (MACROFILE , "r" ) as f :
124
127
macros = json .load (f )
125
128
if isinstance (macros , list ):
126
129
return {
127
- "label" : "Macros" ,
130
+ "label" : rootLabel ,
128
131
"content" : macros ,
129
132
}
130
133
return macros
131
134
except OSError :
132
135
return {
133
- "label" : "Macros" ,
136
+ "label" : rootLabel ,
134
137
"content" : [],
135
138
}
136
139
@@ -140,102 +143,60 @@ def _save_macros(self) -> None:
140
143
if self .readonly :
141
144
return False
142
145
with open (MACROFILE , "w" ) as f :
143
- f .write (json .dumps (self .macros , separators = ("," , ":" )))
146
+ f .write (json .dumps (self .macroStack [ 0 ] , separators = ("," , ":" )))
144
147
return True
145
148
149
+ def _init_group_label (self ) -> dict [str , Key ]:
150
+ group_label = Label (
151
+ font = load_font ("/fonts/6x12.pcf" ) if SETTINGS ["useunicodefont" ] else terminalio .FONT ,
152
+ text = "" ,
153
+ padding_top = 0 ,
154
+ padding_bottom = 0 ,
155
+ padding_left = 0 ,
156
+ padding_right = 0 ,
157
+ color = 0xFFFFFF ,
158
+ anchored_position = (self .macropad .display .width // 2 , self .macropad .display .height - 10 ),
159
+ anchor_point = (0.5 , 0.0 )
160
+ )
161
+
162
+ self .macropad .display .root_group .append (group_label )
163
+
164
+ return group_label
165
+
146
166
def _init_keys (self ) -> list [Key ]:
147
167
""" Initiate the keys and a display group for each key
148
168
149
169
Returns:
150
170
list[Key]: a list of Keys
151
171
"""
152
172
keys = []
153
- group = displayio .Group ()
154
173
155
174
for i in range (self .macropad .keys .key_count ):
156
175
label = Label (
157
176
font = load_font ("/fonts/6x12.pcf" ) if SETTINGS ["useunicodefont" ] else terminalio .FONT ,
158
177
text = "" ,
159
- padding_top = 1 ,
160
- padding_bottom = 2 ,
178
+ padding_top = 0 ,
179
+ padding_bottom = 1 ,
161
180
padding_left = 4 ,
162
181
padding_right = 4 ,
163
182
color = 0xFFFFFF ,
164
183
anchored_position = (
165
184
(self .macropad .display .width - 2 ) / 2 * (i % 3 ) + 1 ,
166
- self .macropad .display .height / 4 * (i // 3 ) + 2 ),
185
+ self .macropad .display .height / 5 * (i // 3 ) + 2 ),
167
186
anchor_point = ((i % 3 ) / 2 , 0.0 )
168
187
)
169
188
170
189
keys .append (Key (self .macropad , i , label ))
171
- group .append (label )
190
+ self . macropad . display . root_group .append (label )
172
191
173
- self .macropad .display .root_group = group
174
192
return keys
175
193
176
- def _init_toolbar (self ) -> dict [str , Key ]:
177
- """ Return a dict for the toolbar keys
178
-
179
- Returns:
180
- dict[str, Key]: position of key, Key
181
- """
182
- return {
183
- "left" : self .keys [0 ],
184
- "center" : self .keys [1 ],
185
- "right" : self .keys [2 ],
186
- }
187
-
188
194
def _init_group (self ) -> None :
189
195
""" initiate the group content
190
196
"""
191
197
self ._update_encoder_macros ()
192
198
193
- self .tabs_content = list (to_chunks (self .group_stack [- 1 ]["content" ], 9 ))
194
199
self ._update_tab ()
195
-
196
- def show_homescreen (self , * args ) -> None :
197
- """ Show or return to Homescreen
198
- """
199
- self .current_tab = 0
200
- self .tabs_content = []
201
- self .tab_index_stack = []
202
- self .group_stack = [self .macros ]
203
-
204
- self ._init_group ()
205
-
206
- def _set_toolbar (self , position :str , label :str , func :dict ) -> None :
207
- """ set the label and function for the given toolbar key
208
-
209
- Args:
210
- position (str): ("left"|"center"|"right")
211
- label (str): the displayed label
212
- func (dict): the function that will be called on key press
213
- """
214
- self .toolbar [position ].label = label
215
- self .toolbar [position ].type = "macro"
216
- self .toolbar [position ].color = (100 , 100 , 100 )
217
- self .toolbar [position ].set_func (func )
218
-
219
- def _update_toolbar (self ) -> None :
220
- """ update the toolbar keys based on tab or folder hierarchy
221
- """
222
- if self .current_tab > 0 :
223
- self ._set_toolbar ("left" , "<-" , self .prev_tab )
224
- elif len (self .group_stack ) > 1 :
225
- self ._set_toolbar ("left" , "<-" , self .close_group )
226
- else :
227
- self .toolbar ["left" ].clear_props ()
228
-
229
- if len (self .group_stack ) > 1 and self .current_tab > 0 :
230
- self ._set_toolbar ("center" , self .group_stack [- 1 ]["label" ], self .show_homescreen )
231
- else :
232
- self .toolbar ["center" ].clear_props ()
233
- self .toolbar ["center" ].label = self .group_stack [- 1 ]["label" ]
234
-
235
- if len (self .tabs_content ) > 1 and self .current_tab < len (self .tabs_content ) - 1 :
236
- self ._set_toolbar ("right" , "->" , self .next_tab )
237
- else :
238
- self .toolbar ["right" ].clear_props ()
239
200
240
201
def run_macro (self , item :dict , * args ) -> None :
241
202
""" run the macro, can be:
@@ -273,6 +234,8 @@ def run_macro(self, item:dict, *args) -> None:
273
234
if control_code :
274
235
self .macropad .consumer_control .press (control_code )
275
236
self .macropad .consumer_control .release ()
237
+ if 'tone' in key :
238
+ self .macropad .play_tone (key ['tone' ]['frequency' ], key ['tone' ]['duration' ])
276
239
if 'mse' in key :
277
240
if "b" in key ["mse" ]:
278
241
btn = getattr (Mouse , f"{ key ['mse' ]['b' ].upper ()} _BUTTON" , None )
@@ -296,75 +259,63 @@ def open_group(self, item:dict, *args) -> None:
296
259
Args:
297
260
item (dict): the group item containing data
298
261
"""
299
- self .tab_index_stack .append (self .current_tab )
300
- self .current_tab = 0
301
262
302
- self .group_stack .append (item )
263
+ self .macroStack .append (item )
303
264
self ._init_group ()
304
265
305
266
def close_group (self , * args ) -> None :
306
267
""" close a group and go a level up
307
268
"""
308
- self .current_tab = self .tab_index_stack .pop ()
269
+ if len (self .macroStack ) > 1 :
270
+ self .macroStack .pop ()
271
+ self ._init_group ()
309
272
310
- self .group_stack .pop ()
273
+ def go_to_root (self , * args ) -> None :
274
+ """ close a group and go to root
275
+ """
276
+ del self .macroStack [1 :]
311
277
self ._init_group ()
312
278
313
279
def _update_tab (self ) -> None :
314
280
""" update the current displayed group tab
315
281
"""
316
- for key in self .keys [ 3 :] :
282
+ for key in self .keys :
317
283
key .clear_props ()
318
284
319
- if len (self .tabs_content ) > 0 :
320
- for i , item in enumerate (self .tabs_content [self .current_tab ], start = 3 ):
321
- self .keys [i ].type = item ["type" ]
322
- self .keys [i ].label = item ["label" ] if item ["type" ] in ["group" , "macro" ] else ""
323
- self .keys [i ].color = item ["color" ] if item ["type" ] in ["group" , "macro" ] else (0 , 0 , 0 )
324
- self .keys [i ].set_func (self ._get_key_func (item ["type" ]), item )
285
+ for i , item in enumerate (self .macroStack [- 1 ]["content" ][:self .macropad .keys .key_count ]):
286
+ self .keys [i ].type = item ["type" ]
287
+ self .keys [i ].label = "" if item ["type" ] == "blank" else item ["label" ]
288
+ self .keys [i ].color = (0 , 0 , 0 ) if item ["type" ] == "blank" else item ["color" ]
289
+ self .keys [i ].set_func (self ._get_key_func (item ["type" ]), item )
325
290
326
- self ._update_toolbar ()
291
+ self .group_label . text = self . macroStack [ - 1 ][ "label" ]
327
292
328
293
for key in self .keys :
329
294
key .update_colors ()
330
295
331
- def next_tab (self , * args ) -> None :
332
- """ increase the tab index and update the tab
333
- """
334
- if self .current_tab < len (self .tabs_content ) - 1 :
335
- self .current_tab += 1
336
- self ._update_tab ()
337
-
338
- def prev_tab (self , * args ) -> None :
339
- """ decrease the tab index and update the tab
340
- """
341
- if self .current_tab > 0 :
342
- self .current_tab -= 1
343
- self ._update_tab ()
344
-
345
296
def _get_key_func (self , type :str ) -> function :
346
297
""" get the specific function for the type
347
298
348
299
Args:
349
- type (str): the item type (group|macro)
300
+ type (str): the item type
350
301
351
302
Returns:
352
303
function: return the function for type
353
304
"""
354
305
key_funcs = {
355
- "group " : self . open_group ,
356
- "macro " : self .run_macro
306
+ "blank " : None ,
307
+ "group " : self .open_group
357
308
}
358
309
359
- return key_funcs .get (type )
310
+ return key_funcs .get (type , self . run_macro )
360
311
361
312
def _update_encoder_macros (self ) -> None :
362
313
""" update the rotary encoder macros defined for opened group
363
314
"""
364
315
self .encoder .update_encoder_macros (
365
- on_switch = self .group_stack [- 1 ].get ("encoder" , {}).get ("switch" ),
366
- on_increased = self .group_stack [- 1 ].get ("encoder" , {}).get ("increased" ),
367
- on_decreased = self .group_stack [- 1 ].get ("encoder" , {}).get ("decreased" )
316
+ on_switch = self .macroStack [- 1 ].get ("encoder" , {}).get ("switch" ),
317
+ on_increased = self .macroStack [- 1 ].get ("encoder" , {}).get ("increased" ),
318
+ on_decreased = self .macroStack [- 1 ].get ("encoder" , {}).get ("decreased" )
368
319
)
369
320
370
321
def _handle_serial_data (self , payload :str ) -> dict :
@@ -407,7 +358,7 @@ def _handle_serial_data(self, payload:str) -> dict:
407
358
408
359
elif command == 'get_macros' :
409
360
response ['ACK' ] = 'macros'
410
- response ['CONTENT' ] = self .macros
361
+ response ['CONTENT' ] = self .macroStack [ 0 ]
411
362
return response
412
363
413
364
elif command == 'set_macros' :
@@ -416,9 +367,9 @@ def _handle_serial_data(self, payload:str) -> dict:
416
367
return response
417
368
418
369
content = payload ['content' ]
419
- self .macros = content
370
+ self .macroStack = [ content ]
420
371
self ._display_on ()
421
- self .show_homescreen ()
372
+ self ._init_group ()
422
373
423
374
response ['ACK' ] = 'Macros received'
424
375
return response
@@ -466,6 +417,8 @@ def _send_serial_data(self, payload:dict) -> None:
466
417
self .serial_data .write (bytearray (payloads .encode ()))
467
418
468
419
def _display_on (self ) -> None :
420
+ """ Turn on the display if it's in sleep mode and reset the sleep timer.
421
+ """
469
422
if self .macropad .display_sleep :
470
423
self .macropad .display_sleep = False
471
424
self .sleep_timer = time .monotonic ()
0 commit comments