Skip to content

Commit 54cf70f

Browse files
authored
Merge pull request #3 from kattni/fixes
Map pixels to match keys on rotation.
2 parents 4f0e7a3 + c2ebe5b commit 54cf70f

File tree

1 file changed

+68
-64
lines changed

1 file changed

+68
-64
lines changed

adafruit_macropad.py

100644100755
+68-64
Original file line numberDiff line numberDiff line change
@@ -109,74 +109,41 @@ def __init__(self, rotation=0, midi_in_channel=1, midi_out_channel=1):
109109
if rotation not in (0, 90, 180, 270):
110110
raise ValueError("Only 90 degree rotations are supported.")
111111

112-
# Define keys:
112+
# Define LEDs:
113+
self._pixels = neopixel.NeoPixel(board.NEOPIXEL, 12)
114+
self._led = digitalio.DigitalInOut(board.LED)
115+
self._led.switch_to_output()
116+
117+
# Define key and pixel maps based on rotation:
118+
self._rotated_pixels = None
119+
self._key_pins = None
120+
121+
def _keys_and_pixels(order=None):
122+
"""
123+
Generate key and pixel maps based on a specified order.
124+
:param order: The order of the keys and pixels.
125+
"""
126+
if not order:
127+
order = list(range(12))
128+
self._key_pins = [getattr(board, "KEY%d" % (num + 1)) for num in order]
129+
self._rotated_pixels = _PixelMapLite(self._pixels, order=order)
130+
113131
if rotation == 0:
114-
self._key_pins = (
115-
board.KEY1,
116-
board.KEY2,
117-
board.KEY3,
118-
board.KEY4,
119-
board.KEY5,
120-
board.KEY6,
121-
board.KEY7,
122-
board.KEY8,
123-
board.KEY9,
124-
board.KEY10,
125-
board.KEY11,
126-
board.KEY12,
127-
)
132+
_keys_and_pixels()
128133

129134
if rotation == 90:
130-
self._key_pins = (
131-
board.KEY3,
132-
board.KEY6,
133-
board.KEY9,
134-
board.KEY12,
135-
board.KEY2,
136-
board.KEY5,
137-
board.KEY8,
138-
board.KEY11,
139-
board.KEY1,
140-
board.KEY4,
141-
board.KEY7,
142-
board.KEY10,
143-
)
135+
_keys_and_pixels(order=(2, 5, 8, 11, 1, 4, 7, 10, 0, 3, 6, 9))
144136

145137
if rotation == 180:
146-
self._key_pins = (
147-
board.KEY12,
148-
board.KEY11,
149-
board.KEY10,
150-
board.KEY9,
151-
board.KEY8,
152-
board.KEY7,
153-
board.KEY6,
154-
board.KEY5,
155-
board.KEY4,
156-
board.KEY3,
157-
board.KEY2,
158-
board.KEY1,
159-
)
138+
_keys_and_pixels(order=(11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
160139

161140
if rotation == 270:
162-
self._key_pins = (
163-
board.KEY10,
164-
board.KEY7,
165-
board.KEY4,
166-
board.KEY1,
167-
board.KEY11,
168-
board.KEY8,
169-
board.KEY5,
170-
board.KEY2,
171-
board.KEY12,
172-
board.KEY9,
173-
board.KEY6,
174-
board.KEY3,
175-
)
141+
_keys_and_pixels(order=(9, 6, 3, 0, 10, 7, 4, 1, 11, 8, 5, 2))
176142

143+
# Define keys:
177144
self._keys = keypad.Keys(self._key_pins, value_when_pressed=False, pull=True)
178145

179-
# Define rotary encoder:
146+
# Define rotary encoder and encoder switch:
180147
self._encoder = rotaryio.IncrementalEncoder(board.ROTA, board.ROTB)
181148
self._encoder_switch = digitalio.DigitalInOut(board.BUTTON)
182149
self._encoder_switch.switch_to_input(pull=digitalio.Pull.UP)
@@ -193,11 +160,6 @@ def __init__(self, rotation=0, midi_in_channel=1, midi_out_channel=1):
193160
self._sine_wave = None
194161
self._sine_wave_sample = None
195162

196-
# Define LEDs:
197-
self._pixels = neopixel.NeoPixel(board.NEOPIXEL, 12, brightness=0.5)
198-
self._led = digitalio.DigitalInOut(board.LED)
199-
self._led.switch_to_output()
200-
201163
# Define HID:
202164
self._keyboard = Keyboard(usb_hid.devices)
203165
# This will need to be updated if we add more keyboard layouts. Currently there is only US.
@@ -280,7 +242,7 @@ def pixels(self):
280242
macropad.pixels[0] = (255, 0, 0)
281243
macropad.pixels[11] = (0, 0, 255)
282244
"""
283-
return self._pixels
245+
return self._rotated_pixels
284246

285247
@property
286248
def red_led(self):
@@ -908,3 +870,45 @@ def play_file(self, file_name):
908870
while audio.playing:
909871
pass
910872
self._speaker_enable.value = False
873+
874+
875+
class _PixelMapLite:
876+
"""Generate a pixel map based on a specified order. Designed to work with a set of 12 pixels,
877+
e.g. the MacroPad keypad LEDs.
878+
879+
:param pixels: The pixel object.
880+
:param tuple order: The specified order of the pixels. Pixels are numbered 0-11. Defaults to
881+
numerical order, ``0`` to ``11``.
882+
"""
883+
884+
def __init__(self, pixels, order=(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)):
885+
self._pixels = pixels
886+
self._order = order
887+
self._num_pixels = len(self._pixels)
888+
889+
# Copy methods from _pixels
890+
for attr in dir(pixels):
891+
if not attr.startswith("__") or attr in ("__enter__", "__exit__"):
892+
setattr(self, attr, getattr(pixels, attr))
893+
894+
def __setitem__(self, index, val):
895+
if isinstance(index, slice):
896+
for val_i, in_i in enumerate(range(*index.indices(self._num_pixels))):
897+
self._pixels[in_i] = self._order[val_i]
898+
else:
899+
self._pixels[self._order[index]] = val
900+
901+
def __getitem__(self, index):
902+
if isinstance(index, slice):
903+
return [
904+
self._pixels[self._order[idx]]
905+
for idx in range(*index.indices(self._num_pixels))
906+
]
907+
if index < 0:
908+
index += self._num_pixels
909+
if index >= self._num_pixels or index < 0:
910+
raise IndexError
911+
return self._pixels[self._order[index]]
912+
913+
def __repr__(self):
914+
return self._pixels.__repr__()

0 commit comments

Comments
 (0)