mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-09-14 15:16:40 +00:00
fix(ui): marquee's hold no longer dominates a barely-overflowing label
User report: a repeater path popup's short "?A1B2C3D4"-style hop tags (often just a couple pixels over the box width) felt stuck rather than scrolling, while longer names (Nodes list) already felt right after the recent marqueeHoldMs() speedup. Root cause: the swing marquee's hold applies uniformly regardless of how much text is actually hidden. When only 1-2 codepoints overflow, the full cycle is hold + a single, barely-there step + hold + step back -- nearly all hold, for almost no new information revealed each side. New marqueeHoldForSkip(skip_cp) scales the hold down (to 1/3 or 1/2) when the computed reveal distance is small; longer overflows keep the full hold, since there's real text worth pausing to read. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -348,6 +348,20 @@ public:
|
|||||||
virtual unsigned long marqueeHoldMs() { return isEink() ? 1200 : 700; }
|
virtual unsigned long marqueeHoldMs() { return isEink() ? 1200 : 700; }
|
||||||
virtual uint8_t marqueeStepChars() { return isEink() ? 3 : 1; }
|
virtual uint8_t marqueeStepChars() { return isEink() ? 3 : 1; }
|
||||||
|
|
||||||
|
// Scales the start/end hold down when only a codepoint or two is actually
|
||||||
|
// hidden -- with a fixed hold, a label that overflows by just that much
|
||||||
|
// (e.g. a short "?A1B2C3D4" hex hop tag squeezed by a couple of pixels)
|
||||||
|
// spends nearly its whole cycle sitting still either side of a single,
|
||||||
|
// barely-there step, which reads as "stuck" rather than "scrolling" for
|
||||||
|
// how little extra text it actually reveals. Longer overflows keep the
|
||||||
|
// full hold, since there's real content worth pausing to read.
|
||||||
|
unsigned long marqueeHoldForSkip(uint16_t skip_cp) {
|
||||||
|
unsigned long full = marqueeHoldMs();
|
||||||
|
if (skip_cp <= 2) return full / 3;
|
||||||
|
if (skip_cp <= 4) return full / 2;
|
||||||
|
return full;
|
||||||
|
}
|
||||||
|
|
||||||
// draw text with ellipsis if it exceeds max_width. Pass selected=true for
|
// draw text with ellipsis if it exceeds max_width. Pass selected=true for
|
||||||
// the row currently highlighted/focused by the user: instead of a static
|
// the row currently highlighted/focused by the user: instead of a static
|
||||||
// ellipsis, an overflowing label then animates a "swing" marquee — holds at
|
// ellipsis, an overflowing label then animates a "swing" marquee — holds at
|
||||||
@@ -417,7 +431,6 @@ public:
|
|||||||
_marquee_max_w = max_width;
|
_marquee_max_w = max_width;
|
||||||
_marquee_skip_cp = 0;
|
_marquee_skip_cp = 0;
|
||||||
_marquee_phase = 0; // hold at start
|
_marquee_phase = 0; // hold at start
|
||||||
_marquee_next_at = now + marqueeHoldMs();
|
|
||||||
|
|
||||||
// Find the codepoint skip at which the remaining suffix's own width
|
// Find the codepoint skip at which the remaining suffix's own width
|
||||||
// already fits max_width — i.e. the fully-scrolled end position.
|
// already fits max_width — i.e. the fully-scrolled end position.
|
||||||
@@ -431,6 +444,7 @@ public:
|
|||||||
if (full_width - removed_w <= max_width) break;
|
if (full_width - removed_w <= max_width) break;
|
||||||
}
|
}
|
||||||
_marquee_max_skip_cp = cp_count;
|
_marquee_max_skip_cp = cp_count;
|
||||||
|
_marquee_next_at = now + marqueeHoldForSkip(cp_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advance the state machine at most once per elapsed step/hold interval.
|
// Advance the state machine at most once per elapsed step/hold interval.
|
||||||
@@ -444,7 +458,7 @@ public:
|
|||||||
if (_marquee_skip_cp >= _marquee_max_skip_cp) {
|
if (_marquee_skip_cp >= _marquee_max_skip_cp) {
|
||||||
_marquee_skip_cp = _marquee_max_skip_cp;
|
_marquee_skip_cp = _marquee_max_skip_cp;
|
||||||
_marquee_phase = 2;
|
_marquee_phase = 2;
|
||||||
_marquee_next_at = now + marqueeHoldMs();
|
_marquee_next_at = now + marqueeHoldForSkip(_marquee_max_skip_cp);
|
||||||
} else {
|
} else {
|
||||||
_marquee_next_at = now + marqueeStepMs();
|
_marquee_next_at = now + marqueeStepMs();
|
||||||
}
|
}
|
||||||
@@ -455,7 +469,7 @@ public:
|
|||||||
if (_marquee_skip_cp <= step) {
|
if (_marquee_skip_cp <= step) {
|
||||||
_marquee_skip_cp = 0;
|
_marquee_skip_cp = 0;
|
||||||
_marquee_phase = 0;
|
_marquee_phase = 0;
|
||||||
_marquee_next_at = now + marqueeHoldMs();
|
_marquee_next_at = now + marqueeHoldForSkip(_marquee_max_skip_cp);
|
||||||
} else {
|
} else {
|
||||||
_marquee_skip_cp -= step;
|
_marquee_skip_cp -= step;
|
||||||
_marquee_next_at = now + marqueeStepMs();
|
_marquee_next_at = now + marqueeStepMs();
|
||||||
|
|||||||
Reference in New Issue
Block a user