mirror of
https://github.com/pelgraine/Meck.git
synced 2026-08-09 18:22:45 +02:00
T-Watch: standalone channel config screen (region, notifications, delete)
The SettingsScreen SUB_CHANNELS sub-screen drives every per-channel action from physical-keyboard hotkeys (Ent: scope, N: notif, T: tone, X/Hold: delete), so on the touch-only watches the channel list rendered but nothing was actionable. Replace it on MECK_TWATCH builds with a standalone WatchChannelConfigScreen following the WatchAlarmScreen / WatchNotesScreen conventions. Desktop builds are unchanged. LIST shows each channel with its region scope tag and notification state (tap to select, tap again or button to open, paged like Notes). DETAIL offers: Region -- opens the watch keyboard via a new TWKB_SCOPE purpose, pre-filled with the current scope, committed through the same setChannel + saveChannels path as desktop (empty submission clears); Clear region -- reverts to the device default directly; Notify -- tap-cycles All -> Mentions -> Off with savePrefs, matching the desktop N-key order. Delete is button-driven rather than touch: a short press (PWR on the S3, boot button on the Plus) arms it, a second press within 3s confirms. Channel 0 remains protected. The tone picker is deliberately absent -- the watch has no audio path. Settings hands off via a _wantsWatchChannels flag polled by UITask::loop (mirrors the _needsTextVKB handshake); Back returns to Settings via gotoSettingsScreen. Keyboard results route through the existing consumeSendRequest purpose dispatch. Note: deleteChannel replicates SettingsScreen's compaction verbatim, including its existing quirk of not shifting channel_notif[] -- kept faithful rather than silently diverging; fix both together if desired. Files: WatchChannelConfigScreen.h (new, both variant dirs), TWatchComposeScreens.h (both variant dirs, TWKB_SCOPE), SettingsScreen.h, UITask.h, UITask.cpp, main.cpp
This commit is contained in:
@@ -1130,6 +1130,7 @@ static uint32_t _atoi(const char* sp) {
|
||||
#endif
|
||||
#if defined(MECK_TWATCH)
|
||||
#include "WatchNotesScreen.h" // After UITask.h -- needs NodePrefs
|
||||
#include "WatchChannelConfigScreen.h" // After UITask.h -- needs NodePrefs, the_mesh
|
||||
#endif
|
||||
#if defined(MECK_TWATCH) && HAS_GPS
|
||||
#include "WatchMapScreen.h" // After BLE -- PNGdec headers conflict with BLE if included earlier
|
||||
@@ -1385,6 +1386,13 @@ static void lastHeardToggleContact() {
|
||||
if (wn) wn->handleTap(x, y);
|
||||
return 0;
|
||||
}
|
||||
// Channel config screen: list rows, detail action rows and the footer are
|
||||
// all tap targets, in the same logical coords as the alarm/notes screens.
|
||||
if (ui_task.isOnWatchChannelConfigScreen()) {
|
||||
WatchChannelConfigScreen* wc = (WatchChannelConfigScreen*)ui_task.getWatchChannelConfigScreen();
|
||||
if (wc) wc->handleTap(x, y);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#if defined(MECK_TWATCH)
|
||||
// Watch: tiles open on long-press and pages change on swipe, so a plain tap
|
||||
|
||||
@@ -341,6 +341,7 @@ private:
|
||||
|
||||
// T5S3: signal UITask to open VKB when entering text edit mode
|
||||
bool _needsTextVKB;
|
||||
bool _wantsWatchChannels; // Watch: hand off to WatchChannelConfigScreen (polled by UITask)
|
||||
|
||||
// 4G modem state (runtime cache of config)
|
||||
#ifdef HAS_4G_MODEM
|
||||
@@ -698,7 +699,7 @@ public:
|
||||
_editMode(EDIT_NONE), _editPos(0), _editPickerIdx(0),
|
||||
_editFloat(0), _editInt(0), _fontPickerOriginal(0), _confirmAction(0),
|
||||
_onboarding(false), _subScreen(SUB_NONE), _savedTopCursor(0),
|
||||
_radioChanged(false), _needsTextVKB(false) {
|
||||
_radioChanged(false), _needsTextVKB(false), _wantsWatchChannels(false) {
|
||||
memset(_editBuf, 0, sizeof(_editBuf));
|
||||
#ifdef HAS_SDCARD
|
||||
_savedExportCursor = 0;
|
||||
@@ -939,6 +940,8 @@ public:
|
||||
// T5S3 VKB integration for text editing (channel name, device name, freq, APN)
|
||||
bool needsTextVKB() const { return _needsTextVKB; }
|
||||
void clearTextNeedsVKB() { _needsTextVKB = false; }
|
||||
bool wantsWatchChannels() const { return _wantsWatchChannels; }
|
||||
void clearWantsWatchChannels() { _wantsWatchChannels = false; }
|
||||
const char* getEditBuf() const { return _editBuf; }
|
||||
SettingsRowType getCurrentRowType() const { return _rows[_cursor].type; }
|
||||
void submitEditText(const char* text) {
|
||||
@@ -3798,12 +3801,18 @@ public:
|
||||
Serial.println("Settings: entered Contacts sub-screen");
|
||||
break;
|
||||
case ROW_CHANNELS_SUBMENU:
|
||||
#if defined(MECK_TWATCH)
|
||||
// Watch: the desktop sub-screen's per-channel actions are keyboard
|
||||
// hotkeys; hand off to the standalone WatchChannelConfigScreen.
|
||||
_wantsWatchChannels = true; // UITask::loop() polls and opens it
|
||||
#else
|
||||
_savedTopCursor = _cursor;
|
||||
_subScreen = SUB_CHANNELS;
|
||||
_cursor = 0;
|
||||
_scrollTop = 0;
|
||||
rebuildRows();
|
||||
Serial.println("Settings: entered Channels sub-screen");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case ROW_RXLOG:
|
||||
|
||||
@@ -84,6 +84,7 @@
|
||||
#endif
|
||||
#if defined(MECK_TWATCH)
|
||||
#include "WatchNotesScreen.h" // After UITask.h -- needs NodePrefs
|
||||
#include "WatchChannelConfigScreen.h" // After UITask.h -- needs NodePrefs, the_mesh
|
||||
#endif
|
||||
#ifdef TWATCH_COMPOSE_ENABLED
|
||||
#include "TWatchComposeScreens.h"
|
||||
@@ -1798,6 +1799,7 @@ void UITask::begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* no
|
||||
#if defined(MECK_TWATCH)
|
||||
// LittleFS ("/maps" partition) is mounted in setup() before UITask::begin().
|
||||
watch_notes_screen = new WatchNotesScreen(this, &rtc_clock, node_prefs);
|
||||
watch_channel_cfg_screen = new WatchChannelConfigScreen(this, node_prefs);
|
||||
#endif
|
||||
#ifdef TWATCH_COMPOSE_ENABLED
|
||||
tw_picker = new TWatchChannelPicker(_display);
|
||||
@@ -2613,6 +2615,13 @@ if (curr) curr->poll();
|
||||
if (watch_notes_screen) setCurrScreen(watch_notes_screen);
|
||||
else gotoHomeScreen();
|
||||
if (nerr) showAlert(nerr, 1200);
|
||||
} else if (purpose == TWatchKeyboardScreen::TWKB_SCOPE) {
|
||||
WatchChannelConfigScreen* wc = (WatchChannelConfigScreen*)watch_channel_cfg_screen;
|
||||
const char* serr = wc ? wc->applyComposedScope(sendText) : "No channel cfg";
|
||||
kb->clearOutBuf();
|
||||
if (watch_channel_cfg_screen) setCurrScreen(watch_channel_cfg_screen);
|
||||
else gotoHomeScreen();
|
||||
if (serr) showAlert(serr, 1200);
|
||||
} else { // TWKB_ADMIN_PASSWORD or TWKB_ADMIN_CLI
|
||||
RepeaterAdminScreen* admin = (RepeaterAdminScreen*)getRepeaterAdminScreen();
|
||||
if (admin) {
|
||||
@@ -2642,6 +2651,27 @@ if (curr) curr->poll();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (curr == watch_channel_cfg_screen && watch_channel_cfg_screen != nullptr) {
|
||||
WatchChannelConfigScreen* wc = (WatchChannelConfigScreen*)watch_channel_cfg_screen;
|
||||
if (wc->wantsKeyboard()) {
|
||||
wc->clearWantKeyboard();
|
||||
openTWatchKeyboard(TWatchKeyboardScreen::TWKB_SCOPE, 0);
|
||||
((TWatchKeyboardScreen*)tw_keyboard)->setInitialText(wc->getEditText());
|
||||
} else if (wc->wantsExit()) {
|
||||
wc->clearWantExit();
|
||||
gotoSettingsScreen();
|
||||
}
|
||||
}
|
||||
else if (curr == settings_screen && settings_screen != nullptr) {
|
||||
SettingsScreen* ss = (SettingsScreen*)settings_screen;
|
||||
if (ss->wantsWatchChannels()) {
|
||||
ss->clearWantsWatchChannels();
|
||||
if (watch_channel_cfg_screen) {
|
||||
((WatchChannelConfigScreen*)watch_channel_cfg_screen)->enter();
|
||||
setCurrScreen(watch_channel_cfg_screen);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_display != NULL && _display->isOn()) {
|
||||
|
||||
@@ -144,6 +144,7 @@ class UITask : public AbstractUITask {
|
||||
#endif
|
||||
#if defined(MECK_TWATCH)
|
||||
UIScreen* watch_notes_screen; // LittleFS note pad (shared NotesScreen needs SD)
|
||||
UIScreen* watch_channel_cfg_screen; // Per-channel region/notif/delete (touch UI)
|
||||
#endif
|
||||
UIScreen* _screenBeforeLock = nullptr;
|
||||
bool _locked = false;
|
||||
@@ -325,6 +326,7 @@ public:
|
||||
#endif
|
||||
#if defined(MECK_TWATCH)
|
||||
bool isOnWatchNotesScreen() const { return curr == watch_notes_screen; }
|
||||
bool isOnWatchChannelConfigScreen() const { return curr == watch_channel_cfg_screen; }
|
||||
#endif
|
||||
bool isOnMinesweeperScreen() const { return curr == minesweeper_screen; }
|
||||
bool isOnMapScreen() const { return curr == map_screen; }
|
||||
@@ -424,6 +426,7 @@ public:
|
||||
#endif
|
||||
#if defined(MECK_TWATCH)
|
||||
UIScreen* getWatchNotesScreen() const { return watch_notes_screen; }
|
||||
UIScreen* getWatchChannelConfigScreen() const { return watch_channel_cfg_screen; }
|
||||
#endif
|
||||
UIScreen* getMinesweeperScreen() const { return minesweeper_screen; }
|
||||
UIScreen* getMapScreen() const { return map_screen; }
|
||||
|
||||
Reference in New Issue
Block a user