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 the
lv_arc_set_bg_angles(arc, start_angle, end_angle) functions or
lv_arc_set_bg_start/end_angle(arc, angle)
.
Zero degrees is at the middle right (3 o'clock) of the object and the degrees are increasing in clockwise direction. The angles should be in the [0;360] range.
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:
LV_ARC_MODE_NORMAL
The indicator arc is drawn from the minimum value to the current.LV_ARC_MODE_REVERSE
The indicator arc is drawn counter-clockwise from the maximum value to the current.LV_ARC_MODE_SYMMETRICAL
The indicator arc is drawn from the middle point to the current value.
The mode can be set by lv_arc_set_mode(arc, LV_ARC_MODE_...) and
used only if the angle is set by lv_arc_set_value()
or the arc is
adjusted by finger.
Change rate
If the arc is pressed the current value will set with a limited speed according to the set change rate. The change rate is defined in degree/second unit and can be set with lv_arc_set_change_rage(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), will only be visible if
LV_PART_KNOB
is visible
Setting the indicator manually
It's also possible to set the angles of the indicator arc directly with
lv_arc_set_angles(arc, start_angle, end_angle) function or
lv_arc_set_start/end_angle(arc, start_angle)
. In this case the set
"value" and "mode" are ignored.
In other words, the angle and value settings are independent. You should exclusively use one or the other. Mixing the two might result in unintended behavior.
To make the arc non-adjustable, remove the style of the knob and make the object non-clickable:
lv_obj_remove_style(arc, NULL, LV_PART_KNOB);
lv_obj_remove_flag(arc, LV_OBJ_FLAG_CLICKABLE);
Advanced hit test
If the LV_OBJ_FLAG_ADV_HITTEST
flag is enabled the arc can be
clicked through in the middle. Clicks are recognized only on the ring of
the background arc. lv_obj_set_ext_click_size()
makes the sensitive
area larger inside and outside with the given number of pixels.
Place another object to the knob
Another object 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, obj_to_align, radius_offset).
Similarly lv_arc_rotate_obj_to_angle(arc, obj_to_rotate, radius_offset) can be used to rotate the object to the current value of the arc.
It's a typical use case to call these functions in the VALUE_CHANGED
event of the arc.
Events
LV_EVENT_VALUE_CHANGED
sent when the arc is pressed/dragged to set a new value.LV_EVENT_DRAW_PART_BEGIN
andLV_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 the arcradius
: radius of the arcarc_dsc
LV_ARC_DRAW_PART_FOREGROUND
The foreground arc.part
:LV_PART_INDICATOR
p1
: center of the arcradius
: radius of the arcarc_dsc
LV_ARC_DRAW_PART_KNOB The knob
part
:LV_PART_KNOB
draw_area
: the area of the knobrect_dsc
:
See the events of the Base object too.
Learn more about Events.
Keys
LV_KEY_RIGHT/UP
Increases the value by one.LV_KEY_LEFT/DOWN
Decreases the value by one.
Learn more about Keys.
Example
Simple Arc
C code
View on GitHub#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
C code
View on GitHub#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