Skip to content

Main menu: add a grid layout next to the icon carousel - #2749

Open
vnxdtzip wants to merge 1 commit into
BruceDevices:devfrom
vnxdtzip:ui/main-menu-grid-layout
Open

Main menu: add a grid layout next to the icon carousel#2749
vnxdtzip wants to merge 1 commit into
BruceDevices:devfrom
vnxdtzip:ui/main-menu-grid-layout

Conversation

@vnxdtzip

@vnxdtzip vnxdtzip commented Aug 3, 2026

Copy link
Copy Markdown

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.conf as mainMenuStyle. 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.

Board Result
Cardputer 240x135 4 columns, 2 visible rows of 4 (15 modules over 4 rows, scrolls)
CYD 320x240 5 x 3, all 15 modules visible at once
Portrait 135x240 2 x 5 of 8 rows

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 new drawIconInBox() helper on MenuItemInterface, 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 scale and 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

  1. Flash and go to Config > Display & UI > Menu Layout, pick Grid.
  2. Back out to the main menu: every module is now a cell, selected one highlighted with the primary color.
  3. Up/Down move a whole row, Prev/Next move one cell, Enter opens the module.
  4. On a Cardputer, scrolling past the second row brings the remaining modules in and the right-hand indicator moves.
  5. Switch back to Carousel and confirm the original behavior is unchanged.
  6. Worth checking with a theme that ships icon images, and with modules hidden via 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-cardputer and by compiling CYD-2432S028 to exercise the HAS_TOUCH paths 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

Main menu can now be shown as a grid of all modules instead of the sliding icon carousel. Pick it under Config > Display & UI > Menu Layout; the carousel remains the default.

Further Comments

The icon size is driven by a single constant, ICON_SCALE_REFERENCE in include/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.

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.
@bmorcelli

Copy link
Copy Markdown
Member

Intereting..

what happens if a theme is set?

@bmorcelli

Copy link
Copy Markdown
Member

Attatch pictures, please 🥺

@vnxdtzip

vnxdtzip commented Aug 3, 2026

Copy link
Copy Markdown
Author

Intereting..

what happens if a theme is set?

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.

@vnxdtzip

vnxdtzip commented Aug 3, 2026

Copy link
Copy Markdown
Author

Attatch pictures, please 🥺

WhatsApp.Video.2026-08-03.at.12.21.06.mp4
WhatsApp Image 2026-08-03 at 12 21 02

@bmorcelli

Copy link
Copy Markdown
Member

awesome!

@Doominator1

Copy link
Copy Markdown
Contributor

That looks good, have you tested the navigation works on devices with rotary encoders such as the t-embed?

@IncursioHack

IncursioHack commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

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.

@IncursioHack

Copy link
Copy Markdown
Collaborator

@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

@IncursioHack

Copy link
Copy Markdown
Collaborator

I removed the FM menu, and the grid reassembled and worked normally.IMG_20260804_091039.jpg

@IncursioHack

Copy link
Copy Markdown
Collaborator

I only encountered visual bugs in the Navigator; it is likely something that needs to be adjusted there. It is usable, but as shown in the screenshots, the Navigator struggles to render so many elements on the screen.
WebUI > Navigator:

image image image

@bmorcelli

Copy link
Copy Markdown
Member

I only encountered visual bugs in the Navigator; it is likely something that needs to be adjusted there. It is usable, but as shown in the screenshots, the Navigator struggles to render so many elements on the screen.
WebUI > Navigator:

image image image

This is limitation from the Tft_logger, too many artifacts to keep on memory, so it drops the older ones..

Not something to be handled by this PR, imho

@vnxdtzip

vnxdtzip commented Aug 4, 2026

Copy link
Copy Markdown
Author

I only encountered visual bugs in the Navigator; it is likely something that needs to be adjusted there. It is usable, but as shown in the screenshots, the Navigator struggles to render so many elements on the screen.
WebUI > Navigator:
image
image
image

This is limitation from the Tft_logger, too many artifacts to keep on memory, so it drops the older ones..

Not something to be handled by this PR, imho

Agreed, and thanks for the call. Leaving it out of this PR.

@vnxdtzip

vnxdtzip commented Aug 4, 2026

Copy link
Copy Markdown
Author

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.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants