mirror of
https://github.com/lvgl/lvgl.git
synced 2026-06-01 16:58:33 +08:00
update layouts
This commit is contained in:
+113
-189
@@ -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;
|
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)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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
@@ -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,38 +71,16 @@ 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);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the x coordinate of a object
|
* Set the x coordinate of a object
|
||||||
@@ -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
|
||||||
**********************/
|
**********************/
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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" */
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user