1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4 
5 
6 #include <Efl_Ui.h>
7 #include "elm_priv.h"
8 #include "efl_ui_tab_bar_private.h"
9 #include "els_box.h"
10 
11 #define MY_CLASS EFL_UI_TAB_BAR_CLASS
12 #define MY_CLASS_NAME "Efl.Ui.Tab_Bar"
13 
14 
15 EOLIAN static Efl_Ui_Selectable*
_efl_ui_tab_bar_efl_ui_single_selectable_last_selected_get(const Eo * obj EINA_UNUSED,Efl_Ui_Tab_Bar_Data * pd)16 _efl_ui_tab_bar_efl_ui_single_selectable_last_selected_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tab_Bar_Data *pd)
17 {
18    return pd->selected;
19 }
20 
21 EOLIAN static void
_efl_ui_tab_bar_efl_ui_single_selectable_fallback_selection_set(Eo * obj EINA_UNUSED,Efl_Ui_Tab_Bar_Data * pd,Efl_Ui_Selectable * fallback)22 _efl_ui_tab_bar_efl_ui_single_selectable_fallback_selection_set(Eo *obj EINA_UNUSED, Efl_Ui_Tab_Bar_Data *pd, Efl_Ui_Selectable *fallback)
23 {
24    pd->fallback_selection = fallback;
25    if (!pd->selected)
26      efl_ui_selectable_selected_set(pd->fallback_selection, EINA_TRUE);
27 }
28 
29 EOLIAN static void
_efl_ui_tab_bar_efl_ui_single_selectable_allow_manual_deselection_set(Eo * obj EINA_UNUSED,Efl_Ui_Tab_Bar_Data * pd,Eina_Bool allow_manual_deselection)30 _efl_ui_tab_bar_efl_ui_single_selectable_allow_manual_deselection_set(Eo *obj EINA_UNUSED, Efl_Ui_Tab_Bar_Data *pd, Eina_Bool allow_manual_deselection)
31 {
32    pd->allow_manual_deselection = !!allow_manual_deselection;
33 }
34 
35 EOLIAN static Eina_Bool
_efl_ui_tab_bar_efl_ui_single_selectable_allow_manual_deselection_get(const Eo * obj EINA_UNUSED,Efl_Ui_Tab_Bar_Data * pd)36 _efl_ui_tab_bar_efl_ui_single_selectable_allow_manual_deselection_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tab_Bar_Data *pd)
37 {
38    return pd->allow_manual_deselection;
39 }
40 
41 
42 EOLIAN static Efl_Ui_Selectable*
_efl_ui_tab_bar_efl_ui_single_selectable_fallback_selection_get(const Eo * obj EINA_UNUSED,Efl_Ui_Tab_Bar_Data * pd)43 _efl_ui_tab_bar_efl_ui_single_selectable_fallback_selection_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tab_Bar_Data *pd)
44 {
45    return pd->fallback_selection;
46 }
47 
48 static void _remove_item(Eo *obj, Efl_Ui_Tab_Bar_Data *pd, Efl_Ui_Item *item);
49 
50 static void
_selelction_change_cb(void * data,const Efl_Event * ev)51 _selelction_change_cb(void *data, const Efl_Event *ev)
52 {
53    Efl_Ui_Tab_Bar_Data *pd = efl_data_scope_safe_get(data, MY_CLASS);
54 
55    EINA_SAFETY_ON_NULL_RETURN(pd);
56 
57    if (!efl_ui_selectable_selected_get(ev->object))
58      {
59         if (pd->selected == ev->object)
60           {
61              pd->selected = NULL;
62           }
63         //checkout if we want to do fallback handling
64         if (!pd->in_value_change)
65           {
66              if (!pd->selected && pd->fallback_selection)
67                efl_ui_selectable_selected_set(pd->fallback_selection, EINA_TRUE);
68           }
69      }
70    else
71      {
72         pd->in_value_change = EINA_TRUE;
73         if (pd->selected)
74           efl_ui_selectable_selected_set(pd->selected, EINA_FALSE);
75         pd->in_value_change = EINA_FALSE;
76         EINA_SAFETY_ON_FALSE_RETURN(!pd->selected);
77         pd->selected = ev->object;
78         efl_event_callback_call(data, EFL_UI_EVENT_ITEM_SELECTED, NULL);
79      }
80    if (!pd->in_value_change)
81      {
82         efl_event_callback_call(data, EFL_UI_SELECTABLE_EVENT_SELECTION_CHANGED, NULL);
83      }
84 }
85 
86 static void
_invalidate_cb(void * data,const Efl_Event * ev)87 _invalidate_cb(void *data, const Efl_Event *ev)
88 {
89    Efl_Ui_Tab_Bar_Data *pd = efl_data_scope_safe_get(data, MY_CLASS);
90 
91    EINA_SAFETY_ON_NULL_RETURN(pd);
92    _remove_item(data, pd, ev->object);
93 }
94 
95 EFL_CALLBACKS_ARRAY_DEFINE(item_listeners,
96   {EFL_UI_EVENT_SELECTED_CHANGED, _selelction_change_cb},
97   {EFL_EVENT_INVALIDATE, _invalidate_cb},
98 )
99 
100 static void
_remove_item(Eo * obj,Efl_Ui_Tab_Bar_Data * pd,Efl_Ui_Item * item)101 _remove_item(Eo *obj, Efl_Ui_Tab_Bar_Data *pd, Efl_Ui_Item *item)
102 {
103    if (pd->selected == item)
104      pd->selected = NULL;
105 
106    efl_event_callback_array_del(item, item_listeners(), obj);
107    if (efl_alive_get(item))
108      _elm_widget_sub_object_redirect_to_top(obj, item);
109 }
110 
111 static Eina_Bool
_register_item(Eo * obj,Efl_Ui_Tab_Bar_Data * pd EINA_UNUSED,Eo * subitem)112 _register_item(Eo *obj, Efl_Ui_Tab_Bar_Data *pd EINA_UNUSED, Eo *subitem)
113 {
114    EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_isa(subitem, EFL_UI_TAB_BAR_DEFAULT_ITEM_CLASS), EINA_FALSE);
115    EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_ui_widget_sub_object_add(obj, subitem), EINA_FALSE);
116    efl_ui_item_container_set(subitem, obj);
117    efl_event_callback_array_add(subitem, item_listeners(), obj);
118    efl_gfx_hint_align_set(subitem, EVAS_HINT_FILL, EVAS_HINT_FILL);
119    return EINA_TRUE;
120 }
121 
122 EOLIAN static void
_efl_ui_tab_bar_efl_object_destructor(Eo * obj,Efl_Ui_Tab_Bar_Data * sd EINA_UNUSED)123 _efl_ui_tab_bar_efl_object_destructor(Eo *obj, Efl_Ui_Tab_Bar_Data *sd EINA_UNUSED)
124 {
125    efl_destructor(efl_super(obj, MY_CLASS));
126 }
127 
128 EOLIAN static Efl_Object *
_efl_ui_tab_bar_efl_object_constructor(Eo * obj,Efl_Ui_Tab_Bar_Data * sd)129 _efl_ui_tab_bar_efl_object_constructor(Eo *obj, Efl_Ui_Tab_Bar_Data *sd)
130 {
131    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
132 
133    if (!elm_widget_theme_klass_get(obj))
134      elm_widget_theme_klass_set(obj, "tab_bar");
135 
136    obj = efl_constructor(efl_super(obj, MY_CLASS));
137 
138    sd->bx = efl_add(EFL_UI_BOX_CLASS, obj);
139    efl_ui_box_homogeneous_set(sd->bx, EINA_TRUE);
140    efl_ui_layout_orientation_set(sd->bx, EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL);
141    efl_ui_widget_internal_set(sd->bx, EINA_TRUE);
142 
143    efl_composite_attach(obj, sd->bx);
144 
145    return obj;
146 }
147 
148 EOLIAN static Efl_Object*
_efl_ui_tab_bar_efl_object_finalize(Eo * obj,Efl_Ui_Tab_Bar_Data * pd)149 _efl_ui_tab_bar_efl_object_finalize(Eo *obj, Efl_Ui_Tab_Bar_Data *pd)
150 {
151    Eo *o = efl_finalize(efl_super(obj, MY_CLASS));
152 
153    if (!o) return NULL;
154 
155    efl_content_set(efl_part(obj,"efl.content"), pd->bx);
156 
157    return o;
158 }
159 
160 EOLIAN static Eina_Bool
_efl_ui_tab_bar_efl_pack_pack_clear(Eo * obj,Efl_Ui_Tab_Bar_Data * pd)161 _efl_ui_tab_bar_efl_pack_pack_clear(Eo *obj, Efl_Ui_Tab_Bar_Data *pd)
162 {
163    for (int i = 0; i < efl_content_count(pd->bx); ++i)
164      {
165         _remove_item(obj, pd, efl_pack_content_get(pd->bx, i));
166      }
167    return efl_pack_clear(pd->bx);
168 }
169 
170 EOLIAN static Eina_Bool
_efl_ui_tab_bar_efl_pack_unpack_all(Eo * obj,Efl_Ui_Tab_Bar_Data * pd)171 _efl_ui_tab_bar_efl_pack_unpack_all(Eo *obj, Efl_Ui_Tab_Bar_Data *pd)
172 {
173    for (int i = 0; i < efl_content_count(pd->bx); ++i)
174      {
175         _remove_item(obj, pd, efl_pack_content_get(pd->bx, i));
176      }
177    return efl_pack_unpack_all(pd->bx);
178 }
179 
180 EOLIAN static Eina_Bool
_efl_ui_tab_bar_efl_pack_unpack(Eo * obj,Efl_Ui_Tab_Bar_Data * pd,Efl_Gfx_Entity * subobj)181 _efl_ui_tab_bar_efl_pack_unpack(Eo *obj, Efl_Ui_Tab_Bar_Data *pd, Efl_Gfx_Entity *subobj)
182 {
183    _remove_item(obj, pd, subobj);
184    return efl_pack_unpack(pd->bx, subobj);
185 }
186 
187 EOLIAN static Eina_Bool
_efl_ui_tab_bar_efl_pack_linear_pack_begin(Eo * obj,Efl_Ui_Tab_Bar_Data * pd,Efl_Gfx_Entity * subobj)188 _efl_ui_tab_bar_efl_pack_linear_pack_begin(Eo *obj, Efl_Ui_Tab_Bar_Data *pd, Efl_Gfx_Entity *subobj)
189 {
190    EINA_SAFETY_ON_FALSE_RETURN_VAL(_register_item(obj, pd, subobj), EINA_FALSE);
191    return efl_pack_begin(pd->bx, subobj);
192 }
193 
194 EOLIAN static Eina_Bool
_efl_ui_tab_bar_efl_pack_linear_pack_end(Eo * obj,Efl_Ui_Tab_Bar_Data * pd,Efl_Gfx_Entity * subobj)195 _efl_ui_tab_bar_efl_pack_linear_pack_end(Eo *obj, Efl_Ui_Tab_Bar_Data *pd, Efl_Gfx_Entity *subobj)
196 {
197    EINA_SAFETY_ON_FALSE_RETURN_VAL(_register_item(obj, pd, subobj), EINA_FALSE);
198    return efl_pack_end(pd->bx, subobj);
199 }
200 
201 EOLIAN static Eina_Bool
_efl_ui_tab_bar_efl_pack_linear_pack_before(Eo * obj,Efl_Ui_Tab_Bar_Data * pd,Efl_Gfx_Entity * subobj,const Efl_Gfx_Entity * existing)202 _efl_ui_tab_bar_efl_pack_linear_pack_before(Eo *obj, Efl_Ui_Tab_Bar_Data *pd, Efl_Gfx_Entity *subobj, const Efl_Gfx_Entity *existing)
203 {
204    if (existing)
205      EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_pack_index_get(pd->bx, existing) >= 0, EINA_FALSE);
206    EINA_SAFETY_ON_FALSE_RETURN_VAL(_register_item(obj, pd, subobj), EINA_FALSE);
207    return efl_pack_before(pd->bx, subobj, existing);
208 }
209 
210 EOLIAN static Eina_Bool
_efl_ui_tab_bar_efl_pack_linear_pack_after(Eo * obj,Efl_Ui_Tab_Bar_Data * pd,Efl_Gfx_Entity * subobj,const Efl_Gfx_Entity * existing)211 _efl_ui_tab_bar_efl_pack_linear_pack_after(Eo *obj, Efl_Ui_Tab_Bar_Data *pd, Efl_Gfx_Entity *subobj, const Efl_Gfx_Entity *existing)
212 {
213    if (existing)
214      EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_pack_index_get(pd->bx, existing) >= 0, EINA_FALSE);
215    EINA_SAFETY_ON_FALSE_RETURN_VAL(_register_item(obj, pd, subobj), EINA_FALSE);
216    return efl_pack_after(pd->bx, subobj, existing);
217 }
218 
219 EOLIAN static Eina_Bool
_efl_ui_tab_bar_efl_pack_linear_pack_at(Eo * obj,Efl_Ui_Tab_Bar_Data * pd,Efl_Gfx_Entity * subobj,int index)220 _efl_ui_tab_bar_efl_pack_linear_pack_at(Eo *obj, Efl_Ui_Tab_Bar_Data *pd, Efl_Gfx_Entity *subobj, int index)
221 {
222    EINA_SAFETY_ON_FALSE_RETURN_VAL(_register_item(obj, pd, subobj), EINA_FALSE);
223    return efl_pack_at(pd->bx, subobj, index);
224 }
225 
226 EOLIAN static int
_efl_ui_tab_bar_efl_container_content_count(Eo * obj EINA_UNUSED,Efl_Ui_Tab_Bar_Data * pd)227 _efl_ui_tab_bar_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_Tab_Bar_Data *pd)
228 {
229    return efl_content_count(pd->bx);
230 }
231 
232 EOLIAN static Eina_Iterator*
_efl_ui_tab_bar_efl_container_content_iterate(Eo * obj EINA_UNUSED,Efl_Ui_Tab_Bar_Data * pd)233 _efl_ui_tab_bar_efl_container_content_iterate(Eo *obj EINA_UNUSED, Efl_Ui_Tab_Bar_Data *pd)
234 {
235    return efl_content_iterate(pd->bx);
236 }
237 
238 EOLIAN static Efl_Gfx_Entity*
_efl_ui_tab_bar_efl_pack_linear_pack_unpack_at(Eo * obj,Efl_Ui_Tab_Bar_Data * pd,int index)239 _efl_ui_tab_bar_efl_pack_linear_pack_unpack_at(Eo *obj, Efl_Ui_Tab_Bar_Data *pd, int index)
240 {
241    _remove_item(obj, pd, efl_pack_content_get(pd->bx, index));
242    return efl_pack_unpack_at(pd->bx, index);
243 }
244 
245 EOLIAN static Eina_Bool
_efl_ui_tab_bar_efl_pack_pack(Eo * obj,Efl_Ui_Tab_Bar_Data * pd,Efl_Gfx_Entity * subobj)246 _efl_ui_tab_bar_efl_pack_pack(Eo *obj, Efl_Ui_Tab_Bar_Data *pd, Efl_Gfx_Entity *subobj)
247 {
248    EINA_SAFETY_ON_FALSE_RETURN_VAL(_register_item(obj, pd, subobj), EINA_FALSE);
249    return efl_pack(pd->bx, subobj);
250 }
251 
252 #include "efl_ui_tab_bar.eo.c"
253