Adapt Leader plugin to KeyEvent handlers

Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
pull/1024/head
Michael Richters 4 years ago
parent 6e2f3e8843
commit 8d4967db8d
No known key found for this signature in database
GPG Key ID: 1288FD13E4EEF0C0

@ -58,9 +58,6 @@ The dictionary is made up of a list of keys, and an action callback. Using the
`LEADER_DICT` and `LEADER_SEQ` helpers is recommended. The dictionary *must* be `LEADER_DICT` and `LEADER_SEQ` helpers is recommended. The dictionary *must* be
marked `PROGMEM`! marked `PROGMEM`!
**Note** that we need to use the `Leader` object before any other that adds or
changes key behaviour! Failing to do so may result in unpredictable behaviour.
## Plugin methods ## Plugin methods
The plugin provides the `Leader` object, with the following methods and properties: The plugin provides the `Leader` object, with the following methods and properties:

@ -20,12 +20,14 @@
#include "kaleidoscope/keyswitch_state.h" #include "kaleidoscope/keyswitch_state.h"
#include "kaleidoscope/keyswitch_state.h" #include "kaleidoscope/keyswitch_state.h"
#include "kaleidoscope/key_events.h" #include "kaleidoscope/key_events.h"
#include "kaleidoscope/KeyEventTracker.h"
namespace kaleidoscope { namespace kaleidoscope {
namespace plugin { namespace plugin {
// --- state --- // --- state ---
Key Leader::sequence_[LEADER_MAX_SEQUENCE_LENGTH + 1]; Key Leader::sequence_[LEADER_MAX_SEQUENCE_LENGTH + 1];
KeyEventTracker Leader::event_tracker_;
uint8_t Leader::sequence_pos_; uint8_t Leader::sequence_pos_;
uint16_t Leader::start_time_ = 0; uint16_t Leader::start_time_ = 0;
uint16_t Leader::time_out = 1000; uint16_t Leader::time_out = 1000;
@ -81,8 +83,9 @@ void Leader::reset(void) {
sequence_[0] = Key_NoKey; sequence_[0] = Key_NoKey;
} }
// DEPRECATED
void Leader::inject(Key key, uint8_t key_state) { void Leader::inject(Key key, uint8_t key_state) {
onKeyswitchEvent(key, UnknownKeyswitchLocation, key_state); Runtime.handleKeyEvent(KeyEvent(KeyAddr::none(), key_state | INJECTED, key));
} }
// --- hooks --- // --- hooks ---
@ -90,61 +93,49 @@ EventHandlerResult Leader::onNameQuery() {
return ::Focus.sendName(F("Leader")); return ::Focus.sendName(F("Leader"));
} }
EventHandlerResult Leader::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t keyState) { EventHandlerResult Leader::onKeyswitchEvent(KeyEvent &event) {
if (keyState & INJECTED) // If the plugin has already processed and released this event, ignore it.
// There's no need to update the event tracker explicitly.
if (event_tracker_.shouldIgnore(event))
return EventHandlerResult::OK; return EventHandlerResult::OK;
if (!isActive() && !isLeader(mapped_key)) if (keyToggledOff(event.state) || event.state & INJECTED)
return EventHandlerResult::OK; return EventHandlerResult::OK;
if (!isActive()) { if (!isActive()) {
// Must be a leader key! if (!isLeader(event.key))
if (keyToggledOff(keyState)) {
// not active, but a leader key = start the sequence on key release!
start_time_ = Runtime.millisAtCycleStart();
sequence_pos_ = 0;
sequence_[sequence_pos_] = mapped_key;
}
// If the sequence was not active yet, ignore the key.
return EventHandlerResult::EVENT_CONSUMED;
}
// active
int8_t action_index = lookup();
if (keyToggledOn(keyState)) {
sequence_pos_++;
if (sequence_pos_ > LEADER_MAX_SEQUENCE_LENGTH) {
reset();
return EventHandlerResult::OK; return EventHandlerResult::OK;
}
start_time_ = Runtime.millisAtCycleStart(); start_time_ = Runtime.millisAtCycleStart();
sequence_[sequence_pos_] = mapped_key; sequence_pos_ = 0;
action_index = lookup(); sequence_[sequence_pos_] = event.key;
if (action_index >= 0) { return EventHandlerResult::ABORT;
return EventHandlerResult::EVENT_CONSUMED;
}
} else if (keyIsPressed(keyState)) {
// held, no need for anything here.
return EventHandlerResult::EVENT_CONSUMED;
} }
++sequence_pos_;
if (sequence_pos_ > LEADER_MAX_SEQUENCE_LENGTH) {
reset();
return EventHandlerResult::OK;
}
start_time_ = Runtime.millisAtCycleStart();
sequence_[sequence_pos_] = event.key;
int8_t action_index = lookup();
if (action_index == NO_MATCH) { if (action_index == NO_MATCH) {
reset(); reset();
return EventHandlerResult::OK; return EventHandlerResult::OK;
} }
if (action_index == PARTIAL_MATCH) { if (action_index == PARTIAL_MATCH) {
return EventHandlerResult::EVENT_CONSUMED; return EventHandlerResult::ABORT;
} }
action_t leaderAction = (action_t) pgm_read_ptr((void const **) & (dictionary[action_index].action)); action_t leaderAction = (action_t) pgm_read_ptr((void const **) & (dictionary[action_index].action));
(*leaderAction)(action_index); (*leaderAction)(action_index);
reset();
return EventHandlerResult::EVENT_CONSUMED; return EventHandlerResult::ABORT;
} }
EventHandlerResult Leader::afterEachCycle() { EventHandlerResult Leader::afterEachCycle() {

@ -17,8 +17,9 @@
#pragma once #pragma once
#include "kaleidoscope/Runtime.h"
#include <Kaleidoscope-Ranges.h> #include <Kaleidoscope-Ranges.h>
#include "kaleidoscope/KeyEventTracker.h"
#include "kaleidoscope/plugin.h"
#define LEADER_MAX_SEQUENCE_LENGTH 4 #define LEADER_MAX_SEQUENCE_LENGTH 4
@ -47,11 +48,12 @@ class Leader : public kaleidoscope::Plugin {
void inject(Key key, uint8_t key_state); void inject(Key key, uint8_t key_state);
EventHandlerResult onNameQuery(); EventHandlerResult onNameQuery();
EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t keyState); EventHandlerResult onKeyswitchEvent(KeyEvent &event);
EventHandlerResult afterEachCycle(); EventHandlerResult afterEachCycle();
private: private:
static Key sequence_[LEADER_MAX_SEQUENCE_LENGTH + 1]; static Key sequence_[LEADER_MAX_SEQUENCE_LENGTH + 1];
static KeyEventTracker event_tracker_;
static uint8_t sequence_pos_; static uint8_t sequence_pos_;
static uint16_t start_time_; static uint16_t start_time_;

Loading…
Cancel
Save