1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-21 06:53:01 +08:00

bar/slider/sw anim updates

This commit is contained in:
Gabor Kiss-Vamosi 2019-03-01 23:50:30 +01:00
parent 4743e11967
commit cae61d4e3e
7 changed files with 166 additions and 225 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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
}
}

View File

@ -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) {

View File

@ -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);
}
/**

View File

@ -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

View File

@ -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;
}
/**