feat(obj): add back support for user flags (#9711)

This commit is contained in:
Gabor Kiss-Vamosi
2026-02-12 16:00:41 +01:00
committed by GitHub
parent 6ed7ba7273
commit 724fe880ee
8 changed files with 55 additions and 25 deletions
@@ -43,7 +43,7 @@ void lv_example_checkbox_2(void)
lv_obj_add_event_cb(obj, event_cb, LV_EVENT_VALUE_CHANGED, NULL);
/*This makes the checkboxes act as radio buttons*/
lv_obj_add_flag(obj, LV_OBJ_FLAG_RADIO_BUTTON);
lv_obj_set_radio_button(obj, true);
lv_obj_add_style(obj, &style_radio, LV_PART_INDICATOR);
lv_obj_add_style(obj, &style_radio_chk, LV_PART_INDICATOR | LV_STATE_CHECKED);
+16 -4
View File
@@ -355,6 +355,12 @@ void lv_obj_set_state(lv_obj_t * obj, lv_state_t state, bool v)
else lv_obj_remove_state(obj, state);
}
void lv_obj_set_radio_button(lv_obj_t * obj, bool en)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
obj->radio_button = en;
}
/*=======================
* Getter functions
*======================*/
@@ -387,6 +393,12 @@ bool lv_obj_has_state(const lv_obj_t * obj, lv_state_t state)
return !!(obj->state & state);
}
bool lv_obj_is_radio_button(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
return obj->radio_button;
}
lv_group_t * lv_obj_get_group(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
@@ -862,7 +874,7 @@ static void lv_obj_event(const lv_obj_class_t * class_p, lv_event_t * e)
lv_obj_add_state(obj, LV_STATE_CHECKED);
}
/*Radio buttons can't be checked off directly*/
else if(!lv_obj_has_flag(obj, LV_OBJ_FLAG_RADIO_BUTTON)) {
else if(!lv_obj_is_radio_button(obj)) {
lv_obj_remove_state(obj, LV_STATE_CHECKED);
}
if(was_checked != lv_obj_has_state(obj, LV_STATE_CHECKED)) {
@@ -872,7 +884,7 @@ static void lv_obj_event(const lv_obj_class_t * class_p, lv_event_t * e)
}
}
else if(code == LV_EVENT_VALUE_CHANGED) {
if(lv_obj_has_flag(obj, LV_OBJ_FLAG_RADIO_BUTTON) && lv_obj_has_state(obj, LV_STATE_CHECKED)) {
if(lv_obj_is_radio_button(obj) && lv_obj_has_state(obj, LV_STATE_CHECKED)) {
lv_obj_t * parent = lv_obj_get_parent(obj);
if(parent) {
uint32_t child_cnt = lv_obj_get_child_count(parent);
@@ -881,7 +893,7 @@ static void lv_obj_event(const lv_obj_class_t * class_p, lv_event_t * e)
lv_obj_t * sibling = lv_obj_get_child(parent, i);
if(obj == sibling) continue;
if(lv_obj_has_flag(sibling, LV_OBJ_FLAG_RADIO_BUTTON) && lv_obj_has_state(sibling, LV_STATE_CHECKED)) {
if(lv_obj_is_radio_button(sibling) && lv_obj_has_state(sibling, LV_STATE_CHECKED)) {
lv_obj_remove_state(sibling, LV_STATE_CHECKED);
lv_result_t res = lv_obj_send_event(sibling, LV_EVENT_VALUE_CHANGED, NULL);
if(res != LV_RESULT_OK) return;
@@ -909,7 +921,7 @@ static void lv_obj_event(const lv_obj_class_t * class_p, lv_event_t * e)
}
else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) {
/*Radio buttons can't be checked off directly*/
if(!lv_obj_has_flag(obj, LV_OBJ_FLAG_RADIO_BUTTON)) {
if(!lv_obj_is_radio_button(obj)) {
lv_obj_remove_state(obj, LV_STATE_CHECKED);
}
}
+30 -15
View File
@@ -70,18 +70,19 @@ typedef enum {
LV_OBJ_FLAG_OVERFLOW_VISIBLE = (1u << 20),/**< Do not clip the children to the parent's ext draw size*/
LV_OBJ_FLAG_EVENT_TRICKLE = (1u << 21), /**< Propagate the events to the children too*/
LV_OBJ_FLAG_STATE_TRICKLE = (1u << 22), /**< Propagate the states to the children too*/
LV_OBJ_FLAG_RADIO_BUTTON = (1u << 23), /**< Allow only one RADIO_BUTTON sibling to be checked*/
LV_OBJ_FLAG_LAYOUT_1 = (1u << 24), /**< Custom flag, free to use by layouts*/
LV_OBJ_FLAG_LAYOUT_2 = (1u << 25), /**< Custom flag, free to use by layouts*/
LV_OBJ_FLAG_LAYOUT_1 = (1u << 23), /**< Custom flag, free to use by layouts*/
LV_OBJ_FLAG_LAYOUT_2 = (1u << 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 = (1u << 26), /**< Custom flag, free to use by widget*/
LV_OBJ_FLAG_WIDGET_2 = (1u << 27), /**< Custom flag, free to use by widget*/
LV_OBJ_FLAG_USER_1 = (1u << 28), /**< Custom flag, free to use by user*/
LV_OBJ_FLAG_USER_2 = (1u << 29), /**< Custom flag, free to use by user*/
LV_OBJ_FLAG_WIDGET_1 = (1u << 25), /**< Custom flag, free to use by widget*/
LV_OBJ_FLAG_WIDGET_2 = (1u << 26), /**< Custom flag, free to use by widget*/
LV_OBJ_FLAG_USER_1 = (1u << 27), /**< Custom flag, free to use by user*/
LV_OBJ_FLAG_USER_2 = (1u << 28), /**< Custom flag, free to use by user*/
LV_OBJ_FLAG_USER_3 = (1u << 29), /**< Custom flag, free to use by user*/
LV_OBJ_FLAG_USER_4 = (1u << 30), /**< Custom flag, free to use by user*/
} lv_obj_flag_t;
#if LV_USE_OBJ_PROPERTY
@@ -111,14 +112,15 @@ enum _lv_signed_prop_id_t {
LV_PROPERTY_ID(OBJ, FLAG_OVERFLOW_VISIBLE, LV_PROPERTY_TYPE_INT, 20),
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_RADIO_BUTTON, LV_PROPERTY_TYPE_INT, 23),
LV_PROPERTY_ID(OBJ, FLAG_LAYOUT_1, LV_PROPERTY_TYPE_INT, 24),
LV_PROPERTY_ID(OBJ, FLAG_LAYOUT_2, LV_PROPERTY_TYPE_INT, 25),
LV_PROPERTY_ID(OBJ, FLAG_FLEX_IN_NEW_TRACK, LV_PROPERTY_TYPE_INT, 24), /*Mapped to FLAG_LAYOUT_1*/
LV_PROPERTY_ID(OBJ, FLAG_WIDGET_1, LV_PROPERTY_TYPE_INT, 26),
LV_PROPERTY_ID(OBJ, FLAG_WIDGET_2, LV_PROPERTY_TYPE_INT, 27),
LV_PROPERTY_ID(OBJ, FLAG_USER_1, LV_PROPERTY_TYPE_INT, 28),
LV_PROPERTY_ID(OBJ, FLAG_USER_2, LV_PROPERTY_TYPE_INT, 29),
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),
LV_PROPERTY_ID(OBJ, FLAG_USER_2, LV_PROPERTY_TYPE_INT, 28),
LV_PROPERTY_ID(OBJ, FLAG_USER_3, LV_PROPERTY_TYPE_INT, 29),
LV_PROPERTY_ID(OBJ, FLAG_USER_4, LV_PROPERTY_TYPE_INT, 30),
LV_PROPERTY_ID(OBJ, FLAG_END, LV_PROPERTY_TYPE_INT, 30),
LV_PROPERTY_ID(OBJ, STATE_START, LV_PROPERTY_TYPE_INT, 31),
@@ -245,6 +247,13 @@ void lv_obj_set_state(lv_obj_t * obj, lv_state_t state, bool v);
*/
void lv_obj_set_user_data(lv_obj_t * obj, void * user_data);
/** Allow only one RADIO_BUTTON sibling to be checked
* @param obj pointer to a widget
* @param en enable or disable radio button behavior
*/
void lv_obj_set_radio_button(lv_obj_t * obj, bool en);
/*=======================
* Getter functions
*======================*/
@@ -280,6 +289,12 @@ lv_state_t lv_obj_get_state(const lv_obj_t * obj);
*/
bool lv_obj_has_state(const lv_obj_t * obj, lv_state_t state);
/** Get whether the object is a radio button
* @param obj pointer to a widget
* @return true if radio button behavior is enabled
*/
bool lv_obj_is_radio_button(const lv_obj_t * obj);
/**
* Get the group of the object
* @param obj pointer to an object
+1
View File
@@ -85,6 +85,7 @@ struct _lv_obj_t {
uint16_t h_ignore_size : 1; /* ignore this obj when calculating content height of parent */
uint16_t w_ignore_size : 1; /* ignore this obj when calculating content width of parent */
uint16_t is_deleting : 1;
uint16_t radio_button : 1; /**< Allow only one RADIO_BUTTON sibling to be checked*/
/** The widget is rendered at least once already.
* It's used to skip initial animations and transitions. */
+3 -2
View File
@@ -14,7 +14,7 @@
* Generated code from properties.py
*/
/* *INDENT-OFF* */
const lv_property_name_t lv_obj_property_names[75] = {
const lv_property_name_t lv_obj_property_names[76] = {
{"align", LV_PROPERTY_OBJ_ALIGN,},
{"child_count", LV_PROPERTY_OBJ_CHILD_COUNT,},
{"content_height", LV_PROPERTY_OBJ_CONTENT_HEIGHT,},
@@ -38,7 +38,6 @@ const lv_property_name_t lv_obj_property_names[75] = {
{"flag_layout_2", LV_PROPERTY_OBJ_FLAG_LAYOUT_2,},
{"flag_overflow_visible", LV_PROPERTY_OBJ_FLAG_OVERFLOW_VISIBLE,},
{"flag_press_lock", LV_PROPERTY_OBJ_FLAG_PRESS_LOCK,},
{"flag_radio_button", LV_PROPERTY_OBJ_FLAG_RADIO_BUTTON,},
{"flag_scroll_chain_hor", LV_PROPERTY_OBJ_FLAG_SCROLL_CHAIN_HOR,},
{"flag_scroll_chain_ver", LV_PROPERTY_OBJ_FLAG_SCROLL_CHAIN_VER,},
{"flag_scroll_elastic", LV_PROPERTY_OBJ_FLAG_SCROLL_ELASTIC,},
@@ -53,6 +52,8 @@ const lv_property_name_t lv_obj_property_names[75] = {
{"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,},
{"flag_user_4", LV_PROPERTY_OBJ_FLAG_USER_4,},
{"flag_widget_1", LV_PROPERTY_OBJ_FLAG_WIDGET_1,},
{"flag_widget_2", LV_PROPERTY_OBJ_FLAG_WIDGET_2,},
{"h", LV_PROPERTY_OBJ_H,},
+1 -1
View File
@@ -23,7 +23,7 @@
extern const lv_property_name_t lv_led_property_names[2];
extern const lv_property_name_t lv_line_property_names[1];
extern const lv_property_name_t lv_menu_property_names[2];
extern const lv_property_name_t lv_obj_property_names[75];
extern const lv_property_name_t lv_obj_property_names[76];
extern const lv_property_name_t lv_roller_property_names[3];
extern const lv_property_name_t lv_scale_property_names[8];
extern const lv_property_name_t lv_slider_property_names[8];
@@ -159,7 +159,7 @@ void test_obj_flag_radio_button(void)
for(uint32_t i = 0; i < 5; i++) {
cb[i] = lv_checkbox_create(scr);
lv_obj_set_y(cb[i], i * 50);
lv_obj_add_flag(cb[i], LV_OBJ_FLAG_RADIO_BUTTON);
lv_obj_set_radio_button(cb[i], true);
lv_group_add_obj(g, cb[i]);
lv_obj_add_event_cb(cb[i], event_cb, LV_EVENT_VALUE_CHANGED, &called[i]);
called[i] = 0;
@@ -147,7 +147,6 @@ void test_obj_property_flag(void)
{ LV_OBJ_FLAG_FLOATING, LV_PROPERTY_OBJ_FLAG_FLOATING },
{ LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS, LV_PROPERTY_OBJ_FLAG_SEND_DRAW_TASK_EVENTS },
{ LV_OBJ_FLAG_OVERFLOW_VISIBLE, LV_PROPERTY_OBJ_FLAG_OVERFLOW_VISIBLE },
{ LV_OBJ_FLAG_RADIO_BUTTON, LV_PROPERTY_OBJ_FLAG_RADIO_BUTTON },
{ LV_OBJ_FLAG_FLEX_IN_NEW_TRACK, LV_PROPERTY_OBJ_FLAG_FLEX_IN_NEW_TRACK },
{ LV_OBJ_FLAG_LAYOUT_1, LV_PROPERTY_OBJ_FLAG_LAYOUT_1 },
{ LV_OBJ_FLAG_LAYOUT_2, LV_PROPERTY_OBJ_FLAG_LAYOUT_2 },
@@ -155,6 +154,8 @@ void test_obj_property_flag(void)
{ LV_OBJ_FLAG_WIDGET_2, LV_PROPERTY_OBJ_FLAG_WIDGET_2 },
{ LV_OBJ_FLAG_USER_1, LV_PROPERTY_OBJ_FLAG_USER_1 },
{ LV_OBJ_FLAG_USER_2, LV_PROPERTY_OBJ_FLAG_USER_2 },
{ LV_OBJ_FLAG_USER_3, LV_PROPERTY_OBJ_FLAG_USER_3 },
{ LV_OBJ_FLAG_USER_4, LV_PROPERTY_OBJ_FLAG_USER_4 },
};
lv_obj_t * obj = lv_obj_create(lv_screen_active());