diff --git a/docs/solo/developer/build-flags.md b/docs/solo/developer/build-flags.md index 5bc2b788..6d09adae 100644 --- a/docs/solo/developer/build-flags.md +++ b/docs/solo/developer/build-flags.md @@ -56,6 +56,7 @@ existing `solo//platformio.ini` for what's already claimed). | `UI_HAS_JOYSTICK=1` + `UI_HAS_JOYSTICK_UPDOWN=1` (optional) + `JOYSTICK_UP` / `JOYSTICK_DOWN` / `JOYSTICK_LEFT` / `JOYSTICK_RIGHT` + `PIN_USER_BTN` + `PIN_BACK_BTN` | A wired joystick (four direction contacts + a press contact for Enter). Replaces single-button navigation entirely once enabled. See [External Keyboard & Joystick](../hardware.md#external-keyboard-and-joystick). | | `PIN_GPIO1` .. `PIN_GPIO4` | Up to four general-purpose pins, each independently switchable between Off / Input / Output (GPIO1/GPIO2 also get an Analog step, if wired to an ADC-capable pin) from Tools › GPIO, and via the `!gpio1`..`!gpio4` bot commands. Not restricted to any particular board — works anywhere the pins are actually free. See [Tools › GPIO](../tools.md#gpio). | | `PIN_HALL_SENSOR` + `HALL_ACTIVE_HIGH=1` (optional) | A Hall-effect or reed sensor for a magnetic flip cover: closing locks and blanks the screen instantly, opening unlocks and wakes it, no combo either way. `HALL_ACTIVE_HIGH` is only for a module wired to pull the pin high (rather than low) when the magnet is near. See [Screen lock › Magnetic cover](../lock.md#magnetic-cover). | +| `UI_ENTER_DOUBLE_BACK=1` | Double-click Enter goes back, for a joystick whose Back button is hard to reach. Delays a single Enter by ~280 ms; in text entry a double is two Enters. Only the GAT562 30S target wires it up; off by default. | --- diff --git a/examples/companion_radio/ui-new/UITask.cpp b/examples/companion_radio/ui-new/UITask.cpp index 78da273e..3ca4a368 100644 --- a/examples/companion_radio/ui-new/UITask.cpp +++ b/examples/companion_radio/ui-new/UITask.cpp @@ -1261,8 +1261,7 @@ void UITask::loop() { #if FEAT_DISPLAY_ROTATION_SETTING && defined(JOYSTICK_UPRIGHT_ROTATION) if (_node_prefs) joy_rot += (JOYSTICK_UPRIGHT_ROTATION - _node_prefs->display_rotation) & 3; #endif - int ev = user_btn.check(); - if (ev == BUTTON_EVENT_CLICK) { + auto enterClick = [&]() { if (back_btn.isPressed() && !_unlock_kb) { // Enter clicked while Back is held — lock/unlock sequence if (_display && !_display->isOn()) { @@ -1287,6 +1286,25 @@ void UITask::loop() { } enqueueKey(checkDisplayOn(KEY_ENTER)); } + }; + int ev = user_btn.check(); +#ifdef UI_ENTER_DOUBLE_BACK + // For a joystick without a reachable Back button: a double click on Enter goes + // back. Multi-click delays a single Enter by the click window. Where text is + // typed (on-screen keyboard, PIN pad) or the lock sequence is counting, a + // double is just two Enters, so a repeated letter still works. + if (ev == BUTTON_EVENT_DOUBLE_CLICK || ev == BUTTON_EVENT_TRIPLE_CLICK) { + int n = (ev == BUTTON_EVENT_DOUBLE_CLICK) ? 2 : 3; + if (_unlock_kb || _kb.isVisible() || back_btn.isPressed()) { + for (int i = 0; i < n; i++) enterClick(); + } else { + enqueueKey(checkDisplayOn(KEY_CANCEL)); + } + ev = BUTTON_EVENT_NONE; + } +#endif + if (ev == BUTTON_EVENT_CLICK) { + enterClick(); } else if (ev == BUTTON_EVENT_LONG_PRESS) { enqueueKey(handleLongPress(KEY_ENTER)); // REVISIT: could be mapped to different key code } diff --git a/variants/gat562_30s_mesh_kit/target.cpp b/variants/gat562_30s_mesh_kit/target.cpp index 538e4e2f..42bb4c39 100644 --- a/variants/gat562_30s_mesh_kit/target.cpp +++ b/variants/gat562_30s_mesh_kit/target.cpp @@ -11,7 +11,11 @@ GAT56230SMeshKitBoard board; #ifdef DISPLAY_CLASS DISPLAY_CLASS display; - MomentaryButton user_btn(PIN_USER_BTN, 1000, true, false, false); + #ifdef UI_ENTER_DOUBLE_BACK + MomentaryButton user_btn(PIN_USER_BTN, 1000, true, false, true); // multi-click: double Enter = Back + #else + MomentaryButton user_btn(PIN_USER_BTN, 1000, true, false, false); + #endif MomentaryButton joystick_left(JOYSTICK_LEFT, 1000, true, false, false); MomentaryButton joystick_right(JOYSTICK_RIGHT, 1000, true, false, false); MomentaryButton back_btn(PIN_BACK_BTN, 1000, true, false, true);