From 16aaa93e7612d642ccee13154c166e37f079952f Mon Sep 17 00:00:00 2001 From: AloyseTech Date: Wed, 14 Nov 2018 17:00:59 +0100 Subject: [PATCH 01/17] Better looking preload animation --- lv_objx/lv_preload.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lv_objx/lv_preload.c b/lv_objx/lv_preload.c index 2d189740c..c531c8e75 100644 --- a/lv_objx/lv_preload.c +++ b/lv_objx/lv_preload.c @@ -92,6 +92,21 @@ lv_obj_t * lv_preload_create(lv_obj_t * par, const lv_obj_t * copy) a.repeat = 1; a.repeat_pause = 0; lv_anim_create(&a); + + lv_anim_t b; + b.var = new_preload; + b.start = ext->arc_length; + b.end = 360; + b.fp = (lv_anim_fp_t)lv_preload_set_arc_length; + b.path = lv_anim_path_ease_in_out; + b.end_cb = NULL; + b.act_time = 0; + b.time = LV_PRELOAD_DEF_SPIN_TIME; + b.playback = 1; + b.playback_pause = 0; + b.repeat = 1; + b.repeat_pause = 100; + lv_anim_create(&b); #endif /*Init the new pre loader pre loader*/ From 624939f6ba6341ef7d0e8169822fcbd418d5dac6 Mon Sep 17 00:00:00 2001 From: AloyseTech Date: Wed, 14 Nov 2018 17:33:44 +0100 Subject: [PATCH 02/17] change the second animation range --- lv_objx/lv_preload.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lv_objx/lv_preload.c b/lv_objx/lv_preload.c index c531c8e75..5d2feda14 100644 --- a/lv_objx/lv_preload.c +++ b/lv_objx/lv_preload.c @@ -96,7 +96,7 @@ lv_obj_t * lv_preload_create(lv_obj_t * par, const lv_obj_t * copy) lv_anim_t b; b.var = new_preload; b.start = ext->arc_length; - b.end = 360; + b.end = 360 - ext->arc_length; b.fp = (lv_anim_fp_t)lv_preload_set_arc_length; b.path = lv_anim_path_ease_in_out; b.end_cb = NULL; @@ -105,7 +105,7 @@ lv_obj_t * lv_preload_create(lv_obj_t * par, const lv_obj_t * copy) b.playback = 1; b.playback_pause = 0; b.repeat = 1; - b.repeat_pause = 100; + b.repeat_pause = 0; lv_anim_create(&b); #endif From 7b9710aa4eecc014a8ce3043bc682d150ef71e39 Mon Sep 17 00:00:00 2001 From: AloyseTech Date: Wed, 14 Nov 2018 23:01:22 +0100 Subject: [PATCH 03/17] Use define to enable or not double animation on preload --- lv_objx/lv_preload.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lv_objx/lv_preload.c b/lv_objx/lv_preload.c index 5d2feda14..39516065e 100644 --- a/lv_objx/lv_preload.c +++ b/lv_objx/lv_preload.c @@ -93,6 +93,7 @@ lv_obj_t * lv_preload_create(lv_obj_t * par, const lv_obj_t * copy) a.repeat_pause = 0; lv_anim_create(&a); +#if LV_PRELOAD_DOUBLE_ANIM lv_anim_t b; b.var = new_preload; b.start = ext->arc_length; @@ -107,7 +108,8 @@ lv_obj_t * lv_preload_create(lv_obj_t * par, const lv_obj_t * copy) b.repeat = 1; b.repeat_pause = 0; lv_anim_create(&b); -#endif +#endif // LV_PRELOAD_DOUBLE_ANIM +#endif // USE_LV_ANIMATION /*Init the new pre loader pre loader*/ if(copy == NULL) { From 5102e71e8484f4c7ff8d04c6abc2878d1937f15b Mon Sep 17 00:00:00 2001 From: AloyseTech Date: Thu, 15 Nov 2018 00:01:05 +0100 Subject: [PATCH 04/17] add optimized chart drawing for test --- lv_objx/lv_chart.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++ lv_objx/lv_chart.h | 3 +- 2 files changed, 79 insertions(+), 1 deletion(-) diff --git a/lv_objx/lv_chart.c b/lv_objx/lv_chart.c index e21c8ca35..d0f7c4d67 100644 --- a/lv_objx/lv_chart.c +++ b/lv_objx/lv_chart.c @@ -34,6 +34,7 @@ static void lv_chart_draw_div(lv_obj_t * chart, const lv_area_t * mask); static void lv_chart_draw_lines(lv_obj_t * chart, const lv_area_t * mask); static void lv_chart_draw_points(lv_obj_t * chart, const lv_area_t * mask); static void lv_chart_draw_cols(lv_obj_t * chart, const lv_area_t * mask); +static void lv_chart_draw_vertical_lines(lv_obj_t * chart, const lv_area_t * mask); /********************** * STATIC VARIABLES @@ -460,6 +461,7 @@ static bool lv_chart_design(lv_obj_t * chart, const lv_area_t * mask, lv_design_ if(ext->type & LV_CHART_TYPE_LINE) lv_chart_draw_lines(chart, mask); if(ext->type & LV_CHART_TYPE_COLUMN) lv_chart_draw_cols(chart, mask); if(ext->type & LV_CHART_TYPE_POINT) lv_chart_draw_points(chart, mask); + if(ext->type & LV_CHART_TYPE_VERTICAL_LINE) lv_chart_draw_vertical_lines(chart, mask); } return true; } @@ -718,4 +720,79 @@ static void lv_chart_draw_cols(lv_obj_t * chart, const lv_area_t * mask) } } } + +/** + * Draw the data lines as vertical lines on a chart if there is only 1px between point + * @param obj pointer to chart object + */ +static void lv_chart_draw_vertical_lines(lv_obj_t * chart, const lv_area_t * mask) +{ + lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart); + + uint16_t i; + lv_point_t p1; + lv_point_t p2; + lv_coord_t w = lv_obj_get_width(chart); + lv_coord_t h = lv_obj_get_height(chart); + lv_coord_t x_ofs = chart->coords.x1; + lv_coord_t y_ofs = chart->coords.y1; + int32_t y_tmp; + lv_chart_series_t * ser; + lv_opa_t opa_scale = lv_obj_get_opa_scale(chart); + lv_style_t style; + lv_style_copy(&style, &lv_style_plain); + style.line.opa = ext->series.opa; + style.line.width = ext->series.width; + + /*Go through all data lines*/ + LL_READ_BACK(ext->series_ll, ser) { + style.line.color = ser->color; + + p1.x = 0 + x_ofs; + p2.x = 0 + x_ofs; + y_tmp = (int32_t)((int32_t) ser->points[0] - ext->ymin) * h; + y_tmp = y_tmp / (ext->ymax - ext->ymin); + p2.y = h - y_tmp + y_ofs; + + if(ext->point_cnt == w) + { + for(i = 0; i < ext->point_cnt; i++) + { + + y_tmp = (int32_t)((int32_t) ser->points[i] - ext->ymin) * h; + y_tmp = y_tmp / (ext->ymax - ext->ymin); + p2.y = h - y_tmp + y_ofs; + + if(p1.y == p2.y) + { + p2.x++; + } + + lv_draw_line(&p1, &p2, mask, &style, opa_scale); + + p2.x = ((w * i) / (ext->point_cnt - 1)) + x_ofs; + p1.x = p2.x; + p1.y = p2.y; + } + } + else + { + for(i = 1; i < ext->point_cnt; i ++) { + p1.x = p2.x; + p1.y = p2.y; + + p2.x = ((w * i) / (ext->point_cnt - 1)) + x_ofs; + + y_tmp = (int32_t)((int32_t) ser->points[i] - ext->ymin) * h; + y_tmp = y_tmp / (ext->ymax - ext->ymin); + p2.y = h - y_tmp + y_ofs; + + if(ser->points[i - 1] >= 0 && ser->points[i] >= 0) + { + lv_draw_line(&p1, &p2, mask, &style, opa_scale); + } + } + } + } +} #endif diff --git a/lv_objx/lv_chart.h b/lv_objx/lv_chart.h index 0567648df..2f1a43b37 100644 --- a/lv_objx/lv_chart.h +++ b/lv_objx/lv_chart.h @@ -49,7 +49,7 @@ typedef struct uint8_t hdiv_cnt; /*Number of horizontal division lines*/ uint8_t vdiv_cnt; /*Number of vertical division lines*/ uint16_t point_cnt; /*Point number in a data line*/ - uint8_t type :3; /*Line, column or point chart (from 'lv_chart_type_t')*/ + uint8_t type :4; /*Line, column or point chart (from 'lv_chart_type_t')*/ struct { lv_coord_t width; /*Line width or point radius*/ uint8_t num; /*Number of data lines in dl_ll*/ @@ -64,6 +64,7 @@ enum LV_CHART_TYPE_LINE = 0x01, LV_CHART_TYPE_COLUMN = 0x02, LV_CHART_TYPE_POINT = 0x04, + LV_CHART_TYPE_VERTICAL_LINE = 0x08, }; typedef uint8_t lv_chart_type_t; From e6214480c4ef47cb4620e5c451d6d77130bf2ebd Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Wed, 14 Nov 2018 20:09:09 -0500 Subject: [PATCH 05/17] Very rough prototype of animated switch --- lv_objx/lv_sw.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ lv_objx/lv_sw.h | 24 ++++++++++++++++ 2 files changed, 100 insertions(+) diff --git a/lv_objx/lv_sw.c b/lv_objx/lv_sw.c index 98c20ea85..83c084fa0 100644 --- a/lv_objx/lv_sw.c +++ b/lv_objx/lv_sw.c @@ -7,6 +7,7 @@ * INCLUDES *********************/ #include "lv_sw.h" + #if USE_LV_SW != 0 /*Testing of dependencies*/ @@ -20,6 +21,8 @@ * DEFINES *********************/ +#define LV_SWITCH_SLIDER_ANIM_MAX 1000 + /********************** * TYPEDEFS **********************/ @@ -66,6 +69,7 @@ lv_obj_t * lv_sw_create(lv_obj_t * par, const lv_obj_t * copy) /*Initialize the allocated 'ext' */ ext->changed = 0; + ext->anim_time = 0; ext->style_knob_off = ext->slider.style_knob; ext->style_knob_on = ext->slider.style_knob; @@ -111,6 +115,12 @@ lv_obj_t * lv_sw_create(lv_obj_t * par, const lv_obj_t * copy) * Setter functions *====================*/ +static void lv_sw_clear_anim(lv_obj_t *sw) +{ + lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); + ext->anim_act = 0; +} + /** * Turn ON the switch * @param sw pointer to a switch object @@ -120,6 +130,28 @@ void lv_sw_on(lv_obj_t * sw) if(lv_sw_get_state(sw)) return; /*Do nothing is already turned on*/ lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); +#if USE_LV_ANIMATION + if(lv_sw_get_anim_time(sw) > 0) { + if(ext->anim_act) { + lv_anim_del(sw, NULL); + ext->anim_act = 0; + } + ext->cur_anim.var = sw; + ext->cur_anim.start = lv_slider_get_value(sw); + ext->cur_anim.end = LV_SWITCH_SLIDER_ANIM_MAX; + ext->cur_anim.fp = (lv_anim_fp_t)lv_slider_set_value; + ext->cur_anim.path = lv_anim_path_linear; + ext->cur_anim.end_cb = (lv_anim_cb_t)lv_sw_clear_anim; + ext->cur_anim.act_time = 0; + ext->cur_anim.time = lv_sw_get_anim_time(sw); + ext->cur_anim.playback = 0; + ext->cur_anim.playback_pause = 0; + ext->cur_anim.repeat = 0; + ext->cur_anim.repeat_pause = 0; + ext->anim_act = 1; + lv_anim_create(&ext->cur_anim); + } else /* continues below if statement */ +#endif lv_slider_set_value(sw, 1); lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on); } @@ -165,6 +197,17 @@ void lv_sw_set_style(lv_obj_t * sw, lv_sw_style_t type, lv_style_t * style) } } + +void lv_sw_set_anim_time(lv_obj_t *sw, uint16_t anim_time) +{ + lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); + ext->anim_time = anim_time; + if(anim_time > 0) { + lv_slider_set_range(sw, 0, LV_SWITCH_SLIDER_ANIM_MAX); + } else + lv_slider_set_range(sw, 0, 1); +} + /*===================== * Getter functions *====================*/ @@ -200,6 +243,13 @@ lv_style_t * lv_sw_get_style(const lv_obj_t * sw, lv_sw_style_t type) return style; } + +uint16_t lv_sw_get_anim_time(const lv_obj_t *sw) +{ + lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); + return ext->anim_time; +} + /********************** * STATIC FUNCTIONS **********************/ @@ -217,9 +267,17 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) /*Save the current (old) value before slider signal modifies it*/ int16_t old_val; + if(sign == LV_SIGNAL_PRESSING) old_val = ext->slider.drag_value; else old_val = lv_slider_get_value(sw); +#if USE_LV_ANIMATION + if(lv_sw_get_anim_time(sw) > 0) { + /* Overwrite old_val */ + old_val = lv_sw_get_state(sw) ? LV_SWITCH_SLIDER_ANIM_MAX : 0; + } +#endif + /*Do not let the slider to call the callback. The Switch will do it if required*/ lv_action_t slider_action = ext->slider.action; ext->slider.action = NULL; @@ -234,6 +292,12 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) } else if(sign == LV_SIGNAL_PRESSING) { int16_t act_val = ext->slider.drag_value; if(act_val != old_val) ext->changed = 1; +#if USE_LV_ANIMATION + if(lv_sw_get_anim_time(sw) > 0) { + /* Keep forcing the slider to old_val */ + lv_slider_set_value(sw, old_val); + } +#endif } else if(sign == LV_SIGNAL_PRESS_LOST) { ext->changed = 0; if(lv_sw_get_state(sw)) lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on); @@ -244,6 +308,18 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) if(v == 0) lv_slider_set_value(sw, 1); else lv_slider_set_value(sw, 0); } +#if USE_LV_ANIMATION + else if(lv_sw_get_anim_time(sw) > 0) { + if(old_val == 0) { + lv_slider_set_value(sw, 0); + lv_bar_set_value(sw, 0); + lv_sw_on(sw); + } else { + lv_slider_set_value(sw, LV_SWITCH_SLIDER_ANIM_MAX); + lv_sw_off(sw); + } + } +#endif if(lv_sw_get_state(sw)) lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on); else lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off); diff --git a/lv_objx/lv_sw.h b/lv_objx/lv_sw.h index 3834c7287..58f6d3f30 100644 --- a/lv_objx/lv_sw.h +++ b/lv_objx/lv_sw.h @@ -44,6 +44,11 @@ typedef struct lv_style_t *style_knob_off; /*Style of the knob when the switch is OFF*/ lv_style_t *style_knob_on; /*Style of the knob when the switch is ON (NULL to use the same as OFF)*/ uint8_t changed :1; /*Indicates the switch explicitly changed by drag*/ +#if USE_LV_ANIMATION + uint16_t anim_time; /*switch animation time */ + lv_anim_t cur_anim; /*current active animation */ + uint8_t anim_act :1; +#endif } lv_sw_ext_t; enum { @@ -100,6 +105,16 @@ static inline void lv_sw_set_action(lv_obj_t * sw, lv_action_t action) */ void lv_sw_set_style(lv_obj_t *sw, lv_sw_style_t type, lv_style_t *style); +#if USE_LV_ANIMATION +/** + * Set the animation time of the switch + * @param sw pointer to a switch object + * @param anim_time animation time + * @return style pointer to a style + */ +void lv_sw_set_anim_time(lv_obj_t *sw, uint16_t anim_time); +#endif + /*===================== * Getter functions *====================*/ @@ -132,6 +147,15 @@ static inline lv_action_t lv_sw_get_action(const lv_obj_t * slider) */ lv_style_t * lv_sw_get_style(const lv_obj_t *sw, lv_sw_style_t type); +#if USE_LV_ANIMATION +/** + * Get the animation time of the switch + * @param sw pointer to a switch object + * @return style pointer to a style + */ +uint16_t lv_sw_get_anim_time(const lv_obj_t *sw); +#endif + /********************** * MACROS **********************/ From 1da612e8a0bef388b74ddc5dd140c3a5e6b6cea1 Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Wed, 14 Nov 2018 20:20:35 -0500 Subject: [PATCH 06/17] Prevent switch from jumping when clicked --- lv_objx/lv_sw.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lv_objx/lv_sw.c b/lv_objx/lv_sw.c index 83c084fa0..fe551e325 100644 --- a/lv_objx/lv_sw.c +++ b/lv_objx/lv_sw.c @@ -296,12 +296,20 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) if(lv_sw_get_anim_time(sw) > 0) { /* Keep forcing the slider to old_val */ lv_slider_set_value(sw, old_val); + ext->slider.drag_value = old_val; } #endif } else if(sign == LV_SIGNAL_PRESS_LOST) { ext->changed = 0; if(lv_sw_get_state(sw)) lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on); else lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off); +#if USE_LV_ANIMATION + if(lv_sw_get_anim_time(sw) > 0) { + /* Keep forcing the slider to old_val */ + lv_slider_set_value(sw, old_val); + ext->slider.drag_value = old_val; + } +#endif } else if(sign == LV_SIGNAL_RELEASED) { if(ext->changed == 0) { int16_t v = lv_slider_get_value(sw); From 65d6c82f81a4170b97ade69ab487db2272718174 Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Wed, 14 Nov 2018 20:24:13 -0500 Subject: [PATCH 07/17] Add off animation and correct initial switch state --- lv_objx/lv_sw.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/lv_objx/lv_sw.c b/lv_objx/lv_sw.c index fe551e325..e08c7601d 100644 --- a/lv_objx/lv_sw.c +++ b/lv_objx/lv_sw.c @@ -165,6 +165,28 @@ void lv_sw_off(lv_obj_t * sw) if(!lv_sw_get_state(sw)) return; /*Do nothing is already turned off*/ lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); +#if USE_LV_ANIMATION + if(lv_sw_get_anim_time(sw) > 0) { + if(ext->anim_act) { + lv_anim_del(sw, NULL); + ext->anim_act = 0; + } + ext->cur_anim.var = sw; + ext->cur_anim.start = LV_SWITCH_SLIDER_ANIM_MAX; + ext->cur_anim.end = 0; + ext->cur_anim.fp = (lv_anim_fp_t)lv_slider_set_value; + ext->cur_anim.path = lv_anim_path_linear; + ext->cur_anim.end_cb = (lv_anim_cb_t)lv_sw_clear_anim; + ext->cur_anim.act_time = 0; + ext->cur_anim.time = lv_sw_get_anim_time(sw); + ext->cur_anim.playback = 0; + ext->cur_anim.playback_pause = 0; + ext->cur_anim.repeat = 0; + ext->cur_anim.repeat_pause = 0; + ext->anim_act = 1; + lv_anim_create(&ext->cur_anim); + } else /* continues below if statement */ +#endif lv_slider_set_value(sw, 0); lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off); } @@ -197,16 +219,20 @@ void lv_sw_set_style(lv_obj_t * sw, lv_sw_style_t type, lv_style_t * style) } } - +#if USE_LV_ANIMATION void lv_sw_set_anim_time(lv_obj_t *sw, uint16_t anim_time) { lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); + bool sw_state = lv_sw_get_state(sw); + uint16_t max = anim_time > 0 ? LV_SWITCH_SLIDER_ANIM_MAX : 1; ext->anim_time = anim_time; if(anim_time > 0) { lv_slider_set_range(sw, 0, LV_SWITCH_SLIDER_ANIM_MAX); } else lv_slider_set_range(sw, 0, 1); + lv_slider_set_value(sw, sw_state ? max : 0); } +#endif /*===================== * Getter functions @@ -244,11 +270,13 @@ lv_style_t * lv_sw_get_style(const lv_obj_t * sw, lv_sw_style_t type) return style; } +#if USE_LV_ANIMATION uint16_t lv_sw_get_anim_time(const lv_obj_t *sw) { lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); return ext->anim_time; } +#endif /********************** * STATIC FUNCTIONS From 4de708b5ad85963a18ab488e2d71caa92a14194d Mon Sep 17 00:00:00 2001 From: AloyseTech Date: Thu, 15 Nov 2018 11:37:00 +0100 Subject: [PATCH 08/17] add api for setting/getting the animation type of preloader --- lv_objx/lv_preload.c | 162 ++++++++++++++++++++++++++++--------------- lv_objx/lv_preload.h | 16 +++++ 2 files changed, 121 insertions(+), 57 deletions(-) diff --git a/lv_objx/lv_preload.c b/lv_objx/lv_preload.c index 39516065e..1700a4dab 100644 --- a/lv_objx/lv_preload.c +++ b/lv_objx/lv_preload.c @@ -24,6 +24,12 @@ #ifndef LV_PRELOAD_DEF_SPIN_TIME # define LV_PRELOAD_DEF_SPIN_TIME 1000 /*[ms]*/ #endif + +#ifndef LV_PRELOAD_DEF_ANIM +# define LV_PRELOAD_DEF_ANIM LV_PRELOAD_TYPE_SPINNING_ARC /*animation type*/ +#endif + + /********************** * TYPEDEFS **********************/ @@ -73,43 +79,12 @@ lv_obj_t * lv_preload_create(lv_obj_t * par, const lv_obj_t * copy) /*Initialize the allocated 'ext' */ ext->arc_length = LV_PRELOAD_DEF_ARC_LENGTH; + ext->anim_type = LV_PRELOAD_DEF_ANIM; /*The signal and design functions are not copied so set them here*/ lv_obj_set_signal_func(new_preload, lv_preload_signal); lv_obj_set_design_func(new_preload, lv_preload_design); -#if USE_LV_ANIMATION - lv_anim_t a; - a.var = new_preload; - a.start = 0; - a.end = 360; - a.fp = (lv_anim_fp_t)lv_preload_spinner_animation; - a.path = lv_anim_path_ease_in_out; - a.end_cb = NULL; - a.act_time = 0; - a.time = LV_PRELOAD_DEF_SPIN_TIME; - a.playback = 0; - a.playback_pause = 0; - a.repeat = 1; - a.repeat_pause = 0; - lv_anim_create(&a); -#if LV_PRELOAD_DOUBLE_ANIM - lv_anim_t b; - b.var = new_preload; - b.start = ext->arc_length; - b.end = 360 - ext->arc_length; - b.fp = (lv_anim_fp_t)lv_preload_set_arc_length; - b.path = lv_anim_path_ease_in_out; - b.end_cb = NULL; - b.act_time = 0; - b.time = LV_PRELOAD_DEF_SPIN_TIME; - b.playback = 1; - b.playback_pause = 0; - b.repeat = 1; - b.repeat_pause = 0; - lv_anim_create(&b); -#endif // LV_PRELOAD_DOUBLE_ANIM -#endif // USE_LV_ANIMATION /*Init the new pre loader pre loader*/ if(copy == NULL) { @@ -123,6 +98,8 @@ lv_obj_t * lv_preload_create(lv_obj_t * par, const lv_obj_t * copy) lv_obj_set_style(new_preload, &lv_style_pretty_color); } + ext->time = LV_PRELOAD_DEF_SPIN_TIME; + } /*Copy an existing pre loader*/ else { @@ -133,6 +110,8 @@ lv_obj_t * lv_preload_create(lv_obj_t * par, const lv_obj_t * copy) lv_obj_refresh_style(new_preload); } + lv_preload_set_animation_type(new_preload, ext->anim_type); + LV_LOG_INFO("preload created"); @@ -165,22 +144,7 @@ void lv_preload_set_spin_time(lv_obj_t * preload, uint16_t time) lv_preload_ext_t * ext = lv_obj_get_ext_attr(preload); ext->time = time; -#if USE_LV_ANIMATION - lv_anim_t a; - a.var = preload; - a.start = 0; - a.end = 360; - a.fp = (lv_anim_fp_t)lv_preload_spinner_animation; - a.path = lv_anim_path_ease_in_out; - a.end_cb = NULL; - a.act_time = 0; - a.time = time; - a.playback = 0; - a.playback_pause = 0; - a.repeat = 1; - a.repeat_pause = 0; - lv_anim_create(&a); -#endif + lv_preload_set_animation_type(preload, ext->anim_type); } /*===================== * Setter functions @@ -195,12 +159,85 @@ void lv_preload_set_spin_time(lv_obj_t * preload, uint16_t time) void lv_preload_set_style(lv_obj_t * preload, lv_preload_style_t type, lv_style_t * style) { switch(type) { - case LV_PRELOAD_STYLE_MAIN: - lv_arc_set_style(preload, LV_ARC_STYLE_MAIN, style); - break; + case LV_PRELOAD_STYLE_MAIN: + lv_arc_set_style(preload, LV_ARC_STYLE_MAIN, style); + break; } } +/** + * Set the animation type of a preloadeer. + * @param preload pointer to pre loader object + * @param type animation type of the preload + * */ +void lv_preload_set_animation_type(lv_obj_t * preload, lv_preloader_type_t type) +{ +#if USE_LV_ANIMATION + lv_preload_ext_t * ext = lv_obj_get_ext_attr(preload); + + /*delete previous animation*/ + //lv_anim_del(preload, NULL); + switch(type) + { + case LV_PRELOAD_TYPE_FILLSPIN_ARC: + { + ext->anim_type = LV_PRELOAD_TYPE_FILLSPIN_ARC; + lv_anim_t a; + a.var = preload; + a.start = 0; + a.end = 360; + a.fp = (lv_anim_fp_t)lv_preload_spinner_animation; + a.path = lv_anim_path_ease_in_out; + a.end_cb = NULL; + a.act_time = 0; + a.time = ext->time; + a.playback = 0; + a.playback_pause = 0; + a.repeat = 1; + a.repeat_pause = 0; + lv_anim_create(&a); + + lv_anim_t b; + b.var = preload; + b.start = ext->arc_length; + b.end = 360 - ext->arc_length; + b.fp = (lv_anim_fp_t)lv_preload_set_arc_length; + b.path = lv_anim_path_ease_in_out; + b.end_cb = NULL; + b.act_time = 0; + b.time = ext->time; + b.playback = 1; + b.playback_pause = 0; + b.repeat = 1; + b.repeat_pause = 0; + lv_anim_create(&b); + break; + } + case LV_PRELOAD_TYPE_SPINNING_ARC: + default: + { + ext->anim_type = LV_PRELOAD_TYPE_SPINNING_ARC; + lv_anim_t a; + a.var = preload; + a.start = 0; + a.end = 360; + a.fp = (lv_anim_fp_t)lv_preload_spinner_animation; + a.path = lv_anim_path_ease_in_out; + a.end_cb = NULL; + a.act_time = 0; + a.time = ext->time; + a.playback = 0; + a.playback_pause = 0; + a.repeat = 1; + a.repeat_pause = 0; + lv_anim_create(&a); + break; + } + } + +#endif //USE_LV_ANIMATION +} + /*===================== * Getter functions *====================*/ @@ -237,17 +274,28 @@ lv_style_t * lv_preload_get_style(const lv_obj_t * preload, lv_preload_style_t t lv_style_t * style = NULL; switch(type) { - case LV_PRELOAD_STYLE_MAIN: - style = lv_arc_get_style(preload, LV_ARC_STYLE_MAIN); - break; - default: - style = NULL; - break; + case LV_PRELOAD_STYLE_MAIN: + style = lv_arc_get_style(preload, LV_ARC_STYLE_MAIN); + break; + default: + style = NULL; + break; } return style; } +/** + * Get the animation type of a preloadeer. + * @param preload pointer to pre loader object + * @return animation type + * */ +lv_preloader_type_t lv_preload_get_animation_type(lv_obj_t * preload) +{ + lv_preload_ext_t * ext = lv_obj_get_ext_attr(preload); + return ext->anim_type; +} + /*===================== * Other functions *====================*/ diff --git a/lv_objx/lv_preload.h b/lv_objx/lv_preload.h index 393eea8e7..4f12f0221 100644 --- a/lv_objx/lv_preload.h +++ b/lv_objx/lv_preload.h @@ -43,6 +43,7 @@ extern "C" { enum { LV_PRELOAD_TYPE_SPINNING_ARC, + LV_PRELOAD_TYPE_FILLSPIN_ARC, }; typedef uint8_t lv_preloader_type_t; @@ -52,6 +53,7 @@ typedef struct { /*New data for this type */ uint16_t arc_length; /*Length of the spinning indicator in degree*/ uint16_t time; /*Time of one round*/ + lv_preloader_type_t anim_type; /*Type of the arc animation*/ } lv_preload_ext_t; @@ -103,6 +105,13 @@ void lv_preload_set_spin_time(lv_obj_t * preload, uint16_t time); * */ void lv_preload_set_style(lv_obj_t * preload, lv_preload_style_t type, lv_style_t *style); +/** + * Set the animation type of a preloadeer. + * @param preload pointer to pre loader object + * @param type animation type of the preload + * */ +void lv_preload_set_animation_type(lv_obj_t * preload, lv_preloader_type_t type); + /*===================== * Getter functions *====================*/ @@ -127,6 +136,13 @@ uint16_t lv_preload_get_spin_time(const lv_obj_t * preload); * */ lv_style_t * lv_preload_get_style(const lv_obj_t * preload, lv_preload_style_t type); +/** + * Get the animation type of a preloadeer. + * @param preload pointer to pre loader object + * @return animation type + * */ +lv_preloader_type_t lv_preload_get_animation_type(lv_obj_t * preload); + /*===================== * Other functions *====================*/ From 938819a8b886113e20609ad608326de3da1d7610 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Fri, 16 Nov 2018 17:42:29 +0100 Subject: [PATCH 09/17] lv_sw: simplify animation --- lv_objx/lv_sw.c | 174 +++++++++++++++--------------------------------- lv_objx/lv_sw.h | 8 +-- 2 files changed, 57 insertions(+), 125 deletions(-) diff --git a/lv_objx/lv_sw.c b/lv_objx/lv_sw.c index e08c7601d..15b3b2da9 100644 --- a/lv_objx/lv_sw.c +++ b/lv_objx/lv_sw.c @@ -20,7 +20,6 @@ /********************* * DEFINES *********************/ - #define LV_SWITCH_SLIDER_ANIM_MAX 1000 /********************** @@ -31,6 +30,7 @@ * STATIC PROTOTYPES **********************/ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param); +static void lv_sw_anim_to_value(lv_obj_t * sw, int16_t value); /********************** * STATIC VARIABLES @@ -68,7 +68,7 @@ lv_obj_t * lv_sw_create(lv_obj_t * par, const lv_obj_t * copy) if(ext == NULL) return NULL; /*Initialize the allocated 'ext' */ - ext->changed = 0; + ext->tmp_state = 0; ext->anim_time = 0; ext->style_knob_off = ext->slider.style_knob; ext->style_knob_on = ext->slider.style_knob; @@ -81,6 +81,7 @@ lv_obj_t * lv_sw_create(lv_obj_t * par, const lv_obj_t * copy) lv_slider_set_range(new_sw, 0, 1); lv_obj_set_size(new_sw, 2 * LV_DPI / 3, LV_DPI / 3); lv_slider_set_knob_in(new_sw, true); + lv_slider_set_range(new_sw, 0, LV_SWITCH_SLIDER_ANIM_MAX); /*Set the default styles*/ lv_theme_t * th = lv_theme_get_current(); @@ -115,44 +116,17 @@ lv_obj_t * lv_sw_create(lv_obj_t * par, const lv_obj_t * copy) * Setter functions *====================*/ -static void lv_sw_clear_anim(lv_obj_t *sw) -{ - lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); - ext->anim_act = 0; -} - /** * Turn ON the switch * @param sw pointer to a switch object */ void lv_sw_on(lv_obj_t * sw) { - if(lv_sw_get_state(sw)) return; /*Do nothing is already turned on*/ - lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); -#if USE_LV_ANIMATION - if(lv_sw_get_anim_time(sw) > 0) { - if(ext->anim_act) { - lv_anim_del(sw, NULL); - ext->anim_act = 0; - } - ext->cur_anim.var = sw; - ext->cur_anim.start = lv_slider_get_value(sw); - ext->cur_anim.end = LV_SWITCH_SLIDER_ANIM_MAX; - ext->cur_anim.fp = (lv_anim_fp_t)lv_slider_set_value; - ext->cur_anim.path = lv_anim_path_linear; - ext->cur_anim.end_cb = (lv_anim_cb_t)lv_sw_clear_anim; - ext->cur_anim.act_time = 0; - ext->cur_anim.time = lv_sw_get_anim_time(sw); - ext->cur_anim.playback = 0; - ext->cur_anim.playback_pause = 0; - ext->cur_anim.repeat = 0; - ext->cur_anim.repeat_pause = 0; - ext->anim_act = 1; - lv_anim_create(&ext->cur_anim); - } else /* continues below if statement */ -#endif - lv_slider_set_value(sw, 1); + + if(lv_sw_get_anim_time(sw) > 0) lv_sw_anim_to_value(sw, LV_SWITCH_SLIDER_ANIM_MAX); + else lv_slider_set_value(sw, LV_SWITCH_SLIDER_ANIM_MAX); + lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on); } @@ -162,32 +136,10 @@ void lv_sw_on(lv_obj_t * sw) */ void lv_sw_off(lv_obj_t * sw) { - if(!lv_sw_get_state(sw)) return; /*Do nothing is already turned off*/ - lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); -#if USE_LV_ANIMATION - if(lv_sw_get_anim_time(sw) > 0) { - if(ext->anim_act) { - lv_anim_del(sw, NULL); - ext->anim_act = 0; - } - ext->cur_anim.var = sw; - ext->cur_anim.start = LV_SWITCH_SLIDER_ANIM_MAX; - ext->cur_anim.end = 0; - ext->cur_anim.fp = (lv_anim_fp_t)lv_slider_set_value; - ext->cur_anim.path = lv_anim_path_linear; - ext->cur_anim.end_cb = (lv_anim_cb_t)lv_sw_clear_anim; - ext->cur_anim.act_time = 0; - ext->cur_anim.time = lv_sw_get_anim_time(sw); - ext->cur_anim.playback = 0; - ext->cur_anim.playback_pause = 0; - ext->cur_anim.repeat = 0; - ext->cur_anim.repeat_pause = 0; - ext->anim_act = 1; - lv_anim_create(&ext->cur_anim); - } else /* continues below if statement */ -#endif - lv_slider_set_value(sw, 0); + if(lv_sw_get_anim_time(sw) > 0) lv_sw_anim_to_value(sw, 0); + else lv_slider_set_value(sw, 0); + lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off); } @@ -219,20 +171,14 @@ void lv_sw_set_style(lv_obj_t * sw, lv_sw_style_t type, lv_style_t * style) } } -#if USE_LV_ANIMATION void lv_sw_set_anim_time(lv_obj_t *sw, uint16_t anim_time) { - lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); - bool sw_state = lv_sw_get_state(sw); - uint16_t max = anim_time > 0 ? LV_SWITCH_SLIDER_ANIM_MAX : 1; - ext->anim_time = anim_time; - if(anim_time > 0) { - lv_slider_set_range(sw, 0, LV_SWITCH_SLIDER_ANIM_MAX); - } else - lv_slider_set_range(sw, 0, 1); - lv_slider_set_value(sw, sw_state ? max : 0); -} +#if USE_LV_ANIMATION == 0 + anim_time = 0; #endif + lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); + ext->anim_time = anim_time; +} /*===================== * Getter functions @@ -270,13 +216,16 @@ lv_style_t * lv_sw_get_style(const lv_obj_t * sw, lv_sw_style_t type) return style; } -#if USE_LV_ANIMATION uint16_t lv_sw_get_anim_time(const lv_obj_t *sw) { + +#if USE_LV_ANIMATION lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); return ext->anim_time; -} +#else + return 0; #endif +} /********************** * STATIC FUNCTIONS @@ -299,13 +248,6 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) if(sign == LV_SIGNAL_PRESSING) old_val = ext->slider.drag_value; else old_val = lv_slider_get_value(sw); -#if USE_LV_ANIMATION - if(lv_sw_get_anim_time(sw) > 0) { - /* Overwrite old_val */ - old_val = lv_sw_get_state(sw) ? LV_SWITCH_SLIDER_ANIM_MAX : 0; - } -#endif - /*Do not let the slider to call the callback. The Switch will do it if required*/ lv_action_t slider_action = ext->slider.action; ext->slider.action = NULL; @@ -317,52 +259,24 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) if(sign == LV_SIGNAL_CLEANUP) { /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ - } else if(sign == LV_SIGNAL_PRESSING) { - int16_t act_val = ext->slider.drag_value; - if(act_val != old_val) ext->changed = 1; -#if USE_LV_ANIMATION - if(lv_sw_get_anim_time(sw) > 0) { - /* Keep forcing the slider to old_val */ - lv_slider_set_value(sw, old_val); - ext->slider.drag_value = old_val; - } -#endif - } else if(sign == LV_SIGNAL_PRESS_LOST) { - ext->changed = 0; + } + else if(sign == LV_SIGNAL_PRESSED) { + ext->tmp_state = lv_sw_get_state(sw); + } + else if(sign == LV_SIGNAL_PRESS_LOST) { if(lv_sw_get_state(sw)) lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on); else lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off); -#if USE_LV_ANIMATION - if(lv_sw_get_anim_time(sw) > 0) { - /* Keep forcing the slider to old_val */ - lv_slider_set_value(sw, old_val); - ext->slider.drag_value = old_val; + } + else if(sign == LV_SIGNAL_RELEASED) { + int16_t v = lv_slider_get_value(sw); + if(v > LV_SWITCH_SLIDER_ANIM_MAX / 2) { + lv_sw_on(sw); + if(ext->tmp_state == 0 && slider_action != NULL) res = slider_action(sw); } -#endif - } else if(sign == LV_SIGNAL_RELEASED) { - if(ext->changed == 0) { - int16_t v = lv_slider_get_value(sw); - if(v == 0) lv_slider_set_value(sw, 1); - else lv_slider_set_value(sw, 0); + else { + lv_sw_off(sw); + if(ext->tmp_state && slider_action != NULL) res = slider_action(sw); } -#if USE_LV_ANIMATION - else if(lv_sw_get_anim_time(sw) > 0) { - if(old_val == 0) { - lv_slider_set_value(sw, 0); - lv_bar_set_value(sw, 0); - lv_sw_on(sw); - } else { - lv_slider_set_value(sw, LV_SWITCH_SLIDER_ANIM_MAX); - lv_sw_off(sw); - } - } -#endif - - if(lv_sw_get_state(sw)) lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on); - else lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off); - - ext->changed = 0; - - if(slider_action != NULL) res = slider_action(sw); } else if(sign == LV_SIGNAL_CONTROLL) { @@ -397,4 +311,24 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) return res; } + +static void lv_sw_anim_to_value(lv_obj_t * sw, int16_t value) +{ + lv_anim_t a; + lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); + a.var = sw; + a.start = ext->slider.bar.cur_value; + a.end = value; + a.fp = (lv_anim_fp_t)lv_slider_set_value; + a.path = lv_anim_path_linear; + a.end_cb = NULL; + a.act_time = 0; + a.time = lv_sw_get_anim_time(sw); + a.playback = 0; + a.playback_pause = 0; + a.repeat = 0; + a.repeat_pause = 0; + lv_anim_create(&a); +} + #endif diff --git a/lv_objx/lv_sw.h b/lv_objx/lv_sw.h index 58f6d3f30..2d198170b 100644 --- a/lv_objx/lv_sw.h +++ b/lv_objx/lv_sw.h @@ -41,13 +41,11 @@ typedef struct { lv_slider_ext_t slider; /*Ext. of ancestor*/ /*New data for this type */ - lv_style_t *style_knob_off; /*Style of the knob when the switch is OFF*/ - lv_style_t *style_knob_on; /*Style of the knob when the switch is ON (NULL to use the same as OFF)*/ - uint8_t changed :1; /*Indicates the switch explicitly changed by drag*/ + lv_style_t *style_knob_off; /*Style of the knob when the switch is OFF*/ + lv_style_t *style_knob_on; /*Style of the knob when the switch is ON (NULL to use the same as OFF)*/ + uint8_t tmp_state :1; /*Saves the initial state of the switch when it begins to drag*/ #if USE_LV_ANIMATION uint16_t anim_time; /*switch animation time */ - lv_anim_t cur_anim; /*current active animation */ - uint8_t anim_act :1; #endif } lv_sw_ext_t; From 07f2e18dfc2d84b1b45e67d9ed4bc210fdf16f5d Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Fri, 16 Nov 2018 18:36:12 +0100 Subject: [PATCH 10/17] lv_sw: animation fixes --- lv_objx/lv_sw.c | 46 ++++++++++++++++++++++++++++++++-------------- lv_objx/lv_sw.h | 5 +++-- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/lv_objx/lv_sw.c b/lv_objx/lv_sw.c index 15b3b2da9..e143ca585 100644 --- a/lv_objx/lv_sw.c +++ b/lv_objx/lv_sw.c @@ -20,7 +20,6 @@ /********************* * DEFINES *********************/ -#define LV_SWITCH_SLIDER_ANIM_MAX 1000 /********************** * TYPEDEFS @@ -68,7 +67,7 @@ lv_obj_t * lv_sw_create(lv_obj_t * par, const lv_obj_t * copy) if(ext == NULL) return NULL; /*Initialize the allocated 'ext' */ - ext->tmp_state = 0; + ext->changed = 0; ext->anim_time = 0; ext->style_knob_off = ext->slider.style_knob; ext->style_knob_on = ext->slider.style_knob; @@ -260,23 +259,42 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) if(sign == LV_SIGNAL_CLEANUP) { /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ } - else if(sign == LV_SIGNAL_PRESSED) { - ext->tmp_state = lv_sw_get_state(sw); + else if(sign == LV_SIGNAL_PRESSING) { + int16_t threshold = LV_SWITCH_SLIDER_ANIM_MAX / 2; + if((old_val < threshold && ext->slider.drag_value > threshold) || + (old_val > threshold && ext->slider.drag_value < threshold)) + { + ext->changed = 1; + } + printf("tmp: %d\n", ext->changed); } else if(sign == LV_SIGNAL_PRESS_LOST) { - if(lv_sw_get_state(sw)) lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on); - else lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off); - } - else if(sign == LV_SIGNAL_RELEASED) { - int16_t v = lv_slider_get_value(sw); - if(v > LV_SWITCH_SLIDER_ANIM_MAX / 2) { - lv_sw_on(sw); - if(ext->tmp_state == 0 && slider_action != NULL) res = slider_action(sw); + if(lv_sw_get_state(sw)) { + lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on); + lv_sw_anim_to_value(sw, LV_SWITCH_SLIDER_ANIM_MAX); } else { - lv_sw_off(sw); - if(ext->tmp_state && slider_action != NULL) res = slider_action(sw); + lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off); + lv_sw_anim_to_value(sw, 0); } + ext->changed = 0; + } + else if(sign == LV_SIGNAL_RELEASED) { + /*If not dragged then toggle the switch*/ + if(ext->changed == 0) { + if(lv_sw_get_state(sw)) lv_sw_off(sw); + else lv_sw_on(sw); + } + /*If the switch was dragged then calculate the new state based on the current position*/ + else { + int16_t v = lv_slider_get_value(sw); + if(v > LV_SWITCH_SLIDER_ANIM_MAX / 2) lv_sw_on(sw); + else lv_sw_off(sw); + + if(slider_action != NULL) res = slider_action(sw); + } + + ext->changed = 0; } else if(sign == LV_SIGNAL_CONTROLL) { diff --git a/lv_objx/lv_sw.h b/lv_objx/lv_sw.h index 2d198170b..87a62c8cc 100644 --- a/lv_objx/lv_sw.h +++ b/lv_objx/lv_sw.h @@ -32,6 +32,7 @@ extern "C" { /********************* * DEFINES *********************/ +#define LV_SWITCH_SLIDER_ANIM_MAX 1000 /********************** * TYPEDEFS @@ -43,7 +44,7 @@ typedef struct /*New data for this type */ lv_style_t *style_knob_off; /*Style of the knob when the switch is OFF*/ lv_style_t *style_knob_on; /*Style of the knob when the switch is ON (NULL to use the same as OFF)*/ - uint8_t tmp_state :1; /*Saves the initial state of the switch when it begins to drag*/ + uint8_t changed :1; /*Indicates the switch explicitly changed by drag*/ #if USE_LV_ANIMATION uint16_t anim_time; /*switch animation time */ #endif @@ -124,7 +125,7 @@ void lv_sw_set_anim_time(lv_obj_t *sw, uint16_t anim_time); */ static inline bool lv_sw_get_state(const lv_obj_t *sw) { - return lv_bar_get_value(sw) == 0 ? false : true; + return lv_bar_get_value(sw) < LV_SWITCH_SLIDER_ANIM_MAX / 2 ? false : true; } /** From 042147b010bbef411f972f4e3f5a8d6288d31669 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sat, 17 Nov 2018 10:48:17 +0100 Subject: [PATCH 11/17] add LV_PRELOAD_DEF_ANIM to lv_conf_templ.h --- lv_conf_templ.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lv_conf_templ.h b/lv_conf_templ.h index 7239e4f28..1cf4903a9 100644 --- a/lv_conf_templ.h +++ b/lv_conf_templ.h @@ -262,6 +262,7 @@ #if USE_LV_PRELOAD != 0 #define LV_PRELOAD_DEF_ARC_LENGTH 60 /*[deg]*/ #define LV_PRELOAD_DEF_SPIN_TIME 1000 /*[ms]*/ +#define LV_PRELOAD_DEF_ANIM LV_PRELOAD_TYPE_SPINNING_ARC #endif /************************* From 2c8cf7d7ea341ff524b0d021d69b229357bdc06a Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sat, 17 Nov 2018 08:02:11 -0500 Subject: [PATCH 12/17] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 191d8bbe0..b79396c25 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ In the simplest case you need 5 things: 3. Register a function which can **read an input device**. (E.g. touch pad) 4. Copy `lv_conf_templ.h` as `lv_conf.h` and set at least `LV_HOR_RES`, `LV_VER_RES` and `LV_COLOR_DEPTH`. 5. Call `lv_task_handler()` periodically every few milliseconds. -For a detailed description visit https://littlevgl.com/porting +For a detailed description visit https://github.com/littlevgl/lvgl/wiki/Porting Or check the [Porting tutorial](https://github.com/littlevgl/lv_examples/blob/master/lv_tutorial/0_porting/lv_tutorial_porting.c) ## Project set-up From bf557a1bb0ad6e83e7dbac2eb9e6ae286aaddaa2 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 19 Nov 2018 06:35:11 +0100 Subject: [PATCH 13/17] lv_sw: add comment --- lv_objx/lv_sw.c | 3 +-- lv_objx/lv_sw.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lv_objx/lv_sw.c b/lv_objx/lv_sw.c index e143ca585..52f5a389c 100644 --- a/lv_objx/lv_sw.c +++ b/lv_objx/lv_sw.c @@ -264,9 +264,8 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) if((old_val < threshold && ext->slider.drag_value > threshold) || (old_val > threshold && ext->slider.drag_value < threshold)) { - ext->changed = 1; + ext->changed = 1; /*If explicitly changed don't need to be toggled on release*/ } - printf("tmp: %d\n", ext->changed); } else if(sign == LV_SIGNAL_PRESS_LOST) { if(lv_sw_get_state(sw)) { diff --git a/lv_objx/lv_sw.h b/lv_objx/lv_sw.h index 87a62c8cc..ba22c677f 100644 --- a/lv_objx/lv_sw.h +++ b/lv_objx/lv_sw.h @@ -44,7 +44,7 @@ typedef struct /*New data for this type */ lv_style_t *style_knob_off; /*Style of the knob when the switch is OFF*/ lv_style_t *style_knob_on; /*Style of the knob when the switch is ON (NULL to use the same as OFF)*/ - uint8_t changed :1; /*Indicates the switch explicitly changed by drag*/ + uint8_t changed :1; /*Indicates the switch state explicitly changed by drag*/ #if USE_LV_ANIMATION uint16_t anim_time; /*switch animation time */ #endif From 892f2be48743bf3a3bc6d0cd9c705fec261265fb Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 19 Nov 2018 07:00:17 +0100 Subject: [PATCH 14/17] add lv_btnm_get_pressed --- lv_objx/lv_btnm.c | 17 ++++++++++++++--- lv_objx/lv_btnm.h | 8 +++++++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/lv_objx/lv_btnm.c b/lv_objx/lv_btnm.c index 3326f2e96..73a96e39d 100644 --- a/lv_objx/lv_btnm.c +++ b/lv_objx/lv_btnm.c @@ -340,16 +340,27 @@ lv_btnm_action_t lv_btnm_get_action(const lv_obj_t * btnm) return ext->action; } +/** + * Get the pressed button + * @param btnm pointer to button matrix object + * @return index of the currently pressed button (LV_BTNM_PR_NONE: if unset) + */ +uint16_t lv_btnm_get_pressed(const lv_obj_t * btnm) +{ + lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); + return ext->btn_id_pr; +} + /** * Get the toggled button * @param btnm pointer to button matrix object - * @return index of the currently toggled button (0: if unset) + * @return index of the currently toggled button (LV_BTNM_PR_NONE: if unset) */ uint16_t lv_btnm_get_toggled(const lv_obj_t * btnm) { lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); - if(ext->toggle == 0) return 0; + if(ext->toggle == 0) return LV_BTNM_PR_NONE; else return ext->btn_id_tgl; } @@ -581,7 +592,7 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param) } #if USE_LV_GROUP - /*Leave the clicked button as pressed if this the focused object in a group*/ + /*Leave the clicked button when releases if this not the focused object in a group*/ lv_group_t * g = lv_obj_get_group(btnm); if(lv_group_get_focused(g) != btnm) { ext->btn_id_pr = LV_BTNM_PR_NONE; diff --git a/lv_objx/lv_btnm.h b/lv_objx/lv_btnm.h index 91214e40f..a1c7c2097 100644 --- a/lv_objx/lv_btnm.h +++ b/lv_objx/lv_btnm.h @@ -147,11 +147,17 @@ const char ** lv_btnm_get_map(const lv_obj_t * btnm); */ lv_btnm_action_t lv_btnm_get_action(const lv_obj_t * btnm); +/** + * Get the pressed button + * @param btnm pointer to button matrix object + * @return index of the currently pressed button (LV_BTNM_PR_NONE: if unset) + */ +uint16_t lv_btnm_get_pressed(const lv_obj_t * btnm); /** * Get the toggled button * @param btnm pointer to button matrix object - * @return index of the currently toggled button (0: if unset) + * @return index of the currently toggled button (LV_BTNM_PR_NONE: if unset) */ uint16_t lv_btnm_get_toggled(const lv_obj_t * btnm); From 5416c2b7787dce8796b6b6172d7de5bc7162f291 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 20 Nov 2018 07:33:32 +0100 Subject: [PATCH 15/17] lv_sw: aniamtion improvements --- lv_objx/lv_sw.c | 82 ++++++++++++++++++++++++++++++++++++++++--------- lv_objx/lv_sw.h | 14 +++++++++ 2 files changed, 81 insertions(+), 15 deletions(-) diff --git a/lv_objx/lv_sw.c b/lv_objx/lv_sw.c index 52f5a389c..570a6c4f4 100644 --- a/lv_objx/lv_sw.c +++ b/lv_objx/lv_sw.c @@ -16,6 +16,7 @@ #endif #include "../lv_themes/lv_theme.h" +#include "../lv_misc/lv_math.h" /********************* * DEFINES @@ -99,9 +100,12 @@ lv_obj_t * lv_sw_create(lv_obj_t * par, const lv_obj_t * copy) lv_sw_ext_t * copy_ext = lv_obj_get_ext_attr(copy); ext->style_knob_off = copy_ext->style_knob_off; ext->style_knob_on = copy_ext->style_knob_on; + ext->anim_time = copy_ext->anim_time; if(lv_sw_get_state(new_sw)) lv_slider_set_style(new_sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on); else lv_slider_set_style(new_sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off); + + /*Refresh the style with new signal function*/ lv_obj_refresh_style(new_sw); } @@ -122,9 +126,7 @@ lv_obj_t * lv_sw_create(lv_obj_t * par, const lv_obj_t * copy) void lv_sw_on(lv_obj_t * sw) { lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); - - if(lv_sw_get_anim_time(sw) > 0) lv_sw_anim_to_value(sw, LV_SWITCH_SLIDER_ANIM_MAX); - else lv_slider_set_value(sw, LV_SWITCH_SLIDER_ANIM_MAX); + lv_slider_set_value(sw, LV_SWITCH_SLIDER_ANIM_MAX); lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on); } @@ -134,6 +136,32 @@ void lv_sw_on(lv_obj_t * sw) * @param sw pointer to a switch object */ void lv_sw_off(lv_obj_t * sw) +{ + lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); + lv_slider_set_value(sw, 0); + + lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off); +} + +/** + * Turn ON the switch with an animation + * @param sw pointer to a switch object + */ +void lv_sw_on_anim(lv_obj_t * sw) +{ + lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); + + if(lv_sw_get_anim_time(sw) > 0) lv_sw_anim_to_value(sw, LV_SWITCH_SLIDER_ANIM_MAX); + else lv_slider_set_value(sw, LV_SWITCH_SLIDER_ANIM_MAX); + + lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on); +} + +/** + * Turn OFF the switch with an animation + * @param sw pointer to a switch object + */ +void lv_sw_off_anim(lv_obj_t * sw) { lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); if(lv_sw_get_anim_time(sw) > 0) lv_sw_anim_to_value(sw, 0); @@ -259,12 +287,39 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) if(sign == LV_SIGNAL_CLEANUP) { /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ } + else if(sign == LV_SIGNAL_PRESSED) { + + /*Save the x coordinate of the pressed point to see if the switch was slid*/ + lv_indev_t * indev = lv_indev_get_act(); + if(indev) { + lv_point_t p; + lv_indev_get_point(indev, &p); + ext->start_x = p.x; + } + ext->slided = 0; + ext->changed = 0; + } else if(sign == LV_SIGNAL_PRESSING) { + /*See if the switch was slid*/ + lv_indev_t * indev = lv_indev_get_act(); + if(indev) { + lv_point_t p = {0,0}; + lv_indev_get_point(indev, &p); + if(LV_MATH_ABS(p.x - ext->start_x) > LV_INDEV_DRAG_LIMIT) ext->slided = 1; + } + + /*If didn't slide then revert the min/max value. So click without slide won't move the switch as a slider*/ + if(ext->slided == 0) { + if(lv_sw_get_state(sw)) ext->slider.drag_value = LV_SWITCH_SLIDER_ANIM_MAX; + else ext->slider.drag_value = 0; + } + + /*If explicitly changed (by slide) don't need to be toggled on release*/ int16_t threshold = LV_SWITCH_SLIDER_ANIM_MAX / 2; if((old_val < threshold && ext->slider.drag_value > threshold) || (old_val > threshold && ext->slider.drag_value < threshold)) { - ext->changed = 1; /*If explicitly changed don't need to be toggled on release*/ + ext->changed = 1; } } else if(sign == LV_SIGNAL_PRESS_LOST) { @@ -276,38 +331,35 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off); lv_sw_anim_to_value(sw, 0); } - ext->changed = 0; } else if(sign == LV_SIGNAL_RELEASED) { /*If not dragged then toggle the switch*/ if(ext->changed == 0) { - if(lv_sw_get_state(sw)) lv_sw_off(sw); - else lv_sw_on(sw); + if(lv_sw_get_state(sw)) lv_sw_off_anim(sw); + else lv_sw_on_anim(sw); } /*If the switch was dragged then calculate the new state based on the current position*/ else { int16_t v = lv_slider_get_value(sw); - if(v > LV_SWITCH_SLIDER_ANIM_MAX / 2) lv_sw_on(sw); - else lv_sw_off(sw); + if(v > LV_SWITCH_SLIDER_ANIM_MAX / 2) lv_sw_on_anim(sw); + else lv_sw_off_anim(sw); if(slider_action != NULL) res = slider_action(sw); } - ext->changed = 0; - } else if(sign == LV_SIGNAL_CONTROLL) { char c = *((char *)param); if(c == LV_GROUP_KEY_ENTER) { - if(old_val) lv_sw_off(sw); - else lv_sw_on(sw); + if(old_val) lv_sw_off_anim(sw); + else lv_sw_on_anim(sw); if(slider_action) res = slider_action(sw); } else if(c == LV_GROUP_KEY_UP || c == LV_GROUP_KEY_RIGHT) { - lv_sw_on(sw); + lv_sw_on_anim(sw); if(slider_action) res = slider_action(sw); } else if(c == LV_GROUP_KEY_DOWN || c == LV_GROUP_KEY_LEFT) { - lv_sw_off(sw); + lv_sw_off_anim(sw); if(slider_action) res = slider_action(sw); } } else if(sign == LV_SIGNAL_GET_EDITABLE) { diff --git a/lv_objx/lv_sw.h b/lv_objx/lv_sw.h index ba22c677f..1eee3a50e 100644 --- a/lv_objx/lv_sw.h +++ b/lv_objx/lv_sw.h @@ -44,7 +44,9 @@ typedef struct /*New data for this type */ lv_style_t *style_knob_off; /*Style of the knob when the switch is OFF*/ lv_style_t *style_knob_on; /*Style of the knob when the switch is ON (NULL to use the same as OFF)*/ + lv_coord_t start_x; uint8_t changed :1; /*Indicates the switch state explicitly changed by drag*/ + uint8_t slided :1; #if USE_LV_ANIMATION uint16_t anim_time; /*switch animation time */ #endif @@ -86,6 +88,18 @@ void lv_sw_on(lv_obj_t *sw); */ void lv_sw_off(lv_obj_t *sw); +/** + * Turn ON the switch with an animation + * @param sw pointer to a switch object + */ +void lv_sw_on_anim(lv_obj_t * sw); + +/** + * Turn OFF the switch with an animation + * @param sw pointer to a switch object + */ +void lv_sw_off_anim(lv_obj_t * sw); + /** * Set a function which will be called when the switch is toggled by the user * @param sw pointer to switch object From 699f40c9b28dacc4dfda7e35be7f1359b19057f2 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 20 Nov 2018 14:49:16 +0100 Subject: [PATCH 16/17] lv_anim: add overshoot path --- lv_misc/lv_anim.c | 24 ++++++++++++++++++++++++ lv_misc/lv_anim.h | 7 +++++++ 2 files changed, 31 insertions(+) diff --git a/lv_misc/lv_anim.c b/lv_misc/lv_anim.c index ca0d4b63d..fd7aa6878 100644 --- a/lv_misc/lv_anim.c +++ b/lv_misc/lv_anim.c @@ -196,6 +196,30 @@ int32_t lv_anim_path_ease_in_out(const lv_anim_t * a) return new_value; } +/** + * Calculate the current value of an animation with overshoot at the end + * @param a pointer to an animation + * @return the current value to set + */ +int32_t lv_anim_path_overshoot(const lv_anim_t * a) +{ + /*Calculate the current step*/ + + uint32_t t; + if(a->time == a->act_time) t = 1024; + else t = (uint32_t)((uint32_t)a->act_time * 1024) / a->time; + + int32_t step = lv_bezier3(t, 0, 600, 1300, 1024); + + int32_t new_value; + new_value = (int32_t) step * (a->end - a->start); + new_value = new_value >> 10; + new_value += a->start; + + + return new_value; +} + /** * Calculate the current value of an animation applying step characteristic. * (Set end value on the end of the animation) diff --git a/lv_misc/lv_anim.h b/lv_misc/lv_anim.h index aaf1c6bff..71ffa930f 100644 --- a/lv_misc/lv_anim.h +++ b/lv_misc/lv_anim.h @@ -129,6 +129,13 @@ int32_t lv_anim_path_linear(const lv_anim_t *a); */ int32_t lv_anim_path_ease_in_out(const lv_anim_t *a); +/** + * Calculate the current value of an animation with overshoot at the end + * @param a pointer to an animation + * @return the current value to set + */ +int32_t lv_anim_path_overshoot(const lv_anim_t * a); + /** * Calculate the current value of an animation applying step characteristic. * (Set end value on the end of the animation) From c5845869857b8edda207d31a47d8a6e3bf0d3d41 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 21 Nov 2018 14:00:19 +0100 Subject: [PATCH 17/17] lv_refr/draw: enable the drawing even with body.opa == LV_OPA_TRANSP E.g. labels don't care with body paramters --- lv_core/lv_refr.c | 12 +++++------- lv_draw/lv_draw_rect.c | 4 ++-- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/lv_core/lv_refr.c b/lv_core/lv_refr.c index 93a81c34c..766c6e2e9 100644 --- a/lv_core/lv_refr.c +++ b/lv_core/lv_refr.c @@ -515,10 +515,9 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p) /* Redraw the object */ lv_style_t * style = lv_obj_get_style(obj); - if(style->body.opa != LV_OPA_TRANSP) { - obj->design_func(obj, &obj_ext_mask, LV_DESIGN_DRAW_MAIN); - //tick_wait_ms(100); /*DEBUG: Wait after every object draw to see the order of drawing*/ - } + obj->design_func(obj, &obj_ext_mask, LV_DESIGN_DRAW_MAIN); + //tick_wait_ms(100); /*DEBUG: Wait after every object draw to see the order of drawing*/ + /*Create a new 'obj_mask' without 'ext_size' because the children can't be visible there*/ lv_obj_get_coords(obj, &obj_area); @@ -547,8 +546,7 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p) } /* If all the children are redrawn make 'post draw' design */ - if(style->body.opa != LV_OPA_TRANSP) { - obj->design_func(obj, &obj_ext_mask, LV_DESIGN_DRAW_POST); - } + obj->design_func(obj, &obj_ext_mask, LV_DESIGN_DRAW_POST); + } } diff --git a/lv_draw/lv_draw_rect.c b/lv_draw/lv_draw_rect.c index b62ccab51..5b4ef1665 100644 --- a/lv_draw/lv_draw_rect.c +++ b/lv_draw/lv_draw_rect.c @@ -71,7 +71,7 @@ void lv_draw_rect(const lv_area_t * coords, const lv_area_t * mask, const lv_sty lv_draw_shadow(coords, mask, style, opa_scale); } #endif - if(style->body.empty == 0) { + if(style->body.empty == 0 && style->body.opa >= LV_OPA_MIN) { lv_draw_rect_main_mid(coords, mask, style, opa_scale); if(style->body.radius != 0) { @@ -79,7 +79,7 @@ void lv_draw_rect(const lv_area_t * coords, const lv_area_t * mask, const lv_sty } } - if(style->body.border.width != 0 && style->body.border.part != LV_BORDER_NONE) { + if(style->body.border.width != 0 && style->body.border.part != LV_BORDER_NONE && style->body.border.opa >= LV_OPA_MIN) { lv_draw_rect_border_straight(coords, mask, style, opa_scale); if(style->body.radius != 0) {