continued to break out keys
This commit is contained in:
14
keyboard.py
14
keyboard.py
@@ -140,8 +140,8 @@ class Keyboard:
|
||||
io_extenders = self.initialize_io_extenders(io_extenders_pinout)
|
||||
self.pins = self.initialize_pins(io_extenders, pinout)
|
||||
|
||||
test_keymap(keymap, debug_repl)
|
||||
self.keymap = keymap
|
||||
self.keymap = self._initialize_keymap(keymap)
|
||||
|
||||
self.layer_colors = layer_colors
|
||||
self.layer = LayerState()
|
||||
|
||||
@@ -150,6 +150,13 @@ class Keyboard:
|
||||
if debug_repl:
|
||||
print("Done initializing keyboard")
|
||||
|
||||
def _initialize_keymap(self, keymap: list[list[KeyBase]]) -> list[list[KeyBase]]:
|
||||
test_keymap(keymap, True)
|
||||
for layer in keymap:
|
||||
for key in layer:
|
||||
key.enrich(layer.index(key), keymap.index(layer))
|
||||
return keymap
|
||||
|
||||
def initialize_hid(self) -> tuple[usb_hid.Device, usb_hid.Device]:
|
||||
"""Initializes keyboard and media device if availabe"""
|
||||
for device in usb_hid.devices:
|
||||
@@ -194,6 +201,9 @@ class Keyboard:
|
||||
self.pressed_keys = set()
|
||||
self.pressed_keys_last_cycle = set()
|
||||
|
||||
def get_key(self, layer_index, key_index) -> KeyBase:
|
||||
return self.keymap[layer_index][key_index]
|
||||
|
||||
def start(self):
|
||||
if self.debug_repl:
|
||||
print("Starting keyboard")
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from keycodes import SE
|
||||
from keytypes import Hold, Keycode, Modifier, Toggle
|
||||
|
||||
|
||||
keymap = [[
|
||||
Hold(1), Toggle(2), Toggle(3), Toggle(4),
|
||||
Toggle(0), Keycode(SE.B), Keycode(SE.C), Keycode(SE.D),
|
||||
|
||||
217
keytypes.py
217
keytypes.py
@@ -27,31 +27,45 @@ class KeyEvents:
|
||||
current: int
|
||||
previous: int
|
||||
|
||||
def __init__(self, current: int, previous: int):
|
||||
self.current = current
|
||||
self.previous = previous
|
||||
def __init__(self):
|
||||
self.current = KeyEvent.RELEASED
|
||||
self.previous = KeyEvent.RELEASED
|
||||
|
||||
def shift(self, next):
|
||||
print(
|
||||
f"next: {next}, current: {self.current}, previous: {self.previous}")
|
||||
self.previous = self.current
|
||||
self.current = next
|
||||
|
||||
|
||||
class KeyBase:
|
||||
event: int
|
||||
events: KeyEvents
|
||||
allowed_events: list[KeyEvent]
|
||||
key_index: int
|
||||
layer_index: int
|
||||
|
||||
def __init__(self, allowed_events: list[int]):
|
||||
self.allowed_events = allowed_events
|
||||
self.event = KeyEvent.NO_EVENT
|
||||
self.events = KeyEvents()
|
||||
self.key_index = None
|
||||
self.layer_index = None
|
||||
|
||||
def _validate_next_event(self, event: int):
|
||||
if event is None or event not in self.allowed_events:
|
||||
def enrich(self, key_index: int, layer_index: int):
|
||||
self.key_index = key_index
|
||||
self.layer_index = layer_index
|
||||
|
||||
def _validate_next_event(self, next_event: int):
|
||||
if next_event is None or next_event not in self.allowed_events:
|
||||
raise Exception(
|
||||
f"KeyEvent with value of {event} is not a valid event for this type of key")
|
||||
f"KeyEvent with value of {next_event} is not a valid event for this type of key")
|
||||
|
||||
def _set_event(self, next: int) -> bool:
|
||||
def _set_event(self, next_event: int) -> bool:
|
||||
"""Sets previous state if new state is valid
|
||||
Returns: A boolean that determines if the state was updated or not"""
|
||||
self._validate_next_event(next)
|
||||
if next is KeyEvent.NO_EVENT:
|
||||
self._validate_next_event(next_event)
|
||||
if next_event is KeyEvent.NO_EVENT:
|
||||
return False
|
||||
self.event = next
|
||||
self.events.shift(next_event)
|
||||
return True
|
||||
|
||||
def handle(self, keyboard):
|
||||
@@ -81,53 +95,55 @@ class KeycodeBase(KeyBase):
|
||||
raise NotImplementedError
|
||||
|
||||
def soft_release(self, keyboard, pin):
|
||||
if self.events.current != KeyEvent.PRESSED_:
|
||||
return
|
||||
self._set_event(KeyEvent.SOFT_RELEASED)
|
||||
self._handle_event(keyboard)
|
||||
|
||||
def _consume_next_event(self, pin) -> bool:
|
||||
"""Returns: a boolean representing if the event property was updated with a new event or not"""
|
||||
pin_event = pin.read_event()
|
||||
previous = int(self.event)
|
||||
next = None
|
||||
if previous == KeyEvent.NO_EVENT:
|
||||
if pin_event == PinEvent.NO_EVENT:
|
||||
next = KeyEvent.NO_EVENT
|
||||
if pin_event == PinEvent.RELEASED:
|
||||
next = KeyEvent.RELEASED
|
||||
if pin_event == PinEvent.PRESSED:
|
||||
next = KeyEvent.PRESSED_
|
||||
if previous == KeyEvent.RELEASED:
|
||||
if pin_event == PinEvent.NO_EVENT:
|
||||
next = KeyEvent.NO_EVENT
|
||||
if pin_event == PinEvent.RELEASED:
|
||||
next = KeyEvent.NO_EVENT
|
||||
if pin_event == PinEvent.PRESSED:
|
||||
next = KeyEvent.PRESSED_
|
||||
if previous == KeyEvent.PRESSED_:
|
||||
if pin_event == PinEvent.NO_EVENT:
|
||||
next = KeyEvent.NO_EVENT
|
||||
if pin_event == PinEvent.RELEASED:
|
||||
next = KeyEvent.RELEASED
|
||||
if pin_event == PinEvent.PRESSED:
|
||||
next = KeyEvent.NO_EVENT
|
||||
if previous == KeyEvent.SOFT_RELEASED:
|
||||
if pin_event == PinEvent.NO_EVENT:
|
||||
next = KeyEvent.NO_EVENT
|
||||
if pin_event == PinEvent.RELEASED:
|
||||
next = KeyEvent.RELEASED
|
||||
if pin_event == PinEvent.PRESSED:
|
||||
next = KeyEvent.NO_EVENT
|
||||
next_pin_event = pin.read_event()
|
||||
current_key_event, previous_key_event = self.events.current, self.events.previous
|
||||
next_key_event = None
|
||||
if current_key_event == KeyEvent.NO_EVENT:
|
||||
if next_pin_event == PinEvent.NO_EVENT:
|
||||
next_key_event = KeyEvent.NO_EVENT
|
||||
if next_pin_event == PinEvent.RELEASED:
|
||||
next_key_event = KeyEvent.RELEASED
|
||||
if next_pin_event == PinEvent.PRESSED:
|
||||
next_key_event = KeyEvent.PRESSED_
|
||||
if current_key_event == KeyEvent.RELEASED:
|
||||
if next_pin_event == PinEvent.NO_EVENT:
|
||||
next_key_event = KeyEvent.NO_EVENT
|
||||
if next_pin_event == PinEvent.RELEASED:
|
||||
next_key_event = KeyEvent.NO_EVENT
|
||||
if next_pin_event == PinEvent.PRESSED:
|
||||
next_key_event = KeyEvent.PRESSED_
|
||||
if current_key_event == KeyEvent.PRESSED_:
|
||||
if next_pin_event == PinEvent.NO_EVENT:
|
||||
next_key_event = KeyEvent.NO_EVENT
|
||||
if next_pin_event == PinEvent.RELEASED:
|
||||
next_key_event = KeyEvent.RELEASED
|
||||
if next_pin_event == PinEvent.PRESSED:
|
||||
next_key_event = KeyEvent.NO_EVENT
|
||||
if current_key_event == KeyEvent.SOFT_RELEASED:
|
||||
if next_pin_event == PinEvent.NO_EVENT:
|
||||
next_key_event = KeyEvent.NO_EVENT
|
||||
if next_pin_event == PinEvent.RELEASED:
|
||||
next_key_event = KeyEvent.RELEASED
|
||||
if next_pin_event == PinEvent.PRESSED:
|
||||
next_key_event = KeyEvent.NO_EVENT
|
||||
|
||||
return self._set_event(next)
|
||||
return self._set_event(next_key_event)
|
||||
|
||||
def _handle_event(self, keyboard) -> None:
|
||||
if self.event == KeyEvent.NO_EVENT:
|
||||
current = self.events.current
|
||||
if current == KeyEvent.NO_EVENT:
|
||||
return
|
||||
if self.event == KeyEvent.PRESSED_:
|
||||
if current == KeyEvent.PRESSED_:
|
||||
keyboard.add_keycode_to_report(self.keycode)
|
||||
if self.event == KeyEvent.RELEASED:
|
||||
if current == KeyEvent.RELEASED:
|
||||
keyboard.remove_keycode_from_report(self.keycode)
|
||||
if self.event == KeyEvent.SOFT_RELEASED:
|
||||
if current == KeyEvent.SOFT_RELEASED:
|
||||
keyboard.remove_keycode_from_report(self.keycode)
|
||||
|
||||
def handle(self, keyboard, pin):
|
||||
@@ -155,11 +171,11 @@ class Modifier(KeycodeBase):
|
||||
|
||||
|
||||
class LayerKeyBase(KeyBase):
|
||||
layer: int
|
||||
layer_to_switch_to: int
|
||||
|
||||
def __init__(self, layer: int, allowed_events):
|
||||
super().__init__(allowed_events)
|
||||
self.layer = layer
|
||||
self.layer_to_switch_to = layer
|
||||
|
||||
|
||||
class Toggle(LayerKeyBase):
|
||||
@@ -171,52 +187,43 @@ class Toggle(LayerKeyBase):
|
||||
KeyEvent.PRESSED_TOGGLED_OFF,
|
||||
KeyEvent.RELEASED,
|
||||
KeyEvent.SOFT_RELEASED]
|
||||
has_received_state_from = None
|
||||
super().__init__(layer, allowed_events)
|
||||
|
||||
def _consume_next_event(self, pin: Pin) -> bool:
|
||||
"""Returns: a boolean representing if the event property was updated with a new event or not"""
|
||||
next_pin_event = pin.read_event()
|
||||
previous = self.event
|
||||
next = None
|
||||
print(f"toggle stuff: {previous}")
|
||||
current_key_event = self.events.current
|
||||
|
||||
if previous == KeyEvent.NO_EVENT:
|
||||
if next_pin_event == PinEvent.NO_EVENT:
|
||||
next = KeyEvent.NO_EVENT
|
||||
if next_pin_event == PinEvent.NO_EVENT:
|
||||
return self._set_event(KeyEvent.NO_EVENT)
|
||||
if current_key_event == KeyEvent.PRESSED_TOGGLED_ON:
|
||||
if next_pin_event == PinEvent.PRESSED:
|
||||
next = KeyEvent.PRESSED_TOGGLED_ON
|
||||
return self._set_event(KeyEvent.NO_EVENT)
|
||||
if next_pin_event == PinEvent.RELEASED:
|
||||
next = KeyEvent.RELEASED
|
||||
if previous == KeyEvent.PRESSED_TOGGLED_ON:
|
||||
if next_pin_event == PinEvent.NO_EVENT:
|
||||
next = KeyEvent.NO_EVENT
|
||||
return self._set_event(KeyEvent.RELEASED_TOGGLED_ON)
|
||||
if current_key_event == KeyEvent.RELEASED_TOGGLED_ON:
|
||||
if next_pin_event == PinEvent.PRESSED:
|
||||
next = KeyEvent.NO_EVENT
|
||||
return self._set_event(KeyEvent.PRESSED_TOGGLED_OFF)
|
||||
if next_pin_event == PinEvent.RELEASED:
|
||||
next = KeyEvent.RELEASED_TOGGLED_ON
|
||||
if previous == KeyEvent.RELEASED_TOGGLED_ON:
|
||||
if next_pin_event == PinEvent.NO_EVENT:
|
||||
next = KeyEvent.NO_EVENT
|
||||
return self._set_event(KeyEvent.NO_EVENT)
|
||||
if current_key_event == KeyEvent.PRESSED_TOGGLED_OFF:
|
||||
if next_pin_event == PinEvent.PRESSED:
|
||||
next = KeyEvent.PRESSED_TOGGLED_OFF
|
||||
return self._set_event(KeyEvent.NO_EVENT)
|
||||
if next_pin_event == PinEvent.RELEASED:
|
||||
next = KeyEvent.NO_EVENT
|
||||
if previous == KeyEvent.PRESSED_TOGGLED_OFF:
|
||||
if next_pin_event == PinEvent.NO_EVENT:
|
||||
next = KeyEvent.NO_EVENT
|
||||
return self._set_event(KeyEvent.RELEASED)
|
||||
if current_key_event == KeyEvent.RELEASED:
|
||||
if next_pin_event == PinEvent.PRESSED:
|
||||
next = KeyEvent.NO_EVENT
|
||||
return self._set_event(KeyEvent.PRESSED_TOGGLED_ON)
|
||||
if next_pin_event == PinEvent.RELEASED:
|
||||
next = KeyEvent.RELEASED
|
||||
if previous == KeyEvent.RELEASED:
|
||||
if next_pin_event == PinEvent.NO_EVENT:
|
||||
next = KeyEvent.NO_EVENT
|
||||
if next_pin_event == PinEvent.PRESSED:
|
||||
next = KeyEvent.PRESSED_TOGGLED_ON
|
||||
return self._set_event(KeyEvent.NO_EVENT)
|
||||
if current_key_event == KeyEvent.SOFT_RELEASED:
|
||||
if next_pin_event == PinEvent.RELEASED:
|
||||
next = KeyEvent.NO_EVENT
|
||||
return self._set_event(KeyEvent.RELEASED)
|
||||
else:
|
||||
return self._set_event(KeyEvent.NO_EVENT)
|
||||
|
||||
return self._set_event(next)
|
||||
raise NotImplementedError()
|
||||
|
||||
def _release_all_other_keys(self, keyboard, pin: Pin):
|
||||
for layer in keyboard.keymap:
|
||||
@@ -227,14 +234,18 @@ class Toggle(LayerKeyBase):
|
||||
key.soft_release(keyboard, pin_of_key)
|
||||
|
||||
def _handle_event(self, keyboard, pin):
|
||||
if self.event == KeyEvent.PRESSED_TOGGLED_ON:
|
||||
keyboard.layer.toggle(self.layer)
|
||||
current = self.events.current
|
||||
if current == KeyEvent.PRESSED_TOGGLED_ON:
|
||||
keyboard.layer.toggle(self.layer_to_switch_to)
|
||||
self._release_all_other_keys(keyboard, pin)
|
||||
if self.event == KeyEvent.RELEASED_TOGGLED_ON:
|
||||
self._swap_state(keyboard)
|
||||
if current == KeyEvent.RELEASED_TOGGLED_ON:
|
||||
pass
|
||||
if self.event == KeyEvent.PRESSED_TOGGLED_OFF:
|
||||
keyboard.layer.release_toggled(self.layer)
|
||||
if self.event == KeyEvent.RELEASED:
|
||||
if current == KeyEvent.PRESSED_TOGGLED_OFF:
|
||||
keyboard.layer.release_toggled()
|
||||
self._release_all_other_keys(keyboard, pin)
|
||||
self._swap_state_back(keyboard)
|
||||
if current == KeyEvent.RELEASED:
|
||||
pass
|
||||
|
||||
def handle(self, keyboard, pin: Pin):
|
||||
@@ -246,7 +257,37 @@ class Toggle(LayerKeyBase):
|
||||
raise NotImplementedError()
|
||||
|
||||
def soft_release(self, keyboard, pin):
|
||||
pass
|
||||
pressed = self.events.current not in [
|
||||
KeyEvent.RELEASED, KeyEvent.PRESSED_TOGGLED_OFF, KeyEvent.SOFT_RELEASED]
|
||||
if not pressed:
|
||||
return
|
||||
print(f"releasing {keyboard}, {self.events.current}")
|
||||
self.has_received_state_from = None
|
||||
self._set_event(KeyEvent.SOFT_RELEASED)
|
||||
|
||||
def _swap_state(self, keyboard) -> None:
|
||||
key_to_swap_with = keyboard.get_key(
|
||||
self.layer_to_switch_to, self.key_index)
|
||||
other_keys_state = key_to_swap_with._handle_on_swap_state(
|
||||
self.events, (self.layer_index, self.key_index))
|
||||
self.events = other_keys_state
|
||||
|
||||
def _swap_state_back(self, keyboard) -> None:
|
||||
if not self.has_received_state_from:
|
||||
return
|
||||
key_to_swap_with = keyboard.get_key(
|
||||
self.has_received_state_from[0], self.has_received_state_from[1])
|
||||
other_keys_state = key_to_swap_with._handle_on_swap_state(
|
||||
self.events, None)
|
||||
self.events = other_keys_state
|
||||
|
||||
def _handle_on_swap_state(self, received_state: KeyEvents, indexes: tuple[int, int]) -> KeyEvents:
|
||||
"""Invoked on the Toggle key that is present on the layer another Toggle key is switching to
|
||||
Makes sure that the state is carried over so that pressing the button once more returns to the old layer."""
|
||||
self.has_received_state_from = indexes
|
||||
state_to_send_back = self.events
|
||||
self.events = received_state
|
||||
return state_to_send_back
|
||||
|
||||
# todo: Release all keys not the same as the old layer
|
||||
# todo: Debounce old toggle when pressing new toggle
|
||||
|
||||
Reference in New Issue
Block a user