diff --git a/src/lv_objx/lv_slider.c b/src/lv_objx/lv_slider.c index a7fb4333b..6a067f841 100644 --- a/src/lv_objx/lv_slider.c +++ b/src/lv_objx/lv_slider.c @@ -316,6 +316,8 @@ static bool lv_slider_design(lv_obj_t * slider, const lv_area_t * mask, lv_desig /*If dragged draw to the drag position*/ if(ext->drag_value != LV_SLIDER_NOT_PRESSED) cur_value = ext->drag_value; + bool sym = false; + if(ext->bar.sym && ext->bar.min_value < 0 && ext->bar.max_value > 0) sym = true; if(slider_w >= slider_h) { lv_coord_t indic_w = lv_area_get_width(&area_indic); @@ -335,7 +337,19 @@ static bool lv_slider_design(lv_obj_t * slider, const lv_area_t * mask, lv_desig { area_indic.x2 = (int32_t)((int32_t)indic_w * (cur_value - min_value)) / (max_value - min_value); } + area_indic.x2 = area_indic.x1 + area_indic.x2 - 1; + if(sym) { + /*Calculate the coordinate of the zero point*/ + lv_coord_t zero; + zero = area_indic.x1 + (-ext->bar.min_value * slider_w) / (ext->bar.max_value - ext->bar.min_value); + if(area_indic.x2 > zero) + area_indic.x1 = zero; + else { + area_indic.x1 = area_indic.x2; + area_indic.x2 = zero; + } + } /*Draw the indicator but don't draw an ugly 1px wide rectangle on the left on min. * value*/ @@ -359,8 +373,21 @@ 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(sym) { + /*Calculate the coordinate of the zero point*/ + lv_coord_t zero; + zero = area_indic.y2 - (-ext->bar.min_value * slider_h) / (ext->bar.max_value - ext->bar.min_value); + if(area_indic.y1 < zero) + area_indic.y2 = zero; + else { + area_indic.y2 = area_indic.y1; + area_indic.y1 = zero; + } + } + /*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); @@ -386,7 +413,12 @@ static bool lv_slider_design(lv_obj_t * slider, const lv_area_t * mask, lv_desig if(slider_w >= slider_h) { if(ext->knob_in == 0) { - knob_area.x1 = area_indic.x2 - slider_h / 2; + if(sym == false) { + knob_area.x1 = area_indic.x2 - slider_h / 2; + } else { + if(cur_value > 0) knob_area.x1 = area_indic.x2 - slider_h / 2; + else knob_area.x1 = area_indic.x1 - slider_h / 2; + } knob_area.x2 = knob_area.x1 + slider_h - 1; } else { #if LV_USE_ANIMATION @@ -415,7 +447,12 @@ static bool lv_slider_design(lv_obj_t * slider, const lv_area_t * mask, lv_desig knob_area.y2 = slider->coords.y2; } else { if(ext->knob_in == 0) { - knob_area.y1 = area_indic.y1 - slider_w / 2; + if(sym == false) { + knob_area.y1 = area_indic.y1 - slider_w / 2; + } else { + if(cur_value > 0) knob_area.y1 = area_indic.y1 - slider_w / 2; + else knob_area.y1 = area_indic.y2 - slider_w / 2; + } knob_area.y2 = knob_area.y1 + slider_w - 1; } else { #if LV_USE_ANIMATION diff --git a/src/lv_objx/lv_slider.h b/src/lv_objx/lv_slider.h index 07086efe4..967c8b688 100644 --- a/src/lv_objx/lv_slider.h +++ b/src/lv_objx/lv_slider.h @@ -93,15 +93,26 @@ static inline void lv_slider_set_range(lv_obj_t * slider, int16_t min, int16_t m } /** - * Set the animation time of the slider - * @param slider pointer to a bar object - * @param anim_time the animation time in milliseconds. + * Make the slider symmetric to zero. The indicator will grow from zero instead of the minimum + * position. + * @param slider pointer to a slider object + * @param en true: enable disable symmetric behavior; false: disable */ static inline void lv_slider_set_anim_time(lv_obj_t * slider, uint16_t anim_time) { lv_bar_set_anim_time(slider, anim_time); } +/** + * Set the animation time of the slider + * @param slider pointer to a bar object + * @param anim_time the animation time in milliseconds. + */ +static inline void lv_slider_set_sym(lv_obj_t * slider, bool en) +{ + lv_bar_set_sym(slider, en); +} + /** * Set the 'knob in' attribute of a slider * @param slider pointer to slider object @@ -156,6 +167,26 @@ static inline int16_t lv_slider_get_max_value(const lv_obj_t * slider) */ bool lv_slider_is_dragged(const lv_obj_t * slider); +/** + * Get the animation time of the slider + * @param slider pointer to a slider object + * @return the animation time in milliseconds. + */ +static inline uint16_t lv_slider_get_anim_time(lv_obj_t * slider) +{ + return lv_bar_get_anim_time(slider); +} + +/** + * Get whether the slider is symmetric or not. + * @param slider pointer to a bar object + * @return true: symmetric is enabled; false: disable + */ +static inline bool lv_slider_get_sym(lv_obj_t * slider) +{ + return lv_bar_get_sym(slider); +} + /** * Get the 'knob in' attribute of a slider * @param slider pointer to slider object