mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-28 07:03:00 +08:00
feat(bar): reverse drawing direction of lv_bar if min > max (#4654)
Signed-off-by: wangxuedong <wangxuedong@xiaomi.com>
This commit is contained in:
parent
c0356c9380
commit
8f57f12a44
@ -33,7 +33,9 @@ A new value can be set by
|
||||
``lv_bar_set_value(bar, new_value, LV_ANIM_ON/OFF)``. The value is
|
||||
interpreted in a range (minimum and maximum values) which can be
|
||||
modified with :cpp:expr:`lv_bar_set_range(bar, min, max)`. The default range is
|
||||
0..100.
|
||||
0..100, and the default drawing direction is from left to right in horizontal mode and
|
||||
bottom to top in vertical mode. If the minimum value is greater than the maximum value, like
|
||||
100..0, the drawing direction changes to the opposite direction.
|
||||
|
||||
The new value in :cpp:func:`lv_bar_set_value` can be set with or without an
|
||||
animation depending on the last parameter (``LV_ANIM_ON/OFF``).
|
||||
|
@ -35,6 +35,9 @@ To set an initial value use :cpp:expr:`lv_slider_set_value(slider, new_value, LV
|
||||
animation time is set by the styles' ``anim_time`` property.
|
||||
|
||||
To specify the range (min, max values), :cpp:expr:`lv_slider_set_range(slider, min , max)` can be used.
|
||||
The default range is 0..100, and the default drawing direction is from left to right in horizontal mode and
|
||||
bottom to top in vertical mode. If the minimum value is greater than the maximum value, like
|
||||
100..0, the drawing direction changes to the opposite direction.
|
||||
|
||||
Modes
|
||||
-----
|
||||
|
@ -34,3 +34,9 @@ Custom drawer to show the current value
|
||||
.. lv_example:: widgets/bar/lv_example_bar_6
|
||||
:language: c
|
||||
|
||||
Bar with opposite direction
|
||||
---------------------------
|
||||
|
||||
.. lv_example:: widgets/bar/lv_example_bar_7
|
||||
:language: c
|
||||
|
||||
|
23
examples/widgets/bar/lv_example_bar_7.c
Normal file
23
examples/widgets/bar/lv_example_bar_7.c
Normal file
@ -0,0 +1,23 @@
|
||||
#include "../../lv_examples.h"
|
||||
#if LV_USE_BAR && LV_BUILD_EXAMPLES
|
||||
|
||||
/**
|
||||
* Bar with opposite direction
|
||||
*/
|
||||
void lv_example_bar_7(void)
|
||||
{
|
||||
lv_obj_t * label;
|
||||
|
||||
|
||||
lv_obj_t * bar_tob = lv_bar_create(lv_scr_act());
|
||||
lv_obj_set_size(bar_tob, 20, 200);
|
||||
lv_bar_set_range(bar_tob, 100, 0);
|
||||
lv_bar_set_value(bar_tob, 70, LV_ANIM_OFF);
|
||||
lv_obj_align(bar_tob, LV_ALIGN_CENTER, 0, -30);
|
||||
|
||||
label = lv_label_create(lv_scr_act());
|
||||
lv_label_set_text(label, "From top to bottom");
|
||||
lv_obj_align_to(label, bar_tob, LV_ALIGN_OUT_TOP_MID, 0, -5);
|
||||
}
|
||||
|
||||
#endif
|
1
examples/widgets/bar/lv_example_bar_7.py
Normal file
1
examples/widgets/bar/lv_example_bar_7.py
Normal file
@ -0,0 +1 @@
|
||||
pass
|
@ -36,6 +36,7 @@ void lv_example_bar_3(void);
|
||||
void lv_example_bar_4(void);
|
||||
void lv_example_bar_5(void);
|
||||
void lv_example_bar_6(void);
|
||||
void lv_example_bar_7(void);
|
||||
|
||||
void lv_example_button_1(void);
|
||||
void lv_example_button_2(void);
|
||||
@ -118,6 +119,7 @@ void lv_example_scale_5(void);
|
||||
void lv_example_slider_1(void);
|
||||
void lv_example_slider_2(void);
|
||||
void lv_example_slider_3(void);
|
||||
void lv_example_slider_4(void);
|
||||
|
||||
void lv_example_span_1(void);
|
||||
|
||||
|
@ -17,4 +17,8 @@ Slider with extended drawer
|
||||
.. lv_example:: widgets/slider/lv_example_slider_3
|
||||
:language: c
|
||||
|
||||
Slider with opposite direction
|
||||
------------------------------
|
||||
|
||||
.. lv_example:: widgets/slider/lv_example_slider_4
|
||||
:language: c
|
||||
|
34
examples/widgets/slider/lv_example_slider_4.c
Normal file
34
examples/widgets/slider/lv_example_slider_4.c
Normal file
@ -0,0 +1,34 @@
|
||||
#include "../../lv_examples.h"
|
||||
#if LV_USE_SLIDER && LV_BUILD_EXAMPLES
|
||||
|
||||
static void slider_event_cb(lv_event_t * e);
|
||||
static lv_obj_t * slider_label;
|
||||
|
||||
/**
|
||||
* Slider with opposite direction
|
||||
*/
|
||||
void lv_example_slider_4(void)
|
||||
{
|
||||
/*Create a slider in the center of the display*/
|
||||
lv_obj_t * slider = lv_slider_create(lv_scr_act());
|
||||
lv_obj_center(slider);
|
||||
lv_obj_add_event(slider, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
/*Reverse the direction of the slider*/
|
||||
lv_slider_set_range(slider, 100, 0);
|
||||
/*Create a label below the slider*/
|
||||
slider_label = lv_label_create(lv_scr_act());
|
||||
lv_label_set_text(slider_label, "0%");
|
||||
|
||||
lv_obj_align_to(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
|
||||
}
|
||||
|
||||
static void slider_event_cb(lv_event_t * e)
|
||||
{
|
||||
lv_obj_t * slider = lv_event_get_target(e);
|
||||
char buf[8];
|
||||
lv_snprintf(buf, sizeof(buf), "%d%%", (int)lv_slider_get_value(slider));
|
||||
lv_label_set_text(slider_label, buf);
|
||||
lv_obj_align_to(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
|
||||
}
|
||||
|
||||
#endif
|
21
examples/widgets/slider/lv_example_slider_4.py
Normal file
21
examples/widgets/slider/lv_example_slider_4.py
Normal file
@ -0,0 +1,21 @@
|
||||
#
|
||||
# Slider with opposite direction
|
||||
#
|
||||
def slider_event_cb(e):
|
||||
|
||||
slider = e.get_target_obj()
|
||||
slider_label.set_text("{:d}%".format(slider.get_value()))
|
||||
slider_label.align_to(slider, lv.ALIGN.OUT_BOTTOM_MID, 0, 10)
|
||||
|
||||
# Create a slider in the center of the display
|
||||
slider = lv.slider(lv.screen_active())
|
||||
slider.center()
|
||||
slider.add_event(slider_event_cb, lv.EVENT.VALUE_CHANGED, None)
|
||||
slider.set_range(100, 0)
|
||||
|
||||
# Create a label below the slider
|
||||
slider_label = lv.label(lv.screen_active())
|
||||
slider_label.set_text("0%")
|
||||
|
||||
slider_label.align_to(slider, lv.ALIGN.OUT_BOTTOM_MID, 0, 10)
|
||||
|
@ -99,6 +99,7 @@ void lv_bar_set_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim)
|
||||
value = value < bar->start_value ? bar->start_value : value; /*Can't be smaller than the left value*/
|
||||
|
||||
if(bar->cur_value == value) return;
|
||||
|
||||
lv_bar_set_value_with_anim(obj, value, &bar->cur_value, &bar->cur_value_anim, anim);
|
||||
}
|
||||
|
||||
@ -116,6 +117,7 @@ void lv_bar_set_start_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim
|
||||
value = value > bar->cur_value ? bar->cur_value : value; /*Can't be greater than the right value*/
|
||||
|
||||
if(bar->start_value == value) return;
|
||||
|
||||
lv_bar_set_value_with_anim(obj, value, &bar->start_value, &bar->start_value_anim, anim);
|
||||
}
|
||||
|
||||
@ -125,27 +127,27 @@ void lv_bar_set_range(lv_obj_t * obj, int32_t min, int32_t max)
|
||||
|
||||
lv_bar_t * bar = (lv_bar_t *)obj;
|
||||
|
||||
if(max < min) {
|
||||
LV_LOG_WARN("error range: min = %" LV_PRId32 ", max = %" LV_PRId32, min, max);
|
||||
return;
|
||||
}
|
||||
bar->val_reversed = min > max;
|
||||
|
||||
if(bar->min_value == min && bar->max_value == max) return;
|
||||
int32_t real_min = bar->val_reversed ? max : min;
|
||||
int32_t real_max = bar->val_reversed ? min : max;
|
||||
if(bar->min_value == real_min && bar->max_value == real_max) return;
|
||||
|
||||
bar->max_value = max;
|
||||
bar->min_value = min;
|
||||
bar->max_value = real_max;
|
||||
bar->min_value = real_min;
|
||||
|
||||
if(lv_bar_get_mode(obj) != LV_BAR_MODE_RANGE)
|
||||
bar->start_value = min;
|
||||
bar->start_value = real_min;
|
||||
|
||||
if(bar->cur_value > max) {
|
||||
bar->cur_value = max;
|
||||
if(bar->cur_value > real_max) {
|
||||
bar->cur_value = real_max;
|
||||
lv_bar_set_value(obj, bar->cur_value, LV_ANIM_OFF);
|
||||
}
|
||||
if(bar->cur_value < min) {
|
||||
bar->cur_value = min;
|
||||
if(bar->cur_value < real_min) {
|
||||
bar->cur_value = real_min;
|
||||
lv_bar_set_value(obj, bar->cur_value, LV_ANIM_OFF);
|
||||
}
|
||||
|
||||
lv_obj_invalidate(obj);
|
||||
}
|
||||
|
||||
@ -188,7 +190,7 @@ int32_t lv_bar_get_min_value(const lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
lv_bar_t * bar = (lv_bar_t *)obj;
|
||||
return bar->min_value;
|
||||
return bar->val_reversed ? bar->max_value : bar->min_value;
|
||||
}
|
||||
|
||||
int32_t lv_bar_get_max_value(const lv_obj_t * obj)
|
||||
@ -196,7 +198,7 @@ int32_t lv_bar_get_max_value(const lv_obj_t * obj)
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
lv_bar_t * bar = (lv_bar_t *)obj;
|
||||
|
||||
return bar->max_value;
|
||||
return bar->val_reversed ? bar->min_value : bar->max_value;
|
||||
}
|
||||
|
||||
lv_bar_mode_t lv_bar_get_mode(lv_obj_t * obj)
|
||||
@ -207,6 +209,15 @@ lv_bar_mode_t lv_bar_get_mode(lv_obj_t * obj)
|
||||
return bar->mode;
|
||||
}
|
||||
|
||||
bool lv_bar_is_symmetrical(lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
lv_bar_t * bar = (lv_bar_t *)obj;
|
||||
|
||||
return bar->mode == LV_BAR_MODE_SYMMETRICAL && bar->min_value < 0 && bar->max_value > 0 &&
|
||||
bar->start_value == bar->min_value;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
@ -226,6 +237,7 @@ static void lv_bar_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
||||
bar->indic_area.y1 = 0;
|
||||
bar->indic_area.y2 = 0;
|
||||
bar->mode = LV_BAR_MODE_NORMAL;
|
||||
bar->val_reversed = false;
|
||||
|
||||
lv_bar_init_anim(obj, &bar->cur_value_anim);
|
||||
lv_bar_init_anim(obj, &bar->start_value_anim);
|
||||
@ -269,9 +281,7 @@ static void draw_indic(lv_event_t * e)
|
||||
}
|
||||
|
||||
bool hor = barw >= barh;
|
||||
bool sym = false;
|
||||
if(bar->mode == LV_BAR_MODE_SYMMETRICAL && bar->min_value < 0 && bar->max_value > 0 &&
|
||||
bar->start_value == bar->min_value) sym = true;
|
||||
bool sym = lv_bar_is_symmetrical(obj);
|
||||
|
||||
/*Calculate the indicator area*/
|
||||
lv_coord_t bg_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN);
|
||||
@ -345,8 +355,15 @@ static void draw_indic(lv_event_t * e)
|
||||
anim_cur_value_x = (int32_t)((int32_t)anim_length * (bar->cur_value - bar->min_value)) / range;
|
||||
}
|
||||
|
||||
/**
|
||||
* The drawing drection of the bar can be reversed only when one of the two conditions(value inversion
|
||||
* or horizontal direction base dir is LV_BASE_DIR_RTL) is met.
|
||||
*/
|
||||
lv_base_dir_t base_dir = lv_obj_get_style_base_dir(obj, LV_PART_MAIN);
|
||||
if(base_dir == LV_BASE_DIR_RTL) {
|
||||
bool hor_need_reversed = hor && base_dir == LV_BASE_DIR_RTL;
|
||||
bool reversed = bar->val_reversed ^ hor_need_reversed;
|
||||
|
||||
if(reversed) {
|
||||
/*Swap axes*/
|
||||
lv_coord_t * tmp;
|
||||
tmp = axis1;
|
||||
@ -365,31 +382,43 @@ static void draw_indic(lv_event_t * e)
|
||||
*axis1 = *axis2 - anim_cur_value_x + 1;
|
||||
*axis2 -= anim_start_value_x;
|
||||
}
|
||||
|
||||
if(sym) {
|
||||
lv_coord_t zero, shift;
|
||||
shift = (-bar->min_value * anim_length) / range;
|
||||
|
||||
if(hor) {
|
||||
lv_coord_t * left = reversed ? axis2 : axis1;
|
||||
lv_coord_t * right = reversed ? axis1 : axis2;
|
||||
if(reversed)
|
||||
zero = *axis1 - shift + 1;
|
||||
else
|
||||
zero = *axis1 + shift;
|
||||
if(*axis2 > zero)
|
||||
*axis1 = zero;
|
||||
|
||||
if(*axis2 > zero) {
|
||||
*right = *axis2;
|
||||
*left = zero;
|
||||
}
|
||||
else {
|
||||
*axis1 = *axis2;
|
||||
*axis2 = zero;
|
||||
*left = *axis2;
|
||||
*right = zero;
|
||||
}
|
||||
}
|
||||
else {
|
||||
lv_coord_t * top = reversed ? axis2 : axis1;
|
||||
lv_coord_t * bottom = reversed ? axis1 : axis2;
|
||||
if(reversed)
|
||||
zero = *axis2 + shift;
|
||||
else
|
||||
zero = *axis2 - shift + 1;
|
||||
if(*axis1 > zero)
|
||||
*axis2 = zero;
|
||||
else {
|
||||
*axis2 = *axis1;
|
||||
*axis1 = zero;
|
||||
|
||||
if(*axis1 > zero) {
|
||||
*bottom = *axis1;
|
||||
*top = zero;
|
||||
}
|
||||
if(*axis2 < *axis1) {
|
||||
/*swap*/
|
||||
zero = *axis1;
|
||||
*axis1 = *axis2;
|
||||
*axis2 = zero;
|
||||
else {
|
||||
*top = *axis1;
|
||||
*bottom = zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ typedef struct {
|
||||
int32_t max_value; /**< Maximum value of the bar*/
|
||||
int32_t start_value; /**< Start value of the bar*/
|
||||
lv_area_t indic_area; /**< Save the indicator area. Might be used by derived types*/
|
||||
bool val_reversed; /**< Whether value been reversed */
|
||||
_lv_bar_anim_t cur_value_anim;
|
||||
_lv_bar_anim_t start_value_anim;
|
||||
lv_bar_mode_t mode : 2; /**< Type of bar*/
|
||||
@ -99,6 +100,7 @@ void lv_bar_set_start_value(lv_obj_t * obj, int32_t start_value, lv_anim_enable_
|
||||
* @param obj pointer to the bar object
|
||||
* @param min minimum value
|
||||
* @param max maximum value
|
||||
* @note If min is greater than max, the drawing direction becomes to the oppsite direction.
|
||||
*/
|
||||
void lv_bar_set_range(lv_obj_t * obj, int32_t min, int32_t max);
|
||||
|
||||
@ -148,6 +150,13 @@ int32_t lv_bar_get_max_value(const lv_obj_t * obj);
|
||||
*/
|
||||
lv_bar_mode_t lv_bar_get_mode(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Give the bar is in symmetrical mode or not
|
||||
* @param obj pointer to bar object
|
||||
* @return true: in symmetrical mode false : not in
|
||||
*/
|
||||
bool lv_bar_is_symmetrical(lv_obj_t * obj);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
@ -24,7 +24,8 @@
|
||||
*********************/
|
||||
#define MY_CLASS &lv_slider_class
|
||||
|
||||
#define LV_SLIDER_KNOB_COORD(is_rtl, area) (is_rtl ? area.x1 : area.x2)
|
||||
#define LV_SLIDER_KNOB_COORD(is_reversed, area) (is_reversed ? area.x1 : area.x2)
|
||||
#define LV_SLIDER_KNOB_COORD_VERTICAL(is_reversed, area) (is_reversed ? area.y2 : area.y1)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@ -238,24 +239,24 @@ static void draw_knob(lv_event_t * e)
|
||||
|
||||
const bool is_rtl = LV_BASE_DIR_RTL == lv_obj_get_style_base_dir(obj, LV_PART_MAIN);
|
||||
const bool is_horizontal = is_slider_horizontal(obj);
|
||||
const bool is_reversed = slider->bar.val_reversed ^ (is_rtl && is_horizontal);
|
||||
|
||||
lv_area_t knob_area;
|
||||
lv_coord_t knob_size;
|
||||
bool is_symmetrical = false;
|
||||
if(slider->bar.mode == LV_BAR_MODE_SYMMETRICAL && slider->bar.min_value < 0 &&
|
||||
slider->bar.max_value > 0) is_symmetrical = true;
|
||||
bool is_symmetrical = lv_slider_is_symmetrical(obj);
|
||||
|
||||
if(is_horizontal) {
|
||||
knob_size = lv_obj_get_height(obj);
|
||||
if(is_symmetrical && slider->bar.cur_value < 0) knob_area.x1 = slider->bar.indic_area.x1;
|
||||
else knob_area.x1 = LV_SLIDER_KNOB_COORD(is_rtl, slider->bar.indic_area);
|
||||
if(is_symmetrical &&
|
||||
slider->bar.cur_value < 0) knob_area.x1 = LV_SLIDER_KNOB_COORD(!is_reversed, slider->bar.indic_area);
|
||||
else knob_area.x1 = LV_SLIDER_KNOB_COORD(is_reversed, slider->bar.indic_area);
|
||||
}
|
||||
else {
|
||||
knob_size = lv_obj_get_width(obj);
|
||||
if(is_symmetrical && slider->bar.cur_value < 0) knob_area.y1 = slider->bar.indic_area.y2;
|
||||
else knob_area.y1 = slider->bar.indic_area.y1;
|
||||
if(is_symmetrical &&
|
||||
slider->bar.cur_value < 0) knob_area.y1 = LV_SLIDER_KNOB_COORD_VERTICAL(!is_reversed, slider->bar.indic_area);
|
||||
else knob_area.y1 = LV_SLIDER_KNOB_COORD_VERTICAL(is_reversed, slider->bar.indic_area);
|
||||
}
|
||||
|
||||
lv_draw_rect_dsc_t knob_rect_dsc;
|
||||
lv_draw_rect_dsc_init(&knob_rect_dsc);
|
||||
lv_obj_init_draw_rect_dsc(obj, LV_PART_KNOB, &knob_rect_dsc);
|
||||
@ -276,11 +277,11 @@ static void draw_knob(lv_event_t * e)
|
||||
|
||||
/*Calculate the second knob area*/
|
||||
if(is_horizontal) {
|
||||
/*use !is_rtl to get the other knob*/
|
||||
knob_area.x1 = LV_SLIDER_KNOB_COORD(!is_rtl, slider->bar.indic_area);
|
||||
/*use !is_reversed to get the other knob*/
|
||||
knob_area.x1 = LV_SLIDER_KNOB_COORD(!is_reversed, slider->bar.indic_area);
|
||||
}
|
||||
else {
|
||||
knob_area.y1 = slider->bar.indic_area.y2;
|
||||
knob_area.y1 = LV_SLIDER_KNOB_COORD_VERTICAL(!is_reversed, slider->bar.indic_area);
|
||||
}
|
||||
position_knob(obj, &knob_area, knob_size, is_horizontal);
|
||||
lv_area_copy(&slider->left_knob_area, &knob_area);
|
||||
@ -338,24 +339,21 @@ static void drag_start(lv_obj_t * obj)
|
||||
else if(mode == LV_SLIDER_MODE_RANGE) {
|
||||
lv_indev_get_point(lv_indev_get_act(), &p);
|
||||
lv_obj_transform_point(obj, &p, true, true);
|
||||
bool hor = is_slider_horizontal(obj);
|
||||
lv_base_dir_t base_dir = lv_obj_get_style_base_dir(obj, LV_PART_MAIN);
|
||||
|
||||
const bool is_rtl = LV_BASE_DIR_RTL == lv_obj_get_style_base_dir(obj, LV_PART_MAIN);
|
||||
const bool is_horizontal = is_slider_horizontal(obj);
|
||||
const bool is_reversed = slider->bar.val_reversed ^ (is_rtl && is_horizontal);
|
||||
lv_coord_t dist_left, dist_right;
|
||||
if(hor) {
|
||||
if((base_dir != LV_BASE_DIR_RTL && p.x > slider->right_knob_area.x2) || (base_dir == LV_BASE_DIR_RTL &&
|
||||
p.x < slider->right_knob_area.x1)) {
|
||||
if(is_horizontal) {
|
||||
if((!is_reversed && p.x > slider->right_knob_area.x2) || (is_reversed && p.x < slider->right_knob_area.x1)) {
|
||||
slider->value_to_set = &slider->bar.cur_value;
|
||||
}
|
||||
else if((base_dir != LV_BASE_DIR_RTL && p.x < slider->left_knob_area.x1) || (base_dir == LV_BASE_DIR_RTL &&
|
||||
p.x > slider->left_knob_area.x2)) {
|
||||
else if((!is_reversed && p.x < slider->left_knob_area.x1) || (is_reversed && p.x > slider->left_knob_area.x2)) {
|
||||
slider->value_to_set = &slider->bar.start_value;
|
||||
}
|
||||
else {
|
||||
/*Calculate the distance from each knob*/
|
||||
dist_left = LV_ABS((slider->left_knob_area.x1 + (slider->left_knob_area.x2 - slider->left_knob_area.x1) / 2) - p.x);
|
||||
dist_right = LV_ABS((slider->right_knob_area.x1 + (slider->right_knob_area.x2 - slider->right_knob_area.x1) / 2) - p.x);
|
||||
|
||||
/*Use whichever one is closer*/
|
||||
if(dist_right < dist_left) {
|
||||
slider->value_to_set = &slider->bar.cur_value;
|
||||
@ -368,10 +366,10 @@ static void drag_start(lv_obj_t * obj)
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(p.y < slider->right_knob_area.y1) {
|
||||
if((!is_reversed && p.y < slider->right_knob_area.y1) || (is_reversed && p.y > slider->right_knob_area.y2)) {
|
||||
slider->value_to_set = &slider->bar.cur_value;
|
||||
}
|
||||
else if(p.y > slider->left_knob_area.y2) {
|
||||
else if((!is_reversed && p.y > slider->left_knob_area.y2) || (is_reversed && p.y < slider->left_knob_area.y1)) {
|
||||
slider->value_to_set = &slider->bar.start_value;
|
||||
}
|
||||
else {
|
||||
@ -424,13 +422,17 @@ static void update_knob_pos(lv_obj_t * obj, bool check_drag)
|
||||
|
||||
int32_t new_value = 0;
|
||||
const int32_t range = slider->bar.max_value - slider->bar.min_value;
|
||||
const bool is_rtl = LV_BASE_DIR_RTL == lv_obj_get_style_base_dir(obj, LV_PART_MAIN);
|
||||
const bool is_horizontal = is_slider_horizontal(obj);
|
||||
const bool is_reversed = slider->bar.val_reversed ^ (is_rtl && is_horizontal);
|
||||
|
||||
if(is_hor) {
|
||||
const lv_coord_t bg_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN);
|
||||
const lv_coord_t bg_right = lv_obj_get_style_pad_right(obj, LV_PART_MAIN);
|
||||
const lv_coord_t w = lv_obj_get_width(obj);
|
||||
const lv_coord_t indic_w = w - bg_left - bg_right;
|
||||
|
||||
if(lv_obj_get_style_base_dir(obj, LV_PART_MAIN) == LV_BASE_DIR_RTL) {
|
||||
if(is_reversed) {
|
||||
/*Make the point relative to the indicator*/
|
||||
new_value = (obj->coords.x2 - bg_right) - p.x;
|
||||
}
|
||||
@ -449,9 +451,16 @@ static void update_knob_pos(lv_obj_t * obj, bool check_drag)
|
||||
const lv_coord_t h = lv_obj_get_height(obj);
|
||||
const lv_coord_t indic_h = h - bg_bottom - bg_top;
|
||||
|
||||
if(is_reversed) {
|
||||
/*Make the point relative to the indicator*/
|
||||
new_value = p.y - (obj->coords.y1 + bg_top);
|
||||
}
|
||||
else {
|
||||
/*Make the point relative to the indicator*/
|
||||
new_value = p.y - (obj->coords.y2 + bg_bottom);
|
||||
new_value = (-new_value * range + indic_h / 2) / indic_h;
|
||||
new_value = -new_value;
|
||||
}
|
||||
new_value = (new_value * range + indic_h / 2) / indic_h;
|
||||
new_value += slider->bar.min_value;
|
||||
}
|
||||
|
||||
|
@ -166,7 +166,7 @@ bool lv_slider_is_dragged(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the mode of the slider.
|
||||
* @param slider pointer to a bar object
|
||||
* @param slider pointer to a slider object
|
||||
* @return see ::lv_slider_mode_t
|
||||
*/
|
||||
static inline lv_slider_mode_t lv_slider_get_mode(lv_obj_t * slider)
|
||||
@ -177,6 +177,16 @@ static inline lv_slider_mode_t lv_slider_get_mode(lv_obj_t * slider)
|
||||
else return LV_SLIDER_MODE_NORMAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Give the slider is in symmetrical mode or not
|
||||
* @param obj pointer to slider object
|
||||
* @return true: in symmetrical mode false : not in
|
||||
*/
|
||||
static inline bool lv_slider_is_symmetrical(lv_obj_t * obj)
|
||||
{
|
||||
return lv_bar_is_symmetrical(obj);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
@ -199,10 +199,9 @@ void test_bar_normal(void)
|
||||
lv_obj_set_style_bg_opa(test_bar, LV_OPA_30, LV_PART_MAIN);
|
||||
lv_obj_set_style_bg_color(test_bar, bg_color, LV_PART_MAIN);
|
||||
lv_obj_set_style_bg_color(test_bar, indic_color, LV_PART_INDICATOR);
|
||||
lv_bar_set_range(test_bar, 0, 100);
|
||||
lv_bar_set_range(test_bar, 100, 0);
|
||||
lv_bar_set_value(test_bar, 30, LV_ANIM_OFF);
|
||||
lv_obj_set_size(test_bar, h, w);
|
||||
lv_obj_set_style_base_dir(test_bar, LV_BASE_DIR_RTL, 0);
|
||||
lv_obj_align(test_bar, LV_ALIGN_TOP_LEFT, x, y);
|
||||
TEST_ASSERT_EQUAL_SCREENSHOT("bar_1.png");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user