Main menu: add a grid layout next to the icon carousel - #2749
Conversation
The main menu only offered the carousel, where reaching a module means stepping sideways through every other one. This adds a second layout that lays all modules out as selectable cells, so any of them is one or two presses away. The choice lives in Config > Display & UI > Menu Layout and is stored in bruce.conf as mainMenuStyle. Carousel stays the default, so existing setups are untouched. The grid sizes itself from the screen: columns from the available width, visible rows from the height, scrolling by rows with a thin indicator when they don't all fit at a readable size. On a Cardputer that lands on 4 columns and 2 visible rows of 4; on a 320x240 board all 15 modules fit at once. Up/Down jump a whole row while Prev/Next keep stepping one cell at a time, and boards without separate Up/Down keys fall back to linear stepping. Rendering reuses each module's existing drawIcon() through a new drawIconInBox() helper, which remaps the icon coordinates and theme colors onto an arbitrary box and restores them afterwards. Only the two cells that changed are repainted on navigation. Files' icon had a hardcoded 10px offset that did not follow the scale and overflowed its box when drawn small; it now scales, with identical output at scale 1.
|
Intereting.. what happens if a theme is set? |
|
Attatch pictures, please 🥺 |
Colors and the border flag work fine, the grid reads the same bruceConfig values. Icon images don't. The grid always renders the vector drawIcon(), never drawIconImg(), so a theme's custom icons show up in the carousel but not in the grid. None of the image helpers (drawImg, drawPNG, drawBmp, showJpeg, showGif) can scale, they only take (x, y, center), so there's no way to fit a full-size icon into a ~36px cell. The label flag is ignored too, labels are always drawn, otherwise the cells would have nothing identifying them. If themed grids are wanted later, a small-variant convention in the theme file (e.g. wifi_small) with vector fallback would be the cheap fix. |
|
awesome! |
|
That looks good, have you tested the navigation works on devices with rotary encoders such as the t-embed? |
|
First of all, I’d like to congratulate you on the PR; it turned out amazing and very elegant—it will definitely be my daily-driver UI. I had posted a previous comment, but due to an oversight on my part, I missed a specific detail; I’m going to test this PR with the CoreS3, which features a touchscreen and a display (2.0" @ 320×240 ILI9342C) with the same dimensions as the CYD. |
|
@vnxdtzip I’ve only run a few tests and still need to check each menu individually, but the tests were promising and worked very well for me. VID_20260804_090417.mp4 |
Thanks for testing it out; I only have a Cardputer Adv, so I can't test it on different screens... this will be my preferred viewing mode too, haha. |









Proposed Changes
The main menu only offers the icon carousel, where reaching a module means stepping sideways through every other one. This adds a second layout that lays all modules out as selectable cells, so any of them is one or two presses away.
The choice lives in Config > Display & UI > Menu Layout and is stored in
bruce.confasmainMenuStyle. Carousel stays the default, so existing setups are untouched and nothing changes unless the user opts in.The grid sizes itself from the screen rather than assuming a resolution: columns come from the available width (minimum 54px cell, enough for a readable label), visible rows from the height (minimum 40px so the vector icons stay legible). When the rows don't all fit it scrolls by row, with a thin indicator on the right.
Navigation: Up/Down jump a whole row preserving the column, Prev/Next keep stepping one cell at a time. Boards without separate Up/Down keys fall back to the existing linear stepping, and touch boards already map those directions through
touchHeatMap, so they work without changes.Rendering reuses each module's existing
drawIcon()through a newdrawIconInBox()helper onMenuItemInterface, which remaps the icon coordinates and theme colors onto an arbitrary box and restores them afterwards. No icon had to be rewritten. Only the two cells that changed are repainted on navigation; a full repaint happens on entry or when the view scrolls.One drive-by fix: Files' icon had a hardcoded 10px offset that did not follow
scaleand overflowed its box when drawn small. It now scales, with identical output at scale 1.Types of Changes
New Feature. Opt-in and additive, no breaking change.
Verification
Config > Display & UI > Menu Layout, pick Grid.Hide Apps(the grid rebuilds its layout from the enabled count).Testing
Not covered by automated tests; the repo has no rendering test harness. Verified by building
m5stack-cardputerand by compilingCYD-2432S028to exercise theHAS_TOUCHpaths and a different resolution.Being upfront about coverage limits: this was validated on a Cardputer. The layout math for other resolutions is derived, not observed on hardware, so a second pair of eyes on a 320x240 and a portrait board would be welcome. Themes that replace icons with images still render the vector icons in grid mode.
Linked Issues
None.
User-Facing Change
Further Comments
The icon size is driven by a single constant,
ICON_SCALE_REFERENCEininclude/MenuItemInterface.h. Lowering it renders every icon larger inside the same cell; the practical ceiling is when the tallest icon starts touching its label. It is currently at 80.