Moved layers to extension

This commit is contained in:
Kyle Brown
2020-10-23 19:21:42 -07:00
parent a7b44699b5
commit 5e8c360de7
4 changed files with 167 additions and 171 deletions

View File

@@ -1,5 +1,6 @@
import board import board
from kmk.extensions.layers import Layers
from kmk.extensions.rgb import RGB from kmk.extensions.rgb import RGB
from kmk.extensions.split import Split from kmk.extensions.split import Split
from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard
@@ -29,5 +30,6 @@ class KMKKeyboard(_KMKKeyboard):
val_default=40, val_default=40,
animation_speed=1, animation_speed=1,
) )
layers_ext = Layers()
split = Split(uart_pin=board.SCL, split_offsets=[6, 6, 6, 6, 6]) split = Split(uart_pin=board.SCL, split_offsets=[6, 6, 6, 6, 6])
extensions = [rgb_ext, split] extensions = [rgb_ext, split, layers_ext]

164
kmk/extensions/layers.py Normal file
View File

@@ -0,0 +1,164 @@
import kmk.handlers.modtap as modtap
from kmk.extensions import Extension
from kmk.key_validators import layer_key_validator, mod_tap_validator
from kmk.keys import make_argumented_key
from kmk.kmktime import ticks_diff, ticks_ms
class Layers(Extension):
def __init__(self):
# Layers
make_argumented_key(
validator=layer_key_validator,
names=('MO',),
on_press=self.mo_pressed,
on_release=self.mo_released,
)
make_argumented_key(
validator=layer_key_validator, names=('DF',), on_press=self.df_pressed
)
make_argumented_key(
validator=layer_key_validator,
names=('LM',),
on_press=self.lm_pressed,
on_release=self.lm_released,
)
make_argumented_key(
validator=layer_key_validator,
names=('LT',),
on_press=self.lt_pressed,
on_release=self.lt_released,
)
make_argumented_key(
validator=layer_key_validator, names=('TG',), on_press=self.tg_pressed
)
make_argumented_key(
validator=layer_key_validator, names=('TO',), on_press=self.to_pressed
)
make_argumented_key(
validator=layer_key_validator,
names=('TT',),
on_press=self.tt_pressed,
on_release=self.tt_released,
)
make_argumented_key(
validator=mod_tap_validator,
names=('MT',),
on_press=modtap.mt_pressed,
on_release=modtap.mt_released,
)
def df_pressed(self, key, state, *args, **kwargs):
'''
Switches the default layer
'''
state._active_layers[-1] = key.meta.layer
return state
def mo_pressed(self, key, state, *args, **kwargs):
'''
Momentarily activates layer, switches off when you let go
'''
state._active_layers.insert(0, key.meta.layer)
return state
def mo_released(self, key, state, KC, *args, **kwargs):
# remove the first instance of the target layer
# from the active list
# under almost all normal use cases, this will
# disable the layer (but preserve it if it was triggered
# as a default layer, etc.)
# this also resolves an issue where using DF() on a layer
# triggered by MO() and then defaulting to the MO()'s layer
# would result in no layers active
try:
del_idx = state._active_layers.index(key.meta.layer)
del state._active_layers[del_idx]
except ValueError:
pass
return state
def lm_pressed(self, key, state, *args, **kwargs):
'''
As MO(layer) but with mod active
'''
state._hid_pending = True
# Sets the timer start and acts like MO otherwise
state._start_time['lm'] = ticks_ms()
state._keys_pressed.add(key.meta.kc)
return self.mo_pressed(key, state, *args, **kwargs)
def lm_released(self, key, state, *args, **kwargs):
'''
As MO(layer) but with mod active
'''
state._hid_pending = True
state._keys_pressed.discard(key.meta.kc)
state._start_time['lm'] = None
return self.mo_released(key, state, *args, **kwargs)
def lt_pressed(self, key, state, *args, **kwargs):
# Sets the timer start and acts like MO otherwise
state._start_time['lt'] = ticks_ms()
return self.mo_pressed(key, state, *args, **kwargs)
def lt_released(self, key, state, *args, **kwargs):
# On keyup, check timer, and press key if needed.
if state._start_time['lt'] and (
ticks_diff(ticks_ms(), state._start_time['lt']) < state.tap_time
):
state._hid_pending = True
state._tap_key(key.meta.kc)
self.mo_released(key, state, *args, **kwargs)
state._start_time['lt'] = None
return state
def tg_pressed(self, key, state, *args, **kwargs):
'''
Toggles the layer (enables it if not active, and vise versa)
'''
# See mo_released for implementation details around this
try:
del_idx = state._active_layers.index(key.meta.layer)
del state._active_layers[del_idx]
except ValueError:
state._active_layers.insert(0, key.meta.layer)
return state
def to_pressed(self, key, state, *args, **kwargs):
'''
Activates layer and deactivates all other layers
'''
state._active_layers.clear()
state._active_layers.insert(0, key.meta.layer)
return state
def tt_pressed(self, key, state, *args, **kwargs):
'''
Momentarily activates layer if held, toggles it if tapped repeatedly
'''
# TODO Make this work with tap dance to function more correctly, but technically works.
if state._start_time['tt'] is None:
# Sets the timer start and acts like MO otherwise
state._start_time['tt'] = ticks_ms()
return self.mo_pressed(key, state, *args, **kwargs)
elif ticks_diff(ticks_ms(), state._start_time['tt']) < state.tap_time:
state._start_time['tt'] = None
return self.tg_pressed(key, state, *args, **kwargs)
def tt_released(self, key, state, *args, **kwargs):
tap_timed_out = (
ticks_diff(ticks_ms(), state._start_time['tt']) >= state.tap_time
)
if state._start_time['tt'] is None or tap_timed_out:
# On first press, works like MO. On second press, does nothing unless let up within
# time window, then acts like TG.
state._start_time['tt'] = None
return self.mo_released(key, state, *args, **kwargs)
return state

View File

@@ -1,124 +0,0 @@
from kmk.kmktime import ticks_diff, ticks_ms
def df_pressed(key, state, *args, **kwargs):
'''
Switches the default layer
'''
state._active_layers[-1] = key.meta.layer
return state
def mo_pressed(key, state, *args, **kwargs):
'''
Momentarily activates layer, switches off when you let go
'''
state._active_layers.insert(0, key.meta.layer)
return state
def mo_released(key, state, KC, *args, **kwargs):
# remove the first instance of the target layer
# from the active list
# under almost all normal use cases, this will
# disable the layer (but preserve it if it was triggered
# as a default layer, etc.)
# this also resolves an issue where using DF() on a layer
# triggered by MO() and then defaulting to the MO()'s layer
# would result in no layers active
try:
del_idx = state._active_layers.index(key.meta.layer)
del state._active_layers[del_idx]
except ValueError:
pass
return state
def lm_pressed(key, state, *args, **kwargs):
'''
As MO(layer) but with mod active
'''
state._hid_pending = True
# Sets the timer start and acts like MO otherwise
state._start_time['lm'] = ticks_ms()
state._keys_pressed.add(key.meta.kc)
return mo_pressed(key, state, *args, **kwargs)
def lm_released(key, state, *args, **kwargs):
'''
As MO(layer) but with mod active
'''
state._hid_pending = True
state._keys_pressed.discard(key.meta.kc)
state._start_time['lm'] = None
return mo_released(key, state, *args, **kwargs)
def lt_pressed(key, state, *args, **kwargs):
# Sets the timer start and acts like MO otherwise
state._start_time['lt'] = ticks_ms()
return mo_pressed(key, state, *args, **kwargs)
def lt_released(key, state, *args, **kwargs):
# On keyup, check timer, and press key if needed.
if state._start_time['lt'] and (
ticks_diff(ticks_ms(), state._start_time['lt']) < state.tap_time
):
state._hid_pending = True
state._tap_key(key.meta.kc)
mo_released(key, state, *args, **kwargs)
state._start_time['lt'] = None
return state
def tg_pressed(key, state, *args, **kwargs):
'''
Toggles the layer (enables it if not active, and vise versa)
'''
# See mo_released for implementation details around this
try:
del_idx = state._active_layers.index(key.meta.layer)
del state._active_layers[del_idx]
except ValueError:
state._active_layers.insert(0, key.meta.layer)
return state
def to_pressed(key, state, *args, **kwargs):
'''
Activates layer and deactivates all other layers
'''
state._active_layers.clear()
state._active_layers.insert(0, key.meta.layer)
return state
def tt_pressed(key, state, *args, **kwargs):
'''
Momentarily activates layer if held, toggles it if tapped repeatedly
'''
# TODO Make this work with tap dance to function more correctly, but technically works.
if state._start_time['tt'] is None:
# Sets the timer start and acts like MO otherwise
state._start_time['tt'] = ticks_ms()
return mo_pressed(key, state, *args, **kwargs)
elif ticks_diff(ticks_ms(), state._start_time['tt']) < state.tap_time:
state._start_time['tt'] = None
return tg_pressed(key, state, *args, **kwargs)
def tt_released(key, state, *args, **kwargs):
tap_timed_out = ticks_diff(ticks_ms(), state._start_time['tt']) >= state.tap_time
if state._start_time['tt'] is None or tap_timed_out:
# On first press, works like MO. On second press, does nothing unless let up within
# time window, then acts like TG.
state._start_time['tt'] = None
return mo_released(key, state, *args, **kwargs)
return state

View File

@@ -1,13 +1,9 @@
from micropython import const from micropython import const
import kmk.handlers.layers as layers
import kmk.handlers.modtap as modtap
import kmk.handlers.stock as handlers import kmk.handlers.stock as handlers
from kmk.consts import UnicodeMode from kmk.consts import UnicodeMode
from kmk.key_validators import ( from kmk.key_validators import (
key_seq_sleep_validator, key_seq_sleep_validator,
layer_key_validator,
mod_tap_validator,
tap_dance_key_validator, tap_dance_key_validator,
unicode_mode_key_validator, unicode_mode_key_validator,
) )
@@ -613,48 +609,6 @@ make_key(
on_release=handlers.gesc_released, on_release=handlers.gesc_released,
) )
# Layers
make_argumented_key(
validator=layer_key_validator,
names=('MO',),
on_press=layers.mo_pressed,
on_release=layers.mo_released,
)
make_argumented_key(
validator=layer_key_validator, names=('DF',), on_press=layers.df_pressed
)
make_argumented_key(
validator=layer_key_validator,
names=('LM',),
on_press=layers.lm_pressed,
on_release=layers.lm_released,
)
make_argumented_key(
validator=layer_key_validator,
names=('LT',),
on_press=layers.lt_pressed,
on_release=layers.lt_released,
)
make_argumented_key(
validator=layer_key_validator, names=('TG',), on_press=layers.tg_pressed
)
make_argumented_key(
validator=layer_key_validator, names=('TO',), on_press=layers.to_pressed
)
make_argumented_key(
validator=layer_key_validator,
names=('TT',),
on_press=layers.tt_pressed,
on_release=layers.tt_released,
)
make_argumented_key(
validator=mod_tap_validator,
names=('MT',),
on_press=modtap.mt_pressed,
on_release=modtap.mt_released,
)
# A dummy key to trigger a sleep_ms call in a sequence of other keys in a # A dummy key to trigger a sleep_ms call in a sequence of other keys in a
# simple sequence macro. # simple sequence macro.
make_argumented_key( make_argumented_key(