From e111ea2a625a37c943a51adfa9f3f93879f49acf Mon Sep 17 00:00:00 2001 From: Karijn Wessing Date: Tue, 24 Aug 2021 14:30:38 +0200 Subject: [PATCH] added lv_obj_move_up() and lv_obj_move_down() (#2467) * - small with unneeded lv_obj_invalidate() fix in lv_obj_move_foreground() and lv_obj_move_background() - added lv_obj_move_up() and lv_obj_move_down() - used new functions in sample 2 - used lv_obj_swap() to shuffle (turn around) list * solved build error * added top and bottom buttons in sample --- docs/CHANGELOG.md | 1 + docs/overview/layer.md | 3 +- docs/widgets/obj.md | 2 + examples/widgets/list/lv_example_list_2.c | 81 +++++++++++++++++++---- src/core/lv_obj_tree.c | 48 ++++++++++++-- src/core/lv_obj_tree.h | 14 ++++ 6 files changed, 131 insertions(+), 18 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 3e5db563a..a8076deff 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ## v8.1.0 (In progress) +- lv_obj_move_up(obj) and lv_obj_move_down(obj) added. (#2461) - lv_obj_swap(obj1, obj2) added. (#2461) - feat(anim) add interface for handling lv_anim user data. (#2415) - feat(obj) add lv_is_initialized (#2402) diff --git a/docs/overview/layer.md b/docs/overview/layer.md index 5be272e63..92c35ae60 100644 --- a/docs/overview/layer.md +++ b/docs/overview/layer.md @@ -40,8 +40,9 @@ lv_obj_del(label2); ## Bring to the foreground -There are 3 explicit way to bring an object to the foreground: +There are 4 explicit way to bring an object to the foreground: - Use `lv_obj_move_foreground(obj)` to explicitly tell the library to bring an object to the foreground. Similarly, use `lv_obj_move_background(obj)` to move to the background. +- Use `lv_obj_move_up(obj)` moves the object one position up in the hierarchy, Similary, use `lv_obj_move_down(obj)` moves the object one position down in the hierarchy. - Use `lv_obj_swap(obj1, obj2)` to swap the relative position of two objects. - When `lv_obj_set_parent(obj, new_parent)` is used, `obj` will be on the foreground on the `new_parent`. diff --git a/docs/widgets/obj.md b/docs/widgets/obj.md index 196c1555c..c67e06a7f 100644 --- a/docs/widgets/obj.md +++ b/docs/widgets/obj.md @@ -69,6 +69,8 @@ for(i = 0; i < lv_obj_get_child_cnt(parent); i++) { You can bring an object to the foreground or send it to the background with `lv_obj_move_foreground(obj)` and `lv_obj_move_background(obj)`. +You can move an object one position up or down in the hierargy with `lv_obj_move_up(obj)` and `lv_obj_move_down(obj)`. + You can swap the position of two objects with `lv_obj_swap(obj1, obj2)`. ### Screens diff --git a/examples/widgets/list/lv_example_list_2.c b/examples/widgets/list/lv_example_list_2.c index 99067acf7..0e99e4b97 100644 --- a/examples/widgets/list/lv_example_list_2.c +++ b/examples/widgets/list/lv_example_list_2.c @@ -1,3 +1,5 @@ +#include + #include "../../lv_examples.h" #if LV_USE_LIST && LV_BUILD_EXAMPLES @@ -39,18 +41,25 @@ static void event_handler(lv_event_t* e) } } -static void event_handler_mu(lv_event_t* e) +static void event_handler_top(lv_event_t* e) +{ + lv_event_code_t code = lv_event_get_code(e); + if (code == LV_EVENT_CLICKED) + { + if (currentButton == NULL) return; + lv_obj_move_background(currentButton); + lv_obj_scroll_to_view(currentButton, LV_ANIM_ON); + } +} + +static void event_handler_up(lv_event_t* e) { lv_event_code_t code = lv_event_get_code(e); if ((code == LV_EVENT_CLICKED) || (code == LV_EVENT_LONG_PRESSED_REPEAT)) { if (currentButton == NULL) return; - lv_obj_t* parent = lv_obj_get_parent(currentButton); - uint_fast32_t i = lv_obj_get_child_id(currentButton); - if (i > 0) { - lv_obj_swap(parent->spec_attr->children[i], parent->spec_attr->children[i - 1]); - lv_obj_scroll_to_view(currentButton, LV_ANIM_ON); - } + lv_obj_move_up(currentButton); + lv_obj_scroll_to_view(currentButton, LV_ANIM_ON); } } @@ -60,11 +69,45 @@ static void event_handler_dn(lv_event_t* e) if ((code == LV_EVENT_CLICKED) || (code == LV_EVENT_LONG_PRESSED_REPEAT)) { if (currentButton == NULL) return; - lv_obj_t* parent = lv_obj_get_parent(currentButton); - uint_fast32_t i = lv_obj_get_child_id(currentButton); - if (i < lv_obj_get_child_cnt(parent) - 1) { - lv_obj_swap(parent->spec_attr->children[i], parent->spec_attr->children[i + 1]); - lv_obj_scroll_to_view(currentButton, LV_ANIM_ON); + lv_obj_move_down(currentButton); + lv_obj_scroll_to_view(currentButton, LV_ANIM_ON); + } +} + +static void event_handler_bottom(lv_event_t* e) +{ + lv_event_code_t code = lv_event_get_code(e); + if (code == LV_EVENT_CLICKED) + { + if (currentButton == NULL) return; + lv_obj_move_foreground(currentButton); + lv_obj_scroll_to_view(currentButton, LV_ANIM_ON); + } +} + +static void event_handler_swap(lv_event_t* e) +{ + lv_event_code_t code = lv_event_get_code(e); + // lv_obj_t* obj = lv_event_get_target(e); + if ((code == LV_EVENT_CLICKED) || (code == LV_EVENT_LONG_PRESSED_REPEAT)) + { + uint32_t first = 0; + uint32_t last = lv_obj_get_child_cnt(list1); + if (last > 1) + { + last--; + while (first < last) + { + lv_obj_t* obj1 = lv_obj_get_child(list1, first); + lv_obj_t* obj2 = lv_obj_get_child(list1, last); + lv_obj_swap(obj1, obj2); + first++; + last--; + } + if (currentButton != NULL) + { + lv_obj_scroll_to_view(currentButton, LV_ANIM_ON); + } } } } @@ -98,13 +141,25 @@ void lv_example_list_2(void) lv_obj_align(list2, LV_ALIGN_TOP_RIGHT, 0, 0); lv_obj_set_flex_flow(list2, LV_FLEX_FLOW_COLUMN); + btn = lv_list_add_btn(list2, NULL, "Top"); + lv_obj_add_event_cb(btn, event_handler_top, LV_EVENT_ALL, NULL); + lv_group_remove_obj(btn); + btn = lv_list_add_btn(list2, LV_SYMBOL_UP, "Up"); - lv_obj_add_event_cb(btn, event_handler_mu, LV_EVENT_ALL, NULL); + lv_obj_add_event_cb(btn, event_handler_up, LV_EVENT_ALL, NULL); lv_group_remove_obj(btn); btn = lv_list_add_btn(list2, LV_SYMBOL_DOWN, "Down"); lv_obj_add_event_cb(btn, event_handler_dn, LV_EVENT_ALL, NULL); lv_group_remove_obj(btn); + + btn = lv_list_add_btn(list2, NULL, "Bottom"); + lv_obj_add_event_cb(btn, event_handler_bottom, LV_EVENT_ALL, NULL); + lv_group_remove_obj(btn); + + btn = lv_list_add_btn(list2, LV_SYMBOL_SHUFFLE, "Shuffle"); + lv_obj_add_event_cb(btn, event_handler_swap, LV_EVENT_ALL, NULL); + lv_group_remove_obj(btn); } #endif diff --git a/src/core/lv_obj_tree.c b/src/core/lv_obj_tree.c index c53d97a95..9e97360bd 100644 --- a/src/core/lv_obj_tree.c +++ b/src/core/lv_obj_tree.c @@ -201,8 +201,6 @@ void lv_obj_move_foreground(lv_obj_t * obj) lv_obj_t * parent = lv_obj_get_parent(obj); - lv_obj_invalidate(parent); - uint32_t 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]; @@ -221,8 +219,6 @@ void lv_obj_move_background(lv_obj_t * obj) lv_obj_t * parent = lv_obj_get_parent(obj); - lv_obj_invalidate(parent); - int32_t i; for(i = lv_obj_get_child_id(obj); i > 0; i--) { parent->spec_attr->children[i] = parent->spec_attr->children[i-1]; @@ -260,6 +256,50 @@ void lv_obj_swap(lv_obj_t * obj1, lv_obj_t * obj2) lv_group_swap_obj(obj1, obj2); } +void lv_obj_move_up(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_obj_t* parent = lv_obj_get_parent(obj); + + uint_fast32_t index = lv_obj_get_child_id(obj); + if (index > 0) + { + lv_obj_t* obj2 = parent->spec_attr->children[index - 1]; + parent->spec_attr->children[index - 1] = obj; + parent->spec_attr->children[index] = obj2; + + lv_event_send(parent, LV_EVENT_CHILD_CHANGED, obj); + lv_event_send(parent, LV_EVENT_CHILD_CHANGED, obj2); + + lv_obj_invalidate(parent); + + lv_group_swap_obj(obj, obj2); + } +} + +void lv_obj_move_down(lv_obj_t* obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_obj_t* parent = lv_obj_get_parent(obj); + + uint_fast32_t index = lv_obj_get_child_id(obj); + if (index < lv_obj_get_child_cnt(parent) - 1) + { + lv_obj_t* obj2 = parent->spec_attr->children[index + 1]; + parent->spec_attr->children[index + 1] = obj; + parent->spec_attr->children[index] = obj2; + + lv_event_send(parent, LV_EVENT_CHILD_CHANGED, obj); + lv_event_send(parent, LV_EVENT_CHILD_CHANGED, obj2); + + lv_obj_invalidate(parent); + + lv_group_swap_obj(obj, obj2); + } +} + lv_obj_t * lv_obj_get_screen(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, MY_CLASS); diff --git a/src/core/lv_obj_tree.h b/src/core/lv_obj_tree.h index 7b916de5b..caf623c9d 100644 --- a/src/core/lv_obj_tree.h +++ b/src/core/lv_obj_tree.h @@ -109,6 +109,20 @@ void lv_obj_move_background(struct _lv_obj_t * obj); */ void lv_obj_swap(struct _lv_obj_t* obj1, struct _lv_obj_t* obj2); +/** + * moves the object one position up in the hierarchy. + * When used in listboxes, it can be used to sort the listbox items. + * @param obj pointer to the object to be moved upwards. + */ +void lv_obj_move_up(struct _lv_obj_t* obj); + +/** + * moves the object one position down in the hierarchy. + * When used in listboxes, it can be used to sort the listbox items. + * @param obj pointer to the object to be moved downwards. + */ +void lv_obj_move_down(struct _lv_obj_t* obj); + /** * Get the screen of an object * @param obj pointer to an object