99* Author(s): Brent Rubell
1010"""
1111import board
12- import digitalio
1312from micropython import const
1413import analogio
15- from gamepadshift import GamePadShift
14+ from keypad import ShiftRegisterKeys , Event
1615from adafruit_debouncer import Debouncer
1716
17+ __version__ = "0.0.0-auto.0"
18+ __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_CursorControl.git"
19+
20+
1821# PyBadge
19- PYBADGE_BUTTON_LEFT = const (128 )
20- PYBADGE_BUTTON_UP = const (64 )
21- PYBADGE_BUTTON_DOWN = const (32 )
22- PYBADGE_BUTTON_RIGHT = const (16 )
22+ PYBADGE_BUTTON_LEFT = const (7 )
23+ PYBADGE_BUTTON_UP = const (6 )
24+ PYBADGE_BUTTON_DOWN = const (5 )
25+ PYBADGE_BUTTON_RIGHT = const (4 )
2326# PyBadge & PyGamer
24- PYBADGE_BUTTON_A = const (2 )
27+ PYBADGE_BUTTON_A = const (1 )
2528
2629
2730class CursorManager :
@@ -33,6 +36,8 @@ class CursorManager:
3336 def __init__ (self , cursor ):
3437 self ._cursor = cursor
3538 self ._is_clicked = False
39+ self ._pad_states = 0
40+ self ._event = Event ()
3641 self ._init_hardware ()
3742
3843 def __enter__ (self ):
@@ -47,6 +52,7 @@ def deinit(self):
4752 self ._pad .deinit ()
4853 self ._cursor .deinit ()
4954 self ._cursor = None
55+ self ._event = None
5056
5157 def _is_deinited (self ):
5258 """Checks if CursorManager object has been deinitd."""
@@ -66,6 +72,7 @@ def _init_hardware(self):
6672 "btn_down" : PYBADGE_BUTTON_DOWN ,
6773 "btn_a" : PYBADGE_BUTTON_A ,
6874 }
75+ self ._pad_states = 0
6976 elif hasattr (board , "JOYSTICK_X" ):
7077 self ._joystick_x = analogio .AnalogIn (board .JOYSTICK_X )
7178 self ._joystick_y = analogio .AnalogIn (board .JOYSTICK_Y )
@@ -77,10 +84,12 @@ def _init_hardware(self):
7784 raise AttributeError (
7885 "Board must have a D-Pad or Joystick for use with CursorManager!"
7986 )
80- self ._pad = GamePadShift (
81- digitalio .DigitalInOut (board .BUTTON_CLOCK ),
82- digitalio .DigitalInOut (board .BUTTON_OUT ),
83- digitalio .DigitalInOut (board .BUTTON_LATCH ),
87+ self ._pad = ShiftRegisterKeys (
88+ clock = board .BUTTON_CLOCK ,
89+ data = board .BUTTON_OUT ,
90+ latch = board .BUTTON_LATCH ,
91+ key_count = 8 ,
92+ value_when_pressed = True ,
8493 )
8594
8695 @property
@@ -92,11 +101,12 @@ def is_clicked(self):
92101
93102 def update (self ):
94103 """Updates the cursor object."""
95- pressed = self ._pad .get_pressed ()
96- self ._check_cursor_movement (pressed )
104+ if self ._pad .events .get_into (self ._event ):
105+ self ._store_button_states ()
106+ self ._check_cursor_movement ()
97107 if self ._is_clicked :
98108 self ._is_clicked = False
99- elif pressed & self ._pad_btns ["btn_a" ]:
109+ elif self . _pad_states & ( 1 << self ._pad_btns ["btn_a" ]) :
100110 self ._is_clicked = True
101111
102112 def _read_joystick_x (self , samples = 3 ):
@@ -106,7 +116,7 @@ def _read_joystick_x(self, samples=3):
106116 reading = 0
107117 # pylint: disable=unused-variable
108118 if hasattr (board , "JOYSTICK_X" ):
109- for sample in range (0 , samples ):
119+ for _ in range (0 , samples ):
110120 reading += self ._joystick_x .value
111121 reading /= samples
112122 return reading
@@ -118,24 +128,33 @@ def _read_joystick_y(self, samples=3):
118128 reading = 0
119129 # pylint: disable=unused-variable
120130 if hasattr (board , "JOYSTICK_Y" ):
121- for sample in range (0 , samples ):
131+ for _ in range (0 , samples ):
122132 reading += self ._joystick_y .value
123133 reading /= samples
124134 return reading
125135
126- def _check_cursor_movement (self , pressed = None ):
127- """Checks the PyBadge D-Pad or the PyGamer's Joystick for movement.
128- :param int pressed: 8-bit number with bits that correspond to buttons
129- which have been pressed down since the last call to get_pressed().
136+ def _store_button_states (self ):
137+ """Stores the state of the PyBadge's D-Pad or the PyGamer's Joystick
138+ into a byte
139+
140+ :param Event event: The latest button press transition event detected.
130141 """
142+ bit_index = self ._event .key_number
143+ current_state = (self ._pad_states >> bit_index ) & 1
144+ if current_state != self ._event .pressed :
145+ self ._pad_states = (1 << bit_index ) ^ self ._pad_states
146+
147+ def _check_cursor_movement (self ):
148+ """Checks the PyBadge D-Pad or the PyGamer's Joystick for movement."""
131149 if hasattr (board , "BUTTON_CLOCK" ) and not hasattr (board , "JOYSTICK_X" ):
132- if pressed & self ._pad_btns ["btn_right" ]:
150+ if self . _pad_states & ( 1 << self ._pad_btns ["btn_right" ]) :
133151 self ._cursor .x += self ._cursor .speed
134- elif pressed & self ._pad_btns ["btn_left" ]:
152+ elif self . _pad_states & ( 1 << self ._pad_btns ["btn_left" ]) :
135153 self ._cursor .x -= self ._cursor .speed
136- if pressed & self ._pad_btns ["btn_up" ]:
154+
155+ if self ._pad_states & (1 << self ._pad_btns ["btn_up" ]):
137156 self ._cursor .y -= self ._cursor .speed
138- elif pressed & self ._pad_btns ["btn_down" ]:
157+ elif self . _pad_states & ( 1 << self ._pad_btns ["btn_down" ]) :
139158 self ._cursor .y += self ._cursor .speed
140159 elif hasattr (board , "JOYSTICK_X" ):
141160 joy_x = self ._read_joystick_x ()
@@ -165,9 +184,8 @@ class DebouncedCursorManager(CursorManager):
165184
166185 def __init__ (self , cursor , debounce_interval = 0.01 ):
167186 CursorManager .__init__ (self , cursor )
168- self ._pressed = 0
169187 self ._debouncer = Debouncer (
170- lambda : bool (self ._pressed & self ._pad_btns ["btn_a" ]),
188+ lambda : bool (self ._pad_states & ( 1 << self ._pad_btns ["btn_a" ]) ),
171189 interval = debounce_interval ,
172190 )
173191
@@ -194,6 +212,7 @@ def held(self):
194212
195213 def update (self ):
196214 """Updates the cursor object."""
197- self ._pressed = self ._pad .get_pressed ()
198- self ._check_cursor_movement (self ._pressed )
215+ if self ._pad .events .get_into (self ._event ):
216+ self ._store_button_states ()
217+ self ._check_cursor_movement ()
199218 self ._debouncer .update ()
0 commit comments