mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-08-02 10:16:11 +00:00
feat(ui): popup menu auto-expands on tall displays (portrait e-ink)
On a 250px-tall portrait e-ink panel the menu previously showed only 3-4 items and required scrolling. render() now computes the maximum items that fit from display.height() and uses that instead of the hardcoded caller hint whenever the screen is taller. handleInput() uses the same _cap value so scroll tracking stays in sync. OLED (64px): fits 4 items — unchanged behaviour. Portrait e-ink (250px): fits up to 22 items (capped at PM_MAX_ITEMS=16), no scroll needed for typical context menus (4-6 items). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
54367327f7
commit
95795a663c
@@ -16,17 +16,18 @@ struct PopupMenu {
|
|||||||
int _count;
|
int _count;
|
||||||
int _sel;
|
int _sel;
|
||||||
int _scroll;
|
int _scroll;
|
||||||
int _visible;
|
int _visible; // caller hint (min visible items)
|
||||||
|
int _cap; // actual visible cap, updated each render()
|
||||||
bool active;
|
bool active;
|
||||||
const char* _title;
|
const char* _title;
|
||||||
|
|
||||||
enum Result { NONE, SELECTED, CANCELLED };
|
enum Result { NONE, SELECTED, CANCELLED };
|
||||||
|
|
||||||
PopupMenu() : _count(0), _sel(0), _scroll(0), _visible(3), active(false), _title(nullptr) {}
|
PopupMenu() : _count(0), _sel(0), _scroll(0), _visible(3), _cap(3), active(false), _title(nullptr) {}
|
||||||
|
|
||||||
void begin(const char* title, int visible = 3) {
|
void begin(const char* title, int visible = 3) {
|
||||||
_count = 0; _sel = 0; _scroll = 0;
|
_count = 0; _sel = 0; _scroll = 0;
|
||||||
_visible = visible; active = true; _title = title;
|
_visible = visible; _cap = visible; active = true; _title = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addItem(const char* item) {
|
void addItem(const char* item) {
|
||||||
@@ -34,7 +35,12 @@ struct PopupMenu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int render(DisplayDriver& display) {
|
int render(DisplayDriver& display) {
|
||||||
int vis = (_count < _visible) ? _count : _visible;
|
// On tall displays (portrait e-ink) show as many items as fit;
|
||||||
|
// on small displays fall back to the caller-specified _visible cap.
|
||||||
|
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;
|
||||||
|
int vis = (_count < _cap) ? _count : _cap;
|
||||||
int bh = 12 + vis * PM_ITEM_H;
|
int bh = 12 + vis * PM_ITEM_H;
|
||||||
|
|
||||||
display.setColor(DisplayDriver::DARK);
|
display.setColor(DisplayDriver::DARK);
|
||||||
@@ -71,14 +77,14 @@ struct PopupMenu {
|
|||||||
if (_count == 0) { active = false; return CANCELLED; }
|
if (_count == 0) { active = false; return CANCELLED; }
|
||||||
if (c == KEY_UP) {
|
if (c == KEY_UP) {
|
||||||
_sel = (_sel > 0) ? _sel - 1 : _count - 1;
|
_sel = (_sel > 0) ? _sel - 1 : _count - 1;
|
||||||
if (_sel < _scroll) _scroll = _sel;
|
if (_sel < _scroll) _scroll = _sel;
|
||||||
else if (_sel == _count - 1 && _count > _visible) _scroll = _count - _visible;
|
else if (_sel == _count - 1 && _count > _cap) _scroll = _count - _cap;
|
||||||
return NONE;
|
return NONE;
|
||||||
}
|
}
|
||||||
if (c == KEY_DOWN) {
|
if (c == KEY_DOWN) {
|
||||||
_sel = (_sel < _count - 1) ? _sel + 1 : 0;
|
_sel = (_sel < _count - 1) ? _sel + 1 : 0;
|
||||||
if (_sel >= _scroll + _visible) _scroll = _sel - _visible + 1;
|
if (_sel >= _scroll + _cap) _scroll = _sel - _cap + 1;
|
||||||
else if (_sel == 0) _scroll = 0;
|
else if (_sel == 0) _scroll = 0;
|
||||||
return NONE;
|
return NONE;
|
||||||
}
|
}
|
||||||
if (c == KEY_ENTER) { active = false; return SELECTED; }
|
if (c == KEY_ENTER) { active = false; return SELECTED; }
|
||||||
|
|||||||
Reference in New Issue
Block a user