merge slider anim update

This commit is contained in:
Gabor Kiss-Vamosi
2019-03-02 01:23:33 +01:00
14 changed files with 273 additions and 243 deletions

View File

@@ -30,6 +30,9 @@
static bool lv_bar_design(lv_obj_t * bar, const lv_area_t * mask, lv_design_mode_t mode);
static lv_res_t lv_bar_signal(lv_obj_t * bar, lv_signal_t sign, void * param);
static void lv_bar_animate(void * bar, int32_t value);
static void lv_bar_anim_ready(void * bar);
/**********************
* STATIC VARIABLES
**********************/
@@ -70,6 +73,10 @@ 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;
ext->sym = 0;
ext->style_indic = &lv_style_pretty_color;
@@ -80,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) {
@@ -99,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");
@@ -115,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;
@@ -142,23 +136,42 @@ void lv_bar_set_value_anim(lv_obj_t * bar, int16_t value, uint16_t anim_time)
new_value = value > ext->max_value ? ext->max_value : value;
new_value = new_value < ext->min_value ? ext->min_value : new_value;
lv_anim_t a;
a.var = bar;
a.start = ext->cur_value;
a.end = new_value;
a.fp = (lv_anim_fp_t)lv_bar_set_value;
a.path = lv_anim_path_linear;
a.end_cb = NULL;
a.act_time = 0;
a.time = anim_time;
a.playback = 0;
a.playback_pause = 0;
a.repeat = 0;
a.repeat_pause = 0;
if(ext->cur_value == new_value) return;
lv_anim_create(&a);
}
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 = ext->anim_time;
a.playback = 0;
a.playback_pause = 0;
a.repeat = 0;
a.repeat_pause = 0;
lv_anim_create(&a);
#endif
}
}
/**
@@ -176,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);
}
@@ -229,7 +242,10 @@ void lv_bar_set_style(lv_obj_t * bar, lv_bar_style_t type, lv_style_t * style)
int16_t lv_bar_get_value(const lv_obj_t * bar)
{
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
return ext->cur_value;
/*If animated tell that it's already at the end value*/
if(ext->anim_state != LV_BAR_ANIM_STATE_INV) return ext->anim_end;
/*No animation, simple return the current value*/
else return ext->cur_value;
}
/**
@@ -330,7 +346,7 @@ static bool lv_bar_design(lv_obj_t * bar, const lv_area_t * mask, lv_design_mode
#endif
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
if(ext->cur_value != ext->min_value || ext->sym) {
if(ext->cur_value != ext->min_value || ext->sym || ext->anim_start != LV_BAR_ANIM_STATE_INV) {
lv_style_t * style_indic = lv_bar_get_style(bar, LV_BAR_STYLE_INDIC);
lv_area_t indic_area;
lv_area_copy(&indic_area, &bar->coords);
@@ -344,9 +360,18 @@ static bool lv_bar_design(lv_obj_t * bar, const lv_area_t * mask, lv_design_mode
if(w >= h) {
/*Horizontal*/
indic_area.x2 = (int32_t)((int32_t)w * (ext->cur_value - ext->min_value)) / (ext->max_value - ext->min_value);
indic_area.x2 = indic_area.x1 + indic_area.x2 - 1;
if(ext->anim_state != LV_BAR_ANIM_STATE_INV) {
/*Calculate the coordinates of anim. start and end*/
lv_coord_t anim_start_x = (int32_t)((int32_t)w * (ext->anim_start - ext->min_value)) / (ext->max_value - ext->min_value);
lv_coord_t anim_end_x = (int32_t)((int32_t)w * (ext->anim_end - ext->min_value)) / (ext->max_value - ext->min_value);
/*Calculate the real position based on `anim_state` (between `anim_start` and `anim_end`)*/
indic_area.x2 = anim_start_x + (((anim_end_x - anim_start_x) * ext->anim_state) >> LV_BAR_ANIM_STATE_NORM);
} else {
indic_area.x2 = (int32_t)((int32_t)w * (ext->cur_value - ext->min_value)) / (ext->max_value - ext->min_value);
}
indic_area.x2 = indic_area.x1 + indic_area.x2 - 1;
if(ext->sym && ext->min_value < 0 && ext->max_value > 0) {
/*Calculate the coordinate of the zero point*/
lv_coord_t zero;
@@ -358,7 +383,17 @@ static bool lv_bar_design(lv_obj_t * bar, const lv_area_t * mask, lv_design_mode
}
}
} else {
indic_area.y1 = (int32_t)((int32_t)h * (ext->cur_value - ext->min_value)) / (ext->max_value - ext->min_value);
if(ext->anim_state != LV_BAR_ANIM_STATE_INV) {
/*Calculate the coordinates of anim. start and end*/
lv_coord_t anim_start_y = (int32_t)((int32_t)h * (ext->anim_start - ext->min_value)) / (ext->max_value - ext->min_value);
lv_coord_t anim_end_y = (int32_t)((int32_t)h * (ext->anim_end - ext->min_value)) / (ext->max_value - ext->min_value);
/*Calculate the real position based on `anim_state` (between `anim_start` and `anim_end`)*/
indic_area.y1 = anim_start_y + (((anim_end_y - anim_start_y) * ext->anim_state) >> LV_BAR_ANIM_STATE_NORM);
} else {
indic_area.y1 = (int32_t)((int32_t)h * (ext->cur_value - ext->min_value)) / (ext->max_value - ext->min_value);
}
indic_area.y1 = indic_area.y2 - indic_area.y1 + 1;
if(ext->sym && ext->min_value < 0 && ext->max_value > 0) {
@@ -426,4 +461,19 @@ static lv_res_t lv_bar_signal(lv_obj_t * bar, lv_signal_t sign, void * param)
}
static void lv_bar_animate(void * bar, int32_t value)
{
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
ext->anim_state = value;
lv_obj_invalidate(bar);
}
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, false);
}
#endif

View File

@@ -29,6 +29,10 @@ extern "C" {
/*********************
* DEFINES
*********************/
#define LV_BAR_ANIM_STATE_START 0
#define LV_BAR_ANIM_STATE_END 256
#define LV_BAR_ANIM_STATE_INV -1
#define LV_BAR_ANIM_STATE_NORM 8 /*log2(LV_BAR_ANIM_STATE_END) used to normalize data*/
/**********************
* TYPEDEFS
@@ -42,6 +46,10 @@ typedef struct
int16_t cur_value; /*Current value of the bar*/
int16_t min_value; /*Minimum value of the bar*/
int16_t max_value; /*Maximum value of the bar*/
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;
@@ -72,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

@@ -170,11 +170,6 @@ void lv_btn_set_toggle(lv_obj_t * btn, bool tgl)
*/
void lv_btn_set_state(lv_obj_t * btn, lv_btn_state_t state)
{
if(state == LV_BTN_STATE_REL) {
printf("asd\n");
}
lv_btn_ext_t * ext = lv_obj_get_ext_attr(btn);
if(ext->state != state) {
ext->state = state;

View File

@@ -275,8 +275,8 @@ void lv_btnm_set_map(const lv_obj_t * btnm, const char ** map)
* @param btnm pointer to a button matrix object
* @param ctrl_map pointer to an array of `lv_btn_ctrl_t` control bytes. The
* length of the array and position of the elements must match
* that when the map was set via `lv_btnm_set_map` (i.e. one
* element for each button AND new line).
* the number and order of the individual buttons (i.e. excludes
* newline entries).
* The control bits are:
* - bit 5 : 1 = inactive (disabled)
* - bit 4 : 1 = no repeat (on long press)

View File

@@ -99,20 +99,20 @@ lv_obj_t * lv_btnm_create(lv_obj_t * par, const lv_obj_t * copy);
*====================*/
/**
* Set a new map. Buttons will be created/deleted according to the map. The
* button matrix keeps a reference to the map and so the string array must not
* be deallocated during the life of the matrix.
* Set the button control map (hidden, disabled etc.) for a button matrix. The
* control map array will be copied and so may be deallocated after this
* function returns.
* @param btnm pointer to a button matrix object
* @param map pointer a string array. The last string has to be: "".
* Use "\n" to begin a new line.
* The first byte can be a control data:
* - bit 7: always 1
* - bit 6: always 0
* - bit 5: inactive (disabled)
* - bit 4: no repeat (on long press)
* - bit 3: hidden
* - bit 2..0: button relative width
* Example (practically use octal numbers): "\224abc": "abc" text with 4 width and no long press
* @param ctrl_map pointer to an array of `lv_btn_ctrl_t` control bytes. The
* length of the array and position of the elements must match
* the number and order of the individual buttons (i.e. excludes
* newline entries).
* The control bits are:
* - bit 5 : 1 = inactive (disabled)
* - bit 4 : 1 = no repeat (on long press)
* - bit 3 : 1 = hidden
* - bit 2..0: Relative width compared to the buttons in the
* same row. [1..7]
*/
void lv_btnm_set_map(const lv_obj_t * btnm, const char ** map);

View File

@@ -212,7 +212,7 @@ void lv_ddlist_set_fix_height(lv_obj_t * ddlist, lv_coord_t h)
/**
* Enable or disable the horizontal fit to the content
* @param ddlist pointer to a drop down list
* @param fit fit mode fron `lv_fit_t` (Typically `LV_FIT_NONE` or `LV_FIT_TIGHT`)
* @param fit fit mode from `lv_fit_t` (Typically `LV_FIT_NONE` or `LV_FIT_TIGHT`)
*/
void lv_ddlist_set_fit(lv_obj_t * ddlist, lv_fit_t fit)
{

View File

@@ -106,7 +106,7 @@ void lv_ddlist_set_fix_height(lv_obj_t * ddlist, lv_coord_t h);
/**
* Enable or disable the horizontal fit to the content
* @param ddlist pointer to a drop down list
* @param fit fit mode fron `lv_fit_t` (Typically `LV_FIT_NONE` or `LV_FIT_TIGHT`)
* @param fit fit mode from `lv_fit_t` (Typically `LV_FIT_NONE` or `LV_FIT_TIGHT`)
*/
void lv_ddlist_set_fit(lv_obj_t * ddlist, lv_fit_t fit);

View File

@@ -418,6 +418,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);
@@ -426,8 +427,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)) {
@@ -442,13 +441,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;
@@ -463,6 +485,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

@@ -100,11 +100,11 @@ void lv_roller_set_visible_row_count(lv_obj_t *roller, uint8_t row_cnt);
/**
* Enable or disable the horizontal fit to the content
* @param roller pointer to a roller
* @param en true: enable auto fit; false: disable auto fit
* @param fit fit mode from `lv_fit_t` (Typically `LV_FIT_NONE` or `LV_FIT_TIGHT`)
*/
static inline void lv_roller_set_hor_fit(lv_obj_t * roller, bool en)
static inline void lv_roller_set_hor_fit(lv_obj_t * roller, lv_fit_t fit)
{
lv_ddlist_set_fit(roller, en);
lv_ddlist_set_fit(roller, fit);
}
/**

View File

@@ -280,11 +280,10 @@ static bool lv_slider_design(lv_obj_t * slider, const lv_area_t * mask, lv_desig
area_bg.y2 -= slider_w > slider_h ? pad_ver_bg : 0; /*Pad only for horizontal slider*/
}
#if USE_LV_GROUP == 0
lv_draw_rect(&area_bg, mask, style_bg, lv_obj_get_opa_scale(slider));
#else
/* Draw the borders later if the bar is focused.
/* Draw the borders later if the slider is focused.
* At value = 100% the indicator can cover to whole background and the focused style won't be visible*/
if(lv_obj_is_focused(slider)) {
lv_style_t style_tmp;
@@ -296,7 +295,6 @@ static bool lv_slider_design(lv_obj_t * slider, const lv_area_t * mask, lv_desig
}
#endif
/*Draw the indicator*/
lv_area_t area_indic;
lv_area_copy(&area_indic, &area_bg);
@@ -316,7 +314,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);
@@ -325,15 +322,39 @@ static bool lv_slider_design(lv_obj_t * slider, const lv_area_t * mask, lv_desig
if(ext->drag_value != LV_SLIDER_NOT_PRESSED) cur_value = ext->drag_value;
if(slider_w >= slider_h) {
area_indic.x2 = (int32_t)((int32_t)(lv_area_get_width(&area_indic)) * (cur_value - min_value)) / (max_value - min_value);
lv_coord_t indic_w = lv_area_get_width(&area_indic);
if(ext->bar.anim_state != LV_BAR_ANIM_STATE_INV) {
/*Calculate the coordinates of anim. start and end*/
lv_coord_t anim_start_x = (int32_t)((int32_t)indic_w * (ext->bar.anim_start - min_value)) / (max_value - min_value);
lv_coord_t anim_end_x = (int32_t)((int32_t)indic_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`)*/
area_indic.x2 = anim_start_x + (((anim_end_x - anim_start_x) * ext->bar.anim_state) >> 8);
} else {
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;
} else {
area_indic.y1 = (int32_t)((int32_t)(lv_area_get_height(&area_indic)) * (cur_value - min_value)) / (max_value - min_value);
area_indic.y1 = area_indic.y2 - area_indic.y1 + 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);
if(cur_value != min_value) 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) {
/*Calculate the coordinates of anim. start and end*/
lv_coord_t anim_start_y = (int32_t)((int32_t)indic_h * (ext->bar.anim_start - min_value)) / (max_value - min_value);
lv_coord_t anim_end_y = (int32_t)((int32_t)indic_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`)*/
area_indic.y1 = anim_start_y + (((anim_end_y - anim_start_y) * ext->bar.anim_state) >> 8);
} else {
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;
/*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
@@ -357,7 +378,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;
}
@@ -369,7 +400,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;
}
@@ -433,7 +474,7 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par
lv_obj_send_event(slider, LV_EVENT_VALUE_CHANGED);
}
} 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;
lv_obj_send_event(slider, LV_EVENT_VALUE_CHANGED);
} else if(sign == LV_SIGNAL_CORD_CHG) {
@@ -473,10 +514,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(slider, lv_slider_get_value(slider) + 1);
lv_slider_set_value(slider, lv_slider_get_value(slider) + 1, true);
lv_obj_send_event(slider, LV_EVENT_VALUE_CHANGED);
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) {
lv_slider_set_value(slider, lv_slider_get_value(slider) - 1);
lv_slider_set_value(slider, lv_slider_get_value(slider) - 1, true);
lv_obj_send_event(slider, LV_EVENT_VALUE_CHANGED);
}
} else if(sign == LV_SIGNAL_GET_EDITABLE) {

View File

@@ -41,8 +41,8 @@ typedef struct
{
lv_bar_ext_t bar; /*Ext. of ancestor*/
/*New data for this type */
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_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;
@@ -75,21 +75,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,17 +269,23 @@ 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);
/*Don't let the slider to call the action. Switch handles it differently*/
lv_event_cb_t event_cb = sw->event_cb;
sw->event_cb = NULL;
lv_res_t res;
/* Include the ancient signal function */
res = ancestor_signal(sw, sign, param);
if(res != LV_RES_OK) return res;
sw->event_cb = event_cb;
if(sign == LV_SIGNAL_CLEANUP) {
/*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
}
@@ -331,7 +302,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};
@@ -341,12 +312,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))
{
@@ -356,48 +327,42 @@ 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);
lv_obj_send_event(sw, LV_EVENT_VALUE_CHANGED);
}
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);
lv_obj_send_event(sw, LV_EVENT_VALUE_CHANGED);
}
}
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(lv_sw_get_state(sw)) lv_sw_off(sw, true);
else lv_sw_on(sw, true);
lv_obj_send_event(sw, LV_EVENT_VALUE_CHANGED);
}
/*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(v > LV_SW_MAX_VALUE / 2) lv_sw_on(sw, true);
else lv_sw_off(sw, true);
lv_obj_send_event(sw, LV_EVENT_VALUE_CHANGED);
}
} 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);
lv_sw_toggle(sw, true);
lv_obj_send_event(sw, LV_EVENT_VALUE_CHANGED);
} else if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) {
lv_slider_set_value(sw, LV_SW_MAX_VALUE, true);
lv_obj_send_event(sw, LV_EVENT_VALUE_CHANGED);
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) {
lv_slider_set_value(sw, 0, true);
lv_obj_send_event(sw, LV_EVENT_VALUE_CHANGED);
lv_obj_send_event(sw, LV_EVENT_VALUE_CHANGED);
} else if(c == LV_GROUP_KEY_UP || c == LV_GROUP_KEY_RIGHT) {
lv_sw_on_anim(sw);
lv_obj_send_event(sw, LV_EVENT_VALUE_CHANGED);
} else if(c == LV_GROUP_KEY_DOWN || c == LV_GROUP_KEY_LEFT) {
lv_sw_off_anim(sw);
lv_obj_send_event(sw, LV_EVENT_VALUE_CHANGED);
}
} else if(sign == LV_SIGNAL_GET_EDITABLE) {
bool * editable = (bool *)param;
@@ -414,25 +379,4 @@ 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)
{
#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 style of a switch
@@ -143,7 +127,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;
}
/**

View File

@@ -1219,7 +1219,6 @@ static lv_res_t lv_ta_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, void
if(ext->label) {
if(lv_obj_get_width(ta) != lv_area_get_width(param) ||
lv_obj_get_height(ta) != lv_area_get_height(param)) {
lv_obj_t * scrl = lv_page_get_scrl(ta);
lv_style_t * style_scrl = lv_obj_get_style(scrl);
lv_obj_set_width(ext->label, lv_obj_get_width(scrl) - 2 * style_scrl->body.padding.hor);
lv_obj_set_pos(ext->label, style_scrl->body.padding.hor, style_scrl->body.padding.ver);