mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-28 07:03:00 +08:00
feat(label): added animation style property to apply it to circular scrolling animation of label widget (#3128)
* feat(label): added animation style property to apply it to circular scrolling animation of label widget Added an animation style property to be used as animation template for different use cases in different widgets. This commit implements using this property to set the start and repeat delay of the circular scrolling animation of the label widget. Closes #3097 * fix(label): changed animation style property's var_type to `const lv_anim_t *` * example(label): added example showing how to customize circular scrolling animation * chore(label): ran code-format.py and added missing function prototype to lv_example_widgets.h
This commit is contained in:
parent
e25fa427d1
commit
340d45cfa9
@ -253,7 +253,7 @@ Set the point from which the background's gradient color should start. 0 means t
|
||||
</ul>
|
||||
|
||||
### bg_grad
|
||||
Set the gradient definition. The pointed instance must exist while the object is alive. NULL to disable. It wraps `BG_GRAD_COLOR`, `BG_GRAD_DIR`, `BG_MAIN_STOP` and `BG_GRAD_STOP` into one descriptor and allows craeting gradients with more colors too.
|
||||
Set the gradient definition. The pointed instance must exist while the object is alive. NULL to disable. It wraps `BG_GRAD_COLOR`, `BG_GRAD_DIR`, `BG_MAIN_STOP` and `BG_GRAD_STOP` into one descriptor and allows creating gradients with more colors too.
|
||||
<ul>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `NULL`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
@ -708,6 +708,15 @@ The intensity of mixing of color filter.
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Ext. draw</strong> No</li>
|
||||
</ul>
|
||||
|
||||
### anim
|
||||
The animation template for the object's animation. Should be a pointer to `lv_anim_t`. The animation parameters are widget specific, e.g. animation time could be the E.g. blink time of the cursor on the text area or scroll time of a roller. See the widgets' documentation to learn more.
|
||||
<ul>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> `NULL`</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Layout</strong> No</li>
|
||||
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Ext. draw</strong> No</li>
|
||||
</ul>
|
||||
|
||||
### anim_time
|
||||
The animation time in milliseconds. Its meaning is widget specific. E.g. blink time of the cursor on the text area or scroll time of a roller. See the widgets' documentation to learn more.
|
||||
<ul>
|
||||
|
@ -58,6 +58,10 @@ The whole mechanism (click and select the text as you drag your finger/mouse) is
|
||||
### Very long texts
|
||||
LVGL can efficiently handle very long (e.g. > 40k characters) labels by saving some extra data (~12 bytes) to speed up drawing. To enable this feature, set `LV_LABEL_LONG_TXT_HINT 1` in `lv_conf.h`.
|
||||
|
||||
### Custom scrolling animations
|
||||
Some aspects of the scrolling animations in long modes `LV_LABEL_LONG_SCROLL` and `LV_LABEL_LONG_SCROLL_CIRCULAR` can be customized by setting the animation property of a style, using `lv_style_set_anim()`.
|
||||
Currently, only the start and repeat delay of the circular scrolling animation can be customized. If you need to customize another aspect of the scrolling animation, feel free to open an [issue on Github](https://github.com/lvgl/lvgl/issues) to request the feature.
|
||||
|
||||
### Symbols
|
||||
The labels can display symbols alongside letters (or on their own). Read the [Font](/overview/font) section to learn more about the symbols.
|
||||
|
||||
|
@ -23,3 +23,9 @@ Draw label with gradient color
|
||||
.. lv_example:: widgets/label/lv_example_label_4
|
||||
:language: c
|
||||
|
||||
Customize circular scrolling animation
|
||||
""""""""""""""""""""""""""""""""""""
|
||||
|
||||
.. lv_example:: widgets/label/lv_example_label_5
|
||||
:language: c
|
||||
|
||||
|
30
examples/widgets/label/lv_example_label_5.c
Normal file
30
examples/widgets/label/lv_example_label_5.c
Normal file
@ -0,0 +1,30 @@
|
||||
#include "../../lv_examples.h"
|
||||
#if LV_USE_LABEL && LV_BUILD_EXAMPLES
|
||||
|
||||
/**
|
||||
* Show customizing the circular scrolling animation of a label with `LV_LABEL_LONG_SCROLL_CIRCULAR`
|
||||
* long mode.
|
||||
*/
|
||||
void lv_example_label_5(void)
|
||||
{
|
||||
static lv_anim_t animation_template;
|
||||
static lv_style_t label_style;
|
||||
|
||||
lv_anim_init(&animation_template);
|
||||
lv_anim_set_delay(&animation_template, 1000); /*Wait 1 second to start the first scroll*/
|
||||
lv_anim_set_repeat_delay(&animation_template,
|
||||
3000); /*Repeat the scroll 3 seconds after the label scrolls back to the initial position*/
|
||||
|
||||
/*Initialize the label style with the animation template*/
|
||||
lv_style_init(&label_style);
|
||||
lv_style_set_anim(&label_style, &animation_template);
|
||||
|
||||
lv_obj_t * label1 = lv_label_create(lv_scr_act());
|
||||
lv_label_set_long_mode(label1, LV_LABEL_LONG_SCROLL_CIRCULAR); /*Circular scroll*/
|
||||
lv_obj_set_width(label1, 150);
|
||||
lv_label_set_text(label1, "It is a circularly scrolling text. ");
|
||||
lv_obj_align(label1, LV_ALIGN_CENTER, 0, 40);
|
||||
lv_obj_add_style(label1, &label_style, LV_STATE_DEFAULT); /*Add the style to the label*/
|
||||
}
|
||||
|
||||
#endif
|
10
examples/widgets/label/lv_example_label_5.py
Normal file
10
examples/widgets/label/lv_example_label_5.py
Normal file
@ -0,0 +1,10 @@
|
||||
#
|
||||
# Show customizing the circular scrolling animation of a label with `LV_LABEL_LONG_SCROLL_CIRCULAR` long mode.
|
||||
#
|
||||
|
||||
label1 = lv.label(lv.scr_act())
|
||||
label1.set_long_mode(lv.label.LONG.SCROLL_CIRCULAR) # Circular scroll
|
||||
label1.set_width(150)
|
||||
label1.set_text("It is a circularly scrolling text. ")
|
||||
label1.align(lv.ALIGN.CENTER, 0, 40)
|
||||
|
@ -82,6 +82,7 @@ void lv_example_label_1(void);
|
||||
void lv_example_label_2(void);
|
||||
void lv_example_label_3(void);
|
||||
void lv_example_label_4(void);
|
||||
void lv_example_label_5(void);
|
||||
|
||||
void lv_example_led_1(void);
|
||||
|
||||
|
@ -344,6 +344,10 @@ props = [
|
||||
'style_type': 'num', 'var_type': 'lv_opa_t' , 'default':'`LV_OPA_TRANSP`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "The intensity of mixing of color filter."},
|
||||
|
||||
{'name': 'ANIM',
|
||||
'style_type': 'ptr', 'var_type': 'const lv_anim_t *', 'default':'`NULL`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "The animation template for the object's animation. Should be a pointer to `lv_anim_t`. The animation parameters are widget specific, e.g. animation time could be the E.g. blink time of the cursor on the text area or scroll time of a roller. See the widgets' documentation to learn more."},
|
||||
|
||||
{'name': 'ANIM_TIME',
|
||||
'style_type': 'num', 'var_type': 'uint32_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "The animation time in milliseconds. Its meaning is widget specific. E.g. blink time of the cursor on the text area or scroll time of a roller. See the widgets' documentation to learn more."},
|
||||
|
@ -681,6 +681,14 @@ void lv_obj_set_style_color_filter_opa(struct _lv_obj_t * obj, lv_opa_t value, l
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_COLOR_FILTER_OPA, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_anim(struct _lv_obj_t * obj, const lv_anim_t * value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.ptr = value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_ANIM, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_anim_time(struct _lv_obj_t * obj, uint32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
|
@ -509,6 +509,12 @@ static inline lv_opa_t lv_obj_get_style_color_filter_opa(const struct _lv_obj_t
|
||||
return (lv_opa_t)v.num;
|
||||
}
|
||||
|
||||
static inline const lv_anim_t * lv_obj_get_style_anim(const struct _lv_obj_t * obj, uint32_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ANIM);
|
||||
return (const lv_anim_t *)v.ptr;
|
||||
}
|
||||
|
||||
static inline uint32_t lv_obj_get_style_anim_time(const struct _lv_obj_t * obj, uint32_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ANIM_TIME);
|
||||
@ -631,6 +637,7 @@ void lv_obj_set_style_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selec
|
||||
void lv_obj_set_style_color_filter_dsc(struct _lv_obj_t * obj, const lv_color_filter_dsc_t * value,
|
||||
lv_style_selector_t selector);
|
||||
void lv_obj_set_style_color_filter_opa(struct _lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_anim(struct _lv_obj_t * obj, const lv_anim_t * value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_anim_time(struct _lv_obj_t * obj, uint32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_anim_speed(struct _lv_obj_t * obj, uint32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_transition(struct _lv_obj_t * obj, const lv_style_transition_dsc_t * value,
|
||||
|
@ -261,12 +261,13 @@ typedef enum {
|
||||
LV_STYLE_OPA = 98 | LV_STYLE_PROP_INHERIT,
|
||||
LV_STYLE_COLOR_FILTER_DSC = 99,
|
||||
LV_STYLE_COLOR_FILTER_OPA = 100,
|
||||
LV_STYLE_ANIM_TIME = 101,
|
||||
LV_STYLE_ANIM_SPEED = 102,
|
||||
LV_STYLE_TRANSITION = 103,
|
||||
LV_STYLE_BLEND_MODE = 104,
|
||||
LV_STYLE_LAYOUT = 105 | LV_STYLE_PROP_LAYOUT_REFR,
|
||||
LV_STYLE_BASE_DIR = 106 | LV_STYLE_PROP_INHERIT | LV_STYLE_PROP_LAYOUT_REFR,
|
||||
LV_STYLE_ANIM = 101,
|
||||
LV_STYLE_ANIM_TIME = 102,
|
||||
LV_STYLE_ANIM_SPEED = 103,
|
||||
LV_STYLE_TRANSITION = 104,
|
||||
LV_STYLE_BLEND_MODE = 105,
|
||||
LV_STYLE_LAYOUT = 106 | LV_STYLE_PROP_LAYOUT_REFR,
|
||||
LV_STYLE_BASE_DIR = 107 | LV_STYLE_PROP_INHERIT | LV_STYLE_PROP_LAYOUT_REFR,
|
||||
|
||||
_LV_STYLE_LAST_BUILT_IN_PROP = 111,
|
||||
|
||||
|
@ -680,6 +680,14 @@ void lv_style_set_color_filter_opa(lv_style_t * style, lv_opa_t value)
|
||||
lv_style_set_prop(style, LV_STYLE_COLOR_FILTER_OPA, v);
|
||||
}
|
||||
|
||||
void lv_style_set_anim(lv_style_t * style, const lv_anim_t * value)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.ptr = value
|
||||
};
|
||||
lv_style_set_prop(style, LV_STYLE_ANIM, v);
|
||||
}
|
||||
|
||||
void lv_style_set_anim_time(lv_style_t * style, uint32_t value)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
|
@ -83,6 +83,7 @@ void lv_style_set_clip_corner(lv_style_t * style, bool value);
|
||||
void lv_style_set_opa(lv_style_t * style, lv_opa_t value);
|
||||
void lv_style_set_color_filter_dsc(lv_style_t * style, const lv_color_filter_dsc_t * value);
|
||||
void lv_style_set_color_filter_opa(lv_style_t * style, lv_opa_t value);
|
||||
void lv_style_set_anim(lv_style_t * style, const lv_anim_t * value);
|
||||
void lv_style_set_anim_time(lv_style_t * style, uint32_t value);
|
||||
void lv_style_set_anim_speed(lv_style_t * style, uint32_t value);
|
||||
void lv_style_set_transition(lv_style_t * style, const lv_style_transition_dsc_t * value);
|
||||
@ -515,6 +516,11 @@ void lv_style_set_base_dir(lv_style_t * style, lv_base_dir_t value);
|
||||
.prop = LV_STYLE_COLOR_FILTER_OPA, .value = { .num = (int32_t)val } \
|
||||
}
|
||||
|
||||
#define LV_STYLE_CONST_ANIM(val) \
|
||||
{ \
|
||||
.prop = LV_STYLE_ANIM, .value = { .ptr = val } \
|
||||
}
|
||||
|
||||
#define LV_STYLE_CONST_ANIM_TIME(val) \
|
||||
{ \
|
||||
.prop = LV_STYLE_ANIM_TIME, .value = { .num = (int32_t)val } \
|
||||
|
@ -1021,6 +1021,7 @@ static void lv_label_refr_text(lv_obj_t * obj)
|
||||
}
|
||||
/*In roll inf. mode keep the size but start offset animations*/
|
||||
else if(label->long_mode == LV_LABEL_LONG_SCROLL_CIRCULAR) {
|
||||
const lv_anim_t * anim_template = lv_obj_get_style_anim(obj, LV_PART_MAIN);
|
||||
uint16_t anim_speed = lv_obj_get_style_anim_speed(obj, LV_PART_MAIN);
|
||||
if(anim_speed == 0) anim_speed = LV_LABEL_DEF_SCROLL_SPEED;
|
||||
lv_anim_t a;
|
||||
@ -1055,8 +1056,14 @@ static void lv_label_refr_text(lv_obj_t * obj)
|
||||
|
||||
lv_anim_t * anim_cur = lv_anim_get(obj, set_ofs_x_anim);
|
||||
int32_t act_time = anim_cur ? anim_cur->act_time : 0;
|
||||
if(act_time < a.time) {
|
||||
a.act_time = act_time; /*To keep the old position*/
|
||||
|
||||
/*If a template animation exists, consider it's start delay and repeat delay*/
|
||||
if(anim_template) {
|
||||
a.act_time = anim_template->act_time;
|
||||
a.repeat_delay = anim_template->repeat_delay;
|
||||
}
|
||||
else if(act_time < a.time) {
|
||||
a.act_time = act_time; /*To keep the old position when the label text is updated mid-scrolling*/
|
||||
a.early_apply = 0;
|
||||
}
|
||||
|
||||
@ -1076,8 +1083,14 @@ static void lv_label_refr_text(lv_obj_t * obj)
|
||||
|
||||
lv_anim_t * anim_cur = lv_anim_get(obj, set_ofs_y_anim);
|
||||
int32_t act_time = anim_cur ? anim_cur->act_time : 0;
|
||||
if(act_time < a.time) {
|
||||
a.act_time = act_time; /*To keep the old position*/
|
||||
|
||||
/*If a template animation exists, consider it's start delay and repeat delay*/
|
||||
if(anim_template) {
|
||||
a.act_time = anim_template->act_time;
|
||||
a.repeat_delay = anim_template->repeat_delay;
|
||||
}
|
||||
else if(act_time < a.time) {
|
||||
a.act_time = act_time; /*To keep the old position when the label text is updated mid-scrolling*/
|
||||
a.early_apply = 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user