diff --git a/docs/src/details/common-widget-features/basics.rst b/docs/src/details/common-widget-features/basics.rst index b2143368ff..dbdd70d7c4 100644 --- a/docs/src/details/common-widget-features/basics.rst +++ b/docs/src/details/common-widget-features/basics.rst @@ -468,6 +468,7 @@ There are some Widget attributes which can be enabled/disabled by - :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_TRICKLE` Propagate the events to the children as well +- :cpp:enumerator:`LV_OBJ_FLAG_STATE_TRICKLE` Propagate the state changes to the children as well - :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_IGNORE_LAYOUT` Make the Widget not positioned by the layouts diff --git a/examples/event/lv_example_event_trickle.c b/examples/event/lv_example_event_trickle.c index 285aa4c384..954f5d56c6 100644 --- a/examples/event/lv_example_event_trickle.c +++ b/examples/event/lv_example_event_trickle.c @@ -25,7 +25,6 @@ void lv_example_event_trickle(void) 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); @@ -34,4 +33,4 @@ void lv_example_event_trickle(void) } } -#endif \ No newline at end of file +#endif diff --git a/src/core/lv_obj.c b/src/core/lv_obj.c index 3190832fa6..a6a8274e8e 100644 --- a/src/core/lv_obj.c +++ b/src/core/lv_obj.c @@ -60,6 +60,8 @@ static void draw_scrollbar(lv_obj_t * obj, lv_layer_t * layer); static lv_result_t scrollbar_init_draw_dsc(lv_obj_t * obj, lv_draw_rect_dsc_t * dsc); static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_find); static void update_obj_state(lv_obj_t * obj, lv_state_t new_state); +static void lv_obj_children_add_state(lv_obj_t * obj, lv_state_t state); +static void lv_obj_children_remove_state(lv_obj_t * obj, lv_state_t state); static void null_on_delete_cb(lv_event_t * e); static void screen_load_on_trigger_event_cb(lv_event_t * e); static void screen_create_on_trigger_event_cb(lv_event_t * e); @@ -322,6 +324,9 @@ void lv_obj_add_state(lv_obj_t * obj, lv_state_t state) lv_state_t new_state = obj->state | state; if(obj->state != new_state) { update_obj_state(obj, new_state); + if(lv_obj_has_flag(obj, LV_OBJ_FLAG_STATE_TRICKLE)) { + lv_obj_children_add_state(obj, state); + } } } @@ -332,6 +337,9 @@ void lv_obj_remove_state(lv_obj_t * obj, lv_state_t state) lv_state_t new_state = obj->state & (~state); if(obj->state != new_state) { update_obj_state(obj, new_state); + if(lv_obj_has_flag(obj, LV_OBJ_FLAG_STATE_TRICKLE)) { + lv_obj_children_remove_state(obj, state); + } } } @@ -1031,6 +1039,40 @@ static void update_obj_state(lv_obj_t * obj, lv_state_t new_state) } } +/** + * Apply the state to the children of the object + * @param obj pointer to an object + * @param state the state to apply + */ +static void lv_obj_children_add_state(lv_obj_t * obj, lv_state_t state) +{ + uint32_t child_count = lv_obj_get_child_count(obj); + + for(uint32_t i = 0; i < child_count; i++) { + lv_obj_t * child = lv_obj_get_child(obj, i); + if(child) { + lv_obj_add_state(child, state); + } + } +} + +/** + * Remove the state from the children of the object + * @param obj pointer to an object + * @param state the state to remove + */ +static void lv_obj_children_remove_state(lv_obj_t * obj, lv_state_t state) +{ + uint32_t child_count = lv_obj_get_child_count(obj); + + for(uint32_t i = 0; i < child_count; i++) { + lv_obj_t * child = lv_obj_get_child(obj, i); + if(child) { + lv_obj_remove_state(child, state); + } + } +} + static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_find) { /*Check all children of `parent`*/ diff --git a/src/core/lv_obj.h b/src/core/lv_obj.h index 2809930d32..8412017e80 100644 --- a/src/core/lv_obj.h +++ b/src/core/lv_obj.h @@ -112,13 +112,14 @@ typedef enum { LV_OBJ_FLAG_FLOATING = (1L << 18), /**< Do not scroll the object when the parent scrolls and ignore layout*/ LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS = (1L << 19), /**< Send `LV_EVENT_DRAW_TASK_ADDED` events*/ LV_OBJ_FLAG_OVERFLOW_VISIBLE = (1L << 20),/**< Do not clip the children to the parent's ext draw size*/ -#if LV_USE_FLEX - LV_OBJ_FLAG_FLEX_IN_NEW_TRACK = (1L << 21), /**< Start a new flex track on this item*/ -#endif - LV_OBJ_FLAG_EVENT_TRICKLE = (1L << 22), /**< Propagate the events to the children too*/ + LV_OBJ_FLAG_EVENT_TRICKLE = (1L << 21), /**< Propagate the events to the children too*/ + LV_OBJ_FLAG_STATE_TRICKLE = (1L << 22), /**< Propagate the states to the children too*/ 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*/ +#if LV_USE_FLEX + LV_OBJ_FLAG_FLEX_IN_NEW_TRACK = LV_OBJ_FLAG_LAYOUT_1, /**< Start a new flex track on this item*/ +#endif LV_OBJ_FLAG_WIDGET_1 = (1L << 25), /**< Custom flag, free to use by widget*/ LV_OBJ_FLAG_WIDGET_2 = (1L << 26), /**< Custom flag, free to use by widget*/ @@ -153,10 +154,11 @@ enum _lv_signed_prop_id_t { LV_PROPERTY_ID(OBJ, FLAG_FLOATING, LV_PROPERTY_TYPE_INT, 18), 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_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_EVENT_TRICKLE, LV_PROPERTY_TYPE_INT, 21), + LV_PROPERTY_ID(OBJ, FLAG_STATE_TRICKLE, LV_PROPERTY_TYPE_INT, 22), 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_FLEX_IN_NEW_TRACK, LV_PROPERTY_TYPE_INT, 23), /*Mapped to FLAG_LAYOUT_1*/ LV_PROPERTY_ID(OBJ, FLAG_WIDGET_1, LV_PROPERTY_TYPE_INT, 25), LV_PROPERTY_ID(OBJ, FLAG_WIDGET_2, LV_PROPERTY_TYPE_INT, 26), LV_PROPERTY_ID(OBJ, FLAG_USER_1, LV_PROPERTY_TYPE_INT, 27), diff --git a/src/others/xml/parsers/lv_xml_obj_parser.c b/src/others/xml/parsers/lv_xml_obj_parser.c index 8b4ca0aada..5fe8ab64e5 100644 --- a/src/others/xml/parsers/lv_xml_obj_parser.c +++ b/src/others/xml/parsers/lv_xml_obj_parser.c @@ -118,6 +118,8 @@ void lv_xml_obj_apply(lv_xml_parser_state_t * state, const char ** attrs) 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("state_trickle", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_STATE_TRICKLE, + lv_xml_to_bool(value)); else if(lv_streq("gesture_bubble", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_GESTURE_BUBBLE, lv_xml_to_bool(value)); else if(lv_streq("adv_hittest", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_ADV_HITTEST, @@ -649,6 +651,7 @@ static lv_obj_flag_t flag_to_enum(const char * txt) 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_trickle", txt)) return LV_OBJ_FLAG_EVENT_TRICKLE; + if(lv_streq("state_trickle", txt)) return LV_OBJ_FLAG_STATE_TRICKLE; 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("ignore_layout", txt)) return LV_OBJ_FLAG_IGNORE_LAYOUT; diff --git a/src/widgets/property/lv_obj_properties.c b/src/widgets/property/lv_obj_properties.c index f62d064f1d..c6572dfc0d 100644 --- a/src/widgets/property/lv_obj_properties.c +++ b/src/widgets/property/lv_obj_properties.c @@ -14,7 +14,7 @@ * Generated code from properties.py */ /* *INDENT-OFF* */ -const lv_property_name_t lv_obj_property_names[74] = { +const lv_property_name_t lv_obj_property_names[75] = { {"align", LV_PROPERTY_OBJ_ALIGN,}, {"child_count", LV_PROPERTY_OBJ_CHILD_COUNT,}, {"content_height", LV_PROPERTY_OBJ_CONTENT_HEIGHT,}, @@ -49,6 +49,7 @@ const lv_property_name_t lv_obj_property_names[74] = { {"flag_send_draw_task_events", LV_PROPERTY_OBJ_FLAG_SEND_DRAW_TASK_EVENTS,}, {"flag_snappable", LV_PROPERTY_OBJ_FLAG_SNAPPABLE,}, {"flag_start", LV_PROPERTY_OBJ_FLAG_START,}, + {"flag_state_trickle", LV_PROPERTY_OBJ_FLAG_STATE_TRICKLE,}, {"flag_user_1", LV_PROPERTY_OBJ_FLAG_USER_1,}, {"flag_user_2", LV_PROPERTY_OBJ_FLAG_USER_2,}, {"flag_user_3", LV_PROPERTY_OBJ_FLAG_USER_3,}, diff --git a/src/widgets/property/lv_obj_property_names.h b/src/widgets/property/lv_obj_property_names.h index e9a9130b64..8f76901d15 100644 --- a/src/widgets/property/lv_obj_property_names.h +++ b/src/widgets/property/lv_obj_property_names.h @@ -15,7 +15,7 @@ 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_label_property_names[4]; - extern const lv_property_name_t lv_obj_property_names[74]; + extern const lv_property_name_t lv_obj_property_names[75]; 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_style_property_names[120]; diff --git a/xmls/lv_obj.xml b/xmls/lv_obj.xml index d5bbf84f21..8895707e97 100644 --- a/xmls/lv_obj.xml +++ b/xmls/lv_obj.xml @@ -344,6 +344,7 @@ Example +