update for beta release
[framework/uifw/e17.git] / src / modules / wizard / e_wizard.c
1 #include "e.h"
2 #include "e_mod_main.h"
3
4 static void _e_wizard_next_eval(void);
5 static E_Popup *_e_wizard_main_new(E_Zone *zone);
6 static E_Popup *_e_wizard_extra_new(E_Zone *zone);
7 static void _e_wizard_cb_key_down(void *data, Evas *e, Evas_Object *obj, void *event);
8 static void _e_wizard_cb_next(void *data, Evas_Object *obj, const char *emission, const char *source);
9
10 static E_Popup *pop = NULL;
11 static Eina_List *pops = NULL;
12 static Evas_Object *o_bg = NULL;
13 static Evas_Object *o_content = NULL;
14 static Eina_List *pages = NULL;
15 static E_Wizard_Page *curpage = NULL;
16 static int next_ok = 1;
17 static int next_can = 0;
18 static int next_prev = 0;
19
20 EAPI int
21 e_wizard_init(void)
22 {
23    Eina_List *l;
24
25    for (l = e_manager_list(); l; l = l->next)
26      {
27         E_Manager *man;
28         Eina_List *l2;
29
30         man = l->data;
31         for (l2 = man->containers; l2; l2 = l2->next)
32           {
33              E_Container *con;
34              Eina_List *l3;
35
36              con = l2->data;
37              for (l3 = con->zones; l3; l3 = l3->next)
38                {
39                   E_Zone *zone;
40
41                   zone = l3->data;
42                   if (!pop)
43                     pop = _e_wizard_main_new(zone);
44                   else
45                     pops = eina_list_append(pops, _e_wizard_extra_new(zone));
46                }
47           }
48      }
49    return 1;
50 }
51
52 EAPI int
53 e_wizard_shutdown(void)
54 {
55    if (pop)
56      {
57         e_object_del(E_OBJECT(pop));
58         pop = NULL;
59      }
60    while (pops)
61      {
62         e_object_del(E_OBJECT(pops->data));
63         pops = eina_list_remove_list(pops, pops);
64      }
65    while (pages)
66      {
67         e_wizard_page_del(pages->data);
68      }
69    return 1;
70 }
71
72 EAPI void
73 e_wizard_go(void)
74 {
75    if (!curpage)
76      {
77         if (pages)
78           {
79              curpage = pages->data;
80              if (pages->next) next_can = 1;
81           }
82      }
83    if (curpage)
84      {
85         if ((!curpage->data) && (curpage->init)) curpage->init(curpage);
86         _e_wizard_next_eval();
87         if ((curpage->show) && (!curpage->show(curpage)))
88           {
89              e_wizard_next();
90           }
91      }
92 }
93
94 EAPI void
95 e_wizard_apply(void)
96 {
97    Eina_List *l;
98
99    for (l = pages; l; l = l->next)
100      {  
101         E_Wizard_Page *pg;
102
103         pg = l->data;
104         if (pg->apply) pg->apply(pg);
105      }
106 }
107
108 EAPI void
109 e_wizard_next(void)
110 {
111    Eina_List *l;
112
113    for (l = pages; l; l = l->next)
114      {
115         if (l->data == curpage)
116           {
117              if (l->next)
118                {
119                   if (curpage)
120                     {
121                        if (curpage->hide)
122                          curpage->hide(curpage);
123                     }
124                   curpage = l->next->data;
125                   if (!curpage->data)
126                     {
127                        if (curpage->init)
128                          curpage->init(curpage);
129                     }
130                   next_can = 1;
131                   _e_wizard_next_eval();
132                   if ((curpage->show) && (curpage->show(curpage)))
133                     {
134                        break;
135                     }
136                }
137              else
138                {
139                   /* FINISH */
140                   e_wizard_apply();
141                   e_wizard_shutdown();
142                   return;
143                }
144           }
145      }
146 }
147
148 EAPI void
149 e_wizard_page_show(Evas_Object *obj)
150 {
151    if (o_content) evas_object_del(o_content);
152    o_content = obj;
153    if (obj)
154      {
155         Evas_Coord minw, minh;
156
157         e_widget_size_min_get(obj, &minw, &minh);
158         edje_extern_object_min_size_set(obj, minw, minh);
159         edje_object_part_swallow(o_bg, "e.swallow.content", obj);
160         evas_object_show(obj);
161         e_widget_focus_set(obj, 1);
162         edje_object_signal_emit(o_bg, "e,action,page,new", "e");
163      }
164 }
165
166 EAPI E_Wizard_Page *
167 e_wizard_page_add(void *handle,
168                   int (*init)     (E_Wizard_Page *pg),
169                   int (*shutdown) (E_Wizard_Page *pg),
170                   int (*show)     (E_Wizard_Page *pg),
171                   int (*hide)     (E_Wizard_Page *pg),
172                   int (*apply)    (E_Wizard_Page *pg)
173                   )
174 {
175    E_Wizard_Page *pg;
176
177    pg = E_NEW(E_Wizard_Page, 1);
178    if (!pg) return NULL;
179
180    pg->handle = handle;
181    pg->evas = pop->evas;
182
183    pg->init = init;
184    pg->shutdown = shutdown;
185    pg->show = show;
186    pg->hide = hide;
187    pg->apply = apply;
188
189    pages = eina_list_append(pages, pg);
190
191    return pg;
192 }
193
194 EAPI void
195 e_wizard_page_del(E_Wizard_Page *pg)
196 {
197 // rare thing.. if we do e_wizard_next() from a page and we end up finishing
198 // ther page seq.. we cant REALLY dlclose... not a problem as wizard runs
199 // once only then e restarts itself with final wizard page
200 //   if (pg->handle) dlclose(pg->handle);
201    pages = eina_list_remove(pages, pg);
202    free(pg);
203 }
204
205 EAPI void
206 e_wizard_button_next_enable_set(int enable)
207 {
208    next_ok = enable;
209    _e_wizard_next_eval();
210 }
211
212 EAPI void
213 e_wizard_title_set(const char *title)
214 {
215    edje_object_part_text_set(o_bg, "e.text.title", title);
216 }
217
218 EAPI void
219 e_wizard_labels_update(void)
220 {
221    edje_object_part_text_set(o_bg, "e.text.label", _("Next"));
222 }
223
224 EAPI const char *
225 e_wizard_dir_get(void)
226 {
227    return e_module_dir_get(wiz_module);
228 }
229
230 static void
231 _e_wizard_next_eval(void)
232 {
233    int ok;
234
235    ok = next_can;
236    if (!next_ok) ok = 0;
237    if (next_prev != ok)
238      {
239         if (ok) edje_object_signal_emit(o_bg, "e,state,next,enable", "e");
240         else edje_object_signal_emit(o_bg, "e,state,next,disable", "e");
241         next_prev = ok;
242      }
243 }
244
245 static E_Popup *
246 _e_wizard_main_new(E_Zone *zone)
247 {
248    E_Popup *pop;
249    Evas_Object *o;
250    Evas_Modifier_Mask mask;
251    Eina_Bool kg;
252
253    pop = e_popup_new(zone, 0, 0, zone->w, zone->h);
254    e_popup_layer_set(pop, 255);
255    o = edje_object_add(pop->evas);
256
257    e_theme_edje_object_set(o, "base/theme/wizard", "e/wizard/main");
258    evas_object_move(o, 0, 0);
259    evas_object_resize(o, zone->w, zone->h);
260    evas_object_show(o);
261    edje_object_signal_callback_add(o, "e,action,next", "",
262                                    _e_wizard_cb_next, pop);
263    o_bg = o;
264
265    o = evas_object_rectangle_add(pop->evas);
266    mask = 0;
267    kg = evas_object_key_grab(o, "Tab", mask, ~mask, 0);
268    if (!kg)
269      fprintf(stderr,"ERROR: unable to redirect \"Tab\" key events to object %p.\n", o);
270    mask = evas_key_modifier_mask_get(pop->evas, "Shift");
271    kg = evas_object_key_grab(o, "Tab", mask, ~mask, 0);
272    if (!kg)
273      fprintf(stderr,"ERROR: unable to redirect \"Tab\" key events to object %p.\n", o);
274    mask = 0;
275    kg = evas_object_key_grab(o, "Return", mask, ~mask, 0);
276    if (!kg)
277      fprintf(stderr,"ERROR: unable to redirect \"Return\" key events to object %p.\n", o);
278    mask = 0;
279    kg = evas_object_key_grab(o, "KP_Enter", mask, ~mask, 0);
280    if (!kg)
281      fprintf(stderr,"ERROR: unable to redirect \"KP_Enter\" key events to object %p.\n", o);
282    evas_object_event_callback_add(o, EVAS_CALLBACK_KEY_DOWN,
283                                   _e_wizard_cb_key_down, pop);
284
285    /* set up next/prev buttons */
286    edje_object_part_text_set(o_bg, "e.text.title", _("Welcome to Enlightenment"));
287    edje_object_signal_emit(o_bg, "e,state,next,disable", "e");
288    e_wizard_labels_update();
289
290    e_popup_edje_bg_object_set(pop, o_bg);
291    e_popup_show(pop);
292    if (!e_grabinput_get(ecore_evas_software_x11_window_get(pop->ecore_evas),
293                         1, ecore_evas_software_x11_window_get(pop->ecore_evas)))
294      {
295         e_object_del(E_OBJECT(pop));
296         pop = NULL;
297      }
298    return pop;
299 }
300
301 static E_Popup *
302 _e_wizard_extra_new(E_Zone *zone)
303 {
304    E_Popup *pop;
305    Evas_Object *o;
306
307    pop = e_popup_new(zone, 0, 0, zone->w, zone->h);
308    e_popup_layer_set(pop, 255);
309    o = edje_object_add(pop->evas);
310    e_theme_edje_object_set(o, "base/theme/wizard", "e/wizard/extra");
311    evas_object_move(o, 0, 0);
312    evas_object_resize(o, zone->w, zone->h);
313    evas_object_show(o);
314    e_popup_edje_bg_object_set(pop, o);
315    e_popup_show(pop);
316    return pop;
317 }
318
319 static void
320 _e_wizard_cb_key_down(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event)
321 {
322    Evas_Event_Key_Down *ev;
323
324    ev = event;
325    if (!o_content) return;
326    if (!strcmp(ev->keyname, "Tab"))
327      {
328         if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
329           e_widget_focus_jump(o_content, 0);
330         else
331           e_widget_focus_jump(o_content, 1);
332      }
333    else if (((!strcmp(ev->keyname, "Return")) ||
334              (!strcmp(ev->keyname, "KP_Enter")) ||
335              (!strcmp(ev->keyname, "space"))))
336      {
337         Evas_Object *o;
338
339         o = e_widget_focused_object_get(o_content);
340         if (o) e_widget_activate(o);
341      }
342 }
343
344 static void
345 _e_wizard_cb_next(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
346 {
347    e_wizard_next();
348 }