Beginnings of basic tap dance
This commit is contained in:
		@@ -28,6 +28,8 @@ class InternalState:
 | 
			
		||||
        'leader': None,
 | 
			
		||||
    }
 | 
			
		||||
    timeouts = {}
 | 
			
		||||
    tapping = False
 | 
			
		||||
    tap_dance_counts = {}
 | 
			
		||||
 | 
			
		||||
    def __init__(self, config):
 | 
			
		||||
        self.config = config
 | 
			
		||||
@@ -45,6 +47,7 @@ class InternalState:
 | 
			
		||||
            Keycodes.KMK.KC_LEAD.code: self._kc_lead,
 | 
			
		||||
            Keycodes.KMK.KC_NO.code: self._kc_no,
 | 
			
		||||
            Keycodes.KMK.KC_DEBUG.code: self._kc_debug_mode,
 | 
			
		||||
            RawKeycodes.KC_TAP_DANCE: self._kc_tap_dance,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    def __repr__(self):
 | 
			
		||||
@@ -57,6 +60,8 @@ class InternalState:
 | 
			
		||||
            'leader_mode_history': self.leader_mode_history,
 | 
			
		||||
            'leader_mode': self.config.leader_mode,
 | 
			
		||||
            'start_time': self.start_time,
 | 
			
		||||
            'tapping': self.tapping,
 | 
			
		||||
            'tap_dance_counts': self.tap_dance_counts,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return ret
 | 
			
		||||
@@ -103,24 +108,27 @@ class InternalState:
 | 
			
		||||
            print('No key accessible for col, row: {}, {}'.format(row, col))
 | 
			
		||||
            return self
 | 
			
		||||
 | 
			
		||||
        if is_pressed:
 | 
			
		||||
            self.keys_pressed.add(kc_changed)
 | 
			
		||||
            self.coord_keys_pressed[int_coord] = kc_changed
 | 
			
		||||
        if self.tapping:
 | 
			
		||||
            self._process_tap_dance(kc_changed, is_pressed)
 | 
			
		||||
        else:
 | 
			
		||||
            self.keys_pressed.discard(kc_changed)
 | 
			
		||||
            self.keys_pressed.discard(self.coord_keys_pressed[int_coord])
 | 
			
		||||
            self.coord_keys_pressed[int_coord] = None
 | 
			
		||||
            if is_pressed:
 | 
			
		||||
                self.keys_pressed.add(kc_changed)
 | 
			
		||||
                self.coord_keys_pressed[int_coord] = kc_changed
 | 
			
		||||
            else:
 | 
			
		||||
                self.keys_pressed.discard(kc_changed)
 | 
			
		||||
                self.keys_pressed.discard(self.coord_keys_pressed.get(int_coord, None))
 | 
			
		||||
                self.coord_keys_pressed[int_coord] = None
 | 
			
		||||
 | 
			
		||||
        if kc_changed.code >= FIRST_KMK_INTERNAL_KEYCODE:
 | 
			
		||||
            self._process_internal_key_event(
 | 
			
		||||
                kc_changed,
 | 
			
		||||
                is_pressed,
 | 
			
		||||
            )
 | 
			
		||||
        else:
 | 
			
		||||
            self.hid_pending = True
 | 
			
		||||
            if kc_changed.code >= FIRST_KMK_INTERNAL_KEYCODE:
 | 
			
		||||
                self._process_internal_key_event(
 | 
			
		||||
                    kc_changed,
 | 
			
		||||
                    is_pressed,
 | 
			
		||||
                )
 | 
			
		||||
            else:
 | 
			
		||||
                self.hid_pending = True
 | 
			
		||||
 | 
			
		||||
        if self.config.leader_mode % 2 == 1:
 | 
			
		||||
            self._process_leader_mode()
 | 
			
		||||
            if self.config.leader_mode % 2 == 1:
 | 
			
		||||
                self._process_leader_mode()
 | 
			
		||||
 | 
			
		||||
        return self
 | 
			
		||||
 | 
			
		||||
@@ -318,6 +326,50 @@ class InternalState:
 | 
			
		||||
 | 
			
		||||
        return self
 | 
			
		||||
 | 
			
		||||
    def _kc_tap_dance(self, changed_key, is_pressed):
 | 
			
		||||
        if is_pressed:
 | 
			
		||||
            self._begin_tap_dance(changed_key)
 | 
			
		||||
        else:
 | 
			
		||||
            self._end_tap_dance()
 | 
			
		||||
 | 
			
		||||
        return self
 | 
			
		||||
 | 
			
		||||
    def _begin_tap_dance(self, changed_key):
 | 
			
		||||
        self.tap_dance_counts[changed_key] = 1
 | 
			
		||||
        self.set_timeout(500, self._end_tap_dance)
 | 
			
		||||
        self.tapping = changed_key
 | 
			
		||||
        return self
 | 
			
		||||
 | 
			
		||||
    def _process_tap_dance(self, changed_key, is_pressed):
 | 
			
		||||
        if is_pressed:
 | 
			
		||||
            if (
 | 
			
		||||
                changed_key not in self.tap_dance_counts or
 | 
			
		||||
                not self.tap_dance_counts[changed_key]
 | 
			
		||||
            ):
 | 
			
		||||
                self._end_tap_dance()
 | 
			
		||||
            else:
 | 
			
		||||
                self.tap_dance_counts[changed_key] += 1
 | 
			
		||||
 | 
			
		||||
                if self.tap_dance_counts[changed_key] == len(changed_key.codes):
 | 
			
		||||
                    self._end_tap_dance()
 | 
			
		||||
 | 
			
		||||
        return self
 | 
			
		||||
 | 
			
		||||
    def _end_tap_dance(self):
 | 
			
		||||
        k = self.tapping
 | 
			
		||||
 | 
			
		||||
        if not k:
 | 
			
		||||
            # already handled elsewhere?
 | 
			
		||||
            return self
 | 
			
		||||
 | 
			
		||||
        v = self.tap_dance_counts[k] - 1
 | 
			
		||||
 | 
			
		||||
        self.pending_keys.append(k.codes[min(v, len(k.codes) - 1)])
 | 
			
		||||
        self.tap_dance_counts[k] = 0
 | 
			
		||||
        self.tapping = False
 | 
			
		||||
 | 
			
		||||
        return self
 | 
			
		||||
 | 
			
		||||
    def _begin_leader_mode(self):
 | 
			
		||||
        if self.config.leader_mode % 2 == 0:
 | 
			
		||||
            self.keys_pressed.discard(Keycodes.KMK.KC_LEAD)
 | 
			
		||||
 
 | 
			
		||||
@@ -80,6 +80,7 @@ class RawKeycodes:
 | 
			
		||||
 | 
			
		||||
    KC_MACRO = 1110
 | 
			
		||||
    KC_MACRO_SLEEP_MS = 1111
 | 
			
		||||
    KC_TAP_DANCE = 1113
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# These shouldn't have all the fancy shenanigans Keycode allows
 | 
			
		||||
@@ -184,6 +185,13 @@ class Macro:
 | 
			
		||||
        return self.keyup() if self.keyup else None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TapDanceKeycode:
 | 
			
		||||
    code = RawKeycodes.KC_TAP_DANCE
 | 
			
		||||
 | 
			
		||||
    def __init__(self, *codes):
 | 
			
		||||
        self.codes = codes
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class KeycodeCategory(type):
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def to_dict(cls):
 | 
			
		||||
@@ -551,6 +559,13 @@ class KMK(KeycodeCategory):
 | 
			
		||||
    def KC_MACRO_SLEEP_MS(ms):
 | 
			
		||||
        return MacroSleepKeycode(RawKeycodes.KC_MACRO_SLEEP_MS, ms)
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def KC_TAP_DANCE(*args):
 | 
			
		||||
        return TapDanceKeycode(*args)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
KMK.KC_TD = KMK.KC_TAP_DANCE
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Layers(KeycodeCategory):
 | 
			
		||||
    @staticmethod
 | 
			
		||||
 
 | 
			
		||||
@@ -61,7 +61,7 @@ keyboard.keymap = [
 | 
			
		||||
        [KC.GESC, KC.QUOT, KC.COMM,            KC.DOT,   KC.P,     KC.Y,    KC.F,    KC.G,     KC.C,    KC.R,    KC.L,  KC.BSPC],
 | 
			
		||||
        [KC.TAB,  KC.A,    KC.O,               KC.E,     KC.U,     KC.I,    KC.D,    KC.H,     KC.T,    KC.N,    KC.S,  KC.ENT],
 | 
			
		||||
        [KC.LGUI, KC.SCLN, KC.Q,               KC.J,     KC.K,     KC.X,    KC.B,    KC.M,     KC.W,    KC.V,    KC.Z,  KC.LALT],
 | 
			
		||||
        [KC.LCTL, KC.LEAD, KC.LSHIFT(KC.LGUI), KC.MO(2), KC.MO(3), KC.LSFT, KC.SPC,  KC.MO(1), KC.LEFT, KC.DOWN, KC.UP, KC.RGHT],
 | 
			
		||||
        [KC.LCTL, KC.TD(KC.A, KC.B), KC.LSHIFT(KC.LGUI), KC.MO(2), KC.MO(3), KC.LSFT, KC.SPC,  KC.MO(1), KC.LEFT, KC.DOWN, KC.UP, KC.RGHT],
 | 
			
		||||
    ],
 | 
			
		||||
 | 
			
		||||
    [
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user