@@ -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