efl_ui_tab_pager: do not directly inherit from spotlight anymore

spotlight moved away from layout, this could have also been solved with
setting a edje object as resize object. However, this commit now
contains the spotlight internally.

The resons why containing it internally is better:
- You now only have one way of selecting a page, marking it as selection
via the selectable API
- You cannot build race conditions between selecting a page and setting
the active_element anymore
- The tab_pager is now also just a simple single_selectable implementor,
which makes this whole usage more convinient.
- There is now a event you can listen to if you want to know if
something has changed the selected item
- push and pop would have never worked correctly in the tab_pager, as
the item would have appeared always before the item was "faded" in. This
possibility is not given anymore

Last but not least, this makes tab_pager usable again, the tab bar is
displayed again.

Differential Revision: https://phab.enlightenment.org/D10775
This commit is contained in:
Marcel Hollerbach 2019-12-02 21:41:46 +01:00
parent 70849969b8
commit 77a04db578
4 changed files with 145 additions and 46 deletions

View File

@ -139,7 +139,7 @@ test_ui_tab_pager(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *ev
page = tab_page_add(tp);
efl_pack_end(tp, page);
if (i == 0)
efl_ui_spotlight_active_element_set(tp, page);
efl_ui_selectable_selected_set(efl_ui_tab_page_tab_bar_item_get(page), EINA_TRUE);
}
ad = (App_Data*)calloc(1, sizeof(App_Data));
@ -174,7 +174,9 @@ static void
_tab_set_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
Tab_Set_Data *tsd = data;
efl_ui_spotlight_active_element_set(tsd->tab_pager, efl_pack_content_get(tsd->tab_pager, elm_spinner_value_get(tsd->spinner)));
Efl_Ui_Tab_Page *page = efl_pack_content_get(tsd->tab_pager, elm_spinner_value_get(tsd->spinner));
efl_ui_selectable_selected_set(efl_ui_tab_page_tab_bar_item_get(page), EINA_TRUE);
}
static void
@ -246,7 +248,7 @@ _pack_before_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
Eo *tab_pager = data;
Eo *tab_page, *cur_tab_page;
cur_tab_page = efl_ui_spotlight_active_element_get(tab_pager);
cur_tab_page = efl_ui_selectable_last_selected_get(tab_pager);
tab_page = tab_page_add(tab_pager);
@ -259,7 +261,7 @@ _pack_after_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
Eo *tab_pager = data;
Eo *tab_page, *cur_tab_page;
cur_tab_page = efl_ui_spotlight_active_element_get(tab_pager);
cur_tab_page = efl_ui_selectable_last_selected_get(tab_pager);
tab_page = tab_page_add(tab_pager);
@ -361,7 +363,7 @@ _unpack_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
Eo *tab_pager = data;
Eo *tab_page = efl_ui_spotlight_active_element_get(tab_pager);
Eo *tab_page = efl_ui_selectable_last_selected_get(tab_pager);
efl_pack_unpack(tab_pager, tab_page);
efl_del(tab_page);
@ -460,7 +462,7 @@ _change_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
char *label = NULL;
char *icon = NULL;
tab_page = efl_ui_spotlight_active_element_get(tcd->tab_pager);
tab_page = efl_ui_selectable_last_selected_get(tcd->tab_pager);
if (efl_ui_selectable_selected_get(tcd->label_check))
{
@ -528,20 +530,20 @@ static void
_tran_set_btn_scroll_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
Efl_Ui_Spotlight_Scroll_Manager *scroll = efl_new(EFL_UI_SPOTLIGHT_SCROLL_MANAGER_CLASS);
efl_ui_spotlight_manager_set(data, scroll);
efl_ui_tab_pager_spotlight_manager_set(data, scroll);
}
static void
_tran_set_btn_stack_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
Efl_Ui_Spotlight_Scroll_Manager *stack = efl_new(EFL_UI_SPOTLIGHT_FADE_MANAGER_CLASS);
efl_ui_spotlight_manager_set(data, stack);
efl_ui_tab_pager_spotlight_manager_set(data, stack);
}
static void
_tran_unset_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
efl_ui_spotlight_manager_set(data, NULL);
efl_ui_tab_pager_spotlight_manager_set(data, NULL);
}
static void

View File

@ -12,24 +12,25 @@
#define MY_CLASS EFL_UI_TAB_PAGER_CLASS
static void
_select(Eo *obj EINA_UNUSED, Efl_Ui_Tab_Page *page)
_efl_ui_tab_pager_spotlight_manager_set(Eo *obj EINA_UNUSED, Efl_Ui_Tab_Pager_Data *pd, Efl_Ui_Spotlight_Manager *manager)
{
Efl_Ui_Tab_Bar_Default_Item *item = efl_ui_tab_page_tab_bar_item_get(page);
if (!efl_ui_selectable_selected_get(item))
efl_ui_selectable_selected_set(item, EINA_TRUE);
efl_ui_spotlight_manager_set(pd->spotlight, manager);
}
static void
_tab_select_cb(void *data, const Efl_Event *event)
{
Efl_Ui_Tab_Bar_Default_Item *selected;
Efl_Ui_Tab_Page *page;
Efl_Ui_Tab_Pager_Data *pd;
pd = efl_data_scope_get(data, MY_CLASS);
EINA_SAFETY_ON_NULL_RETURN(pd);
selected = efl_ui_selectable_last_selected_get(event->object);
page = efl_parent_get(selected);
if (efl_ui_spotlight_active_element_get(data))
efl_ui_spotlight_active_element_set(data, page);
if (efl_ui_spotlight_active_element_get(pd->spotlight))
efl_ui_spotlight_active_element_set(pd->spotlight, page);
}
EOLIAN static Efl_Canvas_Object *
@ -38,13 +39,6 @@ _efl_ui_tab_pager_tab_bar_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tab_Pager_Data *
return sd->tab_bar;
}
EOLIAN static void
_efl_ui_tab_pager_efl_ui_spotlight_container_active_element_set(Eo *obj, Efl_Ui_Tab_Pager_Data *sd EINA_UNUSED, Efl_Ui_Widget *element)
{
efl_ui_spotlight_active_element_set(efl_super(obj, MY_CLASS), element);
_select(obj, element);
}
EOLIAN static void
_efl_ui_tab_pager_efl_object_destructor(Eo *obj, Efl_Ui_Tab_Pager_Data *sd)
{
@ -66,10 +60,26 @@ _efl_ui_tab_pager_efl_object_constructor(Eo *obj, Efl_Ui_Tab_Pager_Data *sd)
sd->tab_bar = efl_add(EFL_UI_TAB_BAR_CLASS, obj);
efl_event_callback_add(sd->tab_bar, EFL_UI_EVENT_ITEM_SELECTED, _tab_select_cb, obj);
efl_event_callback_forwarder_del(sd->tab_bar, EFL_UI_SELECTABLE_EVENT_SELECTION_CHANGED, obj);
sd->spotlight = efl_add(EFL_UI_SPOTLIGHT_CONTAINER_CLASS, obj);
return obj;
}
EOLIAN static Eina_Error
_efl_ui_tab_pager_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_Tab_Pager_Data *pd)
{
Eina_Error err;
err = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS));
efl_content_set(efl_part(obj, "efl.tab_root"), pd->tab_bar);
efl_content_set(efl_part(obj, "efl.page_root"), pd->spotlight);
return err;
}
EOLIAN static Efl_Object*
_efl_ui_tab_pager_efl_object_finalize(Eo *obj, Efl_Ui_Tab_Pager_Data *pd)
{
@ -80,91 +90,157 @@ _efl_ui_tab_pager_efl_object_finalize(Eo *obj, Efl_Ui_Tab_Pager_Data *pd)
return obj;
}
EOLIAN static Eina_Bool
_efl_ui_tab_pager_efl_pack_pack_clear(Eo *obj, Efl_Ui_Tab_Pager_Data *sd)
EOLIAN static int
_efl_ui_tab_pager_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_Tab_Pager_Data *pd)
{
if (!efl_pack_clear(sd->tab_bar))
return EINA_FALSE;
return efl_pack_clear(efl_super(obj, MY_CLASS));
return efl_content_count(pd->spotlight);
}
EOLIAN static Eina_Iterator*
_efl_ui_tab_pager_efl_container_content_iterate(Eo *obj EINA_UNUSED, Efl_Ui_Tab_Pager_Data *pd)
{
return efl_content_iterate(pd->spotlight);
}
EOLIAN static Eina_Bool
_efl_ui_tab_pager_efl_pack_unpack_all(Eo *obj, Efl_Ui_Tab_Pager_Data *sd)
_efl_ui_tab_pager_efl_pack_pack(Eo *obj EINA_UNUSED, Efl_Ui_Tab_Pager_Data *pd, Efl_Gfx_Entity *subobj)
{
return efl_pack(pd->spotlight, subobj);
}
EOLIAN static Efl_Gfx_Entity*
_efl_ui_tab_pager_efl_pack_linear_pack_content_get(Eo *obj EINA_UNUSED, Efl_Ui_Tab_Pager_Data *pd, int index)
{
return efl_pack_content_get(pd->spotlight, index);
}
EOLIAN static int
_efl_ui_tab_pager_efl_pack_linear_pack_index_get(Eo *obj EINA_UNUSED, Efl_Ui_Tab_Pager_Data *pd, const Efl_Gfx_Entity *subobj)
{
return efl_pack_index_get(pd->spotlight, subobj);
}
EOLIAN static Eina_Bool
_efl_ui_tab_pager_efl_pack_pack_clear(Eo *obj EINA_UNUSED, Efl_Ui_Tab_Pager_Data *sd)
{
if (!efl_pack_clear(sd->tab_bar))
return EINA_FALSE;
return efl_pack_clear(sd->spotlight);
}
EOLIAN static Eina_Bool
_efl_ui_tab_pager_efl_pack_unpack_all(Eo *obj EINA_UNUSED, Efl_Ui_Tab_Pager_Data *sd)
{
if (!efl_pack_unpack_all(sd->tab_bar))
return EINA_FALSE;
return efl_pack_unpack_all(efl_super(obj, MY_CLASS));
return efl_pack_unpack_all(sd->spotlight);
}
#define ITEM(s) efl_ui_tab_page_tab_bar_item_get(s)
EOLIAN static Eina_Bool
_efl_ui_tab_pager_efl_pack_unpack(Eo *obj, Efl_Ui_Tab_Pager_Data *sd, Efl_Gfx_Entity *subobj)
_efl_ui_tab_pager_efl_pack_unpack(Eo *obj EINA_UNUSED, Efl_Ui_Tab_Pager_Data *sd, Efl_Gfx_Entity *subobj)
{
if (!efl_pack_unpack(sd->tab_bar, ITEM(subobj)))
return EINA_FALSE;
return efl_pack_unpack(efl_super(obj, MY_CLASS), subobj);
return efl_pack_unpack(sd->spotlight, subobj);
}
EOLIAN static Eina_Bool
_efl_ui_tab_pager_efl_pack_linear_pack_begin(Eo *obj,
_efl_ui_tab_pager_efl_pack_linear_pack_begin(Eo *obj EINA_UNUSED,
Efl_Ui_Tab_Pager_Data *sd,
Efl_Gfx_Entity *subobj)
{
if (!efl_pack_begin(sd->tab_bar, ITEM(subobj)))
return EINA_FALSE;
return efl_pack_begin(efl_super(obj, MY_CLASS), subobj);
return efl_pack_begin(sd->spotlight, subobj);
}
EOLIAN static Eina_Bool
_efl_ui_tab_pager_efl_pack_linear_pack_end(Eo *obj,
_efl_ui_tab_pager_efl_pack_linear_pack_end(Eo *obj EINA_UNUSED,
Efl_Ui_Tab_Pager_Data *sd,
Efl_Gfx_Entity *subobj)
{
if (!efl_pack_end(sd->tab_bar, ITEM(subobj)))
return EINA_FALSE;
return efl_pack_end(efl_super(obj, MY_CLASS), subobj);
return efl_pack_end(sd->spotlight, subobj);
}
EOLIAN static Eina_Bool
_efl_ui_tab_pager_efl_pack_linear_pack_before(Eo *obj,
_efl_ui_tab_pager_efl_pack_linear_pack_before(Eo *obj EINA_UNUSED,
Efl_Ui_Tab_Pager_Data *sd,
Efl_Gfx_Entity *subobj,
const Efl_Gfx_Entity *existing)
{
if (!efl_pack_before(sd->tab_bar, ITEM(subobj), ITEM(existing)))
return EINA_FALSE;
return efl_pack_before(efl_super(obj, MY_CLASS), subobj, existing);
return efl_pack_before(sd->spotlight, subobj, existing);
}
EOLIAN static Eina_Bool
_efl_ui_tab_pager_efl_pack_linear_pack_after(Eo *obj,
_efl_ui_tab_pager_efl_pack_linear_pack_after(Eo *obj EINA_UNUSED,
Efl_Ui_Tab_Pager_Data *sd,
Efl_Gfx_Entity *subobj,
const Efl_Gfx_Entity *existing)
{
if (!efl_pack_after(sd->tab_bar, ITEM(subobj), ITEM(existing)))
return EINA_FALSE;
return efl_pack_after(efl_super(obj, MY_CLASS), subobj, existing);
return efl_pack_after(sd->spotlight, subobj, existing);
}
EOLIAN static Eina_Bool
_efl_ui_tab_pager_efl_pack_linear_pack_at(Eo *obj,
_efl_ui_tab_pager_efl_pack_linear_pack_at(Eo *obj EINA_UNUSED,
Efl_Ui_Tab_Pager_Data *sd,
Efl_Gfx_Entity *subobj,
int index)
{
if (!efl_pack_at(sd->tab_bar, ITEM(subobj), index))
return EINA_FALSE;
return efl_pack_at(efl_super(obj, MY_CLASS), subobj, index);
return efl_pack_at(sd->spotlight, subobj, index);
}
EOLIAN static Efl_Gfx_Entity *
_efl_ui_tab_pager_efl_pack_linear_pack_unpack_at(Eo *obj, Efl_Ui_Tab_Pager_Data *sd, int index)
_efl_ui_tab_pager_efl_pack_linear_pack_unpack_at(Eo *obj EINA_UNUSED, Efl_Ui_Tab_Pager_Data *sd, int index)
{
if (!efl_pack_unpack_at(sd->tab_bar, index))
return NULL;
return efl_pack_unpack_at(efl_super(obj, MY_CLASS), index);
return efl_pack_unpack_at(sd->spotlight, index);
}
EOLIAN static Efl_Ui_Selectable*
_efl_ui_tab_pager_efl_ui_single_selectable_last_selected_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tab_Pager_Data *pd)
{
Efl_Ui_Tab_Bar_Default_Item *item = efl_ui_selectable_last_selected_get(pd->tab_bar);
return efl_parent_get(item);
}
EOLIAN static void
_efl_ui_tab_pager_efl_ui_single_selectable_fallback_selection_set(Eo *obj EINA_UNUSED, Efl_Ui_Tab_Pager_Data *pd, Efl_Ui_Selectable *fallback)
{
efl_ui_selectable_fallback_selection_set(pd->tab_bar, efl_ui_tab_page_tab_bar_item_get(fallback));
}
EOLIAN static Efl_Ui_Selectable*
_efl_ui_tab_pager_efl_ui_single_selectable_fallback_selection_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tab_Pager_Data *pd)
{
Efl_Ui_Tab_Bar_Default_Item *item = efl_ui_selectable_fallback_selection_get(pd->tab_bar);
return efl_parent_get(item);
}
EOLIAN static void
_efl_ui_tab_pager_efl_ui_single_selectable_allow_manual_deselection_set(Eo *obj EINA_UNUSED, Efl_Ui_Tab_Pager_Data *pd, Eina_Bool allow_manual_deselection)
{
efl_ui_selectable_allow_manual_deselection_set(pd->tab_bar, allow_manual_deselection);
}
EOLIAN static Eina_Bool
_efl_ui_tab_pager_efl_ui_single_selectable_allow_manual_deselection_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tab_Pager_Data *pd)
{
return efl_ui_selectable_allow_manual_deselection_get(pd->tab_bar);
}
#include "efl_ui_tab_pager.eo.c"

View File

@ -1,9 +1,12 @@
class @beta Efl.Ui.Tab_Pager extends Efl.Ui.Spotlight.Container
class @beta Efl.Ui.Tab_Pager extends Efl.Ui.Layout_Base
implements Efl.Pack_Linear, Efl.Ui.Single_Selectable
{
[[Container for @Efl.Ui.Tab_Page
This container consists out of a Efl.Ui.Tab_Bar and a place to display the content of the pages.
The items that are generated out of the pages will be displayed in the tab bar of this pager.
The object has an internal @Efl.Ui.Spotlight.Container which displays the content of a item.
]]
methods {
@property tab_bar {
@ -15,20 +18,37 @@ class @beta Efl.Ui.Tab_Pager extends Efl.Ui.Spotlight.Container
tab_bar: Efl.Ui.Tab_Bar; [[Tab bar for the items of the @Efl.Ui.Tab_Page]]
}
}
@property spotlight_manager {
[[Spotlight manager of the internal spotlight container]]
set {
}
values {
manager : Efl.Ui.Spotlight.Manager @move; [[The @Efl.Ui.Spotlight.Manager to pass to the internal @Efl.Ui.Spotlight.Container]]
}
}
}
implements {
Efl.Object.constructor;
Efl.Object.destructor;
Efl.Object.finalize;
Efl.Container.content_count;
Efl.Container.content_iterate;
Efl.Pack.pack_clear;
Efl.Pack.unpack_all;
Efl.Pack.unpack;
Efl.Pack.pack;
Efl.Pack_Linear.pack_begin;
Efl.Pack_Linear.pack_end;
Efl.Pack_Linear.pack_before;
Efl.Pack_Linear.pack_after;
Efl.Pack_Linear.pack_at;
Efl.Pack_Linear.pack_content_get;
Efl.Pack_Linear.pack_index_get;
Efl.Pack_Linear.pack_unpack_at;
Efl.Ui.Spotlight.Container.active_element { set; }
Efl.Ui.Single_Selectable.last_selected {get;}
Efl.Ui.Single_Selectable.fallback_selection {set; get;}
Efl.Ui.Single_Selectable.allow_manual_deselection {set; get;}
Efl.Ui.Widget.theme_apply;
}
}

View File

@ -6,6 +6,7 @@ typedef struct _Efl_Ui_Tab_Pager_Data Efl_Ui_Tab_Pager_Data;
struct _Efl_Ui_Tab_Pager_Data
{
Eo *tab_bar;
Eo *spotlight;
};