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