fixed broken out toggle key
This commit is contained in:
@@ -226,6 +226,7 @@ class Keyboard:
|
||||
if self.pressed_keys != self.pressed_keys_last_cycle:
|
||||
self.send_nkro_report()
|
||||
self.pressed_keys_last_cycle = set(self.pressed_keys)
|
||||
|
||||
except Exception as e:
|
||||
if self.debug_repl:
|
||||
raise e
|
||||
|
||||
23
keymap.py
23
keymap.py
@@ -1,30 +1,33 @@
|
||||
from keycodes import SE
|
||||
from keytypes import Hold, Keycode, Modifier, Toggle
|
||||
from layer_manager import LayerManager
|
||||
|
||||
lm = LayerManager(5)
|
||||
|
||||
keymap = [[
|
||||
Hold(1), Toggle(2), Toggle(3), Toggle(4),
|
||||
Toggle(0), Keycode(SE.B), Keycode(SE.C), Keycode(SE.D),
|
||||
lm.hold(1), lm.toggle(2), lm.toggle(3), lm.toggle(4),
|
||||
lm.toggle(0), Keycode(SE.B), Keycode(SE.C), Keycode(SE.D),
|
||||
Keycode(SE.E), Keycode(SE.F), Keycode(SE.G), Keycode(SE.H),
|
||||
Keycode(SE.I), Keycode(SE.J), Keycode(
|
||||
SE.K), Modifier(SE.LEFT_SHIFT)
|
||||
], [
|
||||
Hold(1), Toggle(2), Toggle(3), Toggle(4),
|
||||
Keycode(SE.ONE), Hold(1), Keycode(SE.C), Keycode(SE.D),
|
||||
lm.hold(1), lm.toggle(2), lm.toggle(3), lm.toggle(4),
|
||||
Keycode(SE.ONE), lm.hold(1), Keycode(SE.C), Keycode(SE.D),
|
||||
Keycode(SE.E), Keycode(SE.F), Keycode(SE.G), Keycode(SE.H),
|
||||
Keycode(SE.BACKSPACE), Keycode(SE.J), Keycode(SE.K), Keycode(SE.L)
|
||||
], [
|
||||
Hold(1), Toggle(2), Toggle(3), Toggle(4),
|
||||
Keycode(SE.A), Hold(1), Hold(2), Keycode(SE.D),
|
||||
lm.hold(1), lm.toggle(2), lm.toggle(3), lm.toggle(4),
|
||||
Keycode(SE.A), lm.hold(1), lm.hold(2), Keycode(SE.D),
|
||||
Keycode(SE.E), Keycode(SE.F), Keycode(SE.G), Keycode(SE.H),
|
||||
Keycode(SE.I), Keycode(SE.J), Keycode(SE.K), Keycode(SE.L)
|
||||
], [
|
||||
Hold(1), Toggle(2), Toggle(3), Toggle(4),
|
||||
Keycode(SE.A), Keycode(SE.B), Hold(2), Hold(3),
|
||||
lm.hold(1), lm.toggle(2), lm.toggle(3), lm.toggle(4),
|
||||
Keycode(SE.A), Keycode(SE.B), lm.hold(2), lm.hold(3),
|
||||
Keycode(SE.E), Keycode(SE.F), Keycode(SE.G), Keycode(SE.H),
|
||||
Keycode(SE.I), Keycode(SE.J), Keycode(SE.K), Keycode(SE.L)
|
||||
], [
|
||||
Hold(1), Toggle(2), Toggle(3), Toggle(4),
|
||||
Keycode(SE.A), Keycode(SE.B), Keycode(SE.C), Hold(3),
|
||||
lm.hold(1), lm.toggle(2), lm.toggle(3), lm.toggle(4),
|
||||
Keycode(SE.A), Keycode(SE.B), Keycode(SE.C), lm.hold(3),
|
||||
Keycode(SE.E), Keycode(SE.F), Keycode(SE.G), Keycode(SE.H),
|
||||
Keycode(SE.I), Keycode(SE.J), Keycode(SE.K), Modifier(SE.LEFT_ALT)
|
||||
]]
|
||||
|
||||
74
keytypes.py
74
keytypes.py
@@ -32,8 +32,6 @@ class KeyEvents:
|
||||
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
|
||||
|
||||
@@ -65,6 +63,8 @@ class KeyBase:
|
||||
self._validate_next_event(next_event)
|
||||
if next_event is KeyEvent.NO_EVENT:
|
||||
return False
|
||||
print(
|
||||
f"[{self.key_index}] next: {next_event}, current: {self.events.current}, previous: {self.events.previous}")
|
||||
self.events.shift(next_event)
|
||||
return True
|
||||
|
||||
@@ -74,7 +74,7 @@ class KeyBase:
|
||||
def self_test(self, keymap: list[list[object]]):
|
||||
raise NotImplementedError()
|
||||
|
||||
def soft_release(self, keyboard, pin):
|
||||
def soft_release(self, keyboard):
|
||||
"""Release key programatically and wait until it's released physically before registrating additional key presses"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@@ -187,16 +187,29 @@ 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()
|
||||
current_key_event = self.events.current
|
||||
current_key_event, previous_key_event = self.events.current, self.events.previous
|
||||
|
||||
# First handle if key is in soft release mode
|
||||
if current_key_event == KeyEvent.SOFT_RELEASED:
|
||||
if previous_key_event == KeyEvent.RELEASED:
|
||||
return self._set_event(KeyEvent.RELEASED)
|
||||
if previous_key_event == KeyEvent.RELEASED_TOGGLED_ON:
|
||||
return self._set_event(KeyEvent.RELEASED)
|
||||
if next_pin_event == PinEvent.RELEASED:
|
||||
return self._set_event(KeyEvent.RELEASED)
|
||||
else:
|
||||
return self._set_event(KeyEvent.NO_EVENT)
|
||||
|
||||
# After that all no events from the pin is handled in the same way
|
||||
if next_pin_event == PinEvent.NO_EVENT:
|
||||
return self._set_event(KeyEvent.NO_EVENT)
|
||||
|
||||
# Then handle each event transition emulating a trigger key
|
||||
if current_key_event == KeyEvent.PRESSED_TOGGLED_ON:
|
||||
if next_pin_event == PinEvent.PRESSED:
|
||||
return self._set_event(KeyEvent.NO_EVENT)
|
||||
@@ -217,36 +230,31 @@ class Toggle(LayerKeyBase):
|
||||
return self._set_event(KeyEvent.PRESSED_TOGGLED_ON)
|
||||
if next_pin_event == PinEvent.RELEASED:
|
||||
return self._set_event(KeyEvent.NO_EVENT)
|
||||
if current_key_event == KeyEvent.SOFT_RELEASED:
|
||||
if next_pin_event == PinEvent.RELEASED:
|
||||
return self._set_event(KeyEvent.RELEASED)
|
||||
else:
|
||||
return self._set_event(KeyEvent.NO_EVENT)
|
||||
|
||||
raise NotImplementedError()
|
||||
|
||||
def _release_all_other_keys(self, keyboard, pin: Pin):
|
||||
def _release_all_other_keys(self, keyboard):
|
||||
for layer in keyboard.keymap:
|
||||
for key in layer:
|
||||
if key is self:
|
||||
continue
|
||||
pin_of_key = keyboard.pins[layer.index(key)]
|
||||
key.soft_release(keyboard, pin_of_key)
|
||||
key.soft_release(keyboard)
|
||||
|
||||
def _handle_event(self, keyboard, pin):
|
||||
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)
|
||||
self._swap_state(keyboard)
|
||||
self._release_all_other_keys(keyboard)
|
||||
return
|
||||
if current == KeyEvent.RELEASED_TOGGLED_ON:
|
||||
pass
|
||||
return
|
||||
if current == KeyEvent.PRESSED_TOGGLED_OFF:
|
||||
keyboard.layer.release_toggled()
|
||||
self._release_all_other_keys(keyboard, pin)
|
||||
self._swap_state_back(keyboard)
|
||||
self._release_all_other_keys(keyboard)
|
||||
return
|
||||
if current == KeyEvent.RELEASED:
|
||||
pass
|
||||
return
|
||||
raise NotImplementedError()
|
||||
|
||||
def handle(self, keyboard, pin: Pin):
|
||||
if not self._consume_next_event(pin):
|
||||
@@ -256,39 +264,13 @@ class Toggle(LayerKeyBase):
|
||||
def self_test(self, keymap: list[list[object]]):
|
||||
raise NotImplementedError()
|
||||
|
||||
def soft_release(self, keyboard, pin):
|
||||
def soft_release(self, keyboard):
|
||||
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
|
||||
# if type(key) is Toggle:
|
||||
|
||||
16
layer_manager.py
Normal file
16
layer_manager.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from keytypes import Hold, Toggle
|
||||
|
||||
|
||||
class LayerManager:
|
||||
holds: list[Hold]
|
||||
toggles: list[Toggle]
|
||||
|
||||
def __init__(self, number_of_layers: int):
|
||||
self.holds = [Hold(i) for i in range(0, number_of_layers)]
|
||||
self.toggles = [Toggle(i) for i in range(0, number_of_layers)]
|
||||
|
||||
def toggle(self, layer) -> Toggle:
|
||||
return self.toggles[layer]
|
||||
|
||||
def hold(self, layer) -> Hold:
|
||||
return self.holds[layer]
|
||||
Reference in New Issue
Block a user