mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-07-26 23:08:11 +00:00
feat(home): page-indicator icons instead of dots
Replace the home carousel's page-indicator dots with a small per-page glyph set (uniform 5x5, smaller than the menu/status icons), the current page underlined rather than inverted (an inverted box read too much like the top status bar). Icons follow buildVisibleOrder, so custom page order and hide/show toggles from Settings carry over automatically; the row pitch shrinks to fit when many pages are enabled, and the band geometry scales with the font (identical layout to the old dots at 1x, clears header/content on 2x e-ink). Adds 13 ICON_PG_* glyphs (clock, star, recent, radio, bluetooth, advert, gps, sensors, settings, map, tools, msg, power). Builds verified: WioTrackerL1 + e-ink solo. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -627,13 +627,41 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
// Small 5x5 glyph shown in the page-indicator row for each HomePage.
|
||||
static const MiniIcon* pageIcon(int page) {
|
||||
switch (page) {
|
||||
case CLOCK: return &ICON_PG_CLOCK;
|
||||
case FAVOURITES: return &ICON_PG_STAR;
|
||||
case RECENT: return &ICON_PG_RECENT;
|
||||
case RADIO: return &ICON_PG_RADIO;
|
||||
case BLUETOOTH: return &ICON_PG_BT;
|
||||
case ADVERT: return &ICON_PG_ADVERT;
|
||||
#if ENV_INCLUDE_GPS == 1
|
||||
case GPS: return &ICON_PG_GPS;
|
||||
#endif
|
||||
#if UI_SENSORS_PAGE == 1
|
||||
case SENSORS: return &ICON_PG_SENSORS;
|
||||
#endif
|
||||
case SETTINGS: return &ICON_PG_SETTINGS;
|
||||
case MAP: return &ICON_PG_MAP;
|
||||
case TOOLS: return &ICON_PG_TOOLS;
|
||||
case QUICK_MSG: return &ICON_PG_MSG;
|
||||
case SHUTDOWN: return &ICON_PG_POWER;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int render(DisplayDriver& display) override {
|
||||
char tmp[80];
|
||||
display.setTextSize(1);
|
||||
const int lh = display.getLineHeight(); // line height at sz1
|
||||
const int step = display.lineStep(); // lh + 2
|
||||
const int dots_y = lh + 4; // page-dot row: just below header
|
||||
const int content_y = dots_y + 6; // first content row (6px gap keeps dots visible)
|
||||
// Page-indicator row: small (5px) page icons replace the old dots. Centre and
|
||||
// gap scale with the font so the band clears the header above and content
|
||||
// below (identical to the old lh+4 / +6 dots layout at 1x).
|
||||
const int pg_half = (5 * miniIconScale(display) + 1) / 2;
|
||||
const int dots_y = lh + pg_half + 1; // icon-row centre, below the header
|
||||
const int content_y = dots_y + pg_half + 3; // first content row, below the icons
|
||||
|
||||
// node name + battery — hidden on CLOCK page (full screen used for dashboard)
|
||||
if (_page != CLOCK) {
|
||||
@@ -660,17 +688,26 @@ public:
|
||||
// ensure current page is visible (e.g. after settings change)
|
||||
if (!isPageVisible(_page)) _page = navPage(_page, +1);
|
||||
|
||||
// curr page indicator — hidden on CLOCK page (full screen used for dashboard)
|
||||
// curr page indicator — a row of small page icons, one per visible page, with
|
||||
// the current page underlined. Hidden on CLOCK (full screen used for dashboard).
|
||||
if (_page != CLOCK) {
|
||||
int order[(int)Count]; int n = buildVisibleOrder(order);
|
||||
int curr_vis = 0;
|
||||
for (int i = 0; i < n; i++) if (order[i] == _page) { curr_vis = i; break; }
|
||||
int x = display.width() / 2 - 5 * (n - 1);
|
||||
const int s = miniIconScale(display);
|
||||
const int icon_w = 5 * s;
|
||||
int pitch = icon_w + 5 * s; // comfortable spacing
|
||||
if (n > 1) { // shrink to fit if many pages
|
||||
int fit = (display.width() - icon_w) / (n - 1);
|
||||
if (fit < pitch) pitch = fit;
|
||||
}
|
||||
int x = display.width() / 2 - pitch * (n - 1) / 2;
|
||||
for (int i = 0; i < n; i++) {
|
||||
int ds = display.isLandscape() ? 2 : 1;
|
||||
if (i == curr_vis) display.fillRect(x-ds, dots_y-ds, 2*ds+1, 2*ds+1);
|
||||
else display.fillRect(x-ds+1, dots_y-ds+1, 2*ds-1, 2*ds-1);
|
||||
x += 10;
|
||||
const MiniIcon* ic = pageIcon(order[i]);
|
||||
if (ic) miniIconDrawCentered(display, x, dots_y, *ic);
|
||||
if (i == curr_vis) // underline the current page
|
||||
display.fillRect(x - icon_w / 2, dots_y + pg_half + 1, icon_w, s);
|
||||
x += pitch;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -179,8 +179,8 @@ MINI_ICON(ICON_NOTE, 5, // ♪ quaver — ringtone editor
|
||||
packRow("...#."),
|
||||
packRow("...#."),
|
||||
packRow("...#."),
|
||||
packRow("##.#."),
|
||||
packRow("##..."));
|
||||
packRow("####."),
|
||||
packRow("####."));
|
||||
MINI_ICON(ICON_CHART, 5, // ascending bars — diagnostics / stats
|
||||
packRow("....#"),
|
||||
packRow("..#.#"),
|
||||
@@ -192,11 +192,93 @@ MINI_ICON(ICON_GEAR, 7, // ⚙ cog with hub hole — system
|
||||
packRow("..#.#.."),
|
||||
packRow(".#####."),
|
||||
packRow("#######"),
|
||||
packRow("###.###"),
|
||||
packRow(".##.##."),
|
||||
packRow("#######"),
|
||||
packRow(".#####."),
|
||||
packRow("..#.#.."));
|
||||
|
||||
// Home-carousel page glyphs — a uniform 5x5 set, deliberately smaller than the
|
||||
// menu/status icons above, used in place of the page-indicator dots. One per
|
||||
// HomePage; see UITask HomeScreen::pageIcon().
|
||||
MINI_ICON(ICON_PG_CLOCK, 5, // clock face + hands
|
||||
packRow(".###."),
|
||||
packRow("#.#.#"),
|
||||
packRow("#.###"),
|
||||
packRow("#...#"),
|
||||
packRow(".###."));
|
||||
MINI_ICON(ICON_PG_STAR, 5, // favourites
|
||||
packRow("..#.."),
|
||||
packRow("#####"),
|
||||
packRow(".###."),
|
||||
packRow("##.##"),
|
||||
packRow("#...#"));
|
||||
MINI_ICON(ICON_PG_RECENT, 5, // stacked lines — recent list
|
||||
packRow("#####"),
|
||||
packRow("....."),
|
||||
packRow("#####"),
|
||||
packRow("....."),
|
||||
packRow("#####"));
|
||||
MINI_ICON(ICON_PG_RADIO, 5, // antenna tower — radio params
|
||||
packRow("..#.."),
|
||||
packRow(".###."),
|
||||
packRow("..#.."),
|
||||
packRow(".#.#."),
|
||||
packRow("#...#"));
|
||||
MINI_ICON(ICON_PG_BT, 5, // bluetooth (compact)
|
||||
packRow("..#.."),
|
||||
packRow("#.##."),
|
||||
packRow(".###."),
|
||||
packRow("#.##."),
|
||||
packRow("..#.."));
|
||||
MINI_ICON(ICON_PG_ADVERT, 5, // mast + radiating waves — advert
|
||||
packRow("#...#"),
|
||||
packRow(".#.#."),
|
||||
packRow("..#.."),
|
||||
packRow("..#.."),
|
||||
packRow("..#.."));
|
||||
MINI_ICON(ICON_PG_GPS, 5, // location pin — GPS
|
||||
packRow(".###."),
|
||||
packRow("#...#"),
|
||||
packRow("#...#"),
|
||||
packRow(".#.#."),
|
||||
packRow("..#.."));
|
||||
MINI_ICON(ICON_PG_SENSORS, 5, // thermometer/gauge — sensors
|
||||
packRow("..#.."),
|
||||
packRow(".#.#."),
|
||||
packRow(".#.#."),
|
||||
packRow(".###."),
|
||||
packRow(".###."));
|
||||
MINI_ICON(ICON_PG_SETTINGS, 5, // small cog — settings
|
||||
packRow(".#.#."),
|
||||
packRow("#####"),
|
||||
packRow("##.##"),
|
||||
packRow("#####"),
|
||||
packRow(".#.#."));
|
||||
MINI_ICON(ICON_PG_MAP, 5, // folded map — map page
|
||||
packRow("#####"),
|
||||
packRow("#.#.#"),
|
||||
packRow("#.#.#"),
|
||||
packRow("#.#.#"),
|
||||
packRow("#####"));
|
||||
MINI_ICON(ICON_PG_TOOLS, 5, // wrench (open jaw + handle) — tools
|
||||
packRow(".#.#."),
|
||||
packRow(".###."),
|
||||
packRow("..#.."),
|
||||
packRow("..#.."),
|
||||
packRow("..#.."));
|
||||
MINI_ICON(ICON_PG_MSG, 5, // speech bubble — quick messages
|
||||
packRow("#####"),
|
||||
packRow("#...#"),
|
||||
packRow("#...#"),
|
||||
packRow("#####"),
|
||||
packRow(".#..."));
|
||||
MINI_ICON(ICON_PG_POWER, 5, // power symbol — shutdown
|
||||
packRow("..#.."),
|
||||
packRow("#.#.#"),
|
||||
packRow("#...#"),
|
||||
packRow("#...#"),
|
||||
packRow(".###."));
|
||||
|
||||
// Trail-map markers — centred on a point (see miniIconDrawCentered) rather
|
||||
// than anchored to a text line.
|
||||
MINI_ICON(ICON_MAP_DOT, 3, // ● filled trail point
|
||||
|
||||
Reference in New Issue
Block a user