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