bu5hm4n pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=d445e5240b03ddf659b3c16c74d982956a2a7b67
commit d445e5240b03ddf659b3c16c74d982956a2a7b67 Author: Marcel Hollerbach <[email protected]> Date: Thu Aug 22 15:06:22 2019 +0200 efl_ui_radio_group: migrate to Efl.Ui.Single_Selectable with this the whole thing is migrated to single_selectable. The group is added to the spec test suite. The elm_test case of radio_group now also has a fallback option to demonstrate the usage of it. This also fixes a broken testcase, where a flag was forgotten to be checked. ref T8024 Reviewed-by: Mike Blumenkrantz <[email protected]> Differential Revision: https://phab.enlightenment.org/D9706 --- src/bin/elementary/test_part_bg.c | 6 +- src/bin/elementary/test_ui_image.c | 2 +- src/bin/elementary/test_ui_radio.c | 18 +++--- src/lib/elementary/efl_ui_radio_box.c | 1 + src/lib/elementary/efl_ui_radio_group.eo | 11 +--- src/lib/elementary/efl_ui_radio_group_impl.c | 69 ++++++++++++++-------- src/lib/elementary/efl_ui_radio_group_impl.eo | 3 +- src/tests/elementary/efl_ui_test_radio_group.c | 38 ++++++------ .../elementary/spec/efl_test_single_selectable.c | 13 +++- 9 files changed, 89 insertions(+), 72 deletions(-) diff --git a/src/bin/elementary/test_part_bg.c b/src/bin/elementary/test_part_bg.c index cb9dd4dbd3..3f8f30be00 100644 --- a/src/bin/elementary/test_part_bg.c +++ b/src/bin/elementary/test_part_bg.c @@ -15,7 +15,7 @@ _reset_cb(void *data, const Efl_Event *ev EINA_UNUSED) Efl_Ui_Radio_Group *radio = data; Evas_Object *target; - radio = efl_ui_radio_group_selected_object_get(radio); + radio = efl_ui_single_selectable_last_selected_get(radio); target = evas_object_data_get(radio, "data"); efl_gfx_color_set(efl_part(target, "background"), 0, 0, 0, 0); @@ -29,7 +29,7 @@ _color_cb(void *data, const Efl_Event *ev EINA_UNUSED) Evas_Object *target; static Eina_Bool i; - radio = efl_ui_radio_group_selected_object_get(radio); + radio = efl_ui_single_selectable_last_selected_get(radio); target = evas_object_data_get(radio, "data"); i ^= EINA_TRUE; efl_gfx_color_set(efl_part(target, "background"), (i) ? 255 : 0, (i) ? 0 : 255, 0, 255); @@ -43,7 +43,7 @@ _scale_type_cb(void *data, const Efl_Event *ev EINA_UNUSED) Efl_Gfx_Image_Scale_Type type; char buf[PATH_MAX]; - radio = efl_ui_radio_group_selected_object_get(radio); + radio = efl_ui_single_selectable_last_selected_get(radio); target = evas_object_data_get(radio, "data"); snprintf(buf, sizeof(buf), "%s/images/plant_01.jpg", elm_app_data_dir_get()); diff --git a/src/bin/elementary/test_ui_image.c b/src/bin/elementary/test_ui_image.c index e3f1bd5b52..87ad9fbafb 100644 --- a/src/bin/elementary/test_ui_image.c +++ b/src/bin/elementary/test_ui_image.c @@ -640,7 +640,7 @@ test_ui_image_prescale(void *data EINA_UNUSED, Eo *obj EINA_UNUSED, void *event_ efl_pack(hbox, rd); efl_event_callback_add(hbox, EFL_UI_RADIO_GROUP_EVENT_VALUE_CHANGED, _cb_prescale_radio_changed, im); - efl_ui_radio_group_selected_object_set(hbox, rd); + efl_ui_selectable_selected_set(rd, EINA_TRUE); efl_pack(box, hbox); diff --git a/src/bin/elementary/test_ui_radio.c b/src/bin/elementary/test_ui_radio.c index ec2740f9cb..487c6aa932 100644 --- a/src/bin/elementary/test_ui_radio.c +++ b/src/bin/elementary/test_ui_radio.c @@ -77,12 +77,12 @@ _set_selected_btn_clicked(void *data, const Efl_Event *ev EINA_UNUSED) } static void -_set_selected_object_btn_clicked(void *data, const Efl_Event *ev) +_set_fallback_radio_btn_clicked(void *data, const Efl_Event *ev EINA_UNUSED) { - Efl_Ui_Radio_Group *group = data; - - efl_ui_radio_group_selected_value_set(group, 3); - efl_ui_radio_group_selected_object_set(group, efl_key_data_get(ev->object, "uk")); + if (!efl_ui_single_selectable_fallback_selection_get(data)) + efl_ui_single_selectable_fallback_selection_set(data, efl_pack_content_get(data, 4)); + else + efl_ui_single_selectable_fallback_selection_set(data, NULL); } void test_efl_ui_radio(void *data EINA_UNUSED, @@ -94,7 +94,6 @@ void test_efl_ui_radio(void *data EINA_UNUSED, Efl_Ui_Box *bx; Eina_Array *arr; Efl_Ui_Button *o; - Efl_Ui_Radio *uk = NULL; win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(), efl_ui_win_type_set(efl_added, EFL_UI_WIN_TYPE_BASIC), @@ -112,8 +111,6 @@ void test_efl_ui_radio(void *data EINA_UNUSED, { Efl_Ui_Radio *r = eina_array_data_get(arr, i); efl_pack_end(bx, r); - if (i == 4) - uk = r; } o = efl_add(EFL_UI_BUTTON_CLASS, table); @@ -128,9 +125,8 @@ void test_efl_ui_radio(void *data EINA_UNUSED, o = efl_add(EFL_UI_BUTTON_CLASS, table); efl_pack_table(table, o, 1, 2, 1, 1); - efl_text_set(o, "Set object for UK"); - efl_key_data_set(o, "uk", uk); - efl_event_callback_add(o, EFL_INPUT_EVENT_CLICKED, _set_selected_object_btn_clicked, bx); + efl_text_set(o, "Fallback set to UK"); + efl_event_callback_add(o, EFL_INPUT_EVENT_CLICKED, _set_fallback_radio_btn_clicked, bx); eina_array_free(arr); } diff --git a/src/lib/elementary/efl_ui_radio_box.c b/src/lib/elementary/efl_ui_radio_box.c index b58e76f3fe..92918ea7eb 100644 --- a/src/lib/elementary/efl_ui_radio_box.c +++ b/src/lib/elementary/efl_ui_radio_box.c @@ -119,6 +119,7 @@ _efl_ui_radio_box_efl_object_constructor(Eo *obj, Efl_Ui_Radio_Box_Data *pd) { pd->group = efl_new(EFL_UI_RADIO_GROUP_IMPL_CLASS, NULL); efl_composite_attach(obj, pd->group); + efl_event_callback_forwarder_add(pd->group, EFL_UI_SINGLE_SELECTABLE_EVENT_SELECTION_CHANGED, obj); efl_event_callback_forwarder_add(pd->group, EFL_UI_RADIO_GROUP_EVENT_VALUE_CHANGED, obj); return efl_constructor(efl_super(obj, MY_CLASS)); } diff --git a/src/lib/elementary/efl_ui_radio_group.eo b/src/lib/elementary/efl_ui_radio_group.eo index 34f0d7b907..5651e237a6 100644 --- a/src/lib/elementary/efl_ui_radio_group.eo +++ b/src/lib/elementary/efl_ui_radio_group.eo @@ -1,19 +1,10 @@ -interface @beta Efl.Ui.Radio_Group +interface @beta Efl.Ui.Radio_Group extends Efl.Ui.Single_Selectable { [[Interface for manually handling a group of @Efl.Ui.Radio buttons. See the documentation of @Efl.Ui.Radio for an explanation of radio button grouping. ]] methods { - @property selected_object { - [[Currently selected button in a radio button group, or $NULL if no button is selected. - - See also @.selected_value. - ]] - values { - selected_object : Efl.Ui.Radio; [[The currently selected radio button in the group, or $NULL.]] - } - } @property selected_value { [[The value associated with the currently selected button in the group. Give each radio button in the group a different value using @Efl.Ui.Radio.state_value. diff --git a/src/lib/elementary/efl_ui_radio_group_impl.c b/src/lib/elementary/efl_ui_radio_group_impl.c index 14dc5a4af6..622924bcdc 100644 --- a/src/lib/elementary/efl_ui_radio_group_impl.c +++ b/src/lib/elementary/efl_ui_radio_group_impl.c @@ -11,41 +11,35 @@ static Eina_Hash *radio_group_map; typedef struct { Efl_Ui_Radio *selected; + Efl_Ui_Radio *fallback_object; Eina_List *registered_set; + Eina_Bool in_value_change; } Efl_Ui_Radio_Group_Impl_Data; + EOLIAN static void -_efl_ui_radio_group_impl_efl_ui_radio_group_selected_object_set(Eo *obj EINA_UNUSED, Efl_Ui_Radio_Group_Impl_Data *pd, Efl_Ui_Radio *selected_object) +_efl_ui_radio_group_impl_efl_ui_single_selectable_fallback_selection_set(Eo *obj EINA_UNUSED, Efl_Ui_Radio_Group_Impl_Data *pd, Efl_Ui_Selectable *fallback) { - int new_value = -1; - Eo *old_selected; - - if (pd->selected == selected_object) return; + pd->fallback_object = fallback; - old_selected = pd->selected; - pd->selected = selected_object; - - //it is essential to *first* set pd->selected to the new state before calling this - //otherwise this here will be called again, and the event will get emitted twice - if (old_selected && efl_alive_get(old_selected)) - efl_ui_selectable_selected_set(old_selected, EINA_FALSE); + if (!pd->selected) + efl_ui_selectable_selected_set(pd->fallback_object, EINA_TRUE); +} - if (pd->selected) - { - efl_ui_selectable_selected_set(pd->selected, EINA_TRUE); - new_value = efl_ui_radio_state_value_get(pd->selected); - } - efl_event_callback_call(obj, EFL_UI_RADIO_GROUP_EVENT_VALUE_CHANGED, &new_value); +EOLIAN static Efl_Ui_Selectable* +_efl_ui_radio_group_impl_efl_ui_single_selectable_fallback_selection_get(const Eo *obj EINA_UNUSED, Efl_Ui_Radio_Group_Impl_Data *pd) +{ + return pd->fallback_object; } EOLIAN static Efl_Ui_Radio* -_efl_ui_radio_group_impl_efl_ui_radio_group_selected_object_get(const Eo *obj EINA_UNUSED, Efl_Ui_Radio_Group_Impl_Data *pd) +_efl_ui_radio_group_impl_efl_ui_single_selectable_last_selected_get(const Eo *obj EINA_UNUSED, Efl_Ui_Radio_Group_Impl_Data *pd) { return pd->selected; } EOLIAN static void -_efl_ui_radio_group_impl_efl_ui_radio_group_selected_value_set(Eo *obj, Efl_Ui_Radio_Group_Impl_Data *pd, int selected_value) +_efl_ui_radio_group_impl_efl_ui_radio_group_selected_value_set(Eo *obj EINA_UNUSED, Efl_Ui_Radio_Group_Impl_Data *pd, int selected_value) { Efl_Ui_Radio *reged; Eina_List *n; @@ -54,7 +48,7 @@ _efl_ui_radio_group_impl_efl_ui_radio_group_selected_value_set(Eo *obj, Efl_Ui_R { if (efl_ui_radio_state_value_get(reged) == selected_value) { - efl_ui_radio_group_selected_object_set(obj, reged); + efl_ui_selectable_selected_set(reged, EINA_TRUE); return; } } @@ -70,18 +64,43 @@ _efl_ui_radio_group_impl_efl_ui_radio_group_selected_value_get(const Eo *obj EIN static void _selected_cb(void *data, const Efl_Event *ev) { + Efl_Ui_Radio_Group_Impl_Data *pd = efl_data_scope_safe_get(data, EFL_UI_RADIO_GROUP_IMPL_CLASS); if (efl_ui_selectable_selected_get(ev->object)) { - efl_ui_radio_group_selected_object_set(data, ev->object); + if (pd->selected) + { + pd->in_value_change = EINA_TRUE; + efl_ui_selectable_selected_set(pd->selected, EINA_FALSE); + } + pd->in_value_change = EINA_FALSE; + EINA_SAFETY_ON_FALSE_RETURN(!pd->selected); + pd->selected = ev->object; } else { //if something was unselected, we need to make sure that we are unsetting the internal pointer to NULL - if (efl_ui_radio_group_selected_object_get(data) == ev->object) + if (pd->selected == ev->object) + { + pd->selected = NULL; + } + //checkout if we want to do fallback handling + if (!pd->in_value_change) { - efl_ui_radio_group_selected_object_set(data, NULL); + if (!pd->selected && pd->fallback_object) + efl_ui_selectable_selected_set(pd->fallback_object, EINA_TRUE); } } + + if (!pd->in_value_change) + { + int value; + if (pd->selected) + value = efl_ui_radio_state_value_get(pd->selected); + else + value = -1; + efl_event_callback_call(data, EFL_UI_RADIO_GROUP_EVENT_VALUE_CHANGED, &value); + efl_event_callback_call(data, EFL_UI_SINGLE_SELECTABLE_EVENT_SELECTION_CHANGED, NULL); + } } static void @@ -123,7 +142,7 @@ EOLIAN static void _efl_ui_radio_group_impl_efl_ui_radio_group_unregister(Eo *obj, Efl_Ui_Radio_Group_Impl_Data *pd, Efl_Ui_Radio *radio) { if (pd->selected == radio) - efl_ui_radio_group_selected_object_set(obj, NULL); + efl_ui_selectable_selected_set(pd->selected, EINA_FALSE); efl_event_callback_array_del(radio, radio_btn_cb(), obj); pd->registered_set = eina_list_remove(pd->registered_set, radio); diff --git a/src/lib/elementary/efl_ui_radio_group_impl.eo b/src/lib/elementary/efl_ui_radio_group_impl.eo index bc41093526..7de7899248 100644 --- a/src/lib/elementary/efl_ui_radio_group_impl.eo +++ b/src/lib/elementary/efl_ui_radio_group_impl.eo @@ -5,9 +5,10 @@ class @beta Efl.Ui.Radio_Group_Impl extends Efl.Object implements Efl.Ui.Radio_G implements { class.constructor; Efl.Object.destructor; - Efl.Ui.Radio_Group.selected_object {get; set;} Efl.Ui.Radio_Group.selected_value {get; set;} Efl.Ui.Radio_Group.register; Efl.Ui.Radio_Group.unregister; + Efl.Ui.Single_Selectable.last_selected {get;} + Efl.Ui.Single_Selectable.fallback_selection {set; get;} } } diff --git a/src/tests/elementary/efl_ui_test_radio_group.c b/src/tests/elementary/efl_ui_test_radio_group.c index 664819dd41..5b00b02318 100644 --- a/src/tests/elementary/efl_ui_test_radio_group.c +++ b/src/tests/elementary/efl_ui_test_radio_group.c @@ -65,20 +65,20 @@ EFL_START_TEST(active_selected_value_setting) efl_ui_radio_group_register(radio_group, r2); ck_assert_int_eq(efl_ui_radio_group_selected_value_get(radio_group), -1); - ck_assert_ptr_eq(efl_ui_radio_group_selected_object_get(radio_group), NULL); + ck_assert_ptr_eq(efl_ui_single_selectable_last_selected_get(radio_group), NULL); RESET_EVT efl_ui_radio_group_selected_value_set(radio_group, 1); ck_assert_int_eq(efl_ui_radio_group_selected_value_get(radio_group), 1); - ck_assert_ptr_eq(efl_ui_radio_group_selected_object_get(radio_group), r1); + ck_assert_ptr_eq(efl_ui_single_selectable_last_selected_get(radio_group), r1); ck_assert_int_eq(efl_ui_selectable_selected_get(r1), EINA_TRUE); ck_assert_int_eq(efl_ui_selectable_selected_get(r2), EINA_FALSE); EXPECT_EVT(1,1); RESET_EVT - efl_ui_radio_group_selected_object_set(radio_group, r2); + efl_ui_selectable_selected_set(r2, EINA_TRUE); ck_assert_int_eq(efl_ui_radio_group_selected_value_get(radio_group), 2); - ck_assert_ptr_eq(efl_ui_radio_group_selected_object_get(radio_group), r2); + ck_assert_ptr_eq(efl_ui_single_selectable_last_selected_get(radio_group), r2); ck_assert_int_eq(efl_ui_selectable_selected_get(r1), EINA_FALSE); ck_assert_int_eq(efl_ui_selectable_selected_get(r2), EINA_TRUE); EXPECT_EVT(1,2); @@ -96,20 +96,20 @@ EFL_START_TEST(active_selection_setting) efl_ui_radio_group_register(radio_group, r2); ck_assert_int_eq(efl_ui_radio_group_selected_value_get(radio_group), -1); - ck_assert_ptr_eq(efl_ui_radio_group_selected_object_get(radio_group), NULL); + ck_assert_ptr_eq(efl_ui_single_selectable_last_selected_get(radio_group), NULL); RESET_EVT - efl_ui_radio_group_selected_object_set(radio_group, r1); + efl_ui_selectable_selected_set(r1, EINA_TRUE); ck_assert_int_eq(efl_ui_radio_group_selected_value_get(radio_group), 1); - ck_assert_ptr_eq(efl_ui_radio_group_selected_object_get(radio_group), r1); + ck_assert_ptr_eq(efl_ui_single_selectable_last_selected_get(radio_group), r1); ck_assert_int_eq(efl_ui_selectable_selected_get(r1), EINA_TRUE); ck_assert_int_eq(efl_ui_selectable_selected_get(r2), EINA_FALSE); EXPECT_EVT(1,1); RESET_EVT - efl_ui_radio_group_selected_object_set(radio_group, r2); + efl_ui_selectable_selected_set(r2, EINA_TRUE); ck_assert_int_eq(efl_ui_radio_group_selected_value_get(radio_group), 2); - ck_assert_ptr_eq(efl_ui_radio_group_selected_object_get(radio_group), r2); + ck_assert_ptr_eq(efl_ui_single_selectable_last_selected_get(radio_group), r2); ck_assert_int_eq(efl_ui_selectable_selected_get(r1), EINA_FALSE); ck_assert_int_eq(efl_ui_selectable_selected_get(r2), EINA_TRUE); EXPECT_EVT(1,2); @@ -126,10 +126,10 @@ EFL_START_TEST(active_selection_object_setting) RESET_EVT ck_assert_int_eq(efl_ui_radio_group_selected_value_get(radio_group), -1); - ck_assert_ptr_eq(efl_ui_radio_group_selected_object_get(radio_group), NULL); + ck_assert_ptr_eq(efl_ui_single_selectable_last_selected_get(radio_group), NULL); efl_ui_selectable_selected_set(r, EINA_TRUE); ck_assert_int_eq(efl_ui_radio_group_selected_value_get(radio_group), 1); - ck_assert_ptr_eq(efl_ui_radio_group_selected_object_get(radio_group), r); + ck_assert_ptr_eq(efl_ui_single_selectable_last_selected_get(radio_group), r); EXPECT_EVT(1,1); } EFL_END_TEST @@ -143,14 +143,14 @@ EFL_START_TEST(unregister_setted) efl_ui_radio_group_register(radio_group, radio()); RESET_EVT - efl_ui_radio_group_selected_object_set(radio_group, r); + efl_ui_selectable_selected_set(r, EINA_TRUE); ck_assert_int_eq(efl_ui_radio_group_selected_value_get(radio_group), 1); - ck_assert_ptr_eq(efl_ui_radio_group_selected_object_get(radio_group), r); + ck_assert_ptr_eq(efl_ui_single_selectable_last_selected_get(radio_group), r); EXPECT_EVT(1,1); RESET_EVT efl_ui_radio_group_unregister(radio_group, r); ck_assert_int_eq(efl_ui_radio_group_selected_value_get(radio_group), -1); - ck_assert_ptr_eq(efl_ui_radio_group_selected_object_get(radio_group), NULL); + ck_assert_ptr_eq(efl_ui_single_selectable_last_selected_get(radio_group), NULL); EXPECT_EVT(1,-1); } EFL_END_TEST @@ -163,14 +163,14 @@ EFL_START_TEST(delete_setted) efl_ui_radio_group_register(radio_group, r); efl_ui_radio_group_register(radio_group, radio()); RESET_EVT - efl_ui_radio_group_selected_object_set(radio_group, r); + efl_ui_selectable_selected_set(r, EINA_TRUE); ck_assert_int_eq(efl_ui_radio_group_selected_value_get(radio_group), 1); - ck_assert_ptr_eq(efl_ui_radio_group_selected_object_get(radio_group), r); + ck_assert_ptr_eq(efl_ui_single_selectable_last_selected_get(radio_group), r); EXPECT_EVT(1,1); RESET_EVT efl_del(r); ck_assert_int_eq(efl_ui_radio_group_selected_value_get(radio_group), -1); - ck_assert_ptr_eq(efl_ui_radio_group_selected_object_get(radio_group), NULL); + ck_assert_ptr_eq(efl_ui_single_selectable_last_selected_get(radio_group), NULL); EXPECT_EVT(1,-1); } EFL_END_TEST @@ -185,12 +185,12 @@ EFL_START_TEST(external_setting) RESET_EVT efl_ui_selectable_selected_set(r, EINA_TRUE); ck_assert_int_eq(efl_ui_radio_group_selected_value_get(radio_group), 1); - ck_assert_ptr_eq(efl_ui_radio_group_selected_object_get(radio_group), r); + ck_assert_ptr_eq(efl_ui_single_selectable_last_selected_get(radio_group), r); EXPECT_EVT(1,1); RESET_EVT efl_ui_selectable_selected_set(r, EINA_FALSE); ck_assert_int_eq(efl_ui_radio_group_selected_value_get(radio_group), -1); - ck_assert_ptr_eq(efl_ui_radio_group_selected_object_get(radio_group), NULL); + ck_assert_ptr_eq(efl_ui_single_selectable_last_selected_get(radio_group), NULL); EXPECT_EVT(1,-1); } EFL_END_TEST diff --git a/src/tests/elementary/spec/efl_test_single_selectable.c b/src/tests/elementary/spec/efl_test_single_selectable.c index fd4b5e0a8b..5ec40b2747 100644 --- a/src/tests/elementary/spec/efl_test_single_selectable.c +++ b/src/tests/elementary/spec/efl_test_single_selectable.c @@ -8,10 +8,11 @@ /* spec-meta-start {"test-interface":"Efl.Ui.Single_Selectable", - "test-widgets": ["Efl.Ui.Grid", "Efl.Ui.List"], + "test-widgets": ["Efl.Ui.Grid", "Efl.Ui.List", "Efl.Ui.Radio_Box"], "custom-mapping" : { "Efl.Ui.Grid" : "EFL_UI_GRID_DEFAULT_ITEM_CLASS", - "Efl.Ui.List" : "EFL_UI_LIST_DEFAULT_ITEM_CLASS" + "Efl.Ui.List" : "EFL_UI_LIST_DEFAULT_ITEM_CLASS", + "Efl.Ui.Radio_Box" : "EFL_UI_RADIO_CLASS" } } @@ -49,9 +50,17 @@ EFL_START_TEST(last_selectable_check) efl_ui_selectable_selected_set(c2, EINA_TRUE); ck_assert_ptr_eq(efl_ui_single_selectable_last_selected_get(widget), c2); + if (c == 0) efl_loop_begin(efl_main_loop_get()); + ck_assert_int_eq(c, 1); + c = 0; + efl_ui_selectable_selected_set(c1, EINA_FALSE); ck_assert_ptr_eq(efl_ui_single_selectable_last_selected_get(widget), c2); efl_ui_selectable_selected_set(c2, EINA_FALSE); + if (c == 0) efl_loop_begin(efl_main_loop_get()); + ck_assert_int_eq(c, 1); + c = 0; + ck_assert_ptr_eq(efl_ui_single_selectable_last_selected_get(widget), NULL); } EFL_END_TEST --
