mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-20 12:32:18 +08:00
feat(obj): add LV_OBJ_FLAG_RADIO_BUTTON to easily create radio buttons (#9328)
This commit is contained in:
committed by
GitHub
parent
d2bbbcc854
commit
721029ac22
@@ -37,6 +37,7 @@ The available flags are:
|
||||
- :cpp:enumerator:`LV_OBJ_FLAG_FLOATING`: Do not scroll with the parent and ignore layout.
|
||||
- :cpp:enumerator:`LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS`: Enable sending ``LV_EVENT_DRAW_TASK_ADDED`` events.
|
||||
- :cpp:enumerator:`LV_OBJ_FLAG_OVERFLOW_VISIBLE`: Allow children to overflow outside the widget's bounds.
|
||||
- :cpp:enumerator:`LV_OBJ_FLAG_RADIO_BUTTON`: Allow only one ``RADIO_BUTTON`` sibling to be checked.
|
||||
- :cpp:enumerator:`LV_OBJ_FLAG_FLEX_IN_NEW_TRACK`: Start a new flex track on this item.
|
||||
- :cpp:enumerator:`LV_OBJ_FLAG_LAYOUT_1`: Custom flag, free to use by layouts.
|
||||
- :cpp:enumerator:`LV_OBJ_FLAG_LAYOUT_2`: Custom flag, free to use by layouts.
|
||||
@@ -44,8 +45,6 @@ The available flags are:
|
||||
- :cpp:enumerator:`LV_OBJ_FLAG_WIDGET_2`: Custom flag, free to use by widgets.
|
||||
- :cpp:enumerator:`LV_OBJ_FLAG_USER_1`: Custom flag, free to use by the user.
|
||||
- :cpp:enumerator:`LV_OBJ_FLAG_USER_2`: Custom flag, free to use by the user.
|
||||
- :cpp:enumerator:`LV_OBJ_FLAG_USER_3`: Custom flag, free to use by the user.
|
||||
- :cpp:enumerator:`LV_OBJ_FLAG_USER_4`: Custom flag, free to use by the user.
|
||||
|
||||
Some examples:
|
||||
|
||||
|
||||
@@ -3,34 +3,16 @@
|
||||
|
||||
static lv_style_t style_radio;
|
||||
static lv_style_t style_radio_chk;
|
||||
static int32_t active_index_1 = 0;
|
||||
static int32_t active_index_2 = 0;
|
||||
|
||||
static void radio_event_handler(lv_event_t * e)
|
||||
static void event_cb(lv_event_t * e)
|
||||
{
|
||||
int32_t * active_id = (int32_t *)lv_event_get_user_data(e);
|
||||
lv_obj_t * cont = (lv_obj_t *)lv_event_get_current_target(e);
|
||||
lv_obj_t * act_cb = lv_event_get_target_obj(e);
|
||||
lv_obj_t * old_cb = lv_obj_get_child(cont, *active_id);
|
||||
|
||||
/*Do nothing if the container was clicked*/
|
||||
if(act_cb == cont) return;
|
||||
|
||||
lv_obj_remove_state(old_cb, LV_STATE_CHECKED); /*Uncheck the previous radio button*/
|
||||
lv_obj_add_state(act_cb, LV_STATE_CHECKED); /*Check the current radio button*/
|
||||
|
||||
*active_id = lv_obj_get_index(act_cb);
|
||||
|
||||
LV_LOG_USER("Selected radio buttons: %d, %d", (int)active_index_1, (int)active_index_2);
|
||||
}
|
||||
|
||||
static void radiobutton_create(lv_obj_t * parent, const char * txt)
|
||||
{
|
||||
lv_obj_t * obj = lv_checkbox_create(parent);
|
||||
lv_checkbox_set_text(obj, txt);
|
||||
lv_obj_add_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE);
|
||||
lv_obj_add_style(obj, &style_radio, LV_PART_INDICATOR);
|
||||
lv_obj_add_style(obj, &style_radio_chk, LV_PART_INDICATOR | LV_STATE_CHECKED);
|
||||
lv_obj_t * obj = lv_event_get_target_obj(e);
|
||||
if(lv_obj_has_state(obj, LV_STATE_CHECKED)) {
|
||||
LV_LOG_USER("%s is selected.", lv_checkbox_get_text(obj));
|
||||
}
|
||||
else {
|
||||
LV_LOG_USER("%s is de-selected.", lv_checkbox_get_text(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,46 +20,37 @@ static void radiobutton_create(lv_obj_t * parent, const char * txt)
|
||||
*/
|
||||
void lv_example_checkbox_2(void)
|
||||
{
|
||||
/* The idea is to enable `LV_OBJ_FLAG_EVENT_BUBBLE` on checkboxes and process the
|
||||
* `LV_EVENT_CLICKED` on the container.
|
||||
* A variable is passed as event user data where the index of the active
|
||||
* radiobutton is saved */
|
||||
|
||||
lv_style_init(&style_radio);
|
||||
lv_style_set_radius(&style_radio, LV_RADIUS_CIRCLE);
|
||||
|
||||
lv_style_init(&style_radio_chk);
|
||||
lv_style_set_bg_image_src(&style_radio_chk, NULL);
|
||||
|
||||
|
||||
lv_obj_t * cont = lv_obj_create(lv_screen_active());
|
||||
lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_size(cont, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||
lv_obj_center(cont);
|
||||
|
||||
uint32_t i;
|
||||
char buf[32];
|
||||
|
||||
lv_obj_t * cont1 = lv_obj_create(lv_screen_active());
|
||||
lv_obj_set_flex_flow(cont1, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_size(cont1, lv_pct(40), lv_pct(80));
|
||||
lv_obj_add_event_cb(cont1, radio_event_handler, LV_EVENT_CLICKED, &active_index_1);
|
||||
|
||||
for(i = 0; i < 5; i++) {
|
||||
lv_snprintf(buf, sizeof(buf), "A %d", (int)i + 1);
|
||||
radiobutton_create(cont1, buf);
|
||||
lv_snprintf(buf, sizeof(buf), "Radio button %d", (int)i + 1);
|
||||
|
||||
}
|
||||
/*Make the first checkbox checked*/
|
||||
lv_obj_add_state(lv_obj_get_child(cont1, 0), LV_STATE_CHECKED);
|
||||
lv_obj_t * obj = lv_checkbox_create(cont);
|
||||
lv_checkbox_set_text(obj, buf);
|
||||
|
||||
lv_obj_t * cont2 = lv_obj_create(lv_screen_active());
|
||||
lv_obj_set_flex_flow(cont2, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_size(cont2, lv_pct(40), lv_pct(80));
|
||||
lv_obj_set_x(cont2, lv_pct(50));
|
||||
lv_obj_add_event_cb(cont2, radio_event_handler, LV_EVENT_CLICKED, &active_index_2);
|
||||
lv_obj_add_event_cb(obj, event_cb, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
|
||||
for(i = 0; i < 3; i++) {
|
||||
lv_snprintf(buf, sizeof(buf), "B %d", (int)i + 1);
|
||||
radiobutton_create(cont2, buf);
|
||||
/*This makes the checkboxes act as radio buttons*/
|
||||
lv_obj_add_flag(obj, LV_OBJ_FLAG_RADIO_BUTTON);
|
||||
|
||||
lv_obj_add_style(obj, &style_radio, LV_PART_INDICATOR);
|
||||
lv_obj_add_style(obj, &style_radio_chk, LV_PART_INDICATOR | LV_STATE_CHECKED);
|
||||
}
|
||||
|
||||
/*Make the first checkbox checked*/
|
||||
lv_obj_add_state(lv_obj_get_child(cont2, 0), LV_STATE_CHECKED);
|
||||
// lv_obj_add_state(lv_obj_get_child(cont, 0), LV_STATE_CHECKED);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+37
-6
@@ -856,11 +856,38 @@ static void lv_obj_event(const lv_obj_class_t * class_p, lv_event_t * e)
|
||||
void * param = lv_event_get_param(e);
|
||||
/*Go the checked state if enabled*/
|
||||
if(lv_indev_get_scroll_obj(param) == NULL && lv_obj_has_flag(obj, LV_OBJ_FLAG_CHECKABLE)) {
|
||||
if(!(lv_obj_get_state(obj) & LV_STATE_CHECKED)) lv_obj_add_state(obj, LV_STATE_CHECKED);
|
||||
else lv_obj_remove_state(obj, LV_STATE_CHECKED);
|
||||
|
||||
lv_result_t res = lv_obj_send_event(obj, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
if(res != LV_RESULT_OK) return;
|
||||
bool was_checked = lv_obj_has_state(obj, LV_STATE_CHECKED);
|
||||
if(!(lv_obj_get_state(obj) & LV_STATE_CHECKED)) {
|
||||
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)) {
|
||||
lv_obj_remove_state(obj, LV_STATE_CHECKED);
|
||||
}
|
||||
if(was_checked != lv_obj_has_state(obj, LV_STATE_CHECKED)) {
|
||||
lv_result_t res = lv_obj_send_event(obj, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
if(res != LV_RESULT_OK) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
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)) {
|
||||
lv_obj_t * parent = lv_obj_get_parent(obj);
|
||||
if(parent) {
|
||||
uint32_t child_cnt = lv_obj_get_child_count(parent);
|
||||
uint32_t i;
|
||||
for(i = 0; i < child_cnt; i++) {
|
||||
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)) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(code == LV_EVENT_PRESS_LOST) {
|
||||
@@ -876,15 +903,19 @@ static void lv_obj_event(const lv_obj_class_t * class_p, lv_event_t * e)
|
||||
else if(code == LV_EVENT_KEY) {
|
||||
if(lv_obj_has_flag(obj, LV_OBJ_FLAG_CHECKABLE)) {
|
||||
uint32_t c = lv_event_get_key(e);
|
||||
bool was_checked = lv_obj_has_state(obj, LV_STATE_CHECKED);
|
||||
if(c == LV_KEY_RIGHT || c == LV_KEY_UP) {
|
||||
lv_obj_add_state(obj, LV_STATE_CHECKED);
|
||||
}
|
||||
else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) {
|
||||
lv_obj_remove_state(obj, LV_STATE_CHECKED);
|
||||
/*Radio buttons can't be checked off directly*/
|
||||
if(!lv_obj_has_flag(obj, LV_OBJ_FLAG_RADIO_BUTTON)) {
|
||||
lv_obj_remove_state(obj, LV_STATE_CHECKED);
|
||||
}
|
||||
}
|
||||
|
||||
/*With Enter LV_EVENT_RELEASED will send VALUE_CHANGE event*/
|
||||
if(c != LV_KEY_ENTER) {
|
||||
if(c != LV_KEY_ENTER && was_checked != lv_obj_has_state(obj, LV_STATE_CHECKED)) {
|
||||
lv_result_t res = lv_obj_send_event(obj, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
if(res != LV_RESULT_OK) return;
|
||||
}
|
||||
|
||||
+38
-40
@@ -46,43 +46,42 @@ extern "C" {
|
||||
* whenever add/remove flags or change bit definition of flags.
|
||||
*/
|
||||
typedef enum {
|
||||
LV_OBJ_FLAG_HIDDEN = (1L << 0), /**< Make the object hidden. (Like it wasn't there at all)*/
|
||||
LV_OBJ_FLAG_CLICKABLE = (1L << 1), /**< Make the object clickable by the input devices*/
|
||||
LV_OBJ_FLAG_CLICK_FOCUSABLE = (1L << 2), /**< Add focused state to the object when clicked*/
|
||||
LV_OBJ_FLAG_CHECKABLE = (1L << 3), /**< Toggle checked state when the object is clicked*/
|
||||
LV_OBJ_FLAG_SCROLLABLE = (1L << 4), /**< Make the object scrollable*/
|
||||
LV_OBJ_FLAG_SCROLL_ELASTIC = (1L << 5), /**< Allow scrolling inside but with slower speed*/
|
||||
LV_OBJ_FLAG_SCROLL_MOMENTUM = (1L << 6), /**< Make the object scroll further when "thrown"*/
|
||||
LV_OBJ_FLAG_SCROLL_ONE = (1L << 7), /**< Allow scrolling only one snappable children*/
|
||||
LV_OBJ_FLAG_SCROLL_CHAIN_HOR = (1L << 8), /**< Allow propagating the horizontal scroll to a parent*/
|
||||
LV_OBJ_FLAG_SCROLL_CHAIN_VER = (1L << 9), /**< Allow propagating the vertical scroll to a parent*/
|
||||
LV_OBJ_FLAG_HIDDEN = (1u << 0), /**< Make the object hidden. (Like it wasn't there at all)*/
|
||||
LV_OBJ_FLAG_CLICKABLE = (1u << 1), /**< Make the object clickable by the input devices*/
|
||||
LV_OBJ_FLAG_CLICK_FOCUSABLE = (1u << 2), /**< Add focused state to the object when clicked*/
|
||||
LV_OBJ_FLAG_CHECKABLE = (1u << 3), /**< Toggle checked state when the object is clicked*/
|
||||
LV_OBJ_FLAG_SCROLLABLE = (1u << 4), /**< Make the object scrollable*/
|
||||
LV_OBJ_FLAG_SCROLL_ELASTIC = (1u << 5), /**< Allow scrolling inside but with slower speed*/
|
||||
LV_OBJ_FLAG_SCROLL_MOMENTUM = (1u << 6), /**< Make the object scroll further when "thrown"*/
|
||||
LV_OBJ_FLAG_SCROLL_ONE = (1u << 7), /**< Allow scrolling only one snappable children*/
|
||||
LV_OBJ_FLAG_SCROLL_CHAIN_HOR = (1u << 8), /**< Allow propagating the horizontal scroll to a parent*/
|
||||
LV_OBJ_FLAG_SCROLL_CHAIN_VER = (1u << 9), /**< Allow propagating the vertical scroll to a parent*/
|
||||
LV_OBJ_FLAG_SCROLL_CHAIN = (LV_OBJ_FLAG_SCROLL_CHAIN_HOR | LV_OBJ_FLAG_SCROLL_CHAIN_VER),
|
||||
LV_OBJ_FLAG_SCROLL_ON_FOCUS = (1L << 10), /**< Automatically scroll object to make it visible when focused*/
|
||||
LV_OBJ_FLAG_SCROLL_WITH_ARROW = (1L << 11), /**< Allow scrolling the focused object with arrow keys*/
|
||||
LV_OBJ_FLAG_SNAPPABLE = (1L << 12), /**< If scroll snap is enabled on the parent it can snap to this object*/
|
||||
LV_OBJ_FLAG_PRESS_LOCK = (1L << 13), /**< Keep the object pressed even if the press slid from the object*/
|
||||
LV_OBJ_FLAG_EVENT_BUBBLE = (1L << 14), /**< Propagate the events to the parent too*/
|
||||
LV_OBJ_FLAG_GESTURE_BUBBLE = (1L << 15), /**< Propagate the gestures to the parent*/
|
||||
LV_OBJ_FLAG_ADV_HITTEST = (1L << 16), /**< Allow performing more accurate hit (click) test. E.g. consider rounded corners.*/
|
||||
LV_OBJ_FLAG_IGNORE_LAYOUT = (1L << 17), /**< Make the object not positioned by the layouts*/
|
||||
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*/
|
||||
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_SCROLL_ON_FOCUS = (1u << 10), /**< Automatically scroll object to make it visible when focused*/
|
||||
LV_OBJ_FLAG_SCROLL_WITH_ARROW = (1u << 11), /**< Allow scrolling the focused object with arrow keys*/
|
||||
LV_OBJ_FLAG_SNAPPABLE = (1u << 12), /**< If scroll snap is enabled on the parent it can snap to this object*/
|
||||
LV_OBJ_FLAG_PRESS_LOCK = (1u << 13), /**< Keep the object pressed even if the press slid from the object*/
|
||||
LV_OBJ_FLAG_EVENT_BUBBLE = (1u << 14), /**< Propagate the events to the parent too*/
|
||||
LV_OBJ_FLAG_GESTURE_BUBBLE = (1u << 15), /**< Propagate the gestures to the parent*/
|
||||
LV_OBJ_FLAG_ADV_HITTEST = (1u << 16), /**< Allow performing more accurate hit (click) test. E.g. consider rounded corners.*/
|
||||
LV_OBJ_FLAG_IGNORE_LAYOUT = (1u << 17), /**< Make the object not positioned by the layouts*/
|
||||
LV_OBJ_FLAG_FLOATING = (1u << 18), /**< Do not scroll the object when the parent scrolls and ignore layout*/
|
||||
LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS = (1u << 19), /**< Send `LV_EVENT_DRAW_TASK_ADDED` events*/
|
||||
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 = (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_1 = (1u << 24), /**< Custom flag, free to use by layouts*/
|
||||
LV_OBJ_FLAG_LAYOUT_2 = (1u << 25), /**< 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*/
|
||||
LV_OBJ_FLAG_USER_1 = (1L << 27), /**< Custom flag, free to use by user*/
|
||||
LV_OBJ_FLAG_USER_2 = (1L << 28), /**< Custom flag, free to use by user*/
|
||||
LV_OBJ_FLAG_USER_3 = (1L << 29), /**< Custom flag, free to use by user*/
|
||||
LV_OBJ_FLAG_USER_4 = (1L << 30), /**< Custom flag, free to use by user*/
|
||||
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_t;
|
||||
|
||||
#if LV_USE_OBJ_PROPERTY
|
||||
@@ -112,15 +111,14 @@ 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_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_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_END, LV_PROPERTY_TYPE_INT, 30),
|
||||
|
||||
LV_PROPERTY_ID(OBJ, STATE_START, LV_PROPERTY_TYPE_INT, 31),
|
||||
|
||||
@@ -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[74] = {
|
||||
{"align", LV_PROPERTY_OBJ_ALIGN,},
|
||||
{"child_count", LV_PROPERTY_OBJ_CHILD_COUNT,},
|
||||
{"content_height", LV_PROPERTY_OBJ_CONTENT_HEIGHT,},
|
||||
@@ -38,6 +38,7 @@ 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,},
|
||||
@@ -52,8 +53,6 @@ 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,},
|
||||
|
||||
@@ -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[75];
|
||||
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_slider_property_names[8];
|
||||
extern const lv_property_name_t lv_style_property_names[123];
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file lv_xml_obj_parser.c
|
||||
*
|
||||
*/
|
||||
* @file lv_xml_obj_parser.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
@@ -141,6 +141,8 @@ void lv_xml_obj_apply(lv_xml_parser_state_t * state, const char ** attrs)
|
||||
lv_xml_to_bool(value));
|
||||
else if(lv_streq("overflow_visible", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_OVERFLOW_VISIBLE,
|
||||
lv_xml_to_bool(value));
|
||||
else if(lv_streq("radio_button", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_RADIO_BUTTON,
|
||||
lv_xml_to_bool(value));
|
||||
else if(lv_streq("flex_in_new_track", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK,
|
||||
lv_xml_to_bool(value));
|
||||
|
||||
@@ -817,8 +819,9 @@ static lv_obj_flag_t flag_to_enum(const char * txt)
|
||||
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("floating", txt)) return LV_OBJ_FLAG_FLOATING;
|
||||
if(lv_streq("send_draw_task_evenTS", txt)) return LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS;
|
||||
if(lv_streq("send_draw_task_events", txt)) return LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS;
|
||||
if(lv_streq("overflow_visible", txt)) return LV_OBJ_FLAG_OVERFLOW_VISIBLE;
|
||||
if(lv_streq("radio_button", txt)) return LV_OBJ_FLAG_RADIO_BUTTON;
|
||||
if(lv_streq("flex_in_new_track", txt)) return LV_OBJ_FLAG_FLEX_IN_NEW_TRACK;
|
||||
if(lv_streq("layout_1", txt)) return LV_OBJ_FLAG_LAYOUT_1;
|
||||
if(lv_streq("layout_2", txt)) return LV_OBJ_FLAG_LAYOUT_2;
|
||||
@@ -826,8 +829,6 @@ static lv_obj_flag_t flag_to_enum(const char * txt)
|
||||
if(lv_streq("widget_2", txt)) return LV_OBJ_FLAG_WIDGET_2;
|
||||
if(lv_streq("user_1", txt)) return LV_OBJ_FLAG_USER_1;
|
||||
if(lv_streq("user_2", txt)) return LV_OBJ_FLAG_USER_2;
|
||||
if(lv_streq("user_3", txt)) return LV_OBJ_FLAG_USER_3;
|
||||
if(lv_streq("user_4", txt)) return LV_OBJ_FLAG_USER_4;
|
||||
|
||||
LV_LOG_WARN("%s is an unknown value for flag", txt);
|
||||
return 0; /*Return 0 in lack of a better option. */
|
||||
|
||||
@@ -138,6 +138,102 @@ void test_obj_flag_overflow_visible_1(void)
|
||||
TEST_ASSERT_EQUAL_UINT32(1, cnt_1);
|
||||
TEST_ASSERT_EQUAL_UINT32(2, cnt_2);
|
||||
TEST_ASSERT_EQUAL_SCREENSHOT("widgets/obj_flag_overflow_visible_1_4.png");
|
||||
}
|
||||
|
||||
static void event_cb(lv_event_t * e)
|
||||
{
|
||||
uint32_t * called = lv_event_get_user_data(e);
|
||||
(*called)++;
|
||||
|
||||
}
|
||||
|
||||
void test_obj_flag_radio_button(void)
|
||||
{
|
||||
lv_group_t * g = lv_group_create();
|
||||
|
||||
lv_indev_set_group(lv_test_indev_get_indev(LV_INDEV_TYPE_KEYPAD), g);
|
||||
|
||||
lv_obj_t * scr = lv_screen_active();
|
||||
lv_obj_t * cb[5];
|
||||
uint32_t called[5];
|
||||
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_group_add_obj(g, cb[i]);
|
||||
lv_obj_add_event_cb(cb[i], event_cb, LV_EVENT_VALUE_CHANGED, &called[i]);
|
||||
called[i] = 0;
|
||||
}
|
||||
|
||||
/*Click the first checkbox*/
|
||||
lv_test_mouse_click_at(20, 5);
|
||||
TEST_ASSERT_TRUE(lv_obj_has_state(cb[0], LV_STATE_CHECKED));
|
||||
TEST_ASSERT_EQUAL_UINT32(called[0], 1);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[1], 0);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[2], 0);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[3], 0);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[4], 0);
|
||||
|
||||
/*Click the second checkbox*/
|
||||
lv_test_mouse_click_at(20, 55);
|
||||
TEST_ASSERT_FALSE(lv_obj_has_state(cb[0], LV_STATE_CHECKED));
|
||||
TEST_ASSERT_TRUE(lv_obj_has_state(cb[1], LV_STATE_CHECKED));
|
||||
TEST_ASSERT_EQUAL_UINT32(called[0], 2);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[1], 1);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[2], 0);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[3], 0);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[4], 0);
|
||||
|
||||
/*Clicking the same checkbox shouldn't change anything*/
|
||||
lv_test_mouse_click_at(20, 55);
|
||||
TEST_ASSERT_FALSE(lv_obj_has_state(cb[0], LV_STATE_CHECKED));
|
||||
TEST_ASSERT_TRUE(lv_obj_has_state(cb[1], LV_STATE_CHECKED));
|
||||
TEST_ASSERT_EQUAL_UINT32(called[0], 2);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[1], 1);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[2], 0);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[3], 0);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[4], 0);
|
||||
|
||||
/*Turn on checkbox 2 with a key*/
|
||||
lv_group_focus_obj(cb[2]);
|
||||
lv_test_key_hit(LV_KEY_UP);
|
||||
TEST_ASSERT_FALSE(lv_obj_has_state(cb[1], LV_STATE_CHECKED));
|
||||
TEST_ASSERT_TRUE(lv_obj_has_state(cb[2], LV_STATE_CHECKED));
|
||||
TEST_ASSERT_EQUAL_UINT32(called[0], 2);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[1], 2);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[2], 1);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[3], 0);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[4], 0);
|
||||
|
||||
/*Nothing happen checking checkbox 2 again*/
|
||||
lv_test_key_hit(LV_KEY_RIGHT);
|
||||
TEST_ASSERT_FALSE(lv_obj_has_state(cb[1], LV_STATE_CHECKED));
|
||||
TEST_ASSERT_TRUE(lv_obj_has_state(cb[2], LV_STATE_CHECKED));
|
||||
TEST_ASSERT_EQUAL_UINT32(called[0], 2);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[1], 2);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[2], 1);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[3], 0);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[4], 0);
|
||||
|
||||
/*Can't check off*/
|
||||
lv_test_key_hit(LV_KEY_DOWN);
|
||||
TEST_ASSERT_FALSE(lv_obj_has_state(cb[1], LV_STATE_CHECKED));
|
||||
TEST_ASSERT_TRUE(lv_obj_has_state(cb[2], LV_STATE_CHECKED));
|
||||
TEST_ASSERT_EQUAL_UINT32(called[0], 2);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[1], 2);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[2], 1);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[3], 0);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[4], 0);
|
||||
|
||||
/*Same with left*/
|
||||
lv_test_key_hit(LV_KEY_LEFT);
|
||||
TEST_ASSERT_FALSE(lv_obj_has_state(cb[1], LV_STATE_CHECKED));
|
||||
TEST_ASSERT_TRUE(lv_obj_has_state(cb[2], LV_STATE_CHECKED));
|
||||
TEST_ASSERT_EQUAL_UINT32(called[0], 2);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[1], 2);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[2], 1);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[3], 0);
|
||||
TEST_ASSERT_EQUAL_UINT32(called[4], 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -147,6 +147,7 @@ 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 },
|
||||
@@ -154,8 +155,6 @@ 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());
|
||||
|
||||
@@ -30,6 +30,7 @@ Example
|
||||
<enum name="floating" help="Do not scroll the object when the parent scrolls and ignore layout"/>
|
||||
<enum name="send_draw_task_events" help="Send `LV_EVENT_DRAW_TASK_ADDED` events"/>
|
||||
<enum name="overflow_visible" help="Do not clip the children to the parent's ext draw size"/>
|
||||
<enum name="radio_button" help="Allow only one radio_button sibling to be checked"/>
|
||||
<enum name="flex_in_new_track" help="Start a new flex track on this item"/>
|
||||
<enum name="layout_1" help="Custom flag, free to use by layouts"/>
|
||||
<enum name="layout_2" help="Custom flag, free to use by layouts"/>
|
||||
@@ -382,6 +383,8 @@ Example
|
||||
<prop name="floating" type="flag:flag lv_obj_flag" help="Do not scroll the object when the parent scrolls and ignore layout"/>
|
||||
<prop name="send_draw_task_events" type="flag:flag lv_obj_flag" help="Send `LV_EVENT_DRAW_TASK_ADDED` events"/>
|
||||
<prop name="overflow_visible" type="flag:flag lv_obj_flag" help="Do not clip the children to the parent's ext draw size"/>
|
||||
<prop name="radio_button" type="flag:flag lv_obj_flag" help="Allow only one radio_button sibling to be checked"/>
|
||||
|
||||
<prop name="flex_in_new_track" type="flag:flag lv_obj_flag" help="Start a new flex track on this item"/>
|
||||
|
||||
<prop name="bind_checked" type="subject" help="Bind widget’s checked state to a subject"/>
|
||||
|
||||
Reference in New Issue
Block a user