Can anyone offer some suggestions on how to implement a grid menu similar to the one on the Apple Watch

Can anyone offer some suggestions on how to implement a grid menu similar to the one on the Apple Watch

Please send an image as a reference to be sure we are thinking about the same thing :slight_smile:


@kisvegabor * Pictures have been sent

It seems like a simple flex layout with wrapping, and center main direction. To make it really look like this you need to set the size of the icons carefully.

For example the weather icon is much smaller than the clock icon in the middle. I don’t have an Apple watch but if I recall correctly as menu is being scrolled the icons in the center are always larger. If you need this feature too, you need some extra work, as something like this is not supported out of the box.

I need to drag the menu in any direction to scroll, but lvgl V8.1 only supports vertical and horizontal scrolling

It’s possible but you definitely need som custom work. E.g. you can handle dragging manually as shown here and zoom the images manually.


  • This is the current effect and can only be dragged in one direction
  • Can you give an example code on how to handle scrolling manually?

I would propose to think placement and size based on fibonacci sequence

You can take a look at this example: Base object (lv_obj) — LVGL documentation

Instead of repositioning an object you can use the lv_obj_scroll_by(obj, dx, dy, anim_en) function.

I can tell you that the size is percentage based. The center icon is 100 x 100 in size. the ring around the center icon is exactly 90% of the center icon size, so it’s 90 x 90. the top and bottom icons are exactly 80% of the center icons size so they are 80 x 80. the next size down is the second to outside ring and those are exactly 70% or 70 x 70. the smallest are 20%.

It’s going to be a pretty simple mathematical equation that is used to determine what the % should be based on the proximity to the center of the display. there is going to be another simple equation used to control the position based on the proximity to the center. The positioning equation is going to take into account the screen ratio which is why you have the icon at the top and bottom being 80% in size and seeming like they are not really in a correct position for their size.

All position measurements are going to be to the center of the icon/button as well. I am sure there is a “snap” feature so when the touch is released it will snap an icon to the center and position all visible icons accordingly.

I am sure it would not be too difficult to come up with some math that would position and size the icons properly based on their proximity to the center.

I didn’t think that LVGL does horizontal and vertical scrolling at the same time… Maybe it does?

If you want it to run nice and smooth you are going to have to handle collecting the touch data and repositioning everything and telling LVGL to refresh the display in a loop in your code. You don’t want to use lv_task_handler to do this as I think it would not capture touch data and update the display fast enough because of the timer values. 30 milliseconds is a long time to wait between display updates for a control like this.

I could hammer something out in Python and someone could port it to C code if needed…

Thank you for your reply.I will try it directly.

Nice ~ I could try to port it to C code.

I put some time into it last night and I have been figuring out the sizes and the locations. I have come up with a good way of positioning and sizing the icons. I might have a test version working this evening. we will see what happens.