99# pylint: disable=import-error, unused-import, too-few-public-methods
1010
1111import os
12- import board
13- import digitalio
1412import displayio
15- import neopixel
16- import rotaryio
17- import keypad
1813import terminalio
19- import usb_hid
2014from adafruit_display_shapes .rect import Rect
2115from adafruit_display_text import label
22- from adafruit_hid .keyboard import Keyboard
23- from adafruit_hid .keycode import Keycode
24- from adafruit_hid .keyboard_layout_us import KeyboardLayoutUS
16+ from adafruit_macropad import MacroPad
2517
2618
2719# CONFIGURABLES ------------------------
3325
3426class App :
3527 """ Class representing a host-side application, for which we have a set
36- of macro sequences. """
28+ of macro sequences. Project code was originally more complex and
29+ this was helpful, but maybe it's excessive now?"""
3730 def __init__ (self , appdata ):
3831 self .name = appdata ['name' ]
3932 self .macros = appdata ['macros' ]
@@ -44,43 +37,36 @@ def switch(self):
4437 GROUP [13 ].text = self .name # Application name
4538 for i in range (12 ):
4639 if i < len (self .macros ): # Key in use, set label + LED color
47- PIXELS [i ] = self .macros [i ][0 ]
40+ MACROPAD . pixels [i ] = self .macros [i ][0 ]
4841 GROUP [i ].text = self .macros [i ][1 ]
49- else : # Key not in use, no label or LED
50- PIXELS [i ] = 0
42+ else : # Key not in use, no label or LED
43+ MACROPAD . pixels [i ] = 0
5144 GROUP [i ].text = ''
52- PIXELS .show ()
53- DISPLAY .refresh ()
45+ MACROPAD . pixels .show ()
46+ MACROPAD . display .refresh ()
5447
5548
5649# INITIALIZATION -----------------------
5750
58- DISPLAY = board .DISPLAY
59- DISPLAY .auto_refresh = False
60- ENCODER = rotaryio .IncrementalEncoder (board .ENCODER_B , board .ENCODER_A )
61- PIXELS = neopixel .NeoPixel (board .NEOPIXEL , 12 , auto_write = False )
62- KEYBOARD = Keyboard (usb_hid .devices )
63- LAYOUT = KeyboardLayoutUS (KEYBOARD )
64- KEYS = keypad .Keys ((board .KEY1 , board .KEY2 , board .KEY3 , board .KEY4 , board .KEY5 ,
65- board .KEY6 , board .KEY7 , board .KEY8 , board .KEY9 , board .KEY10 ,
66- board .KEY11 , board .KEY12 , board .ENCODER_SWITCH ),
67- value_when_pressed = False , pull = True )
68-
69- # Set up displayio group with all labels
70- GROUP = displayio .Group (max_size = 14 )
51+ MACROPAD = MacroPad ()
52+ MACROPAD .display .auto_refresh = False
53+ MACROPAD .pixels .auto_write = False
54+
55+ # Set up displayio group with all the labels
56+ GROUP = displayio .Group (max_size = 14 ) # 12 keys + rect + app name
7157for KEY_INDEX in range (12 ):
7258 x = KEY_INDEX % 3
7359 y = KEY_INDEX // 3
7460 GROUP .append (label .Label (terminalio .FONT , text = '' , color = 0xFFFFFF ,
75- anchored_position = ((DISPLAY .width - 1 ) * x / 2 ,
76- DISPLAY .height - 1 -
61+ anchored_position = ((MACROPAD . display .width - 1 ) * x / 2 ,
62+ MACROPAD . display .height - 1 -
7763 (3 - y ) * 12 ),
7864 anchor_point = (x / 2 , 1.0 ), max_glyphs = 15 ))
79- GROUP .append (Rect (0 , 0 , DISPLAY .width , 12 , fill = 0xFFFFFF ))
65+ GROUP .append (Rect (0 , 0 , MACROPAD . display .width , 12 , fill = 0xFFFFFF ))
8066GROUP .append (label .Label (terminalio .FONT , text = '' , color = 0x000000 ,
81- anchored_position = (DISPLAY .width // 2 , - 2 ),
67+ anchored_position = (MACROPAD . display .width // 2 , - 2 ),
8268 anchor_point = (0.5 , 0.0 ), max_glyphs = 30 ))
83- DISPLAY .show (GROUP )
69+ MACROPAD . display .show (GROUP )
8470
8571# Load all the macro key setups from .py files in MACRO_FOLDER
8672APPS = []
@@ -97,45 +83,66 @@ def switch(self):
9783
9884if not APPS :
9985 GROUP [13 ].text = 'NO MACRO FILES FOUND'
100- DISPLAY .refresh ()
86+ MACROPAD . display .refresh ()
10187 while True :
10288 pass
10389
10490LAST_POSITION = None
91+ LAST_ENCODER_SWITCH = MACROPAD .encoder_switch_debounced .pressed
10592APP_INDEX = 0
10693APPS [APP_INDEX ].switch ()
10794
10895
10996# MAIN LOOP ----------------------------
11097
11198while True :
112- POSITION = ENCODER .position
99+ # Read encoder position. If it's changed, switch apps.
100+ POSITION = MACROPAD .encoder
113101 if POSITION != LAST_POSITION :
114102 APP_INDEX = POSITION % len (APPS )
115103 APPS [APP_INDEX ].switch ()
116104 LAST_POSITION = POSITION
117105
118- EVENT = KEYS .events .get ()
119- if EVENT and EVENT .key_number < len (APPS [APP_INDEX ].macros ):
120- SEQUENCE = APPS [APP_INDEX ].macros [EVENT .key_number ][2 ]
121- if EVENT .pressed :
122- if EVENT .key_number < 12 :
123- PIXELS [EVENT .key_number ] = 0xFFFFFF
124- PIXELS .show ()
125- for item in SEQUENCE :
126- if isinstance (item , int ):
127- if item >= 0 :
128- KEYBOARD .press (item )
129- else :
130- KEYBOARD .release (item )
106+ # Handle encoder button. If state has changed, and if there's a
107+ # corresponding macro, set up variables to act on this just like
108+ # the keypad keys, as if it were a 13th key/macro.
109+ MACROPAD .encoder_switch_debounced .update ()
110+ ENCODER_SWITCH = MACROPAD .encoder_switch_debounced .pressed
111+ if ENCODER_SWITCH != LAST_ENCODER_SWITCH :
112+ LAST_ENCODER_SWITCH = ENCODER_SWITCH
113+ if len (APPS [APP_INDEX ].macros ) < 13 :
114+ continue # No 13th macro, just resume main loop
115+ KEY_NUMBER = 12 # else process below as 13th macro
116+ PRESSED = ENCODER_SWITCH
117+ else :
118+ EVENT = MACROPAD .keys .events .get ()
119+ if not EVENT or EVENT .key_number >= len (APPS [APP_INDEX ].macros ):
120+ continue # No key events, or no corresponding macro, resume loop
121+ KEY_NUMBER = EVENT .key_number
122+ PRESSED = EVENT .pressed
123+
124+ # If code reaches here, a key or the encoder button WAS pressed/released
125+ # and there IS a corresponding macro available for it...other situations
126+ # are avoided by 'continue' statements above which resume the loop.
127+
128+ SEQUENCE = APPS [APP_INDEX ].macros [KEY_NUMBER ][2 ]
129+ if PRESSED :
130+ if KEY_NUMBER < 12 : # No pixel for encoder button
131+ MACROPAD .pixels [KEY_NUMBER ] = 0xFFFFFF
132+ MACROPAD .pixels .show ()
133+ for item in SEQUENCE :
134+ if isinstance (item , int ):
135+ if item >= 0 :
136+ MACROPAD .keyboard .press (item )
131137 else :
132- LAYOUT .write (item )
133- else :
134- # Release any still-pressed modifier keys
135- for item in SEQUENCE :
136- if isinstance (item , int ) and item >= 0 :
137- KEYBOARD .release (item )
138- if EVENT .key_number < 12 :
139- PIXELS [EVENT .key_number ] = APPS [APP_INDEX ].macros [
140- EVENT .key_number ][0 ]
141- PIXELS .show ()
138+ MACROPAD .keyboard .release (item )
139+ else :
140+ MACROPAD .keyboard_layout .write (item )
141+ else :
142+ # Release any still-pressed modifier keys
143+ for item in SEQUENCE :
144+ if isinstance (item , int ) and item >= 0 :
145+ MACROPAD .keyboard .release (item )
146+ if KEY_NUMBER < 12 : # No pixel for encoder button
147+ MACROPAD .pixels [KEY_NUMBER ] = APPS [APP_INDEX ].macros [KEY_NUMBER ][0 ]
148+ MACROPAD .pixels .show ()
0 commit comments