From 99577357f6d53448dea4e7249456a198893192b2 Mon Sep 17 00:00:00 2001 From: Christian Tu Date: Sat, 25 Sep 2021 11:07:33 +0200 Subject: [PATCH] move HoldTap to its own file --- kmk/modules/holdtap.py | 118 ++++++++++++++++++++++++++++++++++++++++ kmk/modules/layers.py | 2 +- kmk/modules/modtap.py | 119 +---------------------------------------- 3 files changed, 120 insertions(+), 119 deletions(-) create mode 100644 kmk/modules/holdtap.py diff --git a/kmk/modules/holdtap.py b/kmk/modules/holdtap.py new file mode 100644 index 0000000..77dd4e9 --- /dev/null +++ b/kmk/modules/holdtap.py @@ -0,0 +1,118 @@ +from micropython import const + +from kmk.modules import Module + + +class ActivationType: + NOT_ACTIVATED = const(0) + HOLD_TIMEOUT = const(1) + INTERRUPTED = const(2) + + +class HoldTapKeyState: + def __init__(self, timeout_key, *args, **kwargs): + self.timeout_key = timeout_key + self.args = args + self.kwargs = kwargs + self.activated = ActivationType.NOT_ACTIVATED + + +class HoldTap(Module): + def __init__(self): + self.key_states = {} + + def during_bootup(self, keyboard): + return + + def before_matrix_scan(self, keyboard): + return + + def after_matrix_scan(self, keyboard): + '''Before other key down decide to send tap kc down.''' + if self.matrix_detected_press(keyboard): + for key, state in self.key_states.items(): + if state.activated == ActivationType.NOT_ACTIVATED: + # press tap because interrupted by other key + self.key_states[key].activated = ActivationType.INTERRUPTED + self.ht_activate_on_interrupt( + key, keyboard, *state.args, **state.kwargs + ) + if keyboard.hid_pending: + keyboard._send_hid() + return + + def before_hid_send(self, keyboard): + return + + def after_hid_send(self, keyboard): + return + + def on_powersave_enable(self, keyboard): + return + + def on_powersave_disable(self, keyboard): + return + + def matrix_detected_press(self, keyboard): + return (keyboard.matrix_update is not None and keyboard.matrix_update[2]) or ( + keyboard.secondary_matrix_update is not None + and keyboard.secondary_matrix_update[2] + ) + + def ht_pressed(self, key, keyboard, *args, **kwargs): + '''Do nothing yet, action resolves when key is released, timer expires or other key is pressed.''' + timeout_key = keyboard.set_timeout( + keyboard.tap_time, + lambda: self.on_tap_time_expired(key, keyboard, *args, **kwargs), + ) + self.key_states[key] = HoldTapKeyState(timeout_key, *args, **kwargs) + return keyboard + + def ht_released(self, key, keyboard, *args, **kwargs): + '''On keyup, release mod or tap key.''' + if key in self.key_states: + state = self.key_states[key] + keyboard.cancel_timeout(state.timeout_key) + if state.activated == ActivationType.HOLD_TIMEOUT: + # release hold + self.ht_deactivate_hold(key, keyboard, *args, **kwargs) + elif state.activated == ActivationType.INTERRUPTED: + # release tap + self.ht_deactivate_on_interrupt(key, keyboard, *args, **kwargs) + else: + # press and release tap because key released within tap time + self.ht_activate_tap(key, keyboard, *args, **kwargs) + keyboard.set_timeout( + False, + lambda: self.ht_deactivate_tap(key, keyboard, *args, **kwargs), + ) + del self.key_states[key] + return keyboard + + def on_tap_time_expired(self, key, keyboard, *args, **kwargs): + '''When tap time expires activate mod if key is still being pressed.''' + if ( + key in self.key_states + and self.key_states[key].activated == ActivationType.NOT_ACTIVATED + ): + # press hold because timer expired after tap time + self.key_states[key].activated = ActivationType.HOLD_TIMEOUT + self.ht_activate_hold(key, keyboard, *args, **kwargs) + + def ht_activate_hold(self, key, keyboard, *args, **kwargs): + pass + + def ht_deactivate_hold(self, key, keyboard, *args, **kwargs): + pass + + def ht_activate_tap(self, key, keyboard, *args, **kwargs): + pass + + def ht_deactivate_tap(self, key, keyboard, *args, **kwargs): + pass + + def ht_activate_on_interrupt(self, key, keyboard, *args, **kwargs): + self.ht_activate_tap(key, keyboard, *args, **kwargs) + + def ht_deactivate_on_interrupt(self, key, keyboard, *args, **kwargs): + self.ht_deactivate_tap(key, keyboard, *args, **kwargs) diff --git a/kmk/modules/layers.py b/kmk/modules/layers.py index d669aef..c369476 100644 --- a/kmk/modules/layers.py +++ b/kmk/modules/layers.py @@ -3,7 +3,7 @@ from micropython import const from kmk.key_validators import layer_key_validator from kmk.keys import make_argumented_key -from kmk.modules.modtap import HoldTap +from kmk.modules.holdtap import HoldTap class LayerType: diff --git a/kmk/modules/modtap.py b/kmk/modules/modtap.py index e619386..6b31a73 100644 --- a/kmk/modules/modtap.py +++ b/kmk/modules/modtap.py @@ -1,123 +1,6 @@ -from micropython import const - from kmk.key_validators import mod_tap_validator from kmk.keys import make_argumented_key -from kmk.modules import Module - - -class ActivationType: - NOT_ACTIVATED = const(0) - HOLD_TIMEOUT = const(1) - INTERRUPTED = const(2) - - -class HoldTapKeyState: - def __init__(self, timeout_key, *args, **kwargs): - self.timeout_key = timeout_key - self.args = args - self.kwargs = kwargs - self.activated = ActivationType.NOT_ACTIVATED - - -class HoldTap(Module): - def __init__(self): - self.key_states = {} - - def during_bootup(self, keyboard): - return - - def before_matrix_scan(self, keyboard): - return - - def after_matrix_scan(self, keyboard): - '''Before other key down decide to send tap kc down.''' - if self.matrix_detected_press(keyboard): - for key, state in self.key_states.items(): - if state.activated == ActivationType.NOT_ACTIVATED: - # press tap because interrupted by other key - self.key_states[key].activated = ActivationType.INTERRUPTED - self.ht_activate_on_interrupt( - key, keyboard, *state.args, **state.kwargs - ) - if keyboard.hid_pending: - keyboard._send_hid() - return - - def before_hid_send(self, keyboard): - return - - def after_hid_send(self, keyboard): - return - - def on_powersave_enable(self, keyboard): - return - - def on_powersave_disable(self, keyboard): - return - - def matrix_detected_press(self, keyboard): - return (keyboard.matrix_update is not None and keyboard.matrix_update[2]) or ( - keyboard.secondary_matrix_update is not None - and keyboard.secondary_matrix_update[2] - ) - - def ht_pressed(self, key, keyboard, *args, **kwargs): - '''Do nothing yet, action resolves when key is released, timer expires or other key is pressed.''' - timeout_key = keyboard.set_timeout( - keyboard.tap_time, - lambda: self.on_tap_time_expired(key, keyboard, *args, **kwargs), - ) - self.key_states[key] = HoldTapKeyState(timeout_key, *args, **kwargs) - return keyboard - - def ht_released(self, key, keyboard, *args, **kwargs): - '''On keyup, release mod or tap key.''' - if key in self.key_states: - state = self.key_states[key] - keyboard.cancel_timeout(state.timeout_key) - if state.activated == ActivationType.HOLD_TIMEOUT: - # release hold - self.ht_deactivate_hold(key, keyboard, *args, **kwargs) - elif state.activated == ActivationType.INTERRUPTED: - # release tap - self.ht_deactivate_on_interrupt(key, keyboard, *args, **kwargs) - else: - # press and release tap because key released within tap time - self.ht_activate_tap(key, keyboard, *args, **kwargs) - keyboard.set_timeout( - False, - lambda: self.ht_deactivate_tap(key, keyboard, *args, **kwargs), - ) - del self.key_states[key] - return keyboard - - def on_tap_time_expired(self, key, keyboard, *args, **kwargs): - '''When tap time expires activate mod if key is still being pressed.''' - if ( - key in self.key_states - and self.key_states[key].activated == ActivationType.NOT_ACTIVATED - ): - # press hold because timer expired after tap time - self.key_states[key].activated = ActivationType.HOLD_TIMEOUT - self.ht_activate_hold(key, keyboard, *args, **kwargs) - - def ht_activate_hold(self, key, keyboard, *args, **kwargs): - pass - - def ht_deactivate_hold(self, key, keyboard, *args, **kwargs): - pass - - def ht_activate_tap(self, key, keyboard, *args, **kwargs): - pass - - def ht_deactivate_tap(self, key, keyboard, *args, **kwargs): - pass - - def ht_activate_on_interrupt(self, key, keyboard, *args, **kwargs): - self.ht_activate_tap(key, keyboard, *args, **kwargs) - - def ht_deactivate_on_interrupt(self, key, keyboard, *args, **kwargs): - self.ht_deactivate_tap(key, keyboard, *args, **kwargs) +from kmk.modules.holdtap import HoldTap class ModTap(HoldTap):