Tizen 2.1 release
[platform/core/uifw/e17.git] / src / modules / conf / e_conf.c
1 #include "e.h"
2
3 typedef struct _E_Configure          E_Configure;
4 typedef struct _E_Configure_CB       E_Configure_CB;
5 typedef struct _E_Configure_Category E_Configure_Category;
6 typedef struct _E_Configure_Item     E_Configure_Item;
7
8 #define E_CONFIGURE_TYPE 0xE0b01014
9
10 struct _E_Configure
11 {
12    E_Object             e_obj_inherit;
13
14    E_Container         *con;
15    E_Win               *win;
16    Evas                *evas;
17    Evas_Object         *edje;
18
19    Evas_Object         *o_list;
20    Evas_Object         *cat_list;
21    Evas_Object         *item_list;
22    Evas_Object         *close;
23
24    Eina_List           *cats;
25    Ecore_Event_Handler *mod_hdl;
26 };
27
28 struct _E_Configure_CB
29 {
30    E_Configure *eco;
31    const char  *path;
32 };
33
34 struct _E_Configure_Category
35 {
36    E_Configure *eco;
37    const char  *label;
38    Eina_List   *items;
39 };
40
41 struct _E_Configure_Item
42 {
43    E_Configure_CB *cb;
44    const char     *label;
45    const char     *icon_file;
46    const char     *icon;
47 };
48
49 static void                  _e_configure_free(E_Configure *eco);
50 static void                  _e_configure_cb_del_req(E_Win *win);
51 static void                  _e_configure_cb_resize(E_Win *win);
52 static void                  _e_configure_cb_close(void *data, void *data2);
53 static E_Configure_Category *_e_configure_category_add(E_Configure *eco, const char *label, const char *icon_file, const char *icon);
54 static void                  _e_configure_category_cb(void *data, void *data2);
55 static void                  _e_configure_item_add(E_Configure_Category *cat, const char *label, const char *icon_file, const char *icon, const char *path);
56 static void                  _e_configure_item_cb(void *data);
57 static void                  _e_configure_focus_cb(void *data, Evas_Object *obj);
58 static void                  _e_configure_keydown_cb(void *data, Evas *e, Evas_Object *obj, void *event);
59 static void                  _e_configure_fill_cat_list(void *data, const char *sel);
60 static Eina_Bool             _e_configure_module_update_cb(void *data, int type, void *event);
61
62 static E_Configure *_e_configure = NULL;
63
64 void
65 e_configure_show(E_Container *con, const char *params)
66 {
67    E_Configure *eco;
68    E_Manager *man;
69    Evas_Coord ew, eh, mw, mh;
70    Evas_Object *o;
71    Evas_Modifier_Mask mask;
72    Eina_Bool kg;
73
74    if (_e_configure)
75      {
76         E_Zone *z, *z2;
77         const Eina_List *l;
78         void *it;
79         int x = 0;
80
81         eco = _e_configure;
82         z = e_util_zone_current_get(e_manager_current_get());
83         z2 = eco->win->border->zone;
84         e_win_show(eco->win);
85         e_win_raise(eco->win);
86         if (z->container == z2->container)
87           e_border_desk_set(eco->win->border, e_desk_current_get(z));
88         else
89           {
90              if (!eco->win->border->sticky)
91                e_desk_show(eco->win->border->desk);
92              ecore_x_pointer_warp(z2->container->win,
93                                   z2->x + (z2->w / 2), z2->y + (z2->h / 2));
94           }
95         e_border_unshade(eco->win->border, E_DIRECTION_DOWN);
96         if ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
97             (e_config->focus_setting == E_FOCUS_NEW_WINDOW))
98           e_border_focus_set(eco->win->border, 1, 1);
99         EINA_LIST_FOREACH(e_widget_toolbar_items_get(eco->cat_list), l, it)
100           {
101              if (e_widget_toolbar_item_label_get(it) == params)
102                {
103                   e_widget_toolbar_item_select(eco->cat_list, x);
104                   break;
105                }
106              x++;
107           }
108         return;
109      }
110
111    if (!con)
112      {
113         man = e_manager_current_get();
114         if (!man) return;
115         con = e_container_current_get(man);
116         if (!con) con = e_container_number_get(man, 0);
117         if (!con) return;
118      }
119
120    eco = E_OBJECT_ALLOC(E_Configure, E_CONFIGURE_TYPE, _e_configure_free);
121    if (!eco) return;
122    eco->win = e_win_new(con);
123    if (!eco->win)
124      {
125         free(eco);
126         return;
127      }
128    eco->win->data = eco;
129    eco->con = con;
130    eco->evas = e_win_evas_get(eco->win);
131
132    /* Event Handler for Module Updates */
133    eco->mod_hdl = ecore_event_handler_add(E_EVENT_MODULE_UPDATE,
134                                           _e_configure_module_update_cb, eco);
135
136    e_win_title_set(eco->win, _("Settings"));
137    e_win_name_class_set(eco->win, "E", "_configure");
138    e_win_dialog_set(eco->win, 0);
139    e_win_delete_callback_set(eco->win, _e_configure_cb_del_req);
140    e_win_resize_callback_set(eco->win, _e_configure_cb_resize);
141    e_win_centered_set(eco->win, 1);
142
143    eco->edje = edje_object_add(eco->evas);
144    e_theme_edje_object_set(eco->edje, "base/theme/configure",
145                            "e/widgets/configure/main");
146    edje_object_part_text_set(eco->edje, "e.text.title", _("Settings"));
147
148    eco->o_list = e_widget_list_add(eco->evas, 0, 0);
149    edje_object_part_swallow(eco->edje, "e.swallow.content", eco->o_list);
150
151    /* Event Obj for keydown */
152    o = evas_object_rectangle_add(eco->evas);
153    mask = 0;
154    kg = evas_object_key_grab(o, "Tab", mask, ~mask, 0);
155    if (!kg)
156      fprintf(stderr, "ERROR: unable to redirect \"Tab\" key events to object %p.\n", o);
157    mask = evas_key_modifier_mask_get(e_win_evas_get(eco->win), "Shift");
158    kg = evas_object_key_grab(o, "Tab", mask, ~mask, 0);
159    if (!kg)
160      fprintf(stderr, "ERROR: unable to redirect \"Tab\" key events to object %p.\n", o);
161    mask = 0;
162    kg = evas_object_key_grab(o, "Return", mask, ~mask, 0);
163    if (!kg)
164      fprintf(stderr, "ERROR: unable to redirect \"Return\" key events to object %p.\n", o);
165    mask = 0;
166    kg = evas_object_key_grab(o, "KP_Enter", mask, ~mask, 0);
167    if (!kg)
168      fprintf(stderr, "ERROR: unable to redirect \"KP_Enter\" key events to object %p.\n", o);
169    mask = 0;
170    kg = evas_object_key_grab(o, "Escape", mask, ~mask, 0);
171    if (!kg)
172      fprintf(stderr, "ERROR: unable to redirect \"Escape\" key events to object %p.\n", o);
173    evas_object_event_callback_add(o, EVAS_CALLBACK_KEY_DOWN,
174                                   _e_configure_keydown_cb, eco->win);
175
176    _e_configure_fill_cat_list(eco, params);
177
178    /* Close Button */
179    eco->close = e_widget_button_add(eco->evas, _("Close"), NULL,
180                                     _e_configure_cb_close, eco, NULL);
181    e_widget_on_focus_hook_set(eco->close, _e_configure_focus_cb, eco->win);
182    e_widget_size_min_get(eco->close, &mw, &mh);
183    edje_extern_object_min_size_set(eco->close, mw, mh);
184    edje_object_part_swallow(eco->edje, "e.swallow.button", eco->close);
185    edje_object_size_min_calc(eco->edje, &ew, &eh);
186    e_win_size_min_set(eco->win, ew, eh);
187    e_util_win_auto_resize_fill(eco->win);
188
189    evas_object_show(eco->edje);
190    e_win_show(eco->win);
191    e_win_border_icon_set(eco->win, "preferences-system");
192
193    /* Preselect "Appearance" */
194    e_widget_focus_set(eco->cat_list, 1);
195    if (!e_widget_toolbar_item_selected_get(eco->cat_list))
196      e_widget_toolbar_item_select(eco->cat_list, 0);
197
198    _e_configure = eco;
199 }
200
201 void
202 e_configure_del(void)
203 {
204    if (_e_configure) e_object_del(E_OBJECT(_e_configure));
205    _e_configure = NULL;
206 }
207
208 static void
209 _e_configure_free(E_Configure *eco)
210 {
211    if (_e_configure->mod_hdl)
212      ecore_event_handler_del(_e_configure->mod_hdl);
213    _e_configure->mod_hdl = NULL;
214    _e_configure = NULL;
215    while (eco->cats)
216      {
217         E_Configure_Category *cat;
218
219         if (!(cat = eco->cats->data)) return;
220         if (cat->label) eina_stringshare_del(cat->label);
221
222         while (cat->items)
223           {
224              E_Configure_Item *ci;
225
226              if (!(ci = cat->items->data)) continue;
227              if (ci->label) eina_stringshare_del(ci->label);
228              if (ci->icon_file) eina_stringshare_del(ci->icon_file);
229              if (ci->icon) eina_stringshare_del(ci->icon);
230              if (ci->cb)
231                {
232                   if (ci->cb->path) eina_stringshare_del(ci->cb->path);
233                   free(ci->cb);
234                }
235              cat->items = eina_list_remove_list(cat->items, cat->items);
236              E_FREE(ci);
237           }
238         eco->cats = eina_list_remove_list(eco->cats, eco->cats);
239         E_FREE(cat);
240      }
241 //   evas_object_del(eco->close);
242 //   evas_object_del(eco->cat_list);
243 //   evas_object_del(eco->item_list);
244 //   evas_object_del(eco->o_list);
245 //   evas_object_del(eco->edje);
246    e_object_del(E_OBJECT(eco->win));
247    E_FREE(eco);
248 }
249
250 static void
251 _e_configure_cb_del_req(E_Win *win)
252 {
253    E_Configure *eco;
254
255    if (!(eco = win->data)) return;
256    e_object_del(E_OBJECT(eco));
257 }
258
259 static void
260 _e_configure_cb_resize(E_Win *win)
261 {
262    E_Configure *eco;
263    Evas_Coord w, h;
264
265    if (!(eco = win->data)) return;
266    ecore_evas_geometry_get(win->ecore_evas, NULL, NULL, &w, &h);
267    evas_object_resize(eco->edje, w, h);
268 }
269
270 static void
271 _e_configure_cb_close(void *data, void *data2 __UNUSED__)
272 {
273    E_Configure *eco;
274
275    if (!(eco = data)) return;
276    e_util_defer_object_del(E_OBJECT(eco));
277 }
278
279 static E_Configure_Category *
280 _e_configure_category_add(E_Configure *eco, const char *label, const char *icon_file, const char *icon)
281 {
282    Evas_Object *o = NULL;
283    E_Configure_Category *cat;
284
285    if (!eco) return NULL;
286    if (!label) return NULL;
287
288    cat = E_NEW(E_Configure_Category, 1);
289    cat->eco = eco;
290    cat->label = eina_stringshare_add(label);
291    if (icon)
292      {
293         o = e_icon_add(eco->evas);
294         if (icon_file)
295           e_icon_file_edje_set(o, icon_file, icon);
296         else if (!e_util_icon_theme_set(o, icon))
297           {
298              evas_object_del(o);
299              o = e_util_icon_add(icon, eco->evas);
300           }
301      }
302    eco->cats = eina_list_append(eco->cats, cat);
303
304    e_widget_toolbar_item_append(eco->cat_list, o, label,
305                                 _e_configure_category_cb, cat, NULL);
306    return cat;
307 }
308
309 static void
310 _e_configure_category_cb(void *data, void *data2 __UNUSED__)
311 {
312    E_Configure_Category *cat;
313    E_Configure *eco;
314    Eina_List *l;
315    Evas_Coord w, h;
316
317    if (!(cat = data)) return;
318    eco = cat->eco;
319
320    evas_event_freeze(evas_object_evas_get(eco->item_list));
321    edje_freeze();
322    e_widget_ilist_freeze(eco->item_list);
323    e_widget_ilist_clear(eco->item_list);
324    /***--- fill ---***/
325    for (l = cat->items; l; l = l->next)
326      {
327         E_Configure_Item *ci;
328         Evas_Object *o = NULL;
329
330         if (!(ci = l->data)) continue;
331         if (ci->icon)
332           {
333              o = e_icon_add(eco->evas);
334              if (ci->icon_file)
335                e_icon_file_edje_set(o, ci->icon_file, ci->icon);
336              else if (!e_util_icon_theme_set(o, ci->icon))
337                {
338                   evas_object_del(o);
339                   o = e_util_icon_add(ci->icon, eco->evas);
340                }
341           }
342         e_widget_ilist_append(eco->item_list, o, ci->label,
343                               _e_configure_item_cb, ci, NULL);
344      }
345    e_widget_ilist_go(eco->item_list);
346    e_widget_size_min_get(eco->item_list, &w, &h);
347    e_widget_size_min_set(eco->item_list, w, h);
348    e_widget_ilist_thaw(eco->item_list);
349    edje_thaw();
350    evas_event_thaw(evas_object_evas_get(eco->item_list));
351 }
352
353 static void
354 _e_configure_item_add(E_Configure_Category *cat, const char *label, const char *icon_file, const char *icon, const char *path)
355 {
356    E_Configure_Item *ci;
357    E_Configure_CB *cb;
358
359    if ((!cat) || (!label)) return;
360
361    ci = E_NEW(E_Configure_Item, 1);
362    cb = E_NEW(E_Configure_CB, 1);
363    cb->eco = cat->eco;
364    cb->path = eina_stringshare_add(path);
365    ci->cb = cb;
366    ci->label = eina_stringshare_add(label);
367    if (icon_file) ci->icon_file = eina_stringshare_add(icon_file);
368    if (icon) ci->icon = eina_stringshare_add(icon);
369    cat->items = eina_list_append(cat->items, ci);
370 }
371
372 static void
373 _e_configure_item_cb(void *data)
374 {
375    E_Configure_Item *ci;
376    E_Configure_CB *cb;
377
378    if (!(ci = data)) return;
379    cb = ci->cb;
380    if (cb->path) e_configure_registry_call(cb->path, cb->eco->con, NULL);
381 }
382
383 static void
384 _e_configure_focus_cb(void *data, Evas_Object *obj)
385 {
386    E_Win *win;
387    E_Configure *eco;
388
389    win = data;
390    if (!(eco = win->data)) return;
391    if (obj == eco->close)
392      {
393         e_widget_focused_object_clear(eco->item_list);
394         e_widget_focused_object_clear(eco->cat_list);
395      }
396    else if (obj == eco->item_list)
397      {
398         e_widget_focused_object_clear(eco->cat_list);
399         e_widget_focused_object_clear(eco->close);
400      }
401    else if (obj == eco->cat_list)
402      {
403         e_widget_focused_object_clear(eco->item_list);
404         e_widget_focused_object_clear(eco->close);
405      }
406 }
407
408 static void
409 _e_configure_keydown_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event)
410 {
411    Evas_Event_Key_Down *ev;
412    E_Win *win;
413    E_Configure *eco;
414
415    ev = event;
416    win = data;
417    eco = win->data;
418
419    if (!strcmp(ev->keyname, "Tab"))
420      {
421         if (evas_key_modifier_is_set(evas_key_modifier_get(e_win_evas_get(win)), "Shift"))
422           {
423              if (e_widget_focus_get(eco->close))
424                e_widget_focus_set(eco->item_list, 0);
425              else if (e_widget_focus_get(eco->item_list))
426                e_widget_focus_set(eco->cat_list, 1);
427              else if (e_widget_focus_get(eco->cat_list))
428                e_widget_focus_set(eco->close, 0);
429           }
430         else
431           {
432              if (e_widget_focus_get(eco->close))
433                e_widget_focus_set(eco->cat_list, 1);
434              else if (e_widget_focus_get(eco->item_list))
435                e_widget_focus_set(eco->close, 0);
436              else if (e_widget_focus_get(eco->cat_list))
437                e_widget_focus_set(eco->item_list, 0);
438           }
439      }
440    else if (((!strcmp(ev->keyname, "Return")) ||
441              (!strcmp(ev->keyname, "KP_Enter")) ||
442              (!strcmp(ev->keyname, "space"))))
443      {
444         Evas_Object *o = NULL;
445
446         if (e_widget_focus_get(eco->cat_list))
447           o = eco->cat_list;
448         else if (e_widget_focus_get(eco->item_list))
449           o = eco->item_list;
450         else if (e_widget_focus_get(eco->close))
451           o = eco->close;
452
453         if (o)
454           {
455              if (!(o = e_widget_focused_object_get(o))) return;
456              e_widget_activate(o);
457           }
458      }
459    else if (!strcmp(ev->keyname, "Escape"))
460      e_widget_activate(eco->close);
461 }
462
463 static void
464 _e_configure_fill_cat_list(void *data, const char *sel)
465 {
466    E_Configure *eco;
467    Evas_Coord mw, mh;
468    E_Configure_Category *cat;
469    Eina_List *l, *ll;
470    E_Configure_Cat *ecat;
471    int num = -1;
472
473    if (!(eco = data)) return;
474
475    if (eco->cat_list) evas_object_del(eco->cat_list);
476    if (eco->item_list) evas_object_del(eco->item_list);
477    eco->cat_list = NULL;
478    eco->item_list = NULL;
479
480    /* Category List */
481    eco->cat_list = e_widget_toolbar_add(eco->evas, 32 * e_scale, 32 * e_scale);
482    e_widget_toolbar_scrollable_set(eco->cat_list, 1);
483    /***--- fill ---***/
484    EINA_LIST_FOREACH(e_configure_registry, l, ecat)
485      {
486         if ((ecat->pri >= 0) && (ecat->items))
487           {
488              E_Configure_It *eci;
489              cat = _e_configure_category_add(eco, _(ecat->label),
490                                              ecat->icon_file, ecat->icon);
491              EINA_LIST_FOREACH(ecat->items, ll, eci)
492                {
493                   char buf[1024];
494
495                   eci = ll->data;
496                   if (eci->pri >= 0)
497                     {
498                        snprintf(buf, sizeof(buf), "%s/%s", ecat->cat,
499                                 eci->item);
500                        _e_configure_item_add(cat, _(eci->label),
501                                              eci->icon_file, eci->icon, buf);
502                     }
503                }
504              if (sel && (ecat->cat == sel))
505                num = e_widget_toolbar_items_count(eco->cat_list) - 1;
506           }
507      }
508    e_widget_on_focus_hook_set(eco->cat_list, _e_configure_focus_cb, eco->win);
509    e_widget_list_object_append(eco->o_list, eco->cat_list, 1, 0, 0.5);
510
511    /* Item List */
512    eco->item_list = e_widget_ilist_add(eco->evas, 32 * e_scale, 32 * e_scale, NULL);
513    e_widget_ilist_selector_set(eco->item_list, 1);
514    e_widget_ilist_go(eco->item_list);
515    e_widget_on_focus_hook_set(eco->item_list, _e_configure_focus_cb, eco->win);
516    e_widget_size_min_get(eco->item_list, &mw, &mh);
517    if (mw < (200 * e_scale)) mw = 200 * e_scale;
518    if (mh < (120 * e_scale)) mh = 120 * e_scale;
519    e_widget_size_min_set(eco->item_list, mw, mh);
520    e_widget_list_object_append(eco->o_list, eco->item_list, 1, 1, 0.5);
521    if (num != -1) e_widget_toolbar_item_select(eco->cat_list, num);
522
523    e_widget_size_min_get(eco->o_list, &mw, &mh);
524    edje_extern_object_min_size_set(eco->o_list, mw, mh);
525 }
526
527 static Eina_Bool
528 _e_configure_module_update_cb(void *data, int type __UNUSED__, void *event __UNUSED__)
529 {
530    E_Configure *eco;
531    int sel = 0;
532
533    if (!(eco = data)) return ECORE_CALLBACK_PASS_ON;
534    if (!eco->cat_list) return ECORE_CALLBACK_PASS_ON;
535    sel = e_widget_toolbar_item_selected_get(eco->cat_list);
536    _e_configure_fill_cat_list(eco, NULL);
537    e_widget_toolbar_item_select(eco->cat_list, sel);
538    return ECORE_CALLBACK_PASS_ON;
539 }
540