diff --git a/README.md b/README.md index 60aa4deb..7dc84369 100644 --- a/README.md +++ b/README.md @@ -52,11 +52,11 @@ static const kaleidoscope::Leader::dictionary_t leader_dictionary[] PROGMEM = LEADER_DICT({LEADER_SEQ(LEAD(0), Key_A), leaderA}, {LEADER_SEQ(LEAD(0), Key_T, Key_X), leaderTX}); +KALEIDOSCOPE_INIT_PLUGINS(Leader); + void setup() { Serial.begin(9600); - Kaleidoscope.use(&Leader); - Kaleidoscope.setup(); Leader.dictionary = leader_dictionary; diff --git a/examples/Leader/Leader.ino b/examples/Leader/Leader.ino index ee25451d..1f1c1b8e 100644 --- a/examples/Leader/Leader.ino +++ b/examples/Leader/Leader.ino @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-Leader -- VIM-style leader keys - * Copyright (C) 2016, 2017 Gergely Nagy + * Copyright (C) 2016, 2017, 2018 Gergely Nagy * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,6 +19,7 @@ #include #include +// *INDENT-OFF* const Key keymaps[][ROWS][COLS] PROGMEM = { [0] = KEYMAP_STACKED (Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, @@ -31,12 +32,13 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, - Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, LEAD(0)), }; +// *INDENT-ON* static void leaderTestA(uint8_t seq_index) { Serial.println(F("leaderTestA")); @@ -50,9 +52,9 @@ static const kaleidoscope::Leader::dictionary_t leader_dictionary[] PROGMEM = LEADER_DICT({LEADER_SEQ(LEAD(0), Key_A), leaderTestA}, {LEADER_SEQ(LEAD(0), Key_A, Key_A), leaderTestAA}); -void setup() { - Kaleidoscope.use(&Leader); +KALEIDOSCOPE_INIT_PLUGINS(Leader); +void setup() { Kaleidoscope.setup(); Leader.dictionary = leader_dictionary; diff --git a/src/Kaleidoscope/Leader.cpp b/src/Kaleidoscope/Leader.cpp index aa075e55..bc993d47 100644 --- a/src/Kaleidoscope/Leader.cpp +++ b/src/Kaleidoscope/Leader.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-Leader -- VIM-style leader keys - * Copyright (C) 2016, 2017 Gergely Nagy + * Copyright (C) 2016, 2017, 2018 Gergely Nagy * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -71,41 +71,34 @@ int8_t Leader::lookup(void) { // --- api --- -Leader::Leader(void) { -} - -void Leader::begin(void) { - Kaleidoscope.useEventHandlerHook(eventHandlerHook); - Kaleidoscope.useLoopHook(loopHook); -} - void Leader::reset(void) { sequence_pos_ = 0; sequence_[0].raw = Key_NoKey.raw; } void Leader::inject(Key key, uint8_t key_state) { - eventHandlerHook(key, UNKNOWN_KEYSWITCH_LOCATION, key_state); + onKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, key_state); } // --- hooks --- -Key Leader::eventHandlerHook(Key mapped_key, byte row, byte col, uint8_t key_state) { - if (key_state & INJECTED) - return mapped_key; +EventHandlerResult Leader::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t keyState) { + if (keyState & INJECTED) + return EventHandlerResult::OK; - if (!keyIsPressed(key_state) && !keyWasPressed(key_state)) { - if (isLeader(mapped_key)) - return Key_NoKey; - return mapped_key; + if (!keyIsPressed(keyState) && !keyWasPressed(keyState)) { + if (isLeader(mapped_key)) { + return EventHandlerResult::EVENT_CONSUMED; + } + return EventHandlerResult::OK; } if (!isActive() && !isLeader(mapped_key)) - return mapped_key; + return EventHandlerResult::OK; if (!isActive()) { // Must be a leader key! - if (keyToggledOff(key_state)) { + if (keyToggledOff(keyState)) { // not active, but a leader key = start the sequence on key release! end_time_ = millis() + time_out; sequence_pos_ = 0; @@ -113,53 +106,76 @@ Key Leader::eventHandlerHook(Key mapped_key, byte row, byte col, uint8_t key_sta } // If the sequence was not active yet, ignore the key. - return Key_NoKey; + return EventHandlerResult::EVENT_CONSUMED; } // active int8_t action_index = lookup(); - if (keyToggledOn(key_state)) { + if (keyToggledOn(keyState)) { sequence_pos_++; if (sequence_pos_ > LEADER_MAX_SEQUENCE_LENGTH) { reset(); - return mapped_key; + return EventHandlerResult::OK; } end_time_ = millis() + time_out; sequence_[sequence_pos_].raw = mapped_key.raw; action_index = lookup(); - if (action_index >= 0) - return Key_NoKey; - } else if (keyIsPressed(key_state)) { + if (action_index >= 0) { + return EventHandlerResult::EVENT_CONSUMED; + } + } else if (keyIsPressed(keyState)) { // held, no need for anything here. - return Key_NoKey; + return EventHandlerResult::EVENT_CONSUMED; } if (action_index == NO_MATCH) { reset(); - return mapped_key; + return EventHandlerResult::OK; } if (action_index == PARTIAL_MATCH) { - return Key_NoKey; + return EventHandlerResult::EVENT_CONSUMED; } action_t leaderAction = (action_t) pgm_read_ptr(&(dictionary[action_index].action)); (*leaderAction)(action_index); - return Key_NoKey; -} -void Leader::loopHook(bool is_post_clear) { - if (!is_post_clear) - return; + return EventHandlerResult::EVENT_CONSUMED; +} +EventHandlerResult Leader::afterEachCycle() { if (!isActive()) - return; + return EventHandlerResult::OK; if (millis() >= end_time_) reset(); + + return EventHandlerResult::OK; +} + +// Legacy V1 API +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API +void Leader::begin() { + Kaleidoscope.useEventHandlerHook(legacyEventHandler); + Kaleidoscope.useLoopHook(legacyLoopHook); +} + +Key Leader::legacyEventHandler(Key mapped_key, byte row, byte col, uint8_t key_state) { + EventHandlerResult r = ::Leader.onKeyswitchEvent(mapped_key, row, col, key_state); + if (r == EventHandlerResult::OK) + return mapped_key; + return Key_NoKey; +} + +void Leader::legacyLoopHook(bool is_post_clear) { + if (!is_post_clear) + return; + + ::Leader.afterEachCycle(); } +#endif } diff --git a/src/Kaleidoscope/Leader.h b/src/Kaleidoscope/Leader.h index 16fd7117..bf0ea507 100644 --- a/src/Kaleidoscope/Leader.h +++ b/src/Kaleidoscope/Leader.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-Leader -- VIM-style leader keys - * Copyright (C) 2016, 2017 Gergely Nagy + * Copyright (C) 2016, 2017, 2018 Gergely Nagy * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,7 +30,7 @@ namespace kaleidoscope { -class Leader : public KaleidoscopePlugin { +class Leader : public kaleidoscope::Plugin { public: typedef void (*action_t)(uint8_t seq_index); typedef struct { @@ -38,23 +38,29 @@ class Leader : public KaleidoscopePlugin { action_t action; } dictionary_t; - Leader(void); + Leader(void) {} static const dictionary_t *dictionary; - void begin(void) final; - static void reset(void); static uint16_t time_out; void inject(Key key, uint8_t key_state); + EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t keyState); + EventHandlerResult afterEachCycle(); + +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API + protected: + void begin(); + static Key legacyEventHandler(Key mapped_key, byte row, byte col, uint8_t key_state); + static void legacyLoopHook(bool is_post_clear); +#endif + private: static Key sequence_[LEADER_MAX_SEQUENCE_LENGTH + 1]; static uint8_t sequence_pos_; static uint32_t end_time_; - static Key eventHandlerHook(Key mapped_key, byte row, byte col, uint8_t key_state); - static void loopHook(bool is_post_clear); static int8_t lookup(void); };