mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-07-26 14:58:12 +00:00
feat(ui): status-bar mini-icons + settings fixes
- Replace single-letter M/B/A/G top-bar indicators with scalable mini-icons: ICON_MUTE (speaker+cross), ICON_BLUETOOTH (rune), ICON_ADVERT (broadcast mast+waves), ICON_TRAIL (map pin). Centred in the cw+2 indicator box; disconnected BT shows the plain glyph instead of lowercase b. - fix(settings): right-side values used display.valCol() without the scrollbar reserve, so after expanding a section they rendered under the indicator. Route all value cursors through valCol(display) = display.valCol() - _reserve. - fix(settings): font toggle used ^=1, which on a stale value of 2 (older Hybrid build) flips 2<->3 — both nonzero, locking applyFont() on Lemon with no way back. Normalise: use_lemon_font = use_lemon_font ? 0 : 1. - docs(settings): document Messages > Resend setting. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -93,4 +93,8 @@ Lists all available home screen pages. For each entry:
|
|||||||
|
|
||||||
### Messages
|
### Messages
|
||||||
|
|
||||||
|
| Setting | Options | Notes |
|
||||||
|
| ------- | -------------- | ---------------------------------------------------------------------------------------------- |
|
||||||
|
| Resend | off / 1×–5× | Auto-resend an on-device direct message this many times when no delivery ACK is received (default 2×) |
|
||||||
|
|
||||||
Up to 10 quick reply templates (Q1–Q10). Press **Enter** on a slot to open the keyboard editor. Supports the same placeholders as the main keyboard (`{time}`, `{loc}`, and sensor placeholders when connected).
|
Up to 10 quick reply templates (Q1–Q10). Press **Enter** on a slot to open the keyboard editor. Supports the same placeholders as the main keyboard (`{time}`, `{loc}`, and sensor placeholders when connected).
|
||||||
|
|||||||
@@ -111,6 +111,10 @@ class SettingsScreen : public UIScreen {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Value column start, pulled left by the scrollbar gutter so right-side
|
||||||
|
// values never render under the indicator when the list scrolls.
|
||||||
|
int valCol(DisplayDriver& display) const { return display.valCol() - _reserve; }
|
||||||
|
|
||||||
void renderBar(DisplayDriver& display, int x, int y, int value, int max_val) {
|
void renderBar(DisplayDriver& display, int x, int y, int value, int max_val) {
|
||||||
const int gap = 2;
|
const int gap = 2;
|
||||||
const int avail = display.width() - x - _reserve;
|
const int avail = display.width() - x - _reserve;
|
||||||
@@ -419,12 +423,12 @@ class SettingsScreen : public UIScreen {
|
|||||||
#if FEAT_BRIGHTNESS_SETTING
|
#if FEAT_BRIGHTNESS_SETTING
|
||||||
if (item == BRIGHTNESS) {
|
if (item == BRIGHTNESS) {
|
||||||
display.print("Bright");
|
display.print("Bright");
|
||||||
renderBar(display, display.valCol(), y, (p ? p->display_brightness : 2) + 1, 5);
|
renderBar(display, valCol(display), y, (p ? p->display_brightness : 2) + 1, 5);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
if (item == BUZZER) {
|
if (item == BUZZER) {
|
||||||
display.print("Buzzer");
|
display.print("Buzzer");
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
#ifdef PIN_BUZZER
|
#ifdef PIN_BUZZER
|
||||||
{ static const char* labels[] = { "ON", "OFF", "Auto" };
|
{ static const char* labels[] = { "ON", "OFF", "Auto" };
|
||||||
int m = _task->getBuzzerMode();
|
int m = _task->getBuzzerMode();
|
||||||
@@ -435,29 +439,29 @@ class SettingsScreen : public UIScreen {
|
|||||||
} else if (item == BUZZER_VOLUME) {
|
} else if (item == BUZZER_VOLUME) {
|
||||||
display.print("BzrVol");
|
display.print("BzrVol");
|
||||||
#ifdef PIN_BUZZER
|
#ifdef PIN_BUZZER
|
||||||
renderBar(display, display.valCol(), y, _task->getBuzzerVolume() + 1, 5);
|
renderBar(display, valCol(display), y, _task->getBuzzerVolume() + 1, 5);
|
||||||
#else
|
#else
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
display.print("N/A");
|
display.print("N/A");
|
||||||
#endif
|
#endif
|
||||||
} else if (item == DM_MELODY) {
|
} else if (item == DM_MELODY) {
|
||||||
display.print("DM sound");
|
display.print("DM sound");
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
{ uint8_t v = p ? p->notif_melody_dm : 0;
|
{ uint8_t v = p ? p->notif_melody_dm : 0;
|
||||||
display.print(SOUND_LABELS[v < SOUND_COUNT ? v : 0]); }
|
display.print(SOUND_LABELS[v < SOUND_COUNT ? v : 0]); }
|
||||||
} else if (item == CH_MELODY) {
|
} else if (item == CH_MELODY) {
|
||||||
display.print("Ch sound");
|
display.print("Ch sound");
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
{ uint8_t v = p ? p->notif_melody_ch : 0;
|
{ uint8_t v = p ? p->notif_melody_ch : 0;
|
||||||
display.print(SOUND_LABELS[v < SOUND_COUNT ? v : 0]); }
|
display.print(SOUND_LABELS[v < SOUND_COUNT ? v : 0]); }
|
||||||
} else if (item == AD_SOUND) {
|
} else if (item == AD_SOUND) {
|
||||||
display.print("AD sound");
|
display.print("AD sound");
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
{ uint8_t v = p ? p->notif_melody_ad : 0;
|
{ uint8_t v = p ? p->notif_melody_ad : 0;
|
||||||
display.print(SOUND_LABELS[v < SOUND_COUNT ? v : 0]); }
|
display.print(SOUND_LABELS[v < SOUND_COUNT ? v : 0]); }
|
||||||
} else if (item == AD_SOUND_SCOPE) {
|
} else if (item == AD_SOUND_SCOPE) {
|
||||||
display.print("AD scope");
|
display.print("AD scope");
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
{ uint8_t v = p ? p->advert_sound_scope : ADVERT_SOUND_SCOPE_ALL;
|
{ uint8_t v = p ? p->advert_sound_scope : ADVERT_SOUND_SCOPE_ALL;
|
||||||
display.print(AD_SCOPE_LABELS[v < AD_SCOPE_COUNT ? v : 0]); }
|
display.print(AD_SCOPE_LABELS[v < AD_SCOPE_COUNT ? v : 0]); }
|
||||||
} else if (isHomePage(item)) {
|
} else if (isHomePage(item)) {
|
||||||
@@ -477,25 +481,25 @@ class SettingsScreen : public UIScreen {
|
|||||||
display.print("TX Pwr");
|
display.print("TX Pwr");
|
||||||
char buf[8];
|
char buf[8];
|
||||||
snprintf(buf, sizeof(buf),"%ddBm", p ? p->tx_power_dbm : 0);
|
snprintf(buf, sizeof(buf),"%ddBm", p ? p->tx_power_dbm : 0);
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
display.print(buf);
|
display.print(buf);
|
||||||
} else if (item == POWER_SAVE) {
|
} else if (item == POWER_SAVE) {
|
||||||
display.print("Pwr save");
|
display.print("Pwr save");
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
display.print((p && p->rx_powersave) ? "ON" : "OFF");
|
display.print((p && p->rx_powersave) ? "ON" : "OFF");
|
||||||
} else if (item == TX_APC) {
|
} else if (item == TX_APC) {
|
||||||
display.print("Auto pwr");
|
display.print("Auto pwr");
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
display.print((p && p->tx_apc) ? "ON" : "OFF");
|
display.print((p && p->tx_apc) ? "ON" : "OFF");
|
||||||
#if AUTO_OFF_MILLIS > 0
|
#if AUTO_OFF_MILLIS > 0
|
||||||
} else if (item == AUTO_OFF) {
|
} else if (item == AUTO_OFF) {
|
||||||
display.print("AutoOff");
|
display.print("AutoOff");
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
display.print(AUTO_OFF_LABELS[autoOffIndex()]);
|
display.print(AUTO_OFF_LABELS[autoOffIndex()]);
|
||||||
#endif
|
#endif
|
||||||
} else if (item == AUTO_LOCK) {
|
} else if (item == AUTO_LOCK) {
|
||||||
display.print("AutoLock");
|
display.print("AutoLock");
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
display.print((p && p->auto_lock) ? "ON" : "OFF");
|
display.print((p && p->auto_lock) ? "ON" : "OFF");
|
||||||
} else if (item == TIMEZONE) {
|
} else if (item == TIMEZONE) {
|
||||||
display.print("TimeZone");
|
display.print("TimeZone");
|
||||||
@@ -503,39 +507,39 @@ class SettingsScreen : public UIScreen {
|
|||||||
int8_t tz = p ? p->tz_offset_hours : 0;
|
int8_t tz = p ? p->tz_offset_hours : 0;
|
||||||
if (tz >= 0) snprintf(buf, sizeof(buf),"UTC+%d", (int)tz);
|
if (tz >= 0) snprintf(buf, sizeof(buf),"UTC+%d", (int)tz);
|
||||||
else snprintf(buf, sizeof(buf),"UTC%d", (int)tz);
|
else snprintf(buf, sizeof(buf),"UTC%d", (int)tz);
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
display.print(buf);
|
display.print(buf);
|
||||||
} else if (item == LOW_BAT) {
|
} else if (item == LOW_BAT) {
|
||||||
display.print("LowBat");
|
display.print("LowBat");
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
display.print(LOW_BAT_LABELS[lowBatIndex()]);
|
display.print(LOW_BAT_LABELS[lowBatIndex()]);
|
||||||
} else if (item == UNITS) {
|
} else if (item == UNITS) {
|
||||||
display.print("Units");
|
display.print("Units");
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
display.print((p && p->units_imperial) ? "Imperial" : "Metric");
|
display.print((p && p->units_imperial) ? "Imperial" : "Metric");
|
||||||
} else if (item == BATT_DISPLAY) {
|
} else if (item == BATT_DISPLAY) {
|
||||||
display.print("BattDisp");
|
display.print("BattDisp");
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
uint8_t mode = p ? p->batt_display_mode : 0;
|
uint8_t mode = p ? p->batt_display_mode : 0;
|
||||||
display.print(BATT_DISPLAY_LABELS[mode < BATT_DISPLAY_COUNT ? mode : 0]);
|
display.print(BATT_DISPLAY_LABELS[mode < BATT_DISPLAY_COUNT ? mode : 0]);
|
||||||
#if FEAT_CLOCK_SECONDS_SETTING
|
#if FEAT_CLOCK_SECONDS_SETTING
|
||||||
} else if (item == CLOCK_SECONDS) {
|
} else if (item == CLOCK_SECONDS) {
|
||||||
display.print("Seconds");
|
display.print("Seconds");
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
display.print((p && p->clock_hide_seconds) ? "OFF" : "ON");
|
display.print((p && p->clock_hide_seconds) ? "OFF" : "ON");
|
||||||
#endif
|
#endif
|
||||||
} else if (item == CLOCK_FORMAT) {
|
} else if (item == CLOCK_FORMAT) {
|
||||||
display.print("Format");
|
display.print("Format");
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
display.print((p && p->clock_12h) ? "12h" : "24h");
|
display.print((p && p->clock_12h) ? "12h" : "24h");
|
||||||
} else if (item == FONT) {
|
} else if (item == FONT) {
|
||||||
display.print("Font");
|
display.print("Font");
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
display.print((p && p->use_lemon_font) ? "Lemon" : "Default");
|
display.print((p && p->use_lemon_font) ? "Lemon" : "Default");
|
||||||
#if FEAT_DISPLAY_ROTATION_SETTING
|
#if FEAT_DISPLAY_ROTATION_SETTING
|
||||||
} else if (item == ROTATION) {
|
} else if (item == ROTATION) {
|
||||||
display.print("Rotation");
|
display.print("Rotation");
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
{ static const char* ROT_LABELS[] = { "0 deg", "90 deg", "180 deg", "270 deg" };
|
{ static const char* ROT_LABELS[] = { "0 deg", "90 deg", "180 deg", "270 deg" };
|
||||||
uint8_t r = p ? (p->display_rotation & 3) : 0;
|
uint8_t r = p ? (p->display_rotation & 3) : 0;
|
||||||
display.print(ROT_LABELS[r]); }
|
display.print(ROT_LABELS[r]); }
|
||||||
@@ -543,7 +547,7 @@ class SettingsScreen : public UIScreen {
|
|||||||
#if FEAT_JOYSTICK_ROTATION_SETTING
|
#if FEAT_JOYSTICK_ROTATION_SETTING
|
||||||
} else if (item == JOY_ROTATION) {
|
} else if (item == JOY_ROTATION) {
|
||||||
display.print("Joystick");
|
display.print("Joystick");
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
{ static const char* ROT_LABELS[] = { "0 deg", "90 deg", "180 deg", "270 deg" };
|
{ static const char* ROT_LABELS[] = { "0 deg", "90 deg", "180 deg", "270 deg" };
|
||||||
uint8_t r = p ? (p->joystick_rotation & 3) : 0;
|
uint8_t r = p ? (p->joystick_rotation & 3) : 0;
|
||||||
display.print(ROT_LABELS[r]); }
|
display.print(ROT_LABELS[r]); }
|
||||||
@@ -551,26 +555,26 @@ class SettingsScreen : public UIScreen {
|
|||||||
#if FEAT_FULL_REFRESH_SETTING
|
#if FEAT_FULL_REFRESH_SETTING
|
||||||
} else if (item == EINK_FULL_REFRESH) {
|
} else if (item == EINK_FULL_REFRESH) {
|
||||||
display.print("Full rfsh");
|
display.print("Full rfsh");
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
{ uint8_t idx = p ? p->eink_full_refresh_every : 0;
|
{ uint8_t idx = p ? p->eink_full_refresh_every : 0;
|
||||||
if (idx >= EINK_FULL_REFRESH_COUNT) idx = 0;
|
if (idx >= EINK_FULL_REFRESH_COUNT) idx = 0;
|
||||||
display.print(EINK_FULL_REFRESH_LABELS[idx]); }
|
display.print(EINK_FULL_REFRESH_LABELS[idx]); }
|
||||||
#endif
|
#endif
|
||||||
} else if (item == DM_FILTER) {
|
} else if (item == DM_FILTER) {
|
||||||
display.print("DM");
|
display.print("DM");
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
display.print((p && p->dm_show_all) ? "all" : "fav");
|
display.print((p && p->dm_show_all) ? "all" : "fav");
|
||||||
} else if (item == CH_FILTER) {
|
} else if (item == CH_FILTER) {
|
||||||
display.print("Channels");
|
display.print("Channels");
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
display.print((p && p->ch_fav_only) ? "fav" : "all");
|
display.print((p && p->ch_fav_only) ? "fav" : "all");
|
||||||
} else if (item == ROOM_FILTER) {
|
} else if (item == ROOM_FILTER) {
|
||||||
display.print("Rooms");
|
display.print("Rooms");
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
display.print((p && p->room_fav_only) ? "fav" : "all");
|
display.print((p && p->room_fav_only) ? "fav" : "all");
|
||||||
} else if (item == DM_RESEND) {
|
} else if (item == DM_RESEND) {
|
||||||
display.print("Resend");
|
display.print("Resend");
|
||||||
display.setCursor(display.valCol(), y);
|
display.setCursor(valCol(display), y);
|
||||||
uint8_t n = p ? p->dm_resend_count : 0;
|
uint8_t n = p ? p->dm_resend_count : 0;
|
||||||
if (n == 0) display.print("OFF");
|
if (n == 0) display.print("OFF");
|
||||||
else { char buf[6]; snprintf(buf, sizeof(buf), "%ux", (unsigned)n); display.print(buf); }
|
else { char buf[6]; snprintf(buf, sizeof(buf), "%ux", (unsigned)n); display.print(buf); }
|
||||||
@@ -806,7 +810,9 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (_selected == FONT && p && (left || right || enter)) {
|
if (_selected == FONT && p && (left || right || enter)) {
|
||||||
p->use_lemon_font ^= 1;
|
// Normalise (not ^=1): a stale value >1 from an older build with extra
|
||||||
|
// font modes would otherwise toggle 2<->3 and stay stuck on Lemon.
|
||||||
|
p->use_lemon_font = p->use_lemon_font ? 0 : 1;
|
||||||
_task->applyFont();
|
_task->applyFont();
|
||||||
_dirty = true;
|
_dirty = true;
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -445,8 +445,7 @@ class HomeScreen : public UIScreen {
|
|||||||
int mx = battLeftX - ind - ind_gap;
|
int mx = battLeftX - ind - ind_gap;
|
||||||
display.fillRect(mx, 0, ind, ind_h);
|
display.fillRect(mx, 0, ind, ind_h);
|
||||||
display.setColor(DisplayDriver::DARK);
|
display.setColor(DisplayDriver::DARK);
|
||||||
display.setCursor(mx + 1, 0);
|
miniIconDraw(display, mx + (ind - ICON_MUTE.w * miniIconScale(display)) / 2, 0, ICON_MUTE);
|
||||||
display.print("M");
|
|
||||||
display.setColor(DisplayDriver::LIGHT);
|
display.setColor(DisplayDriver::LIGHT);
|
||||||
battLeftX = mx;
|
battLeftX = mx;
|
||||||
}
|
}
|
||||||
@@ -456,16 +455,15 @@ class HomeScreen : public UIScreen {
|
|||||||
int leftmostX = battLeftX;
|
int leftmostX = battLeftX;
|
||||||
if (_task->isSerialEnabled()) {
|
if (_task->isSerialEnabled()) {
|
||||||
int btX = battLeftX - ind - ind_gap;
|
int btX = battLeftX - ind - ind_gap;
|
||||||
|
int btIconX = btX + (ind - ICON_BLUETOOTH.w * miniIconScale(display)) / 2;
|
||||||
if (_task->isBLEConnected()) { // BT icon reflects BLE link, not USB
|
if (_task->isBLEConnected()) { // BT icon reflects BLE link, not USB
|
||||||
display.setColor(DisplayDriver::LIGHT);
|
display.setColor(DisplayDriver::LIGHT);
|
||||||
display.fillRect(btX, 0, ind, ind_h);
|
display.fillRect(btX, 0, ind, ind_h);
|
||||||
display.setColor(DisplayDriver::DARK);
|
display.setColor(DisplayDriver::DARK);
|
||||||
display.setCursor(btX + 1, 0);
|
miniIconDraw(display, btIconX, 0, ICON_BLUETOOTH);
|
||||||
display.print("B");
|
|
||||||
display.setColor(DisplayDriver::LIGHT);
|
display.setColor(DisplayDriver::LIGHT);
|
||||||
} else {
|
} else {
|
||||||
display.setCursor(btX + 1, 0);
|
miniIconDraw(display, btIconX, 0, ICON_BLUETOOTH); // plain glyph: available, not linked
|
||||||
display.print("b");
|
|
||||||
}
|
}
|
||||||
leftmostX = btX - ind_gap;
|
leftmostX = btX - ind_gap;
|
||||||
|
|
||||||
@@ -477,8 +475,7 @@ class HomeScreen : public UIScreen {
|
|||||||
display.setColor(DisplayDriver::LIGHT);
|
display.setColor(DisplayDriver::LIGHT);
|
||||||
display.fillRect(aX, 0, ind, ind_h);
|
display.fillRect(aX, 0, ind, ind_h);
|
||||||
display.setColor(DisplayDriver::DARK);
|
display.setColor(DisplayDriver::DARK);
|
||||||
display.setCursor(aX + 1, 0);
|
miniIconDraw(display, aX + (ind - ICON_ADVERT.w * miniIconScale(display)) / 2, 0, ICON_ADVERT);
|
||||||
display.print("A");
|
|
||||||
display.setColor(DisplayDriver::LIGHT);
|
display.setColor(DisplayDriver::LIGHT);
|
||||||
}
|
}
|
||||||
leftmostX = aX - 1;
|
leftmostX = aX - 1;
|
||||||
@@ -492,8 +489,7 @@ class HomeScreen : public UIScreen {
|
|||||||
display.setColor(DisplayDriver::LIGHT);
|
display.setColor(DisplayDriver::LIGHT);
|
||||||
display.fillRect(gX, 0, ind, ind_h);
|
display.fillRect(gX, 0, ind, ind_h);
|
||||||
display.setColor(DisplayDriver::DARK);
|
display.setColor(DisplayDriver::DARK);
|
||||||
display.setCursor(gX + 1, 0);
|
miniIconDraw(display, gX + (ind - ICON_TRAIL.w * miniIconScale(display)) / 2, 0, ICON_TRAIL);
|
||||||
display.print("G");
|
|
||||||
display.setColor(DisplayDriver::LIGHT);
|
display.setColor(DisplayDriver::LIGHT);
|
||||||
}
|
}
|
||||||
leftmostX = gX - 1;
|
leftmostX = gX - 1;
|
||||||
|
|||||||
@@ -118,6 +118,39 @@ MINI_ICON(ICON_CROSS, 4, // ✗
|
|||||||
packRow(".##."),
|
packRow(".##."),
|
||||||
packRow("#..#"));
|
packRow("#..#"));
|
||||||
|
|
||||||
|
// Top-bar status glyphs (replace the single-letter M / B / A indicators).
|
||||||
|
MINI_ICON(ICON_MUTE, 6, // speaker + cross (sound off)
|
||||||
|
packRow("..#..."),
|
||||||
|
packRow(".##..."),
|
||||||
|
packRow("####.#"),
|
||||||
|
packRow("###.#."),
|
||||||
|
packRow("####.#"),
|
||||||
|
packRow(".##..."),
|
||||||
|
packRow("..#..."));
|
||||||
|
MINI_ICON(ICON_BLUETOOTH, 5, // ᛒ bluetooth rune
|
||||||
|
packRow("..#.."),
|
||||||
|
packRow("..##."),
|
||||||
|
packRow("#.#.#"),
|
||||||
|
packRow(".###."),
|
||||||
|
packRow("#.#.#"),
|
||||||
|
packRow("..##."),
|
||||||
|
packRow("..#.."));
|
||||||
|
MINI_ICON(ICON_ADVERT, 6, // broadcast mast + radiating waves (auto-advert)
|
||||||
|
packRow("#....#"),
|
||||||
|
packRow(".#..#."),
|
||||||
|
packRow("..##.."),
|
||||||
|
packRow("..##.."),
|
||||||
|
packRow(".####."),
|
||||||
|
packRow(".####."));
|
||||||
|
|
||||||
|
MINI_ICON(ICON_TRAIL, 6, // map pin / location marker (GPS trail logging)
|
||||||
|
packRow(".####."),
|
||||||
|
packRow("######"),
|
||||||
|
packRow("##..##"),
|
||||||
|
packRow("######"),
|
||||||
|
packRow(".####."),
|
||||||
|
packRow("..##.."));
|
||||||
|
|
||||||
// Keyboard special-key glyphs.
|
// Keyboard special-key glyphs.
|
||||||
MINI_ICON(ICON_SHIFT, 7, // ⇧ caps
|
MINI_ICON(ICON_SHIFT, 7, // ⇧ caps
|
||||||
packRow("...#..."),
|
packRow("...#..."),
|
||||||
|
|||||||
Reference in New Issue
Block a user