emdashes begone (#10847)

This commit is contained in:
Tom
2026-07-01 19:01:27 -05:00
committed by GitHub
parent dee94e0758
commit 3becaf2d95
276 changed files with 1795 additions and 1793 deletions
+11 -11
View File
@@ -2,9 +2,9 @@
BaseUI
Developed and Maintained By:
- Ronald Garcia (HarukiToreda) – Lead development and implementation.
- JasonP (Xaositek) – Screen layout and icon design, UI improvements and testing.
- TonyG (Tropho) – Project management, structural planning, and testing
- Ronald Garcia (HarukiToreda) - Lead development and implementation.
- JasonP (Xaositek) - Screen layout and icon design, UI improvements and testing.
- TonyG (Tropho) - Project management, structural planning, and testing
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -126,7 +126,7 @@ static inline void prepareFrameColorRegions()
// "LOCKED" plus battery so the operator can see the device is alive and
// charged without leaking any node/channel/message/position content.
// Draw the LOCKED frame into the host-side framebuffer. Does NOT commit
// to the panel — the caller is responsible for calling display->display()
// to the panel - the caller is responsible for calling display->display()
// once it has composited any overlays on top. Committing here would cause
// visible flicker between "just LOCKED" and "LOCKED + banner overlay" when
// the pairing-PIN special-case in updateUiFrame paints the overlay after
@@ -166,8 +166,8 @@ static inline void updateUiFrame(OLEDDisplayUi *ui)
if (meshtastic_security::shouldRedactDisplay() && screen != nullptr) {
OLEDDisplay *display = screen->getDisplayDevice();
// Paint LOCKED into the framebuffer WITHOUT committing. We commit
// exactly once at the bottom — after any overlay has been composed
// on top — so the panel never visibly transitions from "just LOCKED"
// exactly once at the bottom - after any overlay has been composed
// on top - so the panel never visibly transitions from "just LOCKED"
// to "LOCKED + overlay" mid-frame. Committing twice per cycle was
// the source of the H13 flicker.
drawLockdownLockScreenIntoBuffer(display);
@@ -663,7 +663,7 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver)
// 16-50 ms before the next ui->update() lands. Painting the
// LOCKED frame now ensures the only thing the operator (or
// someone over their shoulder) can see on wake is the redacted
// view. Gated on lockdown — non-lockdown builds keep the
// view. Gated on lockdown - non-lockdown builds keep the
// previous frame as a UX cue that the display is just dimmed.
// dispdev is dereferenced unguarded throughout this file (incl.
// displayOff() just below), so no null check here.
@@ -793,7 +793,7 @@ void Screen::setup()
// M20: e-ink panels physically retain the last-rendered image without
// power, so a power-cycled lockdown handheld would keep showing
// operator-identifying content (position, messages, node info) until
// the firmware's first natural refresh — which on e-ink can be seconds
// the firmware's first natural refresh - which on e-ink can be seconds
// into boot. Force a full refresh to the LOCKED frame here, immediately
// after the display is initialised and before any other rendering, so
// the persistent pixels are wiped to the redacted view before an
@@ -1035,7 +1035,7 @@ int32_t Screen::runOnce()
bool suppressRegionOnboard = false;
#ifdef MESHTASTIC_LOCKDOWN
// While lockdown is active and storage is still locked, config.lora.region
// is a deliberate UNSET placeholder — the real region lives in encrypted
// is a deliberate UNSET placeholder - the real region lives in encrypted
// storage and is restored on unlock (see NodeDB's locked-boot path). Don't
// pop the region picker over the lock screen: it would trap input, and the
// operator can't set a region until they unlock anyway.
@@ -1473,7 +1473,7 @@ void Screen::setFrames(FrameFocus focus)
break;
case FOCUS_PRESERVE:
// No more adjustment — force stay on same index
// No more adjustment - force stay on same index
if (previousFrameCount > fsi.frameCount) {
ui->switchToFrame(originalPosition - 1);
} else if (previousFrameCount < fsi.frameCount) {
@@ -1828,7 +1828,7 @@ void Screen::handleOnPress()
void Screen::logFrameChange(const char *reason, uint8_t targetIdx)
{
// Reverse-map an index to a stable name string keyed off FramePositions
// field names — so the pytest harness can assert `name=nodelist_nodes`
// field names - so the pytest harness can assert `name=nodelist_nodes`
// without caring about how the positions were ordered this boot.
const auto &p = framesetInfo.positions;
const char *name = "unknown";
+1 -1
View File
@@ -693,7 +693,7 @@ class Screen : public concurrency::OSThread
// so the chatty log doesn't ship in release builds. Enabled via
// build_testing_profile(enable_ui_log=True) in mcp-server/userprefs.py.
// Member function (not free) because FramesetInfo is a private nested
// type — only methods of Screen can reach it.
// type - only methods of Screen can reach it.
void logFrameChange(const char *reason, uint8_t targetIdx);
#endif
+3 -3
View File
@@ -536,7 +536,7 @@ class LGFX : public lgfx::LGFX_Device
cfg.memory_width = 240;
cfg.memory_height = 320;
cfg.offset_x = 0;
cfg.offset_y = 0; // No vertical shift needed — panel is top-aligned
cfg.offset_y = 0; // No vertical shift needed - panel is top-aligned
cfg.offset_rotation = 2; // Rotate 180° to correct upside-down layout
#else
cfg.memory_width = TFT_WIDTH; // Maximum width supported by the driver IC
@@ -1144,8 +1144,8 @@ static LGFX *tft = nullptr;
#elif defined(VARIANT_DISPLAY_DRIVER)
// Board-specific framebuffer backends (class LGFX) can livee in the
// variant files — variant_display.h (declaration) and
// variant_display.cpp (bodies) — so this shared
// variant files - variant_display.h (declaration) and
// variant_display.cpp (bodies) - so this shared
// file isn't inflated for a single board. It exposes the same surface TFTDisplay
// drives, so the generic `tft = new LGFX;` in connect() works.
#include "variant_display.h"
+3 -3
View File
@@ -482,9 +482,9 @@ void drawLoRaFocused(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x,
// Weighting for nonlinear segments
float milestone1 = 25;
float milestone2 = 40;
float weight1 = 0.45; // Weight for 0–25%
float weight2 = 0.35; // Weight for 25–40%
float weight3 = 0.20; // Weight for 40–100%
float weight1 = 0.45; // Weight for 0-25%
float weight2 = 0.35; // Weight for 25-40%
float weight3 = 0.20; // Weight for 40-100%
float totalWeight = weight1 + weight2 + weight3;
int seg1 = chutil_bar_max_fill * (weight1 / totalWeight);
+3 -3
View File
@@ -182,7 +182,7 @@ static void applyLoraRegion(meshtastic_Config_LoRaConfig_RegionCode region, bool
// Reconcile the preset with the explicitly chosen region: a preset locked to another
// region would leave config.lora invalid until applyModemConfig() repairs it with
// error/critical-error side effects — or, for the swappable EU trio, the clamp would
// error/critical-error side effects - or, for the swappable EU trio, the clamp would
// flip the region right back. The user picked the region, so the preset follows it.
const RegionInfo *newRegion = getRegion(region);
if (config.lora.use_preset && !newRegion->supportsPreset(config.lora.modem_preset)) {
@@ -282,7 +282,7 @@ void menuHandler::LoraRegionPicker(uint32_t duration)
// Guard: without a reboot, reconfigure() applies the region directly, so reject
// regions this node can't use up front: unrecognized codes, licensed-only regions,
// and radio hardware mismatches (2.4 GHz vs sub-GHz) — the same checks the admin
// and radio hardware mismatches (2.4 GHz vs sub-GHz) - the same checks the admin
// set-config path applies, but side-effect-free: ignoring a menu selection should
// not record a critical error or notify clients. getRadio() used to catch hardware
// mismatches post-reboot only.
@@ -468,7 +468,7 @@ static constexpr int MAX_PRESET_OPTIONS = 16;
static BannerOverlayOptions buildRegionPresetBanner()
{
// Static storage reused each call — safe because the banner is shown immediately after.
// Static storage reused each call - safe because the banner is shown immediately after.
static const char *optionsArray[MAX_PRESET_OPTIONS];
static int optionsEnumArray[MAX_PRESET_OPTIONS];
static char presetLabelBuf[MAX_PRESET_OPTIONS][12]; // scratch space for name copies
+1 -1
View File
@@ -261,7 +261,7 @@ void NotificationRenderer::drawBannercallback(OLEDDisplay *display, OLEDDisplayU
case notificationTypeEnum::text_banner:
case notificationTypeEnum::selection_picker:
case notificationTypeEnum::pairing_pin:
// pairing_pin is rendered the same as text_banner — it's just a
// pairing_pin is rendered the same as text_banner - it's just a
// text banner. The split type exists only so the lockdown UI
// short-circuit in Screen.cpp can recognise the BLE pair-PIN
// banner as the one safe banner to composite over the LOCKED
+2 -2
View File
@@ -134,7 +134,7 @@ class SafeFastEPD : public FASTEPD
void ED047TC1::begin(SPIClass *spi, uint8_t pin_dc, uint8_t pin_cs, uint8_t pin_busy, uint8_t pin_rst)
{
// Parallel display — SPI parameters are not used
// Parallel display - SPI parameters are not used
(void)spi;
(void)pin_dc;
(void)pin_cs;
@@ -159,7 +159,7 @@ void ED047TC1::begin(SPIClass *spi, uint8_t pin_dc, uint8_t pin_cs, uint8_t pin_
// so variant touch-control polling can read the key reliably.
epaper->ioPinMode(10, INPUT);
#else
#error "ED047TC1 driver: unsupported variant — define T5_S3_EPAPER_PRO_V1 or T5_S3_EPAPER_PRO_V2"
#error "ED047TC1 driver: unsupported variant - define T5_S3_EPAPER_PRO_V1 or T5_S3_EPAPER_PRO_V2"
#endif
if (initRc != BBEP_SUCCESS) {
+4 -4
View File
@@ -10,7 +10,7 @@
Unlike the other NicheGraphics EInk drivers, this one drives a parallel e-paper
panel via the FastEPD library. SPI parameters passed to begin() are ignored.
The ED047TC1 panel has an inactive pixel border on all four edges (~4–8 physical
The ED047TC1 panel has an inactive pixel border on all four edges (~4-8 physical
pixels). DISPLAY_WIDTH / DISPLAY_HEIGHT expose a reduced "safe area" to InkHUD so
that content is never drawn into this dead zone. The update() method copies the
InkHUD frame buffer into the centre of the larger physical 960×540 buffer, using
@@ -18,9 +18,9 @@
V_OFFSET_TOP and V_OFFSET_BOTTOM (vertical, pixel rows) to position it.
Changing these constants shifts content inward from each physical edge:
H_OFFSET_BYTES = 2 → 16px left margin, 16px right margin (960 – 16 – 16 = 928)
H_OFFSET_BYTES = 2 → 16px left margin, 16px right margin (960 - 16 - 16 = 928)
V_OFFSET_TOP = 16 → 16px top margin
V_OFFSET_BOTTOM = 16 → 16px bottom margin (540 – 16 – 16 = 508)
V_OFFSET_BOTTOM = 16 → 16px bottom margin (540 - 16 - 16 = 508)
*/
@@ -74,7 +74,7 @@ class ED047TC1 : public EInk
public:
ED047TC1() : EInk(DISPLAY_WIDTH, DISPLAY_HEIGHT, supported) {}
// EInk interface — SPI params are not used for this parallel display
// EInk interface - SPI params are not used for this parallel display
void begin(SPIClass *spi, uint8_t pin_dc, uint8_t pin_cs, uint8_t pin_busy, uint8_t pin_rst = 0xFF) override;
void update(uint8_t *imageData, UpdateTypes type) override;
@@ -275,11 +275,11 @@ void InkHUD::MapApplet::drawMapTileBackground(int zoom)
void InkHUD::MapApplet::onRender(bool full)
{
// Map center is always the node centroid — tiles are background only.
// Map center is always the node centroid - tiles are background only.
getMapCenter(&latCenter, &lngCenter);
calculateAllMarkers();
// Show placeholder only if we have no position at all — no tiles, no own node
// Show placeholder only if we have no position at all - no tiles, no own node
if (!enoughMarkers() && !centerIsOurNode) {
printAt(X(0.5), Y(0.5) - (getFont().lineHeight() / 2), "Node positions", CENTER, MIDDLE);
printAt(X(0.5), Y(0.5) + (getFont().lineHeight() / 2), "will appear here", CENTER, MIDDLE);
@@ -324,7 +324,7 @@ void InkHUD::MapApplet::onRender(bool full)
float chosenMetersToPx = metersToPxFit; // fallback: fit-scale (may downsample)
if (s_zoomLocked && s_lockedZoom >= 0) {
// Use locked zoom at native 1:1 scale — never zoom out for new nodes
// Use locked zoom at native 1:1 scale - never zoom out for new nodes
chosenZoom = s_lockedZoom;
float mpp = (2.0f * M_PI * R / (256.0f * (float)(1 << chosenZoom))) * cosf(latRad);
chosenMetersToPx = 1.0f / mpp;
@@ -338,7 +338,7 @@ void InkHUD::MapApplet::onRender(bool full)
float mpp = (2.0f * M_PI * R / (256.0f * (float)(1 << zooms[zi]))) * cosf(latRad);
float nativeMetersToPx = 1.0f / mpp;
if (nativeMetersToPx <= metersToPxFit) {
// This zoom at native scale shows all nodes — use it (highest detail that fits)
// This zoom at native scale shows all nodes - use it (highest detail that fits)
chosenZoom = zooms[zi];
chosenMetersToPx = nativeMetersToPx;
break;
@@ -628,7 +628,7 @@ void InkHUD::MapApplet::getMapCenter(float *lat, float *lng)
// When zoom is locked, keep center exactly on own node / zero-hop centroid.
// Skip bounding-box shift so new distant nodes don't move the zoomed view.
if (s_zoomLocked) {
// Own node has no position — re-center on zero-hop centroid instead.
// Own node has no position - re-center on zero-hop centroid instead.
if (!centerIsOurNode) {
uint32_t count = 0;
float xAvg = 0, yAvg = 0, zAvg = 0;
@@ -878,7 +878,7 @@ void InkHUD::MapApplet::calculateAllMarkers()
if (node->num == nodeDB->getNodeNum())
continue;
// Skip nodes with unknown hop count — partial info, not useful to plot
// Skip nodes with unknown hop count - partial info, not useful to plot
if (!node->has_hops_away)
continue;
@@ -35,7 +35,7 @@ class MapApplet : public Applet
MapApplet *asMapApplet() override { return this; } // Identify as MapApplet without RTTI
// Zoom lock — shared across all MapApplet instances (static)
// Zoom lock - shared across all MapApplet instances (static)
static constexpr int ZOOM_MAX_NO_TILES = 16;
void zoomIn();
@@ -260,7 +260,7 @@ int32_t InkHUD::MenuApplet::runOnce()
return OSThread::disable();
}
// Storage for the dynamically-built region preset list — populated in showPage(NODE_CONFIG_PRESET)
// Storage for the dynamically-built region preset list - populated in showPage(NODE_CONFIG_PRESET)
static constexpr uint8_t MAX_REGION_PRESETS = 16;
static meshtastic_Config_LoRaConfig_ModemPreset regionPresets[MAX_REGION_PRESETS];
static uint8_t regionPresetCount = 0;
@@ -1069,7 +1069,7 @@ void InkHUD::MenuApplet::showPage(MenuPage page)
items.push_back(MenuItem("Send", MenuPage::SEND));
// Map zoom controls — only when viewing a map applet
// Map zoom controls - only when viewing a map applet
{
MapApplet *mapApplet = borrowedTileOwner ? borrowedTileOwner->asMapApplet() : nullptr;
if (mapApplet) {
@@ -190,7 +190,7 @@ ProcessMessage InkHUD::ThreadedMessageApplet::handleReceived(const meshtastic_Me
if (mp.to != NODENUM_BROADCAST)
return ProcessMessage::CONTINUE;
// Store in the global messageStore — this handles sender, timestamp, channel, text, and ack status
// Store in the global messageStore - this handles sender, timestamp, channel, text, and ack status
messageStore.addFromPacket(mp);
// If this was an incoming message, suggest that our applet becomes foreground, if permitted
+3 -3
View File
@@ -260,7 +260,7 @@ If you need to create several similar applets, it might make sense to create a r
##### Map Tiles
Map tiles are stored in `MapTile.h` (`src/graphics/niche/InkHUD/Applets/Bases/Map/MapTile.h`). The file committed to the repository contains no tile data by default — the map applets work without tiles, falling back to the original marker-only display.
Map tiles are stored in `MapTile.h` (`src/graphics/niche/InkHUD/Applets/Bases/Map/MapTile.h`). The file committed to the repository contains no tile data by default - the map applets work without tiles, falling back to the original marker-only display.
Tiles are 256×256 pixels, 1-bit (column-major bit packing), compressed per tile with LZ4 to keep flash usage low.
@@ -489,8 +489,8 @@ We keep this separate latest-message cache for this purpose, because:
Broadcasts and DMs take different paths into `messageStore`:
- **Broadcasts** — `ThreadedMessageApplet::handleReceived()` calls `messageStore.addFromPacket()`. `Events::onReceiveTextMessage()` then updates `latestMessage.broadcast` separately for fast access by `AllMessageApplet` and `NotificationApplet`.
- **DMs** — `ThreadedMessageApplet` skips DMs entirely. `Events::onReceiveTextMessage()` calls `messageStore.addFromPacket()` directly and stores the result in `latestMessage.dm`.
- **Broadcasts** - `ThreadedMessageApplet::handleReceived()` calls `messageStore.addFromPacket()`. `Events::onReceiveTextMessage()` then updates `latestMessage.broadcast` separately for fast access by `AllMessageApplet` and `NotificationApplet`.
- **DMs** - `ThreadedMessageApplet` skips DMs entirely. `Events::onReceiveTextMessage()` calls `messageStore.addFromPacket()` directly and stores the result in `latestMessage.dm`.
#### Saving / Loading