fix(ui): standardize context menu cycling + PopupMenu height clamping

PopupMenu:
- _cap now uses max_by_height as a hard ceiling (never draw outside screen).
  Previously max(_visible, max_by_height) let callers exceed the screen on
  OLED 64px. Now: OLED→4 items, landscape e-ink→10, portrait e-ink→22.

QuickMsgScreen:
- Contact context menu: Notif and Melody cycle with LEFT/RIGHT in-place;
  ENTER closes without re-cycling.
- Channel context menu: Notif, Melody and Fav same pattern.

RingtoneEditorScreen:
- Migrated from bespoke menu to PopupMenu (same pattern as everywhere else).
- Duration (1/4…1/32) and BPM (60…180) are now single rows that cycle with
  LEFT/RIGHT; separate BPM+/BPM- rows removed.
- Fixed _menu_dur_label buffer too small for "Duration: 1/16" (14→16 bytes).

NearbyScreen:
- Removed redundant "Back" item from context menu (Cancel key navigates back).

TrailScreen:
- Grid toggle responds to LEFT/RIGHT in addition to ENTER.
- Export labels: "Export GPX (live/saved)" → "Export (live/saved)" to fit PM_BW.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-05-29 00:25:02 +02:00
co-authored by Claude Sonnet 4.6
parent 5caac0b693
commit db8c52ea9a
5 changed files with 178 additions and 165 deletions
+4 -3
View File
@@ -35,11 +35,12 @@ struct PopupMenu {
}
int render(DisplayDriver& display) {
// On tall displays (portrait e-ink) show as many items as fit;
// on small displays fall back to the caller-specified _visible cap.
// Hard ceiling: never show more items than physically fit on screen.
// On tall displays (portrait e-ink) this expands beyond _visible;
// on small displays (OLED 64px) it clamps below _visible.
int max_by_height = (display.height() - PM_BY - 12) / PM_ITEM_H;
if (max_by_height < 1) max_by_height = 1;
_cap = (max_by_height > _visible) ? max_by_height : _visible;
_cap = max_by_height;
int vis = (_count < _cap) ? _count : _cap;
int bh = 12 + vis * PM_ITEM_H;