mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-28 13:36:27 +08:00
feat(events): add event trickle mechanism to propagate events to children (#8415)
Arduino Lint / lint (push) Has been cancelled
Build Examples with C++ Compiler / build-examples (push) Has been cancelled
MicroPython CI / Build esp32 port (push) Has been cancelled
MicroPython CI / Build rp2 port (push) Has been cancelled
MicroPython CI / Build stm32 port (push) Has been cancelled
MicroPython CI / Build unix port (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_NORMAL_8BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_SDL - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_VG_LITE - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_VG_LITE - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_VG_LITE - gcc - Windows (push) Has been cancelled
C/C++ CI / Build ESP IDF ESP32S3 (push) Has been cancelled
C/C++ CI / Run tests with 32bit build (push) Has been cancelled
C/C++ CI / Run tests with 64bit build (push) Has been cancelled
BOM Check / bom-check (push) Has been cancelled
Verify that lv_conf_internal.h matches repository state / verify-conf-internal (push) Has been cancelled
Verify the widget property name / verify-property-name (push) Has been cancelled
Verify code formatting / verify-formatting (push) Has been cancelled
Compare file templates with file names / template-check (push) Has been cancelled
Build docs / build-and-deploy (push) Has been cancelled
Test API JSON generator / Test API JSON (push) Has been cancelled
Check Makefile / Build using Makefile (push) Has been cancelled
Check Makefile for UEFI / Build using Makefile for UEFI (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_32B - Ubuntu (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_64B - Ubuntu (push) Has been cancelled
Port repo release update / run-release-branch-updater (push) Has been cancelled
Verify Font License / verify-font-license (push) Has been cancelled
Verify Kconfig / verify-kconfig (push) Has been cancelled
Arduino Lint / lint (push) Has been cancelled
Build Examples with C++ Compiler / build-examples (push) Has been cancelled
MicroPython CI / Build esp32 port (push) Has been cancelled
MicroPython CI / Build rp2 port (push) Has been cancelled
MicroPython CI / Build stm32 port (push) Has been cancelled
MicroPython CI / Build unix port (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_NORMAL_8BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_SDL - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_VG_LITE - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_VG_LITE - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_VG_LITE - gcc - Windows (push) Has been cancelled
C/C++ CI / Build ESP IDF ESP32S3 (push) Has been cancelled
C/C++ CI / Run tests with 32bit build (push) Has been cancelled
C/C++ CI / Run tests with 64bit build (push) Has been cancelled
BOM Check / bom-check (push) Has been cancelled
Verify that lv_conf_internal.h matches repository state / verify-conf-internal (push) Has been cancelled
Verify the widget property name / verify-property-name (push) Has been cancelled
Verify code formatting / verify-formatting (push) Has been cancelled
Compare file templates with file names / template-check (push) Has been cancelled
Build docs / build-and-deploy (push) Has been cancelled
Test API JSON generator / Test API JSON (push) Has been cancelled
Check Makefile / Build using Makefile (push) Has been cancelled
Check Makefile for UEFI / Build using Makefile for UEFI (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_32B - Ubuntu (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_64B - Ubuntu (push) Has been cancelled
Port repo release update / run-release-branch-updater (push) Has been cancelled
Verify Font License / verify-font-license (push) Has been cancelled
Verify Kconfig / verify-kconfig (push) Has been cancelled
Co-authored-by: Gauthier Provost <gpr@interel.com>
This commit is contained in:
@@ -467,6 +467,7 @@ There are some Widget attributes which can be enabled/disabled by
|
|||||||
- :cpp:enumerator:`LV_OBJ_FLAG_SNAPPABLE` If scroll snap is enabled on the parent it can snap to this Widget
|
- :cpp:enumerator:`LV_OBJ_FLAG_SNAPPABLE` If scroll snap is enabled on the parent it can snap to this Widget
|
||||||
- :cpp:enumerator:`LV_OBJ_FLAG_PRESS_LOCK` Keep the Widget pressed even if the press slid from the Widget
|
- :cpp:enumerator:`LV_OBJ_FLAG_PRESS_LOCK` Keep the Widget pressed even if the press slid from the Widget
|
||||||
- :cpp:enumerator:`LV_OBJ_FLAG_EVENT_BUBBLE` Propagate the events to the parent as well
|
- :cpp:enumerator:`LV_OBJ_FLAG_EVENT_BUBBLE` Propagate the events to the parent as well
|
||||||
|
- :cpp:enumerator:`LV_OBJ_FLAG_EVENT_TRICKLE` Propagate the events to the children as well
|
||||||
- :cpp:enumerator:`LV_OBJ_FLAG_GESTURE_BUBBLE` Propagate the gestures to the parent
|
- :cpp:enumerator:`LV_OBJ_FLAG_GESTURE_BUBBLE` Propagate the gestures to the parent
|
||||||
- :cpp:enumerator:`LV_OBJ_FLAG_ADV_HITTEST` Allow performing more accurate hit (click) test. E.g. accounting for rounded corners
|
- :cpp:enumerator:`LV_OBJ_FLAG_ADV_HITTEST` Allow performing more accurate hit (click) test. E.g. accounting for rounded corners
|
||||||
- :cpp:enumerator:`LV_OBJ_FLAG_IGNORE_LAYOUT` Make the Widget not positioned by the layouts
|
- :cpp:enumerator:`LV_OBJ_FLAG_IGNORE_LAYOUT` Make the Widget not positioned by the layouts
|
||||||
|
|||||||
@@ -265,6 +265,24 @@ The *target* parameter of the event is always the current target Widget,
|
|||||||
not the original Widget. To get the original target call
|
not the original Widget. To get the original target call
|
||||||
:cpp:expr:`lv_event_get_target_obj(e)` in the event handler.
|
:cpp:expr:`lv_event_get_target_obj(e)` in the event handler.
|
||||||
|
|
||||||
|
.. _event_trickle:
|
||||||
|
|
||||||
|
Event Trickle
|
||||||
|
*************
|
||||||
|
|
||||||
|
Also known as Event Capturing, if :cpp:expr:`lv_obj_add_flag(widget, LV_OBJ_FLAG_EVENT_TRICKLE)`
|
||||||
|
is enabled all events will be sent to the Widget's children as well. This is the opposite of
|
||||||
|
event bubbling --- instead of propagating up the parent, events propagate down to the children.
|
||||||
|
|
||||||
|
The trickle mechanism only affects immediate children, not grandchildren or
|
||||||
|
deeper descendants. If you need events to propagate to deeper levels, each child
|
||||||
|
would need to have the :cpp:enumerator:`LV_OBJ_FLAG_EVENT_TRICKLE` flag enabled.
|
||||||
|
|
||||||
|
Like with bubbling, the *target* parameter of the event is always the current target Widget,
|
||||||
|
not the original Widget. To get the original target call
|
||||||
|
:cpp:expr:`lv_event_get_target_obj(e)` in the event handler.
|
||||||
|
|
||||||
|
|
||||||
.. _events_examples:
|
.. _events_examples:
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,11 @@ Event bubbling
|
|||||||
.. lv_example:: event/lv_example_event_bubble
|
.. lv_example:: event/lv_example_event_bubble
|
||||||
:language: c
|
:language: c
|
||||||
|
|
||||||
|
Event trickle-down
|
||||||
|
------------------
|
||||||
|
.. lv_example:: event/lv_example_event_trickle
|
||||||
|
:language: c
|
||||||
|
|
||||||
Draw event
|
Draw event
|
||||||
----------
|
----------
|
||||||
.. lv_example:: event/lv_example_event_draw
|
.. lv_example:: event/lv_example_event_draw
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ void lv_example_event_click(void);
|
|||||||
void lv_example_event_streak(void);
|
void lv_example_event_streak(void);
|
||||||
void lv_example_event_button(void);
|
void lv_example_event_button(void);
|
||||||
void lv_example_event_bubble(void);
|
void lv_example_event_bubble(void);
|
||||||
|
void lv_example_event_trickle(void);
|
||||||
void lv_example_event_draw(void);
|
void lv_example_event_draw(void);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#include "../lv_examples.h"
|
||||||
|
#if LV_BUILD_EXAMPLES && LV_USE_FLEX
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Demonstrate event trickle
|
||||||
|
*/
|
||||||
|
void lv_example_event_trickle(void)
|
||||||
|
{
|
||||||
|
lv_obj_t * cont = lv_obj_create(lv_screen_active());
|
||||||
|
lv_obj_set_size(cont, 290, 200);
|
||||||
|
lv_obj_center(cont);
|
||||||
|
lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_ROW_WRAP);
|
||||||
|
|
||||||
|
static lv_style_t style_black;
|
||||||
|
lv_style_init(&style_black);
|
||||||
|
lv_style_set_text_color(&style_black, lv_color_white());
|
||||||
|
lv_style_set_bg_color(&style_black, lv_color_black());
|
||||||
|
|
||||||
|
/*Enable event trickle-down on the container*/
|
||||||
|
lv_obj_add_flag(cont, LV_OBJ_FLAG_EVENT_TRICKLE);
|
||||||
|
|
||||||
|
lv_obj_add_style(cont, &style_black, LV_STATE_PRESSED);
|
||||||
|
|
||||||
|
uint32_t i;
|
||||||
|
for(i = 0; i < 9; i++) {
|
||||||
|
lv_obj_t * subcont = lv_obj_create(cont);
|
||||||
|
lv_obj_set_size(subcont, 70, 50);
|
||||||
|
|
||||||
|
lv_obj_t * label = lv_label_create(subcont);
|
||||||
|
lv_label_set_text_fmt(label, "%" LV_PRIu32, i);
|
||||||
|
|
||||||
|
/*Add style to the label when clicked*/
|
||||||
|
lv_obj_add_style(subcont, &style_black, LV_STATE_FOCUSED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -115,6 +115,7 @@ typedef enum {
|
|||||||
#if LV_USE_FLEX
|
#if LV_USE_FLEX
|
||||||
LV_OBJ_FLAG_FLEX_IN_NEW_TRACK = (1L << 21), /**< Start a new flex track on this item*/
|
LV_OBJ_FLAG_FLEX_IN_NEW_TRACK = (1L << 21), /**< Start a new flex track on this item*/
|
||||||
#endif
|
#endif
|
||||||
|
LV_OBJ_FLAG_EVENT_TRICKLE = (1L << 22), /**< Propagate the events to the children too*/
|
||||||
|
|
||||||
LV_OBJ_FLAG_LAYOUT_1 = (1L << 23), /**< Custom flag, free to use by layouts*/
|
LV_OBJ_FLAG_LAYOUT_1 = (1L << 23), /**< Custom flag, free to use by layouts*/
|
||||||
LV_OBJ_FLAG_LAYOUT_2 = (1L << 24), /**< Custom flag, free to use by layouts*/
|
LV_OBJ_FLAG_LAYOUT_2 = (1L << 24), /**< Custom flag, free to use by layouts*/
|
||||||
@@ -153,6 +154,7 @@ enum _lv_signed_prop_id_t {
|
|||||||
LV_PROPERTY_ID(OBJ, FLAG_SEND_DRAW_TASK_EVENTS, LV_PROPERTY_TYPE_INT, 19),
|
LV_PROPERTY_ID(OBJ, FLAG_SEND_DRAW_TASK_EVENTS, LV_PROPERTY_TYPE_INT, 19),
|
||||||
LV_PROPERTY_ID(OBJ, FLAG_OVERFLOW_VISIBLE, LV_PROPERTY_TYPE_INT, 20),
|
LV_PROPERTY_ID(OBJ, FLAG_OVERFLOW_VISIBLE, LV_PROPERTY_TYPE_INT, 20),
|
||||||
LV_PROPERTY_ID(OBJ, FLAG_FLEX_IN_NEW_TRACK, LV_PROPERTY_TYPE_INT, 21),
|
LV_PROPERTY_ID(OBJ, FLAG_FLEX_IN_NEW_TRACK, LV_PROPERTY_TYPE_INT, 21),
|
||||||
|
LV_PROPERTY_ID(OBJ, FLAG_EVENT_TRICKLE, LV_PROPERTY_TYPE_INT, 22),
|
||||||
LV_PROPERTY_ID(OBJ, FLAG_LAYOUT_1, LV_PROPERTY_TYPE_INT, 23),
|
LV_PROPERTY_ID(OBJ, FLAG_LAYOUT_1, LV_PROPERTY_TYPE_INT, 23),
|
||||||
LV_PROPERTY_ID(OBJ, FLAG_LAYOUT_2, LV_PROPERTY_TYPE_INT, 24),
|
LV_PROPERTY_ID(OBJ, FLAG_LAYOUT_2, LV_PROPERTY_TYPE_INT, 24),
|
||||||
LV_PROPERTY_ID(OBJ, FLAG_WIDGET_1, LV_PROPERTY_TYPE_INT, 25),
|
LV_PROPERTY_ID(OBJ, FLAG_WIDGET_1, LV_PROPERTY_TYPE_INT, 25),
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
**********************/
|
**********************/
|
||||||
static lv_result_t event_send_core(lv_event_t * e);
|
static lv_result_t event_send_core(lv_event_t * e);
|
||||||
static bool event_is_bubbled(lv_event_t * e);
|
static bool event_is_bubbled(lv_event_t * e);
|
||||||
|
static bool event_is_trickled(lv_event_t * e);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
@@ -60,6 +61,7 @@ lv_result_t lv_obj_send_event(lv_obj_t * obj, lv_event_code_t event_code, void *
|
|||||||
e.deleted = 0;
|
e.deleted = 0;
|
||||||
e.stop_bubbling = 0;
|
e.stop_bubbling = 0;
|
||||||
e.stop_processing = 0;
|
e.stop_processing = 0;
|
||||||
|
e.stop_trickling = 0;
|
||||||
|
|
||||||
lv_event_push(&e);
|
lv_event_push(&e);
|
||||||
|
|
||||||
@@ -378,6 +380,26 @@ static lv_result_t event_send_core(lv_event_t * e)
|
|||||||
res = event_send_core(e);
|
res = event_send_core(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*Trickle down to children if enabled*/
|
||||||
|
if(event_is_trickled(e)) {
|
||||||
|
uint32_t child_count = lv_obj_get_child_count(target);
|
||||||
|
|
||||||
|
/* we don't want the event to bubble up again when trickling down */
|
||||||
|
e->stop_bubbling = 1;
|
||||||
|
|
||||||
|
for(uint32_t i = 0; i < child_count && res == LV_RESULT_OK && !e->stop_processing; i++) {
|
||||||
|
lv_obj_t * child = lv_obj_get_child(target, i);
|
||||||
|
if(child) {
|
||||||
|
e->current_target = child;
|
||||||
|
res = event_send_core(e);
|
||||||
|
if(res != LV_RESULT_OK) {
|
||||||
|
LV_LOG_WARN("Trickle down event %d to child %p failed", e->code, (void *)child);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,3 +443,35 @@ static bool event_is_bubbled(lv_event_t * e)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool event_is_trickled(lv_event_t * e)
|
||||||
|
{
|
||||||
|
if(e->stop_trickling) return false;
|
||||||
|
|
||||||
|
/*Check other codes only if trickle is enabled*/
|
||||||
|
if(lv_obj_has_flag(e->current_target, LV_OBJ_FLAG_EVENT_TRICKLE) == false) return false;
|
||||||
|
|
||||||
|
switch(e->code) {
|
||||||
|
case LV_EVENT_HIT_TEST:
|
||||||
|
case LV_EVENT_COVER_CHECK:
|
||||||
|
case LV_EVENT_REFR_EXT_DRAW_SIZE:
|
||||||
|
case LV_EVENT_DRAW_MAIN_BEGIN:
|
||||||
|
case LV_EVENT_DRAW_MAIN:
|
||||||
|
case LV_EVENT_DRAW_MAIN_END:
|
||||||
|
case LV_EVENT_DRAW_POST_BEGIN:
|
||||||
|
case LV_EVENT_DRAW_POST:
|
||||||
|
case LV_EVENT_DRAW_POST_END:
|
||||||
|
case LV_EVENT_DRAW_TASK_ADDED:
|
||||||
|
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:
|
||||||
|
case LV_EVENT_GET_SELF_SIZE:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -229,6 +229,11 @@ void lv_event_stop_bubbling(lv_event_t * e)
|
|||||||
e->stop_bubbling = 1;
|
e->stop_bubbling = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lv_event_stop_trickling(lv_event_t * e)
|
||||||
|
{
|
||||||
|
e->stop_trickling = 1;
|
||||||
|
}
|
||||||
|
|
||||||
void lv_event_stop_processing(lv_event_t * e)
|
void lv_event_stop_processing(lv_event_t * e)
|
||||||
{
|
{
|
||||||
e->stop_processing = 1;
|
e->stop_processing = 1;
|
||||||
|
|||||||
@@ -195,6 +195,13 @@ void * lv_event_get_user_data(lv_event_t * e);
|
|||||||
*/
|
*/
|
||||||
void lv_event_stop_bubbling(lv_event_t * e);
|
void lv_event_stop_bubbling(lv_event_t * e);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop event from trickling down to children.
|
||||||
|
* This is only valid when called in the middle of an event processing chain.
|
||||||
|
* @param e pointer to the event descriptor
|
||||||
|
*/
|
||||||
|
void lv_event_stop_trickling(lv_event_t * e);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop processing this event.
|
* Stop processing this event.
|
||||||
* This is only valid when called in the middle of an event processing chain.
|
* This is only valid when called in the middle of an event processing chain.
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ struct _lv_event_t {
|
|||||||
uint8_t deleted : 1;
|
uint8_t deleted : 1;
|
||||||
uint8_t stop_processing : 1;
|
uint8_t stop_processing : 1;
|
||||||
uint8_t stop_bubbling : 1;
|
uint8_t stop_bubbling : 1;
|
||||||
|
uint8_t stop_trickling : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -116,6 +116,8 @@ void lv_xml_obj_apply(lv_xml_parser_state_t * state, const char ** attrs)
|
|||||||
else if(lv_streq("press_lock", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_PRESS_LOCK, lv_xml_to_bool(value));
|
else if(lv_streq("press_lock", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_PRESS_LOCK, lv_xml_to_bool(value));
|
||||||
else if(lv_streq("event_bubble", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_EVENT_BUBBLE,
|
else if(lv_streq("event_bubble", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_EVENT_BUBBLE,
|
||||||
lv_xml_to_bool(value));
|
lv_xml_to_bool(value));
|
||||||
|
else if(lv_streq("event_trickle", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_EVENT_TRICKLE,
|
||||||
|
lv_xml_to_bool(value));
|
||||||
else if(lv_streq("gesture_bubble", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_GESTURE_BUBBLE,
|
else if(lv_streq("gesture_bubble", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_GESTURE_BUBBLE,
|
||||||
lv_xml_to_bool(value));
|
lv_xml_to_bool(value));
|
||||||
else if(lv_streq("adv_hittest", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_ADV_HITTEST,
|
else if(lv_streq("adv_hittest", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_ADV_HITTEST,
|
||||||
@@ -646,6 +648,7 @@ static lv_obj_flag_t flag_to_enum(const char * txt)
|
|||||||
if(lv_streq("snappable", txt)) return LV_OBJ_FLAG_SNAPPABLE;
|
if(lv_streq("snappable", txt)) return LV_OBJ_FLAG_SNAPPABLE;
|
||||||
if(lv_streq("press_lock", txt)) return LV_OBJ_FLAG_PRESS_LOCK;
|
if(lv_streq("press_lock", txt)) return LV_OBJ_FLAG_PRESS_LOCK;
|
||||||
if(lv_streq("event_bubble", txt)) return LV_OBJ_FLAG_EVENT_BUBBLE;
|
if(lv_streq("event_bubble", txt)) return LV_OBJ_FLAG_EVENT_BUBBLE;
|
||||||
|
if(lv_streq("event_trickle", txt)) return LV_OBJ_FLAG_EVENT_TRICKLE;
|
||||||
if(lv_streq("gesture_bubble", txt)) return LV_OBJ_FLAG_GESTURE_BUBBLE;
|
if(lv_streq("gesture_bubble", txt)) return LV_OBJ_FLAG_GESTURE_BUBBLE;
|
||||||
if(lv_streq("adv_hittest", txt)) return LV_OBJ_FLAG_ADV_HITTEST;
|
if(lv_streq("adv_hittest", txt)) return LV_OBJ_FLAG_ADV_HITTEST;
|
||||||
if(lv_streq("ignore_layout", txt)) return LV_OBJ_FLAG_IGNORE_LAYOUT;
|
if(lv_streq("ignore_layout", txt)) return LV_OBJ_FLAG_IGNORE_LAYOUT;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
* Generated code from properties.py
|
* Generated code from properties.py
|
||||||
*/
|
*/
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
const lv_property_name_t lv_obj_property_names[73] = {
|
const lv_property_name_t lv_obj_property_names[74] = {
|
||||||
{"align", LV_PROPERTY_OBJ_ALIGN,},
|
{"align", LV_PROPERTY_OBJ_ALIGN,},
|
||||||
{"child_count", LV_PROPERTY_OBJ_CHILD_COUNT,},
|
{"child_count", LV_PROPERTY_OBJ_CHILD_COUNT,},
|
||||||
{"content_height", LV_PROPERTY_OBJ_CONTENT_HEIGHT,},
|
{"content_height", LV_PROPERTY_OBJ_CONTENT_HEIGHT,},
|
||||||
@@ -28,6 +28,7 @@ const lv_property_name_t lv_obj_property_names[73] = {
|
|||||||
{"flag_clickable", LV_PROPERTY_OBJ_FLAG_CLICKABLE,},
|
{"flag_clickable", LV_PROPERTY_OBJ_FLAG_CLICKABLE,},
|
||||||
{"flag_end", LV_PROPERTY_OBJ_FLAG_END,},
|
{"flag_end", LV_PROPERTY_OBJ_FLAG_END,},
|
||||||
{"flag_event_bubble", LV_PROPERTY_OBJ_FLAG_EVENT_BUBBLE,},
|
{"flag_event_bubble", LV_PROPERTY_OBJ_FLAG_EVENT_BUBBLE,},
|
||||||
|
{"flag_event_trickle", LV_PROPERTY_OBJ_FLAG_EVENT_TRICKLE,},
|
||||||
{"flag_flex_in_new_track", LV_PROPERTY_OBJ_FLAG_FLEX_IN_NEW_TRACK,},
|
{"flag_flex_in_new_track", LV_PROPERTY_OBJ_FLAG_FLEX_IN_NEW_TRACK,},
|
||||||
{"flag_floating", LV_PROPERTY_OBJ_FLAG_FLOATING,},
|
{"flag_floating", LV_PROPERTY_OBJ_FLAG_FLOATING,},
|
||||||
{"flag_gesture_bubble", LV_PROPERTY_OBJ_FLAG_GESTURE_BUBBLE,},
|
{"flag_gesture_bubble", LV_PROPERTY_OBJ_FLAG_GESTURE_BUBBLE,},
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
extern const lv_property_name_t lv_image_property_names[11];
|
extern const lv_property_name_t lv_image_property_names[11];
|
||||||
extern const lv_property_name_t lv_keyboard_property_names[4];
|
extern const lv_property_name_t lv_keyboard_property_names[4];
|
||||||
extern const lv_property_name_t lv_label_property_names[4];
|
extern const lv_property_name_t lv_label_property_names[4];
|
||||||
extern const lv_property_name_t lv_obj_property_names[73];
|
extern const lv_property_name_t lv_obj_property_names[74];
|
||||||
extern const lv_property_name_t lv_roller_property_names[3];
|
extern const lv_property_name_t lv_roller_property_names[3];
|
||||||
extern const lv_property_name_t lv_slider_property_names[8];
|
extern const lv_property_name_t lv_slider_property_names[8];
|
||||||
extern const lv_property_name_t lv_style_property_names[120];
|
extern const lv_property_name_t lv_style_property_names[120];
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
#if LV_BUILD_TEST
|
||||||
|
#include "../lvgl.h"
|
||||||
|
#include "../../lvgl_private.h"
|
||||||
|
|
||||||
|
#include "unity/unity.h"
|
||||||
|
|
||||||
|
static uint32_t event_count = 0;
|
||||||
|
static lv_obj_t * last_target = NULL;
|
||||||
|
|
||||||
|
static void test_event_cb(lv_event_t * e)
|
||||||
|
{
|
||||||
|
event_count++;
|
||||||
|
last_target = lv_event_get_current_target_obj(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_event_trickle_basic(void)
|
||||||
|
{
|
||||||
|
/*Create a parent container*/
|
||||||
|
lv_obj_t * parent = lv_obj_create(lv_screen_active());
|
||||||
|
lv_obj_add_flag(parent, LV_OBJ_FLAG_EVENT_TRICKLE);
|
||||||
|
lv_obj_add_event_cb(parent, test_event_cb, LV_EVENT_CLICKED, NULL);
|
||||||
|
|
||||||
|
/*Create children*/
|
||||||
|
lv_obj_t * child1 = lv_obj_create(parent);
|
||||||
|
lv_obj_add_event_cb(child1, test_event_cb, LV_EVENT_CLICKED, NULL);
|
||||||
|
|
||||||
|
lv_obj_t * child2 = lv_obj_create(parent);
|
||||||
|
lv_obj_add_event_cb(child2, test_event_cb, LV_EVENT_CLICKED, NULL);
|
||||||
|
|
||||||
|
/*Reset counters*/
|
||||||
|
event_count = 0;
|
||||||
|
last_target = NULL;
|
||||||
|
|
||||||
|
/*Send event to parent - should trickle down to children*/
|
||||||
|
lv_obj_send_event(parent, LV_EVENT_CLICKED, NULL);
|
||||||
|
|
||||||
|
/*Should have received 3 events: parent + 2 children*/
|
||||||
|
TEST_ASSERT_EQUAL(3, event_count);
|
||||||
|
|
||||||
|
/*Clean up*/
|
||||||
|
lv_obj_delete(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_event_trickle_stop(void)
|
||||||
|
{
|
||||||
|
/*Create a parent container*/
|
||||||
|
lv_obj_t * parent = lv_obj_create(lv_screen_active());
|
||||||
|
lv_obj_add_flag(parent, LV_OBJ_FLAG_EVENT_TRICKLE);
|
||||||
|
|
||||||
|
/*Add event handler that stops trickle down*/
|
||||||
|
lv_obj_add_event_cb(parent, test_event_cb, LV_EVENT_CLICKED, NULL);
|
||||||
|
lv_obj_add_event_cb(parent, (lv_event_cb_t)lv_event_stop_trickling, LV_EVENT_CLICKED, NULL);
|
||||||
|
|
||||||
|
/*Create children*/
|
||||||
|
lv_obj_t * child1 = lv_obj_create(parent);
|
||||||
|
lv_obj_add_event_cb(child1, test_event_cb, LV_EVENT_CLICKED, NULL);
|
||||||
|
|
||||||
|
/*Reset counters*/
|
||||||
|
event_count = 0;
|
||||||
|
last_target = NULL;
|
||||||
|
|
||||||
|
/*Send event to parent - should NOT trickle down due to stop*/
|
||||||
|
lv_obj_send_event(parent, LV_EVENT_CLICKED, NULL);
|
||||||
|
|
||||||
|
/*Should have received only 1 event: parent only*/
|
||||||
|
TEST_ASSERT_EQUAL(1, event_count); /* parent event handler + stop handler */
|
||||||
|
|
||||||
|
/*Clean up*/
|
||||||
|
lv_obj_delete(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_event_trickle_disabled(void)
|
||||||
|
{
|
||||||
|
/*Create a parent container WITHOUT trickle down flag*/
|
||||||
|
lv_obj_t * parent = lv_obj_create(lv_screen_active());
|
||||||
|
lv_obj_add_event_cb(parent, test_event_cb, LV_EVENT_CLICKED, NULL);
|
||||||
|
|
||||||
|
/*Create children*/
|
||||||
|
lv_obj_t * child1 = lv_obj_create(parent);
|
||||||
|
lv_obj_add_event_cb(child1, test_event_cb, LV_EVENT_CLICKED, NULL);
|
||||||
|
|
||||||
|
/*Reset counters*/
|
||||||
|
event_count = 0;
|
||||||
|
last_target = NULL;
|
||||||
|
|
||||||
|
/*Send event to parent - should NOT trickle down*/
|
||||||
|
lv_obj_send_event(parent, LV_EVENT_CLICKED, NULL);
|
||||||
|
|
||||||
|
/*Should have received only 1 event: parent only*/
|
||||||
|
TEST_ASSERT_EQUAL(1, event_count);
|
||||||
|
|
||||||
|
/*Clean up*/
|
||||||
|
lv_obj_delete(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -343,6 +343,7 @@ Example
|
|||||||
<prop name="snappable" type="flag:flag lv_obj_flag"/>
|
<prop name="snappable" type="flag:flag lv_obj_flag"/>
|
||||||
<prop name="press_lock" type="flag:flag lv_obj_flag"/>
|
<prop name="press_lock" type="flag:flag lv_obj_flag"/>
|
||||||
<prop name="event_bubble" type="flag:flag lv_obj_flag"/>
|
<prop name="event_bubble" type="flag:flag lv_obj_flag"/>
|
||||||
|
<prop name="event_trickle" type="flag:flag lv_obj_flag"/>
|
||||||
<prop name="gesture_bubble" type="flag:flag lv_obj_flag"/>
|
<prop name="gesture_bubble" type="flag:flag lv_obj_flag"/>
|
||||||
<prop name="adv_hittest" type="flag:flag lv_obj_flag"/>
|
<prop name="adv_hittest" type="flag:flag lv_obj_flag"/>
|
||||||
<prop name="ignore_layout" type="flag:flag lv_obj_flag"/>
|
<prop name="ignore_layout" type="flag:flag lv_obj_flag"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user