mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-22 23:37:43 +08:00
feat(xml): add color percentage support to animations (#9209)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
3d3bcd5dd3
commit
5472a77c6e
@@ -61,7 +61,7 @@ that you can reference later.
|
||||
Inside a ``<timeline>``, you add ``<animation>``\ s to describe each step.
|
||||
Supported properties of ``<animation>`` are:
|
||||
|
||||
- ``prop``: Style property to animate. All integer style properties are supported (colors are not).
|
||||
- ``prop``: Style property to animate. All integer, percentage and color style properties are supported.
|
||||
- ``selector``: Style selector, e.g. ``knob|pressed``. Default: ``main|default``.
|
||||
- ``target``: Name of the UI element to animate. ``self`` refers to the root element of the Component (the ``<view>``).
|
||||
- ``start``: Start value (integer only).
|
||||
|
||||
@@ -23,8 +23,6 @@ void lv_example_xml_2(void)
|
||||
lv_obj_t * obj = (lv_obj_t *) lv_xml_create(lv_screen_active(), "view", NULL);
|
||||
lv_obj_set_pos(obj, 10, 10);
|
||||
|
||||
lv_xml_component_unregister("my_button");
|
||||
|
||||
const char * slider_attrs[] = {
|
||||
"x", "200",
|
||||
"y", "-15",
|
||||
|
||||
@@ -1,15 +1,42 @@
|
||||
<!-- A simple button that defines a show up animation for itself -->
|
||||
<component>
|
||||
<consts>
|
||||
<px name="size" value="100"/>
|
||||
<color name="orange" value="0xffa020"/>
|
||||
</consts>
|
||||
<api>
|
||||
<prop name="label_text" type="string" default="Click me" />
|
||||
</api>
|
||||
|
||||
<api>
|
||||
<prop name="btn_text" type="string"/>
|
||||
</api>
|
||||
<styles>
|
||||
<style
|
||||
name="style_base"
|
||||
bg_opa="100%"
|
||||
bg_color="0x000044"
|
||||
width="content"
|
||||
height="content"
|
||||
radius="10"
|
||||
pad_hor="30"
|
||||
pad_ver="20"
|
||||
text_color="0xfff"
|
||||
/>
|
||||
|
||||
<view extends="lv_button" width="#size">
|
||||
<my_h3 text="$btn_text" align="center" color="#orange"/>
|
||||
</view>
|
||||
<style name="style_pressed" recolor="0xfff" recolor_opa="20%" />
|
||||
</styles>
|
||||
|
||||
<animations>
|
||||
<!-- Fade in and move up
|
||||
This animation can be played later in an event by a parent component or screen -->
|
||||
<timeline name="show_up">
|
||||
<animation target="self" prop="opa" start="0" end="255" duration="200" early_apply="true" />
|
||||
<animation target="self" prop="bg_color" start="0xff0000" end="0x00ff00" duration="2000" early_apply="true" />
|
||||
<animation target="self" prop="translate_y" start="20" end="0" duration="200" early_apply="true" />
|
||||
<animation target="self" prop="width" start="0%" end="50%" duration="200" early_apply="true" />
|
||||
</timeline>
|
||||
</animations>
|
||||
|
||||
<view extends="lv_button">
|
||||
<remove_style_all />
|
||||
<style name="style_base" />
|
||||
<style name="style_pressed" selector="pressed" />
|
||||
|
||||
<lv_label text="$label_text" align="center" />
|
||||
<play_timeline_event target="self" timeline="show_up" />
|
||||
</view>
|
||||
</component>
|
||||
|
||||
|
||||
@@ -9,26 +9,11 @@
|
||||
<style name="btn_pr_style" bg_opa="255"/>
|
||||
</styles>
|
||||
|
||||
<view extends="lv_obj" name="main" width="280" height="content" style_bg_color="#light_blue"
|
||||
style_layout="grid" style_grid_column_dsc_array="100 fr(1)" style_grid_row_dsc_array="50 200"
|
||||
|
||||
>
|
||||
<lv_obj style_grid_cell_column_pos="0" style_grid_cell_column_span="1" style_grid_cell_x_align="stretch"
|
||||
style_grid_cell_row_pos="0" style_grid_cell_row_span="1" style_grid_cell_y_align="stretch">
|
||||
<lv_label text="0/0"/>
|
||||
</lv_obj>
|
||||
<lv_obj style_grid_cell_column_pos="0" style_grid_cell_column_span="1" style_grid_cell_x_align="stretch"
|
||||
style_grid_cell_row_pos="1" style_grid_cell_row_span="1" style_grid_cell_y_align="stretch">
|
||||
<lv_label text="0/1"/>
|
||||
</lv_obj>
|
||||
<lv_obj style_grid_cell_column_pos="1" style_grid_cell_column_span="1" style_grid_cell_x_align="stretch"
|
||||
style_grid_cell_row_pos="0" style_grid_cell_row_span="1" style_grid_cell_y_align="stretch">
|
||||
<lv_label text="1/0"/>
|
||||
</lv_obj>
|
||||
<lv_obj style_grid_cell_column_pos="1" style_grid_cell_column_span="1" style_grid_cell_x_align="stretch"
|
||||
style_grid_cell_row_pos="1" style_grid_cell_row_span="1" style_grid_cell_y_align="stretch">
|
||||
<lv_label text="1/1"/>
|
||||
</lv_obj>
|
||||
|
||||
<view width="280" height="content"
|
||||
flex_flow="column">
|
||||
<my_button/>
|
||||
<my_button/>
|
||||
<my_button/>
|
||||
<my_button/>
|
||||
</view>
|
||||
</component>
|
||||
+73
-39
@@ -32,9 +32,19 @@
|
||||
**********************/
|
||||
typedef enum {
|
||||
STYLE_PROP_TYPE_INT,
|
||||
STYLE_PROP_TYPE_OPA,
|
||||
STYLE_PROP_TYPE_COLOR,
|
||||
STYLE_PROP_TYPE_UNKNOWN
|
||||
} style_prop_anim_type_t;
|
||||
|
||||
typedef struct {
|
||||
lv_style_selector_t selector;
|
||||
lv_style_prop_t prop;
|
||||
style_prop_anim_type_t prop_type;
|
||||
lv_color_t color_start;
|
||||
lv_color_t color_end;
|
||||
} anim_data_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
@@ -46,8 +56,7 @@ static void process_image_element(lv_xml_parser_state_t * state, const char * ty
|
||||
static void process_prop_element(lv_xml_parser_state_t * state, const char ** attrs);
|
||||
static char * extract_view_content(const char * xml_definition);
|
||||
static style_prop_anim_type_t style_prop_anim_get_type(lv_style_prop_t prop);
|
||||
static int32_t anim_value_to_int(lv_style_prop_t prop_type, const char * value_str);
|
||||
static void int_anim_exec_cb(lv_anim_t * a, int32_t v);
|
||||
static void anim_exec_cb(lv_anim_t * a, int32_t v);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@@ -318,6 +327,7 @@ lv_result_t lv_xml_component_unregister(const char * name)
|
||||
lv_xml_anim_timeline_child_t * child;
|
||||
LV_LL_READ(&timeline->anims_ll, child) {
|
||||
if(child->is_anim) {
|
||||
lv_free(child->data.anim.user_data); /*It was anim_data_t*/
|
||||
lv_free(child->data.anim.var); /*It was the name of the target object*/
|
||||
}
|
||||
else {
|
||||
@@ -592,10 +602,6 @@ static void process_animation_element(lv_xml_parser_state_t * state, const char
|
||||
|
||||
lv_style_selector_t selector = lv_xml_style_selector_text_to_enum(selector_str);
|
||||
|
||||
int32_t start = anim_value_to_int(prop_type, start_str);
|
||||
int32_t end = anim_value_to_int(prop_type, end_str);
|
||||
|
||||
|
||||
if(target_str[0] == '#') target_str = lv_xml_get_const(&state->scope, &target_str[1]);
|
||||
if(prop_str[0] == '#') prop_str = lv_xml_get_const(&state->scope, &prop_str[1]);
|
||||
if(start_str[0] == '#') start_str = lv_xml_get_const(&state->scope, &start_str[1]);
|
||||
@@ -615,20 +621,41 @@ static void process_animation_element(lv_xml_parser_state_t * state, const char
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t selector_and_prop = ((prop & 0xff) << 24) | selector;
|
||||
|
||||
lv_xml_anim_timeline_child_t * child = lv_ll_ins_tail(&at->anims_ll);
|
||||
child->is_anim = true;
|
||||
lv_anim_t * a = &child->data.anim;
|
||||
|
||||
anim_data_t * anim_data = lv_malloc(sizeof(anim_data_t));
|
||||
anim_data->selector = selector;
|
||||
anim_data->prop = prop;
|
||||
anim_data->prop_type = prop_type;
|
||||
|
||||
lv_anim_init(a);
|
||||
|
||||
if(prop_type == STYLE_PROP_TYPE_INT) {
|
||||
int32_t start = lv_xml_to_size(start_str);
|
||||
int32_t end = lv_xml_to_size(end_str);
|
||||
lv_anim_set_values(a, start, end);
|
||||
lv_anim_set_custom_exec_cb(a, anim_exec_cb);
|
||||
}
|
||||
else if(prop_type == STYLE_PROP_TYPE_OPA) {
|
||||
int32_t start = lv_xml_to_opa(start_str);
|
||||
int32_t end = lv_xml_to_opa(end_str);
|
||||
lv_anim_set_values(a, start, end);
|
||||
lv_anim_set_custom_exec_cb(a, anim_exec_cb);
|
||||
}
|
||||
else if(prop_type == STYLE_PROP_TYPE_COLOR) {
|
||||
anim_data->color_start = lv_xml_to_color(start_str);
|
||||
anim_data->color_end = lv_xml_to_color(end_str);
|
||||
lv_anim_set_values(a, 0, 255);
|
||||
lv_anim_set_custom_exec_cb(a, anim_exec_cb);
|
||||
}
|
||||
|
||||
lv_anim_set_var(a, lv_strdup(target_str));
|
||||
lv_anim_set_values(a, start, end);
|
||||
lv_anim_set_custom_exec_cb(a, int_anim_exec_cb);
|
||||
lv_anim_set_duration(a, lv_xml_atoi(duration_str));
|
||||
lv_anim_set_delay(a, lv_xml_atoi(delay_str));
|
||||
lv_anim_set_early_apply(a, lv_xml_to_bool(early_apply_str));
|
||||
lv_anim_set_user_data(a, (void *)((uintptr_t)selector_and_prop));
|
||||
lv_anim_set_user_data(a, anim_data);
|
||||
}
|
||||
|
||||
static void process_include_timeline_element(lv_xml_parser_state_t * state, const char ** attrs)
|
||||
@@ -989,34 +1016,22 @@ static style_prop_anim_type_t style_prop_anim_get_type(lv_style_prop_t prop)
|
||||
case LV_STYLE_MARGIN_RIGHT:
|
||||
case LV_STYLE_MARGIN_TOP:
|
||||
case LV_STYLE_MARGIN_BOTTOM:
|
||||
case LV_STYLE_BG_OPA:
|
||||
case LV_STYLE_BG_MAIN_STOP:
|
||||
case LV_STYLE_BG_GRAD_STOP:
|
||||
case LV_STYLE_BG_IMAGE_RECOLOR_OPA:
|
||||
case LV_STYLE_BORDER_WIDTH:
|
||||
case LV_STYLE_BORDER_OPA:
|
||||
case LV_STYLE_OUTLINE_WIDTH:
|
||||
case LV_STYLE_OUTLINE_OPA:
|
||||
case LV_STYLE_OUTLINE_PAD:
|
||||
case LV_STYLE_SHADOW_WIDTH:
|
||||
case LV_STYLE_SHADOW_OFFSET_X:
|
||||
case LV_STYLE_SHADOW_OFFSET_Y:
|
||||
case LV_STYLE_SHADOW_SPREAD:
|
||||
case LV_STYLE_SHADOW_OPA:
|
||||
case LV_STYLE_TEXT_OPA:
|
||||
case LV_STYLE_TEXT_LETTER_SPACE:
|
||||
case LV_STYLE_TEXT_LINE_SPACE:
|
||||
case LV_STYLE_IMAGE_OPA:
|
||||
case LV_STYLE_IMAGE_RECOLOR_OPA:
|
||||
case LV_STYLE_LINE_OPA:
|
||||
case LV_STYLE_LINE_WIDTH:
|
||||
case LV_STYLE_LINE_DASH_WIDTH:
|
||||
case LV_STYLE_LINE_DASH_GAP:
|
||||
case LV_STYLE_ARC_OPA:
|
||||
case LV_STYLE_ARC_WIDTH:
|
||||
case LV_STYLE_OPA:
|
||||
case LV_STYLE_OPA_LAYERED:
|
||||
case LV_STYLE_COLOR_FILTER_OPA:
|
||||
case LV_STYLE_TRANSFORM_WIDTH:
|
||||
case LV_STYLE_TRANSFORM_HEIGHT:
|
||||
case LV_STYLE_TRANSLATE_X:
|
||||
@@ -1027,33 +1042,52 @@ static style_prop_anim_type_t style_prop_anim_get_type(lv_style_prop_t prop)
|
||||
case LV_STYLE_TRANSFORM_ROTATION:
|
||||
case LV_STYLE_TRANSFORM_PIVOT_X:
|
||||
case LV_STYLE_TRANSFORM_PIVOT_Y:
|
||||
case LV_STYLE_RECOLOR_OPA:
|
||||
return STYLE_PROP_TYPE_INT;
|
||||
|
||||
case LV_STYLE_ARC_OPA:
|
||||
case LV_STYLE_OPA:
|
||||
case LV_STYLE_OPA_LAYERED:
|
||||
case LV_STYLE_BG_OPA:
|
||||
case LV_STYLE_BORDER_OPA:
|
||||
case LV_STYLE_OUTLINE_OPA:
|
||||
case LV_STYLE_SHADOW_OPA:
|
||||
case LV_STYLE_TEXT_OPA:
|
||||
case LV_STYLE_LINE_OPA:
|
||||
case LV_STYLE_IMAGE_OPA:
|
||||
case LV_STYLE_IMAGE_RECOLOR_OPA:
|
||||
case LV_STYLE_RECOLOR_OPA:
|
||||
case LV_STYLE_COLOR_FILTER_OPA:
|
||||
return STYLE_PROP_TYPE_OPA;
|
||||
|
||||
case LV_STYLE_ARC_COLOR:
|
||||
case LV_STYLE_BG_COLOR:
|
||||
case LV_STYLE_BG_GRAD_COLOR:
|
||||
case LV_STYLE_BORDER_COLOR:
|
||||
case LV_STYLE_LINE_COLOR:
|
||||
case LV_STYLE_OUTLINE_COLOR:
|
||||
case LV_STYLE_SHADOW_COLOR:
|
||||
case LV_STYLE_TEXT_COLOR:
|
||||
return STYLE_PROP_TYPE_COLOR;
|
||||
|
||||
default:
|
||||
return STYLE_PROP_TYPE_UNKNOWN;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t anim_value_to_int(lv_style_prop_t prop_type, const char * value_str)
|
||||
static void anim_exec_cb(lv_anim_t * a, int32_t v)
|
||||
{
|
||||
if(prop_type == STYLE_PROP_TYPE_INT) {
|
||||
return lv_xml_atoi(value_str);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void int_anim_exec_cb(lv_anim_t * a, int32_t v)
|
||||
{
|
||||
uint32_t data = (lv_uintptr_t)lv_anim_get_user_data(a);
|
||||
lv_style_prop_t prop = data >> 24;
|
||||
lv_style_selector_t selector = data & 0x00ffffff;
|
||||
anim_data_t * anim_data = lv_anim_get_user_data(a);
|
||||
|
||||
lv_style_value_t style_value;
|
||||
style_value.num = v;
|
||||
lv_obj_set_local_style_prop(a->var, prop, style_value, selector);
|
||||
if(anim_data->prop_type == STYLE_PROP_TYPE_INT || anim_data->prop_type == STYLE_PROP_TYPE_OPA) {
|
||||
style_value.num = v;
|
||||
}
|
||||
else if(anim_data->prop_type == STYLE_PROP_TYPE_COLOR) {
|
||||
style_value.color = lv_color_mix(anim_data->color_end, anim_data->color_start, v);
|
||||
}
|
||||
|
||||
lv_obj_set_local_style_prop(a->var, anim_data->prop, style_value, anim_data->selector);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user