fixed broken out toggle key

This commit is contained in:
2022-01-09 20:44:51 +01:00
parent b75fc313c1
commit 5630bb8154
4 changed files with 58 additions and 56 deletions

View File

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

View File

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

View File

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