mirror of
https://github.com/meshtastic/firmware.git
synced 2025-06-08 06:02:05 +00:00
button thread cleanup
This commit is contained in:
parent
673f5d3ede
commit
e869e1b146
@ -13,6 +13,7 @@
|
||||
#include "modules/ExternalNotificationModule.h"
|
||||
#include "power.h"
|
||||
#include "sleep.h"
|
||||
#include "input/InputBroker.h"
|
||||
#ifdef ARCH_PORTDUINO
|
||||
#include "platform/portduino/PortduinoGlue.h"
|
||||
#endif
|
||||
@ -262,6 +263,48 @@ int32_t ButtonThread::runOnce()
|
||||
#endif
|
||||
|
||||
if (btnEvent != BUTTON_EVENT_NONE) {
|
||||
#if HAS_SCREEN
|
||||
switch (btnEvent) {
|
||||
case BUTTON_EVENT_PRESSED: {
|
||||
LOG_BUTTON("press!");
|
||||
|
||||
// Play boop sound for every button press
|
||||
playBoop();
|
||||
|
||||
// Forward single press to InputBroker (but NOT as DOWN/SELECT, just forward a "button press" event)
|
||||
if (inputBroker) {
|
||||
InputEvent evt = { "button", INPUT_BROKER_MSG_BUTTON_PRESSED, 0, 0, 0 };
|
||||
inputBroker->injectInputEvent(&evt);
|
||||
}
|
||||
|
||||
// Start tracking for potential combination
|
||||
waitingForLongPress = true;
|
||||
shortPressTime = millis();
|
||||
|
||||
break;
|
||||
}
|
||||
case BUTTON_EVENT_LONG_PRESSED: {
|
||||
LOG_BUTTON("Long press!");
|
||||
|
||||
// Play beep sound
|
||||
playBeep();
|
||||
|
||||
// Forward long press to InputBroker (but NOT as DOWN/SELECT, just forward a "button long press" event)
|
||||
if (inputBroker) {
|
||||
InputEvent evt = { "button", INPUT_BROKER_MSG_BUTTON_LONG_PRESSED, 0, 0, 0 };
|
||||
inputBroker->injectInputEvent(&evt);
|
||||
}
|
||||
|
||||
waitingForLongPress = false;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// Ignore all other events on screen devices
|
||||
break;
|
||||
}
|
||||
btnEvent = BUTTON_EVENT_NONE;
|
||||
#else
|
||||
// On devices without screen: full legacy logic
|
||||
switch (btnEvent) {
|
||||
case BUTTON_EVENT_PRESSED: {
|
||||
LOG_BUTTON("press!");
|
||||
@ -489,6 +532,7 @@ int32_t ButtonThread::runOnce()
|
||||
break;
|
||||
}
|
||||
btnEvent = BUTTON_EVENT_NONE;
|
||||
#endif
|
||||
}
|
||||
|
||||
return 50;
|
||||
|
@ -8,9 +8,14 @@
|
||||
#define BUTTON_CLICK_MS 250
|
||||
#endif
|
||||
|
||||
#ifdef HAS_SCREEN
|
||||
#undef BUTTON_LONGPRESS_MS
|
||||
#define BUTTON_LONGPRESS_MS 500
|
||||
#else
|
||||
#ifndef BUTTON_LONGPRESS_MS
|
||||
#define BUTTON_LONGPRESS_MS 5000
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef BUTTON_TOUCH_MS
|
||||
#define BUTTON_TOUCH_MS 400
|
||||
|
@ -1781,7 +1781,6 @@ int Screen::handleUIFrameEvent(const UIFrameEvent *event)
|
||||
|
||||
int Screen::handleInputEvent(const InputEvent *event)
|
||||
{
|
||||
|
||||
#if defined(DISPLAY_CLOCK_FRAME)
|
||||
// For the T-Watch, intercept touches to the 'toggle digital/analog watch face' button
|
||||
uint8_t watchFaceFrame = error_code ? 1 : 0;
|
||||
@ -1812,6 +1811,17 @@ int Screen::handleInputEvent(const InputEvent *event)
|
||||
inputIntercepted = true;
|
||||
}
|
||||
|
||||
// Only allow BUTTON_PRESSED and BUTTON_LONG_PRESSED to trigger frame changes if no module is handling input
|
||||
if (!inputIntercepted) {
|
||||
if (event->inputEvent == INPUT_BROKER_MSG_BUTTON_PRESSED) {
|
||||
showNextFrame();
|
||||
return 0;
|
||||
} else if (event->inputEvent == INPUT_BROKER_MSG_BUTTON_LONG_PRESSED) {
|
||||
// Optional: Define alternate screen action or no-op
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// If no modules are using the input, move between frames
|
||||
if (!inputIntercepted) {
|
||||
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT))
|
||||
|
@ -21,6 +21,8 @@
|
||||
#define INPUT_BROKER_MSG_BLUETOOTH_TOGGLE 0xAA
|
||||
#define INPUT_BROKER_MSG_TAB 0x09
|
||||
#define INPUT_BROKER_MSG_EMOTE_LIST 0x8F
|
||||
#define INPUT_BROKER_MSG_BUTTON_PRESSED 0xe1
|
||||
#define INPUT_BROKER_MSG_BUTTON_LONG_PRESSED 0xe2
|
||||
|
||||
typedef struct _InputEvent {
|
||||
const char *source;
|
||||
@ -37,6 +39,7 @@ class InputBroker : public Observable<const InputEvent *>
|
||||
public:
|
||||
InputBroker();
|
||||
void registerSource(Observable<const InputEvent *> *source);
|
||||
void injectInputEvent(const InputEvent *event) { handleInputEvent(event); }
|
||||
|
||||
protected:
|
||||
int handleInputEvent(const InputEvent *event);
|
||||
|
@ -292,7 +292,9 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
|
||||
switch (runState) {
|
||||
// Node/Channel destination selection mode: Handles character search, arrows, select, cancel, backspace
|
||||
case CANNED_MESSAGE_RUN_STATE_DESTINATION_SELECTION:
|
||||
return handleDestinationSelectionInput(event, isUp, isDown, isSelect); // All allowed input for this state
|
||||
if (handleDestinationSelectionInput(event, isUp, isDown, isSelect))
|
||||
return 1;
|
||||
return 0; // prevent fall-through to selector input
|
||||
|
||||
// Free text input mode: Handles character input, cancel, backspace, select, etc.
|
||||
case CANNED_MESSAGE_RUN_STATE_FREETEXT:
|
||||
@ -408,6 +410,15 @@ bool CannedMessageModule::handleTabSwitch(const InputEvent *event)
|
||||
|
||||
int CannedMessageModule::handleDestinationSelectionInput(const InputEvent *event, bool isUp, bool isDown, bool isSelect)
|
||||
{
|
||||
// Override isDown and isSelect ONLY for destination selector behavior
|
||||
if (runState == CANNED_MESSAGE_RUN_STATE_DESTINATION_SELECTION) {
|
||||
if (event->inputEvent == INPUT_BROKER_MSG_BUTTON_PRESSED) {
|
||||
isDown = true;
|
||||
} else if (event->inputEvent == INPUT_BROKER_MSG_BUTTON_LONG_PRESSED) {
|
||||
isSelect = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (event->kbchar >= 32 && event->kbchar <= 126 && !isUp && !isDown &&
|
||||
event->inputEvent != static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT) &&
|
||||
event->inputEvent != static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT) &&
|
||||
@ -503,6 +514,15 @@ int CannedMessageModule::handleDestinationSelectionInput(const InputEvent *event
|
||||
|
||||
bool CannedMessageModule::handleMessageSelectorInput(const InputEvent *event, bool isUp, bool isDown, bool isSelect)
|
||||
{
|
||||
// Override isDown and isSelect ONLY for canned message list behavior
|
||||
if (runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) {
|
||||
if (event->inputEvent == INPUT_BROKER_MSG_BUTTON_PRESSED) {
|
||||
isDown = true;
|
||||
} else if (event->inputEvent == INPUT_BROKER_MSG_BUTTON_LONG_PRESSED) {
|
||||
isSelect = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (runState == CANNED_MESSAGE_RUN_STATE_DESTINATION_SELECTION)
|
||||
return false;
|
||||
|
||||
@ -591,7 +611,6 @@ bool CannedMessageModule::handleMessageSelectorInput(const InputEvent *event, bo
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
bool CannedMessageModule::handleFreeTextInput(const InputEvent *event)
|
||||
{
|
||||
// Always process only if in FREETEXT mode
|
||||
@ -732,9 +751,18 @@ bool CannedMessageModule::handleFreeTextInput(const InputEvent *event)
|
||||
int CannedMessageModule::handleEmotePickerInput(const InputEvent *event)
|
||||
{
|
||||
int numEmotes = graphics::numEmotes;
|
||||
|
||||
// Override isDown and isSelect ONLY for emote picker behavior
|
||||
bool isUp = isUpEvent(event);
|
||||
bool isDown = isDownEvent(event);
|
||||
bool isSelect = isSelectEvent(event);
|
||||
if (runState == CANNED_MESSAGE_RUN_STATE_EMOTE_PICKER) {
|
||||
if (event->inputEvent == INPUT_BROKER_MSG_BUTTON_PRESSED) {
|
||||
isDown = true;
|
||||
} else if (event->inputEvent == INPUT_BROKER_MSG_BUTTON_LONG_PRESSED) {
|
||||
isSelect = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Scroll emote list
|
||||
if (isUp && emotePickerIndex > 0) {
|
||||
@ -747,6 +775,7 @@ int CannedMessageModule::handleEmotePickerInput(const InputEvent *event)
|
||||
screen->forceDisplay();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Select emote: insert into freetext at cursor and return to freetext
|
||||
if (isSelect) {
|
||||
String label = graphics::emotes[emotePickerIndex].label;
|
||||
@ -761,12 +790,14 @@ int CannedMessageModule::handleEmotePickerInput(const InputEvent *event)
|
||||
screen->forceDisplay();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Cancel returns to freetext
|
||||
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL)) {
|
||||
runState = CANNED_MESSAGE_RUN_STATE_FREETEXT;
|
||||
screen->forceDisplay();
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user