• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lexus2k / lcdgfx / 25076006873

28 Apr 2026 08:28PM UTC coverage: 55.065% (-0.06%) from 55.122%
25076006873

push

github

lexus2k
fix(gui): eliminate flicker and scroll artifacts in menu/checkbox/slider/spinbox

Menu / CheckboxMenu:
- show() now uses a smart incremental redraw: full draw on first call
  or when the visible window scrolls, otherwise only the affected
  rows (old + new selection, plus any items whose checkbox bit
  changed) are repainted.
- Replaced the scroll-arrow band with a slim right-edge scrollbar
  (page-aligned, safe on 1bpp displays).
- drawMenuItem clears its own row interior before drawing, so old
  longer labels don't bleed through after scrolling.
- CheckboxMenu: the box itself is no longer inverted on the
  highlighted row; only the text strip flips colors via
  invertColors().
- CheckboxMenu: toggling the selected item now redraws it
  immediately without requiring an up/down move.
- Added invalidate() to force a full redraw; setRect() invalidates.

Slider / Spinbox:
- show() clears the widget's rectangle interior before redrawing,
  so callers no longer need display.clear() between updates.
- Demos updated accordingly: slider_demo uses a padded "Value: %3d "
  print and drops display.clear(); spinbox_demo drops display.clear()
  from up/down handlers.

All 470 unit tests still pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

0 of 2 new or added lines in 2 files covered. (0.0%)

1 existing line in 1 file now uncovered.

1060 of 1925 relevant lines covered (55.06%)

15802.32 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.08
/src/v2/gui/menu.cpp
1
/*
2
    MIT License
3

4
    Copyright (c) 2020,2022, Alexey Dynda
5

6
    Permission is hereby granted, free of charge, to any person obtaining a copy
7
    of this software and associated documentation files (the "Software"), to deal
8
    in the Software without restriction, including without limitation the rights
9
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
    copies of the Software, and to permit persons to whom the Software is
11
    furnished to do so, subject to the following conditions:
12

13
    The above copyright notice and this permission notice shall be included in all
14
    copies or substantial portions of the Software.
15

16
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
    SOFTWARE.
23
*/
24

25
#include "menu.h"
26

27
LcdGfxMenu::LcdGfxMenu(const char **items, uint8_t count, const NanoRect &rect)
14✔
28
{
29
    menu.items = items;
14✔
30
    menu.count = count;
14✔
31
    menu.selection = 0;
14✔
32
    menu.oldSelection = 0;
14✔
33
    menu.scrollPosition = 0;
14✔
34
    menu.top = rect.p1.y;
14✔
35
    menu.left = rect.p1.x;
14✔
36
    menu.width = rect.p2.x ? rect.width() : 0;
14✔
37
    menu.height = rect.p2.y ? rect.height() : 0;
14✔
38
}
14✔
39

40
void LcdGfxMenu::down()
17✔
41
{
42
    if ( menu.selection < menu.count - 1 )
17✔
43
    {
44
        menu.selection++;
16✔
45
    }
46
    else
47
    {
48
        menu.selection = 0;
1✔
49
    }
50
}
17✔
51

52
void LcdGfxMenu::up()
4✔
53
{
54
    if ( menu.selection > 0 )
4✔
55
    {
56
        menu.selection--;
3✔
57
    }
58
    else
59
    {
60
        menu.selection = menu.count - 1;
1✔
61
    }
62
}
4✔
63

64
uint8_t LcdGfxMenu::selection()
19✔
65
{
66
    return menu.selection;
19✔
67
}
68

69
void LcdGfxMenu::setSelection(uint8_t s)
4✔
70
{
71
    if ( s >= menu.count )
4✔
72
    {
73
        menu.selection = menu.count - 1;
1✔
74
    }
75
    else {
76
        menu.selection = s;
3✔
77
    }
78
}
4✔
79

80
void LcdGfxMenu::setRect(const NanoRect &rect)
×
81
{
82
    menu.top = rect.p1.y;
×
83
    menu.left = rect.p1.x;
×
84
    menu.width = rect.p2.x ? rect.width() : 0;
×
85
    menu.height = rect.p2.y ? rect.height() : 0;
×
86
    // Geometry changed: next show() must do a full redraw of the border.
NEW
87
    invalidate();
×
UNCOV
88
}
×
89

90
uint8_t LcdGfxMenu::size()
1✔
91
{
92
    return menu.count;
1✔
93
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc