diff options
| author | cooljqln <cooljqln@noreply.codeberg.org> | 2024-04-11 07:02:53 +0000 |
|---|---|---|
| committer | cooljqln <cooljqln@noreply.codeberg.org> | 2024-04-11 07:02:53 +0000 |
| commit | dd1ea595a7753706d4fa5f19b66f3dc1cbd56a02 (patch) | |
| tree | 60bfa4569af0f9506ccffe85f19e89bbe2a83332 /src/input/input_trigger.cpp | |
| parent | f580928cbab797e4e8a3eae5ae1c0b18b8066066 (diff) | |
| parent | 33919e9e3f419e13318fa6b8217d8c8dcd86c1eb (diff) | |
| download | tangara-fw-dd1ea595a7753706d4fa5f19b66f3dc1cbd56a02.tar.gz | |
Merge pull request 'jqln/input-devices' (#62) from jqln/input-devices into main
Reviewed-on: https://codeberg.org/cool-tech-zone/tangara-fw/pulls/62
Reviewed-by: ailurux <ailurux@noreply.codeberg.org>
Diffstat (limited to 'src/input/input_trigger.cpp')
| -rw-r--r-- | src/input/input_trigger.cpp | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/src/input/input_trigger.cpp b/src/input/input_trigger.cpp new file mode 100644 index 00000000..9485ecb4 --- /dev/null +++ b/src/input/input_trigger.cpp @@ -0,0 +1,72 @@ +/* + * Copyright 2024 jacqueline <me@jacqueline.id.au> + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#include "input_trigger.hpp" +#include <sys/_stdint.h> + +#include <cstdint> +#include "esp_log.h" +#include "esp_timer.h" + +namespace input { + +Trigger::Trigger() : touch_time_ms_(), times_fired_(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_) { + 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_) { + touch_time_ms_ = now_ms; + times_fired_ = 0; + 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) { + return State::kClick; + } else { + return State::kNone; + } + } + + // Now the more complicated case: the user is continuing to press the button. + if (times_fired_ == 0) { + // We haven't fired yet, so we wait for the long-press event. + if (now_ms - *touch_time_ms_ >= kLongPressDelayMs) { + times_fired_++; + return State::kLongPress; + } + } else { + // We've already fired at least once. How long has the user been holding + // the key for? + uint64_t time_since_long_press = + now_ms - (*touch_time_ms_ + kLongPressDelayMs); + + // How many times should we have fired? + // 1 initial fire (for the long-press), plus one additional fire every + // 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_++; + return State::kRepeatPress; + } + } + + return State::kNone; +} + +} // namespace input |
