diff --git a/lv_objx/lv_bar.c b/lv_objx/lv_bar.c index fa95e726e..f40c7f87e 100644 --- a/lv_objx/lv_bar.c +++ b/lv_objx/lv_bar.c @@ -73,6 +73,7 @@ lv_obj_t * lv_bar_create(lv_obj_t * par, const lv_obj_t * copy) ext->min_value = 0; ext->max_value = 100; ext->cur_value = 0; + ext->anim_time = 500; ext->anim_start = 0; ext->anim_end = 0; ext->anim_state = LV_BAR_ANIM_STATE_INV; @@ -86,7 +87,7 @@ lv_obj_t * lv_bar_create(lv_obj_t * par, const lv_obj_t * copy) if(copy == NULL) { lv_obj_set_click(new_bar, false); lv_obj_set_size(new_bar, LV_DPI * 2, LV_DPI / 3); - lv_bar_set_value(new_bar, ext->cur_value); + lv_bar_set_value(new_bar, ext->cur_value, false); lv_theme_t * th = lv_theme_get_current(); if(th) { @@ -105,7 +106,7 @@ lv_obj_t * lv_bar_create(lv_obj_t * par, const lv_obj_t * copy) /*Refresh the style with new signal function*/ lv_obj_refresh_style(new_bar); - lv_bar_set_value(new_bar, ext->cur_value); + lv_bar_set_value(new_bar, ext->cur_value, false); } LV_LOG_INFO("bar created"); @@ -121,26 +122,13 @@ lv_obj_t * lv_bar_create(lv_obj_t * par, const lv_obj_t * copy) * Set a new value on the bar * @param bar pointer to a bar object * @param value new value + * @param anim true: set the value with an animation; false: change the value immediatelly */ -void lv_bar_set_value(lv_obj_t * bar, int16_t value) -{ - lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar); - if(ext->cur_value == value) return; - - ext->cur_value = value > ext->max_value ? ext->max_value : value; - ext->cur_value = ext->cur_value < ext->min_value ? ext->min_value : ext->cur_value; - lv_obj_invalidate(bar); -} - -#if USE_LV_ANIMATION -/** - * Set a new value with animation on the bar - * @param bar pointer to a bar object - * @param value new value - * @param anim_time animation time in milliseconds - */ -void lv_bar_set_value_anim(lv_obj_t * bar, int16_t value, uint16_t anim_time) +void lv_bar_set_value(lv_obj_t * bar, int16_t value, bool anim) { +#if USE_LV_ANIMATION == 0 + anim = false; +#endif lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar); if(ext->cur_value == value) return; @@ -150,34 +138,40 @@ void lv_bar_set_value_anim(lv_obj_t * bar, int16_t value, uint16_t anim_time) if(ext->cur_value == new_value) return; - /*NO animation in progress -> simply set the values*/ - if(ext->anim_state == LV_BAR_ANIM_STATE_INV) { - ext->anim_start = ext->cur_value; - ext->anim_end = new_value; - } - /*Animation in progress. Start from the animation end value*/ - else { - ext->anim_start = ext->anim_end; - ext->anim_end = new_value; - } + if(anim == false) { + ext->cur_value = new_value; + lv_obj_invalidate(bar); + } else { +#if USE_LV_ANIMATION + /*No animation in progress -> simply set the values*/ + if(ext->anim_state == LV_BAR_ANIM_STATE_INV) { + ext->anim_start = ext->cur_value; + ext->anim_end = new_value; + } + /*Animation in progress. Start from the animation end value*/ + else { + ext->anim_start = ext->anim_end; + ext->anim_end = new_value; + } - lv_anim_t a; - a.var = bar; - a.start = LV_BAR_ANIM_STATE_START; - a.end = LV_BAR_ANIM_STATE_END; - a.fp = (lv_anim_fp_t)lv_bar_animate; - a.path = lv_anim_path_linear; - a.end_cb = lv_bar_anim_ready; - a.act_time = 0; - a.time = anim_time; - a.playback = 0; - a.playback_pause = 0; - a.repeat = 0; - a.repeat_pause = 0; + lv_anim_t a; + a.var = bar; + a.start = LV_BAR_ANIM_STATE_START; + a.end = LV_BAR_ANIM_STATE_END; + a.fp = (lv_anim_fp_t)lv_bar_animate; + a.path = lv_anim_path_linear; + a.end_cb = lv_bar_anim_ready; + a.act_time = 0; + a.time = ext->anim_time; + a.playback = 0; + a.playback_pause = 0; + a.repeat = 0; + a.repeat_pause = 0; - lv_anim_create(&a); -} + lv_anim_create(&a); #endif + } +} /** @@ -195,11 +189,11 @@ void lv_bar_set_range(lv_obj_t * bar, int16_t min, int16_t max) ext->min_value = min; if(ext->cur_value > max) { ext->cur_value = max; - lv_bar_set_value(bar, ext->cur_value); + lv_bar_set_value(bar, ext->cur_value, false); } if(ext->cur_value < min) { ext->cur_value = min; - lv_bar_set_value(bar, ext->cur_value); + lv_bar_set_value(bar, ext->cur_value, false); } lv_obj_invalidate(bar); } @@ -478,7 +472,7 @@ static void lv_bar_anim_ready(void * bar) { lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar); ext->anim_state = LV_BAR_ANIM_STATE_INV; - lv_bar_set_value(bar, ext->anim_end); + lv_bar_set_value(bar, ext->anim_end, false); } diff --git a/lv_objx/lv_bar.h b/lv_objx/lv_bar.h index 8ef3c4de0..0501f4cf3 100644 --- a/lv_objx/lv_bar.h +++ b/lv_objx/lv_bar.h @@ -49,6 +49,7 @@ typedef struct int16_t anim_start; int16_t anim_end; int16_t anim_state; + uint16_t anim_time; uint8_t sym :1; /*Symmetric: means the center is around zero value*/ lv_style_t *style_indic; /*Style of the indicator*/ } lv_bar_ext_t; @@ -79,17 +80,9 @@ lv_obj_t * lv_bar_create(lv_obj_t * par, const lv_obj_t * copy); * Set a new value on the bar * @param bar pointer to a bar object * @param value new value + * @param anim true: set the value with an animation; false: change the value immediatelly */ -void lv_bar_set_value(lv_obj_t * bar, int16_t value); - -/** - * Set a new value with animation on the bar - * @param bar pointer to a bar object - * @param value new value - * @param anim_time animation time in milliseconds - */ -void lv_bar_set_value_anim(lv_obj_t * bar, int16_t value, uint16_t anim_time); - +void lv_bar_set_value(lv_obj_t * bar, int16_t value, bool anim); /** * Set minimum and the maximum values of a bar diff --git a/lv_objx/lv_page.c b/lv_objx/lv_page.c index 8b2f602d8..536ef67b4 100644 --- a/lv_objx/lv_page.c +++ b/lv_objx/lv_page.c @@ -464,6 +464,7 @@ void lv_page_focus(lv_obj_t * page, const lv_obj_t * obj, uint16_t anim_time) lv_style_t * style = lv_page_get_style(page, LV_PAGE_STYLE_BG); lv_style_t * style_scrl = lv_page_get_style(page, LV_PAGE_STYLE_SCRL); + /*If obj is higher then the page focus where the "error" is smaller*/ lv_coord_t obj_y = obj->coords.y1 - ext->scrl->coords.y1; lv_coord_t obj_h = lv_obj_get_height(obj); lv_coord_t scrlable_y = lv_obj_get_y(ext->scrl); @@ -472,8 +473,6 @@ void lv_page_focus(lv_obj_t * page, const lv_obj_t * obj, uint16_t anim_time) lv_coord_t top_err = -(scrlable_y + obj_y); lv_coord_t bot_err = scrlable_y + obj_y + obj_h - page_h; - /*If obj is higher then the page focus where the "error" is smaller*/ - /*Out of the page on the top*/ if((obj_h <= page_h && top_err > 0) || (obj_h > page_h && top_err < bot_err)) { @@ -488,13 +487,36 @@ void lv_page_focus(lv_obj_t * page, const lv_obj_t * obj, uint16_t anim_time) scrlable_y = -(obj_y + style_scrl->body.padding.ver + style->body.padding.ver); scrlable_y -= style_scrl->body.padding.ver; scrlable_y += page_h - obj_h; - } else { - /*Already in focus*/ - return; + } + + /*If obj is wider then the page focus where the "error" is smaller*/ + lv_coord_t obj_x = obj->coords.x1 - ext->scrl->coords.x1; + lv_coord_t obj_w = lv_obj_get_width(obj); + lv_coord_t scrlable_x = lv_obj_get_x(ext->scrl); + lv_coord_t page_w = lv_obj_get_width(page); + + lv_coord_t left_err = -(scrlable_x + obj_x); + lv_coord_t right_err = scrlable_x + obj_x + obj_w - page_w; + + /*Out of the page on the top*/ + if((obj_w <= page_w && left_err > 0) || + (obj_w > page_w && left_err < right_err)) { + /*Calculate a new position and let some space above*/ + scrlable_x = -(obj_x - style_scrl->body.padding.hor- style->body.padding.hor); + scrlable_x += style_scrl->body.padding.hor; + } + /*Out of the page on the bottom*/ + else if((obj_w <= page_w && right_err > 0) || + (obj_w > page_w && left_err >= right_err)) { + /*Calculate a new position and let some space below*/ + scrlable_x = -(obj_x + style_scrl->body.padding.hor + style->body.padding.hor); + scrlable_x -= style_scrl->body.padding.hor; + scrlable_x += page_w - obj_w; } if(anim_time == 0) { lv_obj_set_y(ext->scrl, scrlable_y); + lv_obj_set_x(ext->scrl, scrlable_x); #if USE_LV_ANIMATION } else { lv_anim_t a; @@ -509,6 +531,11 @@ void lv_page_focus(lv_obj_t * page, const lv_obj_t * obj, uint16_t anim_time) a.path = lv_anim_path_linear; a.fp = (lv_anim_fp_t) lv_obj_set_y; lv_anim_create(&a); + + a.start = lv_obj_get_x(ext->scrl); + a.end = scrlable_x; + a.fp = (lv_anim_fp_t) lv_obj_set_x; + lv_anim_create(&a); #endif } } diff --git a/lv_objx/lv_slider.c b/lv_objx/lv_slider.c index 29cd422af..c47742d28 100644 --- a/lv_objx/lv_slider.c +++ b/lv_objx/lv_slider.c @@ -338,7 +338,6 @@ static bool lv_slider_design(lv_obj_t * slider, const lv_area_t * mask, lv_desig area_indic.y1 += pad_ver_indic; area_indic.y2 -= pad_ver_indic; - lv_coord_t cur_value = lv_slider_get_value(slider); lv_coord_t min_value = lv_slider_get_min_value(slider); lv_coord_t max_value = lv_slider_get_max_value(slider); @@ -360,6 +359,9 @@ static bool lv_slider_design(lv_obj_t * slider, const lv_area_t * mask, lv_desig } area_indic.x2 = area_indic.x1 + area_indic.x2 - 1; + /*Draw the indicator but don't draw an ugly 1px wide rectangle on the left on min. value*/ + if(area_indic.x1 != area_indic.x2) lv_draw_rect(&area_indic, mask, style_indic, opa_scale); + } else { lv_coord_t indic_h = lv_area_get_height(&area_indic); if(ext->bar.anim_state != LV_BAR_ANIM_STATE_INV) { @@ -373,9 +375,10 @@ static bool lv_slider_design(lv_obj_t * slider, const lv_area_t * mask, lv_desig area_indic.y1 = (int32_t)((int32_t)indic_h * (cur_value - min_value)) / (max_value - min_value); } area_indic.y1 = area_indic.y2 - area_indic.y1 + 1; - } - if(cur_value != min_value) lv_draw_rect(&area_indic, mask, style_indic, opa_scale); + /*Draw the indicator but don't draw an ugly 1px height rectangle on the bottom on min. value*/ + if(area_indic.x1 != area_indic.x2) lv_draw_rect(&area_indic, mask, style_indic, opa_scale); + } /*Before the knob add the border if required*/ #if USE_LV_GROUP @@ -399,7 +402,17 @@ static bool lv_slider_design(lv_obj_t * slider, const lv_area_t * mask, lv_desig knob_area.x1 = area_indic.x2 - slider_h / 2; knob_area.x2 = knob_area.x1 + slider_h - 1; } else { - knob_area.x1 = (int32_t)((int32_t)(slider_w - slider_h - 1) * (cur_value - min_value)) / (max_value - min_value); + if(ext->bar.anim_state != LV_BAR_ANIM_STATE_INV) { + lv_coord_t w = slider_w - slider_h - 1; + lv_coord_t anim_start_x = (int32_t)((int32_t)w * (ext->bar.anim_start - min_value)) / (max_value - min_value); + lv_coord_t anim_end_x = (int32_t)((int32_t)w * (ext->bar.anim_end - min_value)) / (max_value - min_value); + + /*Calculate the real position based on `anim_state` (between `anim_start` and `anim_end`)*/ + knob_area.x1 = anim_start_x + (((anim_end_x - anim_start_x) * ext->bar.anim_state) >> 8); + } else { + knob_area.x1 = (int32_t)((int32_t)(slider_w - slider_h - 1) * (cur_value - min_value)) / (max_value - min_value); + } + knob_area.x1 += slider->coords.x1; knob_area.x2 = knob_area.x1 + slider_h - 1; } @@ -411,7 +424,17 @@ static bool lv_slider_design(lv_obj_t * slider, const lv_area_t * mask, lv_desig knob_area.y1 = area_indic.y1 - slider_w / 2; knob_area.y2 = knob_area.y1 + slider_w - 1; } else { - knob_area.y2 = (int32_t)((int32_t)(slider_h - slider_w - 1) * (cur_value - min_value)) / (max_value - min_value); + if(ext->bar.anim_state != LV_BAR_ANIM_STATE_INV) { + lv_coord_t h = slider_h - slider_w - 1; + lv_coord_t anim_start_x = (int32_t)((int32_t)h * (ext->bar.anim_start - min_value)) / (max_value - min_value); + lv_coord_t anim_end_x = (int32_t)((int32_t)h * (ext->bar.anim_end - min_value)) / (max_value - min_value); + + /*Calculate the real position based on `anim_state` (between `anim_start` and `anim_end`)*/ + knob_area.y2 = anim_start_x + (((anim_end_x - anim_start_x) * ext->bar.anim_state) >> 8); + } else { + knob_area.y2 = (int32_t)((int32_t)(slider_h - slider_w - 1) * (cur_value - min_value)) / (max_value - min_value); + } + knob_area.y2 = slider->coords.y2 - knob_area.y2; knob_area.y1 = knob_area.y2 - slider_w - 1; } @@ -475,7 +498,7 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par if(ext->action != NULL) res = ext->action(slider); } } else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) { - lv_slider_set_value(slider, ext->drag_value); + lv_slider_set_value(slider, ext->drag_value, false); ext->drag_value = LV_SLIDER_NOT_PRESSED; if(ext->action != NULL) res = ext->action(slider); } else if(sign == LV_SIGNAL_CORD_CHG) { @@ -515,10 +538,10 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par } #endif if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) { - lv_slider_set_value_anim(slider, lv_slider_get_value(slider) + 1, 200); + lv_slider_set_value(slider, lv_slider_get_value(slider) + 1, true); if(ext->action != NULL) res = ext->action(slider); } else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) { - lv_slider_set_value_anim(slider, lv_slider_get_value(slider) - 1, 200); + lv_slider_set_value(slider, lv_slider_get_value(slider) - 1, true); if(ext->action != NULL) res = ext->action(slider); } } else if(sign == LV_SIGNAL_GET_EDITABLE) { diff --git a/lv_objx/lv_slider.h b/lv_objx/lv_slider.h index 6336ae8a8..532e2f5fa 100644 --- a/lv_objx/lv_slider.h +++ b/lv_objx/lv_slider.h @@ -41,9 +41,9 @@ typedef struct { lv_bar_ext_t bar; /*Ext. of ancestor*/ /*New data for this type */ - lv_action_t action; /*Function to call when a new value is set*/ - lv_style_t *style_knob; /*Style of the knob*/ - int16_t drag_value; /*Store a temporal value during press until release (Handled by the library)*/ + lv_action_t action; /*Function to call when a new value is set*/ + lv_style_t *style_knob; /*Style of the knob*/ + int16_t drag_value; /*Store a temporal value during press until release (Handled by the library)*/ uint8_t knob_in :1; /*1: Draw the knob inside the bar*/ } lv_slider_ext_t; @@ -76,21 +76,11 @@ lv_obj_t * lv_slider_create(lv_obj_t * par, const lv_obj_t * copy); * Set a new value on the slider * @param slider pointer to a slider object * @param value new value + * @param anim true: set the value with an animation; false: change the value immediatelly */ -static inline void lv_slider_set_value(lv_obj_t * slider, int16_t value) +static inline void lv_slider_set_value(lv_obj_t * slider, int16_t value, bool anim) { - lv_bar_set_value(slider, value); -} - -/** - * Set a new value with animation on a slider - * @param slider pointer to a slider object - * @param value new value - * @param anim_time animation time in milliseconds - */ -static inline void lv_slider_set_value_anim(lv_obj_t * slider, int16_t value, uint16_t anim_time) -{ - lv_bar_set_value_anim(slider, value, anim_time); + lv_bar_set_value(slider, value, anim); } /** diff --git a/lv_objx/lv_sw.c b/lv_objx/lv_sw.c index 35fe47674..34176edb4 100644 --- a/lv_objx/lv_sw.c +++ b/lv_objx/lv_sw.c @@ -30,7 +30,6 @@ * 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 @@ -80,10 +79,9 @@ lv_obj_t * lv_sw_create(lv_obj_t * par, const lv_obj_t * copy) /*Init the new switch switch*/ if(copy == NULL) { - lv_slider_set_range(new_sw, 0, 1); - lv_obj_set_size(new_sw, 2 * LV_DPI / 3, LV_DPI / 3); + 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); + lv_slider_set_range(new_sw, 0, LV_SW_MAX_VALUE); /*Set the default styles*/ lv_theme_t * th = lv_theme_get_current(); @@ -125,83 +123,50 @@ lv_obj_t * lv_sw_create(lv_obj_t * par, const lv_obj_t * copy) /** * Turn ON the switch - * @param sw pointer to a switch object + * @param sw pointer to a switch objec + * @param anim true: set the value with an animation; false: change the value immediatelly */ -void lv_sw_on(lv_obj_t * sw) +void lv_sw_on(lv_obj_t * sw, bool anim) { +#if USE_LV_ANIMATION == 0 + anim = false; +#endif lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); - lv_slider_set_value(sw, LV_SWITCH_SLIDER_ANIM_MAX); - + lv_slider_set_value(sw, LV_SW_MAX_VALUE, anim); lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on); } /** * Turn OFF the switch * @param sw pointer to a switch object + * @param anim true: set the value with an animation; false: change the value immediatelly */ -void lv_sw_off(lv_obj_t * sw) +void lv_sw_off(lv_obj_t * sw, bool anim) { +#if USE_LV_ANIMATION == 0 + anim = false; +#endif lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); - lv_slider_set_value(sw, 0); - + lv_slider_set_value(sw, 0, anim); lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off); } /** * Toggle the position of the switch * @param sw pointer to a switch object + * @param anim true: set the value with an animation; false: change the value immediatelly * @return resulting state of the switch. */ -bool lv_sw_toggle(lv_obj_t *sw) { - bool state = lv_sw_get_state(sw); - if(state) { - lv_sw_off(sw); - } - else { - lv_sw_on(sw); - } - return !state; -} - -/** - * Turn ON the switch with an animation - * @param sw pointer to a switch object - */ -void lv_sw_on_anim(lv_obj_t * sw) +bool lv_sw_toggle(lv_obj_t *sw, bool anim) { - 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); +#if USE_LV_ANIMATION == 0 + anim = false; +#endif - 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); - else lv_slider_set_value(sw, 0); - - lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off); -} - -/** - * Toggle the position of the switch with an animation - * @param sw pointer to a switch object - * @return resulting state of the switch. - */ -bool lv_sw_toggle_anim(lv_obj_t *sw) { bool state = lv_sw_get_state(sw); - if(state) { - lv_sw_off_anim(sw); - } - else { - lv_sw_on_anim(sw); - } + if(state) lv_sw_off(sw, anim); + else lv_sw_on(sw, anim); + return !state; } @@ -304,18 +269,18 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) { lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); - /*Save the current (old) value before slider signal modifies it*/ + /*Save the current (old) value before slider signal modifies it. It will be required in the later colcualtions*/ int16_t old_val; - if(sign == LV_SIGNAL_PRESSING) old_val = ext->slider.drag_value; else old_val = lv_slider_get_value(sw); - /*Do not let the slider to call the callback. The Switch will do it if required*/ - lv_action_t slider_action = ext->slider.action; + /*Don't let the slider to call the action. Switch handles it differently*/ + lv_action_t action = ext->slider.action; ext->slider.action = NULL; lv_res_t res; /* Include the ancient signal function */ + res = ancestor_signal(sw, sign, param); if(res != LV_RES_OK) return res; @@ -335,7 +300,7 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) ext->changed = 0; } else if(sign == LV_SIGNAL_PRESSING) { - /*See if the switch was slid*/ + /*See if the switch was slid (moved at least a little)*/ lv_indev_t * indev = lv_indev_get_act(); if(indev) { lv_point_t p = {0,0}; @@ -345,12 +310,12 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) /*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; + if(lv_sw_get_state(sw)) ext->slider.drag_value = LV_SW_MAX_VALUE; 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; + int16_t threshold = LV_SW_MAX_VALUE / 2; if((old_val < threshold && ext->slider.drag_value > threshold) || (old_val > threshold && ext->slider.drag_value < threshold)) { @@ -360,48 +325,34 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) 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); -#if USE_LV_ANIMATION - lv_sw_anim_to_value(sw, LV_SWITCH_SLIDER_ANIM_MAX); -#endif + lv_slider_set_value(sw, LV_SW_MAX_VALUE, true); } else { lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off); -#if USE_LV_ANIMATION - lv_sw_anim_to_value(sw, 0); -#endif + lv_slider_set_value(sw, 0, true); } } 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_anim(sw); - else lv_sw_on_anim(sw); - - if(slider_action != NULL) res = slider_action(sw); + if(lv_sw_get_state(sw)) lv_sw_off(sw, true); + else lv_sw_on(sw, true); } /*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_anim(sw); - else lv_sw_off_anim(sw); - - if(slider_action != NULL) res = slider_action(sw); + if(v > LV_SW_MAX_VALUE / 2) lv_sw_on(sw, true); + else lv_sw_off(sw, true); } - } else if(sign == LV_SIGNAL_CONTROLL) { - char c = *((char *)param); if(c == LV_GROUP_KEY_ENTER) { - 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_anim(sw); - if(slider_action) res = slider_action(sw); - } else if(c == LV_GROUP_KEY_DOWN || c == LV_GROUP_KEY_LEFT) { - lv_sw_off_anim(sw); - if(slider_action) res = slider_action(sw); + if(old_val) lv_sw_off(sw, true); + else lv_sw_on(sw, true); + } else if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) { + lv_slider_set_value(sw, LV_SW_MAX_VALUE, true); + } else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) { + lv_slider_set_value(sw, 0, true); } } else if(sign == LV_SIGNAL_GET_EDITABLE) { bool * editable = (bool *)param; @@ -415,31 +366,10 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) buf->type[i] = "lv_sw"; } - /*Restore the callback*/ - if(res == LV_RES_OK) ext->slider.action = slider_action; + /*Revert the action*/ + ext->slider.action = action; return res; } -static void lv_sw_anim_to_value(lv_obj_t * sw, int16_t value) -{ -#if USE_LV_ANIMATION - 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 -} - #endif diff --git a/lv_objx/lv_sw.h b/lv_objx/lv_sw.h index 28b22f739..cc7e16643 100644 --- a/lv_objx/lv_sw.h +++ b/lv_objx/lv_sw.h @@ -32,7 +32,7 @@ extern "C" { /********************* * DEFINES *********************/ -#define LV_SWITCH_SLIDER_ANIM_MAX 1000 +#define LV_SW_MAX_VALUE 100 /********************** * TYPEDEFS @@ -79,40 +79,24 @@ lv_obj_t * lv_sw_create(lv_obj_t * par, const lv_obj_t * copy); /** * Turn ON the switch * @param sw pointer to a switch object + * @param anim true: set the value with an animation; false: change the value immediatelly */ -void lv_sw_on(lv_obj_t *sw); +void lv_sw_on(lv_obj_t *sw, bool anim); /** * Turn OFF the switch * @param sw pointer to a switch object + * @param anim true: set the value with an animation; false: change the value immediatelly */ -void lv_sw_off(lv_obj_t *sw); +void lv_sw_off(lv_obj_t *sw, bool anim); /** * Toggle the position of the switch * @param sw pointer to a switch object + * @param anim true: set the value with an animation; false: change the value immediatelly * @return resulting state of the switch. */ -bool lv_sw_toggle(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); - -/** - * Toggle the position of the switch with an animation - * @param sw pointer to a switch object - * @return resulting state of the switch. - */ -bool lv_sw_toggle_anim(lv_obj_t *sw); +bool lv_sw_toggle(lv_obj_t *sw, bool anim); /** * Set a function which will be called when the switch is toggled by the user @@ -153,7 +137,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) < LV_SWITCH_SLIDER_ANIM_MAX / 2 ? false : true; + return lv_bar_get_value(sw) < LV_SW_MAX_VALUE / 2 ? false : true; } /**