diff --git a/examples/scroll/lv_example_scroll.h b/examples/scroll/lv_example_scroll.h index 71fb86778..c4691a6ee 100644 --- a/examples/scroll/lv_example_scroll.h +++ b/examples/scroll/lv_example_scroll.h @@ -27,6 +27,7 @@ extern "C" { **********************/ void lv_example_scroll_1(void); void lv_example_scroll_2(void); +void lv_example_scroll_3(void); /********************** * MACROS diff --git a/examples/scroll/lv_example_scroll_3.c b/examples/scroll/lv_example_scroll_3.c new file mode 100644 index 000000000..cdc496255 --- /dev/null +++ b/examples/scroll/lv_example_scroll_3.c @@ -0,0 +1,43 @@ +#include "../../lvgl.h" +#if LV_BUILD_EXAMPLES && LV_USE_LIST + +static uint32_t btn_cnt = 1; + +static void float_btn_event_cb(lv_obj_t * float_btn, lv_event_t e) +{ + if(e == LV_EVENT_CLICKED) { + lv_obj_t * list = lv_event_get_user_data(); + char buf[32]; + lv_snprintf(buf, sizeof(buf), "Track %d", btn_cnt); + lv_obj_t * list_btn = lv_list_add_btn(list, LV_SYMBOL_AUDIO, buf, NULL); + btn_cnt++; + lv_obj_scroll_to_view(list_btn, LV_ANIM_ON); + lv_obj_move_background(float_btn); + } +} + +/** + * Show an example to scroll snap + */ +void lv_example_scroll_3(void) +{ + lv_obj_t * list = lv_list_create(lv_scr_act()); + lv_obj_set_size(list, 280, 220); + + for(btn_cnt = 1; btn_cnt <= 2; btn_cnt++) { + char buf[32]; + lv_snprintf(buf, sizeof(buf), "Track %d", btn_cnt); + lv_list_add_btn(list, LV_SYMBOL_AUDIO, buf, NULL); + } + + lv_obj_t * float_btn = lv_btn_create(list, NULL); + lv_obj_set_size(float_btn, 50, 50); + lv_obj_add_flag(float_btn, LV_OBJ_FLAG_FLOATING); + lv_obj_align(float_btn, NULL, LV_ALIGN_IN_BOTTOM_RIGHT, -10, -10); + lv_obj_add_event_cb(float_btn, float_btn_event_cb, list); + lv_obj_set_style_radius(float_btn, LV_PART_MAIN, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE); + lv_obj_set_style_content_text(float_btn, LV_PART_MAIN, LV_STATE_DEFAULT, LV_SYMBOL_PLUS); + lv_obj_set_style_content_font(float_btn, LV_PART_MAIN, LV_STATE_DEFAULT, lv_theme_get_font_large(float_btn)); +} + +#endif diff --git a/examples/widgets/list/lv_example_list_1.c b/examples/widgets/list/lv_example_list_1.c index 1159a24b5..8da20c146 100644 --- a/examples/widgets/list/lv_example_list_1.c +++ b/examples/widgets/list/lv_example_list_1.c @@ -1,16 +1,17 @@ #include "../../../lvgl.h" #if LV_USE_LIST && LV_BUILD_EXAMPLES +static lv_obj_t * list1; static void event_handler(lv_obj_t * obj, lv_event_t event) { if(event == LV_EVENT_CLICKED) { - LV_LOG_USER("Clicked: %s\n", lv_list_get_btn_text(obj)); + LV_LOG_USER("Clicked: %s\n", lv_list_get_btn_text(list1, obj)); } } void lv_example_list_1(void) { /*Create a list*/ - lv_obj_t * list1 = lv_list_create(lv_scr_act()); + list1 = lv_list_create(lv_scr_act()); lv_obj_align(list1, NULL, LV_ALIGN_CENTER, 0, 0); /*Add buttons to the list*/ diff --git a/src/extra/layouts/flex/lv_flex.c b/src/extra/layouts/flex/lv_flex.c index f4820d2a5..cd26f4b00 100644 --- a/src/extra/layouts/flex/lv_flex.c +++ b/src/extra/layouts/flex/lv_flex.c @@ -28,7 +28,6 @@ typedef struct { /********************** * GLOBAL PROTOTYPES **********************/ -void lv_obj_move_children_by(lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_diff); /********************** * STATIC PROTOTYPES @@ -160,6 +159,8 @@ static void flex_update(lv_obj_t * cont, lv_obj_t * item) if(cont->spec_attr == NULL) return; const lv_flex_t * f = (const lv_flex_t *)cont->spec_attr->layout_dsc; + LV_LOG_INFO("Flex update on 0x%p", cont); + bool rtl = lv_obj_get_base_dir(cont) == LV_BIDI_DIR_RTL ? true : false; bool row = f->dir == LV_FLEX_FLOW_ROW ? true : false; lv_coord_t track_gap = !row ? lv_obj_get_style_pad_column(cont, LV_PART_MAIN) : lv_obj_get_style_pad_row(cont, LV_PART_MAIN); @@ -272,9 +273,7 @@ static int32_t find_track_end(lv_obj_t * cont, int32_t item_start_id, lv_coord_t lv_obj_t * item = lv_obj_get_child(cont, item_id); while(item) { - if(!lv_obj_has_flag(item, LV_OBJ_FLAG_IGNORE_LAYOUT) && !lv_obj_has_flag(item, LV_OBJ_FLAG_HIDDEN)) { - if(item_id != item_start_id && lv_obj_has_flag(item, LV_OBJ_FLAG_LAYOUT_1)) break; - + if(!lv_obj_has_flag_any(item, LV_OBJ_FLAG_IGNORE_LAYOUT | LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) { lv_coord_t main_size = (row ? item->w_set : item->h_set); if(_LV_FLEX_GET_GROW(main_size)) { grow_sum += _LV_FLEX_GET_GROW(main_size); @@ -289,8 +288,8 @@ static int32_t find_track_end(lv_obj_t * cont, int32_t item_start_id, lv_coord_t t->track_cross_size = LV_MAX(get_cross_size(item), t->track_cross_size); t->item_cnt++; - } + item_id += f->rev ? -1 : +1; if(item_id < 0) break; item = lv_obj_get_child(cont, item_id); @@ -345,7 +344,7 @@ static void children_repos(lv_obj_t * cont, int32_t item_first_id, int32_t item_ lv_obj_t * item = lv_obj_get_child(cont, item_first_id); /*Reposition the children*/ while(item && item_first_id != item_last_id) { - if(lv_obj_has_flag(item, LV_OBJ_FLAG_IGNORE_LAYOUT) || lv_obj_has_flag(item, LV_OBJ_FLAG_HIDDEN)) { + if(lv_obj_has_flag_any(item, LV_OBJ_FLAG_IGNORE_LAYOUT | LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) { item = get_next_item(cont, f->rev, &item_first_id); continue; } @@ -393,7 +392,7 @@ static void children_repos(lv_obj_t * cont, int32_t item_first_id, int32_t item_ item->coords.y1 += diff_y; item->coords.y2 += diff_y; lv_obj_invalidate(item); - lv_obj_move_children_by(item, diff_x, diff_y); + lv_obj_move_children_by(item, diff_x, diff_y, true); } if(!(row && rtl)) main_pos += area_get_main_size(&item->coords) + item_gap + place_gap; diff --git a/src/extra/layouts/grid/lv_grid.c b/src/extra/layouts/grid/lv_grid.c index 98289b8d8..d8de33526 100644 --- a/src/extra/layouts/grid/lv_grid.c +++ b/src/extra/layouts/grid/lv_grid.c @@ -122,6 +122,7 @@ static 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; + LV_LOG_INFO("Grid update on 0x%p. Triggered by 0x%p", cont, item); if(item) item_refr(item); else full_refresh(cont); } @@ -251,7 +252,7 @@ static void calc_cols(lv_obj_t * cont, _lv_grid_calc_t * c) for(ci = 0; ci < lv_obj_get_child_cnt(cont); ci++) { lv_obj_t * item = lv_obj_get_child(cont, ci); if(LV_COORD_IS_LAYOUT(item->x_set) == false || LV_COORD_IS_LAYOUT(item->y_set) == false) continue; - if(lv_obj_has_flag(item, LV_OBJ_FLAG_IGNORE_LAYOUT)) continue; + if(lv_obj_has_flag_any(item, LV_OBJ_FLAG_IGNORE_LAYOUT | LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) continue; uint32_t col_pos = GET_CELL_POS(item->x_set); if(col_pos != i) continue; uint32_t col_span = GET_CELL_SPAN(item->x_set); @@ -312,7 +313,7 @@ static void calc_rows(lv_obj_t * cont, _lv_grid_calc_t * c) for(ci = 0; ci < lv_obj_get_child_cnt(cont); ci++) { lv_obj_t * item = lv_obj_get_child(cont, ci); if(LV_COORD_IS_LAYOUT(item->x_set) == false || LV_COORD_IS_LAYOUT(item->y_set) == false) continue; - if(lv_obj_has_flag(item, LV_OBJ_FLAG_IGNORE_LAYOUT)) continue; + if(lv_obj_has_flag_any(item, LV_OBJ_FLAG_IGNORE_LAYOUT | LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) continue; uint32_t row_pos = GET_CELL_POS(item->y_set); if(row_pos != i) continue; uint32_t row_span = GET_CELL_SPAN(item->y_set); @@ -367,7 +368,7 @@ 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) { if(LV_COORD_IS_LAYOUT(item->x_set) == 0 || LV_COORD_IS_LAYOUT(item->y_set) == 0) return; - if(lv_obj_has_flag(item, LV_OBJ_FLAG_IGNORE_LAYOUT)) return; + if(lv_obj_has_flag_any(item, LV_OBJ_FLAG_IGNORE_LAYOUT | LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) return; uint32_t col_span = GET_CELL_SPAN(item->x_set); uint32_t row_span = GET_CELL_SPAN(item->y_set); if(row_span == 0 || col_span == 0) return; diff --git a/src/extra/themes/default/lv_theme_default.c b/src/extra/themes/default/lv_theme_default.c index 2b2d331ce..cae528396 100644 --- a/src/extra/themes/default/lv_theme_default.c +++ b/src/extra/themes/default/lv_theme_default.c @@ -589,18 +589,6 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) } #if LV_USE_BTN else if(lv_obj_check_type(obj, &lv_btn_class)) { -#if LV_USE_LIST - /*Add different buttons to the lists*/ - if(lv_obj_check_type(lv_obj_get_parent(obj), &lv_list_class)) { - lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_white); - lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->list_btn); - lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_FOCUS_KEY, &styles->bg_color_primary); - lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_FOCUS_KEY, &styles->list_item_grow); - lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->list_item_grow); - lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->pressed); - return; - } -#endif lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->btn); lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_primary); lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->transition_delayed); @@ -774,17 +762,6 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) } #endif -#if LV_USE_LABEL - else if(lv_obj_check_type(obj, &lv_label_class)) { -#if LV_USE_LIST - if(lv_obj_check_type(lv_obj_get_parent(obj), &lv_list_class)) { - lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_grey); - lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->list_item_grow); - } -#endif - } -#endif - #if LV_USE_ARC else if(lv_obj_check_type(obj, &lv_arc_class)) { lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->arc_indic); @@ -849,6 +826,19 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) lv_obj_add_style(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled); return; } + else if(lv_obj_check_type(obj, &lv_list_text_class)) { + lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_grey); + lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->list_item_grow); + } + else if(lv_obj_check_type(obj, &lv_list_btn_class)) { + lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->bg_color_white); + lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->list_btn); + lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_FOCUS_KEY, &styles->bg_color_primary); + lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_FOCUS_KEY, &styles->list_item_grow); + lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->list_item_grow); + lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_PRESSED, &styles->pressed); + + } #endif #if LV_USE_MSGBOX else if(lv_obj_check_type(obj, &lv_msgbox_class)) { diff --git a/src/extra/widgets/list/lv_list.c b/src/extra/widgets/list/lv_list.c index 11d1959ca..600144ef1 100644 --- a/src/extra/widgets/list/lv_list.c +++ b/src/extra/widgets/list/lv_list.c @@ -31,6 +31,14 @@ const lv_obj_class_t lv_list_class = { .base_class = &lv_obj_class, }; +const lv_obj_class_t lv_list_btn_class = { + .base_class = &lv_btn_class, +}; + +const lv_obj_class_t lv_list_text_class = { + .base_class = &lv_label_class, +}; + /********************** * STATIC VARIABLES **********************/ @@ -54,7 +62,7 @@ lv_obj_t * lv_list_create(lv_obj_t * parent) lv_obj_t * lv_list_add_text(lv_obj_t * list, const char * txt) { - lv_obj_t * label = lv_label_create(list, NULL); + lv_obj_t * label = lv_obj_create_from_class(&lv_list_text_class, list, NULL); lv_label_set_text(label, txt); lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR); lv_obj_set_width(label, LV_SIZE_PCT(100)); @@ -63,7 +71,7 @@ lv_obj_t * lv_list_add_text(lv_obj_t * list, const char * txt) lv_obj_t * lv_list_add_btn(lv_obj_t * list, const char * icon, const char * txt, lv_event_cb_t event_cb) { - lv_obj_t * btn = lv_btn_create(list, NULL); + lv_obj_t * btn = lv_obj_create_from_class(&lv_list_btn_class, list, NULL); lv_obj_set_width(btn, LV_SIZE_PCT(100)); lv_obj_add_event_cb(btn, event_cb, NULL); lv_obj_set_layout(btn, &lv_flex_inline); @@ -83,7 +91,7 @@ lv_obj_t * lv_list_add_btn(lv_obj_t * list, const char * icon, const char * txt, return btn; } -const char * lv_list_get_btn_text(lv_obj_t * btn) +const char * lv_list_get_btn_text(lv_obj_t * list, lv_obj_t * btn) { uint32_t i; for(i = 0; i < lv_obj_get_child_cnt(btn); i++) { diff --git a/src/extra/widgets/list/lv_list.h b/src/extra/widgets/list/lv_list.h index eebfa00ae..e2b133569 100644 --- a/src/extra/widgets/list/lv_list.h +++ b/src/extra/widgets/list/lv_list.h @@ -27,6 +27,8 @@ extern "C" { **********************/ extern const lv_obj_class_t lv_list_class; +extern const lv_obj_class_t lv_list_text_class; +extern const lv_obj_class_t lv_list_btn_class; /********************** * GLOBAL PROTOTYPES **********************/ @@ -37,7 +39,7 @@ lv_obj_t * lv_list_add_text(lv_obj_t * list, const char * txt); lv_obj_t * lv_list_add_btn(lv_obj_t * list, const char * icon, const char * txt, lv_event_cb_t event_cb); -const char * lv_list_get_btn_text(lv_obj_t * btn); +const char * lv_list_get_btn_text(lv_obj_t * list, lv_obj_t * btn); /********************** * MACROS diff --git a/src/lv_core/lv_indev.c b/src/lv_core/lv_indev.c index a38d79498..54d9c2090 100644 --- a/src/lv_core/lv_indev.c +++ b/src/lv_core/lv_indev.c @@ -183,7 +183,7 @@ void lv_indev_set_cursor(lv_indev_t * indev, lv_obj_t * cur_obj) lv_obj_set_parent(indev->cursor, lv_disp_get_layer_sys(indev->driver.disp)); lv_obj_set_pos(indev->cursor, indev->proc.types.pointer.act_point.x, indev->proc.types.pointer.act_point.y); lv_obj_clear_flag(indev->cursor, LV_OBJ_FLAG_CLICKABLE); - lv_obj_add_flag(indev->cursor, LV_OBJ_FLAG_IGNORE_LAYOUT); + lv_obj_add_flag(indev->cursor, LV_OBJ_FLAG_IGNORE_LAYOUT | LV_OBJ_FLAG_FLOATING); } void lv_indev_set_group(lv_indev_t * indev, lv_group_t * group) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 20ea03ecf..8c170b760 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -135,7 +135,7 @@ void lv_init(void) uint8_t * txt_u8 = (uint8_t *) txt; if(txt_u8[0] != 0xc3 || txt_u8[1] != 0x81 || txt_u8[2] != 0x00) { - LV_LOG_WARN("The strings has no UTF-8 encoding. Some characters won't be displayed.") + LV_LOG_WARN("The strings has no UTF-8 encoding. Non-ASCII characters won't be displayed.") } #if LV_USE_ASSERT_MEM_INTEGRITY @@ -146,6 +146,10 @@ void lv_init(void) LV_LOG_WARN("Object sanity checks are enabled via LV_USE_ASSERT_OBJ which makes LVGL much slower") #endif +#if LV_LOG_LEVEL == LV_LOG_LEVEL_TRACE + LV_LOG_WARN("Log level is set the Trace which makes LVGL much slower") +#endif + lv_initialized = true; LV_LOG_INFO("lv_init ready"); @@ -310,7 +314,7 @@ void lv_obj_add_flag(lv_obj_t * obj, lv_obj_flag_t f) obj->flags |= f; - if(f & LV_OBJ_FLAG_IGNORE_LAYOUT) lv_signal_send(lv_obj_get_parent(obj), LV_SIGNAL_CHILD_CHG, obj); + if(f & (LV_OBJ_FLAG_IGNORE_LAYOUT | LV_OBJ_FLAG_FLOATING)) lv_signal_send(lv_obj_get_parent(obj), LV_SIGNAL_CHILD_CHG, obj); if(f & (LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_LAYOUT_1 | LV_OBJ_FLAG_LAYOUT_2)) { lv_obj_invalidate(obj); @@ -332,7 +336,7 @@ void lv_obj_clear_flag(lv_obj_t * obj, lv_obj_flag_t f) lv_obj_update_layout(lv_obj_get_parent(obj), obj); } } - if(f & LV_OBJ_FLAG_IGNORE_LAYOUT) lv_signal_send(lv_obj_get_parent(obj), LV_SIGNAL_CHILD_CHG, obj); + if(f & (LV_OBJ_FLAG_IGNORE_LAYOUT | LV_OBJ_FLAG_FLOATING)) lv_signal_send(lv_obj_get_parent(obj), LV_SIGNAL_CHILD_CHG, obj); } void lv_obj_add_state(lv_obj_t * obj, lv_state_t state) @@ -399,6 +403,13 @@ bool lv_obj_has_flag(const lv_obj_t * obj, lv_obj_flag_t f) return (obj->flags & f) == f ? true : false; } +bool lv_obj_has_flag_any(const lv_obj_t * obj, lv_obj_flag_t f) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + return (obj->flags & f) ? true : false; +} + lv_bidi_dir_t lv_obj_get_base_dir(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, MY_CLASS); diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index 3472f6750..059b3848d 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -203,6 +203,7 @@ enum { LV_OBJ_FLAG_FOCUS_BUBBLE = (1 << 14), /**< Propagate the focus to the parent */ LV_OBJ_FLAG_ADV_HITTEST = (1 << 15), /**< Allow performing more accurate hit (click) test. E.g. consider rounded corners. */ LV_OBJ_FLAG_IGNORE_LAYOUT = (1 << 16), /**< Make the object position-able by the layouts */ + LV_OBJ_FLAG_FLOATING = (1 << 17), LV_OBJ_FLAG_LAYOUT_1 = (1 << 23), /** Custom flag, free to use by layouts*/ LV_OBJ_FLAG_LAYOUT_2 = (1 << 24), /** Custom flag, free to use by layouts*/ @@ -416,13 +417,22 @@ void lv_obj_set_base_dir(lv_obj_t * obj, lv_bidi_dir_t dir); *======================*/ /** - * Check if a given flag or flags are set on an object. + * Check if a given flag or all the given flags are set on an object. * @param obj pointer to an object * @param f the flag(s) to check (OR-ed values can be used) * @return true: all flags are set; false: not all flags are set */ bool lv_obj_has_flag(const lv_obj_t * obj, lv_obj_flag_t f); +/** + * Check if a given flag or any of the flags are set on an object. + * @param obj pointer to an object + * @param f the flag(s) to check (OR-ed values can be used) + * @return true: at lest one flag flag is set; false: none of the flags are set + */ +bool lv_obj_has_flag_any(const lv_obj_t * obj, lv_obj_flag_t f); + + /** * Get the base direction of the object * @param obj pointer to an object diff --git a/src/lv_core/lv_obj_pos.c b/src/lv_core/lv_obj_pos.c index 8f4c643d9..346628dae 100644 --- a/src/lv_core/lv_obj_pos.c +++ b/src/lv_core/lv_obj_pos.c @@ -26,7 +26,6 @@ static bool refr_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h); static void calc_auto_size(lv_obj_t * obj, lv_coord_t * w_out, lv_coord_t * h_out); void lv_obj_move_to(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, bool notify); -void lv_obj_move_children_by(lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_diff); /********************** * STATIC VARIABLES @@ -154,7 +153,7 @@ void lv_obj_set_layout(lv_obj_t * obj, const void * layout) bool lv_obj_is_layout_positioned(const lv_obj_t * obj) { - if(lv_obj_has_flag(obj, LV_OBJ_FLAG_IGNORE_LAYOUT)) return false; + if(lv_obj_has_flag_any(obj, LV_OBJ_FLAG_IGNORE_LAYOUT | LV_OBJ_FLAG_FLOATING)) return false; lv_obj_t * parent = lv_obj_get_parent(obj); if(parent == NULL) return false; @@ -449,7 +448,7 @@ void lv_obj_move_to(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, bool notify) obj->coords.x2 += diff.x; obj->coords.y2 += diff.y; - lv_obj_move_children_by(obj, diff.x, diff.y); + lv_obj_move_children_by(obj, diff.x, diff.y, false); /*Inform the object about its new coordinates*/ lv_signal_send(obj, LV_SIGNAL_COORD_CHG, &ori); @@ -466,17 +465,18 @@ void lv_obj_move_to(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, bool notify) if(on1 || (!on1 && on2)) lv_obj_scrollbar_invalidate(parent); } -void lv_obj_move_children_by(lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_diff) +void lv_obj_move_children_by(lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_diff, bool ignore_floating) { uint32_t i; for(i = 0; i < lv_obj_get_child_cnt(obj); i++) { lv_obj_t * child = lv_obj_get_child(obj, i); + if(ignore_floating && lv_obj_has_flag(child, LV_OBJ_FLAG_FLOATING)) continue; child->coords.x1 += x_diff; child->coords.y1 += y_diff; child->coords.x2 += x_diff; child->coords.y2 += y_diff; - lv_obj_move_children_by(child, x_diff, y_diff); + lv_obj_move_children_by(child, x_diff, y_diff, false); } } diff --git a/src/lv_core/lv_obj_pos.h b/src/lv_core/lv_obj_pos.h index 5464abe0a..e16c381a4 100644 --- a/src/lv_core/lv_obj_pos.h +++ b/src/lv_core/lv_obj_pos.h @@ -246,6 +246,9 @@ lv_coord_t lv_obj_get_self_height(struct _lv_obj_t * obj); bool lv_obj_handle_self_size_chg(struct _lv_obj_t * obj); + +void lv_obj_move_children_by(struct _lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_diff, bool ignore_floating); + /** * Mark an area of an object as invalid. * The area will be truncated to the object's area and marked for redraw. diff --git a/src/lv_core/lv_obj_scroll.c b/src/lv_core/lv_obj_scroll.c index 10bc9bcef..a63f4548b 100644 --- a/src/lv_core/lv_obj_scroll.c +++ b/src/lv_core/lv_obj_scroll.c @@ -27,7 +27,6 @@ /********************** * GLOBAL PROTOTYPES **********************/ -void lv_obj_move_children_by(lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_diff); /********************** * STATIC PROTOTYPES @@ -140,6 +139,7 @@ lv_coord_t lv_obj_get_scroll_bottom(lv_obj_t * obj) uint32_t i; for(i = 0; i < lv_obj_get_child_cnt(obj); i++) { lv_obj_t * child = lv_obj_get_child(obj, i); + if(lv_obj_has_flag_any(child, LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) continue; child_res = LV_MAX(child_res, child->coords.y2); } @@ -175,6 +175,7 @@ lv_coord_t lv_obj_get_scroll_left(lv_obj_t * obj) lv_coord_t x1 = LV_COORD_MAX; for(i = 0; i < lv_obj_get_child_cnt(obj); i++) { lv_obj_t * child = lv_obj_get_child(obj, i); + if(lv_obj_has_flag_any(child, LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) continue; x1 = LV_MIN(x1, child->coords.x1); } @@ -207,6 +208,7 @@ lv_coord_t lv_obj_get_scroll_right(lv_obj_t * obj) uint32_t i; for(i = 0; i < lv_obj_get_child_cnt(obj); i++) { lv_obj_t * child = lv_obj_get_child(obj, i); + if(lv_obj_has_flag_any(child, LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) continue; child_res = LV_MAX(child_res, child->coords.x2); } @@ -521,7 +523,7 @@ static void scroll_by_raw(lv_obj_t * obj, lv_coord_t x, lv_coord_t y) obj->spec_attr->scroll.x += x; obj->spec_attr->scroll.y += y; - lv_obj_move_children_by(obj, x, y); + lv_obj_move_children_by(obj, x, y, true); lv_res_t res = lv_signal_send(obj, LV_SIGNAL_SCROLL, NULL); if(res != LV_RES_OK) return; lv_obj_invalidate(obj); diff --git a/src/lv_core/lv_obj_tree.c b/src/lv_core/lv_obj_tree.c index 3e31b9d69..29a44dd21 100644 --- a/src/lv_core/lv_obj_tree.c +++ b/src/lv_core/lv_obj_tree.c @@ -205,10 +205,10 @@ void lv_obj_move_background(lv_obj_t * obj) lv_obj_invalidate(parent); uint32_t i; - for(i = lv_obj_get_child_id(obj); i < lv_obj_get_child_cnt(parent) - 2; i++) { + for(i = lv_obj_get_child_id(obj); i < lv_obj_get_child_cnt(parent) - 1; i++) { parent->spec_attr->children[i] = parent->spec_attr->children[i + 1]; } - parent->spec_attr->children[ lv_obj_get_child_cnt(parent) - 1] = obj; + parent->spec_attr->children[lv_obj_get_child_cnt(parent) - 1] = obj; /*Notify the new parent about the child*/ lv_signal_send(parent, LV_SIGNAL_CHILD_CHG, obj); diff --git a/src/lv_core/lv_refr.c b/src/lv_core/lv_refr.c index 21cf04e3d..b6e09e0b8 100644 --- a/src/lv_core/lv_refr.c +++ b/src/lv_core/lv_refr.c @@ -45,6 +45,7 @@ static void lv_refr_obj_and_children(lv_obj_t * top_p, const lv_area_t * mask_p) static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p); static void lv_refr_vdb_flush(void); static lv_draw_res_t call_draw_cb(lv_obj_t * obj, const lv_area_t * clip_area, lv_draw_mode_t mode); +static void call_flush_cb(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p); /********************** * STATIC VARIABLES @@ -789,7 +790,7 @@ static void lv_refr_vdb_rotate(lv_area_t *area, lv_color_t *color_p) { } if(drv->rotated == LV_DISP_ROT_180) { lv_refr_vdb_rotate_180(drv, area, color_p); - drv->flush_cb(drv, area, color_p); + call_flush_cb(drv, area, color_p); } else if(drv->rotated == LV_DISP_ROT_90 || drv->rotated == LV_DISP_ROT_270) { /*Allocate a temporary buffer to store rotated image */ lv_color_t * rot_buf = NULL; @@ -838,7 +839,7 @@ static void lv_refr_vdb_rotate(lv_area_t *area, lv_color_t *color_p) { } } /*Flush the completed area to the display*/ - drv->flush_cb(drv, area, rot_buf == NULL ? color_p : rot_buf); + call_flush_cb(drv, area, rot_buf == NULL ? color_p : rot_buf); /*FIXME: Rotation forces legacy behavior where rendering and flushing are done serially*/ while(vdb->flushing) { if(drv->wait_cb) drv->wait_cb(drv); @@ -873,7 +874,7 @@ static void lv_refr_vdb_flush(void) if(disp->driver.rotated != LV_DISP_ROT_NONE && disp->driver.sw_rotate) { lv_refr_vdb_rotate(&vdb->area, vdb->buf_act); } else { - disp->driver.flush_cb(&disp->driver, &vdb->area, color_p); + call_flush_cb(&disp->driver, &vdb->area, color_p); } } if(vdb->buf1 && vdb->buf2) { @@ -900,3 +901,9 @@ static lv_draw_res_t call_draw_cb(lv_obj_t * obj, const lv_area_t * clip_area, l return res; } + +static void call_flush_cb(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p) +{ + LV_LOG_INFO("Calling flush_cb on (%d;%d)(%d;%d) area with 0x%p image pointer", area->x1, area->y1, area->x2, area->y2, color_p); + drv->flush_cb(drv, area, color_p); +}