mirror of
https://github.com/pelgraine/Meck.git
synced 2026-08-06 16:52:46 +02:00
tdpro settings screen updates and ui changes; gps baudrate selector kept to settings screen only; firmware version and build date updated
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef FIRMWARE_VERSION
|
||||
#define FIRMWARE_VERSION "Meck v1.0.1"
|
||||
#define FIRMWARE_VERSION "Meck v1.1"
|
||||
#endif
|
||||
|
||||
#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
|
||||
|
||||
@@ -51,6 +51,25 @@ extern MyMesh the_mesh;
|
||||
// ---------------------------------------------------------------------------
|
||||
#include "RadioPresets.h"
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// GPS baud rate options (shared with UITask GPS home page overlay)
|
||||
// ---------------------------------------------------------------------------
|
||||
static const uint32_t GPS_BAUD_OPTIONS[] = { 0, 4800, 9600, 19200, 38400, 57600, 115200 };
|
||||
#define GPS_BAUD_OPTION_COUNT 7
|
||||
|
||||
static inline const char* gpsBaudLabel(uint32_t baud, char* buf, int bufLen) {
|
||||
if (baud == 0) return "Default (38400)";
|
||||
snprintf(buf, bufLen, "%lu", (unsigned long)baud);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static inline int findGpsBaudIndex(uint32_t baud) {
|
||||
for (int i = 0; i < GPS_BAUD_OPTION_COUNT; i++) {
|
||||
if (GPS_BAUD_OPTIONS[i] == baud) return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Settings row types
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -64,10 +83,11 @@ enum SettingsRowType : uint8_t {
|
||||
ROW_TX_POWER, // TX power (1-20 dBm)
|
||||
ROW_UTC_OFFSET, // UTC offset (-12 to +14)
|
||||
ROW_MSG_NOTIFY, // Keyboard flash on new msg toggle
|
||||
ROW_DARK_MODE, // Dark mode toggle (inverted display)
|
||||
#if defined(LilyGo_T5S3_EPaper_Pro)
|
||||
ROW_DARK_MODE, // Dark mode toggle (inverted display)
|
||||
ROW_PORTRAIT_MODE, // Portrait orientation toggle
|
||||
#endif
|
||||
ROW_GPS_BAUD, // GPS baud rate picker (requires reboot)
|
||||
ROW_PATH_HASH_SIZE, // Path hash size (1, 2, or 3 bytes per hop)
|
||||
#ifdef MECK_WIFI_COMPANION
|
||||
ROW_WIFI_SETUP, // WiFi SSID/password configuration
|
||||
@@ -84,6 +104,8 @@ enum SettingsRowType : uint8_t {
|
||||
ROW_AUTOADD_ROOM, // Toggle: auto-add Room Servers
|
||||
ROW_AUTOADD_SENSOR, // Toggle: auto-add Sensors
|
||||
ROW_AUTOADD_OVERWRITE, // Toggle: overwrite oldest non-favourite when full
|
||||
ROW_CONTACTS_SUBMENU, // Folder row → enters Contacts sub-screen
|
||||
ROW_CHANNELS_SUBMENU, // Folder row → enters Channels sub-screen
|
||||
ROW_CH_HEADER, // "--- Channels ---" separator
|
||||
ROW_CHANNEL, // A channel entry (dynamic, index stored separately)
|
||||
ROW_ADD_CHANNEL, // "+ Add Hashtag Channel"
|
||||
@@ -111,6 +133,15 @@ enum EditMode : uint8_t {
|
||||
#endif
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Settings sub-screens (collapsible sections)
|
||||
// ---------------------------------------------------------------------------
|
||||
enum SubScreen : uint8_t {
|
||||
SUB_NONE, // Top-level settings list
|
||||
SUB_CONTACTS, // Contacts settings sub-screen
|
||||
SUB_CHANNELS, // Channels management sub-screen
|
||||
};
|
||||
|
||||
// Max rows in the settings list (increased for contact sub-toggles + WiFi)
|
||||
#if defined(HAS_4G_MODEM) && defined(MECK_WIFI_COMPANION)
|
||||
#define SETTINGS_MAX_ROWS 56 // Extra rows for IMEI, Carrier, APN, contacts, WiFi
|
||||
@@ -153,6 +184,10 @@ private:
|
||||
// Onboarding mode
|
||||
bool _onboarding;
|
||||
|
||||
// Sub-screen navigation
|
||||
SubScreen _subScreen;
|
||||
int _savedTopCursor; // cursor position to restore when leaving sub-screen
|
||||
|
||||
// Dirty flag for radio params  prompt to apply
|
||||
bool _radioChanged;
|
||||
|
||||
@@ -240,66 +275,68 @@ private:
|
||||
void rebuildRows() {
|
||||
_numRows = 0;
|
||||
|
||||
addRow(ROW_NAME);
|
||||
addRow(ROW_RADIO_PRESET);
|
||||
addRow(ROW_FREQ);
|
||||
addRow(ROW_BW);
|
||||
addRow(ROW_SF);
|
||||
addRow(ROW_CR);
|
||||
addRow(ROW_TX_POWER);
|
||||
addRow(ROW_UTC_OFFSET);
|
||||
addRow(ROW_MSG_NOTIFY);
|
||||
addRow(ROW_PATH_HASH_SIZE);
|
||||
addRow(ROW_DARK_MODE);
|
||||
#if defined(LilyGo_T5S3_EPaper_Pro)
|
||||
addRow(ROW_PORTRAIT_MODE);
|
||||
#endif
|
||||
#ifdef MECK_WIFI_COMPANION
|
||||
addRow(ROW_WIFI_SETUP);
|
||||
addRow(ROW_WIFI_TOGGLE);
|
||||
#endif
|
||||
#ifdef HAS_4G_MODEM
|
||||
addRow(ROW_MODEM_TOGGLE);
|
||||
// addRow(ROW_RINGTONE);
|
||||
#endif
|
||||
|
||||
// --- Contacts section ---
|
||||
addRow(ROW_CONTACT_HEADER);
|
||||
addRow(ROW_CONTACT_MODE);
|
||||
|
||||
// Show per-type sub-toggles only in Custom mode
|
||||
if (getContactMode() == CONTACT_MODE_CUSTOM) {
|
||||
addRow(ROW_AUTOADD_CHAT);
|
||||
addRow(ROW_AUTOADD_REPEATER);
|
||||
addRow(ROW_AUTOADD_ROOM);
|
||||
addRow(ROW_AUTOADD_SENSOR);
|
||||
addRow(ROW_AUTOADD_OVERWRITE);
|
||||
}
|
||||
|
||||
// --- Channels section ---
|
||||
addRow(ROW_CH_HEADER);
|
||||
|
||||
// Enumerate current channels
|
||||
for (uint8_t i = 0; i < MAX_GROUP_CHANNELS; i++) {
|
||||
ChannelDetails ch;
|
||||
if (the_mesh.getChannel(i, ch) && ch.name[0] != '\0') {
|
||||
addRow(ROW_CHANNEL, i);
|
||||
} else {
|
||||
break; // channels are contiguous
|
||||
if (_subScreen == SUB_CONTACTS) {
|
||||
// --- Contacts sub-screen: only contact-related rows ---
|
||||
addRow(ROW_CONTACT_MODE);
|
||||
if (getContactMode() == CONTACT_MODE_CUSTOM) {
|
||||
addRow(ROW_AUTOADD_CHAT);
|
||||
addRow(ROW_AUTOADD_REPEATER);
|
||||
addRow(ROW_AUTOADD_ROOM);
|
||||
addRow(ROW_AUTOADD_SENSOR);
|
||||
addRow(ROW_AUTOADD_OVERWRITE);
|
||||
}
|
||||
} else if (_subScreen == SUB_CHANNELS) {
|
||||
// --- Channels sub-screen: only channel-related rows ---
|
||||
for (uint8_t i = 0; i < MAX_GROUP_CHANNELS; i++) {
|
||||
ChannelDetails ch;
|
||||
if (the_mesh.getChannel(i, ch) && ch.name[0] != '\0') {
|
||||
addRow(ROW_CHANNEL, i);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
addRow(ROW_ADD_CHANNEL);
|
||||
} else {
|
||||
// --- Top-level settings list ---
|
||||
addRow(ROW_NAME);
|
||||
addRow(ROW_RADIO_PRESET);
|
||||
addRow(ROW_FREQ);
|
||||
addRow(ROW_BW);
|
||||
addRow(ROW_SF);
|
||||
addRow(ROW_CR);
|
||||
addRow(ROW_TX_POWER);
|
||||
addRow(ROW_UTC_OFFSET);
|
||||
addRow(ROW_MSG_NOTIFY);
|
||||
addRow(ROW_GPS_BAUD);
|
||||
addRow(ROW_PATH_HASH_SIZE);
|
||||
#if defined(LilyGo_T5S3_EPaper_Pro)
|
||||
addRow(ROW_DARK_MODE);
|
||||
addRow(ROW_PORTRAIT_MODE);
|
||||
#endif
|
||||
#ifdef MECK_WIFI_COMPANION
|
||||
addRow(ROW_WIFI_SETUP);
|
||||
addRow(ROW_WIFI_TOGGLE);
|
||||
#endif
|
||||
#ifdef HAS_4G_MODEM
|
||||
addRow(ROW_MODEM_TOGGLE);
|
||||
#endif
|
||||
|
||||
// Folder rows for sub-screens
|
||||
addRow(ROW_CONTACTS_SUBMENU);
|
||||
addRow(ROW_CHANNELS_SUBMENU);
|
||||
|
||||
// Info section (stays at top level)
|
||||
addRow(ROW_INFO_HEADER);
|
||||
addRow(ROW_PUB_KEY);
|
||||
addRow(ROW_FIRMWARE);
|
||||
|
||||
#ifdef HAS_4G_MODEM
|
||||
addRow(ROW_IMEI);
|
||||
addRow(ROW_OPERATOR_INFO);
|
||||
addRow(ROW_APN);
|
||||
#endif
|
||||
}
|
||||
|
||||
addRow(ROW_ADD_CHANNEL);
|
||||
addRow(ROW_INFO_HEADER);
|
||||
addRow(ROW_PUB_KEY);
|
||||
addRow(ROW_FIRMWARE);
|
||||
|
||||
#ifdef HAS_4G_MODEM
|
||||
addRow(ROW_IMEI);
|
||||
addRow(ROW_OPERATOR_INFO);
|
||||
addRow(ROW_APN);
|
||||
#endif
|
||||
|
||||
// Clamp cursor
|
||||
if (_cursor >= _numRows) _cursor = _numRows - 1;
|
||||
if (_cursor < 0) _cursor = 0;
|
||||
@@ -321,7 +358,7 @@ private:
|
||||
#ifdef HAS_4G_MODEM
|
||||
&& t != ROW_IMEI && t != ROW_OPERATOR_INFO
|
||||
#endif
|
||||
;
|
||||
; // ROW_CONTACTS_SUBMENU and ROW_CHANNELS_SUBMENU ARE selectable
|
||||
}
|
||||
|
||||
void skipNonSelectable(int dir) {
|
||||
@@ -439,12 +476,15 @@ public:
|
||||
_numRows(0), _cursor(0), _scrollTop(0),
|
||||
_editMode(EDIT_NONE), _editPos(0), _editPickerIdx(0),
|
||||
_editFloat(0), _editInt(0), _confirmAction(0),
|
||||
_onboarding(false), _radioChanged(false) {
|
||||
_onboarding(false), _subScreen(SUB_NONE), _savedTopCursor(0),
|
||||
_radioChanged(false) {
|
||||
memset(_editBuf, 0, sizeof(_editBuf));
|
||||
}
|
||||
|
||||
void enter() {
|
||||
_editMode = EDIT_NONE;
|
||||
_subScreen = SUB_NONE;
|
||||
_savedTopCursor = 0;
|
||||
_cursor = 0;
|
||||
_scrollTop = 0;
|
||||
_radioChanged = false;
|
||||
@@ -477,42 +517,6 @@ public:
|
||||
bool isEditing() const { return _editMode != EDIT_NONE; }
|
||||
bool hasRadioChanges() const { return _radioChanged; }
|
||||
|
||||
// Returns true when cursor is on a non-public channel row (deletable)
|
||||
bool isCursorOnDeletableChannel() const {
|
||||
if (_cursor < 0 || _cursor >= _numRows) return false;
|
||||
return _rows[_cursor].type == ROW_CHANNEL && _rows[_cursor].param > 0
|
||||
&& _editMode == EDIT_NONE;
|
||||
}
|
||||
|
||||
// T5S3 VKB integration for text editing (channel name, device name, freq, APN)
|
||||
bool isEditingText() const { return _editMode == EDIT_TEXT; }
|
||||
bool isEditingNumOrPicker() const { return _editMode == EDIT_NUMBER || _editMode == EDIT_PICKER; }
|
||||
const char* getEditBuf() const { return _editBuf; }
|
||||
|
||||
// Get a suitable VKB label for the current text edit field
|
||||
const char* getEditLabel() const {
|
||||
if (_cursor < 0 || _cursor >= _numRows) return "Edit";
|
||||
switch (_rows[_cursor].type) {
|
||||
case ROW_NAME: return "Device Name";
|
||||
case ROW_ADD_CHANNEL: return "Add Channel";
|
||||
case ROW_FREQ: return "Frequency";
|
||||
#ifdef HAS_4G_MODEM
|
||||
case ROW_APN: return "Edit APN";
|
||||
#endif
|
||||
default: return "Edit";
|
||||
}
|
||||
}
|
||||
|
||||
// Fill edit buffer with VKB result and confirm via Enter
|
||||
void submitEditText(const char* text) {
|
||||
int len = strlen(text);
|
||||
if (len >= SETTINGS_TEXT_BUF) len = SETTINGS_TEXT_BUF - 1;
|
||||
memcpy(_editBuf, text, len);
|
||||
_editBuf[len] = '\0';
|
||||
_editPos = len;
|
||||
handleKeyInput('\r'); // trigger existing confirm logic
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// WiFi scan helpers
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -664,6 +668,10 @@ public:
|
||||
display.setCursor(0, 0);
|
||||
if (_onboarding) {
|
||||
display.print("Welcome! Setup");
|
||||
} else if (_subScreen == SUB_CONTACTS) {
|
||||
display.print("Settings > Contacts");
|
||||
} else if (_subScreen == SUB_CHANNELS) {
|
||||
display.print("Settings > Channels");
|
||||
} else {
|
||||
display.print("Settings");
|
||||
}
|
||||
@@ -809,13 +817,26 @@ public:
|
||||
display.print(tmp);
|
||||
break;
|
||||
|
||||
case ROW_GPS_BAUD: {
|
||||
char baudStr[16];
|
||||
if (editing && _editMode == EDIT_PICKER) {
|
||||
snprintf(tmp, sizeof(tmp), "< GPS Baud: %s > *",
|
||||
gpsBaudLabel(GPS_BAUD_OPTIONS[_editPickerIdx], baudStr, sizeof(baudStr)));
|
||||
} else {
|
||||
snprintf(tmp, sizeof(tmp), "GPS Baud: %s *",
|
||||
gpsBaudLabel(_prefs->gps_baudrate, baudStr, sizeof(baudStr)));
|
||||
}
|
||||
display.print(tmp);
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(LilyGo_T5S3_EPaper_Pro)
|
||||
case ROW_DARK_MODE:
|
||||
snprintf(tmp, sizeof(tmp), "Dark Mode: %s",
|
||||
_prefs->dark_mode ? "ON" : "OFF");
|
||||
display.print(tmp);
|
||||
break;
|
||||
|
||||
#if defined(LilyGo_T5S3_EPaper_Pro)
|
||||
case ROW_PORTRAIT_MODE:
|
||||
snprintf(tmp, sizeof(tmp), "Portrait Mode: %s",
|
||||
_prefs->portrait_mode ? "ON" : "OFF");
|
||||
@@ -853,6 +874,17 @@ public:
|
||||
// break;
|
||||
#endif
|
||||
|
||||
// --- Submenu folder rows ---
|
||||
case ROW_CONTACTS_SUBMENU:
|
||||
display.setColor(selected ? DisplayDriver::DARK : DisplayDriver::GREEN);
|
||||
display.print("Contacts >>");
|
||||
break;
|
||||
|
||||
case ROW_CHANNELS_SUBMENU:
|
||||
display.setColor(selected ? DisplayDriver::DARK : DisplayDriver::GREEN);
|
||||
display.print("Channels >>");
|
||||
break;
|
||||
|
||||
// --- Contacts section ---
|
||||
case ROW_CONTACT_HEADER:
|
||||
display.setColor(DisplayDriver::YELLOW);
|
||||
@@ -917,11 +949,7 @@ public:
|
||||
snprintf(tmp, sizeof(tmp), " %s", ch.name);
|
||||
if (selected) {
|
||||
// Show delete hint on right
|
||||
#if defined(LilyGo_T5S3_EPaper_Pro)
|
||||
const char* hint = "Hold:Delete";
|
||||
#else
|
||||
const char* hint = "Del:X";
|
||||
#endif
|
||||
int hintW = display.getTextWidth(hint);
|
||||
display.setCursor(display.width() - hintW - 2, y);
|
||||
display.print(hint);
|
||||
@@ -1035,11 +1063,7 @@ public:
|
||||
} else if (_confirmAction == 2) {
|
||||
display.drawTextCentered(display.width() / 2, by + 4, "Apply radio changes?");
|
||||
}
|
||||
#if defined(LilyGo_T5S3_EPaper_Pro)
|
||||
display.drawTextCentered(display.width() / 2, by + bh - 14, "Tap:Yes Boot:No");
|
||||
#else
|
||||
display.drawTextCentered(display.width() / 2, by + bh - 14, "Enter:Yes Q:No");
|
||||
#endif
|
||||
display.setTextSize(1);
|
||||
}
|
||||
|
||||
@@ -1137,10 +1161,17 @@ public:
|
||||
|
||||
#if defined(LilyGo_T5S3_EPaper_Pro)
|
||||
if (_editMode == EDIT_NONE) {
|
||||
display.print("Swipe:Scroll");
|
||||
const char* r = "Tap:Toggle Hold:Edit";
|
||||
display.setCursor(display.width() - display.getTextWidth(r) - 2, footerY);
|
||||
display.print(r);
|
||||
if (_subScreen != SUB_NONE) {
|
||||
display.print("Boot:Back");
|
||||
const char* r = "Tap:Toggle Hold:Edit";
|
||||
display.setCursor(display.width() - display.getTextWidth(r) - 2, footerY);
|
||||
display.print(r);
|
||||
} else {
|
||||
display.print("Swipe:Scroll");
|
||||
const char* r = "Tap:Toggle Hold:Edit";
|
||||
display.setCursor(display.width() - display.getTextWidth(r) - 2, footerY);
|
||||
display.print(r);
|
||||
}
|
||||
} else if (_editMode == EDIT_NUMBER) {
|
||||
display.print("Swipe:Adjust");
|
||||
const char* r = "Tap:OK Boot:Cancel";
|
||||
@@ -1199,7 +1230,11 @@ public:
|
||||
} else if (_editMode == EDIT_CONFIRM) {
|
||||
// Footer already covered by overlay
|
||||
} else {
|
||||
display.print("Q:Bck");
|
||||
if (_subScreen != SUB_NONE) {
|
||||
display.print("Q:Back");
|
||||
} else {
|
||||
display.print("Q:Bck");
|
||||
}
|
||||
const char* r = "W/S:Up/Dwn Entr:Chng";
|
||||
display.setCursor(display.width() - display.getTextWidth(r) - 2, footerY);
|
||||
display.print(r);
|
||||
@@ -1426,6 +1461,9 @@ public:
|
||||
if (type == ROW_CONTACT_MODE) {
|
||||
_editPickerIdx--;
|
||||
if (_editPickerIdx < 0) _editPickerIdx = CONTACT_MODE_COUNT - 1;
|
||||
} else if (type == ROW_GPS_BAUD) {
|
||||
_editPickerIdx--;
|
||||
if (_editPickerIdx < 0) _editPickerIdx = GPS_BAUD_OPTION_COUNT - 1;
|
||||
} else {
|
||||
// Radio preset
|
||||
_editPickerIdx--;
|
||||
@@ -1437,6 +1475,9 @@ public:
|
||||
if (type == ROW_CONTACT_MODE) {
|
||||
_editPickerIdx++;
|
||||
if (_editPickerIdx >= CONTACT_MODE_COUNT) _editPickerIdx = 0;
|
||||
} else if (type == ROW_GPS_BAUD) {
|
||||
_editPickerIdx++;
|
||||
if (_editPickerIdx >= GPS_BAUD_OPTION_COUNT) _editPickerIdx = 0;
|
||||
} else {
|
||||
// Radio preset
|
||||
_editPickerIdx++;
|
||||
@@ -1448,6 +1489,12 @@ public:
|
||||
if (type == ROW_CONTACT_MODE) {
|
||||
applyContactMode(_editPickerIdx);
|
||||
_editMode = EDIT_NONE;
|
||||
} else if (type == ROW_GPS_BAUD) {
|
||||
_prefs->gps_baudrate = GPS_BAUD_OPTIONS[_editPickerIdx];
|
||||
the_mesh.savePrefs();
|
||||
_editMode = EDIT_NONE;
|
||||
Serial.printf("Settings: GPS baud set to %lu (reboot to apply)\n",
|
||||
(unsigned long)_prefs->gps_baudrate);
|
||||
} else {
|
||||
// Apply radio preset
|
||||
if (_editPickerIdx >= 0 && _editPickerIdx < (int)NUM_RADIO_PRESETS) {
|
||||
@@ -1627,13 +1674,16 @@ public:
|
||||
case ROW_PATH_HASH_SIZE:
|
||||
startEditInt(_prefs->path_hash_mode + 1); // display as 1-3
|
||||
break;
|
||||
case ROW_GPS_BAUD:
|
||||
startEditPicker(findGpsBaudIndex(_prefs->gps_baudrate));
|
||||
break;
|
||||
#if defined(LilyGo_T5S3_EPaper_Pro)
|
||||
case ROW_DARK_MODE:
|
||||
_prefs->dark_mode = _prefs->dark_mode ? 0 : 1;
|
||||
the_mesh.savePrefs();
|
||||
Serial.printf("Settings: Dark mode = %s\n",
|
||||
_prefs->dark_mode ? "ON" : "OFF");
|
||||
break;
|
||||
#if defined(LilyGo_T5S3_EPaper_Pro)
|
||||
case ROW_PORTRAIT_MODE:
|
||||
_prefs->portrait_mode = _prefs->portrait_mode ? 0 : 1;
|
||||
the_mesh.savePrefs();
|
||||
@@ -1748,6 +1798,24 @@ public:
|
||||
(_prefs->autoadd_config & AUTO_ADD_OVERWRITE_OLDEST) ? "ON" : "OFF");
|
||||
break;
|
||||
|
||||
// --- Submenu folder rows ---
|
||||
case ROW_CONTACTS_SUBMENU:
|
||||
_savedTopCursor = _cursor;
|
||||
_subScreen = SUB_CONTACTS;
|
||||
_cursor = 0;
|
||||
_scrollTop = 0;
|
||||
rebuildRows();
|
||||
Serial.println("Settings: entered Contacts sub-screen");
|
||||
break;
|
||||
case ROW_CHANNELS_SUBMENU:
|
||||
_savedTopCursor = _cursor;
|
||||
_subScreen = SUB_CHANNELS;
|
||||
_cursor = 0;
|
||||
_scrollTop = 0;
|
||||
rebuildRows();
|
||||
Serial.println("Settings: entered Channels sub-screen");
|
||||
break;
|
||||
|
||||
case ROW_ADD_CHANNEL:
|
||||
startEditText("");
|
||||
break;
|
||||
@@ -1771,8 +1839,18 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Q: back  if radio changed, prompt to apply first
|
||||
// Q: back -- if in sub-screen, return to top level; else exit settings
|
||||
if (c == 'q' || c == 'Q') {
|
||||
if (_subScreen != SUB_NONE) {
|
||||
// Return to top-level settings list
|
||||
_subScreen = SUB_NONE;
|
||||
rebuildRows();
|
||||
_cursor = _savedTopCursor;
|
||||
if (_cursor >= _numRows) _cursor = _numRows - 1;
|
||||
skipNonSelectable(1);
|
||||
Serial.println("Settings: back to top level");
|
||||
return true;
|
||||
}
|
||||
if (_radioChanged) {
|
||||
_editMode = EDIT_CONFIRM;
|
||||
_confirmAction = 2;
|
||||
|
||||
@@ -138,6 +138,7 @@ class HomeScreen : public UIScreen {
|
||||
unsigned long _shutdown_at; // earliest time to proceed with shutdown (after e-ink refresh)
|
||||
bool _editing_utc;
|
||||
int8_t _saved_utc_offset; // for cancel/undo
|
||||
|
||||
AdvertPath recent[UI_RECENT_LIST_SIZE];
|
||||
|
||||
|
||||
@@ -254,7 +255,7 @@ public:
|
||||
_shutdown_init(false), _shutdown_at(0), _editing_utc(false), _saved_utc_offset(0), sensors_lpp(200) { }
|
||||
|
||||
bool isEditingUTC() const { return _editing_utc; }
|
||||
void cancelEditUTC() {
|
||||
void cancelEditing() {
|
||||
if (_editing_utc) {
|
||||
_node_prefs->utc_offset_hours = _saved_utc_offset;
|
||||
_editing_utc = false;
|
||||
@@ -666,7 +667,9 @@ public:
|
||||
display.drawTextLeftAlign(0, y, "time(U)");
|
||||
display.drawTextRightAlign(display.width()-1, y, "no sync");
|
||||
}
|
||||
y = y + 12;
|
||||
}
|
||||
|
||||
// UTC offset editor overlay
|
||||
if (_editing_utc) {
|
||||
// Draw background box
|
||||
@@ -686,6 +689,7 @@ public:
|
||||
display.drawTextCentered(display.width() / 2, by + bh - 10, "W/S:adj Enter:ok Q:cancel");
|
||||
display.setTextSize(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
#if UI_SENSORS_PAGE == 1
|
||||
} else if (_page == HomePage::SENSORS) {
|
||||
@@ -842,11 +846,7 @@ public:
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#if defined(LilyGo_T5S3_EPaper_Pro)
|
||||
return _editing_utc ? 700 : 2000; // Faster refresh for touch-only (no key to force update)
|
||||
#else
|
||||
return _editing_utc ? 700 : 5000; // match e-ink refresh cycle while editing UTC
|
||||
#endif
|
||||
return _editing_utc ? 700 : 5000;
|
||||
}
|
||||
|
||||
bool handleInput(char c) override {
|
||||
@@ -1179,11 +1179,11 @@ void UITask::begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* no
|
||||
map_screen = nullptr;
|
||||
#endif
|
||||
|
||||
// Apply saved dark mode preference before first render
|
||||
#if defined(LilyGo_T5S3_EPaper_Pro)
|
||||
// Apply saved display preferences before first render
|
||||
if (_node_prefs->dark_mode) {
|
||||
::display.setDarkMode(true);
|
||||
}
|
||||
#if defined(LilyGo_T5S3_EPaper_Pro)
|
||||
if (_node_prefs->portrait_mode) {
|
||||
::display.setPortraitMode(true);
|
||||
}
|
||||
@@ -1278,16 +1278,9 @@ void UITask::newMsg(uint8_t path_len, const char* from_name, const char* text, i
|
||||
#endif
|
||||
|
||||
if (_display != NULL) {
|
||||
#if defined(LilyGo_T5S3_EPaper_Pro)
|
||||
// E-ink: always wake — no backlight cost, and stale image shows wrong MSG count
|
||||
if (!_display->isOn()) {
|
||||
_display->turnOn();
|
||||
}
|
||||
#else
|
||||
if (!_display->isOn() && !hasConnection()) {
|
||||
_display->turnOn();
|
||||
}
|
||||
#endif
|
||||
if (_display->isOn()) {
|
||||
_auto_off = millis() + AUTO_OFF_MILLIS; // extend the auto-off timer
|
||||
_next_refresh = 100; // trigger refresh
|
||||
@@ -1552,11 +1545,11 @@ if (curr) curr->poll();
|
||||
|
||||
if (_display != NULL && _display->isOn()) {
|
||||
if (millis() >= _next_refresh && curr) {
|
||||
// Sync dark mode with prefs (settings toggle takes effect here)
|
||||
#if defined(LilyGo_T5S3_EPaper_Pro)
|
||||
// Sync display modes with prefs (settings toggles take effect here)
|
||||
if (_node_prefs && display.isDarkMode() != (_node_prefs->dark_mode != 0)) {
|
||||
display.setDarkMode(_node_prefs->dark_mode != 0);
|
||||
}
|
||||
#if defined(LilyGo_T5S3_EPaper_Pro)
|
||||
if (_node_prefs && display.isPortraitMode() != (_node_prefs->portrait_mode != 0)) {
|
||||
display.setPortraitMode(_node_prefs->portrait_mode != 0);
|
||||
// Text reader layout depends on orientation — force recalculation
|
||||
@@ -1839,14 +1832,6 @@ void UITask::onVKBSubmit() {
|
||||
if (_screenBeforeVKB) setCurrScreen(_screenBeforeVKB);
|
||||
break;
|
||||
}
|
||||
case VKB_SETTINGS_TEXT: {
|
||||
SettingsScreen* ss = (SettingsScreen*)settings_screen;
|
||||
if (ss) {
|
||||
ss->submitEditText(text); // Fills buffer + triggers Enter confirm
|
||||
}
|
||||
if (_screenBeforeVKB) setCurrScreen(_screenBeforeVKB);
|
||||
break;
|
||||
}
|
||||
case VKB_NOTES: {
|
||||
NotesScreen* notes = (NotesScreen*)getNotesScreen();
|
||||
if (notes && strlen(text) > 0) {
|
||||
@@ -2006,7 +1991,7 @@ void UITask::injectKey(char c) {
|
||||
|
||||
void UITask::gotoHomeScreen() {
|
||||
// Cancel any active editing state when navigating to home
|
||||
((HomeScreen *) home)->cancelEditUTC();
|
||||
((HomeScreen *) home)->cancelEditing();
|
||||
setCurrScreen(home);
|
||||
if (_display != NULL && !_display->isOn()) {
|
||||
_display->turnOn();
|
||||
|
||||
Reference in New Issue
Block a user