Arc (lv_arc)

Overview

The Arc consists of a background and a foreground arc. The foreground (indicator) can be touch-adjusted.

Parts and Styles

  • LV_PART_MAIN Draws a background using the typical background style properties and an arc using the arc style properties. The arc's size and position will respect the padding style properties.

  • LV_PART_INDICATOR Draws another arc using the arc style properties. Its padding values are interpreted relative to the background arc.

  • LV_PART_KNOB Draws a handle on the end of the indicator using all background properties and padding values. With zero padding the knob size is the same as the indicator's width. Larger padding makes it larger, smaller padding makes it smaller.

Usage

Value and range

A new value can be set using lv_arc_set_value(arc, new_value). The value is interpreted in a range (minimum and maximum values) which can be modified with lv_arc_set_range(arc, min, max). The default range is 0..100.

The indicator arc is drawn on the main part's arc. This if the value is set to maximum the indicator arc will cover the entire "background" arc. To set the start and end angle of the background arc use any of these functions:

Zero degrees is at the middle right (3 o'clock) of the Widget and the degrees increasing in the clockwise direction. The angle values should be in the range [0..360].

Rotation

An offset to the 0-degree position can be added with lv_arc_set_rotation(arc, deg).

Mode

The arc can be one of the following modes:

The mode can be set by lv_arc_set_mode(arc, LV_ARC_MODE_...) and has no effect until angle is set by lv_arc_set_value() or value of the arc is changed by pointer input (finger, mouse, etc.).

Change rate

When the arc's value is changed by pointer input (finger, mouse, etc.), the rate of its change is limited according to its change rate. Change rate is defined in degrees/second units and can be set with lv_arc_set_change_rate(arc, rate)

Knob offset

Changing the knob offset allows the location of the knob to be moved relative to the end of the arc. The knob offset can be set by lv_arc_set_knob_offset(arc, offset_angle), and will only be visible if LV_PART_KNOB is visible.

Setting indicator programmatically

It is possible to set indicator angle directly with any of these functions:

When used, "value" and "mode" are ignored.

In other words, the angle and value settings are independent. You should exclusively use one or the other of the two methods. Mixing the two could result in unintended behavior.

To make the arc non-adjustable by external input, remove the style of the knob and make the Widget non-clickable:

lv_obj_remove_style(arc, NULL, LV_PART_KNOB);
lv_obj_remove_flag(arc, LV_OBJ_FLAG_CLICKABLE);

Interactive area

By default LV_OBJ_FLAG_ADV_HITTEST is disabled which means the arc's whole area is interactive. As usual lv_obj_set_ext_click_area() can be used to increase the area that will respond to pointer input (touch, mouse, etc.) outside the arc by a specified number of pixels.

If LV_OBJ_FLAG_ADV_HITTEST is enabled the arc will be sensitive only in the range between start and end background angles and on the arc itself (not inside the arc). In this case ext_click_area makes the sensitive area ticker both inward and outward. Additionally, a tolerance of lv_dpx(50) pixels is applied to each angle, extending the hit-test range along the arc's length.

Place another Widget on the knob

Another Widget can be positioned according to the current position of the arc in order to follow the arc's current value (angle). To do this use lv_arc_align_obj_to_angle(arc, widget_to_align, radius_offset).

Similarly lv_arc_rotate_obj_to_angle(arc, widget_to_rotate, radius_offset) can be used to rotate the Widget to the current value of the arc.

A typical use case is to call these functions in the VALUE_CHANGED event of the arc.

Events

  • LV_EVENT_VALUE_CHANGED sent when arc is pressed/dragged to a new value.

  • LV_EVENT_DRAW_PART_BEGIN and LV_EVENT_DRAW_PART_END are sent with the following types:

    • LV_ARC_DRAW_PART_BACKGROUND The background arc.

      • part: LV_PART_MAIN

      • p1: center of arc

      • radius: radius of arc

      • arc_dsc

    • LV_ARC_DRAW_PART_FOREGROUND The foreground arc.

    • LV_ARC_DRAW_PART_KNOB The knob

      • part: LV_PART_KNOB

      • draw_area: the area of the knob

      • rect_dsc:

Further Reading

Learn more about Base-Widget Events emitted by all Widgets.

Learn more about Events.

Keys

  • LV_KEY_RIGHT/UP Increases value by one.

  • LV_KEY_LEFT/DOWN Decreases value by one.

Further Reading

Learn more about Keys.

Example

Simple Arc

A simple example to demonstrate the use of an arc.
#include "../../lv_examples.h"

#if LV_USE_ARC && LV_BUILD_EXAMPLES

static void value_changed_event_cb(lv_event_t * e);

void lv_example_arc_1(void)
{
    lv_obj_t * label = lv_label_create(lv_screen_active());

    /*Create an Arc*/
    lv_obj_t * arc = lv_arc_create(lv_screen_active());
    lv_obj_set_size(arc, 150, 150);
    lv_arc_set_rotation(arc, 135);
    lv_arc_set_bg_angles(arc, 0, 270);
    lv_arc_set_value(arc, 10);
    lv_obj_center(arc);
    lv_obj_add_event_cb(arc, value_changed_event_cb, LV_EVENT_VALUE_CHANGED, label);

    /*Manually update the label for the first time*/
    lv_obj_send_event(arc, LV_EVENT_VALUE_CHANGED, NULL);
}

static void value_changed_event_cb(lv_event_t * e)
{
    lv_obj_t * arc = lv_event_get_target(e);
    lv_obj_t * label = lv_event_get_user_data(e);

    lv_label_set_text_fmt(label, "%" LV_PRId32 "%%", lv_arc_get_value(arc));

    /*Rotate the label to the current position of the arc*/
    lv_arc_rotate_obj_to_angle(arc, label, 25);
}

#endif

Loader with Arc

#include "../../lv_examples.h"

#if LV_USE_ARC && LV_BUILD_EXAMPLES

static void set_angle(void * obj, int32_t v)
{
    lv_arc_set_value(obj, v);
}

/**
 * Create an arc which acts as a loader.
 */
void lv_example_arc_2(void)
{
    /*Create an Arc*/
    lv_obj_t * arc = lv_arc_create(lv_screen_active());
    lv_arc_set_rotation(arc, 270);
    lv_arc_set_bg_angles(arc, 0, 360);
    lv_obj_remove_style(arc, NULL, LV_PART_KNOB);   /*Be sure the knob is not displayed*/
    lv_obj_remove_flag(arc, LV_OBJ_FLAG_CLICKABLE);  /*To not allow adjusting by click*/
    lv_obj_center(arc);

    lv_anim_t a;
    lv_anim_init(&a);
    lv_anim_set_var(&a, arc);
    lv_anim_set_exec_cb(&a, set_angle);
    lv_anim_set_duration(&a, 1000);
    lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);    /*Just for the demo*/
    lv_anim_set_repeat_delay(&a, 500);
    lv_anim_set_values(&a, 0, 100);
    lv_anim_start(&a);

}

#endif

API

lv_arc.h

lv_observer.h

lv_types.h