Skip to content

Commit c6d381f

Browse files
Use .py instead of .json for macro files, code’s way simpler
1 parent 48df9c3 commit c6d381f

File tree

7 files changed

+120
-97
lines changed

7 files changed

+120
-97
lines changed

Macropad_Hotkeys/code.py

Lines changed: 38 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
# pylint: disable=import-error, unused-import, too-few-public-methods, eval-used
1010

11-
import json
1211
import os
1312
import time
1413
import board
@@ -18,9 +17,11 @@
1817
import rotaryio
1918
import terminalio
2019
import usb_hid
20+
from adafruit_display_shapes.rect import Rect
2121
from adafruit_display_text import label
2222
from adafruit_hid.keyboard import Keyboard
2323
from adafruit_hid.keycode import Keycode
24+
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
2425

2526

2627
# CONFIGURABLES ------------------------
@@ -55,71 +56,48 @@ def debounce(self):
5556
return value
5657
return None
5758

58-
class Macro:
59-
""" Class representing a single macro sequence - a text label, LED color
60-
for the keypad, and a keycode sequence to issue when activated. """
61-
def __init__(self, desc, color, sequence):
62-
self.desc = desc
63-
self.color = eval(color)
64-
self.sequence = sequence
65-
self.in_order = False
66-
for key in sequence:
67-
if key.startswith('+') or key.startswith('-'):
68-
self.in_order = True
69-
break
70-
7159
class App:
7260
""" Class representing a host-side application, for which we have a set
7361
of macro sequences. """
74-
def __init__(self, filename):
75-
with open(MACRO_FOLDER + '/' + filename) as jsonfile:
76-
json_data = json.load(jsonfile)
77-
self.name = json_data['name']
78-
default_color = json_data['color'] if 'color' in json_data else '0'
79-
self.macros = []
80-
for mac in json_data['macros']:
81-
self.macros.append(Macro(
82-
mac['desc'] if 'desc' in mac else None,
83-
mac['color'] if 'color' in mac else default_color,
84-
mac['sequence'] if 'sequence' in mac else None))
62+
def __init__(self, appdata):
63+
self.name = appdata['name']
64+
self.macros = appdata['macros']
8565

8666
def switch(self):
8767
""" Activate application settings; update OLED labels and LED
8868
colors. """
89-
GROUP[12].text = self.name # Application name
69+
GROUP[13].text = self.name # Application name
9070
for i in range(12):
9171
if i < len(self.macros): # Key in use, set label + LED color
92-
PIXELS[i] = self.macros[i].color
93-
GROUP[i].text = self.macros[i].desc
72+
PIXELS[i] = self.macros[i][0]
73+
GROUP[i].text = self.macros[i][1]
9474
else: # Key not in use, no label or LED
9575
PIXELS[i] = 0
9676
GROUP[i].text = ''
9777
PIXELS.show()
9878

99-
def code(name):
100-
""" Convert a key code name (e.g. 'COMMAND') to a numeric value for
101-
press/release events. """
102-
return eval('Keycode.' + name.upper())
103-
10479

10580
# INITIALIZATION -----------------------
10681

10782
DISPLAY = board.DISPLAY
10883
ENCODER = rotaryio.IncrementalEncoder(board.ENCODER_B, board.ENCODER_A)
10984
PIXELS = neopixel.NeoPixel(board.NEOPIXEL, 12, auto_write=False)
11085
KEYBOARD = Keyboard(usb_hid.devices)
86+
LAYOUT = KeyboardLayoutUS(KEYBOARD)
87+
11188

112-
GROUP = displayio.Group(max_size=13)
89+
GROUP = displayio.Group(max_size=14)
11390
for KEY_INDEX in range(12):
11491
x = KEY_INDEX % 3
11592
y = KEY_INDEX // 3
11693
GROUP.append(label.Label(terminalio.FONT, text='', color=0xFFFFFF,
11794
anchored_position=((DISPLAY.width - 1) * x / 2,
11895
DISPLAY.height - 1 -
119-
(3 - y) * 11),
96+
(3 - y) * 12),
12097
anchor_point=(x / 2, 1.0), max_glyphs=15))
121-
GROUP.append(label.Label(terminalio.FONT, text='', color=0xFFFFFF,
122-
anchored_position=(DISPLAY.width//2, 0),
98+
GROUP.append(Rect(0, 0, DISPLAY.width, 12, fill=0xFFFFFF))
99+
GROUP.append(label.Label(terminalio.FONT, text='', color=0x000000,
100+
anchored_position=(DISPLAY.width//2, -2),
123101
anchor_point=(0.5, 0.0), max_glyphs=30))
124102
DISPLAY.show(GROUP)
125103

@@ -129,12 +107,14 @@ def code(name):
129107
board.KEY11, board.KEY12, board.ENCODER_SWITCH):
130108
KEYS.append(Key(pin))
131109

110+
# Load all the macro key setups from .py files in MACRO_FOLDER
132111
APPS = []
133112
FILES = os.listdir(MACRO_FOLDER)
134113
FILES.sort()
135114
for FILENAME in FILES:
136-
if FILENAME.endswith('.json'):
137-
APPS.append(App(FILENAME))
115+
if FILENAME.endswith('.py'):
116+
module = __import__(MACRO_FOLDER + '/' + FILENAME[:-3])
117+
APPS.append(App(module.app))
138118

139119
if not APPS:
140120
print('No valid macro files found')
@@ -158,28 +138,24 @@ def code(name):
158138
for KEY_INDEX, KEY in enumerate(KEYS[0: len(APPS[APP_INDEX].macros)]):
159139
action = KEY.debounce()
160140
if action is not None:
161-
keys = APPS[APP_INDEX].macros[KEY_INDEX].sequence
141+
sequence = APPS[APP_INDEX].macros[KEY_INDEX][2]
162142
if action is False: # Macro key pressed
163-
PIXELS[KEY_INDEX] = 0xFFFFFF
164-
PIXELS.show()
165-
if APPS[APP_INDEX].macros[KEY_INDEX].in_order:
166-
for x in APPS[APP_INDEX].macros[KEY_INDEX].sequence:
167-
if x.startswith('+'): # Press and hold key
168-
KEYBOARD.press(code(x[1:]))
169-
elif x.startswith('-'): # Release key
170-
KEYBOARD.release(code(x[1:]))
171-
else: # Press and release key
172-
KEYBOARD.press(code(x))
173-
KEYBOARD.release(code(x))
174-
else: # Send press events now, release later
175-
for x in APPS[APP_INDEX].macros[KEY_INDEX].sequence:
176-
KEYBOARD.press(code(x))
177-
elif action is True: # Macro key released
178-
# Release all keys in reverse order
179-
for x in reversed(APPS[APP_INDEX].macros[KEY_INDEX].sequence):
180-
if x.startswith('+') or x.startswith('-'):
181-
KEYBOARD.release(code(x[1:]))
143+
if KEY_INDEX < 12:
144+
PIXELS[KEY_INDEX] = 0xFFFFFF
145+
PIXELS.show()
146+
for item in sequence:
147+
if isinstance(item, int):
148+
if item >= 0:
149+
KEYBOARD.press(item)
150+
else:
151+
KEYBOARD.release(item)
182152
else:
183-
KEYBOARD.release(code(x))
184-
PIXELS[KEY_INDEX] = APPS[APP_INDEX].macros[KEY_INDEX].color
185-
PIXELS.show()
153+
LAYOUT.write(item)
154+
elif action is True: # Macro key released
155+
# Release any still-pressed modifier keys
156+
for item in sequence:
157+
if isinstance(item, int) and item >= 0:
158+
KEYBOARD.release(item)
159+
if KEY_INDEX < 12:
160+
PIXELS[KEY_INDEX] = APPS[APP_INDEX].macros[KEY_INDEX][0]
161+
PIXELS.show()

Macropad_Hotkeys/macros/mac-adobe-illustrator.json

Lines changed: 0 additions & 13 deletions
This file was deleted.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from adafruit_hid.keycode import Keycode # REQUIRED if using Keycode.* values
2+
3+
app = { # REQUIRED dict, must be named 'app'
4+
'name' : 'Illustrator', # Application name
5+
'macros' : [ # List of button macros...
6+
# COLOR LABEL KEY SEQUENCE
7+
# 1st row ----------
8+
(0x004000, 'Undo', [Keycode.COMMAND, 'z']),
9+
(0x004000, 'Redo', [Keycode.COMMAND, 'Z']),
10+
(0x303000, 'Pen', 'p'), # Path-drawing tool
11+
# 2nd row ----------
12+
13+
(0x101010, 'Select', 'v'), # Select (path)
14+
(0x400000, 'Reflect', 'o'), # Reflect selection
15+
(0x303000, 'Rect', 'm'), # Draw rectangle
16+
# 3rd row ----------
17+
(0x101010, 'Direct', 'a'), # Direct (point) selection
18+
(0x400000, 'Rotate', 'r'), # Rotate selection
19+
(0x303000, 'Oval', 'l'), # Draw ellipse
20+
# 4th row ----------
21+
(0x101010, 'Eyedrop', 'i'), # Cycle eyedropper/measure modes
22+
(0x400000, 'Scale', 's'), # Scale selection
23+
(0x303000, 'Text', 't'), # Type tool
24+
# Encoder button ---
25+
(0x000000, '', [Keycode.COMMAND, Keycode.OPTION, 'S']) # Save for web
26+
]
27+
}

Macropad_Hotkeys/macros/mac-adobe-photoshop.json

Lines changed: 0 additions & 13 deletions
This file was deleted.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from adafruit_hid.keycode import Keycode # REQUIRED if using Keycode.* values
2+
3+
app = { # REQUIRED dict, must be named 'app'
4+
'name' : 'Photoshop', # Application name
5+
'macros' : [ # List of button macros...
6+
# COLOR LABEL KEY SEQUENCE
7+
# 1st row ----------
8+
(0x004000, 'Undo', [Keycode.COMMAND, 'z']),
9+
(0x004000, 'Redo', [Keycode.COMMAND, 'Z']),
10+
(0x000040, 'Brush', 'B'), # Cycle brush modes
11+
# 2nd row ----------
12+
(0x101010, 'B&W', 'd'), # Default colors
13+
(0x101010, 'Marquee', 'M'), # Cycle rect/ellipse marquee (select)
14+
(0x000040, 'Eraser', 'E'), # Cycle eraser modes
15+
# 3rd row ----------
16+
(0x101010, 'Swap', 'x'), # Swap foreground/background colors
17+
(0x101010, 'Move', 'v'), # Move layer
18+
(0x000040, 'Fill', 'G'), # Cycle fill/gradient modes
19+
# 4th row ----------
20+
(0x101010, 'Eyedrop', 'I'), # Cycle eyedropper/measure modes
21+
(0x101010, 'Wand', 'W'), # Cycle "magic wand" (selection) modes
22+
(0x000040, 'Heal', 'J'), # Cycle "healing" modes
23+
# Encoder button ---
24+
(0x000000, '', [Keycode.COMMAND, Keycode.OPTION, 'S']) # Save for web
25+
]
26+
}

Macropad_Hotkeys/macros/mac-safari.json

Lines changed: 0 additions & 9 deletions
This file was deleted.

Macropad_Hotkeys/macros/mac-safari.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from adafruit_hid.keycode import Keycode # REQUIRED if using Keycode.* values
2+
3+
app = { # REQUIRED dict, must be named 'app'
4+
'name' : 'Safari', # Application name
5+
'macros' : [ # List of button macros...
6+
# COLOR LABEL KEY SEQUENCE
7+
# 1st row ----------
8+
(0x004000, '< Back', [Keycode.COMMAND, '[']),
9+
(0x004000, 'Fwd >', [Keycode.COMMAND, ']']),
10+
(0x400000, 'Up', [Keycode.SHIFT, ' ']), # Scroll up
11+
# 2nd row ----------
12+
(0x202000, '< Tab', [Keycode.CONTROL, Keycode.SHIFT, Keycode.TAB]),
13+
(0x202000, 'Tab >', [Keycode.CONTROL, Keycode.TAB]),
14+
(0x400000, 'Down', ' '), # Scroll down
15+
# 3rd row ----------
16+
(0x000040, 'Reload', [Keycode.COMMAND, 'r']),
17+
(0x000040, 'Home', [Keycode.COMMAND, 'H']),
18+
(0x000040, 'Private', [Keycode.COMMAND, 'N']),
19+
# 4th row ----------
20+
(0x000000, 'Ada', [Keycode.COMMAND, 'n', -Keycode.COMMAND,
21+
'www.adafruit.com\n']), # Adafruit in new window
22+
(0x800000, 'Digi', [Keycode.COMMAND, 'n', -Keycode.COMMAND,
23+
'www.digikey.com\n']), # Digi-Key in new window
24+
(0x101010, 'Hacks', [Keycode.COMMAND, 'n', -Keycode.COMMAND,
25+
'www.hackaday.com\n']), # Hack-a-Day in new win
26+
# Encoder button ---
27+
(0x000000, '', [Keycode.COMMAND, 'w']) # Close window/tab
28+
]
29+
}

0 commit comments

Comments
 (0)