update layouts

This commit is contained in:
Gabor Kiss-Vamosi
2021-01-03 00:12:42 +01:00
parent 98c2cdde3a
commit d027a4f00f
13 changed files with 447 additions and 669 deletions
+113 -189
View File
@@ -23,17 +23,43 @@ typedef struct {
uint32_t item_cnt; uint32_t item_cnt;
}track_t; }track_t;
/********************** /**********************
* STATIC PROTOTYPES * STATIC PROTOTYPES
**********************/ **********************/
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 void flex_update(lv_obj_t * cont, lv_obj_t * item);
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 int32_t find_track_end(lv_obj_t * cont, int32_t item_start_id, lv_coord_t max_main_size, 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 children_repos(lv_obj_t * cont, int32_t item_first_id, int32_t item_last_id, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t max_main_size, track_t * t);
static void place_content(lv_flex_place_t place, lv_coord_t max_size, lv_coord_t content_size, lv_coord_t item_cnt, lv_coord_t * start_pos, lv_coord_t * gap);
static lv_obj_t * get_next_item(lv_obj_t * cont, bool rev, int32_t * item_id);
static lv_flex_dir_t get_dir(const lv_obj_t * obj); /**********************
static bool get_rev(const lv_obj_t * obj); * GLOBAL VARIABLES
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); const lv_flex_t lv_flex_center = {
.update_cb = flex_update,
.item_main_place = LV_FLEX_PLACE_CENTER,
.item_cross_place = LV_FLEX_PLACE_CENTER,
.track_place = LV_FLEX_PLACE_CENTER,
.dir = LV_FLEX_FLOW_COLUMN
};
const lv_flex_t lv_flex_stacked = {
.update_cb = flex_update,
.item_main_place = LV_FLEX_PLACE_START,
.item_cross_place = LV_FLEX_PLACE_START,
.track_place = LV_FLEX_PLACE_START,
.dir = LV_FLEX_FLOW_COLUMN
};
const lv_flex_t lv_flex_even = {
.update_cb = flex_update,
.item_main_place = LV_FLEX_PLACE_SPACE_EVENLY,
.item_cross_place = LV_FLEX_PLACE_CENTER,
.track_place = LV_FLEX_PLACE_CENTER,
.dir = LV_FLEX_FLOW_ROW,
.wrap = 1
};
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
@@ -51,113 +77,53 @@ static lv_obj_t * get_next_item(lv_obj_t * cont, bool rev, uint32_t * item_id);
* Setter functions * Setter functions
*====================*/ *====================*/
void lv_obj_set_flex_dir(lv_obj_t * obj, lv_flex_dir_t flex_dir) void lv_flex_init(lv_flex_t * flex)
{ {
lv_obj_allocate_spec_attr(obj); _lv_memset_00(flex, sizeof(lv_flex_t));
flex->update_cb = flex_update;
if(obj->spec_attr->flex_cont.dir == flex_dir) return; flex->dir = LV_FLEX_FLOW_ROW;
flex->item_main_place = LV_FLEX_PLACE_START;
obj->spec_attr->flex_cont.dir = flex_dir & 0x3; flex->track_place = LV_FLEX_PLACE_START;
obj->spec_attr->flex_cont.wrap = flex_dir & _LV_FLEX_WRAP ? 1 : 0; flex->item_cross_place = LV_FLEX_PLACE_START;
obj->spec_attr->flex_cont.rev = flex_dir & _LV_FLEX_REVERSE ? 1 : 0;
_lv_flex_refresh(obj);
} }
void lv_obj_set_flex_place(lv_obj_t * obj, lv_flex_place_t main_place, lv_flex_place_t cross_place) void lv_flex_set_flow(lv_flex_t * flex, lv_flex_flow_t flow)
{ {
lv_obj_allocate_spec_attr(obj); flex->dir = flow & 0x3;
if(obj->spec_attr->flex_cont.main_place == main_place && flex->wrap = flow & _LV_FLEX_WRAP ? 1 : 0;
obj->spec_attr->flex_cont.cross_place == cross_place) { flex->rev = flow & _LV_FLEX_REVERSE ? 1 : 0;
return;
}
obj->spec_attr->flex_cont.main_place = main_place;
obj->spec_attr->flex_cont.cross_place = cross_place;
_lv_flex_refresh(obj);
} }
void lv_obj_set_flex_gap(lv_obj_t * obj, lv_coord_t gap) void lv_flex_set_place(lv_flex_t * flex, lv_flex_place_t item_main_place, lv_flex_place_t item_cross_place, lv_flex_place_t track_place)
{ {
if(obj->spec_attr == NULL) lv_obj_allocate_spec_attr(obj); flex->item_main_place = item_main_place;
flex->track_place = track_place;
if(obj->spec_attr->flex_cont.gap == gap) return; flex->item_cross_place = item_cross_place;
obj->spec_attr->flex_cont.gap = gap;
_lv_flex_refresh(obj);
} }
void lv_obj_set_flex_item(lv_obj_t * obj, bool en) void lv_flex_set_gap(lv_flex_t * flex, lv_coord_t main_gap, lv_coord_t cross_gap)
{ {
if(en) { flex->item_gap = main_gap;
lv_coord_t f = _LV_COORD_FELX(LV_FLEX_PLACE_START); flex->track_gap = cross_gap;
lv_obj_set_pos(obj, f, f);
} else {
lv_obj_set_pos(obj, lv_obj_get_x(obj), lv_obj_get_y(obj));
}
}
void lv_obj_set_flex_item_place(lv_obj_t * obj, lv_flex_place_t place)
{
if(place == LV_FLEX_PLACE_NONE) {
lv_obj_set_pos(obj, lv_obj_get_x(obj), lv_obj_get_x(obj));
} else {
lv_coord_t f = _LV_COORD_FELX(place);
lv_obj_set_pos(obj, f, f);
}
} }
/*===================== /*=====================
* Getter functions * Getter functions
*====================*/ *====================*/
lv_flex_dir_t lv_obj_get_flex_dir(const lv_obj_t * obj) static void flex_update(lv_obj_t * cont, lv_obj_t * item)
{ {
if(obj->spec_attr) return obj->spec_attr->flex_cont.dir; if(cont->spec_attr == NULL) return;
else return LV_FLEX_DIR_NONE; const lv_flex_t * f = cont->spec_attr->layout_dsc;
}
lv_flex_place_t lv_obj_get_flex_item_place(const lv_obj_t * obj)
{
if(obj->spec_attr) return obj->spec_attr->flex_cont.main_place;
else return LV_FLEX_PLACE_START;
}
lv_flex_place_t lv_obj_get_flex_track_place(const lv_obj_t * obj)
{
if(obj->spec_attr) return obj->spec_attr->flex_cont.cross_place;
else return LV_FLEX_PLACE_START;
}
lv_coord_t lv_obj_get_flex_gap(const lv_obj_t * obj)
{
if(obj->spec_attr) return obj->spec_attr->flex_cont.gap;
else return 0;
}
lv_flex_place_t lv_obj_get_flex_self_place(lv_obj_t * obj)
{
lv_coord_t x = lv_obj_get_x(obj);
if(LV_COORD_IS_FLEX(x)) return LV_COORD_GET_FLEX(x);
else return LV_FLEX_PLACE_NONE;
}
void _lv_flex_refresh(lv_obj_t * cont)
{
lv_flex_dir_t dir = get_dir(cont);
if(dir == LV_FLEX_DIR_NONE) return;
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;
bool row = dir == LV_FLEX_DIR_ROW ? true : false; bool row = f->dir == LV_FLEX_FLOW_ROW ? true : false;
/*Count the grow units and free space*/ /*Count the grow units and free space*/
lv_coord_t max_main_size = (row ? lv_obj_get_width_fit(cont) : lv_obj_get_height_fit(cont)); lv_coord_t max_main_size = (row ? lv_obj_get_width_fit(cont) : lv_obj_get_height_fit(cont));
lv_coord_t abs_y = cont->coords.y1 + lv_obj_get_style_pad_top(cont, LV_PART_MAIN) - lv_obj_get_scroll_y(cont); lv_coord_t abs_y = cont->coords.y1 + lv_obj_get_style_pad_top(cont, LV_PART_MAIN) - lv_obj_get_scroll_y(cont);
lv_coord_t abs_x = cont->coords.x1 + lv_obj_get_style_pad_left(cont, LV_PART_MAIN) - lv_obj_get_scroll_x(cont); lv_coord_t abs_x = cont->coords.x1 + lv_obj_get_style_pad_left(cont, LV_PART_MAIN) - lv_obj_get_scroll_x(cont);
lv_flex_place_t cross_place = lv_obj_get_flex_track_place(cont); lv_flex_place_t cross_place = f->track_place;
lv_flex_place_t main_place = cont->spec_attr->flex_cont.main_place;
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) ||
@@ -174,32 +140,38 @@ 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;
uint32_t track_first_item; int32_t track_first_item;
uint32_t next_track_first_item; int32_t next_track_first_item;
bool rev = get_rev(cont);
if(cross_place != LV_FLEX_PLACE_START) { if(cross_place != LV_FLEX_PLACE_START) {
track_first_item = rev ? cont->spec_attr->child_cnt - 1 : 0; track_first_item = f->rev ? cont->spec_attr->child_cnt - 1 : 0;
track_t t; track_t t;
while(track_first_item ) { while(track_first_item < cont->spec_attr->child_cnt && track_first_item >= 0) {
/*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 + f->track_gap;
track_cnt++; track_cnt++;
track_first_item = next_track_first_item; track_first_item = next_track_first_item;
} }
if(track_cnt) total_track_cross_size -= f->track_gap; /*No gap after the last track*/
/* Place the tracks to get the start position
* If the the height of the tracks is larger than the available space
* always use the gap = 0 and start position = 0 to avoid unintuitive scrolling*/
lv_coord_t max_cross_size = (row ? lv_obj_get_height_fit(cont) : lv_obj_get_width_fit(cont)); lv_coord_t max_cross_size = (row ? lv_obj_get_height_fit(cont) : lv_obj_get_width_fit(cont));
if(total_track_cross_size < max_cross_size) {
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 ? cont->spec_attr->child_cnt - 1 : 0; track_first_item = f->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;
} }
while(track_first_item) { while(track_first_item < cont->spec_attr->child_cnt && track_first_item >= 0) {
track_t t; track_t t;
/*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);
@@ -207,13 +179,13 @@ void _lv_flex_refresh(lv_obj_t * cont)
if(rtl && !row) { if(rtl && !row) {
*cross_pos -= t.track_cross_size; *cross_pos -= t.track_cross_size;
} }
children_repos(cont, track_first_item, next_track_first_item, abs_x, abs_y, max_main_size, main_place, &t); children_repos(cont, track_first_item, next_track_first_item, abs_x, abs_y, max_main_size, &t);
track_first_item = next_track_first_item; track_first_item = next_track_first_item;
if(rtl && !row) { if(rtl && !row) {
*cross_pos -= gap; *cross_pos -= gap + f->track_gap;
} else { } else {
*cross_pos += t.track_cross_size + gap; *cross_pos += t.track_cross_size + gap + f->track_gap;
} }
} }
LV_ASSERT_MEM_INTEGRITY(); LV_ASSERT_MEM_INTEGRITY();
@@ -223,12 +195,11 @@ void _lv_flex_refresh(lv_obj_t * cont)
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
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 int32_t find_track_end(lv_obj_t * cont, int32_t item_start_id, lv_coord_t max_main_size, track_t * t)
{ {
bool wrap = get_wrap(cont); const lv_flex_t * f = cont->spec_attr->layout_dsc;
bool rev = get_rev(cont);
lv_coord_t gap = lv_obj_get_flex_gap(cont); bool row = f->dir == LV_FLEX_FLOW_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);
@@ -239,38 +210,31 @@ static uint32_t find_track_end(lv_obj_t * cont, uint32_t item_start_id, lv_coord
t->grow_unit = 0; t->grow_unit = 0;
t->item_cnt = 0; t->item_cnt = 0;
uint32_t item_id = item_start_id; int32_t item_id = item_start_id;
lv_obj_t * item = get_next_item(cont, rev, &item_id); lv_obj_t * item = lv_obj_get_child(cont, item_id);
while(item) { while(item) {
/*Ignore non-flex items*/
lv_coord_t main_set = (row ? item->x_set : item->y_set);
if(LV_COORD_IS_FLEX(main_set) == false) {
item = get_next_item(cont, rev, &item_id);
continue;
}
lv_coord_t main_size = (row ? item->w_set : item->h_set); lv_coord_t main_size = (row ? item->w_set : item->h_set);
if(_LV_FLEX_GET_GROW(main_size)) { if(_LV_FLEX_GET_GROW(main_size)) {
grow_sum += _LV_FLEX_GET_GROW(main_size); grow_sum += _LV_FLEX_GET_GROW(main_size);
grow_item_cnt++; grow_item_cnt++;
} else { } else {
lv_coord_t item_size = get_main_size(item) + gap; lv_coord_t item_size = get_main_size(item) + f->item_gap;
if(wrap && t->track_main_size + item_size > max_main_size) break; if(f->wrap && t->track_main_size + item_size > max_main_size) break;
t->track_main_size += item_size; t->track_main_size += item_size;
} }
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_id += rev ? -1 : +1; item_id += f->rev ? -1 : +1;
item = lv_obj_get_child(cont, item_id); item = lv_obj_get_child(cont, item_id);
t->item_cnt++; t->item_cnt++;
} }
if(t->track_main_size > 0) t->track_main_size -= gap; /*There is no gap after the last item*/ if(t->track_main_size > 0) t->track_main_size -= f->item_gap; /*There is no gap after the last item*/
if(grow_item_cnt && grow_sum) { if(grow_item_cnt && grow_sum) {
lv_coord_t s = max_main_size - t->track_main_size; lv_coord_t s = max_main_size - t->track_main_size;
s -= grow_item_cnt * gap; s -= grow_item_cnt * f->item_gap;
t->grow_unit = s / grow_sum; t->grow_unit = s / grow_sum;
t->track_main_size = max_main_size; /*If there is at least one "grow item" the track takes the full space*/ t->track_main_size = max_main_size; /*If there is at least one "grow item" the track takes the full space*/
} else { } else {
@@ -279,7 +243,7 @@ static uint32_t find_track_end(lv_obj_t * cont, uint32_t item_start_id, lv_coord
/*Have at least one item in a row*/ /*Have at least one item in a row*/
if(item && item_id == item_start_id) { if(item && item_id == item_start_id) {
item = get_next_item(cont, rev, &item_id); item = get_next_item(cont, f->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);
@@ -291,19 +255,18 @@ static uint32_t find_track_end(lv_obj_t * cont, uint32_t item_start_id, lv_coord
} }
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, int32_t item_first_id, int32_t item_last_id, lv_coord_t abs_x, lv_coord_t abs_y, lv_coord_t max_main_size, track_t * t)
{ {
bool rev = get_rev(cont);
lv_coord_t gap = lv_obj_get_flex_gap(cont); const lv_flex_t * f = cont->spec_attr->layout_dsc;
bool row = get_dir(cont) == LV_FLEX_DIR_ROW ? true : false; bool row = f->dir == LV_FLEX_FLOW_ROW ? true : false;
lv_coord_t(*obj_get_main_size)(const lv_obj_t *) = (row ? lv_obj_get_width_margin : lv_obj_get_height_margin); lv_coord_t(*obj_get_main_size)(const lv_obj_t *) = (row ? lv_obj_get_width_margin : lv_obj_get_height_margin);
lv_coord_t(*obj_get_cross_size)(const lv_obj_t *) = (!row ? lv_obj_get_width_margin : lv_obj_get_height_margin); lv_coord_t(*obj_get_cross_size)(const lv_obj_t *) = (!row ? lv_obj_get_width_margin : lv_obj_get_height_margin);
void (*area_set_main_size)(lv_area_t *, lv_coord_t) = (row ? lv_area_set_width : lv_area_set_height); void (*area_set_main_size)(lv_area_t *, lv_coord_t) = (row ? lv_area_set_width : lv_area_set_height);
void (*area_set_cross_size)(lv_area_t *, lv_coord_t) = (!row ? lv_area_set_width : lv_area_set_height);
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_coord_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_coord_t (*get_margin_start)(const lv_obj_t *, uint32_t part) = (row ? lv_obj_get_style_margin_left : lv_obj_get_style_margin_top);
lv_coord_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_coord_t (*get_margin_end)(const lv_obj_t *, uint32_t part) = (row ? lv_obj_get_style_margin_right : lv_obj_get_style_margin_bottom);
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;
@@ -312,31 +275,19 @@ static void children_repos(lv_obj_t * cont, uint32_t item_first_id, uint32_t ite
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(f->item_main_place, max_main_size, t->track_main_size, t->item_cnt, &main_pos, &place_gap);
lv_obj_t * item = get_next_item(cont, rev, &item_first_id); lv_obj_t * item = lv_obj_get_child(cont, item_first_id);
/*Reposition the children*/ /*Reposition the children*/
while(item && item_first_id != item_last_id) { while(item && item_first_id != item_last_id) {
/*Ignore non-flex items*/
lv_coord_t main_set = (row ? item->x_set : item->y_set);
if(LV_COORD_IS_FLEX(main_set) == false) {
item = get_next_item(cont, rev, &item_first_id);
continue;
}
lv_coord_t main_size = (row ? item->w_set : item->h_set); lv_coord_t main_size = (row ? item->w_set : item->h_set);
if(_LV_FLEX_GET_GROW(main_size) || LV_COORD_GET_FLEX(main_set) == LV_FLEX_PLACE_STRETCH) { if(_LV_FLEX_GET_GROW(main_size)) {
lv_area_t old_coords; lv_area_t old_coords;
lv_area_copy(&old_coords, &item->coords); lv_area_copy(&old_coords, &item->coords);
if(_LV_FLEX_GET_GROW(main_size)) {
lv_coord_t s = _LV_FLEX_GET_GROW(main_size) * t->grow_unit; lv_coord_t s = _LV_FLEX_GET_GROW(main_size) * t->grow_unit;
s -= get_margin_start(item, LV_PART_MAIN) + get_margin_end(item, LV_PART_MAIN); s -= get_margin_start(item, LV_PART_MAIN) + get_margin_end(item, LV_PART_MAIN);
area_set_main_size(&item->coords, s); area_set_main_size(&item->coords, s);
}
if(LV_COORD_GET_FLEX(main_set) == LV_FLEX_PLACE_STRETCH) {
area_set_cross_size(&item->coords, t->track_cross_size);
}
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);
@@ -346,18 +297,15 @@ static void children_repos(lv_obj_t * cont, uint32_t item_first_id, uint32_t ite
} }
lv_coord_t cross_pos = 0; lv_coord_t cross_pos = 0;
lv_coord_t cross_set = (row ? item->y_set : item->x_set); switch(f->item_cross_place) {
switch(LV_COORD_GET_FLEX(cross_set)) {
case LV_FLEX_PLACE_CENTER: case LV_FLEX_PLACE_CENTER:
cross_pos = (t->track_cross_size - obj_get_cross_size(item)) / 2; cross_pos = (t->track_cross_size - obj_get_cross_size(item)) / 2;
break; break;
case LV_FLEX_PLACE_END: case LV_FLEX_PLACE_END:
cross_pos = t->track_cross_size - obj_get_cross_size(item); cross_pos = t->track_cross_size - obj_get_cross_size(item);
break; break;
} default:
break;
if(row && rtl) {
main_pos -= obj_get_main_size(item) + gap + place_gap;
} }
lv_coord_t diff_x = abs_x - item->coords.x1 + lv_obj_get_style_margin_left(item, LV_PART_MAIN); lv_coord_t diff_x = abs_x - item->coords.x1 + lv_obj_get_style_margin_left(item, LV_PART_MAIN);
@@ -374,13 +322,13 @@ static void children_repos(lv_obj_t * cont, uint32_t item_first_id, uint32_t ite
} }
if(!(row && rtl)) { if(!(row && rtl)) {
main_pos += obj_get_main_size(item) + gap + place_gap; main_pos += obj_get_main_size(item) + f->item_gap + place_gap;
} }
item = get_next_item(cont, rev, &item_first_id); item = get_next_item(cont, f->rev, &item_first_id);
} }
} }
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_flex_place_t place, lv_coord_t max_size, lv_coord_t content_size, lv_coord_t item_cnt, lv_coord_t * start_pos, lv_coord_t * gap)
{ {
if(item_cnt <= 1) { if(item_cnt <= 1) {
switch(place) { switch(place) {
@@ -389,27 +337,29 @@ static void place_content(lv_coord_t place, lv_coord_t max_size, lv_coord_t trac
case LV_FLEX_PLACE_SPACE_EVENLY: case LV_FLEX_PLACE_SPACE_EVENLY:
place = LV_FLEX_PLACE_CENTER; place = LV_FLEX_PLACE_CENTER;
break; break;
default:
break;
} }
} }
switch(place) { switch(place) {
case LV_FLEX_PLACE_CENTER: case LV_FLEX_PLACE_CENTER:
*gap = 0; *gap = 0;
*start_pos += (max_size - track_size) / 2; *start_pos += (max_size - content_size) / 2;
break; break;
case LV_FLEX_PLACE_END: case LV_FLEX_PLACE_END:
*gap = 0; *gap = 0;
*start_pos += max_size - track_size; *start_pos += max_size - content_size;
break; break;
case LV_FLEX_PLACE_SPACE_BETWEEN: case LV_FLEX_PLACE_SPACE_BETWEEN:
*gap = (lv_coord_t)(max_size - track_size) / (lv_coord_t)(item_cnt - 1); *gap = (lv_coord_t)(max_size - content_size) / (lv_coord_t)(item_cnt - 1);
break; break;
case LV_FLEX_PLACE_SPACE_AROUND: case LV_FLEX_PLACE_SPACE_AROUND:
*gap += (lv_coord_t)(max_size - track_size) / (lv_coord_t)(item_cnt); *gap += (lv_coord_t)(max_size - content_size) / (lv_coord_t)(item_cnt);
*start_pos += *gap / 2; *start_pos += *gap / 2;
break; break;
case LV_FLEX_PLACE_SPACE_EVENLY: case LV_FLEX_PLACE_SPACE_EVENLY:
*gap = (lv_coord_t)(max_size - track_size) / (lv_coord_t)(item_cnt + 1); *gap = (lv_coord_t)(max_size - content_size) / (lv_coord_t)(item_cnt + 1);
*start_pos += *gap; *start_pos += *gap;
break; break;
default: default:
@@ -417,41 +367,15 @@ static void place_content(lv_coord_t place, lv_coord_t max_size, lv_coord_t trac
} }
} }
static lv_flex_dir_t get_dir(const lv_obj_t * obj) static lv_obj_t * get_next_item(lv_obj_t * cont, bool rev, int32_t * item_id)
{
if(obj->spec_attr) return obj->spec_attr->flex_cont.dir;
else return false;
}
static bool get_rev(const lv_obj_t * obj)
{
if(obj->spec_attr) return obj->spec_attr->flex_cont.rev;
else return false;
}
static bool get_wrap(const lv_obj_t * obj)
{
if(obj->spec_attr) return obj->spec_attr->flex_cont.wrap;
else return false;
}
static lv_obj_t * get_next_item(lv_obj_t * cont, bool rev, uint32_t * item_id)
{ {
if(rev) { if(rev) {
if(*item_id > 0) {
(*item_id)--; (*item_id)--;
return cont->spec_attr->children[*item_id]; if(*item_id >= 0) return cont->spec_attr->children[*item_id];
} else return NULL;
else {
return NULL;
}
} else { } else {
if((*item_id) <= cont->spec_attr->child_cnt - 1) { (*item_id)++;
item_id++; if((*item_id) < cont->spec_attr->child_cnt) return cont->spec_attr->children[*item_id];
return cont->spec_attr->children[*item_id]; else return NULL;
}
else {
return NULL;
}
} }
} }
+30 -28
View File
@@ -13,16 +13,16 @@ extern "C" {
/********************* /*********************
* INCLUDES * INCLUDES
*********************/ *********************/
#include "../lv_misc/lv_area.h" #include "lv_obj_pos.h"
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
/** Can be set as width or height (on main axis) to grow the object in order fill the free space*/ /** Can be set as width or height (on main axis) to grow the object in order fill the free space*/
#define LV_FLEX_GROW(grow) (_LV_COORD_FELX(grow)) #define LV_FLEX_GROW(grow) (LV_COORD_SET_LAYOUT(grow))
#define _LV_FLEX_GET_GROW(v) (LV_COORD_IS_FLEX(v) ? LV_COORD_GET_FLEX(v) : 0) #define _LV_FLEX_GET_GROW(v) (LV_COORD_IS_LAYOUT(v) ? _LV_COORD_PLAIN(v) : 0)
#define _LV_FLEX_WRAP (1 << 2) #define _LV_FLEX_WRAP (1 << 2)
#define _LV_FLEX_REVERSE (1 << 3) #define _LV_FLEX_REVERSE (1 << 3)
@@ -39,32 +39,33 @@ typedef enum {
LV_FLEX_PLACE_START, LV_FLEX_PLACE_START,
LV_FLEX_PLACE_END, LV_FLEX_PLACE_END,
LV_FLEX_PLACE_CENTER, LV_FLEX_PLACE_CENTER,
LV_FLEX_PLACE_STRETCH,
LV_FLEX_PLACE_SPACE_EVENLY, LV_FLEX_PLACE_SPACE_EVENLY,
LV_FLEX_PLACE_SPACE_AROUND, LV_FLEX_PLACE_SPACE_AROUND,
LV_FLEX_PLACE_SPACE_BETWEEN, LV_FLEX_PLACE_SPACE_BETWEEN,
}lv_flex_place_t; }lv_flex_place_t;
typedef enum { typedef enum {
LV_FLEX_DIR_NONE, LV_FLEX_FLOW_ROW = 0x01,
LV_FLEX_DIR_ROW = 0x01, LV_FLEX_FLOW_COLUMN = 0x02,
LV_FLEX_DIR_COLUMN = 0x02, LV_FLEX_FLOW_ROW_WRAP = LV_FLEX_FLOW_ROW | _LV_FLEX_WRAP,
LV_FLEX_DIR_ROW_WRAP = LV_FLEX_DIR_ROW | _LV_FLEX_WRAP, LV_FLEX_FLOW_ROW_REVERSE = LV_FLEX_FLOW_ROW | _LV_FLEX_REVERSE,
LV_FLEX_DIR_ROW_REVERSE = LV_FLEX_DIR_ROW | _LV_FLEX_REVERSE, LV_FLEX_FLOW_ROW_WRAP_REVERSE = LV_FLEX_FLOW_ROW | _LV_FLEX_WRAP | _LV_FLEX_REVERSE,
LV_FLEX_DIR_ROW_WRAP_REVERSE = LV_FLEX_DIR_ROW | _LV_FLEX_WRAP | _LV_FLEX_REVERSE, LV_FLEX_FLOW_COLUMN_WRAP = LV_FLEX_FLOW_COLUMN | _LV_FLEX_WRAP,
LV_FLEX_DIR_COLUMN_WRAP = LV_FLEX_DIR_COLUMN | _LV_FLEX_WRAP, LV_FLEX_FLOW_COLUMN_REVERSE = LV_FLEX_FLOW_COLUMN | _LV_FLEX_REVERSE,
LV_FLEX_DIR_COLUMN_REVERSE = LV_FLEX_DIR_COLUMN | _LV_FLEX_REVERSE, LV_FLEX_FLOW_COLUMN_WRAP_REVERSE = LV_FLEX_FLOW_COLUMN | _LV_FLEX_WRAP | _LV_FLEX_REVERSE,
LV_FLEX_DIR_COLUMN_WRAP_REVERSE = LV_FLEX_DIR_COLUMN | _LV_FLEX_WRAP | _LV_FLEX_REVERSE, }lv_flex_flow_t;
}lv_flex_dir_t;
typedef struct { typedef struct {
lv_coord_t gap; lv_layout_update_cb_t update_cb; /*The first element must be the update callback*/
uint8_t dir :2; lv_coord_t item_gap;
uint8_t wrap :1; lv_coord_t track_gap;
uint8_t rev :1; uint32_t dir :2;
uint8_t main_place :3; uint32_t wrap :1;
uint8_t cross_place :3; uint32_t rev :1;
}lv_flex_cont_t; uint32_t item_main_place :3;
uint32_t track_place :3;
uint32_t item_cross_place :3;
}lv_flex_t;
/********************** /**********************
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
@@ -81,7 +82,7 @@ typedef struct {
* @param obj pointer to an object * @param obj pointer to an object
* @param flex_dir the flex direction, an element of `lv_flex_dir_t` * @param flex_dir the flex direction, an element of `lv_flex_dir_t`
*/ */
void lv_obj_set_flex_dir(struct _lv_obj_t * obj, lv_flex_dir_t flex_dir); void lv_obj_set_flex_dir(struct _lv_obj_t * obj, lv_flex_flow_t flex_dir);
/** /**
* Set how to place the items and the tracks * Set how to place the items and the tracks
@@ -127,7 +128,7 @@ void lv_obj_set_flex_item_place(struct _lv_obj_t * obj, lv_flex_place_t place);
* @param obj pointer to an object * @param obj pointer to an object
* @return the flex direction of `obj` * @return the flex direction of `obj`
*/ */
lv_flex_dir_t lv_obj_get_flex_dir(const struct _lv_obj_t * obj); lv_flex_flow_t lv_obj_get_flex_dir(const struct _lv_obj_t * obj);
/** /**
* Get the item placement of a flex container * Get the item placement of a flex container
@@ -157,12 +158,13 @@ lv_coord_t lv_obj_get_flex_gap(const struct _lv_obj_t * obj);
* @return `LV_FLEX_PLACE_NONE/START/CENTER/END` * @return `LV_FLEX_PLACE_NONE/START/CENTER/END`
*/ */
lv_flex_place_t lv_obj_get_flex_self_place(struct _lv_obj_t * obj); lv_flex_place_t lv_obj_get_flex_self_place(struct _lv_obj_t * obj);
/**
* Rearrange the flex items of a flex container
* @param cont pointer to a flex container object
*/
void _lv_flex_refresh(struct _lv_obj_t * cont);
/**********************
* GLOBAL VARIABLES
**********************/
extern const lv_flex_t lv_flex_center;
extern const lv_flex_t lv_flex_stacked;
extern const lv_flex_t lv_flex_even;
/********************** /**********************
* MACROS * MACROS
+115 -199
View File
@@ -26,11 +26,15 @@ typedef struct {
/********************** /**********************
* STATIC PROTOTYPES * STATIC PROTOTYPES
**********************/ **********************/
static void calc_cols(lv_obj_t * cont, _lv_grid_calc_t * calc); void grid_update(lv_obj_t * cont, lv_obj_t * item);
static void calc_rows(lv_obj_t * cont, _lv_grid_calc_t * calc); static void full_refresh(lv_obj_t * cont);
static void item_repos(lv_obj_t * item, _lv_grid_calc_t * calc, item_repos_hint_t * hint); static void item_refr(lv_obj_t * item);
static void calc(struct _lv_obj_t * obj, _lv_grid_calc_t * calc);
static void calc_free(_lv_grid_calc_t * calc);
static void calc_cols(lv_obj_t * cont, _lv_grid_calc_t * c);
static void calc_rows(lv_obj_t * cont, _lv_grid_calc_t * c);
static void item_repos(lv_obj_t * item, _lv_grid_calc_t * c, item_repos_hint_t * hint);
static lv_coord_t grid_place(lv_coord_t cont_size, bool auto_size, uint8_t place, lv_coord_t gap, uint32_t track_num, lv_coord_t * size_array, lv_coord_t * pos_array, bool reverse); static lv_coord_t grid_place(lv_coord_t cont_size, bool auto_size, uint8_t place, lv_coord_t gap, uint32_t track_num, lv_coord_t * size_array, lv_coord_t * pos_array, bool reverse);
static void report_grid_change_core(const lv_grid_t * grid, lv_obj_t * obj);
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
@@ -47,6 +51,7 @@ static void report_grid_change_core(const lv_grid_t * grid, lv_obj_t * obj);
void lv_grid_init(lv_grid_t * grid) void lv_grid_init(lv_grid_t * grid)
{ {
_lv_memset_00(grid,sizeof(lv_grid_t)); _lv_memset_00(grid,sizeof(lv_grid_t));
grid->update_cb = grid_update;
grid->col_place = LV_GRID_START; grid->col_place = LV_GRID_START;
grid->row_place = LV_GRID_START; grid->row_place = LV_GRID_START;
} }
@@ -72,55 +77,79 @@ void lv_grid_set_gap(lv_grid_t * grid, lv_coord_t col_gap, uint8_t row_gap)
grid->row_gap = row_gap; grid->row_gap = row_gap;
} }
/**
* Set a grid for an object
* @param obj pointer to an object
* @param grid the grid to set
*/
void lv_obj_set_grid(lv_obj_t * obj, const lv_grid_t * grid)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
if(obj->spec_attr == NULL) lv_obj_allocate_spec_attr(obj);
obj->spec_attr->grid = grid;
_lv_grid_full_refresh(obj);
}
/**
* Get the grid of an object
* @param obj pointer to an object
* @return the grid, NULL if no grid
*/
const lv_grid_t * lv_obj_get_grid(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
if(obj->spec_attr) return obj->spec_attr->grid;
return NULL;
}
void lv_obj_set_grid_cell(lv_obj_t * obj, lv_coord_t col_pos, lv_coord_t row_pos) void lv_obj_set_grid_cell(lv_obj_t * obj, lv_coord_t col_pos, lv_coord_t row_pos)
{ {
lv_obj_set_pos(obj, col_pos, row_pos); lv_obj_set_pos(obj, col_pos, row_pos);
} }
/**
* Notify all object if a style is modified
* @param grid pointer to a grid. Only the objects with this grid will be notified
* (NULL to notify all objects with any grid)
*/
void lv_obj_report_grid_change(const lv_grid_t * grid)
{
lv_disp_t * d = lv_disp_get_next(NULL);
while(d) {
/**********************
* STATIC FUNCTIONS
**********************/
void grid_update(lv_obj_t * cont, lv_obj_t * item)
{
if(cont->spec_attr == NULL) return;
if(cont->spec_attr->layout_dsc == NULL) return;
if(item) item_refr(item);
else full_refresh(cont);
}
/**
* Refresh the all grid item on a container
* @param cont pointer to a grid container object
*/
static void full_refresh(lv_obj_t * cont)
{
const lv_grid_t * g = cont->spec_attr->layout_dsc;
/*Calculate the grid*/
if(g == NULL) return;
_lv_grid_calc_t c;
calc(cont, &c);
item_repos_hint_t hint;
_lv_memset_00(&hint, sizeof(hint));
/* Calculate the grids absolute x and y coordinates.
* It will be used as helper during item repositioning to avoid calculating this value for every children*/
lv_coord_t pad_left = lv_obj_get_style_pad_left(cont, LV_PART_MAIN);
lv_coord_t pad_top = lv_obj_get_style_pad_top(cont, LV_PART_MAIN);
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);
uint32_t i; uint32_t i;
for(i = 0; i < d->screen_cnt; i++) { for(i = 0; i < cont->spec_attr->child_cnt; i++) {
report_grid_change_core(grid, d->screens[i]); lv_obj_t * item = cont->spec_attr->children[i];
if(LV_COORD_IS_LAYOUT(item->x_set) && LV_COORD_IS_LAYOUT(item->y_set)) {
item_repos(item, &c, &hint);
} }
d = lv_disp_get_next(d);
} }
calc_free(&c);
if(cont->w_set == LV_SIZE_AUTO || cont->h_set == LV_SIZE_AUTO) {
lv_obj_set_size(cont, cont->w_set, cont->h_set);
}
}
/**
* Refresh the position of a grid item
* @param item pointer to a grid item
*/
static void item_refr(lv_obj_t * item)
{
/*Calculate the grid*/
lv_obj_t * cont = lv_obj_get_parent(item);
if(cont == NULL) return;
_lv_grid_calc_t c;
calc(cont, &c);
item_repos(item, &c, NULL);
calc_free(&c);
} }
/** /**
@@ -129,10 +158,9 @@ void lv_obj_report_grid_change(const lv_grid_t * grid)
* @param calc store the calculated cells sizes here * @param calc store the calculated cells sizes here
* @note `_lv_grid_calc_free(calc_out)` needs to be called when `calc_out` is not needed anymore * @note `_lv_grid_calc_free(calc_out)` needs to be called when `calc_out` is not needed anymore
*/ */
void _lv_grid_calc(struct _lv_obj_t * cont, _lv_grid_calc_t * calc_out) static void calc(struct _lv_obj_t * cont, _lv_grid_calc_t * calc_out)
{ {
const lv_grid_t * g = lv_obj_get_grid(cont); const lv_grid_t * g = cont->spec_attr->layout_dsc;
if(g == NULL) return;
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;
@@ -160,7 +188,7 @@ void _lv_grid_calc(struct _lv_obj_t * cont, _lv_grid_calc_t * calc_out)
* Free the a grid calculation's data * Free the a grid calculation's data
* @param calc pointer to the calculated gtrid cell coordinates * @param calc pointer to the calculated gtrid cell coordinates
*/ */
void _lv_grid_calc_free(_lv_grid_calc_t * calc) static void calc_free(_lv_grid_calc_t * calc)
{ {
_lv_mem_buf_release(calc->x); _lv_mem_buf_release(calc->x);
_lv_mem_buf_release(calc->y); _lv_mem_buf_release(calc->y);
@@ -168,149 +196,53 @@ void _lv_grid_calc_free(_lv_grid_calc_t * calc)
_lv_mem_buf_release(calc->h); _lv_mem_buf_release(calc->h);
} }
/** static void calc_cols(lv_obj_t * cont, _lv_grid_calc_t * c)
* Check if the object's grid columns has FR cells or not
* @param obj pointer to an object
* @return true: has FR; false: has no FR
*/
bool _lv_grid_has_fr_col(struct _lv_obj_t * obj)
{ {
const lv_grid_t * g = lv_obj_get_grid(obj); const lv_grid_t * grid = cont->spec_attr->layout_dsc;
if(g->col_dsc == NULL) return false;
uint32_t i;
for(i = 0; i < g->col_dsc_len; i++) {
if(LV_GRID_IS_FR(g->col_dsc[i])) return true;
}
return false;
}
/**
* Check if the object's grid rows has FR cells or not
* @param obj pointer to an object
* @return true: has FR; false: has no FR
*/
bool _lv_grid_has_fr_row(struct _lv_obj_t * obj)
{
const lv_grid_t * g = lv_obj_get_grid(obj);
if(g == NULL) return false;
if(g->row_dsc == NULL) return false;
uint32_t i;
for(i = 0; i < g->row_dsc_len; i++) {
if(LV_GRID_IS_FR(g->row_dsc[i])) return true;
}
return false;
}
/**
* Refresh the all grid item on a container
* @param cont pointer to a grid container object
*/
void _lv_grid_full_refresh(lv_obj_t * cont)
{
/*Calculate the grid*/
if(lv_obj_get_grid(cont) == NULL) return;
_lv_grid_calc_t calc;
_lv_grid_calc(cont, &calc);
item_repos_hint_t hint;
_lv_memset_00(&hint, sizeof(hint));
/* Calculate the grids absolute x and y coordinates.
* It will be used as helper during item repositioning to avoid calculating this value for every children*/
lv_coord_t pad_left = lv_obj_get_style_pad_left(cont, LV_PART_MAIN);
lv_coord_t pad_top = lv_obj_get_style_pad_top(cont, LV_PART_MAIN);
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);
uint32_t i;
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)) {
item_repos(item, &calc, &hint);
}
}
_lv_grid_calc_free(&calc);
if(cont->w_set == LV_SIZE_AUTO || cont->h_set == LV_SIZE_AUTO) {
lv_obj_set_size(cont, cont->w_set, cont->h_set);
}
}
/**
* Refresh the position of a grid item
* @param item pointer to a grid item
*/
void lv_grid_item_refr_pos(lv_obj_t * item)
{
/*Calculate the grid*/
lv_obj_t * cont = lv_obj_get_parent(item);
if(cont == NULL) return;
if(cont->spec_attr == NULL) return;
if(cont->spec_attr->grid == NULL) return;
_lv_grid_calc_t calc;
_lv_grid_calc(cont, &calc);
item_repos(item, &calc, NULL);
_lv_grid_calc_free(&calc);
}
/**********************
* STATIC FUNCTIONS
**********************/
static void calc_cols(lv_obj_t * cont, _lv_grid_calc_t * calc)
{
const lv_grid_t * grid = cont->spec_attr->grid;
uint32_t i; uint32_t i;
lv_coord_t cont_w = lv_obj_get_width_fit(cont); lv_coord_t cont_w = lv_obj_get_width_fit(cont);
calc->col_num = grid->col_dsc_len; c->col_num = grid->col_dsc_len;
calc->x = _lv_mem_buf_get(sizeof(lv_coord_t) * calc->col_num); c->x = _lv_mem_buf_get(sizeof(lv_coord_t) * c->col_num);
calc->w = _lv_mem_buf_get(sizeof(lv_coord_t) * calc->col_num); c->w = _lv_mem_buf_get(sizeof(lv_coord_t) * c->col_num);
uint32_t col_fr_cnt = 0; uint32_t col_fr_cnt = 0;
lv_coord_t grid_w = 0; lv_coord_t grid_w = 0;
bool auto_w = cont->w_set == LV_SIZE_AUTO ? true : false; bool auto_w = cont->w_set == LV_SIZE_AUTO ? true : false;
for(i = 0; i < calc->col_num; i++) { for(i = 0; i < c->col_num; i++) {
lv_coord_t x = grid->col_dsc[i]; lv_coord_t x = grid->col_dsc[i];
if(LV_GRID_IS_FR(x)) col_fr_cnt += LV_GRID_GET_FR(x); if(LV_GRID_IS_FR(x)) col_fr_cnt += LV_GRID_GET_FR(x);
else { else {
calc->w[i] = x; c->w[i] = x;
grid_w += x; grid_w += x;
} }
} }
cont_w -= grid->col_gap * (calc->col_num - 1); cont_w -= grid->col_gap * (c->col_num - 1);
lv_coord_t free_w = cont_w - grid_w; lv_coord_t free_w = cont_w - grid_w;
for(i = 0; i < calc->col_num; i++) { for(i = 0; i < c->col_num; i++) {
lv_coord_t x = grid->col_dsc[i]; lv_coord_t x = grid->col_dsc[i];
if(LV_GRID_IS_FR(x)) { if(LV_GRID_IS_FR(x)) {
if(auto_w) calc->w[i] = 0; /*Fr is considered zero if the cont has auto width*/ if(auto_w) c->w[i] = 0; /*Fr is considered zero if the cont has auto width*/
else { else {
lv_coord_t f = LV_GRID_GET_FR(x); lv_coord_t f = LV_GRID_GET_FR(x);
calc->w[i] = (free_w * f) / col_fr_cnt; c->w[i] = (free_w * f) / col_fr_cnt;
} }
} }
} }
} }
static void calc_rows(lv_obj_t * cont, _lv_grid_calc_t * calc) static void calc_rows(lv_obj_t * cont, _lv_grid_calc_t * c)
{ {
const lv_grid_t * grid = cont->spec_attr->grid; const lv_grid_t * grid = cont->spec_attr->layout_dsc;
uint32_t i; uint32_t i;
calc->row_num = grid->row_dsc_len; c->row_num = grid->row_dsc_len;
calc->y = _lv_mem_buf_get(sizeof(lv_coord_t) * calc->row_num); c->y = _lv_mem_buf_get(sizeof(lv_coord_t) * c->row_num);
calc->h = _lv_mem_buf_get(sizeof(lv_coord_t) * calc->row_num); c->h = _lv_mem_buf_get(sizeof(lv_coord_t) * c->row_num);
uint32_t row_fr_cnt = 0; uint32_t row_fr_cnt = 0;
lv_coord_t grid_h = 0; lv_coord_t grid_h = 0;
@@ -322,7 +254,7 @@ static void calc_rows(lv_obj_t * cont, _lv_grid_calc_t * calc)
lv_coord_t x = grid->row_dsc[i]; lv_coord_t x = grid->row_dsc[i];
if(LV_GRID_IS_FR(x)) row_fr_cnt += LV_GRID_GET_FR(x); if(LV_GRID_IS_FR(x)) row_fr_cnt += LV_GRID_GET_FR(x);
else { else {
calc->h[i] = x; c->h[i] = x;
grid_h += x; grid_h += x;
} }
} }
@@ -333,10 +265,10 @@ static void calc_rows(lv_obj_t * cont, _lv_grid_calc_t * calc)
for(i = 0; i < grid->row_dsc_len; i++) { for(i = 0; i < grid->row_dsc_len; i++) {
lv_coord_t x = grid->row_dsc[i]; lv_coord_t x = grid->row_dsc[i];
if(LV_GRID_IS_FR(x)) { if(LV_GRID_IS_FR(x)) {
if(auto_h) calc->h[i] = 0; /*Fr is considered zero if the obj has auto height*/ if(auto_h) c->h[i] = 0; /*Fr is considered zero if the obj has auto height*/
else { else {
lv_coord_t f = LV_GRID_GET_FR(x); lv_coord_t f = LV_GRID_GET_FR(x);
calc->h[i] = (free_h * f) / row_fr_cnt; c->h[i] = (free_h * f) / row_fr_cnt;
} }
} }
} }
@@ -349,21 +281,21 @@ static void calc_rows(lv_obj_t * cont, _lv_grid_calc_t * calc)
* @param child_id_ext helper value if the ID of the child is know (order from the oldest) else -1 * @param child_id_ext helper value if the ID of the child is know (order from the oldest) else -1
* @param grid_abs helper value, the absolute position of the grid, NULL if unknown * @param grid_abs helper value, the absolute position of the grid, NULL if unknown
*/ */
static void item_repos(lv_obj_t * item, _lv_grid_calc_t * calc, item_repos_hint_t * hint) static void item_repos(lv_obj_t * item, _lv_grid_calc_t * c, item_repos_hint_t * hint)
{ {
if(_lv_obj_is_grid_item(item) == false) return; if(LV_COORD_IS_LAYOUT(item->x_set) && LV_COORD_IS_LAYOUT(item->y_set)) return;
uint32_t col_pos = LV_GRID_GET_CELL_POS(item->x_set); uint32_t col_pos = LV_GRID_GET_CELL_POS(item->x_set);
uint32_t col_span = LV_GRID_GET_CELL_SPAN(item->x_set); uint32_t col_span = LV_GRID_GET_CELL_SPAN(item->x_set);
uint32_t row_pos = LV_GRID_GET_CELL_POS(item->y_set); uint32_t row_pos = LV_GRID_GET_CELL_POS(item->y_set);
uint32_t row_span = LV_GRID_GET_CELL_SPAN(item->y_set); uint32_t row_span = LV_GRID_GET_CELL_SPAN(item->y_set);
lv_coord_t col_x1 = calc->x[col_pos]; lv_coord_t col_x1 = c->x[col_pos];
lv_coord_t col_x2 = calc->x[col_pos + col_span - 1] + calc->w[col_pos + col_span - 1]; lv_coord_t col_x2 = c->x[col_pos + col_span - 1] + c->w[col_pos + col_span - 1];
lv_coord_t col_w = col_x2 - col_x1; lv_coord_t col_w = col_x2 - col_x1;
lv_coord_t row_y1 = calc->y[row_pos]; lv_coord_t row_y1 = c->y[row_pos];
lv_coord_t row_y2 = calc->y[row_pos + row_span - 1] + calc->h[row_pos + row_span - 1]; lv_coord_t row_y2 = c->y[row_pos + row_span - 1] + c->h[row_pos + row_span - 1];
lv_coord_t row_h = row_y2 - row_y1; lv_coord_t row_h = row_y2 - row_y1;
uint8_t x_flag = LV_GRID_GET_CELL_PLACE(item->x_set); uint8_t x_flag = LV_GRID_GET_CELL_PLACE(item->x_set);
@@ -377,47 +309,50 @@ static void item_repos(lv_obj_t * item, _lv_grid_calc_t * calc, item_repos_hint_
lv_coord_t x; lv_coord_t x;
lv_coord_t y; lv_coord_t y;
lv_coord_t item_w = lv_obj_get_width(item); lv_coord_t item_w = lv_area_get_width(&item->coords);
lv_coord_t item_h = lv_obj_get_height(item); lv_coord_t item_h = lv_area_get_height(&item->coords);
lv_coord_t margin_top = lv_obj_get_style_margin_top(item, LV_PART_MAIN); lv_coord_t margin_top = lv_obj_get_style_margin_top(item, LV_PART_MAIN);
lv_coord_t margin_bottom = lv_obj_get_style_margin_bottom(item, LV_PART_MAIN); lv_coord_t margin_bottom = lv_obj_get_style_margin_bottom(item, LV_PART_MAIN);
lv_coord_t margin_left = lv_obj_get_style_margin_left(item, LV_PART_MAIN); lv_coord_t margin_left = lv_obj_get_style_margin_left(item, LV_PART_MAIN);
lv_coord_t margin_right = lv_obj_get_style_margin_right(item, LV_PART_MAIN); lv_coord_t margin_right = lv_obj_get_style_margin_right(item, LV_PART_MAIN);
if(item->w_set == LV_SIZE_LAYOUT) item->w_set = item_w;
if(item->h_set == LV_SIZE_LAYOUT) item->h_set = item_h;
switch(x_flag) { switch(x_flag) {
default: default:
case LV_GRID_START: case LV_GRID_START:
x = calc->x[col_pos] + margin_left; x = c->x[col_pos] + margin_left;
break; break;
case LV_GRID_STRETCH: case LV_GRID_STRETCH:
x = calc->x[col_pos] + margin_left; x = c->x[col_pos] + margin_left;
item_w = col_w - margin_left - margin_right; item_w = col_w - margin_left - margin_right;
item->w_set = LV_SIZE_STRETCH; item->w_set = LV_SIZE_LAYOUT;
break; break;
case LV_GRID_CENTER: case LV_GRID_CENTER:
x = calc->x[col_pos] + (col_w - (item_w + margin_left - margin_right)) / 2; x = c->x[col_pos] + (col_w - (item_w + margin_left - margin_right)) / 2;
break; break;
case LV_GRID_END: case LV_GRID_END:
x = calc->x[col_pos] + col_w - lv_obj_get_width(item) - margin_right; x = c->x[col_pos] + col_w - lv_obj_get_width(item) - margin_right;
break; break;
} }
switch(y_flag) { switch(y_flag) {
default: default:
case LV_GRID_START: case LV_GRID_START:
y = calc->y[row_pos] + margin_top; y = c->y[row_pos] + margin_top;
break; break;
case LV_GRID_STRETCH: case LV_GRID_STRETCH:
y = calc->y[row_pos] + margin_top; y = c->y[row_pos] + margin_top;
item_h = row_h - margin_top - margin_bottom; item_h = row_h - margin_top - margin_bottom;
item->h_set = LV_SIZE_STRETCH; item->h_set = LV_SIZE_LAYOUT;
break; break;
case LV_GRID_CENTER: case LV_GRID_CENTER:
y = calc->y[row_pos] + (row_h - (item_h + margin_top + margin_bottom)) / 2; y = c->y[row_pos] + (row_h - (item_h + margin_top + margin_bottom)) / 2;
break; break;
case LV_GRID_END: case LV_GRID_END:
y = calc->y[row_pos] + row_h - lv_obj_get_height(item) - margin_bottom; y = c->y[row_pos] + row_h - lv_obj_get_height(item) - margin_bottom;
break; break;
} }
@@ -516,22 +451,3 @@ static lv_coord_t grid_place(lv_coord_t cont_size, bool auto_size, uint8_t plac
/*Return the full size of the grid*/ /*Return the full size of the grid*/
return total_gird_size; return total_gird_size;
} }
/**
* Refresh the grid of all children of an object. (Called recursively)
* @param grid refresh objects only with this grid.
* @param obj pointer to an object
*/
static void report_grid_change_core(const lv_grid_t * grid, lv_obj_t * obj)
{
if(obj->spec_attr) {
if(obj->spec_attr->grid == grid || (obj->spec_attr->grid && grid == NULL)) _lv_grid_full_refresh(obj);
}
uint32_t i;
for(i = 0; i < obj->spec_attr->child_cnt; i++) {
report_grid_change_core(grid, obj->spec_attr->children[i]);
}
}
+5 -21
View File
@@ -13,7 +13,7 @@ extern "C" {
/********************* /*********************
* INCLUDES * INCLUDES
*********************/ *********************/
#include "../lv_misc/lv_area.h" #include "lv_obj_pos.h"
/********************* /*********************
* DEFINES * DEFINES
@@ -45,9 +45,9 @@ extern "C" {
#define LV_GRID_GET_CELL_SPAN(c) (((c) & _LV_GRID_CELL_SPAN_MASK) >> _LV_GRID_CELL_SHIFT) #define LV_GRID_GET_CELL_SPAN(c) (((c) & _LV_GRID_CELL_SPAN_MASK) >> _LV_GRID_CELL_SHIFT)
#define LV_GRID_GET_CELL_PLACE(c) ((c) >> (_LV_GRID_CELL_SHIFT * 2) & 0x7) #define LV_GRID_GET_CELL_PLACE(c) ((c) >> (_LV_GRID_CELL_SHIFT * 2) & 0x7)
#define LV_GRID_FR(x) (_LV_COORD_GRID(x)) #define LV_GRID_FR(x) (LV_COORD_SET_LAYOUT(x))
#define LV_GRID_IS_FR(x) (LV_COORD_IS_GRID(x)) #define LV_GRID_IS_FR(x) (LV_COORD_IS_LAYOUT(x))
#define LV_GRID_GET_FR(x) (LV_COORD_GET_GRID(x)) #define LV_GRID_GET_FR(x) (_LV_COORD_PLAIN(x))
/********************** /**********************
* TYPEDEFS * TYPEDEFS
@@ -57,6 +57,7 @@ extern "C" {
struct _lv_obj_t; struct _lv_obj_t;
typedef struct { typedef struct {
lv_layout_update_cb_t update_cb; /*The first element must be the update callback*/
const lv_coord_t * col_dsc; const lv_coord_t * col_dsc;
const lv_coord_t * row_dsc; const lv_coord_t * row_dsc;
uint8_t col_dsc_len; uint8_t col_dsc_len;
@@ -90,20 +91,6 @@ void lv_grid_set_place(lv_grid_t * grid, uint8_t col_place, uint8_t row_place);
void lv_grid_set_gap(lv_grid_t * grid, lv_coord_t col_gap, uint8_t row_gap); void lv_grid_set_gap(lv_grid_t * grid, lv_coord_t col_gap, uint8_t row_gap);
/**
* Set a grid for an object
* @param obj pointer to an object
* @param grid the grid to set
*/
void lv_obj_set_grid(struct _lv_obj_t * obj, const lv_grid_t * grid);
/**
* Get the grid of an object
* @param obj pointer to an object
* @return the grid, NULL if no grid
*/
const lv_grid_t * lv_obj_get_grid(struct _lv_obj_t * obj);
void lv_obj_set_grid_cell(struct _lv_obj_t * obj, lv_coord_t col_pos, lv_coord_t row_pos); void lv_obj_set_grid_cell(struct _lv_obj_t * obj, lv_coord_t col_pos, lv_coord_t row_pos);
/** /**
@@ -113,9 +100,6 @@ void lv_obj_set_grid_cell(struct _lv_obj_t * obj, lv_coord_t col_pos, lv_coord_t
*/ */
void lv_obj_report_grid_change(const lv_grid_t * grid); void lv_obj_report_grid_change(const lv_grid_t * grid);
void _lv_grid_calc(struct _lv_obj_t * obj, _lv_grid_calc_t * calc);
void _lv_grid_calc_free(_lv_grid_calc_t * calc);
bool _lv_grid_has_fr_col(struct _lv_obj_t * obj); bool _lv_grid_has_fr_col(struct _lv_obj_t * obj);
+7 -12
View File
@@ -1474,7 +1474,7 @@ static void lv_obj_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t
obj->flags |= LV_OBJ_FLAG_SCROLLABLE; obj->flags |= LV_OBJ_FLAG_SCROLLABLE;
obj->flags |= LV_OBJ_FLAG_SCROLL_ELASTIC; obj->flags |= LV_OBJ_FLAG_SCROLL_ELASTIC;
obj->flags |= LV_OBJ_FLAG_SCROLL_MOMENTUM; obj->flags |= LV_OBJ_FLAG_SCROLL_MOMENTUM;
obj->flags |= LV_OBJ_FLAG_FOCUS_SCROLL; obj->flags |= LV_OBJ_FLAG_SCROLL_ON_FOCUS;
if(parent) obj->flags |= LV_OBJ_FLAG_GESTURE_BUBBLE; if(parent) obj->flags |= LV_OBJ_FLAG_GESTURE_BUBBLE;
obj->style_list.cache_state = LV_OBJ_STYLE_CACHE_STATE_INVALID; obj->style_list.cache_state = LV_OBJ_STYLE_CACHE_STATE_INVALID;
@@ -1747,7 +1747,7 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
else if(sign == LV_SIGNAL_FOCUS) { else if(sign == LV_SIGNAL_FOCUS) {
lv_obj_t * parent = lv_obj_get_parent(obj); lv_obj_t * parent = lv_obj_get_parent(obj);
lv_obj_t * child = obj; lv_obj_t * child = obj;
while(parent && lv_obj_has_flag(child, LV_OBJ_FLAG_FOCUS_SCROLL)) { while(parent && lv_obj_has_flag(child, LV_OBJ_FLAG_SCROLL_ON_FOCUS)) {
lv_obj_scroll_to_view(child, LV_ANIM_ON); lv_obj_scroll_to_view(child, LV_ANIM_ON);
child = parent; child = parent;
parent = lv_obj_get_parent(parent); parent = lv_obj_get_parent(parent);
@@ -1805,14 +1805,11 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
lv_obj_set_size(child, child->w_set, child->h_set); lv_obj_set_size(child, child->w_set, child->h_set);
} }
} }
if(lv_obj_get_grid(obj)) _lv_grid_full_refresh(obj); lv_obj_update_layout(obj, NULL);
if(lv_obj_get_flex_dir(obj) != LV_FLEX_DIR_NONE) _lv_flex_refresh(obj);
} }
} }
else if(sign == LV_SIGNAL_CHILD_CHG) { else if(sign == LV_SIGNAL_CHILD_CHG) {
if(param == NULL || _lv_obj_is_flex_item(param)) { lv_obj_update_layout(obj, param);
_lv_flex_refresh(obj);
}
if(obj->w_set == LV_SIZE_AUTO || obj->h_set == LV_SIZE_AUTO) { if(obj->w_set == LV_SIZE_AUTO || obj->h_set == LV_SIZE_AUTO) {
lv_obj_set_size(obj, obj->w_set, obj->h_set); lv_obj_set_size(obj, obj->w_set, obj->h_set);
@@ -1835,11 +1832,9 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
*s = LV_MATH_MAX(*s, d); *s = LV_MATH_MAX(*s, d);
} }
else if(sign == LV_SIGNAL_STYLE_CHG) { else if(sign == LV_SIGNAL_STYLE_CHG) {
if(_lv_obj_is_grid_item(obj)) lv_grid_item_refr_pos(obj); /* Padding might have changed so the layout should be recalculated
if(lv_obj_get_grid(obj)) _lv_grid_full_refresh(obj); * If margin has also changed the parent's layout also needs to be updated but it's done in CHILD_CHG signal*/
lv_obj_update_layout(obj, NULL);
if(_lv_obj_is_flex_item(obj)) _lv_flex_refresh(lv_obj_get_parent(obj));
if(lv_obj_get_flex_dir(obj)) _lv_flex_refresh(obj);
/*Reposition non grid objects on by one*/ /*Reposition non grid objects on by one*/
uint32_t i; uint32_t i;
+2 -4
View File
@@ -181,7 +181,7 @@ enum {
LV_OBJ_FLAG_EVENT_BUBBLE = (1 << 11), LV_OBJ_FLAG_EVENT_BUBBLE = (1 << 11),
LV_OBJ_FLAG_GESTURE_BUBBLE = (1 << 12), LV_OBJ_FLAG_GESTURE_BUBBLE = (1 << 12),
LV_OBJ_FLAG_FOCUS_BUBBLE = (1 << 13), LV_OBJ_FLAG_FOCUS_BUBBLE = (1 << 13),
LV_OBJ_FLAG_FOCUS_SCROLL = (1 << 14), /** Automatically scroll the focused object's ancestors to make the focused object visible*/ LV_OBJ_FLAG_SCROLL_ON_FOCUS = (1 << 14), /** Automatically scroll the focused object's ancestors to make the focused object visible*/
LV_OBJ_FLAG_ADV_HITTEST = (1 << 15), LV_OBJ_FLAG_ADV_HITTEST = (1 << 15),
}; };
typedef uint16_t lv_obj_flag_t; typedef uint16_t lv_obj_flag_t;
@@ -192,7 +192,6 @@ typedef uint16_t lv_obj_flag_t;
#include "lv_obj_style.h" #include "lv_obj_style.h"
#include "lv_obj_draw.h" #include "lv_obj_draw.h"
typedef struct { typedef struct {
struct _lv_obj_t ** children; /**< Store the pointer of the children.*/ struct _lv_obj_t ** children; /**< Store the pointer of the children.*/
uint32_t child_cnt; uint32_t child_cnt;
@@ -200,11 +199,10 @@ typedef struct {
void * group_p; void * group_p;
#endif #endif
const lv_grid_t * grid; const void * layout_dsc;
lv_event_cb_t event_cb; /**< Event callback function */ lv_event_cb_t event_cb; /**< Event callback function */
lv_flex_cont_t flex_cont;
lv_point_t scroll; /**< The current X/Y scroll offset*/ lv_point_t scroll; /**< The current X/Y scroll offset*/
lv_coord_t ext_draw_pad; /**< EXTend the size in every direction for drawing. */ lv_coord_t ext_draw_pad; /**< EXTend the size in every direction for drawing. */
+48 -98
View File
@@ -16,6 +16,9 @@
/********************** /**********************
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
typedef struct {
lv_layout_update_cb_t update_cb;
}lv_layout_base_t;
/********************** /**********************
* STATIC PROTOTYPES * STATIC PROTOTYPES
@@ -34,6 +37,24 @@ static bool refr_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h);
* GLOBAL FUNCTIONS * GLOBAL FUNCTIONS
**********************/ **********************/
bool lv_obj_is_layout_positioned(const lv_obj_t * obj)
{
lv_obj_t * parent = lv_obj_get_parent(obj);
if(parent == NULL) return false;
if(parent->spec_attr && parent->spec_attr->layout_dsc) return true;
else return false;
}
void lv_obj_update_layout(lv_obj_t * cont, lv_obj_t * item)
{
if(cont->spec_attr == NULL) return;
if(cont->spec_attr->layout_dsc == NULL) return;
const lv_layout_base_t * layout = cont->spec_attr->layout_dsc;
if(layout->update_cb == NULL) return;
layout->update_cb(cont, item);
}
/** /**
* Set relative the position of an object (relative to the parent) * Set relative the position of an object (relative to the parent)
* @param obj pointer to an object * @param obj pointer to an object
@@ -50,37 +71,15 @@ void lv_obj_set_pos(lv_obj_t * obj, lv_coord_t x, lv_coord_t y)
{ {
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
if(lv_obj_is_layout_positioned(obj)) {
LV_LOG_WARN("Can't set position because the position is set by a layout");
return;
}
obj->x_set = x; obj->x_set = x;
obj->y_set = y; obj->y_set = y;
bool gi = _lv_obj_is_grid_item(obj);
bool fi = _lv_obj_is_flex_item(obj);
/*For consistency set the size to stretched if the objects is stretched on the grid*/
if(gi) {
if(LV_GRID_GET_CELL_PLACE(obj->x_set) == LV_GRID_STRETCH) obj->w_set = LV_SIZE_STRETCH;
if(LV_GRID_GET_CELL_PLACE(obj->y_set) == LV_GRID_STRETCH) obj->h_set = LV_SIZE_STRETCH;
}
/*If not grid or flex item but has grid or flex position set the position to 0*/
if(!gi) {
if(LV_COORD_IS_GRID(x)) x = 0;
if(LV_COORD_IS_GRID(y)) y = 0;
}
if(!fi) {
if(LV_COORD_IS_FLEX(x)) x = 0;
if(LV_COORD_IS_FLEX(y)) y = 0;
}
/*If the object is on a grid item let the grid to position it. */
if(gi) {
lv_grid_item_refr_pos(obj);
} else if(fi) {
_lv_flex_refresh(lv_obj_get_parent(obj));
} else {
_lv_obj_move_to(obj, x, y, true); _lv_obj_move_to(obj, x, y, true);
}
} }
/** /**
@@ -117,33 +116,12 @@ void lv_obj_set_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h)
{ {
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
bool gi = _lv_obj_is_grid_item(obj);
bool fi = _lv_obj_is_flex_item(obj);
bool x_stretch = false;
bool y_stretch = false;
/*Use `LV_SIZE_STRETCH` value if the layout changes the size of the object*/ if(obj->w_set == LV_SIZE_LAYOUT && obj->h_set == LV_SIZE_LAYOUT) return;
if(gi) {
if(LV_GRID_GET_CELL_PLACE(obj->x_set)) x_stretch = true;
if(LV_GRID_GET_CELL_PLACE(obj->y_set)) y_stretch = true;
}
if(fi) {
lv_obj_t * parent = lv_obj_get_parent(obj);
if(parent->spec_attr->flex_cont.dir == LV_FLEX_DIR_ROW && LV_COORD_GET_FLEX(obj->y_set) == LV_FLEX_PLACE_STRETCH) y_stretch = true;
if(parent->spec_attr->flex_cont.dir == LV_FLEX_DIR_COLUMN && LV_COORD_GET_FLEX(obj->x_set) == LV_FLEX_PLACE_STRETCH) x_stretch = true;
}
if(x_stretch) w = LV_SIZE_STRETCH;
if(y_stretch) h = LV_SIZE_STRETCH;
obj->w_set = w; if(obj->w_set == LV_SIZE_LAYOUT) w = lv_obj_get_width(obj);
obj->h_set = h; if(obj->h_set == LV_SIZE_LAYOUT) h = lv_obj_get_height(obj);
/*If both stretched the size is managed by the grid*/
if(x_stretch && y_stretch) return;
if(x_stretch) w = lv_obj_get_width(obj);
if(y_stretch) h = lv_obj_get_height(obj);
/*Calculate the required auto sizes*/ /*Calculate the required auto sizes*/
bool x_auto = obj->w_set == LV_SIZE_AUTO ? true : false; bool x_auto = obj->w_set == LV_SIZE_AUTO ? true : false;
@@ -163,10 +141,10 @@ void lv_obj_set_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h)
lv_obj_t * parent = lv_obj_get_parent(obj); lv_obj_t * parent = lv_obj_get_parent(obj);
if(parent) { if(parent) {
lv_coord_t cont_w = lv_obj_get_width_fit(parent); lv_coord_t parent_w = lv_obj_get_width_fit(parent);
lv_coord_t cont_h = lv_obj_get_height_fit(parent); lv_coord_t parent_h = lv_obj_get_height_fit(parent);
if(pct_w) w = (_LV_COORD_GET_PCT(obj->w_set) * cont_w) / 100; if(pct_w) w = (LV_COORD_GET_PCT(obj->w_set) * parent_w) / 100;
if(pct_h) h = (_LV_COORD_GET_PCT(obj->h_set) * cont_h) / 100; if(pct_h) h = (LV_COORD_GET_PCT(obj->h_set) * parent_h) / 100;
} }
refr_size(obj, w, h); refr_size(obj, w, h);
@@ -250,6 +228,21 @@ void lv_obj_set_height_margin(lv_obj_t * obj, lv_coord_t h)
lv_obj_set_height(obj, h - mtop - mbottom); lv_obj_set_height(obj, h - mtop - mbottom);
} }
/**
* Set a layout for an object
* @param obj pointer to an object
* @param layout pointer to a layout descriptor to set
*/
void lv_obj_set_layout(lv_obj_t * obj, const void * layout)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_obj_allocate_spec_attr(obj);
obj->spec_attr->layout_dsc = layout;
lv_obj_update_layout(obj, NULL);
}
/** /**
* Align an object to an other object. * Align an object to an other object.
* @param obj pointer to an object to align * @param obj pointer to an object to align
@@ -625,14 +618,6 @@ void _lv_obj_move_to(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, bool notify_par
x += pad_left + parent->coords.x1 - lv_obj_get_scroll_x(parent); x += pad_left + parent->coords.x1 - lv_obj_get_scroll_x(parent);
y += pad_top + parent->coords.y1 - lv_obj_get_scroll_y(parent); y += pad_top + parent->coords.y1 - lv_obj_get_scroll_y(parent);
} else {
/*If no parent then it's screen but screen can't be on a grid*/
if(LV_COORD_IS_GRID(obj->x_set) || LV_COORD_IS_GRID(obj->x_set)) {
obj->x_set = 0;
obj->y_set = 0;
x = 0;
y = 0;
}
} }
/*Calculate and set the movement*/ /*Calculate and set the movement*/
@@ -690,41 +675,6 @@ void _lv_obj_move_children_by(lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_di
} }
} }
/**
* Check if an object is valid grid item or not.
* @param obj pointer to an object to check
* @return true: grid item; false: not grid item
*/
bool _lv_obj_is_grid_item(lv_obj_t * obj)
{
lv_obj_t * cont = lv_obj_get_parent(obj);
if(cont == NULL) return false;
const lv_grid_t * g = lv_obj_get_grid(cont);
if(g == NULL) return false;
if(g->col_dsc == NULL) return false;
if(g->row_dsc == NULL) return false;
if(g->row_dsc_len == 0) return false;
if(g->col_dsc_len == 0) return false;
if(LV_COORD_IS_GRID(obj->x_set) == false || LV_COORD_IS_GRID(obj->y_set) == false) return false;
return true;
}
/**
* Check if an object is valid grid item or not.
* @param obj pointer to an object to check
* @return true: grid item; false: not grid item
*/
bool _lv_obj_is_flex_item(struct _lv_obj_t * obj)
{
lv_obj_t * cont = lv_obj_get_parent(obj);
if(cont == NULL) return false;
if(lv_obj_get_flex_dir(cont) == LV_FLEX_DIR_NONE) return false;
if(LV_COORD_IS_FLEX(obj->x_set) == false || LV_COORD_IS_FLEX(obj->y_set) == false) return false;
return true;
}
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
+9 -9
View File
@@ -24,10 +24,19 @@ extern "C" {
**********************/ **********************/
struct _lv_obj_t; struct _lv_obj_t;
typedef void (*lv_layout_update_cb_t)(struct _lv_obj_t * cont, struct _lv_obj_t * item);
typedef union {
uint32_t num;
const void * ptr;
}lv_layout_data_t;
/********************** /**********************
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
**********************/ **********************/
void lv_obj_update_layout(struct _lv_obj_t * cont, struct _lv_obj_t * item);
/** /**
* Set relative the position of an object (relative to the parent) * Set relative the position of an object (relative to the parent)
* @param obj pointer to an object * @param obj pointer to an object
@@ -245,15 +254,6 @@ void _lv_obj_move_to(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y, bool no
*/ */
void _lv_obj_move_children_by(struct _lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_diff); void _lv_obj_move_children_by(struct _lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_diff);
/**
* Check if an object is valid grid item or not.
* @param obj pointer to an object to check
* @return true: grid item; false: not grid item
*/
bool _lv_obj_is_grid_item(struct _lv_obj_t * obj);
bool _lv_obj_is_flex_item(struct _lv_obj_t * obj);
/********************** /**********************
* MACROS * MACROS
**********************/ **********************/
+34 -22
View File
@@ -47,7 +47,7 @@ typedef enum {
static void report_style_change_core(void * style, lv_obj_t * obj); 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);
#if LV_USE_ANIMATION #if LV_USE_ANIMATION
static void trans_del(lv_obj_t * obj, uint8_t part, lv_style_prop_t prop, lv_style_trans_t * tr_limit); static bool trans_del(lv_obj_t * obj, uint8_t part, lv_style_prop_t prop, lv_style_trans_t * tr_limit);
static void trans_anim_cb(lv_style_trans_t * tr, lv_anim_value_t v); static void trans_anim_cb(lv_style_trans_t * tr, lv_anim_value_t v);
static void trans_anim_start_cb(lv_anim_t * a); static void trans_anim_start_cb(lv_anim_t * a);
static void trans_anim_ready_cb(lv_anim_t * a); static void trans_anim_ready_cb(lv_anim_t * a);
@@ -78,14 +78,7 @@ void _lv_obj_style_init(void)
_lv_ll_init(&LV_GC_ROOT(_lv_obj_style_trans_ll), sizeof(lv_style_trans_t)); _lv_ll_init(&LV_GC_ROOT(_lv_obj_style_trans_ll), sizeof(lv_style_trans_t));
} }
/** void lv_obj_add_style_no_refresh(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_t * style)
* Add a new style to the style list of an object.
* @param obj pointer to an object
* @param part the part of the object which style property should be set.
* E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_MAIN`, `LV_SLIDER_PART_KNOB`
* @param style pointer to a style to add (Only its pointer will be saved)
*/
void lv_obj_add_style(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_t * style)
{ {
if(style == NULL) return; if(style == NULL) return;
@@ -117,6 +110,18 @@ void lv_obj_add_style(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_
obj->style_list.styles[i].part = part; obj->style_list.styles[i].part = part;
obj->style_list.styles[i].state = state; obj->style_list.styles[i].state = state;
}
/**
* Add a new style to the style list of an object.
* @param obj pointer to an object
* @param part the part of the object which style property should be set.
* E.g. `LV_OBJ_PART_MAIN`, `LV_BTN_PART_MAIN`, `LV_SLIDER_PART_KNOB`
* @param style pointer to a style to add (Only its pointer will be saved)
*/
void lv_obj_add_style(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_t * style)
{
lv_obj_add_style_no_refresh(obj, part, state, style);
_lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL); _lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL);
} }
@@ -160,6 +165,17 @@ void lv_obj_remove_style(lv_obj_t * obj, uint32_t part, uint32_t state, lv_style
_lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL); _lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL);
} }
void lv_obj_remove_all_styles_no_refresh(lv_obj_t * obj)
{
#if LV_USE_ANIMATION
trans_del(obj, 0xFF, 0xFF, NULL);
#endif
lv_mem_free(obj->style_list.styles);
obj->style_list.styles = NULL;
obj->style_list.style_cnt = 0;
}
/** /**
* Reset a style to the default (empty) state. * Reset a style to the default (empty) state.
* Release all used memories and cancel pending related transitions. * Release all used memories and cancel pending related transitions.
@@ -170,14 +186,7 @@ void lv_obj_remove_style(lv_obj_t * obj, uint32_t part, uint32_t state, lv_style
*/ */
void lv_obj_remove_all_styles(lv_obj_t * obj) void lv_obj_remove_all_styles(lv_obj_t * obj)
{ {
#if LV_USE_ANIMATION lv_obj_remove_all_styles_no_refresh(obj);
trans_del(obj, 0xFF, 0xFF, NULL);
#endif
lv_mem_free(obj->style_list.styles);
obj->style_list.styles = NULL;
obj->style_list.style_cnt = 0;
_lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL); _lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL);
} }
@@ -800,8 +809,8 @@ static void update_cache(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop)
else list->cache_img_recolor_opa_zero = 0; else list->cache_img_recolor_opa_zero = 0;
} }
if(prop == LV_STYLE_PROP_ALL || prop == LV_STYLE_CONTENT_SRC) { if(prop == LV_STYLE_PROP_ALL || prop == LV_STYLE_CONTENT_SRC) {
if(get_prop_core(obj, part, LV_STYLE_CONTENT_SRC, &v) == false) v.num = 0; if(get_prop_core(obj, part, LV_STYLE_CONTENT_SRC, &v) == false) v.ptr = NULL;
if(v.num == 0) list->cache_content_src_zero = 1; if(v.ptr == NULL) list->cache_content_src_zero = 1;
else list->cache_content_src_zero = 0; else list->cache_content_src_zero = 0;
} }
if(prop == LV_STYLE_PROP_ALL || prop == LV_STYLE_COLOR_FILTER_CB || prop == LV_STYLE_COLOR_FILTER_OPA) { if(prop == LV_STYLE_PROP_ALL || prop == LV_STYLE_COLOR_FILTER_CB || prop == LV_STYLE_COLOR_FILTER_OPA) {
@@ -847,7 +856,7 @@ static void update_cache(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop)
static cache_t read_cache(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop) static cache_t read_cache(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop)
{ {
lv_obj_style_list_t * list = &obj->style_list; const lv_obj_style_list_t * list = &obj->style_list;
if(part != LV_PART_MAIN) return CACHE_NEED_CHECK; if(part != LV_PART_MAIN) return CACHE_NEED_CHECK;
if(obj->state != list->cache_state) return CACHE_NEED_CHECK; if(obj->state != list->cache_state) return CACHE_NEED_CHECK;
if(obj->style_list.skip_trans) return CACHE_NEED_CHECK; if(obj->style_list.skip_trans) return CACHE_NEED_CHECK;
@@ -941,7 +950,7 @@ static cache_t read_cache(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t
else return CACHE_NEED_CHECK; else return CACHE_NEED_CHECK;
break; break;
case LV_STYLE_CONTENT_SRC: case LV_STYLE_CONTENT_SRC:
if(list->cache_shadow_width_zero ) return CACHE_ZERO; if(list->cache_content_src_zero ) return CACHE_ZERO;
else return CACHE_NEED_CHECK; else return CACHE_NEED_CHECK;
break; break;
case LV_STYLE_COLOR_FILTER_CB: case LV_STYLE_COLOR_FILTER_CB:
@@ -1028,10 +1037,11 @@ static void refresh_children_style(lv_obj_t * obj)
* @param prop a property or 0xFF to remove all properties * @param prop a property or 0xFF to remove all properties
* @param tr_limit delete transitions only "older" then this. `NULL` is not used * @param tr_limit delete transitions only "older" then this. `NULL` is not used
*/ */
static void trans_del(lv_obj_t * obj, uint8_t part, lv_style_prop_t prop, lv_style_trans_t * tr_limit) static bool trans_del(lv_obj_t * obj, uint8_t part, lv_style_prop_t prop, lv_style_trans_t * tr_limit)
{ {
lv_style_trans_t * tr; lv_style_trans_t * tr;
lv_style_trans_t * tr_prev; lv_style_trans_t * tr_prev;
bool removed = false;
tr = _lv_ll_get_tail(&LV_GC_ROOT(_lv_obj_style_trans_ll)); tr = _lv_ll_get_tail(&LV_GC_ROOT(_lv_obj_style_trans_ll));
while(tr != NULL) { while(tr != NULL) {
if(tr == tr_limit) break; if(tr == tr_limit) break;
@@ -1049,12 +1059,14 @@ static void trans_del(lv_obj_t * obj, uint8_t part, lv_style_prop_t prop, lv_sty
lv_anim_del(tr, NULL); lv_anim_del(tr, NULL);
_lv_ll_remove(&LV_GC_ROOT(_lv_obj_style_trans_ll), tr); _lv_ll_remove(&LV_GC_ROOT(_lv_obj_style_trans_ll), tr);
lv_mem_free(tr); lv_mem_free(tr);
removed = true;
} }
} }
} }
tr = tr_prev; tr = tr_prev;
} }
return removed;
} }
static void trans_anim_cb(lv_style_trans_t * tr, lv_anim_value_t v) static void trans_anim_cb(lv_style_trans_t * tr, lv_anim_value_t v)
+13 -18
View File
@@ -224,31 +224,26 @@ void _lv_area_align(const lv_area_t * base, const lv_area_t * to_align, lv_align
#define _LV_COORD_TYPE_SHIFT (13) #define _LV_COORD_TYPE_SHIFT (13)
#define _LV_COORD_TYPE_MASK (3 << _LV_COORD_TYPE_SHIFT) #define _LV_COORD_TYPE_MASK (3 << _LV_COORD_TYPE_SHIFT)
#define _LV_COORD_PLAIN(x) ((x) & (~_LV_COORD_TYPE_MASK)) /*Remove type specifiers*/
#define _LV_COORD_TYPE_PX (0 << _LV_COORD_TYPE_SHIFT) #define _LV_COORD_TYPE_PX (0 << _LV_COORD_TYPE_SHIFT)
#define _LV_COORD_TYPE_GRID (1 << _LV_COORD_TYPE_SHIFT) #define _LV_COORD_TYPE_SPEC (1 << _LV_COORD_TYPE_SHIFT)
#define _LV_COORD_TYPE_FLEX (2 << _LV_COORD_TYPE_SHIFT) #define _LV_COORD_TYPE_LAYOUT (2 << _LV_COORD_TYPE_SHIFT)
#define _LV_COORD_TYPE_SPEC (3 << _LV_COORD_TYPE_SHIFT) #define _LV_COORD_TYPE_RESERVED (3 << _LV_COORD_TYPE_SHIFT)
#define LV_COORD_IS_PX(x) ((((x) & _LV_COORD_TYPE_MASK) == _LV_COORD_TYPE_PX) ? true : false) #define LV_COORD_IS_PX(x) ((((x) & _LV_COORD_TYPE_MASK) == _LV_COORD_TYPE_PX) ? true : false)
#define LV_COORD_IS_GRID(x) ((((x) & _LV_COORD_TYPE_MASK) == _LV_COORD_TYPE_GRID) ? true : false)
#define LV_COORD_IS_FLEX(x) ((((x) & _LV_COORD_TYPE_MASK) == _LV_COORD_TYPE_FLEX) ? true : false)
#define LV_COORD_IS_SPEC(x) ((((x) & _LV_COORD_TYPE_MASK) == _LV_COORD_TYPE_SPEC) ? true : false) #define LV_COORD_IS_SPEC(x) ((((x) & _LV_COORD_TYPE_MASK) == _LV_COORD_TYPE_SPEC) ? true : false)
#define LV_COORD_IS_LAYOUT(x) ((((x) & _LV_COORD_TYPE_MASK) == _LV_COORD_TYPE_LAYOUT) ? true : false)
#define LV_COORD_GET_PX(x) ((x) & ~(_LV_COORD_TYPE_MASK)) #define LV_COORD_SET_SPEC(x) ((x) | _LV_COORD_TYPE_SPEC)
#define LV_COORD_GET_GRID(x) ((x) & ~(_LV_COORD_TYPE_MASK)) #define LV_COORD_SET_LAYOUT(x) ((x) | _LV_COORD_TYPE_LAYOUT)
#define LV_COORD_GET_FLEX(x) ((x) & ~(_LV_COORD_TYPE_MASK))
#define LV_COORD_GET_SPEC(x) ((x) & ~(_LV_COORD_TYPE_MASK))
#define _LV_COORD_GRID(x) (_LV_COORD_TYPE_GRID | (x))
#define _LV_COORD_FELX(x) (_LV_COORD_TYPE_FLEX | (x))
#define _LV_COORD_SPEC(x) (_LV_COORD_TYPE_SPEC | (x))
/*Special coordinates*/ /*Special coordinates*/
#define LV_COORD_PCT(x) _LV_COORD_SPEC((x)) #define LV_COORD_PCT(x) _LV_COORD_SPEC(x)
#define LV_COORD_IS_PCT(x) ((LV_COORD_IS_SPEC(x) && LV_COORD_GET_SPEC(x) <= 1000) ? true : false) #define LV_COORD_IS_PCT(x) ((LV_COORD_IS_SPEC(x) && _LV_COORD_PLAIN(x) <= 1000) ? true : false)
#define _LV_COORD_GET_PCT(x) LV_COORD_GET_SPEC(x) #define LV_COORD_GET_PCT(x) _LV_COORD_PLAIN(x)
#define LV_SIZE_AUTO _LV_COORD_SPEC(1001) #define LV_SIZE_AUTO LV_COORD_SET_SPEC(1001)
#define LV_SIZE_STRETCH _LV_COORD_SPEC(1002) #define LV_SIZE_LAYOUT LV_COORD_SET_SPEC(1002) /*The size is managed by the layout therefore `lv_obj_set_width/height/size()` can't change is*/
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
+1 -1
View File
@@ -5,7 +5,7 @@
* It's important because the virtual functions should be called from the level of the constructor. * It's important because the virtual functions should be called from the level of the constructor.
*/ */
#define LV_CLASS_CONSTRUCTOR_BEGIN(inst, classname) \ #define LV_CLASS_CONSTRUCTOR_BEGIN(inst, classname) \
void * _original_class_p = inst->class_p; \ const void * _original_class_p = inst->class_p; \
obj->class_p = (void*)&classname; obj->class_p = (void*)&classname;
/** /**
+3 -1
View File
@@ -60,10 +60,12 @@ lv_theme_t * lv_theme_get_act(void)
*/ */
void lv_theme_apply(lv_obj_t * obj) void lv_theme_apply(lv_obj_t * obj)
{ {
lv_obj_remove_all_styles(obj); lv_obj_remove_all_styles_no_refresh(obj);
/*Apply the theme including the base theme(s)*/ /*Apply the theme including the base theme(s)*/
apply_theme(act_theme, obj); apply_theme(act_theme, obj);
_lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL);
} }
/** /**
+57 -57
View File
@@ -595,106 +595,106 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
LV_UNUSED(th); LV_UNUSED(th);
if(lv_obj_get_parent(obj) == NULL) { if(lv_obj_get_parent(obj) == NULL) {
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->scr); lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->scr);
lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar); lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar);
lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled); lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled);
return; return;
} }
if(lv_obj_check_type(obj, &lv_obj)) { if(lv_obj_check_type(obj, &lv_obj)) {
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card); lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar); lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar);
lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled); lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled);
} }
#if LV_USE_BTN #if LV_USE_BTN
else if(lv_obj_check_type(obj, &lv_btn)) { else if(lv_obj_check_type(obj, &lv_btn)) {
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->btn); lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->btn);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->btn_color); lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->btn_color);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->transition_delayed); lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->transition_delayed);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->pressed); lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->pressed);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->transition_normal); lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->transition_normal);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->grow); lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->grow);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_CHECKED, &styles->btn_color_checked); lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_CHECKED, &styles->btn_color_checked);
} }
#endif #endif
#if LV_USE_BAR #if LV_USE_BAR
else if(lv_obj_check_type(obj, &lv_bar)) { else if(lv_obj_check_type(obj, &lv_bar)) {
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_gray); lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_gray);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->circle); lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->bg_color_primary); lv_obj_add_style_no_refresh(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->bg_color_primary);
lv_obj_add_style(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->circle); lv_obj_add_style_no_refresh(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->circle);
} }
#endif #endif
#if LV_USE_SLIDER #if LV_USE_SLIDER
else if(lv_obj_check_type(obj, &lv_slider)) { else if(lv_obj_check_type(obj, &lv_slider)) {
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_gray); lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_gray);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->circle); lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->transition_delayed); lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->transition_delayed);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->transition_normal); lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->transition_normal);
lv_obj_add_style(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->bg_color_primary); lv_obj_add_style_no_refresh(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->bg_color_primary);
lv_obj_add_style(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->circle); lv_obj_add_style_no_refresh(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->knob); lv_obj_add_style_no_refresh(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->knob);
lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_PRESSED, &styles->grow); lv_obj_add_style_no_refresh(obj, LV_PART_KNOB, LV_STATE_PRESSED, &styles->grow);
lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->transition_delayed); lv_obj_add_style_no_refresh(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->transition_delayed);
lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_PRESSED, &styles->transition_normal); lv_obj_add_style_no_refresh(obj, LV_PART_KNOB, LV_STATE_PRESSED, &styles->transition_normal);
} }
#endif #endif
#if LV_USE_CHECKBOX #if LV_USE_CHECKBOX
else if(lv_obj_check_type(obj, &lv_checkbox)) { else if(lv_obj_check_type(obj, &lv_checkbox)) {
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->cb_marker); lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->cb_marker);
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_CHECKED, &styles->bg_color_primary); lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_CHECKED, &styles->bg_color_primary);
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_CHECKED, &styles->cb_marker_checked); lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_CHECKED, &styles->cb_marker_checked);
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_PRESSED, &styles->pressed); lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_PRESSED, &styles->pressed);
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_PRESSED, &styles->grow); lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_PRESSED, &styles->grow);
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_PRESSED, &styles->transition_normal); lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_PRESSED, &styles->transition_normal);
lv_obj_add_style(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->transition_delayed); lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->transition_delayed);
} }
#endif #endif
#if LV_USE_SWITCH #if LV_USE_SWITCH
else if(lv_obj_check_type(obj, &lv_switch)) { else if(lv_obj_check_type(obj, &lv_switch)) {
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_gray); lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_gray);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->circle); lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->bg_color_primary); lv_obj_add_style_no_refresh(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->bg_color_primary);
lv_obj_add_style(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->circle); lv_obj_add_style_no_refresh(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->circle);
lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->knob); lv_obj_add_style_no_refresh(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->knob);
lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->bg_color_white); lv_obj_add_style_no_refresh(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->bg_color_white);
lv_obj_add_style(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->pad_small_negative); lv_obj_add_style_no_refresh(obj, LV_PART_KNOB, LV_STATE_DEFAULT, &styles->pad_small_negative);
} }
#endif #endif
#if LV_USE_SWITCH #if LV_USE_SWITCH
else if(lv_obj_check_type(obj, &lv_chart)) { else if(lv_obj_check_type(obj, &lv_chart)) {
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card); lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->chart_bg); lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->chart_bg);
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->pad_zero); lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->pad_zero);
lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar); lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar);
lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled); lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled);
lv_obj_add_style(obj, LV_PART_SERIES, LV_STATE_DEFAULT, &styles->chart_series); lv_obj_add_style_no_refresh(obj, LV_PART_SERIES, LV_STATE_DEFAULT, &styles->chart_series);
} }
#endif #endif
#if LV_USE_ROLLER #if LV_USE_ROLLER
else if(lv_obj_check_type(obj, &lv_roller)) { else if(lv_obj_check_type(obj, &lv_roller)) {
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card); lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
// lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->pad_zero); // lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->pad_zero);
lv_obj_add_style(obj, LV_PART_HIGHLIGHT, LV_STATE_DEFAULT, &styles->bg_color_primary); lv_obj_add_style_no_refresh(obj, LV_PART_HIGHLIGHT, LV_STATE_DEFAULT, &styles->bg_color_primary);
// lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar); // lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar);
// lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled); // lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled);
// lv_obj_add_style(obj, LV_PART_SERIES, LV_STATE_DEFAULT, &styles->chart_series); // lv_obj_add_style_no_refresh(obj, LV_PART_SERIES, LV_STATE_DEFAULT, &styles->chart_series);
} }
#endif #endif
#if LV_USE_DROPDOWN #if LV_USE_DROPDOWN
else if(lv_obj_check_type(obj, &lv_dropdown)) { else if(lv_obj_check_type(obj, &lv_dropdown)) {
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card); lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
} }
else if(lv_obj_check_type(obj, &lv_dropdown_list)) { else if(lv_obj_check_type(obj, &lv_dropdown_list)) {
lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card); lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card);
lv_obj_add_style(obj, LV_PART_HIGHLIGHT, LV_STATE_DEFAULT, &styles->bg_color_primary); lv_obj_add_style_no_refresh(obj, LV_PART_HIGHLIGHT, LV_STATE_DEFAULT, &styles->bg_color_primary);
lv_obj_add_style(obj, LV_PART_HIGHLIGHT, LV_STATE_PRESSED, &styles->bg_color_gray); lv_obj_add_style_no_refresh(obj, LV_PART_HIGHLIGHT, LV_STATE_PRESSED, &styles->bg_color_gray);
} }
#endif #endif