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 <michael.blumenkrantz@gmail.com>
Differential Revision: https://phab.enlightenment.org/D9706
This commit is contained in:
Marcel Hollerbach 2019-08-22 15:06:22 +02:00
parent c6e338bb9a
commit d445e5240b
9 changed files with 89 additions and 72 deletions

View File

@ -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());

View File

@ -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);

View File

@ -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);
}

View File

@ -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));
}

View File

@ -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.

View File

@ -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;
pd->fallback_object = fallback;
if (pd->selected == selected_object) return;
if (!pd->selected)
efl_ui_selectable_selected_set(pd->fallback_object, EINA_TRUE);
}
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->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,17 +64,42 @@ _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)
{
efl_ui_radio_group_selected_object_set(data, NULL);
pd->selected = NULL;
}
//checkout if we want to do fallback handling
if (!pd->in_value_change)
{
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);
}
}
@ -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);

View File

@ -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;}
}
}

View File

@ -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

View File

@ -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