Merge pull request #720 from oltaco/newui-multiclick-toggles
new-ui: add double/triple clicks, buzzer and gps toggle functions
This commit is contained in:
@@ -225,11 +225,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool handleInput(char c) override {
|
bool handleInput(char c) override {
|
||||||
if (c == KEY_LEFT) {
|
if (c == KEY_LEFT || c == KEY_PREV) {
|
||||||
_page = (_page + HomePage::Count - 1) % HomePage::Count;
|
_page = (_page + HomePage::Count - 1) % HomePage::Count;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (c == KEY_RIGHT || c == KEY_SELECT) {
|
if (c == KEY_NEXT || c == KEY_RIGHT) {
|
||||||
_page = (_page + 1) % HomePage::Count;
|
_page = (_page + 1) % HomePage::Count;
|
||||||
if (_page == HomePage::RECENT) {
|
if (_page == HomePage::RECENT) {
|
||||||
_task->showAlert("Recent adverts", 800);
|
_task->showAlert("Recent adverts", 800);
|
||||||
@@ -331,7 +331,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool handleInput(char c) override {
|
bool handleInput(char c) override {
|
||||||
if (c == KEY_SELECT || c == KEY_RIGHT) {
|
if (c == KEY_NEXT || c == KEY_RIGHT) {
|
||||||
num_unread--;
|
num_unread--;
|
||||||
if (num_unread == 0) {
|
if (num_unread == 0) {
|
||||||
_task->gotoHomeScreen();
|
_task->gotoHomeScreen();
|
||||||
@@ -494,9 +494,13 @@ void UITask::loop() {
|
|||||||
#if defined(PIN_USER_BTN)
|
#if defined(PIN_USER_BTN)
|
||||||
int ev = user_btn.check();
|
int ev = user_btn.check();
|
||||||
if (ev == BUTTON_EVENT_CLICK) {
|
if (ev == BUTTON_EVENT_CLICK) {
|
||||||
c = checkDisplayOn(KEY_SELECT);
|
c = checkDisplayOn(KEY_NEXT);
|
||||||
} else if (ev == BUTTON_EVENT_LONG_PRESS) {
|
} else if (ev == BUTTON_EVENT_LONG_PRESS) {
|
||||||
c = handleLongPress(KEY_ENTER);
|
c = handleLongPress(KEY_ENTER);
|
||||||
|
} else if (ev == BUTTON_EVENT_DOUBLE_CLICK) {
|
||||||
|
c = handleDoubleClick(KEY_PREV);
|
||||||
|
} else if (ev == BUTTON_EVENT_TRIPLE_CLICK) {
|
||||||
|
c = handleTripleClick(KEY_SELECT);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(WIO_TRACKER_L1)
|
#if defined(WIO_TRACKER_L1)
|
||||||
@@ -516,9 +520,13 @@ void UITask::loop() {
|
|||||||
#if defined(PIN_USER_BTN_ANA)
|
#if defined(PIN_USER_BTN_ANA)
|
||||||
ev = analog_btn.check();
|
ev = analog_btn.check();
|
||||||
if (ev == BUTTON_EVENT_CLICK) {
|
if (ev == BUTTON_EVENT_CLICK) {
|
||||||
c = checkDisplayOn(KEY_SELECT);
|
c = checkDisplayOn(KEY_NEXT);
|
||||||
} else if (ev == BUTTON_EVENT_LONG_PRESS) {
|
} else if (ev == BUTTON_EVENT_LONG_PRESS) {
|
||||||
c = handleLongPress(KEY_ENTER);
|
c = handleLongPress(KEY_ENTER);
|
||||||
|
} else if (ev == BUTTON_EVENT_DOUBLE_CLICK) {
|
||||||
|
c = handleDoubleClick(KEY_PREV);
|
||||||
|
} else if (ev == BUTTON_EVENT_TRIPLE_CLICK) {
|
||||||
|
c = handleTripleClick(KEY_SELECT);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(DISP_BACKLIGHT) && defined(BACKLIGHT_BTN)
|
#if defined(DISP_BACKLIGHT) && defined(BACKLIGHT_BTN)
|
||||||
@@ -615,20 +623,53 @@ char UITask::handleLongPress(char c) {
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
char UITask::handleDoubleClick(char c) {
|
||||||
void UITask::handleButtonTriplePress() {
|
MESH_DEBUG_PRINTLN("UITask: double click triggered");
|
||||||
MESH_DEBUG_PRINTLN("UITask: triple press triggered");
|
checkDisplayOn(c);
|
||||||
// Toggle buzzer quiet mode
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
char UITask::handleTripleClick(char c) {
|
||||||
|
MESH_DEBUG_PRINTLN("UITask: triple click triggered");
|
||||||
|
checkDisplayOn(c);
|
||||||
|
toggleBuzzer();
|
||||||
|
c = 0;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UITask::toggleGPS() {
|
||||||
|
if (_sensors != NULL) {
|
||||||
|
// toggle GPS on/off
|
||||||
|
int num = _sensors->getNumSettings();
|
||||||
|
for (int i = 0; i < num; i++) {
|
||||||
|
if (strcmp(_sensors->getSettingName(i), "gps") == 0) {
|
||||||
|
if (strcmp(_sensors->getSettingValue(i), "1") == 0) {
|
||||||
|
_sensors->setSettingValue("gps", "0");
|
||||||
|
soundBuzzer(UIEventType::ack);
|
||||||
|
showAlert("GPS: Disabled", 800);
|
||||||
|
} else {
|
||||||
|
_sensors->setSettingValue("gps", "1");
|
||||||
|
soundBuzzer(UIEventType::ack);
|
||||||
|
showAlert("GPS: Enabled", 800);
|
||||||
|
}
|
||||||
|
_next_refresh = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UITask::toggleBuzzer() {
|
||||||
|
// Toggle buzzer quiet mode
|
||||||
#ifdef PIN_BUZZER
|
#ifdef PIN_BUZZER
|
||||||
if (buzzer.isQuiet()) {
|
if (buzzer.isQuiet()) {
|
||||||
buzzer.quiet(false);
|
buzzer.quiet(false);
|
||||||
soundBuzzer(UIEventType::ack);
|
soundBuzzer(UIEventType::ack);
|
||||||
showAlert("Buzzer: ON", 600);
|
showAlert("Buzzer: ON", 800);
|
||||||
} else {
|
} else {
|
||||||
buzzer.quiet(true);
|
buzzer.quiet(true);
|
||||||
showAlert("Buzzer: OFF", 600);
|
showAlert("Buzzer: OFF", 800);
|
||||||
}
|
}
|
||||||
_next_refresh = 0; // trigger refresh
|
_next_refresh = 0; // trigger refresh
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ class UITask : public AbstractUITask {
|
|||||||
// Button action handlers
|
// Button action handlers
|
||||||
char checkDisplayOn(char c);
|
char checkDisplayOn(char c);
|
||||||
char handleLongPress(char c);
|
char handleLongPress(char c);
|
||||||
|
char handleDoubleClick(char c);
|
||||||
|
char handleTripleClick(char c);
|
||||||
|
|
||||||
void setCurrScreen(UIScreen* c);
|
void setCurrScreen(UIScreen* c);
|
||||||
|
|
||||||
@@ -61,6 +63,10 @@ public:
|
|||||||
bool hasDisplay() const { return _display != NULL; }
|
bool hasDisplay() const { return _display != NULL; }
|
||||||
bool isButtonPressed() const;
|
bool isButtonPressed() const;
|
||||||
|
|
||||||
|
void toggleBuzzer();
|
||||||
|
void toggleGPS();
|
||||||
|
|
||||||
|
|
||||||
// from AbstractUITask
|
// from AbstractUITask
|
||||||
void msgRead(int msgcount) override;
|
void msgRead(int msgcount) override;
|
||||||
void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) override;
|
void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) override;
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#include "MomentaryButton.h"
|
#include "MomentaryButton.h"
|
||||||
|
|
||||||
|
#define MULTI_CLICK_WINDOW_MS 280
|
||||||
|
|
||||||
MomentaryButton::MomentaryButton(int8_t pin, int long_press_millis, bool reverse, bool pulldownup) {
|
MomentaryButton::MomentaryButton(int8_t pin, int long_press_millis, bool reverse, bool pulldownup) {
|
||||||
_pin = pin;
|
_pin = pin;
|
||||||
_reverse = reverse;
|
_reverse = reverse;
|
||||||
@@ -9,6 +11,10 @@ MomentaryButton::MomentaryButton(int8_t pin, int long_press_millis, bool reverse
|
|||||||
cancel = 0;
|
cancel = 0;
|
||||||
_long_millis = long_press_millis;
|
_long_millis = long_press_millis;
|
||||||
_threshold = 0;
|
_threshold = 0;
|
||||||
|
_click_count = 0;
|
||||||
|
_last_click_time = 0;
|
||||||
|
_multi_click_window = MULTI_CLICK_WINDOW_MS;
|
||||||
|
_pending_click = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MomentaryButton::MomentaryButton(int8_t pin, int long_press_millis, int analog_threshold) {
|
MomentaryButton::MomentaryButton(int8_t pin, int long_press_millis, int analog_threshold) {
|
||||||
@@ -20,6 +26,10 @@ MomentaryButton::MomentaryButton(int8_t pin, int long_press_millis, int analog_t
|
|||||||
cancel = 0;
|
cancel = 0;
|
||||||
_long_millis = long_press_millis;
|
_long_millis = long_press_millis;
|
||||||
_threshold = analog_threshold;
|
_threshold = analog_threshold;
|
||||||
|
_click_count = 0;
|
||||||
|
_last_click_time = 0;
|
||||||
|
_multi_click_window = MULTI_CLICK_WINDOW_MS;
|
||||||
|
_pending_click = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MomentaryButton::begin() {
|
void MomentaryButton::begin() {
|
||||||
@@ -35,6 +45,10 @@ bool MomentaryButton::isPressed() const {
|
|||||||
|
|
||||||
void MomentaryButton::cancelClick() {
|
void MomentaryButton::cancelClick() {
|
||||||
cancel = 1;
|
cancel = 1;
|
||||||
|
down_at = 0;
|
||||||
|
_click_count = 0;
|
||||||
|
_last_click_time = 0;
|
||||||
|
_pending_click = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MomentaryButton::isPressed(int level) const {
|
bool MomentaryButton::isPressed(int level) const {
|
||||||
@@ -60,13 +74,20 @@ int MomentaryButton::check(bool repeat_click) {
|
|||||||
// button UP
|
// button UP
|
||||||
if (_long_millis > 0) {
|
if (_long_millis > 0) {
|
||||||
if (down_at > 0 && (unsigned long)(millis() - down_at) < _long_millis) { // only a CLICK if still within the long_press millis
|
if (down_at > 0 && (unsigned long)(millis() - down_at) < _long_millis) { // only a CLICK if still within the long_press millis
|
||||||
event = BUTTON_EVENT_CLICK;
|
_click_count++;
|
||||||
|
_last_click_time = millis();
|
||||||
|
_pending_click = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
event = BUTTON_EVENT_CLICK; // any UP results in CLICK event when NOT using long_press feature
|
_click_count++;
|
||||||
|
_last_click_time = millis();
|
||||||
|
_pending_click = true;
|
||||||
}
|
}
|
||||||
if (event == BUTTON_EVENT_CLICK && cancel) {
|
if (event == BUTTON_EVENT_CLICK && cancel) {
|
||||||
event = BUTTON_EVENT_NONE;
|
event = BUTTON_EVENT_NONE;
|
||||||
|
_click_count = 0;
|
||||||
|
_last_click_time = 0;
|
||||||
|
_pending_click = false;
|
||||||
}
|
}
|
||||||
down_at = 0;
|
down_at = 0;
|
||||||
}
|
}
|
||||||
@@ -77,8 +98,16 @@ int MomentaryButton::check(bool repeat_click) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_long_millis > 0 && down_at > 0 && (unsigned long)(millis() - down_at) >= _long_millis) {
|
if (_long_millis > 0 && down_at > 0 && (unsigned long)(millis() - down_at) >= _long_millis) {
|
||||||
event = BUTTON_EVENT_LONG_PRESS;
|
if (_pending_click) {
|
||||||
down_at = 0;
|
// long press during multi-click detection - cancel pending clicks
|
||||||
|
cancelClick();
|
||||||
|
} else {
|
||||||
|
event = BUTTON_EVENT_LONG_PRESS;
|
||||||
|
down_at = 0;
|
||||||
|
_click_count = 0;
|
||||||
|
_last_click_time = 0;
|
||||||
|
_pending_click = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (down_at > 0 && repeat_click) {
|
if (down_at > 0 && repeat_click) {
|
||||||
unsigned long diff = (unsigned long)(millis() - down_at);
|
unsigned long diff = (unsigned long)(millis() - down_at);
|
||||||
@@ -87,5 +116,30 @@ int MomentaryButton::check(bool repeat_click) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_pending_click && (millis() - _last_click_time) >= _multi_click_window) {
|
||||||
|
if (down_at > 0) {
|
||||||
|
// still pressed - wait for button release before processing clicks
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
switch (_click_count) {
|
||||||
|
case 1:
|
||||||
|
event = BUTTON_EVENT_CLICK;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
event = BUTTON_EVENT_DOUBLE_CLICK;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
event = BUTTON_EVENT_TRIPLE_CLICK;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// For 4+ clicks, treat as triple click?
|
||||||
|
event = BUTTON_EVENT_TRIPLE_CLICK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_click_count = 0;
|
||||||
|
_last_click_time = 0;
|
||||||
|
_pending_click = false;
|
||||||
|
}
|
||||||
|
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,8 @@
|
|||||||
#define BUTTON_EVENT_NONE 0
|
#define BUTTON_EVENT_NONE 0
|
||||||
#define BUTTON_EVENT_CLICK 1
|
#define BUTTON_EVENT_CLICK 1
|
||||||
#define BUTTON_EVENT_LONG_PRESS 2
|
#define BUTTON_EVENT_LONG_PRESS 2
|
||||||
|
#define BUTTON_EVENT_DOUBLE_CLICK 3
|
||||||
|
#define BUTTON_EVENT_TRIPLE_CLICK 4
|
||||||
|
|
||||||
class MomentaryButton {
|
class MomentaryButton {
|
||||||
int8_t _pin;
|
int8_t _pin;
|
||||||
@@ -13,6 +15,10 @@ class MomentaryButton {
|
|||||||
int _long_millis;
|
int _long_millis;
|
||||||
int _threshold; // analog mode
|
int _threshold; // analog mode
|
||||||
unsigned long down_at;
|
unsigned long down_at;
|
||||||
|
uint8_t _click_count;
|
||||||
|
unsigned long _last_click_time;
|
||||||
|
int _multi_click_window;
|
||||||
|
bool _pending_click;
|
||||||
|
|
||||||
bool isPressed(int level) const;
|
bool isPressed(int level) const;
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,17 @@
|
|||||||
|
|
||||||
#include "DisplayDriver.h"
|
#include "DisplayDriver.h"
|
||||||
|
|
||||||
#define KEY_LEFT 0xB4
|
#define KEY_LEFT 0xB4
|
||||||
#define KEY_UP 0xB5
|
#define KEY_UP 0xB5
|
||||||
#define KEY_DOWN 0xB6
|
#define KEY_DOWN 0xB6
|
||||||
#define KEY_RIGHT 0xB7
|
#define KEY_RIGHT 0xB7
|
||||||
#define KEY_SELECT 10
|
#define KEY_SELECT 10
|
||||||
#define KEY_ENTER 13
|
#define KEY_ENTER 13
|
||||||
#define KEY_BACK 27 // Esc
|
#define KEY_CANCEL 27 // Esc
|
||||||
|
#define KEY_HOME 0xF0
|
||||||
|
#define KEY_NEXT 0xF1
|
||||||
|
#define KEY_PREV 0xF2
|
||||||
|
#define KEY_CONTEXT_MENU 0xF3
|
||||||
|
|
||||||
class UIScreen {
|
class UIScreen {
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
Reference in New Issue
Block a user