From 0fa7a321bff6da14b5ce943888ea44c4a0ea5c5c Mon Sep 17 00:00:00 2001 From: pelgraine <140762863+pelgraine@users.noreply.github.com> Date: Fri, 10 Jul 2026 18:40:53 +1000 Subject: [PATCH] Rename LILYGO_TWATCH_S3_PLUS to MECK_TWATCH as the watch form-factor gate The macro was doing double duty: gating the 240x240 touch UI (tile grid, lock screen, VKB, grey palette) and gating the Plus's onboard GNSS. A non-GPS watch cannot reuse the first without dragging in the second. MECK_TWATCH watch form factor LILYGO_TWATCH_S3_PLUS Plus-only hardware (GNSS on BLDO1, GPIO0 user button) MECK_PMU_BUTTON user button is the AXP2101 PWRON key, not a GPIO 84 sites renamed across 14 files. The WatchMapScreen include, construction and its three touch handlers now also require HAS_GPS, as does the Maps tile branch inside the home tile grid. Behaviour-preserving: the Plus defines both MECK_TWATCH and HAS_GPS=1, so every new condition evaluates as before. No other board defines MECK_TWATCH. --- examples/companion_radio/MyMesh.cpp | 2 +- examples/companion_radio/NodePrefs.h | 2 +- examples/companion_radio/main.cpp | 44 +++++++------- .../companion_radio/ui-new/ChannelScreen.h | 2 +- .../companion_radio/ui-new/ContactsScreen.h | 4 +- .../companion_radio/ui-new/DiscoveryScreen.h | 4 +- .../companion_radio/ui-new/PathEditorScreen.h | 4 +- .../ui-new/RepeaterAdminScreen.h | 16 ++--- .../companion_radio/ui-new/SettingsScreen.h | 10 ++-- examples/companion_radio/ui-new/UITask.cpp | 60 +++++++++---------- examples/companion_radio/ui-new/UITask.h | 16 ++--- .../companion_radio/ui-new/VirtualKeyboard.h | 4 +- src/helpers/ui/LGFXDisplay.cpp | 6 +- src/helpers/ui/LGFXDisplay.h | 2 +- variants/lilygo_twatch_s3_plus/platformio.ini | 4 ++ 15 files changed, 93 insertions(+), 87 deletions(-) diff --git a/examples/companion_radio/MyMesh.cpp b/examples/companion_radio/MyMesh.cpp index a83c98e8..8627e32e 100644 --- a/examples/companion_radio/MyMesh.cpp +++ b/examples/companion_radio/MyMesh.cpp @@ -2426,7 +2426,7 @@ void MyMesh::handleCmdFrame(size_t len) { if (strcmp(sp, "gps") == 0) { _prefs.gps_enabled = (np[0] == '1') ? 1 : 0; savePrefs(); - #if defined(LILYGO_TWATCH_S3_PLUS) + #if defined(MECK_TWATCH) // Apply the BLDO1 GPS rail live so the toggle takes effect now, no reboot if (_prefs.gps_enabled) board.gpsPowerOn(); else board.gpsPowerOff(); #endif diff --git a/examples/companion_radio/NodePrefs.h b/examples/companion_radio/NodePrefs.h index 67795fc2..50c95009 100644 --- a/examples/companion_radio/NodePrefs.h +++ b/examples/companion_radio/NodePrefs.h @@ -109,7 +109,7 @@ struct NodePrefs { // persisted to file // upward → fillRect must start above baseline to cover ascenders. // T5S3: always 0 (both sizes use baseline fonts with highlight at y). inline int smallHighlightOff() const { -#if defined(LilyGo_T5S3_EPaper_Pro) || defined(LILYGO_TWATCH_S3_PLUS) +#if defined(LilyGo_T5S3_EPaper_Pro) || defined(MECK_TWATCH) return 0; #else // Custom 7pt fonts at textSize 0 use GFXfont (baseline rendering), not built-in. diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index 82242960..f6818c96 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -709,14 +709,14 @@ // ============================================================================= // Define MECK_TOUCH_ENABLED for any platform with touch support -#if defined(LilyGo_T5S3_EPaper_Pro) || (defined(LilyGo_TDeck_Pro) && defined(HAS_TOUCHSCREEN)) || defined(LILYGO_TWATCH_S3_PLUS) +#if defined(LilyGo_T5S3_EPaper_Pro) || (defined(LilyGo_TDeck_Pro) && defined(HAS_TOUCHSCREEN)) || defined(MECK_TWATCH) #define MECK_TOUCH_ENABLED 1 #endif // --- T-Watch S3 Plus: screen headers for the touch UI --- // The watch needs the same concrete screen types as the gesture machine casts // to, but none of the T5S3/T-Deck hardware baggage (GT911, SD, TCA8418 keyboard). -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) #include "TextReaderScreen.h" #include "NotesScreen.h" #include "ContactsScreen.h" @@ -901,7 +901,7 @@ #define TOUCH_LONG_PRESS_MS 750 #if defined(LilyGo_T5S3_EPaper_Pro) #define TOUCH_SWIPE_THRESHOLD 60 // T5S3: 960×540 — 60px ≈ 6% of width - #elif defined(LILYGO_TWATCH_S3_PLUS) + #elif defined(MECK_TWATCH) #define TOUCH_SWIPE_THRESHOLD 16 // Watch: getTouch() returns 0..119 (240px/UI_ZOOM); 16 is ~13% of width #else #define TOUCH_SWIPE_THRESHOLD 30 // T-Deck Pro: 240×320 — 30px ≈ 12.5% of width @@ -939,7 +939,7 @@ } #elif defined(LilyGo_TDeck_Pro) return touchInput.getPoint(*outX, *outY); - #elif defined(LILYGO_TWATCH_S3_PLUS) + #elif defined(MECK_TWATCH) { // FT6336U is read through the LovyanGFX panel backing the display. // display.getTouch() returns coordinates already divided by UI_ZOOM. @@ -964,7 +964,7 @@ #elif defined(LilyGo_TDeck_Pro) float sx = (float)EINK_WIDTH / 128.0f; // 240/128 = 1.875 float sy = (float)EINK_HEIGHT / 128.0f; // 320/128 = 2.5 - #elif defined(LILYGO_TWATCH_S3_PLUS) + #elif defined(MECK_TWATCH) // display.getTouch() already divides by UI_ZOOM, so px/py span the // 240/UI_ZOOM logical canvas (0..119 at UI_ZOOM=2). Scale to 128 virtual. float sx = (240.0f / UI_ZOOM) / 128.0f; @@ -1058,7 +1058,7 @@ static uint32_t _atoi(const char* sp) { DataStore store(LittleFS, rtc_clock); #elif defined(ESP32) #include - #if defined(LILYGO_TWATCH_S3_PLUS) + #if defined(MECK_TWATCH) #include // watch: dedicated 'maps' tiles partition #endif DataStore store(SPIFFS, rtc_clock); @@ -1125,7 +1125,7 @@ static uint32_t _atoi(const char* sp) { /* GLOBAL OBJECTS */ #ifdef DISPLAY_CLASS #include "UITask.h" - #if defined(LILYGO_TWATCH_S3_PLUS) + #if defined(MECK_TWATCH) && HAS_GPS #include "WatchMapScreen.h" // After BLE -- PNGdec headers conflict with BLE if included earlier #elif HAS_GPS && !defined(LILYGO_TECHO_CARD) #include "MapScreen.h" // After BLE -- PNGdec headers conflict with BLE if included earlier @@ -1352,7 +1352,7 @@ static void lastHeardToggleContact() { return '\r'; } -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) && HAS_GPS // Map screen: footer +/- buttons zoom; a tap in the map area recenters on // GPS. (A top-strip tap is already handled above -> home.) if (ui_task.isOnMapScreen()) { @@ -1601,7 +1601,7 @@ static void lastHeardToggleContact() { // Settings screen: tap to select row, tap same row to activate if (ui_task.isOnSettingsScreen()) { SettingsScreen* ss = (SettingsScreen*)ui_task.getSettingsScreen(); -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) // Watch: while editing the UTC offset, tap the upper half to increment // and the lower half to decrement. Long-press saves. if (ss && ss->isEditing() && ss->getCurrentRowType() == ROW_UTC_OFFSET) { @@ -1625,7 +1625,7 @@ static void lastHeardToggleContact() { if (ui_task.isOnSMSScreen()) return 0; #endif -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) // Repeater admin (watch): tap selects a menu row (tap again = activate); // param entry opens the keyboard for the value. if (ui_task.isOnRepeaterAdmin()) { @@ -1660,7 +1660,7 @@ static void lastHeardToggleContact() { if (ui_task.isOnSMSScreen()) return 0; #endif -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) && HAS_GPS // Map screen: swipe pans the viewport (logical-pixel delta) if (ui_task.isOnMapScreen()) { WatchMapScreen* wms = (WatchMapScreen*)ui_task.getMapScreen(); @@ -1782,7 +1782,7 @@ static void lastHeardToggleContact() { return 'q'; } -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) // Watch FIRST page: long-press on a coloured tile opens its screen. // The grid renders in the logical (display.width()) space; touchToVirtual // yields 128-space coords, so scale them back to render space to hit-test. @@ -1806,6 +1806,7 @@ static void lastHeardToggleContact() { if (row == 1 && col == 0) { ui_task.gotoSettingsScreen(); return 0; } if (row == 1 && col == 1) { ui_task.gotoDiscoveryScreen(); return 0; } if (row == 2 && col == 0) { ui_task.gotoTraceScreen(); return 0; } +#if HAS_GPS if (row == 2 && col == 1) { // Maps: mark the tile FS ready (detectZoomRange in enter() needs it) // before opening; GPS centre + markers are populated in the main loop. @@ -1814,6 +1815,7 @@ static void lastHeardToggleContact() { ui_task.gotoMapScreen(); return 0; } +#endif if (row == 3 && col == 0) { ui_task.gotoNotesScreen(); return 0; } if (row == 3 && col == 1) { ui_task.gotoStepsScreen(); return 0; } } @@ -1954,7 +1956,7 @@ static void lastHeardToggleContact() { } } return 0; -#elif defined(LILYGO_TWATCH_S3_PLUS) +#elif defined(MECK_TWATCH) // Watch: long press = DM (tw-keyboard) / admin / room action. // purpose ints match TWatchKeyboardScreen::Purpose: DM=1. { @@ -2030,14 +2032,14 @@ static void lastHeardToggleContact() { #if defined(LilyGo_T5S3_EPaper_Pro) ui_task.showVirtualKeyboard(VKB_ADMIN_PASSWORD, "Admin Password", "", 32); return 0; -#elif defined(LILYGO_TWATCH_S3_PLUS) +#elif defined(MECK_TWATCH) ui_task.openTWatchKeyboard(2, 0); // TWKB_ADMIN_PASSWORD return 0; #else return KEY_ENTER; // T-Deck Pro: keyboard handles password entry #endif } -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) // Watch: keyboard only for param entry; menu/other states activate the // highlighted item (no raw CLI keyboard). if (astate == RepeaterAdminScreen::STATE_PARAM_ENTRY) { @@ -2062,7 +2064,7 @@ static void lastHeardToggleContact() { if (ui_task.isOnSettingsScreen()) { SettingsScreen* ss = (SettingsScreen*)ui_task.getSettingsScreen(); if (ss) { -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) // Watch: long-press while editing the UTC offset saves the value. if (ss->isEditing() && ss->getCurrentRowType() == ROW_UTC_OFFSET) { return '\r'; @@ -2302,7 +2304,7 @@ void setup() { } MESH_DEBUG_PRINTLN("setup() - SPIFFS.begin() done"); -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) // Mount the dedicated 'maps' partition as LittleFS (map tiles live here, // kept separate from the SPIFFS DataStore that holds identity/contacts). // formatOnFail=true so a freshly flashed (raw) maps partition is formatted @@ -2787,7 +2789,7 @@ void setup() { #ifdef PIN_GPS_EN digitalWrite(PIN_GPS_EN, GPS_EN_ACTIVE); #endif - #if defined(LILYGO_TWATCH_S3_PLUS) + #if defined(MECK_TWATCH) board.gpsPowerOn(); // GPS power is the AXP2101 BLDO1 rail #endif #if defined(LilyGo_TDeck_Pro_Max) @@ -2807,7 +2809,7 @@ void setup() { #if defined(LilyGo_TDeck_Pro_Max) board.gpsPowerOff(); // MAX: GPS power is XL9555-routed, not PIN_GPS_EN #endif - #if defined(LILYGO_TWATCH_S3_PLUS) + #if defined(MECK_TWATCH) board.gpsPowerOff(); // GPS power is the AXP2101 BLDO1 rail #endif sensors.setSettingValue("gps", "0"); @@ -2985,7 +2987,7 @@ void loop() { // Map screen: periodically update own GPS position and contact markers #ifdef DISPLAY_CLASS - #if HAS_GPS && !defined(LILYGO_TECHO_CARD) && !defined(LILYGO_TWATCH_S3_PLUS) + #if HAS_GPS && !defined(LILYGO_TECHO_CARD) && !defined(MECK_TWATCH) if (ui_task.isOnMapScreen()) { static unsigned long lastMapUpdate = 0; if (millis() - lastMapUpdate > 30000) { // Every 30 seconds @@ -3012,7 +3014,7 @@ void loop() { #endif #endif -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) && HAS_GPS // Watch map screen: on open, centre on GPS and populate contact markers; then // refresh own position + markers periodically while it stays open. { diff --git a/examples/companion_radio/ui-new/ChannelScreen.h b/examples/companion_radio/ui-new/ChannelScreen.h index 5b51a455..8d0107e1 100644 --- a/examples/companion_radio/ui-new/ChannelScreen.h +++ b/examples/companion_radio/ui-new/ChannelScreen.h @@ -182,7 +182,7 @@ public: // Sanitize emoji: replace UTF-8 emoji sequences with single-byte escape codes // The text already contains "Sender: message" format -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) // Watch build: drop emoji entirely instead of storing sprite escape bytes. // The watch UI has no sprite rendering and no room for emoji at 120x120 // virtual. Non-emoji UTF-8 (accented letters etc.) passes through diff --git a/examples/companion_radio/ui-new/ContactsScreen.h b/examples/companion_radio/ui-new/ContactsScreen.h index fd5544bb..8ddab3df 100644 --- a/examples/companion_radio/ui-new/ContactsScreen.h +++ b/examples/companion_radio/ui-new/ContactsScreen.h @@ -301,7 +301,7 @@ public: int selCount = getSelectedCount(); snprintf(tmp, sizeof(tmp), "%d Selected [%s]", selCount, filterLabel(_filter)); } else { -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) snprintf(tmp, sizeof(tmp), "Contacts[%s]", filterLabel(_filter)); #else snprintf(tmp, sizeof(tmp), "Contacts [%s]", filterLabel(_filter)); @@ -470,7 +470,7 @@ public: display.setCursor(display.width() - display.getTextWidth(right) - 2, footerY); display.print(right); } -#elif defined(LILYGO_TWATCH_S3_PLUS) +#elif defined(MECK_TWATCH) display.setCursor(0, footerY); if (!_selectMode) { display.print("Long Press: Enter"); diff --git a/examples/companion_radio/ui-new/DiscoveryScreen.h b/examples/companion_radio/ui-new/DiscoveryScreen.h index b60579a3..8b2f5173 100644 --- a/examples/companion_radio/ui-new/DiscoveryScreen.h +++ b/examples/companion_radio/ui-new/DiscoveryScreen.h @@ -103,7 +103,7 @@ public: display.setColor(DisplayDriver::LIGHT); display.setCursor(4, 28); display.print(active ? "Listening for adverts..." : "No nodes found"); -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) display.setCursor(4, 38); display.print("Hold: Rescan"); display.setCursor(4, 48); @@ -211,7 +211,7 @@ public: const char* right = "Hold:Rescan"; display.setCursor(display.width() - display.getTextWidth(right) - 2, footerY); display.print(right); -#elif defined(LILYGO_TWATCH_S3_PLUS) +#elif defined(MECK_TWATCH) display.print("Tap:Slct"); const char* right = "Hold:Rescan"; diff --git a/examples/companion_radio/ui-new/PathEditorScreen.h b/examples/companion_radio/ui-new/PathEditorScreen.h index b47ed585..4824a4ed 100644 --- a/examples/companion_radio/ui-new/PathEditorScreen.h +++ b/examples/companion_radio/ui-new/PathEditorScreen.h @@ -281,7 +281,7 @@ public: if (selected) { display.setColor(DisplayDriver::LIGHT); -#if defined(LilyGo_T5S3_EPaper_Pro) || defined(LILYGO_TWATCH_S3_PLUS) +#if defined(LilyGo_T5S3_EPaper_Pro) || defined(MECK_TWATCH) display.fillRect(0, y, display.width(), lineH); #else display.fillRect(0, y + 5, display.width(), lineH); @@ -383,7 +383,7 @@ public: const char* right = "Hold:Select"; display.setCursor(display.width() - display.getTextWidth(right) - 2, footerY); display.print(right); -#elif defined(LILYGO_TWATCH_S3_PLUS) +#elif defined(MECK_TWATCH) display.setCursor(0, footerY); display.print("Tap:Slct"); const char* right = "Hold:Entr"; diff --git a/examples/companion_radio/ui-new/RepeaterAdminScreen.h b/examples/companion_radio/ui-new/RepeaterAdminScreen.h index f70ca853..a5409546 100644 --- a/examples/companion_radio/ui-new/RepeaterAdminScreen.h +++ b/examples/companion_radio/ui-new/RepeaterAdminScreen.h @@ -595,7 +595,7 @@ public: // --- Header --- display.setTextSize(1); -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) // Clip long lines at the screen edge instead of wrapping them onto the row // below (restored before returning so other screens are unaffected). ((LGFXDisplay*)&display)->setTextWrap(false); @@ -644,7 +644,7 @@ public: #if defined(LilyGo_T5S3_EPaper_Pro) display.print("Boot:Exit"); renderFooterRight(display, footerY, "Hold:Type"); -#elif defined(LILYGO_TWATCH_S3_PLUS) +#elif defined(MECK_TWATCH) display.print("Long Press: login"); #else display.print("Sh+Del:Exit"); @@ -665,7 +665,7 @@ public: #if defined(LilyGo_T5S3_EPaper_Pro) display.print("Boot:Exit"); renderFooterMidRight(display, footerY, "Back:Exit", "Tap:Open", "Swipe:Sel"); -#elif defined(LILYGO_TWATCH_S3_PLUS) +#elif defined(MECK_TWATCH) display.print("Long Press: Select"); #else display.print("Sh+Del:Exit"); @@ -677,7 +677,7 @@ public: #if defined(LilyGo_T5S3_EPaper_Pro) display.print("Boot:Back"); renderFooterMidRight(display, footerY, "Back:Back", "Tap:Run", "Swipe:Sel"); -#elif defined(LILYGO_TWATCH_S3_PLUS) +#elif defined(MECK_TWATCH) display.print("Long Press: Run"); #else display.print("Sh+Del:Back"); @@ -689,7 +689,7 @@ public: #if defined(LilyGo_T5S3_EPaper_Pro) display.print("Boot:Cancel"); renderFooterRight(display, footerY, "Tap:Send"); -#elif defined(LILYGO_TWATCH_S3_PLUS) +#elif defined(MECK_TWATCH) display.print("Tap: Enter value"); #else display.print("Sh+Del:Cancel"); @@ -723,7 +723,7 @@ public: break; } -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) ((LGFXDisplay*)&display)->setTextWrap(true); // restore default before returning #endif @@ -1125,7 +1125,7 @@ private: void renderResponse(DisplayDriver& display, int y, int bodyHeight) { display.setTextSize(the_mesh.getNodePrefs()->smallTextSize()); int lineHeight = the_mesh.getNodePrefs()->smallLineH(); -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) // Watch: clip long response lines at the screen edge instead of wrapping // them onto the row below. ((LGFXDisplay*)&display)->setTextWrap(false); @@ -1167,7 +1167,7 @@ private: } display.setTextSize(1); -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) ((LGFXDisplay*)&display)->setTextWrap(true); // restore default #endif } diff --git a/examples/companion_radio/ui-new/SettingsScreen.h b/examples/companion_radio/ui-new/SettingsScreen.h index b0addb63..9d9156a3 100644 --- a/examples/companion_radio/ui-new/SettingsScreen.h +++ b/examples/companion_radio/ui-new/SettingsScreen.h @@ -499,7 +499,7 @@ private: addRow(ROW_BACKLIGHT_BRIGHTNESS); addRow(ROW_KB_BACKLIGHT); #endif -#if !defined(LILYGO_TWATCH_S3_PLUS) +#if !defined(MECK_TWATCH) addRow(ROW_MSG_NOTIFY); #endif #if HAS_GPS @@ -507,10 +507,10 @@ private: #endif addRow(ROW_PATH_HASH_SIZE); addRow(ROW_DEFAULT_SCOPE); -#if !defined(LILYGO_TWATCH_S3_PLUS) +#if !defined(MECK_TWATCH) addRow(ROW_DARK_MODE); #endif -#if !defined(LILYGO_TECHO_LITE) && !defined(LILYGO_TWATCH_S3_PLUS) +#if !defined(LILYGO_TECHO_LITE) && !defined(MECK_TWATCH) addRow(ROW_LARGE_FONT); addRow(ROW_FONT_STYLE); #endif @@ -2940,13 +2940,13 @@ public: } else if (_subScreen != SUB_NONE) { display.print("Sh+Del:Back"); } else { -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) display.print("Hold:Edit"); #else display.print("Sh+Del:Bk"); #endif } -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) const char* r = (_subScreen == SUB_NONE) ? "Tap:Cycle" : "Tap/Ent:Edit"; #else const char* r = "Tap/Ent:Edit"; diff --git a/examples/companion_radio/ui-new/UITask.cpp b/examples/companion_radio/ui-new/UITask.cpp index 1f24a197..02132e95 100644 --- a/examples/companion_radio/ui-new/UITask.cpp +++ b/examples/companion_radio/ui-new/UITask.cpp @@ -16,7 +16,7 @@ #ifdef MECK_WEB_READER #include "WebReaderScreen.h" #endif -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) && HAS_GPS #include "WatchMapScreen.h" #elif HAS_GPS && !defined(LILYGO_TECHO_CARD) #include "MapScreen.h" @@ -25,7 +25,7 @@ #if defined(LilyGo_TDeck_Pro_Max) #include "DRV2605Haptic.h" // haptic motor for "Buzzer (vibrate)" channels #endif -#if defined(LilyGo_T5S3_EPaper_Pro) || defined(MECK_AUDIO_VARIANT) || defined(LILYGO_TWATCH_S3_PLUS) +#if defined(LilyGo_T5S3_EPaper_Pro) || defined(MECK_AUDIO_VARIANT) || defined(MECK_TWATCH) #include "HomeIcons.h" #endif #if defined(WIFI_SSID) || defined(MECK_WIFI_COMPANION) @@ -136,7 +136,7 @@ public: // version info display.setColor(DisplayDriver::LIGHT); -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) display.setTextSize(1); // 240x240: size 2 overflows the 120px virtual width and wraps #else display.setTextSize(2); @@ -377,7 +377,7 @@ public: int render(DisplayDriver& display) override { char tmp[80]; -#if defined(LilyGo_T5S3_EPaper_Pro) || defined(LILYGO_TWATCH_S3_PLUS) +#if defined(LilyGo_T5S3_EPaper_Pro) || defined(MECK_TWATCH) _task->setHomeShowingTiles(false); // Reset — only set true on FIRST page #endif @@ -412,13 +412,13 @@ public: #define HOME_HDR_Y 1 #elif defined(LILYGO_TECHO_LITE) #define HOME_HDR_Y 0 -#elif defined(LILYGO_TWATCH_S3_PLUS) +#elif defined(MECK_TWATCH) #define HOME_HDR_Y 1 #else #define HOME_HDR_Y -3 #endif display.setCursor(0, HOME_HDR_Y); -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) // Watch: render the name in a very small font so long names fit beside the // centred clock instead of overrunning it. Colour was set above (GREEN). ((LGFXDisplay*)&display)->printSmallFont(0, HOME_HDR_Y, filtered_name); @@ -435,12 +435,12 @@ public: // alarm enabled indicator (AL icon, left of audio or battery) renderAlarmIndicator(display, battLeftX); -#elif !defined(LILYGO_TWATCH_S3_PLUS) +#elif !defined(MECK_TWATCH) renderBatteryIndicator(display, _task->getBattMilliVolts()); #endif // centered clock — only show when time is valid -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) // Watch: right-aligned header cluster, right to left -- battery %, unread // count, then clock, all in the tiny node-name font. Battery % is // colour-coded by charge level. @@ -522,7 +522,7 @@ public: int y = 13; // Below header #elif defined(LilyGo_T5S3_EPaper_Pro) int y = 14; // Closer to header -#elif defined(LILYGO_TWATCH_S3_PLUS) +#elif defined(MECK_TWATCH) int y = (_page == HomePage::FIRST) ? 9 : 18; // first page: tuck up under the header #else int y = 14; @@ -537,7 +537,7 @@ public: } if (_page == HomePage::FIRST) { -#if defined(LilyGo_T5S3_EPaper_Pro) || defined(LILYGO_TWATCH_S3_PLUS) +#if defined(LilyGo_T5S3_EPaper_Pro) || defined(MECK_TWATCH) _task->setHomeShowingTiles(true); #endif #if defined(LilyGo_T5S3_EPaper_Pro) @@ -548,12 +548,12 @@ public: #endif #elif defined(LILYGO_TECHO_LITE) int y = 18; // Below page dots -#elif defined(LILYGO_TWATCH_S3_PLUS) +#elif defined(MECK_TWATCH) int y = 12; // 4-row grid starts just below the dots #else int y = 20; #endif -#if !defined(LILYGO_TWATCH_S3_PLUS) +#if !defined(MECK_TWATCH) display.setColor(DisplayDriver::YELLOW); display.setTextSize(2); sprintf(tmp, "MSG: %d", _task->getUnreadMsgCount()); @@ -563,7 +563,7 @@ public: y += 12; // Compact #elif defined(LilyGo_TDeck_Pro_Max) y += 10; // MAX: pull < Connected > up under MSG to make room for [T] Phone -#elif defined(LILYGO_TWATCH_S3_PLUS) +#elif defined(MECK_TWATCH) // watch: no MSG banner gap -- the 4-row grid sits just under the dots #else y += 14; // Reduced from 18 @@ -677,7 +677,7 @@ public: } display.setTextSize(1); -#elif defined(LILYGO_TWATCH_S3_PLUS) +#elif defined(MECK_TWATCH) // ----- T-Watch S3 Plus: P4-style coloured tile grid (3x2) ----- // Border colours approximate the Meck P4 home palette (RGB565): a white // icon + label on a dark navy fill, each tile a distinct bright border. @@ -905,7 +905,7 @@ public: #if defined(LilyGo_T5S3_EPaper_Pro) display.drawTextCentered(display.width() / 2, display.height() - 24, "Tap here for full Last Heard list"); -#elif defined(LILYGO_TWATCH_S3_PLUS) +#elif defined(MECK_TWATCH) display.drawTextCentered(display.width() / 2, display.height() - 24, "Long Press: Full Last Heard List"); #else @@ -966,7 +966,7 @@ public: display.setTextSize(1); #if defined(LilyGo_T5S3_EPaper_Pro) display.drawTextCentered(display.width() / 2, 80, "toggle: " PRESS_LABEL); -#elif defined(LILYGO_TWATCH_S3_PLUS) +#elif defined(MECK_TWATCH) display.drawTextCentered(display.width() / 2, 68, "toggle: " PRESS_LABEL); #else display.drawTextCentered(display.width() / 2, 68, "toggle: " PRESS_LABEL); @@ -1021,7 +1021,7 @@ public: #endif #if defined(LilyGo_T5S3_EPaper_Pro) display.drawTextCentered(display.width() / 2, 64, "advert: " PRESS_LABEL); -#elif defined(LILYGO_TWATCH_S3_PLUS) +#elif defined(MECK_TWATCH) display.drawTextCentered(display.width() / 2, 57, "advert: " PRESS_LABEL); #else display.drawTextCentered(display.width() / 2, 57, "advert: " PRESS_LABEL); @@ -1427,7 +1427,7 @@ public: // T5S3: Long press boot button to lock/unlock. Touch disabled while locked. // T-Deck Pro: Double-press boot button to lock/unlock. Touch+keyboard disabled. // ========================================================================== -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) // Watch lock/clock screen: big HH:MM plus a day+date line, shown when the // display is woken (by raise-to-wake or a tap) after the idle timeout. class ClockScreen : public UIScreen { @@ -1599,7 +1599,7 @@ void UITask::begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* no _sensors = sensors; _auto_off = millis() + AUTO_OFF_MILLIS; -#if defined(PIN_USER_BTN) +#if defined(PIN_USER_BTN) || defined(MECK_PMU_BUTTON) user_btn.begin(); #endif #if defined(PIN_USER_BTN_ANA) @@ -1689,7 +1689,7 @@ void UITask::begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* no #if defined(LilyGo_T5S3_EPaper_Pro) || defined(LilyGo_TDeck_Pro) lock_screen = new LockScreen(this, &rtc_clock, node_prefs); #endif -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) lock_screen = new ClockScreen(this, &rtc_clock, node_prefs); steps_screen = new StepsScreen(this); #endif @@ -1708,7 +1708,7 @@ void UITask::begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* no #ifdef HAS_4G_MODEM sms_screen = new SMSScreen(this, node_prefs); #endif -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) && HAS_GPS map_screen = new WatchMapScreen(this); #elif HAS_GPS && !defined(LILYGO_TECHO_CARD) map_screen = new MapScreen(this); @@ -2006,7 +2006,7 @@ void UITask::newMsg(uint8_t path_len, const char* from_name, const char* text, i } if (_display != NULL && !suppressNotif) { -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) // Watch: a new message must not wake the screen. The unread counter has // already been incremented above; leave the display asleep so the count // is only seen on the next tilt-wake to the clock screen. Only refresh @@ -2183,7 +2183,7 @@ void UITask::shutdown(bool restart){ } bool UITask::isButtonPressed() const { -#ifdef PIN_USER_BTN +#if defined(PIN_USER_BTN) || defined(MECK_PMU_BUTTON) return user_btn.isPressed(); #else return false; @@ -2192,7 +2192,7 @@ bool UITask::isButtonPressed() const { void UITask::loop() { char c = 0; -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) // TEMP power-debug probe: every 60s, log display state + board power stats. { static unsigned long _pwr_dbg_next = 0; @@ -2206,7 +2206,7 @@ void UITask::loop() { } } #endif -#if defined(PIN_USER_BTN) +#if defined(PIN_USER_BTN) || defined(MECK_PMU_BUTTON) int ev = user_btn.check(); if (ev == BUTTON_EVENT_CLICK) { #if defined(LilyGo_T5S3_EPaper_Pro) @@ -2649,7 +2649,7 @@ if (curr) curr->poll(); } #endif } -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) // Raise-to-wake: a wrist-raise (BMA423 tilt) while the display is off turns // it back on showing the clock screen and restarts the idle timer. if (_display != NULL && !_display->isOn() && board.tiltFired()) { @@ -3183,7 +3183,7 @@ void UITask::toggleGPS() { #if defined(LilyGo_TDeck_Pro_Max) board.gpsPowerOff(); // MAX: GPS power is XL9555-routed, not PIN_GPS_EN #endif - #if defined(LILYGO_TWATCH_S3_PLUS) + #if defined(MECK_TWATCH) board.gpsPowerOff(); // Watch: GPS power is the AXP2101 BLDO1 rail #endif notify(UIEventType::ack); @@ -3197,7 +3197,7 @@ void UITask::toggleGPS() { #if defined(LilyGo_TDeck_Pro_Max) board.gpsPowerOn(); // MAX: GPS power is XL9555-routed, not PIN_GPS_EN #endif - #if defined(LILYGO_TWATCH_S3_PLUS) + #if defined(MECK_TWATCH) board.gpsPowerOn(); // Watch: GPS power is the AXP2101 BLDO1 rail #endif notify(UIEventType::ack); @@ -3656,7 +3656,7 @@ void UITask::gotoTraceScreen() { _next_refresh = 100; } -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) uint32_t UITask::getTodaySteps() { uint32_t raw = board.getStepCount(); return (raw >= _stepBaseline) ? (raw - _stepBaseline) : raw; @@ -3742,7 +3742,7 @@ void UITask::gotoWebReader() { #if HAS_GPS void UITask::gotoMapScreen() { if (!map_screen) return; // Not available on this platform (T-Echo Card) -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) WatchMapScreen* map = (WatchMapScreen*)map_screen; if (_display != NULL) { map->enter(*_display); diff --git a/examples/companion_radio/ui-new/UITask.h b/examples/companion_radio/ui-new/UITask.h index 6d39065f..0092d05a 100644 --- a/examples/companion_radio/ui-new/UITask.h +++ b/examples/companion_radio/ui-new/UITask.h @@ -34,7 +34,7 @@ #include "AlarmScreen.h" #endif -#if defined(LilyGo_T5S3_EPaper_Pro) || defined(LILYGO_TWATCH_S3_PLUS) +#if defined(LilyGo_T5S3_EPaper_Pro) || defined(MECK_TWATCH) #include "VirtualKeyboard.h" #endif @@ -117,9 +117,9 @@ class UITask : public AbstractUITask { UIScreen* curr; bool _homeShowingTiles = false; // Set by HomeScreen render when tile grid is visible int _tileGridVY = 44; // Virtual Y of tile grid top (updated each render) -#if defined(LilyGo_T5S3_EPaper_Pro) || defined(LILYGO_TWATCH_S3_PLUS) +#if defined(LilyGo_T5S3_EPaper_Pro) || defined(MECK_TWATCH) UIScreen* lock_screen; // Lock screen (big clock + battery + unread) -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) UIScreen* steps_screen; // Steps screen (big daily step count) int32_t _lastStepDay = 0; // local day-of-epoch, for the midnight step reset uint32_t _stepBaseline = 0; // raw step count at the start of the local day @@ -225,7 +225,7 @@ public: void gotoGamesMenu(); // Navigate to games launcher menu void gotoSnakeScreen(); // Navigate to snake game void gotoMinesweeperScreen(); // Navigate to minesweeper game -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) void gotoStepsScreen(); // Navigate to the step counter screen uint32_t getTodaySteps(); // Daily step count (raw - baseline) #endif @@ -290,17 +290,17 @@ public: bool isOnTraceScreen() const { return curr == trace_screen; } bool isOnGamesMenu() const { return curr == games_menu_screen; } bool isOnSnakeScreen() const { return curr == snake_screen; } -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) bool isOnStepsScreen() const { return curr == steps_screen; } #endif bool isOnMinesweeperScreen() const { return curr == minesweeper_screen; } bool isOnMapScreen() const { return curr == map_screen; } -#if defined(LilyGo_T5S3_EPaper_Pro) || defined(LilyGo_TDeck_Pro) || defined(LILYGO_TWATCH_S3_PLUS) +#if defined(LilyGo_T5S3_EPaper_Pro) || defined(LilyGo_TDeck_Pro) || defined(MECK_TWATCH) bool isLocked() const { return _locked; } void lockScreen(); void unlockScreen(); #endif -#if defined(LilyGo_T5S3_EPaper_Pro) || defined(LILYGO_TWATCH_S3_PLUS) +#if defined(LilyGo_T5S3_EPaper_Pro) || defined(MECK_TWATCH) bool isVKBActive() const { return _vkbActive; } unsigned long vkbOpenedAt() const { return _vkbOpenedAt; } VirtualKeyboard& getVKB() { return _vkb; } @@ -382,7 +382,7 @@ public: UIScreen* getTraceScreen() const { return trace_screen; } UIScreen* getGamesMenuScreen() const { return games_menu_screen; } UIScreen* getSnakeScreen() const { return snake_screen; } -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) UIScreen* getStepsScreen() const { return steps_screen; } #endif UIScreen* getMinesweeperScreen() const { return minesweeper_screen; } diff --git a/examples/companion_radio/ui-new/VirtualKeyboard.h b/examples/companion_radio/ui-new/VirtualKeyboard.h index 49b5379f..2080bc92 100644 --- a/examples/companion_radio/ui-new/VirtualKeyboard.h +++ b/examples/companion_radio/ui-new/VirtualKeyboard.h @@ -12,7 +12,7 @@ // if (keyboard.status() == VKB_SUBMITTED) { ... keyboard.getText() ... } // ============================================================================= -#if defined(LilyGo_T5S3_EPaper_Pro) || defined(LILYGO_TWATCH_S3_PLUS) +#if defined(LilyGo_T5S3_EPaper_Pro) || defined(MECK_TWATCH) #ifndef VIRTUAL_KEYBOARD_H #define VIRTUAL_KEYBOARD_H @@ -536,4 +536,4 @@ private: }; #endif // VIRTUAL_KEYBOARD_H -#endif // LilyGo_T5S3_EPaper_Pro || LILYGO_TWATCH_S3_PLUS \ No newline at end of file +#endif // LilyGo_T5S3_EPaper_Pro || MECK_TWATCH \ No newline at end of file diff --git a/src/helpers/ui/LGFXDisplay.cpp b/src/helpers/ui/LGFXDisplay.cpp index 7b6ac894..49ade88d 100644 --- a/src/helpers/ui/LGFXDisplay.cpp +++ b/src/helpers/ui/LGFXDisplay.cpp @@ -56,14 +56,14 @@ void LGFXDisplay::setColor(Color c) { _color = TFT_WHITE; break; case RED: -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) _color = 0x7BEF; // dark grey -- the watch UI uses a grey/white/black palette #else _color = TFT_RED; #endif break; case GREEN: -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) _color = 0xC618; // light grey #else _color = TFT_GREEN; @@ -73,7 +73,7 @@ void LGFXDisplay::setColor(Color c) { _color = TFT_BLUE; break; case YELLOW: -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) _color = TFT_WHITE; #else _color = TFT_YELLOW; diff --git a/src/helpers/ui/LGFXDisplay.h b/src/helpers/ui/LGFXDisplay.h index 93a98754..c034d7ac 100644 --- a/src/helpers/ui/LGFXDisplay.h +++ b/src/helpers/ui/LGFXDisplay.h @@ -28,7 +28,7 @@ public: void startFrame(Color bkg = DARK) override; void setTextSize(int sz) override; void setColor(Color c) override; -#if defined(LILYGO_TWATCH_S3_PLUS) +#if defined(MECK_TWATCH) // Set an exact RGB565 colour, bypassing the Color enum + watch grey remap. // Used by the watch P4-style tile grid for per-tile border/fill colours. void setRawColor(uint16_t c) { _color = c; buffer.setTextColor(c); } diff --git a/variants/lilygo_twatch_s3_plus/platformio.ini b/variants/lilygo_twatch_s3_plus/platformio.ini index 7dd1fec9..d6dd8a59 100644 --- a/variants/lilygo_twatch_s3_plus/platformio.ini +++ b/variants/lilygo_twatch_s3_plus/platformio.ini @@ -11,6 +11,10 @@ build_flags = ${esp32_base.build_flags} ${sensor_base.build_flags} -I variants/lilygo_twatch_s3_plus + ; MECK_TWATCH gates the watch form factor (240x240, UI_ZOOM=2, touch, lock + ; screen, tile grid, grey palette). LILYGO_TWATCH_S3_PLUS gates hardware that + ; is specific to the Plus (onboard GNSS on BLDO1, GPIO0 user button). + -D MECK_TWATCH -D LILYGO_TWATCH_S3_PLUS -D TWATCH_COMPOSE_ENABLED -D MECK_RX_DUTY_CYCLE