How can i stack 2 arcs with the same center point

What do you want to achieve?

Hey guys,
I’m trying to design some kind of smart watch, I want to have an arc over another arc with different range, but the centers should be aligned.
It’s somewhat similar to lvgl’s example for " Smartwatch GUI for NXP" with the media player screen.
As soon as I add the second arc I cant control the first one, even though their knobs never overlap, how can i fix it

Thanks, Dan

What have you tried so far?

chat gpt suggested i try the “adv hittest” flag but it didnt change much.

I have uploaded a screenshot of the design attempt alongside the flags

Code to reproduce

/*You code here*/

Screenshot and/or video

Environment

  • MCU/MPU/Board: CrowPanel Advance 4.3“ HMI|ESP32-S3 AI-Powered IPS Touch Screen (800x480)
  • LVGL version: 8.3

lv_obj_t* cont1 = lv_obj_create(lv_scr_act());
lv_obj_remove_style_all(cont1);
lv_obj_set_size(cont1, 480, 240);
lv_obj_align(cont1, LV_ALIGN_TOP_MID, 0, 0);
lv_obj_t* arc1 = lv_arc_create(cont1);
lv_obj_set_size(arc1, 480, 480);
lv_arc_set_angles(arc1, 0, 180);
lv_obj_align(arc1, LV_ALIGN_TOP_MID, 0, 0);
lv_obj_t* cont2 = lv_obj_create(lv_scr_act());
lv_obj_remove_style_all(cont2);

lv_obj_set_size(cont2, 480, 240);
lv_obj_align_to(cont2, cont1, LV_ALIGN_OUT_BOTTOM_MID, 0, 0);
lv_obj_t* arc2 = lv_arc_create(cont2);
lv_obj_set_size(arc2, 480, 480);
lv_arc_set_angles(arc2, 0, 180);
lv_arc_set_rotation(arc2, 180);

lv_obj_align(arc2, LV_ALIGN_BOTTOM_MID, 0, 0);

Hi, The easiest way to solve this problem is to place the arcs inside a container where only the active part of the arc widget is visible. This way, the arc won’t detect the area outside the container. I’ve also attached a video to make it clear what I mean. For future reference, if you have questions about SquareLine Studio, I recommend posting them in the SquareLine forum, as they’ll definitely be able to help you there.

arc

Thanks for your replies! ive tried putting each arc in a container and it works much better, still have few spots where the arc is getting stuck (both arcs have different point of getting stuck)

here is the code generated by the studio, what am i missing?

//panel 5 is the gray circle
ui_Panel5 = lv_obj_create(ui_Panel6);
lv_obj_set_width(ui_Panel5, 400);
lv_obj_set_height(ui_Panel5, 400);
lv_obj_set_align(ui_Panel5, LV_ALIGN_CENTER);
lv_obj_clear_flag(ui_Panel5, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_SCROLLABLE); /// Flags
lv_obj_set_style_radius(ui_Panel5, 200, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_bg_color(ui_Panel5, lv_color_hex(0x4C4D4D), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_bg_opa(ui_Panel5, 200, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_border_width(ui_Panel5, 0, LV_PART_MAIN | LV_STATE_DEFAULT);

ui_Container4 = lv_obj_create(ui_Panel5);
lv_obj_remove_style_all(ui_Container4);
lv_obj_set_width(ui_Container4, 450);
lv_obj_set_height(ui_Container4, 200);
lv_obj_set_align(ui_Container4, LV_ALIGN_TOP_MID);
lv_obj_clear_flag(ui_Container4, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_SCROLLABLE); /// Flags

ui_Arc1 = lv_arc_create(ui_Container4);
lv_obj_set_width(ui_Arc1, 380);
lv_obj_set_height(ui_Arc1, 380);
lv_obj_set_align(ui_Arc1, LV_ALIGN_TOP_MID);
lv_obj_add_flag(ui_Arc1, LV_OBJ_FLAG_ADV_HITTEST); /// Flags
lv_arc_set_value(ui_Arc1, 50);
lv_arc_set_bg_angles(ui_Arc1, 10, 170);
lv_arc_set_rotation(ui_Arc1, 180);

ui_Container8 = lv_obj_create(ui_Panel5);
lv_obj_remove_style_all(ui_Container8);
lv_obj_set_width(ui_Container8, 450);
lv_obj_set_height(ui_Container8, 100);
lv_obj_set_align(ui_Container8, LV_ALIGN_BOTTOM_MID);
lv_obj_clear_flag(ui_Container8, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_SCROLLABLE); /// Flags

ui_Arc2 = lv_arc_create(ui_Container8);
lv_obj_set_width(ui_Arc2, 380);
lv_obj_set_height(ui_Arc2, 380);
lv_obj_set_align(ui_Arc2, LV_ALIGN_BOTTOM_MID);
lv_obj_add_flag(ui_Arc2, LV_OBJ_FLAG_ADV_HITTEST); /// Flags
lv_arc_set_value(ui_Arc2, 50);
lv_arc_set_bg_angles(ui_Arc2, 40, 140);

In LVGL specifically, each arc is still treated as a rectangular hit area unless you explicitly change how input is evaluated. So even if your knobs don’t overlap visually, their hitboxes can still interfere with each other.

A few things to check:

First, make sure you’re really isolating interaction. LV_OBJ_FLAG_ADV_HITTEST sometimes isn’t enough on its own depending on version and object hierarchy. You may need to explicitly adjust or override the hit-test callback so each arc only responds when the touch is within its actual arc radius/angle range, not the bounding box.

Second, check the object layering and parent-child relationship. If both arcs share the same parent, LVGL will still run hit-testing in order, and the “topmost” object can steal events even if it doesn’t look like it should.

Third, consider disabling pointer input on the decorative arc entirely (lv_obj_clear_flag(arc, LV_OBJ_FLAG_CLICKABLE)) and manually handling interaction for both arcs in a single controller logic layer. That’s often the cleanest approach for smartwatch-style UIs where multiple visual arcs represent one input system.

Finally, if you’re using an older LVGL version, there were some known quirks with arc gesture handling that were improved in later releases.

What’s likely happening is not the visual overlap itself, but the hit-test region of the second arc interfering with the first one. Even if the knobs don’t overlap visually, LVGL still considers the full object area (or its gesture-sensitive region) when deciding which object receives input.

A few things to try:

  1. Make sure only the knob is interactive

For each arc, explicitly limit interaction to the knob:

lv_obj_clear_flag(arc, LV_OBJ_FLAG_CLICKABLE);
lv_obj_add_flag(arc, LV_OBJ_FLAG_ADV_HITTEST);

Then handle input via the arc’s value change events rather than direct touch capture.

  1. Use separate input groups or disable propagation

If both arcs are in the same input context, touch events can “stick” to the topmost object. You can try:

lv_indev_set_group(indev, NULL);

or ensure each arc doesn’t unintentionally capture gestures.

  1. Check lv_obj_set_ext_click_area

Sometimes extending clickable area (even indirectly via styles or containers) causes hidden overlap:

lv_obj_set_ext_click_area(arc, 0);
4. Layering matters more than expected

Even if arcs don’t visually overlap, the draw order + hit-test order does. Try explicitly controlling z-order:

lv_obj_move_foreground(arc1);
lv_obj_move_background(arc2);

and test reversing them.

  1. Debug tip

Enable input debugging in LVGL (or log lv_indev_get_point) to see which object actually receives the touch — often it’s not the one you expect.

In short: this usually isn’t a rendering issue but a hit-test / input routing problem. Once you isolate interaction to only the knob or decouple input handling per arc, it tends to resolve.