diff --git a/examples/Keystrokes/Escape-OneShot/Escape-OneShot.ino b/examples/Keystrokes/Escape-OneShot/Escape-OneShot.ino index 5f6689ca..921d4d92 100644 --- a/examples/Keystrokes/Escape-OneShot/Escape-OneShot.ino +++ b/examples/Keystrokes/Escape-OneShot/Escape-OneShot.ino @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-Escape-OneShot -- Turn ESC into a key that cancels OneShots, if active. - * Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc + * Copyright (C) 2016-2021 Keyboard.io, Inc * * 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 the Free Software @@ -16,8 +16,10 @@ */ #include +#include #include #include +#include // *INDENT-OFF* KEYMAPS( @@ -61,8 +63,11 @@ KEYMAPS( ) // *INDENT-ON* -KALEIDOSCOPE_INIT_PLUGINS(OneShot, - EscapeOneShot); +KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings, + Focus, + OneShot, + EscapeOneShot, + EscapeOneShotConfig); void setup() { Kaleidoscope.setup(); diff --git a/plugins/Kaleidoscope-Escape-OneShot/README.md b/plugins/Kaleidoscope-Escape-OneShot/README.md index 8ce762f0..8debee44 100644 --- a/plugins/Kaleidoscope-Escape-OneShot/README.md +++ b/plugins/Kaleidoscope-Escape-OneShot/README.md @@ -23,12 +23,35 @@ void setup () { } ``` +If one wishes to configure the plugin at run-time via [Focus][plugin:focus], the +optional `EscapeOneShotConfig` plugin must also be enabled: + + [plugin:focus]: Kaleidoscope-FocusSerial.md + +```c++ +#include +#include +#include +#include +#include + +KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings, + Focus, + OneShot, + EscapeOneShot, + EscapeOneShotConfig); + +void setup () { + Kaleidoscope.setup (); +} +``` + The plugin only makes sense when using one-shot keys. ## Plugin methods -The plugin provides the `EscapeOneShot` object, which has one public -configuration method: +The plugin provides the `EscapeOneShot` object, which has the following public +configuration methods: ### `.setCancelKey(key)` @@ -39,10 +62,45 @@ configuration method: > modifiers), there is the special `OneShotCancelKey`, which will not > have any side effects. +### `.getCancelKey(key)` + +> Returns the `Key` value that will trigger deactivation of one-shot (including +> sticky) keys. + +### `.enable()`, `.disable()`, `.toggle()`, and `.isEnabled()` + +> Enables, disables, toggles, and returns the enabled state of the plugin, +> respectively. +> +> By default, the plugin starts enabled. + +## Focus commands + +The plugin provides two Focus commands: `escape_oneshot.enabled`, and +`escape_oneshot.cancel_key`. + +### `escape_oneshot.enabled [0|1]` + +> Without arguments, returns whether the plugin is enabled or not. +> +> With an argument, enables or disables it. + +### `escape_oneshot.cancel_key [keycode]` + +> Without an argument, returns the raw 16-bit keycode of the cancel key set. +> +> With an argument - a raw 16-bit keycode -, sets the cancel key to the one +> corresponding to the given code. + ## Dependencies * [Kaleidoscope-OneShot](Kaleidoscope-OneShot.md) +### Optional dependencies + +* [Kaleidoscope-EEPROM-Settings](Kaleidoscope-EEPROM-Settings.md) +* [Kaleidoscope-FocusSerial](Kaleidoscope-FocusSerial.md) + ## Further reading Starting from the [example][plugin:example] is the recommended way of getting diff --git a/plugins/Kaleidoscope-Escape-OneShot/src/kaleidoscope/plugin/Escape-OneShot-Config.cpp b/plugins/Kaleidoscope-Escape-OneShot/src/kaleidoscope/plugin/Escape-OneShot-Config.cpp new file mode 100644 index 00000000..422a9b2f --- /dev/null +++ b/plugins/Kaleidoscope-Escape-OneShot/src/kaleidoscope/plugin/Escape-OneShot-Config.cpp @@ -0,0 +1,107 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-Escape-OneShot -- Turn ESC into a key that cancels OneShots, if active. + * Copyright (C) 2016-2021 Keyboard.io, Inc + * + * 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 the Free Software + * Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include "kaleidoscope/plugin/Escape-OneShot.h" + +#include +#include + +#include "kaleidoscope/Runtime.h" + +namespace kaleidoscope { +namespace plugin { + +uint16_t EscapeOneShotConfig::settings_base_; + +EventHandlerResult EscapeOneShotConfig::onSetup() { + settings_base_ = ::EEPROMSettings.requestSlice(sizeof(EscapeOneShot::settings_)); + struct { + uint8_t b; + uint16_t w; + } checker; + + Runtime.storage().get(settings_base_, checker); + + // Check if we have an empty eeprom... + if (checker.b == 0xff && checker.w == 0xffff) { + // ...if the eeprom was empty, store the default settings. + Runtime.storage().put(settings_base_, EscapeOneShot::settings_); + Runtime.storage().commit(); + } + + Runtime.storage().get(settings_base_, EscapeOneShot::settings_); + return EventHandlerResult::OK; +} + +EventHandlerResult EscapeOneShotConfig::onNameQuery() { + return ::Focus.sendName(F("EscapeOneShot")); +} + +EventHandlerResult EscapeOneShotConfig::onFocusEvent(const char *command) { + enum { + ENABLED, + CANCEL_KEY + } subCommand; + + if (::Focus.handleHelp(command, PSTR("escape_oneshot.enabled\n" + "escape_oneshot.cancel_key"))) + return EventHandlerResult::OK; + + if (strncmp_P(command, PSTR("escape_oneshot."), 15) != 0) + return EventHandlerResult::OK; + if (strcmp_P(command + 15, PSTR("enabled")) == 0) + subCommand = ENABLED; + else if (strcmp_P(command + 15, PSTR("cancel_key")) == 0) + subCommand = CANCEL_KEY; + else + return EventHandlerResult::OK; + + switch (subCommand) { + case ENABLED: + if (::Focus.isEOL()) { + ::Focus.send(::EscapeOneShot.isEnabled()); + } else { + uint8_t v; + ::Focus.read(v); + if (v != 0) { + ::EscapeOneShot.enable(); + } else { + ::EscapeOneShot.disable(); + } + } + break; + + case CANCEL_KEY: + if (::Focus.isEOL()) { + ::Focus.send(::EscapeOneShot.getCancelKey()); + } else { + Key k; + ::Focus.read(k); + ::EscapeOneShot.setCancelKey(k); + } + break; + } + + Runtime.storage().put(settings_base_, EscapeOneShot::settings_); + Runtime.storage().commit(); + return EventHandlerResult::EVENT_CONSUMED; +} + +} // namespace plugin +} // namespace kaleidoscope + +kaleidoscope::plugin::EscapeOneShotConfig EscapeOneShotConfig; diff --git a/plugins/Kaleidoscope-Escape-OneShot/src/kaleidoscope/plugin/Escape-OneShot.h b/plugins/Kaleidoscope-Escape-OneShot/src/kaleidoscope/plugin/Escape-OneShot.h index d94111db..bd14ff21 100644 --- a/plugins/Kaleidoscope-Escape-OneShot/src/kaleidoscope/plugin/Escape-OneShot.h +++ b/plugins/Kaleidoscope-Escape-OneShot/src/kaleidoscope/plugin/Escape-OneShot.h @@ -50,6 +50,8 @@ class EscapeOneShot : public kaleidoscope::Plugin { return !settings_.disabled; } + friend class EscapeOneShotConfig; + private: struct Settings { bool disabled; @@ -57,9 +59,20 @@ class EscapeOneShot : public kaleidoscope::Plugin { }; static Settings settings_; }; + +class EscapeOneShotConfig : public Plugin { + public: + EventHandlerResult onSetup(); + EventHandlerResult onFocusEvent(const char *command); + EventHandlerResult onNameQuery(); + + + private: + static uint16_t settings_base_; }; } } extern kaleidoscope::plugin::EscapeOneShot EscapeOneShot; +extern kaleidoscope::plugin::EscapeOneShotConfig EscapeOneShotConfig;