Use double-clicks instead of long-presses for wheel shortcuts

custom
jacqueline 12 months ago
parent b255ea799e
commit 1736f7874b
  1. 4
      src/input/include/input_hook.hpp
  2. 7
      src/input/include/input_trigger.hpp
  3. 5
      src/input/input_hook.cpp
  4. 4
      src/input/input_nav_buttons.cpp
  5. 4
      src/input/input_touch_dpad.cpp
  6. 13
      src/input/input_touch_wheel.cpp
  7. 44
      src/input/input_trigger.cpp

@ -45,9 +45,10 @@ class Hook {
class TriggerHooks {
public:
TriggerHooks(std::string name, std::optional<HookCallback> cb)
: TriggerHooks(name, cb, cb, cb) {}
: TriggerHooks(name, cb, cb, cb, cb) {}
TriggerHooks(std::string name,
std::optional<HookCallback> click,
std::optional<HookCallback> double_click,
std::optional<HookCallback> long_press,
std::optional<HookCallback> repeat);
@ -66,6 +67,7 @@ class TriggerHooks {
Trigger trigger_;
Hook click_;
Hook double_click_;
Hook long_press_;
Hook repeat_;
};

@ -13,6 +13,7 @@
namespace input {
const uint16_t kDoubleClickDelayMs = 500;
const uint16_t kLongPressDelayMs = LV_INDEV_DEF_LONG_PRESS_TIME;
const uint16_t kRepeatDelayMs = LV_INDEV_DEF_LONG_PRESS_REP_TIME;
@ -21,6 +22,7 @@ class Trigger {
enum class State {
kNone,
kClick,
kDoubleClick,
kLongPress,
kRepeatPress,
};
@ -31,7 +33,10 @@ class Trigger {
private:
std::optional<uint64_t> touch_time_ms_;
uint16_t times_fired_;
bool was_pressed_;
bool was_double_click_;
uint16_t times_long_pressed_;
};
} // namespace input

@ -39,10 +39,12 @@ auto Hook::callback() -> std::optional<HookCallback> {
TriggerHooks::TriggerHooks(std::string name,
std::optional<HookCallback> click,
std::optional<HookCallback> double_click,
std::optional<HookCallback> long_press,
std::optional<HookCallback> repeat)
: name_(name),
click_("click", click),
double_click_("double_click", double_click),
long_press_("long_press", long_press),
repeat_("repeat", repeat) {}
@ -51,6 +53,9 @@ auto TriggerHooks::update(bool pressed, lv_indev_data_t* d) -> void {
case Trigger::State::kClick:
click_.invoke(d);
break;
case Trigger::State::kDoubleClick:
double_click_.invoke(d);
break;
case Trigger::State::kLongPress:
long_press_.invoke(d);
break;

@ -15,8 +15,8 @@ namespace input {
NavButtons::NavButtons(drivers::IGpios& gpios)
: gpios_(gpios),
up_("upper", actions::scrollUp(), actions::select(), {}),
down_("lower", actions::scrollDown(), actions::select(), {}) {}
up_("upper", {}, actions::scrollUp(), actions::select(), {}),
down_("lower", {}, actions::scrollDown(), actions::select(), {}) {}
auto NavButtons::read(lv_indev_data_t* data) -> void {
up_.update(!gpios_.Get(drivers::IGpios::Pin::kKeyUp), data);

@ -21,9 +21,9 @@ namespace input {
TouchDPad::TouchDPad(drivers::TouchWheel& wheel)
: wheel_(wheel),
centre_("centre", actions::select(), {}, {}),
centre_("centre", actions::select(), {}, {}, {}),
up_("up", actions::scrollUp()),
right_("right", {}, {}, {}),
right_("right", {}),
down_("down", actions::scrollDown()),
left_("left", actions::goBack()) {}

@ -39,11 +39,11 @@ TouchWheel::TouchWheel(drivers::NvsStorage& nvs, drivers::TouchWheel& wheel)
threshold_ = calculateThreshold(int_val);
return true;
}),
centre_("centre", actions::select(), {}, {}),
up_("up", {}, actions::scrollToTop(), actions::scrollUp()),
right_("right", {}, {}, {}),
down_("down", {}, actions::scrollToBottom(), actions::scrollDown()),
left_("left", {}, actions::goBack(), {}),
centre_("centre", actions::select(), {}, {}, {}),
up_("up", {}, actions::scrollToTop(), {}, {}),
right_("right", {}),
down_("down", {}, actions::scrollToBottom(), {}, {}),
left_("left", {}, actions::goBack(), {}, {}),
is_scrolling_(false),
threshold_(calculateThreshold(nvs.ScrollSensitivity())),
is_first_read_(true),
@ -68,7 +68,8 @@ auto TouchWheel::read(lv_indev_data_t* data) -> void {
data->enc_diff = 0;
}
centre_.update(!is_scrolling_ && wheel_data.is_button_touched, data);
centre_.update(wheel_data.is_button_touched && !wheel_data.is_wheel_touched,
data);
// If the user is touching the wheel but not scrolling, then they may be
// clicking on one of the wheel's cardinal directions.

@ -8,34 +8,50 @@
#include <sys/_stdint.h>
#include <cstdint>
#include "esp_log.h"
#include "esp_timer.h"
namespace input {
Trigger::Trigger() : touch_time_ms_(), times_fired_(0) {}
Trigger::Trigger()
: touch_time_ms_(),
was_pressed_(false),
was_double_click_(false),
times_long_pressed_(0) {}
auto Trigger::update(bool is_pressed) -> State {
// Bail out early if we're in a steady-state of not pressed.
if (!is_pressed && !touch_time_ms_) {
if (!is_pressed && !was_pressed_) {
was_double_click_ = false;
times_long_pressed_ = 0;
return State::kNone;
}
uint64_t now_ms = esp_timer_get_time() / 1000;
// Initial press of this key: record the current time, and report that we
// haven't triggered yet.
if (is_pressed && !touch_time_ms_) {
// This key wasn't being pressed, but now it is.
if (is_pressed && !was_pressed_) {
// Is this a double click?
if (now_ms - *touch_time_ms_ < kDoubleClickDelayMs) {
// Don't update touch_time_ms_, since we don't want triple clicks to
// register as double clicks.
was_double_click_ = true;
was_pressed_ = true;
return State::kDoubleClick;
}
// Not a double click; update our accounting info and wait for the next
// call.
touch_time_ms_ = now_ms;
times_fired_ = 0;
was_double_click_ = false;
times_long_pressed_ = 0;
was_pressed_ = true;
return State::kNone;
}
// The key was released. If there were no long-press events fired during the
// press, then this was a standard click.
if (!is_pressed && touch_time_ms_) {
touch_time_ms_.reset();
if (times_fired_ == 0) {
if (!is_pressed && was_pressed_) {
was_pressed_ = false;
if (!was_double_click_ && times_long_pressed_ == 0) {
return State::kClick;
} else {
return State::kNone;
@ -43,10 +59,10 @@ auto Trigger::update(bool is_pressed) -> State {
}
// Now the more complicated case: the user is continuing to press the button.
if (times_fired_ == 0) {
if (times_long_pressed_ == 0) {
// We haven't fired yet, so we wait for the long-press event.
if (now_ms - *touch_time_ms_ >= kLongPressDelayMs) {
times_fired_++;
times_long_pressed_++;
return State::kLongPress;
}
} else {
@ -60,8 +76,8 @@ auto Trigger::update(bool is_pressed) -> State {
// kRepeatDelayMs since the long-press event.
uint16_t expected_times_fired =
1 + (time_since_long_press / kRepeatDelayMs);
if (times_fired_ < expected_times_fired) {
times_fired_++;
if (times_long_pressed_ < expected_times_fired) {
times_long_pressed_++;
return State::kRepeatPress;
}
}

Loading…
Cancel
Save