From 578773189086405aa752609e43b90bb602b2f6c1 Mon Sep 17 00:00:00 2001 From: Josh Klar Date: Sat, 22 Sep 2018 00:46:14 -0700 Subject: [PATCH] Add support for changing to N layers as needed --- boards/klardotsh/threethree_matrix_pyboard.py | 4 +- kmk/common/internal_keycodes.py | 27 ++++++----- kmk/common/internal_state.py | 46 +++++++++++-------- kmk/common/keycodes.py | 43 ++++++++++++++--- 4 files changed, 80 insertions(+), 40 deletions(-) diff --git a/boards/klardotsh/threethree_matrix_pyboard.py b/boards/klardotsh/threethree_matrix_pyboard.py index e714932..54817e5 100644 --- a/boards/klardotsh/threethree_matrix_pyboard.py +++ b/boards/klardotsh/threethree_matrix_pyboard.py @@ -17,8 +17,8 @@ def main(): diode_orientation = DiodeOrientation.COLUMNS keymap = [ - [KC.DF, KC.H, KC.RESET], - [KC.MO, KC.I, KC.ENTER], + [KC.DF(1), KC.H, KC.RESET], + [KC.MO(2), KC.I, KC.ENTER], [KC.CTRL, KC.SPACE, KC.SHIFT], ] diff --git a/kmk/common/internal_keycodes.py b/kmk/common/internal_keycodes.py index 2b1377c..65be714 100644 --- a/kmk/common/internal_keycodes.py +++ b/kmk/common/internal_keycodes.py @@ -13,32 +13,37 @@ def process(state, action, logger=None): logger.warning(action['keycode']) if action['keycode'] == Keycodes.KMK.KC_RESET: - return reset(logger) - elif action['keycode'] == Keycodes.Layers.KC_DF: - return df(state, "Filler", action, logger=logger) - elif action['keycode'] == Keycodes.Layers.KC_MO: - return mo(state, "Filler", action, logger=logger) + return reset(state, action, logger=logger) + elif action['keycode'].code == Keycodes.Layers._KC_DF: + return df(state, action, logger=logger) + elif action['keycode'].code == Keycodes.Layers._KC_MO: + return mo(state, action, logger=logger) + else: + return state -def reset(logger): +def reset(state, action, logger): logger.debug('Rebooting to bootloader') import machine machine.bootloader() -def df(state, layer, action, logger): +def df(state, action, logger): """Switches the default layer""" - state.active_layers = [1] + state.active_layers[0] = action['keycode'].layer return state -def mo(state, layer, action, logger): +def mo(state, action, logger): """Momentarily activates layer, switches off when you let go""" if action['type'] == KEY_UP_EVENT: - state.active_layers = [0] + state.active_layers = [ + layer for layer in state.active_layers + if layer != action['keycode'].layer + ] elif action['type'] == KEY_DOWN_EVENT: - state.active_layers = [0, 1] + state.active_layers.append(action['keycode'].layer) return state diff --git a/kmk/common/internal_state.py b/kmk/common/internal_state.py index 2078b9a..362d748 100644 --- a/kmk/common/internal_state.py +++ b/kmk/common/internal_state.py @@ -50,34 +50,40 @@ class InternalState: matrix = [] diode_orientation = DiodeOrientation.COLUMNS active_layers = [0] + _oldstates = [] - @property - def __dict__(self): - return { + def __init__(self, preserve_intermediate_states=False): + self.preserve_intermediate_states = preserve_intermediate_states + + def to_dict(self, verbose=False): + ret = { 'keys_pressed': self.keys_pressed, 'modifiers_pressed': self.modifiers_pressed, - 'keymap': self.keymap, - 'col_pins': self.col_pins, - 'row_pins': self.row_pins, - 'diode_orientation': self.diode_orientation, 'active_layers': self.active_layers, } + if verbose: + ret.update({ + 'keymap': self.keymap, + 'matrix': self.matrix, + 'col_pins': self.col_pins, + 'row_pins': self.row_pins, + 'diode_orientation': self.diode_orientation, + }) + + return ret + def __repr__(self): - return 'InternalState({})'.format(self.__dict__) + return 'InternalState({})'.format(self.to_dict()) - def copy(self, **kwargs): - new_state = InternalState() - - for k, v in self.__dict__.items(): - if hasattr(new_state, k): - setattr(new_state, k, v) + def update(self, **kwargs): + if self.preserve_intermediate_states: + self._oldstates.append(repr(self.to_dict(verbose=True))) for k, v in kwargs.items(): - if hasattr(new_state, k): - setattr(new_state, k, v) + setattr(self, k, v) - return new_state + return self def kmk_reducer(state=None, action=None, logger=None): @@ -94,7 +100,7 @@ def kmk_reducer(state=None, action=None, logger=None): return state if action['type'] == KEY_UP_EVENT: - newstate = state.copy( + newstate = state.update( keys_pressed=frozenset( key for key in state.keys_pressed if key != action['keycode'] ), @@ -113,7 +119,7 @@ def kmk_reducer(state=None, action=None, logger=None): return newstate if action['type'] == KEY_DOWN_EVENT: - newstate = state.copy( + newstate = state.update( keys_pressed=( state.keys_pressed | {action['keycode']} ), @@ -132,7 +138,7 @@ def kmk_reducer(state=None, action=None, logger=None): return newstate if action['type'] == INIT_FIRMWARE_EVENT: - return state.copy( + return state.update( keymap=action['keymap'], row_pins=action['row_pins'], col_pins=action['col_pins'], diff --git a/kmk/common/keycodes.py b/kmk/common/keycodes.py index 2d6ae12..d80b91c 100644 --- a/kmk/common/keycodes.py +++ b/kmk/common/keycodes.py @@ -9,6 +9,7 @@ from kmk.common.types import AttrDict from kmk.common.util import flatten_dict Keycode = namedtuple('Keycode', ('code', 'is_modifier')) +LayerKeycode = namedtuple('LayerKeycode', ('code', 'layer')) class KeycodeCategory(type): @@ -322,13 +323,41 @@ class Keycodes(KeycodeCategory): KC_LOCK = Keycode(1006, False) class Layers(KeycodeCategory): - KC_DF = Keycode(1050, False) - KC_MO = Keycode(1051, False) - KC_LM = Keycode(1052, False) - KC_LT = Keycode(1053, False) - KC_TG = Keycode(1054, False) - KC_TO = Keycode(1055, False) - KC_TT = Keycode(1056, False) + _KC_DF = 1050 + _KC_MO = 1051 + _KC_LM = 1052 + _KC_LT = 1053 + _KC_TG = 1054 + _KC_TO = 1055 + _KC_TT = 1056 + + @staticmethod + def KC_DF(layer): + return LayerKeycode(Keycodes.Layers._KC_DF, layer) + + @staticmethod + def KC_MO(layer): + return LayerKeycode(Keycodes.Layers._KC_MO, layer) + + @staticmethod + def KC_LM(layer): + return LayerKeycode(Keycodes.Layers._KC_LM, layer) + + @staticmethod + def KC_LT(layer): + return LayerKeycode(Keycodes.Layers._KC_LT, layer) + + @staticmethod + def KC_TG(layer): + return LayerKeycode(Keycodes.Layers._KC_TG, layer) + + @staticmethod + def KC_TO(layer): + return LayerKeycode(Keycodes.Layers._KC_TO, layer) + + @staticmethod + def KC_TT(layer): + return LayerKeycode(Keycodes.Layers._KC_TT, layer) ALL_KEYS = KC = AttrDict({