Fix trace screen for t5s3 and add home icon for trace screen to t5s3

This commit is contained in:
pelgraine
2026-05-07 20:27:58 +10:00
parent 5cca0e8e50
commit 661157e368
5 changed files with 108 additions and 9 deletions
+21 -3
View File
@@ -696,6 +696,7 @@
#include "DiscoveryScreen.h"
#include "LastHeardScreen.h"
#include "PathEditorScreen.h"
#include "Tracescreen.h"
static TouchDrvGT911 gt911Touch;
static bool gt911Ready = false;
@@ -1208,18 +1209,18 @@ static void lastHeardToggleContact() {
// Home screen FIRST page: tile taps (virtual coordinate hit test)
if (ui_task.isOnHomeScreen() && ui_task.isHomeShowingTiles()) {
const int tileW = 40, tileH = 28, gapX = 1, gapY = 1;
const int tileW = 40, tileH = 22, gapX = 1, gapY = 1;
const int gridW = tileW * 3 + gapX * 2;
const int gridX = (128 - gridW) / 2; // =3
int gridY = ui_task.getTileGridVY();
// Check if tap is within the tile grid area
if (vx >= gridX && vx < gridX + gridW &&
vy >= gridY && vy < gridY + 2 * (tileH + gapY)) {
vy >= gridY && vy < gridY + 3 * (tileH + gapY)) {
int col = (vx - gridX) / (tileW + gapX);
if (col > 2) col = 2;
int row = (vy - gridY) / (tileH + gapY);
if (row > 1) row = 1;
if (row > 2) row = 2;
if (row == 0 && col == 0) { ui_task.gotoChannelPickerScreen(); return 0; }
if (row == 0 && col == 1) { ui_task.gotoContactsScreen(); return 0; }
@@ -1231,6 +1232,8 @@ static void lastHeardToggleContact() {
#else
if (row == 1 && col == 2) { ui_task.gotoDiscoveryScreen(); return 0; }
#endif
// Third row: only centre tile (col 1) is real; col 0 and col 2 fall through to page-flip
if (row == 2 && col == 1) { ui_task.gotoTraceScreen(); return 0; }
}
// Tap outside tiles — left half backward, right half forward
return (vx < 64) ? (char)KEY_PREV : (char)KEY_NEXT;
@@ -1694,6 +1697,21 @@ static void lastHeardToggleContact() {
return KEY_ENTER;
}
// Trace screen: long press = Enter on most rows; on T5S3 the Type Path row
// opens the virtual keyboard instead so users can enter a comma-separated
// hash list without a physical keyboard.
if (ui_task.isOnTraceScreen()) {
#if defined(LilyGo_T5S3_EPaper_Pro)
TraceScreen* ts = (TraceScreen*)ui_task.getTraceScreen();
if (ts && ts->isOnTypePathRow()) {
const char* current = ts->getCurrentPathAsText();
ui_task.showVirtualKeyboard(VKB_TRACE_PATH, "Type Path", current, 79);
return 0;
}
#endif
return KEY_ENTER;
}
// Repeater admin: long press → open keyboard for password or CLI
if (ui_task.isOnRepeaterAdmin()) {
RepeaterAdminScreen* admin = (RepeaterAdminScreen*)ui_task.getRepeaterAdminScreen();
@@ -306,6 +306,33 @@ public:
bool wantsExit() const { return _wantExit; }
bool isEditing() const { return _editing; }
// --- Public helpers for T5S3 long-press → virtual keyboard integration ---
// True if the highlighted menu row is the Type Path entry (STATE_BUILD only).
bool isOnTypePathRow() const {
return _state == STATE_BUILD && menuItemAt(_menuSel) == MENU_TYPE_PATH;
}
// Returns the current path formatted as a comma-separated string, suitable
// for pre-populating an external text editor (e.g. the T5S3 virtual keyboard).
// The returned pointer references an internal buffer and is valid until the
// next call to this method or to setTypedPath()/parseTypedPath().
const char* getCurrentPathAsText() {
pathToEditBuf();
return _editBuf;
}
// Apply a path typed externally (via virtual keyboard submission).
// Replaces the working path buffer with whatever parses out of `text`
// and ensures the inline editor flag is cleared so the menu redraws cleanly.
void setTypedPath(const char* text) {
if (!text) return;
strncpy(_editBuf, text, sizeof(_editBuf) - 1);
_editBuf[sizeof(_editBuf) - 1] = '\0';
parseTypedPath();
_editing = false;
}
void enter(int pathHashMode) {
_state = STATE_BUILD;
_hopCount = 0;
@@ -433,7 +460,11 @@ private:
snprintf(tmp, sizeof(tmp), "%c Path: %s", prefix, pathStr);
display.print(tmp);
} else {
#if defined(LilyGo_T5S3_EPaper_Pro)
snprintf(tmp, sizeof(tmp), "%c Type Path: [Long press]", prefix);
#else
snprintf(tmp, sizeof(tmp), "%c Type Path: [Press Enter]", prefix);
#endif
display.print(tmp);
}
break;
@@ -494,9 +525,17 @@ private:
display.setColor(DisplayDriver::LIGHT);
display.setCursor(0, footerY);
if (_editing) {
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Boot:Cancel Tap:Apply");
#else
display.print("Q:Cancel Enter:Apply");
#endif
} else {
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Boot:Exit Tap:Sel");
#else
display.print("Q:Exit W/S:Nav Ent:Sel");
#endif
}
return 5000;
@@ -555,7 +594,11 @@ private:
display.drawRect(0, footerY - 2, display.width(), 1);
display.setColor(DisplayDriver::LIGHT);
display.setCursor(0, footerY);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Boot:Back Tap:Add");
#else
display.print("Q:Back W/S:Scroll Ent:Add");
#endif
return 5000;
}
@@ -607,7 +650,11 @@ private:
display.drawRect(0, footerY - 2, display.width(), 1);
display.setColor(DisplayDriver::LIGHT);
display.setCursor(0, footerY);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Boot:Cancel");
#else
display.print("Q:Cancel");
#endif
return 500; // Fast refresh for elapsed timer
}
@@ -699,7 +746,11 @@ private:
display.drawRect(0, footerY - 2, display.width(), 1);
display.setColor(DisplayDriver::LIGHT);
display.setCursor(0, footerY);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Boot:Back Tap:New Trace");
#else
display.print("Q:Back Ent:New Trace");
#endif
return 5000;
}
+29 -6
View File
@@ -499,7 +499,7 @@ public:
};
const int tileW = 40;
const int tileH = 28;
const int tileH = 22;
const int gapX = 1;
const int gapY = 1;
const int gridW = tileW * 3 + gapX * 2;
@@ -518,20 +518,35 @@ public:
// Icon centered in tile
int iconX = tx + (tileW - HOME_ICON_W) / 2;
int iconY = ty + 4;
int iconY = ty + 2;
display.drawXbm(iconX, iconY, tiles[row][col].icon, HOME_ICON_W, HOME_ICON_H);
// Label centered below icon
display.setTextSize(_node_prefs->smallTextSize());
display.drawTextCentered(tx + tileW / 2, ty + 18, tiles[row][col].label);
display.drawTextCentered(tx + tileW / 2, ty + 15, tiles[row][col].label);
}
}
// Nav hint below grid
y = gridY + 2 * tileH + gapY + 2;
// Third row: single centred Trace tile (column 1 position only)
{
int row3y = gridY + 2 * (tileH + gapY);
int col1x = gridX + (tileW + gapX);
display.setColor(DisplayDriver::LIGHT);
display.drawRect(col1x, row3y, tileW, tileH);
int iconX = col1x + (tileW - HOME_ICON_W) / 2;
int iconY = row3y + 2;
display.drawXbm(iconX, iconY, icon_trace, HOME_ICON_W, HOME_ICON_H);
display.setTextSize(_node_prefs->smallTextSize());
display.drawTextCentered(col1x + tileW / 2, row3y + 15, "Trace");
}
// Nav hint at bottom of screen
display.setColor(DisplayDriver::GREEN);
display.setTextSize(_node_prefs->smallTextSize());
display.drawTextCentered(display.width() / 2, y, "Tap tile to open");
display.drawTextCentered(display.width() / 2, display.height() - 8, "Tap tile to open");
}
display.setTextSize(1);
@@ -2523,6 +2538,14 @@ void UITask::onVKBSubmit() {
if (_screenBeforeVKB) setCurrScreen(_screenBeforeVKB);
break;
}
case VKB_TRACE_PATH: {
TraceScreen* ts = (TraceScreen*)getTraceScreen();
if (ts) {
ts->setTypedPath(text);
}
if (_screenBeforeVKB) setCurrScreen(_screenBeforeVKB);
break;
}
}
_screenBeforeVKB = nullptr;
_next_refresh = 0;
@@ -54,6 +54,12 @@ static const uint8_t icon_alarm[] PROGMEM = {
0x40,0x40, 0x20,0x80, 0x1F,0x00, 0x00,0x00, 0x20,0x40, 0x40,0x20,
};
// ➡ Right arrow (Trace Route)
static const uint8_t icon_trace[] PROGMEM = {
0x00,0x00, 0x00,0x00, 0x00,0x80, 0x00,0xC0, 0x00,0xE0, 0xFF,0xF0,
0xFF,0xF0, 0x00,0xE0, 0x00,0xC0, 0x00,0x80, 0x00,0x00, 0x00,0x00,
};
// 🔔 Bell — 7x8 status bar indicator (alarm enabled)
// MSB-first, 1 byte per row
#define BELL_ICON_W 7
@@ -39,6 +39,7 @@ enum VKBPurpose {
VKB_WEB_LINK, // Web reader link number entry
#endif
VKB_TEXT_PAGE, // Text reader: go to page number
VKB_TRACE_PATH, // Trace screen: type comma-separated path values
};
class VirtualKeyboard {