From 5f90029811e5eb65263ed0d8843aa6be20bcdc7c Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 4 Oct 2021 16:52:11 +0200 Subject: [PATCH] feat(event) add LV_EVENT_CHILD_CREATED/DELETED (#2618) * feat(event) add LV_EVENT_CHILD_CREATED/DELETED * update docs and CHANGELOG --- docs/CHANGELOG.md | 1 + docs/overview/event.md | 2 ++ src/core/lv_event.c | 27 +++++++++++++++++++++------ src/core/lv_event.h | 4 +++- src/core/lv_obj_class.c | 1 + src/core/lv_obj_tree.c | 8 ++++++++ 6 files changed, 36 insertions(+), 7 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 292660252..534908ef6 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -38,6 +38,7 @@ - fix(disp) set default theme also for non-default displays - feat(btnmatrix/keyboard): add option to show popovers on button press - fix(types) LV_FORMAT_ATTRIBUTE now works with gnu version greater than 4.4 +- feat(event) add add LV_EVENT_CHILD_CREATED/DELETED ## v8.0.2 (16.07.2021) - fix(theme) improve button focus of keyboard diff --git a/docs/overview/event.md b/docs/overview/event.md index e13b39ee1..d2fb2b974 100644 --- a/docs/overview/event.md +++ b/docs/overview/event.md @@ -104,6 +104,8 @@ The following event codes exist: ### Other events - `LV_EVENT_DELETE` Object is being deleted - `LV_EVENT_CHILD_CHANGED` Child was removed/added +- `LV_EVENT_CHILD_CREATED` Child was created, always bubbles up to all parents +- `LV_EVENT_CHILD_DELETED` Child was deleted, always bubbles up to all parents - `LV_EVENT_SIZE_CHANGED` Object coordinates/size have changed - `LV_EVENT_STYLE_CHANGED` Object's style has changed - `LV_EVENT_BASE_DIR_CHANGED` The base dir has changed diff --git a/src/core/lv_event.c b/src/core/lv_event.c index 20b54c7fd..b052b6bba 100644 --- a/src/core/lv_event.c +++ b/src/core/lv_event.c @@ -28,7 +28,8 @@ typedef struct _lv_event_dsc_t { **********************/ static lv_event_dsc_t * lv_obj_get_event_dsc(const lv_obj_t * obj, uint32_t id); static lv_res_t event_send_core(lv_event_t * e); -static bool event_is_bubbled(lv_event_code_t e); +static bool event_is_bubbled(lv_event_t * e); + /********************** * STATIC VARIABLES @@ -427,20 +428,32 @@ static lv_res_t event_send_core(lv_event_t * e) event_dsc = lv_obj_get_event_dsc(e->current_target, i); } - if(res == LV_RES_OK && event_is_bubbled(e->code)) { - if(lv_obj_has_flag(e->current_target, LV_OBJ_FLAG_EVENT_BUBBLE) && e->current_target->parent) { + if(res == LV_RES_OK && e->current_target->parent && event_is_bubbled(e)) + { e->current_target = e->current_target->parent; res = event_send_core(e); if(res != LV_RES_OK) return LV_RES_INV; - } + } return res; } -static bool event_is_bubbled(lv_event_code_t e) +static bool event_is_bubbled(lv_event_t * e) { - switch(e) { + /*Event codes that always bubble*/ + switch(e->code) { + case LV_EVENT_CHILD_CREATED: + case LV_EVENT_CHILD_DELETED: + return true; + default: + break; + } + + /*Check other codes only if bubbling is enabled*/ + if(lv_obj_has_flag(e->current_target, LV_OBJ_FLAG_EVENT_BUBBLE) == false) return false; + + switch(e->code) { case LV_EVENT_HIT_TEST: case LV_EVENT_COVER_CHECK: case LV_EVENT_REFR_EXT_DRAW_SIZE: @@ -454,6 +467,8 @@ static bool event_is_bubbled(lv_event_code_t e) case LV_EVENT_DRAW_PART_END: case LV_EVENT_REFRESH: case LV_EVENT_DELETE: + case LV_EVENT_CHILD_CREATED: + case LV_EVENT_CHILD_DELETED: case LV_EVENT_CHILD_CHANGED: case LV_EVENT_SIZE_CHANGED: case LV_EVENT_STYLE_CHANGED: diff --git a/src/core/lv_event.h b/src/core/lv_event.h index 7fac61640..a7115dbc5 100644 --- a/src/core/lv_event.h +++ b/src/core/lv_event.h @@ -72,7 +72,9 @@ typedef enum { /** Other events*/ LV_EVENT_DELETE, /**< Object is being deleted*/ - LV_EVENT_CHILD_CHANGED, /**< Child was removed/added*/ + LV_EVENT_CHILD_CHANGED, /**< Child was removed, added, or its size, position were changed */ + LV_EVENT_CHILD_CREATED, /**< Child was created, always bubbles up to all parents*/ + LV_EVENT_CHILD_DELETED, /**< Child was deleted, always bubbles up to all parents*/ LV_EVENT_SIZE_CHANGED, /**< Object coordinates/size have changed*/ LV_EVENT_STYLE_CHANGED, /**< Object's style has changed*/ LV_EVENT_LAYOUT_CHANGED, /**< The children position has changed due to a layout recalculation*/ diff --git a/src/core/lv_obj_class.c b/src/core/lv_obj_class.c index fe1b183d8..6f5f748d8 100644 --- a/src/core/lv_obj_class.c +++ b/src/core/lv_obj_class.c @@ -123,6 +123,7 @@ void lv_obj_class_init_obj(lv_obj_t * obj) /*Call the ancestor's event handler to the parent to notify it about the new child. *Also triggers layout update*/ lv_event_send(parent, LV_EVENT_CHILD_CHANGED, obj); + lv_event_send(parent, LV_EVENT_CHILD_CREATED, obj); /*Invalidate the area if not screen created*/ lv_obj_invalidate(obj); diff --git a/src/core/lv_obj_tree.c b/src/core/lv_obj_tree.c index 93b56135b..efe5395b4 100644 --- a/src/core/lv_obj_tree.c +++ b/src/core/lv_obj_tree.c @@ -72,6 +72,7 @@ void lv_obj_del(lv_obj_t * obj) lv_obj_readjust_scroll(par, LV_ANIM_OFF); lv_obj_scrollbar_invalidate(par); lv_event_send(par, LV_EVENT_CHILD_CHANGED, NULL); + lv_event_send(par, LV_EVENT_CHILD_DELETED, NULL); } /*Handle if the active screen was deleted*/ @@ -193,9 +194,11 @@ void lv_obj_set_parent(lv_obj_t * obj, lv_obj_t * parent) /*Notify the original parent because one of its children is lost*/ lv_event_send(old_parent, LV_EVENT_CHILD_CHANGED, obj); + lv_event_send(old_parent, LV_EVENT_CHILD_DELETED, NULL); /*Notify the new parent about the child*/ lv_event_send(parent, LV_EVENT_CHILD_CHANGED, obj); + lv_event_send(parent, LV_EVENT_CHILD_CREATED, NULL); lv_obj_invalidate(obj); } @@ -242,11 +245,16 @@ void lv_obj_swap(lv_obj_t * obj1, lv_obj_t * obj2) uint_fast32_t index1 = lv_obj_get_index(obj1); uint_fast32_t index2 = lv_obj_get_index(obj2); + lv_event_send(parent2, LV_EVENT_CHILD_DELETED, obj2); + lv_event_send(parent, LV_EVENT_CHILD_DELETED, obj1); + parent->spec_attr->children[index1] = obj2; parent2->spec_attr->children[index2] = obj1; lv_event_send(parent, LV_EVENT_CHILD_CHANGED, obj2); + lv_event_send(parent, LV_EVENT_CHILD_CREATED, obj2); lv_event_send(parent2, LV_EVENT_CHILD_CHANGED, obj1); + lv_event_send(parent2, LV_EVENT_CHILD_CREATED, obj1); lv_obj_invalidate(parent);