1 #include "e_mod_main.h"
2 
3 typedef struct _Tab Tab;
4 
5 struct _Tab
6 {
7    Tab_View    *tab_view;
8    Evry_Plugin *plugin;
9    Evas_Object *o_tab;
10 
11    int          cw, mw;
12 };
13 
14 static void _tabs_update(Tab_View *v);
15 static void _plugin_select(Tab_View *v, Evry_Plugin *p);
16 static void _plugin_next(Tab_View *v);
17 static void _plugin_prev(Tab_View *v);
18 
19 static Eina_Bool
_timer_cb(void * data)20 _timer_cb(void *data)
21 {
22    Tab_View *v = data;
23 
24    _tabs_update(v);
25 
26    v->timer = NULL;
27    return ECORE_CALLBACK_CANCEL;
28 }
29 
30 static void
_tab_cb_down(void * data EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)31 _tab_cb_down(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
32 {
33    /* Evas_Event_Mouse_Down *ev = event_info; */
34 }
35 
36 static void
_tab_cb_up(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)37 _tab_cb_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
38 {
39    Evas_Event_Mouse_Up *ev = event_info;
40    Tab *tab = data;
41    Tab_View *v = tab->tab_view;
42 
43    if (ev->button != 1)
44      return;
45 
46    if (tab->plugin)
47      {
48         _plugin_select(v, tab->plugin);
49         v->view->update(v->view);
50      }
51    else
52      {
53         evry_browse_back(v->state->selector);
54      }
55 }
56 
57 static void
_tabs_cb_wheel(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)58 _tabs_cb_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
59 {
60    Evas_Event_Mouse_Wheel *ev = event_info;
61    Tab_View *v = data;
62 
63    if (ev->z > 0)
64      {
65         _plugin_next(v);
66         v->view->update(v->view);
67      }
68    else if (ev->z < 0)
69      {
70         _plugin_prev(v);
71         v->view->update(v->view);
72      }
73 }
74 
75 static Tab *
_add_tab(Tab_View * v,Evry_Plugin * p)76 _add_tab(Tab_View *v, Evry_Plugin *p)
77 {
78    Evas_Object *o;
79    Tab *tab = E_NEW(Tab, 1);
80    tab->plugin = p;
81    tab->tab_view = v;
82    o = edje_object_add(v->evas);
83    if (p)
84      {
85         e_theme_edje_object_set(o, "base/theme/modules/everything",
86                                 "e/modules/everything/tab_item");
87         edje_object_part_text_set(o, "e.text.label", EVRY_ITEM(p)->label);
88      }
89    else
90      {
91         e_theme_edje_object_set(o, "base/theme/modules/everything",
92                                 "e/modules/everything/tab_item/back");
93         edje_object_part_text_set(o, "e.text.label", _("Back"));
94      }
95 
96    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN,
97                                   _tab_cb_down, tab);
98    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP,
99                                   _tab_cb_up, tab);
100    tab->o_tab = o;
101 
102    edje_object_size_min_calc(o, &tab->cw, NULL);
103    edje_object_size_min_get(o, &tab->mw, NULL);
104 
105    v->tabs = eina_list_append(v->tabs, tab);
106 
107    return tab;
108 }
109 
110 static void
_tabs_update(Tab_View * v)111 _tabs_update(Tab_View *v)
112 {
113    Eina_List *l, *ll, *plugins;
114    Evry_Plugin *p;
115    const Evry_State *s = v->state;
116    Tab *tab;
117    Evas_Coord w, x, mw;
118    Evas_Object *o;
119    unsigned int cur = 0, i = 0;
120 
121    if (s->delete_me)
122      return;
123 
124    evas_object_geometry_get(v->o_tabs, &x, NULL, &w, NULL);
125 
126    if (!w && !v->timer)
127      {
128         v->timer = ecore_timer_loop_add(0.001, _timer_cb, v);
129         return;
130      }
131 
132    /* remove tabs for not active plugins */
133 
134    EINA_LIST_FOREACH (v->tabs, l, tab)
135      {
136         if (!tab->plugin)
137           continue;
138 
139         elm_box_unpack(v->o_tabs, tab->o_tab);
140         evas_object_hide(tab->o_tab);
141      }
142 
143    if (s->selector->states->next)
144      {
145         cur++;
146         i++;
147 
148         if (!(tab = eina_list_data_get(v->tabs)))
149           {
150              tab = _add_tab(v, NULL);
151 
152              o = tab->o_tab;
153              evas_object_show(o);
154              mw = tab->cw;
155              if (mw < tab->mw) mw = tab->mw;
156              E_EXPAND(o);
157              E_FILL(o);
158              evas_object_size_hint_min_set(o, mw, 1);
159              elm_box_pack_end(v->o_tabs, o);
160           }
161      }
162 
163    for (l = s->cur_plugins; l; l = l->next, cur++)
164      if (l->data == s->plugin) break;
165 
166    if (cur > 2)
167      {
168         if ((cur + 1) == eina_list_count(s->cur_plugins))
169           plugins = eina_list_nth_list(s->cur_plugins, cur - 3);
170         else
171           plugins = eina_list_nth_list(s->cur_plugins, cur - 2);
172      }
173    else
174      {
175         plugins = s->cur_plugins;
176      }
177 
178    /* show/update tabs of active plugins */
179    EINA_LIST_FOREACH (plugins, l, p)
180      {
181         EINA_LIST_FOREACH (v->tabs, ll, tab)
182           if (tab->plugin == p) break;
183 
184         if (!tab && !(tab = _add_tab(v, p)))
185           continue;
186 
187         o = tab->o_tab;
188         evas_object_show(o);
189         mw = tab->cw;
190         if (mw < tab->mw) mw = tab->mw;
191         E_EXPAND(o);
192         E_FILL(o);
193         evas_object_size_hint_min_set(o, mw, 1);
194         elm_box_pack_end(v->o_tabs, o);
195 
196         if (s->plugin == p)
197           edje_object_signal_emit(o, "e,state,selected", "e");
198         else
199           edje_object_signal_emit(o, "e,state,unselected", "e");
200 
201         if (++i > 3) break;
202      }
203 
204    elm_box_align_set(v->o_tabs, 0.0, 0.5);
205 }
206 
207 static void
_tabs_clear(Tab_View * v)208 _tabs_clear(Tab_View *v)
209 {
210    Eina_List *l;
211    Tab *tab;
212 
213    EINA_LIST_FOREACH (v->tabs, l, tab)
214      {
215         if (!tab->plugin)
216           continue;
217 
218         elm_box_unpack(v->o_tabs, tab->o_tab);
219         evas_object_hide(tab->o_tab);
220      }
221 }
222 
223 static void
_plugin_select(Tab_View * v,Evry_Plugin * p)224 _plugin_select(Tab_View *v, Evry_Plugin *p)
225 {
226    evry_plugin_select(p);
227 
228    _tabs_update(v);
229 }
230 
231 static void
_plugin_next(Tab_View * v)232 _plugin_next(Tab_View *v)
233 {
234    Eina_List *l;
235    Evry_Plugin *p = NULL;
236    const Evry_State *s = v->state;
237 
238    if (!s->plugin) return;
239 
240    l = eina_list_data_find_list(s->cur_plugins, s->plugin);
241 
242    if (l && l->next)
243      p = l->next->data;
244    else if (s->plugin != s->cur_plugins->data)
245      p = s->cur_plugins->data;
246 
247    if (p) _plugin_select(v, p);
248 }
249 
250 static void
_plugin_next_by_name(Tab_View * v,const char * key)251 _plugin_next_by_name(Tab_View *v, const char *key)
252 {
253    Eina_List *l;
254    Evry_Plugin *p, *first = NULL, *next = NULL;
255    int found = 0;
256    const Evry_State *s = v->state;
257 
258    if (!s->plugin) return;
259 
260    EINA_LIST_FOREACH (s->cur_plugins, l, p)
261      {
262         /* if (!p)
263          *   {
264          *      // FIXME how can this happen?
265          *      ERR("plugin == NULL");
266          *      continue;
267          *   } */
268 
269         if (EVRY_ITEM(p)->label && (!strncasecmp(EVRY_ITEM(p)->label, key, 1)))
270           {
271              if (!first) first = p;
272 
273              if (found && !next)
274                next = p;
275           }
276         if (p == s->plugin) found = 1;
277      }
278 
279    if (next)
280      p = next;
281    else if (first != s->plugin)
282      p = first;
283    else
284      p = NULL;
285 
286    if (p) _plugin_select(v, p);
287 }
288 
289 static void
_plugin_prev(Tab_View * v)290 _plugin_prev(Tab_View *v)
291 {
292    Eina_List *l;
293    Evry_Plugin *p = NULL;
294    const Evry_State *s = v->state;
295 
296    if (!s->plugin) return;
297 
298    l = eina_list_data_find_list(s->cur_plugins, s->plugin);
299 
300    if (l && l->prev)
301      p = l->prev->data;
302    else
303      {
304         l = eina_list_last(s->cur_plugins);
305         if (s->plugin != l->data)
306           p = l->data;
307      }
308 
309    if (p) _plugin_select(v, p);
310 }
311 
312 static int
_tabs_key_down(Tab_View * v,const Ecore_Event_Key * ev)313 _tabs_key_down(Tab_View *v, const Ecore_Event_Key *ev)
314 {
315    const char *key = ev->key;
316 
317    if (!v->state || !v->state->cur_plugins) return 0;
318 
319    if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT)
320      {
321         if (!strcmp(key, "Next"))
322           {
323              _plugin_next(v);
324              return 1;
325           }
326         else if (!strcmp(key, "Prior"))
327           {
328              _plugin_prev(v);
329              return 1;
330           }
331      }
332    else if (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)
333      {
334         if (!strcmp(key, "Left"))
335           {
336              _plugin_prev(v);
337              return 1;
338           }
339         else if (!strcmp(key, "Right"))
340           {
341              _plugin_next(v);
342              return 1;
343           }
344         else if (ev->compose)
345           {
346              _plugin_next_by_name(v, key);
347              return 1;
348           }
349      }
350 
351    return 0;
352 }
353 
354 Tab_View *
evry_tab_view_new(Evry_View * view,const Evry_State * s,Evas_Object * parent)355 evry_tab_view_new(Evry_View *view, const Evry_State *s, Evas_Object *parent)
356 {
357    Tab_View *v;
358    Evas_Object *o;
359 
360    v = E_NEW(Tab_View, 1);
361    v->update = &_tabs_update;
362    v->clear = &_tabs_clear;
363    v->key_down = &_tabs_key_down;
364    v->view = view;
365    v->state = s;
366 
367    v->evas = evas_object_evas_get(parent);
368    o = elm_box_add(e_win_evas_object_win_get(parent));
369    elm_box_horizontal_set(o, 1);
370    elm_box_homogeneous_set(o, 1);
371    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_WHEEL,
372                                   _tabs_cb_wheel, v);
373    v->o_tabs = o;
374 
375    return v;
376 }
377 
378 void
evry_tab_view_free(Tab_View * v)379 evry_tab_view_free(Tab_View *v)
380 {
381    Tab *tab;
382 
383    EINA_LIST_FREE (v->tabs, tab)
384      {
385         evas_object_del(tab->o_tab);
386         E_FREE(tab);
387      }
388 
389    evas_object_del(v->o_tabs);
390 
391    if (v->animator)
392      ecore_animator_del(v->animator);
393 
394    if (v->timer)
395      ecore_timer_del(v->timer);
396 
397    E_FREE(v);
398 }
399 
400