add lv_obj, lv_bar, lv_slider to work with classes

This commit is contained in:
Gabor Kiss-Vamosi
2020-12-11 18:04:23 +01:00
parent 396ef46307
commit ec124559f6
22 changed files with 968 additions and 1209 deletions

View File

@@ -120,25 +120,6 @@ lv_obj_t * lv_disp_get_layer_sys(lv_disp_t * disp)
return disp->sys_layer; return disp->sys_layer;
} }
/**
* Assign a screen to a display.
* @param disp pointer to a display where to assign the screen
* @param scr pointer to a screen object to assign
*/
void lv_disp_assign_screen(lv_disp_t * disp, lv_obj_t * scr)
{
if(lv_obj_get_parent(scr) != NULL) {
LV_LOG_WARN("lv_disp_assign_screen: try to assign a non-screen object");
return;
}
lv_disp_t * old_disp = lv_obj_get_disp(scr);
if(old_disp == disp) return;
_lv_ll_chg_list(&old_disp->scr_ll, &disp->scr_ll, scr, true);
}
/** /**
* Set the background color of a display * Set the background color of a display
* @param disp pointer to a display * @param disp pointer to a display

View File

@@ -78,14 +78,6 @@ lv_obj_t * lv_disp_get_layer_top(lv_disp_t * disp);
*/ */
lv_obj_t * lv_disp_get_layer_sys(lv_disp_t * disp); lv_obj_t * lv_disp_get_layer_sys(lv_disp_t * disp);
/**
* Assign a screen to a display.
* @param disp pointer to a display where to assign the screen
* @param scr pointer to a screen object to assign
*/
void lv_disp_assign_screen(lv_disp_t * disp, lv_obj_t * scr);
/** /**
* Set the background color of a display * Set the background color of a display
* @param disp pointer to a display * @param disp pointer to a display

View File

@@ -26,14 +26,14 @@ typedef struct {
/********************** /**********************
* STATIC PROTOTYPES * STATIC PROTOTYPES
**********************/ **********************/
//static lv_obj_t * find_track_end(lv_obj_t * cont, lv_obj_t * item_start, lv_coord_t max_size, lv_coord_t * grow_unit, lv_coord_t * track_cross_size, lv_coord_t * track_main_size, uint32_t * item_cnt); static uint32_t find_track_end(lv_obj_t * cont, uint32_t item_start_id, lv_coord_t max_main_size, track_t * t);
static lv_obj_t * find_track_end(lv_obj_t * cont, lv_obj_t * item_start, lv_coord_t max_main_size, track_t * t); static void children_repos(lv_obj_t * cont, uint32_t item_first_id, uint32_t item_last_id, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t max_main_size, lv_flex_place_t main_place, track_t * t);
static void children_repos(lv_obj_t * cont, lv_obj_t * item_first, lv_obj_t * item_last, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t max_main_size, lv_flex_place_t main_place, track_t * t);
static void place_content(lv_coord_t place, lv_coord_t max_size, lv_coord_t track_size, lv_coord_t item_cnt, lv_coord_t * start_pos, lv_coord_t * gap); static void place_content(lv_coord_t place, lv_coord_t max_size, lv_coord_t track_size, lv_coord_t item_cnt, lv_coord_t * start_pos, lv_coord_t * gap);
static lv_flex_dir_t get_dir(const lv_obj_t * obj); static lv_flex_dir_t get_dir(const lv_obj_t * obj);
static bool get_rev(const lv_obj_t * obj); static bool get_rev(const lv_obj_t * obj);
static bool get_wrap(const lv_obj_t * obj); static bool get_wrap(const lv_obj_t * obj);
static lv_obj_t * get_next_item(lv_obj_t * cont, bool rev, uint32_t * item_id);
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
@@ -158,7 +158,6 @@ void _lv_flex_refresh(lv_obj_t * cont)
lv_flex_place_t cross_place = lv_obj_get_flex_track_place(cont); lv_flex_place_t cross_place = lv_obj_get_flex_track_place(cont);
lv_flex_place_t main_place = cont->spec_attr->flex_cont.main_place; lv_flex_place_t main_place = cont->spec_attr->flex_cont.main_place;
lv_ll_t * ll = _lv_obj_get_child_ll(cont);
lv_coord_t * cross_pos = (row ? &abs_y : &abs_x); lv_coord_t * cross_pos = (row ? &abs_y : &abs_x);
if((row && cont->h_set == LV_SIZE_AUTO) || if((row && cont->h_set == LV_SIZE_AUTO) ||
@@ -175,14 +174,14 @@ void _lv_flex_refresh(lv_obj_t * cont)
lv_coord_t total_track_cross_size = 0; lv_coord_t total_track_cross_size = 0;
lv_coord_t gap = 0; lv_coord_t gap = 0;
uint32_t track_cnt = 0; uint32_t track_cnt = 0;
lv_obj_t * track_first_item; uint32_t track_first_item;
lv_obj_t * next_track_first_item; uint32_t next_track_first_item;
bool rev = get_rev(cont); bool rev = get_rev(cont);
if(cross_place != LV_FLEX_PLACE_START) { if(cross_place != LV_FLEX_PLACE_START) {
track_first_item = rev ? _lv_ll_get_head(ll) : _lv_ll_get_tail(ll); track_first_item = rev ? cont->spec_attr->child_cnt - 1 : 0;
track_t t; track_t t;
while(track_first_item) { while(track_first_item ) {
/*Search the first item of the next row */ /*Search the first item of the next row */
next_track_first_item = find_track_end(cont, track_first_item, max_main_size, &t); next_track_first_item = find_track_end(cont, track_first_item, max_main_size, &t);
total_track_cross_size += t.track_cross_size; total_track_cross_size += t.track_cross_size;
@@ -194,7 +193,7 @@ void _lv_flex_refresh(lv_obj_t * cont)
place_content(cross_place, max_cross_size, total_track_cross_size, track_cnt, cross_pos, &gap); place_content(cross_place, max_cross_size, total_track_cross_size, track_cnt, cross_pos, &gap);
} }
track_first_item = rev ? _lv_ll_get_head(ll) : _lv_ll_get_tail(ll); track_first_item = rev ? cont->spec_attr->child_cnt - 1 : 0;
if(rtl && !row) { if(rtl && !row) {
*cross_pos += total_track_cross_size; *cross_pos += total_track_cross_size;
@@ -224,7 +223,7 @@ void _lv_flex_refresh(lv_obj_t * cont)
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
static lv_obj_t * find_track_end(lv_obj_t * cont, lv_obj_t * item_start, lv_coord_t max_main_size, track_t * t) static uint32_t find_track_end(lv_obj_t * cont, uint32_t item_start_id, lv_coord_t max_main_size, track_t * t)
{ {
bool wrap = get_wrap(cont); bool wrap = get_wrap(cont);
bool rev = get_rev(cont); bool rev = get_rev(cont);
@@ -232,9 +231,6 @@ static lv_obj_t * find_track_end(lv_obj_t * cont, lv_obj_t * item_start, lv_coor
bool row = get_dir(cont) == LV_FLEX_DIR_ROW ? true : false; bool row = get_dir(cont) == LV_FLEX_DIR_ROW ? true : false;
lv_coord_t(*get_main_size)(const lv_obj_t *) = (row ? lv_obj_get_width_margin : lv_obj_get_height_margin); lv_coord_t(*get_main_size)(const lv_obj_t *) = (row ? lv_obj_get_width_margin : lv_obj_get_height_margin);
lv_coord_t(*get_cross_size)(const lv_obj_t *) = (!row ? lv_obj_get_width_margin : lv_obj_get_height_margin); lv_coord_t(*get_cross_size)(const lv_obj_t *) = (!row ? lv_obj_get_width_margin : lv_obj_get_height_margin);
void * (*ll_iter)(const lv_ll_t * , const void *) = rev ? _lv_ll_get_next : _lv_ll_get_prev;
lv_ll_t * ll = _lv_obj_get_child_ll(cont);
lv_coord_t grow_sum = 0; lv_coord_t grow_sum = 0;
t->track_main_size = 0; t->track_main_size = 0;
@@ -243,12 +239,14 @@ static lv_obj_t * find_track_end(lv_obj_t * cont, lv_obj_t * item_start, lv_coor
t->grow_unit = 0; t->grow_unit = 0;
t->item_cnt = 0; t->item_cnt = 0;
lv_obj_t * item = item_start; uint32_t item_id = item_start_id;
lv_obj_t * item = get_next_item(cont, rev, &item_id);
while(item) { while(item) {
/*Ignore non-flex items*/ /*Ignore non-flex items*/
lv_coord_t main_set = (row ? item->x_set : item->y_set); lv_coord_t main_set = (row ? item->x_set : item->y_set);
if(LV_COORD_IS_FLEX(main_set) == false) { if(LV_COORD_IS_FLEX(main_set) == false) {
item = ll_iter(ll, item); item = get_next_item(cont, rev, &item_id);
continue; continue;
} }
@@ -263,7 +261,8 @@ static lv_obj_t * find_track_end(lv_obj_t * cont, lv_obj_t * item_start, lv_coor
} }
t->track_cross_size = LV_MATH_MAX(get_cross_size(item), t->track_cross_size); t->track_cross_size = LV_MATH_MAX(get_cross_size(item), t->track_cross_size);
item = ll_iter(ll, item); item_id += rev ? -1 : +1;
item = lv_obj_get_child(cont, item_id);
t->item_cnt++; t->item_cnt++;
} }
@@ -279,8 +278,8 @@ static lv_obj_t * find_track_end(lv_obj_t * cont, lv_obj_t * item_start, lv_coor
} }
/*Have at least one item in a row*/ /*Have at least one item in a row*/
if(item && item == item_start) { if(item && item_id == item_start_id) {
item = ll_iter(ll, item); item = get_next_item(cont, rev, &item_id);
if(item) { if(item) {
t->track_cross_size = get_cross_size(item); t->track_cross_size = get_cross_size(item);
t->track_main_size = get_main_size(item); t->track_main_size = get_main_size(item);
@@ -288,11 +287,11 @@ static lv_obj_t * find_track_end(lv_obj_t * cont, lv_obj_t * item_start, lv_coor
} }
} }
return item; return item_id;
} }
static void children_repos(lv_obj_t * cont, lv_obj_t * item_first, lv_obj_t * item_last, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t max_main_size, lv_flex_place_t main_place, track_t * t) static void children_repos(lv_obj_t * cont, uint32_t item_first_id, uint32_t item_last_id, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t max_main_size, lv_flex_place_t main_place, track_t * t)
{ {
bool rev = get_rev(cont); bool rev = get_rev(cont);
lv_coord_t gap = lv_obj_get_flex_gap(cont); lv_coord_t gap = lv_obj_get_flex_gap(cont);
@@ -305,25 +304,23 @@ static void children_repos(lv_obj_t * cont, lv_obj_t * item_first, lv_obj_t * it
lv_coord_t (*area_get_main_size)(const lv_area_t *) = (!row ? lv_area_get_width : lv_area_get_height); lv_coord_t (*area_get_main_size)(const lv_area_t *) = (!row ? lv_area_get_width : lv_area_get_height);
lv_style_int_t (*get_margin_start)(const lv_obj_t *, uint8_t part) = (row ? lv_obj_get_style_margin_left : lv_obj_get_style_margin_top); lv_style_int_t (*get_margin_start)(const lv_obj_t *, uint8_t part) = (row ? lv_obj_get_style_margin_left : lv_obj_get_style_margin_top);
lv_style_int_t (*get_margin_end)(const lv_obj_t *, uint8_t part) = (row ? lv_obj_get_style_margin_right : lv_obj_get_style_margin_bottom); lv_style_int_t (*get_margin_end)(const lv_obj_t *, uint8_t part) = (row ? lv_obj_get_style_margin_right : lv_obj_get_style_margin_bottom);
void * (*ll_iter)(const lv_ll_t * , const void *) = rev ? _lv_ll_get_next : _lv_ll_get_prev;
bool rtl = lv_obj_get_base_dir(cont) == LV_BIDI_DIR_RTL ? true : false; bool rtl = lv_obj_get_base_dir(cont) == LV_BIDI_DIR_RTL ? true : false;
if(row && rtl) abs_x += lv_obj_get_width_fit(cont); if(row && rtl) abs_x += lv_obj_get_width_fit(cont);
lv_ll_t * ll = _lv_obj_get_child_ll(cont);
lv_coord_t main_pos = 0; lv_coord_t main_pos = 0;
lv_coord_t place_gap = 0; lv_coord_t place_gap = 0;
place_content(main_place, max_main_size, t->track_main_size, t->item_cnt, &main_pos, &place_gap); place_content(main_place, max_main_size, t->track_main_size, t->item_cnt, &main_pos, &place_gap);
/*Reposition the children*/
lv_obj_t * item = item_first; /*Just to use a shorter name*/
while(item != item_last) {
lv_obj_t * item = get_next_item(cont, rev, &item_first_id);
/*Reposition the children*/
while(item && item_first_id != item_last_id) {
/*Ignore non-flex items*/ /*Ignore non-flex items*/
lv_coord_t main_set = (row ? item->x_set : item->y_set); lv_coord_t main_set = (row ? item->x_set : item->y_set);
if(LV_COORD_IS_FLEX(main_set) == false) { if(LV_COORD_IS_FLEX(main_set) == false) {
item = ll_iter(ll, item); item = get_next_item(cont, rev, &item_first_id);
continue; continue;
} }
@@ -343,7 +340,7 @@ static void children_repos(lv_obj_t * cont, lv_obj_t * item_first, lv_obj_t * it
if(lv_area_get_height(&old_coords) != area_get_main_size(&item->coords)) { if(lv_area_get_height(&old_coords) != area_get_main_size(&item->coords)) {
lv_obj_invalidate(item); lv_obj_invalidate(item);
item->signal_cb(item, LV_SIGNAL_COORD_CHG, &old_coords); lv_signal_send(item, LV_SIGNAL_COORD_CHG, &old_coords);
lv_obj_invalidate(item); lv_obj_invalidate(item);
} }
} }
@@ -379,7 +376,7 @@ static void children_repos(lv_obj_t * cont, lv_obj_t * item_first, lv_obj_t * it
if(!(row && rtl)) { if(!(row && rtl)) {
main_pos += obj_get_main_size(item) + gap + place_gap; main_pos += obj_get_main_size(item) + gap + place_gap;
} }
item = ll_iter(ll, item); item = get_next_item(cont, rev, &item_first_id);
} }
} }
@@ -437,3 +434,24 @@ static bool get_wrap(const lv_obj_t * obj)
if(obj->spec_attr) return obj->spec_attr->flex_cont.wrap; if(obj->spec_attr) return obj->spec_attr->flex_cont.wrap;
else return false; else return false;
} }
static lv_obj_t * get_next_item(lv_obj_t * cont, bool rev, uint32_t * item_id)
{
if(rev) {
if(*item_id > 0) {
(*item_id)--;
return cont->spec_attr->children[*item_id];
}
else {
return NULL;
}
} else {
if((*item_id) <= cont->spec_attr->child_cnt - 1) {
item_id++;
return cont->spec_attr->children[*item_id];
}
else {
return NULL;
}
}
}

View File

@@ -115,9 +115,9 @@ void lv_obj_report_grid_change(const lv_grid_t * grid)
lv_disp_t * d = lv_disp_get_next(NULL); lv_disp_t * d = lv_disp_get_next(NULL);
while(d) { while(d) {
lv_obj_t * i; uint32_t i;
_LV_LL_READ(&d->scr_ll, i) { for(i = 0; i < d->screen_cnt; i++) {
report_grid_change_core(grid, i); report_grid_change_core(grid, d->screens[i]);
} }
d = lv_disp_get_next(d); d = lv_disp_get_next(d);
} }
@@ -136,11 +136,10 @@ void _lv_grid_calc(struct _lv_obj_t * cont, _lv_grid_calc_t * calc_out)
if(g->col_dsc == NULL || g->row_dsc == NULL) return; if(g->col_dsc == NULL || g->row_dsc == NULL) return;
if(g->col_dsc_len == 0 || g->row_dsc_len == 0) return; if(g->col_dsc_len == 0 || g->row_dsc_len == 0) return;
if(lv_obj_get_child(cont, NULL) == NULL) { if(lv_obj_get_child(cont, 0) == NULL) {
_lv_memset_00(calc_out, sizeof(_lv_grid_calc_t)); _lv_memset_00(calc_out, sizeof(_lv_grid_calc_t));
return; return;
} }
// printf("calc: %d, %d\n", obj->grid->col_dsc_len, obj->grid->row_dsc_len);
calc_rows(cont, calc_out); calc_rows(cont, calc_out);
calc_cols(cont, calc_out); calc_cols(cont, calc_out);
@@ -228,12 +227,12 @@ void _lv_grid_full_refresh(lv_obj_t * cont)
hint.grid_abs.x = pad_left + cont->coords.x1 - lv_obj_get_scroll_x(cont); hint.grid_abs.x = pad_left + cont->coords.x1 - lv_obj_get_scroll_x(cont);
hint.grid_abs.y = pad_top + cont->coords.y1 - lv_obj_get_scroll_y(cont); hint.grid_abs.y = pad_top + cont->coords.y1 - lv_obj_get_scroll_y(cont);
lv_obj_t * item = lv_obj_get_child_back(cont, NULL); uint32_t i;
while(item) { for(i = 0; i < cont->spec_attr->child_cnt; i++) {
lv_obj_t * item = cont->spec_attr->children[i];
if(LV_COORD_IS_GRID(item->x_set) && LV_COORD_IS_GRID(item->y_set)) { if(LV_COORD_IS_GRID(item->x_set) && LV_COORD_IS_GRID(item->y_set)) {
item_repos(item, &calc, &hint); item_repos(item, &calc, &hint);
} }
item = lv_obj_get_child_back(cont, item);
} }
_lv_grid_calc_free(&calc); _lv_grid_calc_free(&calc);
@@ -430,7 +429,7 @@ static void item_repos(lv_obj_t * item, _lv_grid_calc_t * calc, item_repos_hint_
lv_area_set_width(&item->coords, item_w); lv_area_set_width(&item->coords, item_w);
lv_area_set_height(&item->coords, item_h); lv_area_set_height(&item->coords, item_h);
lv_obj_invalidate(item); lv_obj_invalidate(item);
item->signal_cb(item, LV_SIGNAL_COORD_CHG, &old_coords); lv_signal_send(item, LV_SIGNAL_COORD_CHG, &old_coords);
} }
bool moved = true; bool moved = true;
@@ -530,10 +529,9 @@ static void report_grid_change_core(const lv_grid_t * grid, lv_obj_t * obj)
if(obj->spec_attr->grid == grid || (obj->spec_attr->grid && grid == NULL)) _lv_grid_full_refresh(obj); if(obj->spec_attr->grid == grid || (obj->spec_attr->grid && grid == NULL)) _lv_grid_full_refresh(obj);
} }
lv_obj_t * child = lv_obj_get_child(obj, NULL); uint32_t i;
while(child) { for(i = 0; i < obj->spec_attr->child_cnt; i++) {
report_grid_change_core(grid, child); report_grid_change_core(grid, obj->spec_attr->children[i]);
child = lv_obj_get_child(obj, child);
} }
} }

View File

@@ -1050,16 +1050,13 @@ lv_obj_t * lv_indev_search_obj(lv_obj_t * obj, lv_point_t * point)
/*If the point is on this object check its children too*/ /*If the point is on this object check its children too*/
if(lv_obj_hit_test(obj, point)) { if(lv_obj_hit_test(obj, point)) {
lv_obj_t * i; int32_t i;
for(i = lv_obj_get_child_cnt(obj) - 1; i >= 0; i--) {
lv_ll_t * ll = _lv_obj_get_child_ll(obj); lv_obj_t * child = lv_obj_get_child(obj, i);
_LV_LL_READ(ll, i) { found_p = lv_indev_search_obj(child, point);
found_p = lv_indev_search_obj(i, point);
/*If a child was found then break*/ /*If a child was found then break*/
if(found_p != NULL) { if(found_p != NULL) break;
break;
}
} }
/*If then the children was not ok, and this obj is clickable /*If then the children was not ok, and this obj is clickable
@@ -1222,7 +1219,7 @@ void indev_gesture(lv_indev_proc_t * proc)
proc->types.pointer.gesture_dir = LV_GESTURE_DIR_TOP; proc->types.pointer.gesture_dir = LV_GESTURE_DIR_TOP;
} }
gesture_obj->signal_cb(gesture_obj, LV_SIGNAL_GESTURE, indev_act); lv_signal_send(gesture_obj, LV_SIGNAL_GESTURE, indev_act);
if(indev_reset_check(proc)) return; if(indev_reset_check(proc)) return;
lv_event_send(gesture_obj, LV_EVENT_GESTURE, NULL); lv_event_send(gesture_obj, LV_EVENT_GESTURE, NULL);
if(indev_reset_check(proc)) return; if(indev_reset_check(proc)) return;

View File

@@ -258,10 +258,11 @@ static lv_obj_t * find_scroll_obj(lv_indev_proc_t * proc)
* 5. Use the last candidate. Always the "deepest" parent or the object from point 3 */ * 5. Use the last candidate. Always the "deepest" parent or the object from point 3 */
lv_obj_t * obj_act = proc->types.pointer.act_obj; lv_obj_t * obj_act = proc->types.pointer.act_obj;
while(obj_act) { while(obj_act) {
/*Halt search on a scroll freeze object*/
if(lv_obj_has_flag(obj_act, LV_OBJ_FLAG_SCROLL_FREEZE)) return NULL;
if(lv_obj_has_flag(obj_act, LV_OBJ_FLAG_SCROLLABLE) == false) { if(lv_obj_has_flag(obj_act, LV_OBJ_FLAG_SCROLLABLE) == false) {
/*If this object don't want to chain the scroll ot the parent stop searching*/
if(lv_obj_has_flag(obj_act, LV_OBJ_FLAG_SCROLL_CHAIN) == false) break;
obj_act = lv_obj_get_parent(obj_act); obj_act = lv_obj_get_parent(obj_act);
continue; continue;
} }
@@ -330,6 +331,9 @@ static lv_obj_t * find_scroll_obj(lv_indev_proc_t * proc)
break; break;
} }
/*If this object don't want to chain the scroll ot the parent stop searching*/
if(lv_obj_has_flag(obj_act, LV_OBJ_FLAG_SCROLL_CHAIN) == false) break;
/*Try the parent */ /*Try the parent */
obj_act = lv_obj_get_parent(obj_act); obj_act = lv_obj_get_parent(obj_act);
} }
@@ -411,8 +415,9 @@ static lv_coord_t find_snap_point_x(const lv_obj_t * obj, lv_coord_t min, lv_coo
lv_coord_t dist = LV_COORD_MAX; lv_coord_t dist = LV_COORD_MAX;
lv_obj_t * child = lv_obj_get_child_back(obj, NULL); uint32_t i;
while(child) { for(i = 0; i < lv_obj_get_child_cnt(obj); i++) {
lv_obj_t * child = lv_obj_get_child(obj, i);
if(lv_obj_has_flag(child, LV_OBJ_FLAG_SNAPABLE)) { if(lv_obj_has_flag(child, LV_OBJ_FLAG_SNAPABLE)) {
lv_coord_t x_child = 0; lv_coord_t x_child = 0;
lv_coord_t x_parent = 0; lv_coord_t x_parent = 0;
@@ -436,8 +441,6 @@ static lv_coord_t find_snap_point_x(const lv_obj_t * obj, lv_coord_t min, lv_coo
if(LV_MATH_ABS(x) < LV_MATH_ABS(dist)) dist = x; if(LV_MATH_ABS(x) < LV_MATH_ABS(dist)) dist = x;
} }
} }
child = lv_obj_get_child_back(obj, child);
} }
return dist == LV_COORD_MAX ? 0: -dist; return dist == LV_COORD_MAX ? 0: -dist;
@@ -459,8 +462,9 @@ static lv_coord_t find_snap_point_y(const lv_obj_t * obj, lv_coord_t min, lv_coo
lv_coord_t dist = LV_COORD_MAX; lv_coord_t dist = LV_COORD_MAX;
lv_obj_t * child = lv_obj_get_child_back(obj, NULL); uint32_t i;
while(child) { for(i = 0; i < lv_obj_get_child_cnt(obj); i++) {
lv_obj_t * child = lv_obj_get_child(obj, i);
if(lv_obj_has_flag(child, LV_OBJ_FLAG_SNAPABLE)) { if(lv_obj_has_flag(child, LV_OBJ_FLAG_SNAPABLE)) {
lv_coord_t y_child = 0; lv_coord_t y_child = 0;
lv_coord_t y_parent = 0; lv_coord_t y_parent = 0;
@@ -484,8 +488,6 @@ static lv_coord_t find_snap_point_y(const lv_obj_t * obj, lv_coord_t min, lv_coo
if(LV_MATH_ABS(y) < LV_MATH_ABS(dist)) dist = y; if(LV_MATH_ABS(y) < LV_MATH_ABS(dist)) dist = y;
} }
} }
child = lv_obj_get_child_back(obj, child);
} }
return dist == LV_COORD_MAX ? 0 : -dist; return dist == LV_COORD_MAX ? 0 : -dist;

File diff suppressed because it is too large Load Diff

View File

@@ -24,6 +24,7 @@ extern "C" {
#include "../lv_misc/lv_area.h" #include "../lv_misc/lv_area.h"
#include "../lv_misc/lv_color.h" #include "../lv_misc/lv_color.h"
#include "../lv_misc/lv_debug.h" #include "../lv_misc/lv_debug.h"
#include "../lv_misc/lv_class.h"
#include "../lv_hal/lv_hal.h" #include "../lv_hal/lv_hal.h"
#include "../lv_draw/lv_draw_rect.h" #include "../lv_draw/lv_draw_rect.h"
#include "../lv_draw/lv_draw_label.h" #include "../lv_draw/lv_draw_label.h"
@@ -120,13 +121,11 @@ typedef void (*lv_event_cb_t)(struct _lv_obj_t * obj, lv_event_t event);
* on the object. */ * on the object. */
enum { enum {
/*General signals*/ /*General signals*/
LV_SIGNAL_CLEANUP, /**< Object is being deleted */
LV_SIGNAL_CHILD_CHG, /**< Child was removed/added */ LV_SIGNAL_CHILD_CHG, /**< Child was removed/added */
LV_SIGNAL_COORD_CHG, /**< Object coordinates/size have changed */ LV_SIGNAL_COORD_CHG, /**< Object coordinates/size have changed */
LV_SIGNAL_STYLE_CHG, /**< Object's style has changed */ LV_SIGNAL_STYLE_CHG, /**< Object's style has changed */
LV_SIGNAL_BASE_DIR_CHG, /**< The base dir has changed*/ LV_SIGNAL_BASE_DIR_CHG, /**< The base dir has changed*/
LV_SIGNAL_REFR_EXT_DRAW_PAD, /**< Object's extra padding has changed */ LV_SIGNAL_REFR_EXT_DRAW_PAD, /**< Object's extra padding has changed */
LV_SIGNAL_GET_TYPE, /**< LVGL needs to retrieve the object's type */
LV_SIGNAL_GET_STYLE, /**< Get the style of an object*/ LV_SIGNAL_GET_STYLE, /**< Get the style of an object*/
LV_SIGNAL_GET_SELF_SIZE, /**< Get the internal size of a widget*/ LV_SIGNAL_GET_SELF_SIZE, /**< Get the internal size of a widget*/
@@ -176,7 +175,7 @@ enum {
LV_OBJ_FLAG_SCROLL_ELASTIC = (1 << 5), LV_OBJ_FLAG_SCROLL_ELASTIC = (1 << 5),
LV_OBJ_FLAG_SCROLL_MOMENTUM = (1 << 6), LV_OBJ_FLAG_SCROLL_MOMENTUM = (1 << 6),
LV_OBJ_FLAG_SCROLL_STOP = (1 << 7), LV_OBJ_FLAG_SCROLL_STOP = (1 << 7),
LV_OBJ_FLAG_SCROLL_FREEZE = (1 << 8), /** Do not allow scrolling on this object and do not propagate the scroll to parent */ LV_OBJ_FLAG_SCROLL_CHAIN = (1 << 8), /** Allow propagating the scroll to a parent */
LV_OBJ_FLAG_SNAPABLE = (1 << 9), LV_OBJ_FLAG_SNAPABLE = (1 << 9),
LV_OBJ_FLAG_PRESS_LOCK = (1 << 10), LV_OBJ_FLAG_PRESS_LOCK = (1 << 10),
LV_OBJ_FLAG_EVENT_BUBBLE = (1 << 11), LV_OBJ_FLAG_EVENT_BUBBLE = (1 << 11),
@@ -195,8 +194,8 @@ typedef uint16_t lv_obj_flag_t;
typedef struct { typedef struct {
lv_ll_t child_ll; /**< Linked list to store the children objects*/ lv_obj_t ** children; /**< Store the pointer of the children.*/
uint32_t child_cnt;
#if LV_USE_GROUP != 0 #if LV_USE_GROUP != 0
void * group_p; void * group_p;
#endif #endif
@@ -223,32 +222,30 @@ typedef struct {
}lv_obj_spec_attr_t; }lv_obj_spec_attr_t;
struct _lv_obj_t { LV_CLASS_DECLARE_START(lv_obj, lv_base)
lv_obj_spec_attr_t * spec_attr;
struct _lv_obj_t * parent; /**< Pointer to the parent object*/
#define _lv_obj_constructor void (*constructor)(struct _lv_obj_t * obj, struct _lv_obj_t * parent, const struct _lv_obj_t * copy)
lv_signal_cb_t signal_cb; /**< Object type specific signal function*/ #define _lv_obj_data \
lv_design_cb_t design_cb; /**< Object type specific design function*/ _lv_base_data \
struct _lv_obj_t * parent; \
void * ext_attr; /**< Object type specific extended data*/ lv_obj_spec_attr_t * spec_attr; \
lv_style_list_t style_list; \
#if LV_USE_USER_DATA lv_area_t coords; \
lv_obj_user_data_t user_data; /**< Custom user data for object. */ lv_coord_t x_set; \
#endif lv_coord_t y_set; \
lv_coord_t w_set; \
lv_style_list_t style_list; lv_coord_t h_set; \
lv_obj_flag_t flags; \
/*Attributes and states*/
lv_obj_flag_t flags;
lv_state_t state; lv_state_t state;
lv_area_t coords; /**< Coordinates of the object (x1, y1, x2, y2)*/ #define _lv_obj_class_dsc \
lv_coord_t x_set; _lv_base_class_dsc \
lv_coord_t y_set; lv_signal_cb_t signal_cb; /**< Object type specific signal function*/ \
lv_coord_t w_set; lv_design_cb_t design_cb; /**< Object type specific design function*/
lv_coord_t h_set;
}; LV_CLASS_DECLARE_END(lv_obj, lv_base)
extern lv_obj_class_t lv_obj;
enum { enum {
LV_OBJ_PART_MAIN, LV_OBJ_PART_MAIN,
@@ -573,31 +570,15 @@ lv_disp_t * lv_obj_get_disp(const lv_obj_t * obj);
*/ */
lv_obj_t * lv_obj_get_parent(const lv_obj_t * obj); lv_obj_t * lv_obj_get_parent(const lv_obj_t * obj);
/**
* Iterate through the children of an object (start from the "youngest, lastly created")
* @param obj pointer to an object
* @param child NULL at first call to get the next children
* and the previous return value later
* @return the child after 'act_child' or NULL if no more child
*/
lv_obj_t * lv_obj_get_child(const lv_obj_t * obj, const lv_obj_t * child);
/**
* Iterate through the children of an object (start from the "oldest", firstly created)
* @param obj pointer to an object
* @param child NULL at first call to get the next children
* and the previous return value later
* @return the child after 'act_child' or NULL if no more child
*/
lv_obj_t * lv_obj_get_child_back(const lv_obj_t * obj, const lv_obj_t * child);
/** /**
* Get the Nth child of a an object. 0th is the lastly created. * Get the Nth child of a an object. 0th is the lastly created.
* @param obj pointer to an object whose children should be get * @param obj pointer to an object whose children should be get
* @param id of a child * @param id of a child
* @return the child or `NULL` if `id` was greater then the `number of children - 1` * @return the child or `NULL` if `id` was greater then the `number of children - 1`
*/ */
lv_obj_t * lv_obj_get_child_by_id(const lv_obj_t * obj, uint32_t id); lv_obj_t * lv_obj_get_child(const lv_obj_t * obj, uint32_t id);
uint32_t lv_obj_get_child_cnt(const lv_obj_t * obj);
/** /**
* Get the child index of an object. * Get the child index of an object.
@@ -748,16 +729,7 @@ void * lv_obj_get_group(const lv_obj_t * obj);
*/ */
bool lv_obj_is_focused(const lv_obj_t * obj); bool lv_obj_is_focused(const lv_obj_t * obj);
/** lv_obj_t ** lv_obj_get_children(const lv_obj_t * obj);
* Tell if an object is an instance of a certain widget type or not
* @param obj pointer to an object
* @param type_str the type to check. The name of the widget's type, g.g. "lv_label", "lv_btn", etc
* @return true: `obj` has the given type
* @note Not only the "final" type matters. Therefore every widget has "lv_obj" type and "lv_slider" is an "lv_bar" too.
*/
bool lv_obj_is_instance_of(lv_obj_t * obj, const char * type_str);
lv_ll_t * _lv_obj_get_child_ll(const lv_obj_t * obj) ;
/** /**
* Get the really focused object by taking `focus_parent` into account. * Get the really focused object by taking `focus_parent` into account.
@@ -770,15 +742,6 @@ lv_obj_t * _lv_obj_get_focused_obj(const lv_obj_t * obj);
* OTHER FUNCTIONS * OTHER FUNCTIONS
*------------------*/ *------------------*/
/**
* Used in the signal callback to handle `LV_SIGNAL_GET_TYPE` signal
* @param buf pointer to `lv_obj_type_t`. (`param` in the signal callback)
* @param name name of the object. E.g. "lv_btn". (Only the pointer is saved)
* @return LV_RES_OK
*/
lv_res_t _lv_obj_handle_get_type_signal(lv_obj_type_t * buf, const char * name);
/** /**
* Check if any object has a given type * Check if any object has a given type
* @param obj pointer to an object * @param obj pointer to an object

View File

@@ -386,7 +386,7 @@ void _lv_obj_refresh_ext_draw_pad(lv_obj_t * obj)
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_coord_t s = 0; lv_coord_t s = 0;
obj->signal_cb(obj, LV_SIGNAL_REFR_EXT_DRAW_PAD, &s); lv_signal_send(obj, LV_SIGNAL_REFR_EXT_DRAW_PAD, &s);
/*Store the result if the special attrs already allocated*/ /*Store the result if the special attrs already allocated*/
if(obj->spec_attr) { if(obj->spec_attr) {

View File

@@ -660,10 +660,10 @@ void _lv_obj_move_to(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, bool notify_par
_lv_obj_move_children_by(obj, diff.x, diff.y); _lv_obj_move_children_by(obj, diff.x, diff.y);
/*Inform the object about its new coordinates*/ /*Inform the object about its new coordinates*/
obj->signal_cb(obj, LV_SIGNAL_COORD_CHG, &ori); lv_signal_send(obj, LV_SIGNAL_COORD_CHG, &ori);
/*Send a signal to the parent too*/ /*Send a signal to the parent too*/
if(parent && notify_parent) parent->signal_cb(parent, LV_SIGNAL_CHILD_CHG, obj); if(parent && notify_parent) lv_signal_send(parent, LV_SIGNAL_CHILD_CHG, obj);
/*Invalidate the new area*/ /*Invalidate the new area*/
lv_obj_invalidate(obj); lv_obj_invalidate(obj);
@@ -678,15 +678,15 @@ void _lv_obj_move_to(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, bool notify_par
*/ */
void _lv_obj_move_children_by(lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_diff) void _lv_obj_move_children_by(lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_diff)
{ {
lv_obj_t * i; uint32_t i;
lv_ll_t * ll = _lv_obj_get_child_ll(obj); for(i = 0; i < lv_obj_get_child_cnt(obj); i++) {
_LV_LL_READ(ll, i) { lv_obj_t * child = lv_obj_get_child(obj, i);
i->coords.x1 += x_diff; child->coords.x1 += x_diff;
i->coords.y1 += y_diff; child->coords.y1 += y_diff;
i->coords.x2 += x_diff; child->coords.x2 += x_diff;
i->coords.y2 += y_diff; child->coords.y2 += y_diff;
_lv_obj_move_children_by(i, x_diff, y_diff); _lv_obj_move_children_by(child, x_diff, y_diff);
} }
} }
@@ -770,11 +770,11 @@ static bool refr_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h)
} }
/*Send a signal to the object with its new coordinates*/ /*Send a signal to the object with its new coordinates*/
obj->signal_cb(obj, LV_SIGNAL_COORD_CHG, &ori); lv_signal_send(obj, LV_SIGNAL_COORD_CHG, &ori);
/*Send a signal to the parent too*/ /*Send a signal to the parent too*/
lv_obj_t * par = lv_obj_get_parent(obj); lv_obj_t * par = lv_obj_get_parent(obj);
if(par != NULL) par->signal_cb(par, LV_SIGNAL_CHILD_CHG, obj); if(par != NULL) lv_signal_send(par, LV_SIGNAL_CHILD_CHG, obj);
/*Invalidate the new area*/ /*Invalidate the new area*/
lv_obj_invalidate(obj); lv_obj_invalidate(obj);

View File

@@ -127,19 +127,12 @@ lv_coord_t lv_obj_get_scroll_bottom(lv_obj_t * obj)
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_coord_t child_res = LV_COORD_MIN; lv_coord_t child_res = LV_COORD_MIN;
uint32_t i;
lv_obj_t * child = lv_obj_get_child(obj, NULL); for(i = 0; i < lv_obj_get_child_cnt(obj); i++) {
if(child) { lv_obj_t * child = lv_obj_get_child(obj, i);
lv_coord_t y2 = LV_COORD_MIN; child_res = LV_MATH_MAX(child_res, child->coords.y2 + lv_obj_get_style_margin_bottom(child, LV_OBJ_PART_MAIN));
while(child) {
y2 = LV_MATH_MAX(y2, child->coords.y2 + lv_obj_get_style_margin_bottom(child, LV_OBJ_PART_MAIN));
child = lv_obj_get_child(obj, child);
} }
child_res = y2;
}
lv_coord_t pad_top = lv_obj_get_style_pad_top(obj, LV_OBJ_PART_MAIN); lv_coord_t pad_top = lv_obj_get_style_pad_top(obj, LV_OBJ_PART_MAIN);
lv_coord_t pad_bottom = lv_obj_get_style_pad_bottom(obj, LV_OBJ_PART_MAIN); lv_coord_t pad_bottom = lv_obj_get_style_pad_bottom(obj, LV_OBJ_PART_MAIN);
@@ -167,15 +160,17 @@ lv_coord_t lv_obj_get_scroll_left(lv_obj_t * obj)
lv_coord_t pad_left = lv_obj_get_style_pad_left(obj, LV_OBJ_PART_MAIN); lv_coord_t pad_left = lv_obj_get_style_pad_left(obj, LV_OBJ_PART_MAIN);
lv_coord_t child_res = 0; lv_coord_t child_res = 0;
lv_obj_t * child = lv_obj_get_child(obj, NULL);
if(child) {
lv_coord_t x1 = LV_COORD_MAX;
while(child) {
x1 = LV_MATH_MIN(x1, child->coords.x1 - lv_obj_get_style_margin_left(child, LV_OBJ_PART_MAIN));
child = lv_obj_get_child(obj, child);
}
child_res = x1;
uint32_t i;
lv_coord_t x1 = LV_COORD_MAX;
for(i = 0; i < lv_obj_get_child_cnt(obj); i++) {
lv_obj_t * child = lv_obj_get_child(obj, i);
x1 = LV_MATH_MIN(x1, child->coords.x1 - lv_obj_get_style_margin_left(child, LV_OBJ_PART_MAIN));
}
if(x1 != LV_COORD_MAX) {
child_res = x1;
child_res = (obj->coords.x1 + pad_left) - child_res; child_res = (obj->coords.x1 + pad_left) - child_res;
} }
@@ -199,15 +194,10 @@ lv_coord_t lv_obj_get_scroll_right(lv_obj_t * obj)
/*With other base direction (LTR) scrolling to the right is normal so find the right most coordinate*/ /*With other base direction (LTR) scrolling to the right is normal so find the right most coordinate*/
lv_coord_t child_res = LV_COORD_MIN; lv_coord_t child_res = LV_COORD_MIN;
lv_obj_t * child = lv_obj_get_child(obj, NULL); uint32_t i;
if(child) { for(i = 0; i < lv_obj_get_child_cnt(obj); i++) {
lv_coord_t x2 = LV_COORD_MIN; lv_obj_t * child = lv_obj_get_child(obj, i);
while(child) { child_res = LV_MATH_MAX(child_res, child->coords.x2 + lv_obj_get_style_margin_right(child, LV_OBJ_PART_MAIN));
x2 = LV_MATH_MAX(x2, child->coords.x2 + lv_obj_get_style_margin_right(child, LV_OBJ_PART_MAIN));
child = lv_obj_get_child(obj, child);
}
child_res = x2;
} }
lv_coord_t pad_right = lv_obj_get_style_pad_right(obj, LV_OBJ_PART_MAIN); lv_coord_t pad_right = lv_obj_get_style_pad_right(obj, LV_OBJ_PART_MAIN);

View File

@@ -190,9 +190,9 @@ void lv_obj_report_style_change(lv_style_t * style)
lv_disp_t * d = lv_disp_get_next(NULL); lv_disp_t * d = lv_disp_get_next(NULL);
while(d) { while(d) {
lv_obj_t * i; uint32_t i;
_LV_LL_READ(&d->scr_ll, i) { for(i = 0; i < d->screen_cnt; i++) {
report_style_change_core(style, i); report_style_change_core(style, d->screens[i]);
} }
d = lv_disp_get_next(d); d = lv_disp_get_next(d);
} }
@@ -318,10 +318,10 @@ void _lv_obj_invalidate_style_cache(lv_obj_t * obj, uint8_t part, lv_style_prope
list->valid_cache = 0; list->valid_cache = 0;
} }
lv_obj_t * child = lv_obj_get_child(obj, NULL); uint32_t i;
while(child) { for(i = 0; i < lv_obj_get_child_cnt(obj); i++) {
lv_obj_t * child = lv_obj_get_child(obj, i);
update_style_cache_children(child); update_style_cache_children(child);
child = lv_obj_get_child(obj, child);
} }
} }
#endif /*LV_STYLE_CACHE_LEVEL >= 1*/ #endif /*LV_STYLE_CACHE_LEVEL >= 1*/
@@ -871,7 +871,7 @@ void _lv_obj_refresh_style(lv_obj_t * obj, uint8_t part, lv_style_property_t pro
if(real_refr) { if(real_refr) {
lv_obj_invalidate(obj); lv_obj_invalidate(obj);
obj->signal_cb(obj, LV_SIGNAL_STYLE_CHG, NULL); lv_signal_send(obj, LV_SIGNAL_STYLE_CHG, NULL);
switch(prop) { switch(prop) {
case LV_STYLE_PROP_ALL: case LV_STYLE_PROP_ALL:
@@ -879,7 +879,7 @@ void _lv_obj_refresh_style(lv_obj_t * obj, uint8_t part, lv_style_property_t pro
case LV_STYLE_MARGIN_BOTTOM: case LV_STYLE_MARGIN_BOTTOM:
case LV_STYLE_MARGIN_LEFT: case LV_STYLE_MARGIN_LEFT:
case LV_STYLE_MARGIN_RIGHT: case LV_STYLE_MARGIN_RIGHT:
if(obj->parent) obj->parent->signal_cb(obj->parent, LV_SIGNAL_CHILD_CHG, obj); if(obj->parent) lv_signal_send(obj->parent, LV_SIGNAL_CHILD_CHG, obj);
break; break;
} }
@@ -1099,12 +1099,11 @@ static void report_style_change_core(void * style, lv_obj_t * obj)
} }
} }
lv_obj_t * child = lv_obj_get_child(obj, NULL); uint32_t i;
while(child) { for(i = 0; i < lv_obj_get_child_cnt(obj); i++) {
lv_obj_t * child = lv_obj_get_child(obj, i);
report_style_change_core(style, child); report_style_change_core(style, child);
child = lv_obj_get_child(obj, child);
} }
} }
/** /**
@@ -1114,14 +1113,14 @@ static void report_style_change_core(void * style, lv_obj_t * obj)
*/ */
static void refresh_children_style(lv_obj_t * obj) static void refresh_children_style(lv_obj_t * obj)
{ {
lv_obj_t * child = lv_obj_get_child(obj, NULL); uint32_t i;
while(child != NULL) { for(i = 0; i < lv_obj_get_child_cnt(obj); i++) {
lv_obj_t * child = lv_obj_get_child(obj, i);
lv_obj_invalidate(child); lv_obj_invalidate(child);
child->signal_cb(child, LV_SIGNAL_STYLE_CHG, NULL); lv_signal_send(child, LV_SIGNAL_STYLE_CHG, NULL);
lv_obj_invalidate(child); lv_obj_invalidate(child);
refresh_children_style(child); /*Check children too*/ refresh_children_style(child); /*Check children too*/
child = lv_obj_get_child(obj, child);
} }
} }
@@ -1514,10 +1513,10 @@ static void update_style_cache_children(lv_obj_t * obj)
list->ignore_cache = ignore_cache_ori; list->ignore_cache = ignore_cache_ori;
} }
lv_obj_t * child = lv_obj_get_child(obj, NULL); uint32_t i;
while(child) { for(i = 0; i < lv_obj_get_child_cnt(obj); i++) {
lv_obj_t * child = lv_obj_get_child(obj, i);
update_style_cache_children(child); update_style_cache_children(child);
child = lv_obj_get_child(obj, child);
} }
} }

View File

@@ -594,7 +594,7 @@ static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj)
/*If this object is fully cover the draw area check the children too */ /*If this object is fully cover the draw area check the children too */
if(_lv_area_is_in(area_p, &obj->coords, 0) && lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN) == false) { if(_lv_area_is_in(area_p, &obj->coords, 0) && lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN) == false) {
lv_design_res_t design_res = obj->design_cb(obj, area_p, LV_DESIGN_COVER_CHK); lv_design_res_t design_res = obj->class_p->design_cb(obj, area_p, LV_DESIGN_COVER_CHK);
if(design_res == LV_DESIGN_RES_MASKED) return NULL; if(design_res == LV_DESIGN_RES_MASKED) return NULL;
#if LV_USE_OPA_SCALE #if LV_USE_OPA_SCALE
@@ -603,10 +603,10 @@ static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj)
} }
#endif #endif
lv_obj_t * i; uint32_t i;
lv_ll_t * ll = _lv_obj_get_child_ll(obj); for(i = 0; i < lv_obj_get_child_cnt(obj); i++) {
_LV_LL_READ(ll, i) { lv_obj_t * child = lv_obj_get_child(obj, i);
found_p = lv_refr_get_top_obj(area_p, i); found_p = lv_refr_get_top_obj(area_p, child);
/*If a children is ok then break*/ /*If a children is ok then break*/
if(found_p != NULL) { if(found_p != NULL) {
@@ -649,20 +649,22 @@ static void lv_refr_obj_and_children(lv_obj_t * top_p, const lv_area_t * mask_p)
/*Do until not reach the screen*/ /*Do until not reach the screen*/
while(par != NULL) { while(par != NULL) {
lv_ll_t * ll = _lv_obj_get_child_ll(par); bool go = false;
/*object before border_p has to be redrawn*/ uint32_t i;
lv_obj_t * i = _lv_ll_get_prev(ll, border_p); for(i = 0; i < lv_obj_get_child_cnt(par); i++) {
lv_obj_t * child = lv_obj_get_child(par, i);
while(i != NULL) { if(!go) {
if(child == border_p) go = true;
} else {
/*Refresh the objects*/ /*Refresh the objects*/
lv_refr_obj(i, mask_p); lv_refr_obj(child, mask_p);
i = _lv_ll_get_prev(ll, i); }
} }
/*Call the post draw design function of the parents of the to object*/ /*Call the post draw design function of the parents of the to object*/
if(par->design_cb) par->design_cb(par, mask_p, LV_DESIGN_DRAW_POST); par->class_p->design_cb(par, mask_p, LV_DESIGN_DRAW_POST);
/*The new border will be there last parents, /*The new border will be the last parents,
*so the 'younger' brothers of parent will be refreshed*/ *so the 'younger' brothers of parent will be refreshed*/
border_p = par; border_p = par;
/*Go a level deeper*/ /*Go a level deeper*/
@@ -696,9 +698,8 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
/*Draw the parent and its children only if they ore on 'mask_parent'*/ /*Draw the parent and its children only if they ore on 'mask_parent'*/
if(union_ok != false) { if(union_ok != false) {
/* Redraw the object */ /* Redraw the object */
if(obj->design_cb) obj->design_cb(obj, &obj_ext_mask, LV_DESIGN_DRAW_MAIN); obj->class_p->design_cb(obj, &obj_ext_mask, LV_DESIGN_DRAW_MAIN);
#if MASK_AREA_DEBUG #if MASK_AREA_DEBUG
static lv_color_t debug_color = LV_COLOR_RED; static lv_color_t debug_color = LV_COLOR_RED;
@@ -722,12 +723,12 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
union_ok = _lv_area_intersect(&obj_mask, mask_ori_p, &obj_area); union_ok = _lv_area_intersect(&obj_mask, mask_ori_p, &obj_area);
if(union_ok != false) { if(union_ok != false) {
lv_area_t mask_child; /*Mask from obj and its child*/ lv_area_t mask_child; /*Mask from obj and its child*/
lv_obj_t * child_p;
lv_area_t child_area; lv_area_t child_area;
lv_ll_t * ll = _lv_obj_get_child_ll(obj); uint32_t i;
_LV_LL_READ_BACK(ll, child_p) { for(i = 0; i < lv_obj_get_child_cnt(obj); i++) {
lv_obj_get_coords(child_p, &child_area); lv_obj_t * child = lv_obj_get_child(obj, i);
ext_size = _lv_obj_get_ext_draw_pad(child_p); lv_obj_get_coords(child, &child_area);
ext_size = _lv_obj_get_ext_draw_pad(child);
child_area.x1 -= ext_size; child_area.x1 -= ext_size;
child_area.y1 -= ext_size; child_area.y1 -= ext_size;
child_area.x2 += ext_size; child_area.x2 += ext_size;
@@ -739,13 +740,13 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
/*If the parent and the child has common area then refresh the child */ /*If the parent and the child has common area then refresh the child */
if(union_ok) { if(union_ok) {
/*Refresh the next children*/ /*Refresh the next children*/
lv_refr_obj(child_p, &mask_child); lv_refr_obj(child, &mask_child);
} }
} }
} }
/* If all the children are redrawn make 'post draw' design */ /* If all the children are redrawn make 'post draw' design */
if(obj->design_cb) obj->design_cb(obj, &obj_ext_mask, LV_DESIGN_DRAW_POST); obj->class_p->design_cb(obj, &obj_ext_mask, LV_DESIGN_DRAW_POST);
} }
} }

View File

@@ -128,7 +128,6 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
_lv_memset_00(disp, sizeof(lv_disp_t)); _lv_memset_00(disp, sizeof(lv_disp_t));
_lv_memcpy(&disp->driver, driver, sizeof(lv_disp_drv_t)); _lv_memcpy(&disp->driver, driver, sizeof(lv_disp_drv_t));
_lv_ll_init(&disp->scr_ll, sizeof(lv_obj_t));
disp->last_activity_time = 0; disp->last_activity_time = 0;
if(disp_def == NULL) disp_def = disp; if(disp_def == NULL) disp_def = disp;
@@ -187,9 +186,9 @@ void lv_disp_drv_update(lv_disp_t * disp, lv_disp_drv_t * new_drv)
{ {
memcpy(&disp->driver, new_drv, sizeof(lv_disp_drv_t)); memcpy(&disp->driver, new_drv, sizeof(lv_disp_drv_t));
lv_obj_t * scr; uint32_t i;
_LV_LL_READ(&disp->scr_ll, scr) { for(i = 0; disp->screens[i]; i++) {
lv_obj_set_size(scr, lv_disp_get_hor_res(disp), lv_disp_get_ver_res(disp)); lv_obj_set_size(disp->screens[i], lv_disp_get_hor_res(disp), lv_disp_get_ver_res(disp));
} }
} }

View File

@@ -152,12 +152,12 @@ typedef struct _disp_t {
lv_timer_t * refr_task; lv_timer_t * refr_task;
/** Screens of the display*/ /** Screens of the display*/
lv_ll_t scr_ll; struct _lv_obj_t ** screens; /**< Array of screen objects. `NULL` terminated*/
struct _lv_obj_t * act_scr; /**< Currently active screen on this display */ struct _lv_obj_t * act_scr; /**< Currently active screen on this display */
struct _lv_obj_t * prev_scr; /**< Previous screen. Used during screen animations */ struct _lv_obj_t * prev_scr; /**< Previous screen. Used during screen animations */
struct _lv_obj_t * top_layer; /**< @see lv_disp_get_layer_top */ struct _lv_obj_t * top_layer; /**< @see lv_disp_get_layer_top */
struct _lv_obj_t * sys_layer; /**< @see lv_disp_get_layer_sys */ struct _lv_obj_t * sys_layer; /**< @see lv_disp_get_layer_sys */
uint32_t screen_cnt;
uint8_t del_prev : uint8_t del_prev :
1; /**< 1: Automatically delete the previous screen when the screen load animation is ready */ 1; /**< 1: Automatically delete the previous screen when the screen load animation is ready */

View File

@@ -20,7 +20,6 @@
/********************** /**********************
* STATIC PROTOTYPES * STATIC PROTOTYPES
**********************/ **********************/
static void lv_class_base_construct(void * inst);
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
@@ -45,60 +44,43 @@ void _lv_class_init(void * class_p, uint32_t class_size, uint32_t instance_size,
if(bc) _lv_memcpy(c, base_p, bc->_class_size); if(bc) _lv_memcpy(c, base_p, bc->_class_size);
c->base_p = base_p; /*Save the base to allow accessing its methods later*/ c->base_p = base_p; /*Save the base to allow accessing its methods later*/
c->constructor_cb = lv_class_base_construct; c->constructor = NULL;
c->_instance_size = instance_size; c->_instance_size = instance_size;
c->_class_size = class_size; c->_class_size = class_size;
c->_inited = 1; c->_inited = 1;
} }
void * _lv_class_new(void * class_p) void * lv_class_new(void * class_p)
{ {
lv_base_class_t * base_class_p = class_p; lv_base_class_t * base_class_p = class_p;
lv_base_t * instance = lv_mem_alloc(base_class_p->_instance_size); lv_base_t * instance = lv_mem_alloc(base_class_p->_instance_size);
_lv_memset_00(instance, base_class_p->_instance_size); _lv_memset_00(instance, base_class_p->_instance_size);
instance->class_p = class_p; instance->class_p = class_p;
// instance->_dynamic = 1;
/*Call the constructor of base classes and this class*/
lv_class_construct(instance, class_p);
instance->_dynamic = 1;
return instance; return instance;
} }
void * _lv_class_new_static(void * class_p, void * instance)
void lv_class_destroy(void * instance)
{ {
lv_base_class_t * base_class_p = class_p; lv_mem_free(instance);
lv_base_t * base_inst = instance;
_lv_memset_00(base_inst, base_class_p->_instance_size);
base_inst->class_p = class_p;
/*Call the constructor of base classes and this class*/
lv_class_construct(instance, class_p);
base_inst->_dynamic = 0;
return instance;
} }
/**
* Recursively call all constructor of base(s). Starting from the the oldest.
* @param inst pointer to an instance
* @param dsc pointer to the class dsc whose constructor should be called
*/
void lv_class_construct(void * inst, lv_base_class_t * dsc)
{
if(dsc->base_p) lv_class_construct(inst, dsc->base_p);
if(dsc->constructor_cb) dsc->constructor_cb(inst);
}
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
//static void desctructor_chain(void * inst)
//{
// lv_base_t * base_inst = inst;
// if(base->)
//}
/** /**
* Constructor of the base class. Just zero out the instance * Constructor of the base class. Just zero out the instance
* @param inst pointer to an instance * @param inst pointer to an instance
*/ */
static void lv_class_base_construct(void * inst) void lv_class_base_construct(void * inst)
{ {
lv_base_t * base_inst = inst; lv_base_t * base_inst = inst;
void * class_p = base_inst->class_p; void * class_p = base_inst->class_p;

View File

@@ -10,6 +10,32 @@
extern "C" { extern "C" {
#endif #endif
/* EXAMPLE CLASS DECLARATION
LV_CLASS_DECLARE_START(person, lv_base)
#define _person_create struct _person_t * (*create)(struct _person_t * father, struct _person_t * mother)
#define _person_create_static struct _person_t * (*create_static)(struct _person_t * p, struct _person_t * father, struct _person_t * mother)
#define _person_data \
_lv_base_data \
bool male; \
char name[64]; \
uint32_t age; \
struct _person_t * mother; \
struct _person_t * father; \
#define _person_class_dsc \
_lv_base_class_dsc \
uint32_t max_age; \
void (*set_name)(struct _person_t * p, const char * name);
LV_CLASS_DECLARE_END(person, lv_base)
*/
/********************* /*********************
* INCLUDES * INCLUDES
*********************/ *********************/
@@ -18,27 +44,22 @@ extern "C" {
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
#define LV_CLASS_MIXIN_EMPTY
#define _lv_base_class_dsc \ #define _lv_base_class_dsc \
void(*constructor_cb)(void * inst); \ void(*destructor)(void * inst); \
void(*descructor_cb)(void * inst); \
uint32_t _instance_size; \ uint32_t _instance_size; \
uint32_t _class_size; \ uint32_t _class_size; \
uint32_t _inited :1; uint32_t _inited :1;
#define _lv_base_data \ #define _lv_base_data
uint32_t _dynamic :1;
/********************** /**********************
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
/*Just to have a type that can be referenced later*/
typedef struct _lv_base_class_t typedef struct _lv_base_class_t
{ {
struct _lv_base_class_t * base_p; struct _lv_base_class_t * base_p;
void * (*create)(void); void (*constructor)(void *);
void (*create_static)(void *);
_lv_base_class_dsc _lv_base_class_dsc
}lv_base_class_t; }lv_base_class_t;
@@ -65,8 +86,9 @@ void _lv_class_init(void * class_p, uint32_t class_size, uint32_t instance_size,
* @param class pointer to a class to create * @param class pointer to a class to create
* @return the created instance * @return the created instance
*/ */
void * _lv_class_new(void * class_p); void * lv_class_new(void * class_p);
void lv_class_base_construct(void * inst);
void lv_class_destroy(void * instance);
void lv_class_construct(void * inst, lv_base_class_t * dsc); void lv_class_construct(void * inst, lv_base_class_t * dsc);
@@ -89,8 +111,7 @@ struct _##classname##_class_t; \
#define LV_CLASS_DECLARE_END(classname, basename) \ #define LV_CLASS_DECLARE_END(classname, basename) \
typedef struct _##classname##_class_t { \ typedef struct _##classname##_class_t { \
basename##_class_t * base_p; \ basename##_class_t * base_p; \
_##classname##_create; \ _##classname##_constructor; \
_##classname##_create_static; \
_##classname##_class_dsc \ _##classname##_class_dsc \
}classname##_class_t; \ }classname##_class_t; \
\ \
@@ -99,6 +120,23 @@ typedef struct _##classname##_t { \
_##classname##_data \ _##classname##_data \
} classname##_t; } classname##_t;
/**
* Start the constructor
* Makes the instance look like to instance of the class where the constructor is called.
* It's important because the virtual functions should be called from the level of the constructor.
*/
#define LV_CLASS_CONSTRUCTOR_BEGIN(inst, classname) \
void * _original_class_p = ((lv_base_t*)inst)->class_p; \
obj->class_p = (void*)&classname;
/**
* Finish the constructor.
* It reverts the original base class (changed by LV_CLASS_CONSTRUCTOR_BEGIN).
*/
#define LV_CLASS_CONSTRUCTOR_END(inst, classname) \
((lv_base_t*)inst)->class_p = _original_class_p;
/** /**
* Initialize a class. Need to be called only once for every class * Initialize a class. Need to be called only once for every class
*/ */

View File

@@ -161,10 +161,7 @@ void * lv_mem_alloc(size_t size)
return &zero_mem; return &zero_mem;
} }
// last_ent = NULL; printf("alloc:%d\n", size);
static uint32_t c = 0;
c++;
// if(c%10 == 0) printf("alloc:%d\n", c);
#ifdef LV_ARCH_64 #ifdef LV_ARCH_64
/*Round the size up to 8*/ /*Round the size up to 8*/

View File

@@ -38,16 +38,18 @@
/********************** /**********************
* STATIC PROTOTYPES * STATIC PROTOTYPES
**********************/ **********************/
static void lv_bar_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy);
static void lv_bar_destructor(void * obj);
static lv_design_res_t lv_bar_design(lv_obj_t * bar, const lv_area_t * clip_area, lv_design_mode_t mode); static lv_design_res_t lv_bar_design(lv_obj_t * bar, const lv_area_t * clip_area, lv_design_mode_t mode);
static lv_res_t lv_bar_signal(lv_obj_t * bar, lv_signal_t sign, void * param); static lv_res_t lv_bar_signal(lv_obj_t * bar, lv_signal_t sign, void * param);
static lv_style_list_t * lv_bar_get_style(lv_obj_t * bar, uint8_t part); static lv_style_list_t * lv_bar_get_style(lv_bar_t * bar, uint8_t part);
static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area); static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area);
#if LV_USE_ANIMATION #if LV_USE_ANIMATION
static void lv_bar_set_value_with_anim(lv_obj_t * bar, int16_t new_value, int16_t * value_ptr, static void lv_bar_set_value_with_anim(lv_bar_t * bar, int16_t new_value, int16_t * value_ptr,
lv_bar_anim_t * anim_info, lv_anim_enable_t en); lv_bar_anim_t * anim_info, lv_anim_enable_t en);
static void lv_bar_init_anim(lv_obj_t * bar, lv_bar_anim_t * bar_anim); static void lv_bar_init_anim(lv_bar_t * bar, lv_bar_anim_t * bar_anim);
static void lv_bar_anim(lv_bar_anim_t * bar, lv_anim_value_t value); static void lv_bar_anim(lv_bar_anim_t * bar, lv_anim_value_t value);
static void lv_bar_anim_ready(lv_anim_t * a); static void lv_bar_anim_ready(lv_anim_t * a);
#endif #endif
@@ -55,8 +57,7 @@ static void lv_bar_anim_ready(lv_anim_t * a);
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
**********************/ **********************/
static lv_design_cb_t ancestor_design; lv_bar_class_t lv_bar;
static lv_signal_cb_t ancestor_signal;
/********************** /**********************
* MACROS * MACROS
@@ -75,65 +76,26 @@ static lv_signal_cb_t ancestor_signal;
*/ */
lv_obj_t * lv_bar_create(lv_obj_t * parent, const lv_obj_t * copy) lv_obj_t * lv_bar_create(lv_obj_t * parent, const lv_obj_t * copy)
{ {
LV_LOG_TRACE("lv_bar create started"); if(!lv_bar._inited) {
LV_CLASS_INIT(lv_bar, lv_obj);
/*Create the ancestor basic object*/ lv_bar.constructor = lv_bar_constructor;
lv_obj_t * bar = lv_obj_create(parent, copy); lv_bar.destructor = lv_bar_destructor;
LV_ASSERT_MEM(bar); lv_bar.design_cb = lv_bar_design;
if(bar == NULL) return NULL; lv_bar.signal_cb = lv_bar_signal;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(bar);
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(bar);
/*Allocate the object type specific extended data*/
lv_bar_ext_t * ext = lv_obj_allocate_ext_attr(bar, sizeof(lv_bar_ext_t));
LV_ASSERT_MEM(ext);
if(ext == NULL) {
lv_obj_del(bar);
return NULL;
} }
ext->min_value = 0; lv_obj_t * obj = lv_class_new(&lv_bar);
ext->start_value = 0; lv_bar.constructor(obj, parent, copy);
ext->max_value = 100;
ext->cur_value = 0;
#if LV_USE_ANIMATION
ext->anim_time = 200;
lv_bar_init_anim(bar, &ext->cur_value_anim);
lv_bar_init_anim(bar, &ext->start_value_anim);
#endif
ext->type = LV_BAR_TYPE_NORMAL;
lv_style_list_init(&ext->style_indic); lv_bar_t * bar = (lv_bar_t *) obj;
const lv_bar_t * bar_copy = (const lv_bar_t *) copy;
lv_obj_set_signal_cb(bar, lv_bar_signal); if(!copy) lv_theme_apply(obj, LV_THEME_BAR);
lv_obj_set_design_cb(bar, lv_bar_design); else {
lv_style_list_copy(&bar->style_indic, &bar_copy->style_indic);
if(copy == NULL) { _lv_obj_refresh_style(obj, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
lv_obj_clear_flag(bar, LV_OBJ_FLAG_CHECKABLE);
lv_obj_clear_flag(bar, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_size(bar, LV_DPI * 2, LV_DPI / 10);
lv_bar_set_value(bar, ext->cur_value, false);
lv_theme_apply(bar, LV_THEME_BAR);
} else {
lv_bar_ext_t * ext_copy = lv_obj_get_ext_attr(copy);
ext->min_value = ext_copy->min_value;
ext->start_value = ext_copy->start_value;
ext->max_value = ext_copy->max_value;
ext->cur_value = ext_copy->cur_value;
ext->type = ext_copy->type;
lv_style_list_copy(&ext->style_indic, &ext_copy->style_indic);
/*Refresh the style with new signal function*/
_lv_obj_refresh_style(bar, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
lv_bar_set_value(bar, ext->cur_value, LV_ANIM_OFF);
} }
LV_LOG_INFO("bar created");
return bar; return obj;
} }
/*===================== /*=====================
@@ -146,26 +108,26 @@ lv_obj_t * lv_bar_create(lv_obj_t * parent, const lv_obj_t * copy)
* @param value new value * @param value new value
* @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately
*/ */
void lv_bar_set_value(lv_obj_t * bar, int16_t value, lv_anim_enable_t anim) void lv_bar_set_value(lv_obj_t * obj, int16_t value, lv_anim_enable_t anim)
{ {
LV_ASSERT_OBJ(bar, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_bar_t * bar = (lv_bar_t *)obj;
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar); if(bar->cur_value == value) return;
if(ext->cur_value == value) return;
int16_t new_value = value; int16_t new_value = value;
new_value = value > ext->max_value ? ext->max_value : new_value; new_value = value > bar->max_value ? bar->max_value : new_value;
new_value = new_value < ext->min_value ? ext->min_value : new_value; new_value = new_value < bar->min_value ? bar->min_value : new_value;
new_value = new_value < ext->start_value ? ext->start_value : new_value; new_value = new_value < bar->start_value ? bar->start_value : new_value;
if(ext->cur_value == new_value) return; if(bar->cur_value == new_value) return;
#if LV_USE_ANIMATION == 0 #if LV_USE_ANIMATION == 0
LV_UNUSED(anim); LV_UNUSED(anim);
ext->cur_value = new_value; bar->cur_value = new_value;
lv_obj_invalidate(bar); lv_obj_invalidate(bar);
#else #else
lv_bar_set_value_with_anim(bar, new_value, &ext->cur_value, &ext->cur_value_anim, anim); lv_bar_set_value_with_anim(bar, new_value, &bar->cur_value, &bar->cur_value_anim, anim);
#endif #endif
} }
@@ -175,24 +137,23 @@ void lv_bar_set_value(lv_obj_t * bar, int16_t value, lv_anim_enable_t anim)
* @param value new start value * @param value new start value
* @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately
*/ */
void lv_bar_set_start_value(lv_obj_t * bar, int16_t start_value, lv_anim_enable_t anim) void lv_bar_set_start_value(lv_obj_t * obj, int16_t start_value, lv_anim_enable_t anim)
{ {
LV_ASSERT_OBJ(bar, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar); lv_bar_t * bar = (lv_bar_t *)obj;
if(ext->start_value == start_value) return;
int16_t new_value = start_value; int16_t new_value = start_value;
new_value = new_value > ext->max_value ? ext->max_value : new_value; new_value = new_value > bar->max_value ? bar->max_value : new_value;
new_value = new_value < ext->min_value ? ext->min_value : new_value; new_value = new_value < bar->min_value ? bar->min_value : new_value;
new_value = new_value > ext->cur_value ? ext->cur_value : new_value; new_value = new_value > bar->cur_value ? bar->cur_value : new_value;
if(ext->start_value == new_value) return; if(bar->start_value == new_value) return;
#if LV_USE_ANIMATION == 0 #if LV_USE_ANIMATION == 0
LV_UNUSED(anim); LV_UNUSED(anim);
ext->start_value = new_value; bar->start_value = new_value;
#else #else
lv_bar_set_value_with_anim(bar, new_value, &ext->start_value, &ext->start_value_anim, anim); lv_bar_set_value_with_anim(bar, new_value, &bar->start_value, &bar->start_value_anim, anim);
#endif #endif
} }
@@ -202,28 +163,28 @@ void lv_bar_set_start_value(lv_obj_t * bar, int16_t start_value, lv_anim_enable_
* @param min minimum value * @param min minimum value
* @param max maximum value * @param max maximum value
*/ */
void lv_bar_set_range(lv_obj_t * bar, int16_t min, int16_t max) void lv_bar_set_range(lv_obj_t * obj, int16_t min, int16_t max)
{ {
LV_ASSERT_OBJ(bar, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_bar_t * bar = (lv_bar_t *)obj;
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar); if(bar->min_value == min && bar->max_value == max) return;
if(ext->min_value == min && ext->max_value == max) return;
ext->max_value = max; bar->max_value = max;
ext->min_value = min; bar->min_value = min;
if(lv_bar_get_type(bar) != LV_BAR_TYPE_CUSTOM) if(lv_bar_get_type(obj) != LV_BAR_TYPE_CUSTOM)
ext->start_value = min; bar->start_value = min;
if(ext->cur_value > max) { if(bar->cur_value > max) {
ext->cur_value = max; bar->cur_value = max;
lv_bar_set_value(bar, ext->cur_value, false); lv_bar_set_value(obj, bar->cur_value, false);
} }
if(ext->cur_value < min) { if(bar->cur_value < min) {
ext->cur_value = min; bar->cur_value = min;
lv_bar_set_value(bar, ext->cur_value, false); lv_bar_set_value(obj, bar->cur_value, false);
} }
lv_obj_invalidate(bar); lv_obj_invalidate(obj);
} }
/** /**
@@ -231,16 +192,16 @@ void lv_bar_set_range(lv_obj_t * bar, int16_t min, int16_t max)
* @param bar pointer to bar object * @param bar pointer to bar object
* @param type bar type * @param type bar type
*/ */
void lv_bar_set_type(lv_obj_t * bar, lv_bar_type_t type) void lv_bar_set_type(lv_obj_t * obj, lv_bar_type_t type)
{ {
LV_ASSERT_OBJ(bar, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_bar_t * bar = (lv_bar_t *)obj;
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar); bar->type = type;
ext->type = type; if(bar->type != LV_BAR_TYPE_CUSTOM)
if(ext->type != LV_BAR_TYPE_CUSTOM) bar->start_value = bar->min_value;
ext->start_value = ext->min_value;
lv_obj_invalidate(bar); lv_obj_invalidate(obj);
} }
/** /**
@@ -248,13 +209,13 @@ void lv_bar_set_type(lv_obj_t * bar, lv_bar_type_t type)
* @param bar pointer to a bar object * @param bar pointer to a bar object
* @param anim_time the animation time in milliseconds. * @param anim_time the animation time in milliseconds.
*/ */
void lv_bar_set_anim_time(lv_obj_t * bar, uint16_t anim_time) void lv_bar_set_anim_time(lv_obj_t * obj, uint16_t anim_time)
{ {
LV_ASSERT_OBJ(bar, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
#if LV_USE_ANIMATION #if LV_USE_ANIMATION
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar); lv_bar_t * bar = (lv_bar_t *)obj;
ext->anim_time = anim_time; bar->anim_time = anim_time;
#else #else
(void)bar; /*Unused*/ (void)bar; /*Unused*/
(void)anim_time; /*Unused*/ (void)anim_time; /*Unused*/
@@ -270,12 +231,12 @@ void lv_bar_set_anim_time(lv_obj_t * bar, uint16_t anim_time)
* @param bar pointer to a bar object * @param bar pointer to a bar object
* @return the value of the bar * @return the value of the bar
*/ */
int16_t lv_bar_get_value(const lv_obj_t * bar) int16_t lv_bar_get_value(const lv_obj_t * obj)
{ {
LV_ASSERT_OBJ(bar, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_bar_t * bar = (lv_bar_t *)obj;
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar); return LV_BAR_GET_ANIM_VALUE(bar->cur_value, bar->cur_value_anim);
return LV_BAR_GET_ANIM_VALUE(ext->cur_value, ext->cur_value_anim);
} }
/** /**
@@ -283,15 +244,14 @@ int16_t lv_bar_get_value(const lv_obj_t * bar)
* @param bar pointer to a bar object * @param bar pointer to a bar object
* @return the start value of the bar * @return the start value of the bar
*/ */
int16_t lv_bar_get_start_value(const lv_obj_t * bar) int16_t lv_bar_get_start_value(const lv_obj_t * obj)
{ {
LV_ASSERT_OBJ(bar, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_bar_t * bar = (lv_bar_t *)obj;
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar); if(bar->type != LV_BAR_TYPE_CUSTOM) return bar->min_value;
if(ext->type != LV_BAR_TYPE_CUSTOM) return ext->min_value; return LV_BAR_GET_ANIM_VALUE(bar->start_value, bar->start_value_anim);
return LV_BAR_GET_ANIM_VALUE(ext->start_value, ext->start_value_anim);
} }
/** /**
@@ -299,12 +259,11 @@ int16_t lv_bar_get_start_value(const lv_obj_t * bar)
* @param bar pointer to a bar object * @param bar pointer to a bar object
* @return the minimum value of the bar * @return the minimum value of the bar
*/ */
int16_t lv_bar_get_min_value(const lv_obj_t * bar) int16_t lv_bar_get_min_value(const lv_obj_t * obj)
{ {
LV_ASSERT_OBJ(bar, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_bar_t * bar = (lv_bar_t *)obj;
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar); return bar->min_value;
return ext->min_value;
} }
/** /**
@@ -312,12 +271,12 @@ int16_t lv_bar_get_min_value(const lv_obj_t * bar)
* @param bar pointer to a bar object * @param bar pointer to a bar object
* @return the maximum value of the bar * @return the maximum value of the bar
*/ */
int16_t lv_bar_get_max_value(const lv_obj_t * bar) int16_t lv_bar_get_max_value(const lv_obj_t * obj)
{ {
LV_ASSERT_OBJ(bar, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_bar_t * bar = (lv_bar_t *)obj;
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar); return bar->max_value;
return ext->max_value;
} }
/** /**
@@ -325,12 +284,12 @@ int16_t lv_bar_get_max_value(const lv_obj_t * bar)
* @param bar pointer to bar object * @param bar pointer to bar object
* @return bar type * @return bar type
*/ */
lv_bar_type_t lv_bar_get_type(lv_obj_t * bar) lv_bar_type_t lv_bar_get_type(lv_obj_t * obj)
{ {
LV_ASSERT_OBJ(bar, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_bar_t * bar = (lv_bar_t *)obj;
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar); return bar->type;
return ext->type;
} }
/** /**
@@ -338,13 +297,14 @@ lv_bar_type_t lv_bar_get_type(lv_obj_t * bar)
* @param bar pointer to a bar object * @param bar pointer to a bar object
* @return the animation time in milliseconds. * @return the animation time in milliseconds.
*/ */
uint16_t lv_bar_get_anim_time(const lv_obj_t * bar) uint16_t lv_bar_get_anim_time(const lv_obj_t * obj)
{ {
LV_ASSERT_OBJ(bar, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
#if LV_USE_ANIMATION #if LV_USE_ANIMATION
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return ext->anim_time; lv_bar_t * bar = (lv_bar_t *)obj;
return bar->anim_time;
#else #else
(void)bar; /*Unused*/ (void)bar; /*Unused*/
return 0; return 0;
@@ -356,6 +316,59 @@ uint16_t lv_bar_get_anim_time(const lv_obj_t * bar)
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
static void lv_bar_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy)
{
LV_LOG_TRACE("lv_bar create started");
LV_CLASS_CONSTRUCTOR_BEGIN(obj, lv_bar)
lv_bar.base_p->constructor(obj, parent, copy);
lv_bar_t * bar = (lv_bar_t *) obj;
bar->min_value = 0;
bar->max_value = 100;
bar->start_value = 0;
bar->cur_value = 0;
bar->type = LV_BAR_TYPE_NORMAL;
lv_style_list_init(&bar->style_indic);
#if LV_USE_ANIMATION
bar->anim_time = 200;
lv_bar_init_anim(bar, &bar->cur_value_anim);
lv_bar_init_anim(bar, &bar->start_value_anim);
#endif
if(copy == NULL) {
lv_obj_clear_flag(obj, LV_OBJ_FLAG_CHECKABLE);
lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_size(obj, LV_DPI * 2, LV_DPI / 10);
lv_bar_set_value(obj, 0, LV_ANIM_OFF);
} else {
lv_bar_t * bar_copy = (lv_bar_t *)copy;
bar->min_value = bar_copy->min_value;
bar->start_value = bar_copy->start_value;
bar->max_value = bar_copy->max_value;
bar->cur_value = bar_copy->cur_value;
bar->type = bar_copy->type;
lv_bar_set_value(obj, bar->cur_value, LV_ANIM_OFF);
}
LV_CLASS_CONSTRUCTOR_END(obj, lv_bar)
LV_LOG_INFO("bar created");
}
static void lv_bar_destructor(void * obj)
{
lv_bar_t * bar = obj;
_lv_obj_reset_style_list_no_refr(obj, LV_BAR_PART_INDIC);
#if LV_USE_ANIMATION
lv_anim_del(&bar->cur_value_anim, NULL);
lv_anim_del(&bar->start_value_anim, NULL);
#endif
bar->class_p->base_p->destructor(obj);
}
/** /**
* Handle the drawing related tasks of the bars * Handle the drawing related tasks of the bars
* @param bar pointer to an object * @param bar pointer to an object
@@ -366,16 +379,18 @@ uint16_t lv_bar_get_anim_time(const lv_obj_t * bar)
* LV_DESIGN_DRAW_POST: drawing after every children are drawn * LV_DESIGN_DRAW_POST: drawing after every children are drawn
* @param return an element of `lv_design_res_t` * @param return an element of `lv_design_res_t`
*/ */
static lv_design_res_t lv_bar_design(lv_obj_t * bar, const lv_area_t * clip_area, lv_design_mode_t mode) static lv_design_res_t lv_bar_design(lv_obj_t * obj, const lv_area_t * clip_area, lv_design_mode_t mode)
{ {
lv_bar_t * bar = (lv_bar_t *)obj;
if(mode == LV_DESIGN_COVER_CHK) { if(mode == LV_DESIGN_COVER_CHK) {
/*Return false if the object is not covers the mask area*/ /*Return false if the object is not covers the mask area*/
return ancestor_design(bar, clip_area, mode); return lv_bar.base_p->design_cb(obj, clip_area, mode);
} }
else if(mode == LV_DESIGN_DRAW_MAIN) { else if(mode == LV_DESIGN_DRAW_MAIN) {
// draw_bg(bar, clip_area); //Draw the background
ancestor_design(bar, clip_area, mode); lv_bar.base_p->design_cb(obj, clip_area, mode);
draw_indic(bar, clip_area); draw_indic(obj, clip_area);
/*Get the value and draw it after the indicator*/ /*Get the value and draw it after the indicator*/
lv_draw_rect_dsc_t draw_dsc; lv_draw_rect_dsc_t draw_dsc;
@@ -385,52 +400,53 @@ static lv_design_res_t lv_bar_design(lv_obj_t * bar, const lv_area_t * clip_area
draw_dsc.shadow_opa = LV_OPA_TRANSP; draw_dsc.shadow_opa = LV_OPA_TRANSP;
draw_dsc.pattern_opa = LV_OPA_TRANSP; draw_dsc.pattern_opa = LV_OPA_TRANSP;
draw_dsc.outline_opa = LV_OPA_TRANSP; draw_dsc.outline_opa = LV_OPA_TRANSP;
lv_obj_init_draw_rect_dsc(bar, LV_BAR_PART_MAIN, &draw_dsc); lv_obj_init_draw_rect_dsc(obj, LV_BAR_PART_MAIN, &draw_dsc);
lv_draw_rect(&bar->coords, clip_area, &draw_dsc); lv_draw_rect(&bar->coords, clip_area, &draw_dsc);
} }
else if(mode == LV_DESIGN_DRAW_POST) { else if(mode == LV_DESIGN_DRAW_POST) {
ancestor_design(bar, clip_area, mode); lv_bar.base_p->design_cb(obj, clip_area, mode);
} }
return LV_DESIGN_RES_OK; return LV_DESIGN_RES_OK;
} }
static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area) static void draw_indic(lv_obj_t * obj, const lv_area_t * clip_area)
{ {
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar); lv_bar_t * bar = (lv_bar_t *)obj;
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(bar);
lv_coord_t objw = lv_obj_get_width(bar); lv_bidi_dir_t base_dir = lv_obj_get_base_dir(obj);
lv_coord_t objh = lv_obj_get_height(bar);
int32_t range = ext->max_value - ext->min_value; lv_coord_t objw = lv_obj_get_width(obj);
lv_coord_t objh = lv_obj_get_height(obj);
int32_t range = bar->max_value - bar->min_value;
bool hor = objw >= objh ? true : false; bool hor = objw >= objh ? true : false;
bool sym = false; bool sym = false;
if(ext->type == LV_BAR_TYPE_SYMMETRICAL && ext->min_value < 0 && ext->max_value > 0 && if(bar->type == LV_BAR_TYPE_SYMMETRICAL && bar->min_value < 0 && bar->max_value > 0 &&
ext->start_value == ext->min_value) sym = true; bar->start_value == bar->min_value) sym = true;
/*Calculate the indicator area*/ /*Calculate the indicator area*/
lv_style_int_t bg_left = lv_obj_get_style_pad_left(bar, LV_BAR_PART_MAIN); lv_style_int_t bg_left = lv_obj_get_style_pad_left(obj, LV_BAR_PART_MAIN);
lv_style_int_t bg_right = lv_obj_get_style_pad_right(bar, LV_BAR_PART_MAIN); lv_style_int_t bg_right = lv_obj_get_style_pad_right(obj, LV_BAR_PART_MAIN);
lv_style_int_t bg_top = lv_obj_get_style_pad_top(bar, LV_BAR_PART_MAIN); lv_style_int_t bg_top = lv_obj_get_style_pad_top(obj, LV_BAR_PART_MAIN);
lv_style_int_t bg_bottom = lv_obj_get_style_pad_bottom(bar, LV_BAR_PART_MAIN); lv_style_int_t bg_bottom = lv_obj_get_style_pad_bottom(obj, LV_BAR_PART_MAIN);
/*Respect padding and minimum width/height too*/ /*Respect padding and minimum width/height too*/
lv_area_copy(&ext->indic_area, &bar->coords); lv_area_copy(&bar->indic_area, &bar->coords);
ext->indic_area.x1 += bg_left; bar->indic_area.x1 += bg_left;
ext->indic_area.x2 -= bg_right; bar->indic_area.x2 -= bg_right;
ext->indic_area.y1 += bg_top; bar->indic_area.y1 += bg_top;
ext->indic_area.y2 -= bg_bottom; bar->indic_area.y2 -= bg_bottom;
if(hor && lv_area_get_height(&ext->indic_area) < LV_BAR_SIZE_MIN) { if(hor && lv_area_get_height(&bar->indic_area) < LV_BAR_SIZE_MIN) {
ext->indic_area.y1 = bar->coords.y1 + (objh / 2) - (LV_BAR_SIZE_MIN / 2); bar->indic_area.y1 = bar->coords.y1 + (objh / 2) - (LV_BAR_SIZE_MIN / 2);
ext->indic_area.y2 = ext->indic_area.y1 + LV_BAR_SIZE_MIN; bar->indic_area.y2 = bar->indic_area.y1 + LV_BAR_SIZE_MIN;
} }
else if(!hor && lv_area_get_width(&ext->indic_area) < LV_BAR_SIZE_MIN) { else if(!hor && lv_area_get_width(&bar->indic_area) < LV_BAR_SIZE_MIN) {
ext->indic_area.x1 = bar->coords.x1 + (objw / 2) - (LV_BAR_SIZE_MIN / 2); bar->indic_area.x1 = bar->coords.x1 + (objw / 2) - (LV_BAR_SIZE_MIN / 2);
ext->indic_area.x2 = ext->indic_area.x1 + LV_BAR_SIZE_MIN; bar->indic_area.x2 = bar->indic_area.x1 + LV_BAR_SIZE_MIN;
} }
lv_coord_t indicw = lv_area_get_width(&ext->indic_area); lv_coord_t indicw = lv_area_get_width(&bar->indic_area);
lv_coord_t indich = lv_area_get_height(&ext->indic_area); lv_coord_t indich = lv_area_get_height(&bar->indic_area);
/*Calculate the indicator length*/ /*Calculate the indicator length*/
lv_coord_t anim_length = hor ? indicw : indich; lv_coord_t anim_length = hor ? indicw : indich;
@@ -441,24 +457,24 @@ static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area)
lv_coord_t (*indic_length_calc)(const lv_area_t * area); lv_coord_t (*indic_length_calc)(const lv_area_t * area);
if(hor) { if(hor) {
axis1 = &ext->indic_area.x1; axis1 = &bar->indic_area.x1;
axis2 = &ext->indic_area.x2; axis2 = &bar->indic_area.x2;
indic_length_calc = lv_area_get_width; indic_length_calc = lv_area_get_width;
} }
else { else {
axis1 = &ext->indic_area.y1; axis1 = &bar->indic_area.y1;
axis2 = &ext->indic_area.y2; axis2 = &bar->indic_area.y2;
indic_length_calc = lv_area_get_height; indic_length_calc = lv_area_get_height;
} }
#if LV_USE_ANIMATION #if LV_USE_ANIMATION
if(LV_BAR_IS_ANIMATING(ext->start_value_anim)) { if(LV_BAR_IS_ANIMATING(bar->start_value_anim)) {
lv_coord_t anim_start_value_start_x = lv_coord_t anim_start_value_start_x =
(int32_t)((int32_t)anim_length * (ext->start_value_anim.anim_start - ext->min_value)) / range; (int32_t)((int32_t)anim_length * (bar->start_value_anim.anim_start - bar->min_value)) / range;
lv_coord_t anim_start_value_end_x = lv_coord_t anim_start_value_end_x =
(int32_t)((int32_t)anim_length * (ext->start_value_anim.anim_end - ext->min_value)) / range; (int32_t)((int32_t)anim_length * (bar->start_value_anim.anim_end - bar->min_value)) / range;
anim_start_value_x = (((anim_start_value_end_x - anim_start_value_start_x) * ext->start_value_anim.anim_state) / anim_start_value_x = (((anim_start_value_end_x - anim_start_value_start_x) * bar->start_value_anim.anim_state) /
LV_BAR_ANIM_STATE_END); LV_BAR_ANIM_STATE_END);
anim_start_value_x += anim_start_value_start_x; anim_start_value_x += anim_start_value_start_x;
@@ -466,24 +482,24 @@ static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area)
else else
#endif #endif
{ {
anim_start_value_x = (int32_t)((int32_t)anim_length * (ext->start_value - ext->min_value)) / range; anim_start_value_x = (int32_t)((int32_t)anim_length * (bar->start_value - bar->min_value)) / range;
} }
#if LV_USE_ANIMATION #if LV_USE_ANIMATION
if(LV_BAR_IS_ANIMATING(ext->cur_value_anim)) { if(LV_BAR_IS_ANIMATING(bar->cur_value_anim)) {
lv_coord_t anim_cur_value_start_x = lv_coord_t anim_cur_value_start_x =
(int32_t)((int32_t)anim_length * (ext->cur_value_anim.anim_start - ext->min_value)) / range; (int32_t)((int32_t)anim_length * (bar->cur_value_anim.anim_start - bar->min_value)) / range;
lv_coord_t anim_cur_value_end_x = lv_coord_t anim_cur_value_end_x =
(int32_t)((int32_t)anim_length * (ext->cur_value_anim.anim_end - ext->min_value)) / range; (int32_t)((int32_t)anim_length * (bar->cur_value_anim.anim_end - bar->min_value)) / range;
anim_cur_value_x = anim_cur_value_start_x + (((anim_cur_value_end_x - anim_cur_value_start_x) * anim_cur_value_x = anim_cur_value_start_x + (((anim_cur_value_end_x - anim_cur_value_start_x) *
ext->cur_value_anim.anim_state) / bar->cur_value_anim.anim_state) /
LV_BAR_ANIM_STATE_END); LV_BAR_ANIM_STATE_END);
} }
else else
#endif #endif
{ {
anim_cur_value_x = (int32_t)((int32_t)anim_length * (ext->cur_value - ext->min_value)) / range; anim_cur_value_x = (int32_t)((int32_t)anim_length * (bar->cur_value - bar->min_value)) / range;
} }
if(hor && base_dir == LV_BIDI_DIR_RTL) { if(hor && base_dir == LV_BIDI_DIR_RTL) {
@@ -507,7 +523,7 @@ static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area)
} }
if(sym) { if(sym) {
lv_coord_t zero; lv_coord_t zero;
zero = *axis1 + (-ext->min_value * anim_length) / range; zero = *axis1 + (-bar->min_value * anim_length) / range;
if(*axis2 > zero) if(*axis2 > zero)
*axis1 = zero; *axis1 = zero;
else { else {
@@ -519,21 +535,21 @@ static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area)
/*Draw the indicator*/ /*Draw the indicator*/
/*Do not draw a zero length indicator*/ /*Do not draw a zero length indicator*/
if(!sym && indic_length_calc(&ext->indic_area) <= 1) return; if(!sym && indic_length_calc(&bar->indic_area) <= 1) return;
uint16_t bg_radius = lv_obj_get_style_radius(bar, LV_BAR_PART_MAIN); uint16_t bg_radius = lv_obj_get_style_radius(obj, LV_BAR_PART_MAIN);
lv_coord_t short_side = LV_MATH_MIN(objw, objh); lv_coord_t short_side = LV_MATH_MIN(objw, objh);
if(bg_radius > short_side >> 1) bg_radius = short_side >> 1; if(bg_radius > short_side >> 1) bg_radius = short_side >> 1;
lv_draw_rect_dsc_t draw_indic_dsc; lv_draw_rect_dsc_t draw_indic_dsc;
lv_draw_rect_dsc_init(&draw_indic_dsc); lv_draw_rect_dsc_init(&draw_indic_dsc);
lv_obj_init_draw_rect_dsc(bar, LV_BAR_PART_INDIC, &draw_indic_dsc); lv_obj_init_draw_rect_dsc(obj, LV_BAR_PART_INDIC, &draw_indic_dsc);
/* Draw only the shadow if the indicator is long enough. /* Draw only the shadow if the indicator is long enough.
* The radius of the bg and the indicator can make a strange shape where * The radius of the bg and the indicator can make a strange shape where
* it'd be very difficult to draw shadow. */ * it'd be very difficult to draw shadow. */
if((hor && lv_area_get_width(&ext->indic_area) > bg_radius * 2) || if((hor && lv_area_get_width(&bar->indic_area) > bg_radius * 2) ||
(!hor && lv_area_get_height(&ext->indic_area) > bg_radius * 2)) { (!hor && lv_area_get_height(&bar->indic_area) > bg_radius * 2)) {
lv_opa_t bg_opa = draw_indic_dsc.bg_opa; lv_opa_t bg_opa = draw_indic_dsc.bg_opa;
lv_opa_t border_opa = draw_indic_dsc.border_opa; lv_opa_t border_opa = draw_indic_dsc.border_opa;
lv_opa_t value_opa = draw_indic_dsc.value_opa; lv_opa_t value_opa = draw_indic_dsc.value_opa;
@@ -542,7 +558,7 @@ static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area)
draw_indic_dsc.border_opa = LV_OPA_TRANSP; draw_indic_dsc.border_opa = LV_OPA_TRANSP;
draw_indic_dsc.value_opa = LV_OPA_TRANSP; draw_indic_dsc.value_opa = LV_OPA_TRANSP;
draw_indic_dsc.pattern_image = NULL; draw_indic_dsc.pattern_image = NULL;
lv_draw_rect(&ext->indic_area, clip_area, &draw_indic_dsc); lv_draw_rect(&bar->indic_area, clip_area, &draw_indic_dsc);
draw_indic_dsc.bg_opa = bg_opa; draw_indic_dsc.bg_opa = bg_opa;
draw_indic_dsc.border_opa = border_opa; draw_indic_dsc.border_opa = border_opa;
draw_indic_dsc.value_opa = value_opa; draw_indic_dsc.value_opa = value_opa;
@@ -580,7 +596,7 @@ static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area)
/*Create a mask to the current indicator area to see only this part from the whole gradient.*/ /*Create a mask to the current indicator area to see only this part from the whole gradient.*/
lv_draw_mask_radius_param_t mask_indic_param; lv_draw_mask_radius_param_t mask_indic_param;
lv_draw_mask_radius_init(&mask_indic_param, &ext->indic_area, draw_indic_dsc.radius, false); lv_draw_mask_radius_init(&mask_indic_param, &bar->indic_area, draw_indic_dsc.radius, false);
int16_t mask_indic_id = lv_draw_mask_add(&mask_indic_param, NULL); int16_t mask_indic_id = lv_draw_mask_add(&mask_indic_param, NULL);
lv_draw_rect(&mask_indic_max_area, clip_area, &draw_indic_dsc); lv_draw_rect(&mask_indic_max_area, clip_area, &draw_indic_dsc);
@@ -593,7 +609,7 @@ static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area)
draw_indic_dsc.shadow_opa = LV_OPA_TRANSP; draw_indic_dsc.shadow_opa = LV_OPA_TRANSP;
draw_indic_dsc.value_opa = LV_OPA_TRANSP; draw_indic_dsc.value_opa = LV_OPA_TRANSP;
draw_indic_dsc.pattern_image = NULL; draw_indic_dsc.pattern_image = NULL;
lv_draw_rect(&ext->indic_area, clip_area, &draw_indic_dsc); lv_draw_rect(&bar->indic_area, clip_area, &draw_indic_dsc);
lv_draw_mask_remove_id(mask_indic_id); lv_draw_mask_remove_id(mask_indic_id);
lv_draw_mask_remove_id(mask_bg_id); lv_draw_mask_remove_id(mask_bg_id);
@@ -601,7 +617,7 @@ static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area)
/*When not masks draw the value*/ /*When not masks draw the value*/
draw_indic_dsc.value_opa = value_opa; draw_indic_dsc.value_opa = value_opa;
draw_indic_dsc.border_opa = LV_OPA_TRANSP; draw_indic_dsc.border_opa = LV_OPA_TRANSP;
lv_draw_rect(&ext->indic_area, clip_area, &draw_indic_dsc); lv_draw_rect(&bar->indic_area, clip_area, &draw_indic_dsc);
} }
@@ -612,49 +628,37 @@ static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area)
* @param param pointer to a signal specific variable * @param param pointer to a signal specific variable
* @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted
*/ */
static lv_res_t lv_bar_signal(lv_obj_t * bar, lv_signal_t sign, void * param) static lv_res_t lv_bar_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
{ {
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_bar_t * bar = (lv_bar_t *)obj;
lv_res_t res; lv_res_t res;
/* Include the ancient signal function */ /* Include the ancient signal function */
res = ancestor_signal(bar, sign, param); res = lv_bar.base_p->signal_cb(obj, sign, param);
if(res != LV_RES_OK) return res; if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_STYLE) { if(sign == LV_SIGNAL_GET_STYLE) {
lv_get_style_info_t * info = param; lv_get_style_info_t * info = param;
info->result = lv_bar_get_style(bar, info->part); info->result = lv_bar_get_style(bar, info->part);
if(info->result != NULL) return LV_RES_OK; if(info->result != NULL) return LV_RES_OK;
else return ancestor_signal(bar, sign, param); else return lv_bar.base_p->signal_cb(obj, sign, param);
}
else if(sign == LV_SIGNAL_GET_TYPE) {
return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
} }
else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) { else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
lv_coord_t indic_size; lv_coord_t indic_size;
indic_size = _lv_obj_get_draw_rect_ext_pad_size(bar, LV_BAR_PART_INDIC); indic_size = _lv_obj_get_draw_rect_ext_pad_size(obj, LV_BAR_PART_INDIC);
/*Bg size is handled by lv_obj*/ /*Bg size is handled by lv_obj*/
lv_coord_t * s = param; lv_coord_t * s = param;
*s = LV_MATH_MAX(*s, indic_size); *s = LV_MATH_MAX(*s, indic_size);
}
if(sign == LV_SIGNAL_CLEANUP) {
_lv_obj_reset_style_list_no_refr(bar, LV_BAR_PART_INDIC);
#if LV_USE_ANIMATION
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
lv_anim_del(&ext->cur_value_anim, NULL);
lv_anim_del(&ext->start_value_anim, NULL);
#endif
} }
return res; return res;
} }
static lv_style_list_t * lv_bar_get_style(lv_obj_t * bar, uint8_t part) static lv_style_list_t * lv_bar_get_style(lv_bar_t * bar, uint8_t part)
{ {
LV_ASSERT_OBJ(bar, LV_OBJX_NAME);
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
lv_style_list_t * list; lv_style_list_t * list;
switch(part) { switch(part) {
@@ -662,7 +666,7 @@ static lv_style_list_t * lv_bar_get_style(lv_obj_t * bar, uint8_t part)
list = &bar->style_list; list = &bar->style_list;
break; break;
case LV_BAR_PART_INDIC: case LV_BAR_PART_INDIC:
list = &ext->style_indic; list = &bar->style_indic;
break; break;
default: default:
list = NULL; list = NULL;
@@ -681,24 +685,25 @@ static void lv_bar_anim(lv_bar_anim_t * var, lv_anim_value_t value)
static void lv_bar_anim_ready(lv_anim_t * a) static void lv_bar_anim_ready(lv_anim_t * a)
{ {
lv_bar_anim_t * var = a->var; lv_bar_anim_t * var = a->var;
lv_bar_ext_t * ext = lv_obj_get_ext_attr(var->bar); lv_bar_t * bar = (lv_bar_t *)var->bar;
var->anim_state = LV_BAR_ANIM_STATE_INV; var->anim_state = LV_BAR_ANIM_STATE_INV;
if(var == &ext->cur_value_anim) if(var == &bar->cur_value_anim)
ext->cur_value = var->anim_end; bar->cur_value = var->anim_end;
else if(var == &ext->start_value_anim) else if(var == &bar->start_value_anim)
ext->start_value = var->anim_end; bar->start_value = var->anim_end;
lv_obj_invalidate(var->bar); lv_obj_invalidate(var->bar);
} }
static void lv_bar_set_value_with_anim(lv_obj_t * bar, int16_t new_value, int16_t * value_ptr, static void lv_bar_set_value_with_anim(lv_bar_t * bar, int16_t new_value, int16_t * value_ptr,
lv_bar_anim_t * anim_info, lv_anim_enable_t en) lv_bar_anim_t * anim_info, lv_anim_enable_t en)
{ {
if(en == LV_ANIM_OFF) { if(en == LV_ANIM_OFF) {
*value_ptr = new_value; *value_ptr = new_value;
lv_obj_invalidate(bar); lv_obj_invalidate((lv_obj_t*)bar);
} }
else { else {
lv_bar_ext_t * ext = lv_obj_get_ext_attr(bar);
/*No animation in progress -> simply set the values*/ /*No animation in progress -> simply set the values*/
if(anim_info->anim_state == LV_BAR_ANIM_STATE_INV) { if(anim_info->anim_state == LV_BAR_ANIM_STATE_INV) {
anim_info->anim_start = *value_ptr; anim_info->anim_start = *value_ptr;
@@ -719,14 +724,14 @@ static void lv_bar_set_value_with_anim(lv_obj_t * bar, int16_t new_value, int16_
lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_bar_anim); lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_bar_anim);
lv_anim_set_values(&a, LV_BAR_ANIM_STATE_START, LV_BAR_ANIM_STATE_END); lv_anim_set_values(&a, LV_BAR_ANIM_STATE_START, LV_BAR_ANIM_STATE_END);
lv_anim_set_ready_cb(&a, lv_bar_anim_ready); lv_anim_set_ready_cb(&a, lv_bar_anim_ready);
lv_anim_set_time(&a, ext->anim_time); lv_anim_set_time(&a, bar->anim_time);
lv_anim_start(&a); lv_anim_start(&a);
} }
} }
static void lv_bar_init_anim(lv_obj_t * bar, lv_bar_anim_t * bar_anim) static void lv_bar_init_anim(lv_bar_t * bar, lv_bar_anim_t * bar_anim)
{ {
bar_anim->bar = bar; bar_anim->bar = (lv_obj_t *)bar;
bar_anim->anim_start = 0; bar_anim->anim_start = 0;
bar_anim->anim_end = 0; bar_anim->anim_end = 0;
bar_anim->anim_state = LV_BAR_ANIM_STATE_INV; bar_anim->anim_state = LV_BAR_ANIM_STATE_INV;

View File

@@ -58,24 +58,37 @@ typedef struct {
} lv_bar_anim_t; } lv_bar_anim_t;
#endif #endif
/** Data of bar*/
typedef struct {
/*No inherited ext, derived from the base object */
/*New data for this type */ LV_CLASS_DECLARE_START(lv_bar, lv_obj);
int16_t cur_value; /*Current value of the bar*/
int16_t min_value; /*Minimum value of the bar*/ #define _lv_bar_constructor void (*constructor)(struct _lv_obj_t * obj, struct _lv_obj_t * parent, const struct _lv_obj_t * copy)
int16_t max_value; /*Maximum value of the bar*/
int16_t start_value; /*Start value of the bar*/
lv_area_t indic_area; /*Save the indicator area. MIght be used by derived types*/
#if LV_USE_ANIMATION #if LV_USE_ANIMATION
lv_anim_value_t anim_time; #define _lv_bar_anim_data \
lv_bar_anim_t cur_value_anim; lv_anim_value_t anim_time; \
lv_bar_anim_t cur_value_anim; \
lv_bar_anim_t start_value_anim; lv_bar_anim_t start_value_anim;
#else
#define _lv_bar_anim_data
#endif #endif
uint8_t type : 2; /*Type of bar*/
#define _lv_bar_data \
_lv_obj_data \
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 start_value; /*Start value of the bar*/ \
lv_area_t indic_area; /*Save the indicator area. Might be used by derived types*/ \
_lv_bar_anim_data \
uint8_t type : 2; /*Type of bar*/ \
lv_style_list_t style_indic; /*Style of the indicator*/ lv_style_list_t style_indic; /*Style of the indicator*/
} lv_bar_ext_t;
#define _lv_bar_class_dsc \
_lv_obj_class_dsc \
LV_CLASS_DECLARE_END(lv_bar, lv_obj);
extern lv_bar_class_t lv_bar;
/** Bar parts */ /** Bar parts */
enum { enum {

View File

@@ -16,6 +16,7 @@
#include "../lv_draw/lv_draw.h" #include "../lv_draw/lv_draw.h"
#include "../lv_themes/lv_theme.h" #include "../lv_themes/lv_theme.h"
#include "../lv_misc/lv_math.h" #include "../lv_misc/lv_math.h"
#include "../lv_core/lv_disp.h"
#include "lv_img.h" #include "lv_img.h"
/********************* /*********************
@@ -32,17 +33,18 @@
/********************** /**********************
* STATIC PROTOTYPES * STATIC PROTOTYPES
**********************/ **********************/
static void lv_slider_desctructor(void * obj);
static void lv_slider_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy);
static lv_design_res_t lv_slider_design(lv_obj_t * slider, const lv_area_t * clip_area, lv_design_mode_t mode); static lv_design_res_t lv_slider_design(lv_obj_t * slider, const lv_area_t * clip_area, lv_design_mode_t mode);
static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * param); static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * param);
static lv_style_list_t * lv_slider_get_style(lv_obj_t * slider, uint8_t part); static lv_style_list_t * lv_slider_get_style(lv_slider_t * slider, uint8_t part);
static void lv_slider_position_knob(lv_obj_t * slider, lv_area_t * knob_area, lv_coord_t knob_size, bool hor); static void lv_slider_position_knob(lv_obj_t * slider, lv_area_t * knob_area, lv_coord_t knob_size, bool hor);
static void lv_slider_draw_knob(lv_obj_t * slider, const lv_area_t * knob_area, const lv_area_t * clip_area); static void lv_slider_draw_knob(lv_obj_t * slider, const lv_area_t * knob_area, const lv_area_t * clip_area);
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
**********************/ **********************/
static lv_design_cb_t ancestor_design; lv_slider_class_t lv_slider;
static lv_signal_cb_t ancestor_signal;
/********************** /**********************
* MACROS * MACROS
@@ -63,51 +65,33 @@ lv_obj_t * lv_slider_create(lv_obj_t * parent, const lv_obj_t * copy)
{ {
LV_LOG_TRACE("slider create started"); LV_LOG_TRACE("slider create started");
/*Create the ancestor slider*/ if(!lv_slider._inited) {
lv_obj_t * slider = lv_bar_create(parent, copy); LV_CLASS_INIT(lv_slider, lv_bar);
LV_ASSERT_MEM(slider); lv_slider.constructor = lv_slider_constructor;
if(slider == NULL) return NULL; lv_slider.destructor = lv_slider_desctructor;
lv_slider.signal_cb = lv_slider_signal;
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(slider); lv_slider.design_cb = lv_slider_design;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(slider);
/*Allocate the slider type specific extended data*/
lv_slider_ext_t * ext = lv_obj_allocate_ext_attr(slider, sizeof(lv_slider_ext_t));
LV_ASSERT_MEM(ext);
if(ext == NULL) {
lv_obj_del(slider);
return NULL;
} }
/*Initialize the allocated 'ext' */
ext->value_to_set = NULL;
ext->dragging = 0;
ext->left_knob_focus = 0;
lv_style_list_init(&ext->style_knob);
/*The signal and design functions are not copied so set them here*/ lv_obj_t * obj = lv_class_new(&lv_slider);
lv_obj_set_signal_cb(slider, lv_slider_signal); lv_slider.constructor(obj, parent, copy);
lv_obj_set_design_cb(slider, lv_slider_design);
lv_slider_t * slider = (lv_slider_t *) obj;
/*Init the new slider slider*/ /*Init the new slider slider*/
if(copy == NULL) { if(copy == NULL) {
lv_theme_apply(slider, LV_THEME_SLIDER); lv_theme_apply(obj, LV_THEME_SLIDER);
lv_obj_add_flag(slider, LV_OBJ_FLAG_SCROLL_FREEZE);
lv_obj_set_ext_click_area(slider, 0, 0, LV_DPI / 10, LV_DPI / 10);
lv_obj_set_height(slider, LV_DPI / 15);
} else { } else {
lv_slider_ext_t * copy_ext = lv_obj_get_ext_attr(copy); lv_slider_t * copy_slider = (lv_slider_t *) copy;
lv_style_list_copy(&ext->style_knob, &copy_ext->style_knob); lv_style_list_copy(&slider->style_knob, &copy_slider->style_knob);
lv_area_copy(&ext->left_knob_area, &copy_ext->left_knob_area);
lv_area_copy(&ext->right_knob_area, &copy_ext->right_knob_area);
_lv_obj_refresh_style(slider, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); _lv_obj_refresh_style(obj, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
} }
LV_LOG_INFO("slider created"); LV_LOG_INFO("slider created");
return slider; return obj;
} }
/*===================== /*=====================
@@ -123,18 +107,55 @@ lv_obj_t * lv_slider_create(lv_obj_t * parent, const lv_obj_t * copy)
* @param slider pointer to a slider object * @param slider pointer to a slider object
* @return true: drag in progress false: not dragged * @return true: drag in progress false: not dragged
*/ */
bool lv_slider_is_dragged(const lv_obj_t * slider) bool lv_slider_is_dragged(const lv_obj_t * obj)
{ {
LV_ASSERT_OBJ(slider, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_slider_t * slider = (lv_slider_t *) obj;
lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider); return slider->dragging ? true : false;
return ext->dragging ? true : false;
} }
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
static void lv_slider_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy)
{
LV_CLASS_CONSTRUCTOR_BEGIN(obj, lv_slider)
lv_slider.base_p->constructor(obj, parent, copy);
lv_slider_t * slider = (lv_slider_t*) obj;
/*Initialize the allocated 'slider' */
slider->value_to_set = NULL;
slider->dragging = 0;
slider->left_knob_focus = 0;
lv_style_list_init(&slider->style_knob);
/*Init the new slider slider*/
if(copy == NULL) {
lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLL_CHAIN);
lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_ext_click_area(obj, lv_dpx(5), lv_dpx(5), lv_dpx(5), lv_dpx(5));
lv_obj_set_height(obj, LV_DPI / 15);
} else {
lv_slider_t * copy_slider = (lv_slider_t *) copy;
lv_area_copy(&slider->left_knob_area, &copy_slider->left_knob_area);
lv_area_copy(&slider->right_knob_area, &copy_slider->right_knob_area);
}
LV_CLASS_CONSTRUCTOR_END(obj, lv_slider)
}
static void lv_slider_desctructor(void * obj)
{
lv_slider_t * slider = obj;
_lv_obj_reset_style_list_no_refr(obj, LV_SLIDER_PART_KNOB);
slider->class_p->base_p->destructor(obj);
}
/** /**
* Handle the drawing related tasks of the sliders * Handle the drawing related tasks of the sliders
* @param slider pointer to an object * @param slider pointer to an object
@@ -145,7 +166,7 @@ bool lv_slider_is_dragged(const lv_obj_t * slider)
* LV_DESIGN_DRAW_POST: drawing after every children are drawn * LV_DESIGN_DRAW_POST: drawing after every children are drawn
* @param return an element of `lv_design_res_t` * @param return an element of `lv_design_res_t`
*/ */
static lv_design_res_t lv_slider_design(lv_obj_t * slider, const lv_area_t * clip_area, lv_design_mode_t mode) static lv_design_res_t lv_slider_design(lv_obj_t * obj, const lv_area_t * clip_area, lv_design_mode_t mode)
{ {
/*Return false if the object is not covers the mask_p area*/ /*Return false if the object is not covers the mask_p area*/
if(mode == LV_DESIGN_COVER_CHK) { if(mode == LV_DESIGN_COVER_CHK) {
@@ -154,71 +175,71 @@ static lv_design_res_t lv_slider_design(lv_obj_t * slider, const lv_area_t * cli
/*Draw the object*/ /*Draw the object*/
else if(mode == LV_DESIGN_DRAW_MAIN) { else if(mode == LV_DESIGN_DRAW_MAIN) {
/* The ancestor design function will draw the background and the indicator. /* The ancestor design function will draw the background and the indicator.
* It also sets ext->bar.indic_area*/ * It also sets slider->indic_area*/
ancestor_design(slider, clip_area, mode); lv_slider.base_p->design_cb(obj, clip_area, mode);
lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider); lv_slider_t * slider = (lv_slider_t *)obj;
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(slider); lv_bidi_dir_t base_dir = lv_obj_get_base_dir(obj);
lv_coord_t objw = lv_obj_get_width(slider); lv_coord_t objw = lv_obj_get_width(obj);
lv_coord_t objh = lv_obj_get_height(slider); lv_coord_t objh = lv_obj_get_height(obj);
bool hor = objw >= objh ? true : false; bool hor = objw >= objh ? true : false;
lv_coord_t knob_size = hor ? objh : objw; lv_coord_t knob_size = hor ? objh : objw;
bool sym = false; bool sym = false;
if(ext->bar.type == LV_BAR_TYPE_SYMMETRICAL && ext->bar.min_value < 0 && ext->bar.max_value > 0) sym = true; if(slider->type == LV_BAR_TYPE_SYMMETRICAL && slider->min_value < 0 && slider->max_value > 0) sym = true;
lv_area_t knob_area; lv_area_t knob_area;
/*Horizontal*/ /*Horizontal*/
if(hor) { if(hor) {
if(!sym) { if(!sym) {
knob_area.x1 = LV_SLIDER_KNOB_COORD(hor, base_dir == LV_BIDI_DIR_RTL, ext->bar.indic_area); knob_area.x1 = LV_SLIDER_KNOB_COORD(hor, base_dir == LV_BIDI_DIR_RTL, slider->indic_area);
} }
else { else {
if(ext->bar.cur_value >= 0) { if(slider->cur_value >= 0) {
knob_area.x1 = LV_SLIDER_KNOB_COORD(hor, base_dir == LV_BIDI_DIR_RTL, ext->bar.indic_area); knob_area.x1 = LV_SLIDER_KNOB_COORD(hor, base_dir == LV_BIDI_DIR_RTL, slider->indic_area);
} }
else { else {
knob_area.x1 = LV_SLIDER_KNOB_COORD(hor, base_dir != LV_BIDI_DIR_RTL, ext->bar.indic_area); knob_area.x1 = LV_SLIDER_KNOB_COORD(hor, base_dir != LV_BIDI_DIR_RTL, slider->indic_area);
} }
} }
} }
/*Vertical*/ /*Vertical*/
else { else {
if(!sym) { if(!sym) {
knob_area.y1 = ext->bar.indic_area.y1; knob_area.y1 = slider->indic_area.y1;
} }
else { else {
if(ext->bar.cur_value >= 0) { if(slider->cur_value >= 0) {
knob_area.y1 = ext->bar.indic_area.y1; knob_area.y1 = slider->indic_area.y1;
} }
else { else {
knob_area.y1 = ext->bar.indic_area.y2; knob_area.y1 = slider->indic_area.y2;
} }
} }
} }
lv_slider_position_knob(slider, &knob_area, knob_size, hor); lv_slider_position_knob(obj, &knob_area, knob_size, hor);
lv_area_copy(&ext->right_knob_area, &knob_area); lv_area_copy(&slider->right_knob_area, &knob_area);
lv_slider_draw_knob(slider, &knob_area, clip_area); lv_slider_draw_knob(obj, &knob_area, clip_area);
if(lv_slider_get_type(slider) == LV_SLIDER_TYPE_RANGE) { if(lv_slider_get_type(obj) == LV_SLIDER_TYPE_RANGE) {
/* Draw a second knob for the start_value side */ /* Draw a second knob for the start_value side */
if(hor) { if(hor) {
knob_area.x1 = LV_SLIDER_KNOB_COORD(hor, base_dir != LV_BIDI_DIR_RTL, ext->bar.indic_area); knob_area.x1 = LV_SLIDER_KNOB_COORD(hor, base_dir != LV_BIDI_DIR_RTL, slider->indic_area);
} }
else { else {
knob_area.y1 = ext->bar.indic_area.y2; knob_area.y1 = slider->indic_area.y2;
} }
lv_slider_position_knob(slider, &knob_area, knob_size, hor); lv_slider_position_knob(obj, &knob_area, knob_size, hor);
lv_area_copy(&ext->left_knob_area, &knob_area); lv_area_copy(&slider->left_knob_area, &knob_area);
lv_slider_draw_knob(slider, &knob_area, clip_area); lv_slider_draw_knob(obj, &knob_area, clip_area);
} }
} }
/*Post draw when the children are drawn*/ /*Post draw when the children are drawn*/
else if(mode == LV_DESIGN_DRAW_POST) { else if(mode == LV_DESIGN_DRAW_POST) {
return ancestor_design(slider, clip_area, mode); return lv_slider.base_p->design_cb(obj, clip_area, mode);
} }
return LV_DESIGN_RES_OK; return LV_DESIGN_RES_OK;
@@ -231,107 +252,106 @@ static lv_design_res_t lv_slider_design(lv_obj_t * slider, const lv_area_t * cli
* @param param pointer to a signal specific variable * @param param pointer to a signal specific variable
* @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted
*/ */
static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * param) static lv_res_t lv_slider_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
{ {
lv_res_t res; lv_res_t res;
lv_slider_t * slider = (lv_slider_t *)obj;
if(sign == LV_SIGNAL_GET_STYLE) { if(sign == LV_SIGNAL_GET_STYLE) {
lv_get_style_info_t * info = param; lv_get_style_info_t * info = param;
info->result = lv_slider_get_style(slider, info->part); info->result = lv_slider_get_style(slider, info->part);
if(info->result != NULL) return LV_RES_OK; if(info->result != NULL) return LV_RES_OK;
else return ancestor_signal(slider, sign, param); else return lv_slider.base_p->signal_cb(obj, sign, param);
} }
/* Include the ancient signal function */ /* Include the ancient signal function */
res = ancestor_signal(slider, sign, param); res = lv_slider.base_p->signal_cb(obj, sign, param);
if(res != LV_RES_OK) return res; if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
lv_slider_type_t type = lv_slider_get_type(slider); lv_slider_type_t type = lv_slider_get_type(obj);
lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider);
/* Advanced hit testing: react only on dragging the knob(s) */ /* Advanced hit testing: react only on dragging the knob(s) */
if(sign == LV_SIGNAL_HIT_TEST) { if(sign == LV_SIGNAL_HIT_TEST) {
lv_hit_test_info_t * info = param; lv_hit_test_info_t * info = param;
/* Ordinary slider: was the knob area hit? */ /* Ordinary slider: was the knob area hit? */
info->result = _lv_area_is_point_on(&ext->right_knob_area, info->point, 0); info->result = _lv_area_is_point_on(&slider->right_knob_area, info->point, 0);
/* There's still a change we have a hit, if we have another knob */ /* There's still a change we have a hit, if we have another knob */
if((info->result == false) && (type == LV_SLIDER_TYPE_RANGE)) { if((info->result == false) && (type == LV_SLIDER_TYPE_RANGE)) {
info->result = _lv_area_is_point_on(&ext->left_knob_area, info->point, 0); info->result = _lv_area_is_point_on(&slider->left_knob_area, info->point, 0);
} }
} }
lv_point_t p; lv_point_t p;
if(sign == LV_SIGNAL_PRESSED) { if(sign == LV_SIGNAL_PRESSED) {
ext->dragging = true; slider->dragging = true;
if(type == LV_SLIDER_TYPE_NORMAL || type == LV_SLIDER_TYPE_SYMMETRICAL) { if(type == LV_SLIDER_TYPE_NORMAL || type == LV_SLIDER_TYPE_SYMMETRICAL) {
ext->value_to_set = &ext->bar.cur_value; slider->value_to_set = &slider->cur_value;
} }
else if(type == LV_SLIDER_TYPE_RANGE) { else if(type == LV_SLIDER_TYPE_RANGE) {
lv_indev_get_point(param, &p); lv_indev_get_point(param, &p);
bool hor = lv_obj_get_width(slider) >= lv_obj_get_height(slider); bool hor = lv_obj_get_width(obj) >= lv_obj_get_height(obj);
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(slider); lv_bidi_dir_t base_dir = lv_obj_get_base_dir(obj);
lv_coord_t dist_left, dist_right; lv_coord_t dist_left, dist_right;
if(hor) { if(hor) {
if((base_dir != LV_BIDI_DIR_RTL && p.x > ext->right_knob_area.x2) || (base_dir == LV_BIDI_DIR_RTL && if((base_dir != LV_BIDI_DIR_RTL && p.x > slider->right_knob_area.x2) || (base_dir == LV_BIDI_DIR_RTL &&
p.x < ext->right_knob_area.x1)) { p.x < slider->right_knob_area.x1)) {
ext->value_to_set = &ext->bar.cur_value; slider->value_to_set = &slider->cur_value;
} }
else if((base_dir != LV_BIDI_DIR_RTL && p.x < ext->left_knob_area.x1) || (base_dir == LV_BIDI_DIR_RTL && else if((base_dir != LV_BIDI_DIR_RTL && p.x < slider->left_knob_area.x1) || (base_dir == LV_BIDI_DIR_RTL &&
p.x > ext->left_knob_area.x2)) { p.x > slider->left_knob_area.x2)) {
ext->value_to_set = &ext->bar.start_value; slider->value_to_set = &slider->start_value;
} }
else { else {
/* Calculate the distance from each knob */ /* Calculate the distance from each knob */
dist_left = LV_MATH_ABS((ext->left_knob_area.x1 + (ext->left_knob_area.x2 - ext->left_knob_area.x1) / 2) - p.x); dist_left = LV_MATH_ABS((slider->left_knob_area.x1 + (slider->left_knob_area.x2 - slider->left_knob_area.x1) / 2) - p.x);
dist_right = LV_MATH_ABS((ext->right_knob_area.x1 + (ext->right_knob_area.x2 - ext->right_knob_area.x1) / 2) - p.x); dist_right = LV_MATH_ABS((slider->right_knob_area.x1 + (slider->right_knob_area.x2 - slider->right_knob_area.x1) / 2) - p.x);
/* Use whichever one is closer */ /* Use whichever one is closer */
if(dist_right < dist_left)ext->value_to_set = &ext->bar.cur_value; if(dist_right < dist_left)slider->value_to_set = &slider->cur_value;
else ext->value_to_set = &ext->bar.start_value; else slider->value_to_set = &slider->start_value;
} }
} }
else { else {
if(p.y < ext->right_knob_area.y1) { if(p.y < slider->right_knob_area.y1) {
ext->value_to_set = &ext->bar.cur_value; slider->value_to_set = &slider->cur_value;
} }
else if(p.y > ext->left_knob_area.y2) { else if(p.y > slider->left_knob_area.y2) {
ext->value_to_set = &ext->bar.start_value; slider->value_to_set = &slider->start_value;
} }
else { else {
/* Calculate the distance from each knob */ /* Calculate the distance from each knob */
dist_left = LV_MATH_ABS((ext->left_knob_area.y1 + (ext->left_knob_area.y2 - ext->left_knob_area.y1) / 2) - p.y); dist_left = LV_MATH_ABS((slider->left_knob_area.y1 + (slider->left_knob_area.y2 - slider->left_knob_area.y1) / 2) - p.y);
dist_right = LV_MATH_ABS((ext->right_knob_area.y1 + (ext->right_knob_area.y2 - ext->right_knob_area.y1) / 2) - p.y); dist_right = LV_MATH_ABS((slider->right_knob_area.y1 + (slider->right_knob_area.y2 - slider->right_knob_area.y1) / 2) - p.y);
/* Use whichever one is closer */ /* Use whichever one is closer */
if(dist_right < dist_left)ext->value_to_set = &ext->bar.cur_value; if(dist_right < dist_left)slider->value_to_set = &slider->cur_value;
else ext->value_to_set = &ext->bar.start_value; else slider->value_to_set = &slider->start_value;
} }
} }
} }
} }
else if(sign == LV_SIGNAL_PRESSING && ext->value_to_set != NULL) { else if(sign == LV_SIGNAL_PRESSING && slider->value_to_set != NULL) {
if(lv_indev_get_type(param) != LV_INDEV_TYPE_POINTER) return res; if(lv_indev_get_type(param) != LV_INDEV_TYPE_POINTER) return res;
lv_indev_get_point(param, &p); lv_indev_get_point(param, &p);
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(slider); lv_bidi_dir_t base_dir = lv_obj_get_base_dir(obj);
lv_coord_t w = lv_obj_get_width(slider); lv_coord_t w = lv_obj_get_width(obj);
lv_coord_t h = lv_obj_get_height(slider); lv_coord_t h = lv_obj_get_height(obj);
lv_style_int_t bg_left = lv_obj_get_style_pad_left(slider, LV_SLIDER_PART_MAIN); lv_style_int_t bg_left = lv_obj_get_style_pad_left(obj, LV_SLIDER_PART_MAIN);
lv_style_int_t bg_right = lv_obj_get_style_pad_right(slider, LV_SLIDER_PART_MAIN); lv_style_int_t bg_right = lv_obj_get_style_pad_right(obj, LV_SLIDER_PART_MAIN);
lv_style_int_t bg_top = lv_obj_get_style_pad_top(slider, LV_SLIDER_PART_MAIN); lv_style_int_t bg_top = lv_obj_get_style_pad_top(obj, LV_SLIDER_PART_MAIN);
lv_style_int_t bg_bottom = lv_obj_get_style_pad_bottom(slider, LV_SLIDER_PART_MAIN); lv_style_int_t bg_bottom = lv_obj_get_style_pad_bottom(obj, LV_SLIDER_PART_MAIN);
int32_t range = ext->bar.max_value - ext->bar.min_value; int32_t range = slider->max_value - slider->min_value;
int16_t new_value = 0; int16_t new_value = 0;
int16_t real_max_value = ext->bar.max_value; int16_t real_max_value = slider->max_value;
int16_t real_min_value = ext->bar.min_value; int16_t real_min_value = slider->min_value;
if(w >= h) { if(w >= h) {
lv_coord_t indic_w = w - bg_left - bg_right; lv_coord_t indic_w = w - bg_left - bg_right;
@@ -342,37 +362,37 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par
new_value = p.x - (slider->coords.x1 + bg_left); /*Make the point relative to the indicator*/ new_value = p.x - (slider->coords.x1 + bg_left); /*Make the point relative to the indicator*/
} }
new_value = (new_value * range) / indic_w; new_value = (new_value * range) / indic_w;
new_value += ext->bar.min_value; new_value += slider->min_value;
} }
else { else {
lv_coord_t indic_h = h - bg_bottom - bg_top; lv_coord_t indic_h = h - bg_bottom - bg_top;
new_value = p.y - (slider->coords.y2 + bg_bottom); /*Make the point relative to the indicator*/ new_value = p.y - (slider->coords.y2 + bg_bottom); /*Make the point relative to the indicator*/
new_value = (-new_value * range) / indic_h; new_value = (-new_value * range) / indic_h;
new_value += ext->bar.min_value; new_value += slider->min_value;
} }
/* Figure out the min. and max. for this mode */ /* Figure out the min. and max. for this mode */
if(ext->value_to_set == &ext->bar.start_value) { if(slider->value_to_set == &slider->start_value) {
real_max_value = ext->bar.cur_value; real_max_value = slider->cur_value;
} }
else { else {
real_min_value = ext->bar.start_value; real_min_value = slider->start_value;
} }
if(new_value < real_min_value) new_value = real_min_value; if(new_value < real_min_value) new_value = real_min_value;
else if(new_value > real_max_value) new_value = real_max_value; else if(new_value > real_max_value) new_value = real_max_value;
if(*ext->value_to_set != new_value) { if(*slider->value_to_set != new_value) {
*ext->value_to_set = new_value; *slider->value_to_set = new_value;
lv_obj_invalidate(slider); lv_obj_invalidate(obj);
res = lv_event_send(slider, LV_EVENT_VALUE_CHANGED, NULL); res = lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL);
if(res != LV_RES_OK) return res; if(res != LV_RES_OK) return res;
} }
} }
else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) { else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) {
ext->dragging = false; slider->dragging = false;
ext->value_to_set = NULL; slider->value_to_set = NULL;
#if LV_USE_GROUP #if LV_USE_GROUP
/*Leave edit mode if released. (No need to wait for LONG_PRESS) */ /*Leave edit mode if released. (No need to wait for LONG_PRESS) */
@@ -382,9 +402,9 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par
if(indev_type == LV_INDEV_TYPE_ENCODER) { if(indev_type == LV_INDEV_TYPE_ENCODER) {
if(editing) { if(editing) {
if(lv_slider_get_type(slider) == LV_SLIDER_TYPE_RANGE) { if(lv_slider_get_type(slider) == LV_SLIDER_TYPE_RANGE) {
if(ext->left_knob_focus == 0) ext->left_knob_focus = 1; if(slider->left_knob_focus == 0) slider->left_knob_focus = 1;
else { else {
ext->left_knob_focus = 0; slider->left_knob_focus = 0;
lv_group_set_editing(g, false); lv_group_set_editing(g, false);
} }
} }
@@ -397,28 +417,28 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par
} }
else if(sign == LV_SIGNAL_FOCUS) { else if(sign == LV_SIGNAL_FOCUS) {
ext->left_knob_focus = 0; slider->left_knob_focus = 0;
} }
else if(sign == LV_SIGNAL_COORD_CHG) { else if(sign == LV_SIGNAL_COORD_CHG) {
/* The knob size depends on slider size. /* The knob size depends on slider size.
* During the drawing method the ext. size is used by the knob so refresh the ext. size.*/ * During the drawing method the obj. size is used by the knob so refresh the obj. size.*/
if(lv_obj_get_width(slider) != lv_area_get_width(param) || if(lv_obj_get_width(obj) != lv_area_get_width(param) ||
lv_obj_get_height(slider) != lv_area_get_height(param)) { lv_obj_get_height(obj) != lv_area_get_height(param)) {
_lv_obj_refresh_ext_draw_pad(slider); _lv_obj_refresh_ext_draw_pad(obj);
} }
} }
else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) { else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
lv_style_int_t knob_left = lv_obj_get_style_pad_left(slider, LV_SLIDER_PART_KNOB); lv_style_int_t knob_left = lv_obj_get_style_pad_left(obj, LV_SLIDER_PART_KNOB);
lv_style_int_t knob_right = lv_obj_get_style_pad_right(slider, LV_SLIDER_PART_KNOB); lv_style_int_t knob_right = lv_obj_get_style_pad_right(obj,LV_SLIDER_PART_KNOB);
lv_style_int_t knob_top = lv_obj_get_style_pad_top(slider, LV_SLIDER_PART_KNOB); lv_style_int_t knob_top = lv_obj_get_style_pad_top(obj, LV_SLIDER_PART_KNOB);
lv_style_int_t knob_bottom = lv_obj_get_style_pad_bottom(slider, LV_SLIDER_PART_KNOB); lv_style_int_t knob_bottom = lv_obj_get_style_pad_bottom(obj, LV_SLIDER_PART_KNOB);
/* The smaller size is the knob diameter*/ /* The smaller size is the knob diameter*/
lv_coord_t knob_size = LV_MATH_MIN(lv_obj_get_width(slider), lv_obj_get_height(slider)) >> 1; lv_coord_t knob_size = LV_MATH_MIN(lv_obj_get_width(obj), lv_obj_get_height(obj)) >> 1;
knob_size += LV_MATH_MAX(LV_MATH_MAX(knob_left, knob_right), LV_MATH_MAX(knob_bottom, knob_top)); knob_size += LV_MATH_MAX(LV_MATH_MAX(knob_left, knob_right), LV_MATH_MAX(knob_bottom, knob_top));
knob_size += 2; /*For rounding error*/ knob_size += 2; /*For rounding error*/
knob_size += _lv_obj_get_draw_rect_ext_pad_size(slider, LV_SLIDER_PART_KNOB); knob_size += _lv_obj_get_draw_rect_ext_pad_size(obj, LV_SLIDER_PART_KNOB);
/*Indic. size is handled by bar*/ /*Indic. size is handled by bar*/
lv_coord_t * s = param; lv_coord_t * s = param;
@@ -430,14 +450,14 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par
char c = *((char *)param); char c = *((char *)param);
if(c == LV_KEY_RIGHT || c == LV_KEY_UP) { if(c == LV_KEY_RIGHT || c == LV_KEY_UP) {
if(!ext->left_knob_focus) lv_slider_set_value(slider, lv_slider_get_value(slider) + 1, LV_ANIM_ON); if(!slider->left_knob_focus) lv_slider_set_value(slider, lv_slider_get_value(slider) + 1, LV_ANIM_ON);
else lv_slider_set_left_value(slider, lv_slider_get_left_value(slider) + 1, LV_ANIM_ON); else lv_slider_set_left_value(slider, lv_slider_get_left_value(slider) + 1, LV_ANIM_ON);
res = lv_event_send(slider, LV_EVENT_VALUE_CHANGED, NULL); res = lv_event_send(slider, LV_EVENT_VALUE_CHANGED, NULL);
if(res != LV_RES_OK) return res; if(res != LV_RES_OK) return res;
} }
else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) { else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) {
if(!ext->left_knob_focus) lv_slider_set_value(slider, lv_slider_get_value(slider) - 1, LV_ANIM_ON); if(!slider->left_knob_focus) lv_slider_set_value(slider, lv_slider_get_value(slider) - 1, LV_ANIM_ON);
else lv_slider_set_left_value(slider, lv_slider_get_left_value(slider) - 1, LV_ANIM_ON); else lv_slider_set_left_value(slider, lv_slider_get_left_value(slider) - 1, LV_ANIM_ON);
res = lv_event_send(slider, LV_EVENT_VALUE_CHANGED, NULL); res = lv_event_send(slider, LV_EVENT_VALUE_CHANGED, NULL);
@@ -445,9 +465,6 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par
} }
#endif #endif
} }
else if(sign == LV_SIGNAL_CLEANUP) {
_lv_obj_reset_style_list_no_refr(slider, LV_SLIDER_PART_KNOB);
}
else if(sign == LV_SIGNAL_GET_EDITABLE) { else if(sign == LV_SIGNAL_GET_EDITABLE) {
#if LV_USE_GROUP #if LV_USE_GROUP
bool * editable = (bool *)param; bool * editable = (bool *)param;
@@ -459,11 +476,8 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par
} }
static lv_style_list_t * lv_slider_get_style(lv_obj_t * slider, uint8_t part) static lv_style_list_t * lv_slider_get_style(lv_slider_t * slider, uint8_t part)
{ {
LV_ASSERT_OBJ(slider, LV_OBJX_NAME);
lv_slider_ext_t * ext = lv_obj_get_ext_attr(slider);
lv_style_list_t * style_dsc_p; lv_style_list_t * style_dsc_p;
switch(part) { switch(part) {
@@ -471,10 +485,10 @@ static lv_style_list_t * lv_slider_get_style(lv_obj_t * slider, uint8_t part)
style_dsc_p = &slider->style_list; style_dsc_p = &slider->style_list;
break; break;
case LV_SLIDER_PART_INDIC: case LV_SLIDER_PART_INDIC:
style_dsc_p = &ext->bar.style_indic; style_dsc_p = &slider->style_indic;
break; break;
case LV_SLIDER_PART_KNOB: case LV_SLIDER_PART_KNOB:
style_dsc_p = &ext->style_knob; style_dsc_p = &slider->style_knob;
break; break;
default: default:
style_dsc_p = NULL; style_dsc_p = NULL;

View File

@@ -40,17 +40,23 @@ enum {
}; };
typedef uint8_t lv_slider_type_t; typedef uint8_t lv_slider_type_t;
/*Data of slider*/ LV_CLASS_DECLARE_START(lv_slider, lv_bar)
typedef struct {
lv_bar_ext_t bar; /*Ext. of ancestor*/ #define _lv_slider_constructor void (*constructor)(struct _lv_obj_t * obj, struct _lv_obj_t * parent, const struct _lv_obj_t * copy)
/*New data for this type */
lv_style_list_t style_knob; /*Style of the knob*/ #define _lv_slider_data \
lv_area_t left_knob_area; _lv_bar_data \
lv_area_t right_knob_area; lv_style_list_t style_knob; /*Style of the knob*/ \
int16_t * value_to_set; /* Which bar value to set */ lv_area_t left_knob_area; \
uint8_t dragging : 1; /*1: the slider is being dragged*/ lv_area_t right_knob_area; \
int16_t * value_to_set; /* Which bar value to set */ \
uint8_t dragging : 1; /*1: the slider is being dragged*/ \
uint8_t left_knob_focus : 1; /*1: with encoder now the right knob can be adjusted*/ uint8_t left_knob_focus : 1; /*1: with encoder now the right knob can be adjusted*/
} lv_slider_ext_t;
#define _lv_slider_class_dsc \
_lv_bar_class_dsc \
LV_CLASS_DECLARE_END(lv_slider, lv_bar)
/** Built-in styles of slider*/ /** Built-in styles of slider*/
enum { enum {