abc43c6e7b0f42cce7ae4d1645af0fc1ab0118ee
[framework/uifw/elementary.git] / src / lib / elm_popup.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3 #include <stdlib.h>
4
5 /**
6  * @defgroup Popup Popup
7  * @ingroup Elementary
8  *
9  * This is a popup widget. it can be used to display information/ get information from user.
10  */
11
12 typedef struct _Widget_Data Widget_Data;
13
14 struct _Widget_Data
15 {
16    Evas_Object *notify;
17    Evas_Object *layout;
18    const char *title_area;
19    Evas_Object *title_icon;
20    Evas_Object *content_area;
21    Evas_Object *desc_label;
22    Evas_Object *action_area;
23    Eina_List *button_list;
24    Elm_Popup_Mode mode;
25    int no_of_buttons;
26    Evas_Object *content;
27    Elm_Notify_Orient notify_orient;
28    Eina_Bool delete_me : 1;
29 };
30
31 typedef struct _Action_Area_Data Action_Area_Data;
32
33 struct _Action_Area_Data
34 {
35    Evas_Object *obj;
36    Evas_Object *btn;
37    int response_id;
38 };
39
40 static const char *widtype = NULL;
41 static void _del_hook(Evas_Object *obj);
42 static void _theme_hook(Evas_Object *obj);
43 static void _sizing_eval(Evas_Object *obj);
44 static void _elm_popup_buttons_add_valist(Evas_Object *obj, const char *first_button_text, va_list args);
45 static Evas_Object* _elm_popup_add_button(Evas_Object *obj, const char *text, int response_id);
46 static void _action_area_clicked(void *data, Evas_Object *obj, void *event_info);
47 static void _block_clicked_cb(void *data, Evas_Object *obj, void *event_info);
48 static void _show(void *data, Evas *e, Evas_Object *obj, void *event_info);
49 static void _hide(void *data, Evas *e, Evas_Object *obj, void *event_info);
50 static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
51 static void _state_set_cb(void *data, Evas_Object *obj __UNUSED__,
52                            const char *emission __UNUSED__,
53                            const char *source __UNUSED__);
54
55 static void
56 _del_hook(Evas_Object *obj)
57 {
58    Widget_Data *wd = elm_widget_data_get(obj);
59    if (!wd) return;
60    free(wd);
61 }
62
63 static void
64 _del_pre_hook(Evas_Object *obj)
65 {
66    Widget_Data *wd = elm_widget_data_get(obj);
67    Action_Area_Data *action_data = NULL;
68    Eina_List *list = NULL;
69
70    if (!wd) return;
71    evas_object_event_callback_del_full(obj, EVAS_CALLBACK_SHOW, _show, NULL);
72    evas_object_event_callback_del_full(obj, EVAS_CALLBACK_HIDE, _hide, NULL);
73    evas_object_smart_callback_del(wd->notify, "block,clicked", _block_clicked_cb);
74    EINA_LIST_FOREACH(wd->button_list, list, action_data)
75      {
76         free(action_data);
77         action_data = NULL;
78      }
79    eina_list_free(wd->button_list);
80 }
81
82 static void
83 _theme_hook(Evas_Object *obj)
84 {
85    Widget_Data *wd = elm_widget_data_get(obj);
86    char buf[4096];
87    Eina_List *list = NULL;
88    Action_Area_Data *action_data = NULL;
89    int index =0;
90
91    if (!wd) return;
92    elm_layout_theme_set(wd->layout, "popup", "base", elm_widget_style_get(obj));
93    elm_notify_orient_set(wd->notify, wd->notify_orient);
94    _mirrored_set(obj, elm_widget_mirrored_get(obj));
95    edje_object_message_signal_process(elm_layout_edje_get(wd->layout));
96    if (wd->action_area)
97      {
98         snprintf(buf, sizeof(buf), "buttons%d", wd->no_of_buttons);
99         elm_layout_theme_set(wd->action_area, "popup", buf, elm_widget_style_get(obj));
100         EINA_LIST_FOREACH(wd->button_list, list, action_data)
101           {
102              snprintf(buf, sizeof(buf), "popup_button/%s", elm_widget_style_get(obj));
103              elm_object_style_set(action_data->btn, buf);
104              ++index;
105              snprintf(buf, sizeof(buf), "actionbtn%d", index);
106              elm_object_content_part_set(wd->action_area, buf, action_data->btn);
107           }
108         elm_object_content_part_set(wd->layout, "elm.swallow.buttonArea", wd->action_area);
109      }
110    if (wd->content_area)
111      {
112         elm_layout_theme_set(wd->content_area, "popup", "content", elm_widget_style_get(obj));
113         if (wd->desc_label)
114           {
115              snprintf(buf, sizeof(buf), "popup_description/%s", elm_widget_style_get(obj));
116              elm_object_style_set(wd->desc_label, buf);
117              elm_object_content_part_set(wd->content_area, "elm.swallow.content", wd->desc_label);
118           }
119         else if (wd->content)
120           {
121              elm_object_content_part_set(wd->content_area, "elm.swallow.content", wd->content);
122           }
123         elm_object_content_part_set(wd->layout, "elm.swallow.content", wd->content_area);
124      }
125    if (wd->title_area)
126      {
127         edje_object_part_text_set(elm_layout_edje_get(wd->layout), "elm.swallow.title", wd->title_area);
128      }
129    _sizing_eval(obj);
130 }
131
132 static void
133 _sizing_eval(Evas_Object *obj)
134 {
135    Widget_Data *wd = elm_widget_data_get(obj);
136    Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
137
138    if (!wd) return;
139    edje_object_size_min_calc(elm_layout_edje_get(wd->layout), &minw, &minh);
140    evas_object_size_hint_min_set(obj, minw, minh);
141    evas_object_size_hint_max_set(obj, maxw, maxh);
142 }
143
144 static void
145 _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info)
146 {
147    _sizing_eval(data);
148 }
149
150 static void
151 _block_clicked_cb(void *data, Evas_Object *obj, void *event_info)
152 {
153    Widget_Data *wd = elm_widget_data_get((Evas_Object*)data);
154
155    if (wd->mode == ELM_POPUP_TYPE_ALERT)
156      {
157         evas_object_hide((Evas_Object*)data);
158         evas_object_smart_callback_call((Evas_Object *)data, "response", (void *)ELM_POPUP_RESPONSE_NONE);
159      }
160 }
161
162 static void
163 _show(void *data, Evas *e, Evas_Object *obj, void *event_info)
164 {
165    Widget_Data *wd = elm_widget_data_get(obj);
166
167    if (!wd) return;
168    elm_layout_theme_set(wd->layout, "popup", "base", elm_widget_style_get(obj));
169    _sizing_eval(obj);
170    evas_object_show(obj);
171 }
172
173 static void
174 _hide(void *data, Evas *e, Evas_Object *obj, void *event_info)
175 {
176    Widget_Data *wd = elm_widget_data_get(obj);
177
178    if (!wd) return;
179    evas_object_hide(obj);
180 }
181
182 static void
183 _action_area_clicked(void *data, Evas_Object *obj, void *event_info)
184 {
185    Action_Area_Data *adata = data;
186
187    if (!adata) return;
188    evas_object_hide(adata->obj);
189    evas_object_smart_callback_call(adata->obj, "response", (void *)adata->response_id);
190 }
191
192 static Evas_Object*
193 _elm_popup_add_button(Evas_Object *obj, const char *text, int response_id)
194 {
195    char buf[4096];
196    Widget_Data *wd = elm_widget_data_get(obj);
197    Evas_Object *btn;
198    Action_Area_Data *adata;
199
200    if (!wd) return NULL;
201    adata = ELM_NEW(Action_Area_Data);
202    btn = elm_button_add(obj);
203    snprintf(buf, sizeof(buf), "popup_button/%s", elm_widget_style_get(obj));
204    elm_object_style_set(btn, buf);
205    elm_object_focus_allow_set(btn, EINA_FALSE);
206    elm_object_text_set(btn, text);
207    adata->response_id = response_id;
208    adata->obj = obj;
209    adata->btn = btn;
210    wd->button_list = eina_list_append(wd->button_list, adata);
211    evas_object_smart_callback_add(btn, "clicked", _action_area_clicked, adata);
212    return btn;
213 }
214
215 static void
216 _elm_popup_buttons_add_valist(Evas_Object *obj, const char *first_button_text, va_list args)
217 {
218    const char *text = NULL;
219    char buf[4096];
220    int response = 0;
221    int index = 0;
222    Evas_Object *btn;
223    Widget_Data *wd = elm_widget_data_get(obj);
224
225    if (!wd) return;
226    if (first_button_text == NULL) return;
227    text = first_button_text;
228    response = va_arg(args, int);
229    while (text != NULL)
230      {
231         btn = _elm_popup_add_button(obj, text, response);
232         ++index;
233         snprintf(buf, sizeof(buf), "actionbtn%d", index);
234         elm_object_content_part_set(wd->action_area, buf, btn);
235         evas_object_event_callback_add(wd->action_area, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
236                                        _changed_size_hints, obj);
237         text = va_arg(args, char*);
238         if (text == NULL) break;
239         response = va_arg(args, int);
240      }
241 }
242
243 static void
244 _elm_popup_timeout(void *data, Evas_Object *obj, void *event_info)
245 {
246    evas_object_hide((Evas_Object*)data);
247    evas_object_smart_callback_call((Evas_Object *)data, "response", (void *)ELM_POPUP_RESPONSE_TIMEOUT);
248 }
249
250 static Eina_Bool
251 _elm_signal_exit(void *data __UNUSED__, int ev_type __UNUSED__, void *ev __UNUSED__)
252 {
253    int res_id  =  ELM_POPUP_RESPONSE_NONE;
254    int *id = data;
255    *id = res_id;
256    ecore_main_loop_quit();
257    return EINA_TRUE;
258 }
259
260 static void
261 response_cb(void *data, Evas_Object *obj, void *event_info)
262 {
263    int res_id = (int) event_info;
264    int *id = data;
265
266    *id = res_id;
267    ecore_main_loop_quit();
268 }
269
270 static void
271 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
272 {
273    Widget_Data *wd = elm_widget_data_get(obj);
274
275    if (!wd) return;
276    elm_object_mirrored_set(wd->notify, rtl);
277 }
278
279 static void
280 _state_set_cb(void *data, Evas_Object *obj __UNUSED__,
281                const char *emission __UNUSED__, const char *source __UNUSED__)
282 {
283    Widget_Data *wd = elm_widget_data_get((Evas_Object*)data);
284    if (!wd) return;
285    if (wd->layout) elm_layout_sizing_eval(wd->layout);
286 }
287
288 /**
289  * Add a new Popup object.
290  *
291  * @param[in] parent_app The parent object
292  * @return The new object or NULL if it cannot be created
293  *
294  * @ingroup Popup
295  */
296 EAPI Evas_Object *
297 elm_popup_add(Evas_Object *parent)
298 {
299    Evas_Object *obj;
300    Evas *e;
301    Widget_Data *wd;
302 #ifdef HAVE_ELEMENTARY_X
303    Ecore_X_Window_Type type;
304 #endif
305
306    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
307    ELM_SET_WIDTYPE(widtype, "popup");
308    elm_widget_type_set(obj, widtype);
309    elm_widget_sub_object_add(parent, obj);
310    elm_widget_data_set(obj, wd);
311    elm_widget_del_pre_hook_set(obj, _del_pre_hook);
312    elm_widget_del_hook_set(obj, _del_hook);
313    elm_widget_theme_hook_set(obj, _theme_hook);
314
315    wd->notify = elm_notify_add(parent);
316    elm_widget_sub_object_add(obj, wd->notify);
317    elm_widget_resize_object_set(obj, wd->notify);
318    elm_notify_orient_set(wd->notify, ELM_NOTIFY_ORIENT_CENTER);
319    wd->notify_orient = ELM_NOTIFY_ORIENT_CENTER;
320    elm_notify_repeat_events_set(wd->notify, EINA_FALSE);
321    evas_object_size_hint_weight_set(wd->notify, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
322    evas_object_size_hint_align_set(wd->notify, EVAS_HINT_FILL, EVAS_HINT_FILL);
323    elm_object_style_set(wd->notify, "popup");
324
325    wd->layout = elm_layout_add(parent);
326    evas_object_size_hint_weight_set(wd->layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
327    evas_object_size_hint_align_set(wd->layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
328
329    elm_layout_theme_set(wd->layout, "popup", "base", elm_widget_style_get(obj));
330    elm_object_content_set(wd->notify, wd->layout);
331
332    edje_object_signal_callback_add(elm_layout_edje_get(wd->layout), "elm,state,title,visible", "elm", _state_set_cb, obj);
333    edje_object_signal_callback_add(elm_layout_edje_get(wd->layout), "elm,state,button,visible", "elm", _state_set_cb, obj);
334    edje_object_signal_callback_add(elm_layout_edje_get(wd->layout), "elm,state,button,title,visible", "elm", _state_set_cb, obj);
335
336    evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _show, NULL);
337    evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _hide, NULL);
338    wd->mode = ELM_POPUP_TYPE_NONE;
339    evas_object_smart_callback_add(wd->notify, "block,clicked", _block_clicked_cb, obj);
340 #ifdef HAVE_ELEMENTARY_X
341    ecore_x_netwm_window_type_get(elm_win_xwindow_get(parent), &type);
342    if (type == ECORE_X_WINDOW_TYPE_DIALOG)
343      {
344         elm_object_style_set(wd->notify, "transparent");
345      }
346 #endif
347    _sizing_eval(obj);
348    return obj;
349 }
350
351 /**
352  * Add a new Popup object.
353  *
354  * @param[in] parent The parent object
355  * @param[in] title text to be displayed in title area.
356  * @param[in] desc_text text to be displayed in description area.
357  * @param[in] no_of_buttons Number of buttons to be packed in action area.
358  * @param[in] first_button_text button text
359  * @param[in] Varargs response ID for first button, then additional buttons followed by response id's ending with NULL
360  * @return The new object or NULL if it cannot be created
361  *
362  * @ingroup Popup
363  */
364 EAPI Evas_Object *
365 elm_popup_with_buttons_add(Evas_Object *parent, const char *title, const char *desc_text,int no_of_buttons, const char *first_button_text, ...)
366 {
367    Evas_Object *popup;
368    char buf[4096];
369    Widget_Data *wd;
370
371    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
372    popup = elm_popup_add(parent);
373    wd = elm_widget_data_get(popup);
374    if (desc_text)
375      {
376         elm_popup_desc_set(popup, desc_text);
377      }
378    if (title)
379      {
380         elm_popup_title_label_set(popup, title);
381      }
382    if (first_button_text)
383      {
384         va_list args;
385         va_start(args, first_button_text);
386         wd->action_area = elm_layout_add(popup);
387         elm_object_content_part_set(wd->layout, "elm.swallow.buttonArea", wd->action_area);
388         snprintf(buf,sizeof(buf), "buttons%d", no_of_buttons);
389                                 wd->no_of_buttons = no_of_buttons;
390         elm_layout_theme_set(wd->action_area, "popup", buf, elm_widget_style_get(popup));
391         edje_object_signal_emit(elm_layout_edje_get(wd->layout), "elm,state,button,visible", "elm");
392         if (wd->title_area)
393           {
394              edje_object_signal_emit(elm_layout_edje_get(wd->layout), "elm,state,button,title,visible", "elm");
395           }
396         _elm_popup_buttons_add_valist (popup, first_button_text, args);
397         va_end(args);
398      }
399    edje_object_message_signal_process(wd->layout);
400    _sizing_eval(popup);
401    return popup;
402 }
403
404
405 /**
406  * This Set's the description text in content area of Popup widget.
407  *
408  * @param[in] obj The Popup object
409  * @param[in] text description text.
410  *
411  * @ingroup Popup
412  */
413 EAPI void
414 elm_popup_desc_set(Evas_Object *obj, const char *text)
415 {
416    ELM_CHECK_WIDTYPE(obj, widtype);
417    Widget_Data *wd = elm_widget_data_get(obj);
418    char buf[4096];
419
420    if (!wd) return;
421    if (wd->content_area)
422      {
423         evas_object_del(wd->content_area);
424         wd->content_area = NULL;
425      }
426    wd->content_area = elm_layout_add(obj);
427    elm_layout_theme_set(wd->content_area, "popup", "content", elm_widget_style_get(obj));
428    wd->desc_label = elm_label_add(obj);
429    snprintf(buf, sizeof(buf), "popup_description/%s", elm_widget_style_get(obj));
430    elm_object_style_set(wd->desc_label, buf);
431    elm_label_line_wrap_set(wd->desc_label, ELM_WRAP_MIXED);
432    elm_object_text_set(wd->desc_label, text);
433    evas_object_size_hint_weight_set(wd->desc_label, EVAS_HINT_EXPAND, 0.0);
434    evas_object_size_hint_align_set(wd->desc_label, EVAS_HINT_FILL, EVAS_HINT_FILL);
435    evas_object_show(wd->desc_label);
436    elm_object_content_part_set(wd->content_area, "elm.swallow.content", wd->desc_label);
437    elm_object_content_part_set(wd->layout, "elm.swallow.content", wd->content_area);
438    evas_object_event_callback_add(wd->content_area, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
439                                   _changed_size_hints, obj);
440    _sizing_eval(obj);
441 }
442
443 /**
444  * This Get's the description text packed in content area of popup object.
445  *
446  * @param[in] obj The Popup object
447  * @return  description text.
448  *
449  * @ingroup Popup
450  */
451 EAPI const char*
452 elm_popup_desc_get(Evas_Object *obj)
453 {
454    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
455    Widget_Data *wd = elm_widget_data_get(obj);
456
457    if (!wd) return NULL;
458    return elm_object_text_get(wd->desc_label);
459 }
460
461 /**
462  * This Set's the title text in title area of popup object.
463  *
464  * @param[in] obj The popup object
465  * @param[in] text The title text
466  *
467  * @ingroup Popup
468  */
469 EAPI void
470 elm_popup_title_label_set(Evas_Object *obj, const char *text)
471 {
472    ELM_CHECK_WIDTYPE(obj, widtype);
473    Widget_Data *wd = elm_widget_data_get(obj);
474
475    if (!wd) return;
476    eina_stringshare_replace(&wd->title_area, text);
477    edje_object_part_text_set(elm_layout_edje_get(wd->layout), "elm.swallow.title", text);
478    edje_object_signal_emit(elm_layout_edje_get(wd->layout), "elm,state,title,visible", "elm");
479    if (wd->action_area)
480       edje_object_signal_emit(elm_layout_edje_get(wd->layout), "elm,state,button,title,visible", "elm");
481    if (wd->title_icon)
482       edje_object_signal_emit(elm_layout_edje_get(wd->layout), "elm,state,title,icon,visible", "elm");
483    edje_object_message_signal_process(wd->layout);
484    _sizing_eval(obj);
485 }
486
487 /**
488  * This Get's the title text packed in title area of popup object.
489  *
490  * @param[in] obj The Popup object
491  * @return title text
492  *
493  * @ingroup Popup
494  */
495 EAPI const char*
496 elm_popup_title_label_get(Evas_Object *obj)
497 {
498    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
499    Widget_Data *wd = elm_widget_data_get(obj);
500
501    if (!wd) return NULL;
502    return wd->title_area;
503 }
504
505 /**
506  * This Set's the icon in the title area of Popup object.
507  *
508  * @param[in] obj The popup object
509  * @param[in] icon The title icon
510  *
511  * @ingroup Popup
512  */
513 EAPI void
514 elm_popup_title_icon_set(Evas_Object *obj, Evas_Object *icon)
515 {
516    ELM_CHECK_WIDTYPE(obj, widtype);
517    Widget_Data *wd = elm_widget_data_get(obj);
518
519    if (!wd) return;
520    if (wd->title_icon)
521      {
522         evas_object_del(wd->title_icon);
523         wd->title_icon = NULL;
524      }
525    wd->title_icon = icon;
526    elm_object_content_part_set(wd->layout, "elm.swallow.title.icon", wd->title_icon);
527    edje_object_signal_emit(elm_layout_edje_get(wd->layout), "elm,state,title,icon,visible", "elm");
528    edje_object_message_signal_process(wd->layout);
529    _sizing_eval(obj);
530 }
531
532 /**
533  * This Get's the icon packed in title area of Popup object.
534  *
535  * @param[in] obj The Popup object
536  * @return title icon
537  *
538  * @ingroup Popup
539  */
540 EAPI Evas_Object*
541 elm_popup_title_icon_get(Evas_Object *obj)
542 {
543    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
544    Widget_Data *wd = elm_widget_data_get(obj);
545
546    if (!wd) return NULL;
547    return wd->title_icon;
548 }
549
550 /**
551  * This Set's the content widget in content area of Popup object.
552  *
553  * @param[in] obj The popup object
554  * @param[in] content The content widget
555  *
556  * @ingroup Popup
557  */
558 EAPI void
559 elm_popup_content_set(Evas_Object *obj, Evas_Object *content)
560 {
561    ELM_CHECK_WIDTYPE(obj, widtype);
562    Widget_Data *wd = elm_widget_data_get(obj);
563
564    if (!wd) return;
565    if (wd->content == content) return;
566    if (wd->content_area)
567      {
568         evas_object_del(wd->content_area);
569         wd->content_area = NULL;
570      }
571    wd->content = content;
572    if (content)
573      {
574         wd->content_area = elm_layout_add(obj);
575         elm_layout_theme_set(wd->content_area, "popup","content", elm_widget_style_get(obj));
576         elm_object_content_part_set(wd->content_area, "elm.swallow.content", content);
577         elm_object_content_part_set(wd->layout, "elm.swallow.content", wd->content_area);
578         evas_object_event_callback_add(wd->content_area, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
579                                        _changed_size_hints, obj);
580      }
581    _sizing_eval(obj);
582 }
583
584 /**
585  * This Get's the content widget packed in content area of Popup object.
586  *
587  * @param[in] obj The Popup object
588  * @return content packed in popup widget
589  *
590  * @ingroup Popup
591  */
592 EAPI Evas_Object*
593 elm_popup_content_get(Evas_Object *obj)
594 {
595    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
596    Widget_Data *wd = elm_widget_data_get(obj);
597
598    if (!wd) return NULL;
599    return wd->content;
600 }
601
602 /**
603  * Adds the buttons in to the action area of popup object.
604  *
605  * @param[in] obj The popup object
606  * @param[in] no_of_buttons Number of buttons that has to be packed in action area.
607  * @param[in] first_button_text   Label of first button
608  * @param[in] Varargs  Response ID(Elm_Popup_Response/ any integer value) for first button, then additional buttons along with their response id ending with NULL.
609  * @ingroup Popup
610  */
611 EAPI void
612 elm_popup_buttons_add(Evas_Object *obj,int no_of_buttons, const char *first_button_text,  ...)
613 {
614    ELM_CHECK_WIDTYPE(obj, widtype);
615    Widget_Data *wd = elm_widget_data_get(obj);
616    char buf[4096];
617    va_list args;
618
619    if (!wd) return;
620    va_start(args, first_button_text);
621    if (wd->action_area)
622      {
623         evas_object_del(wd->action_area);
624         wd->action_area = NULL;
625      }
626    wd->action_area = elm_layout_add(obj);
627    elm_object_content_part_set(wd->layout, "elm.swallow.buttonArea", wd->action_area);
628    evas_object_size_hint_weight_set(wd->action_area, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
629    evas_object_size_hint_align_set(wd->action_area, EVAS_HINT_FILL, EVAS_HINT_FILL);
630    snprintf(buf, sizeof(buf), "buttons%d", no_of_buttons);
631    elm_layout_theme_set(wd->action_area, "popup", buf, elm_widget_style_get(obj));
632    wd->no_of_buttons = no_of_buttons;
633    edje_object_signal_emit(elm_layout_edje_get(wd->layout), "elm,state,button,visible", "elm");
634    if (wd->title_area)
635      edje_object_signal_emit(elm_layout_edje_get(wd->layout), "elm,state,button,title,visible", "elm");
636    _elm_popup_buttons_add_valist (obj, first_button_text, args);
637    va_end(args);
638    edje_object_message_signal_process(wd->layout);
639    _sizing_eval(obj);
640 }
641
642 /**
643  * This Set's the time before the popup window is hidden,
644  * and ELM_POPUP_RESPONSE_TIMEOUT is sent along with response signal.
645  *
646  * @param[in] obj The popup object
647  * @param[in] timeout The timeout value in seconds.
648  *
649  * @ingroup Popup
650  */
651 EAPI void
652 elm_popup_timeout_set(Evas_Object *obj, double timeout)
653 {
654    ELM_CHECK_WIDTYPE(obj, widtype);
655    Widget_Data *wd = elm_widget_data_get(obj);
656
657    if (!wd) return;
658    elm_notify_timeout_set(wd->notify, timeout);
659    evas_object_smart_callback_add(wd->notify, "timeout", _elm_popup_timeout, obj);
660 }
661
662 /**
663  * This Set's the mode of popup, by default ELM_POPUP_TYPE_NONE is set i.e, popup
664  * will not close when clicked outside. if ELM_POPUP_TYPE_ALERT is set, popup will close
665  * when clicked outside, and ELM_POPUP_RESPONSE_NONE is sent along with response signal.
666  *
667  * @param[in] obj The popup object
668  * @param[in] mode  Elm_Popup_Mode
669  *
670  * @ingroup Popup
671  */
672 EAPI void
673 elm_popup_mode_set(Evas_Object *obj, Elm_Popup_Mode mode)
674 {
675    ELM_CHECK_WIDTYPE(obj, widtype);
676    Widget_Data *wd = elm_widget_data_get(obj);
677
678    if (!wd) return;
679    if (mode == wd->mode) return;
680    wd->mode = mode;
681 }
682
683 /**
684  * This Hides the popup by emitting response signal.
685  *
686  * @param[in] obj The popup object
687  * @param[in] response_id  response ID of the signal to be emitted along with response signal
688  *
689  * @ingroup Popup
690  */
691 EAPI void
692 elm_popup_response(Evas_Object *obj, int  response_id)
693 {
694    ELM_CHECK_WIDTYPE(obj, widtype);
695    Widget_Data *wd = elm_widget_data_get(obj);
696
697    if (!wd) return;
698    evas_object_hide(obj);
699    evas_object_smart_callback_call((Evas_Object *)obj, "response", (void *)response_id);
700 }
701
702 /**
703  * This API controls the direction from which popup will appear and location of popup.
704  * @param[in] obj The popup object
705  * @param[in] orient  the orientation of the popup
706  *
707  * @ingroup Popup
708  */
709 EAPI void
710 elm_popup_orient_set(Evas_Object *obj, Elm_Popup_Orient orient)
711 {
712    ELM_CHECK_WIDTYPE(obj, widtype);
713    Widget_Data *wd = elm_widget_data_get(obj);
714    Elm_Notify_Orient notify_orient = -1;
715
716    if (!wd) return;
717    switch (orient)
718      {
719       case ELM_POPUP_ORIENT_TOP:
720          notify_orient = ELM_NOTIFY_ORIENT_TOP;
721          break;
722       case ELM_POPUP_ORIENT_CENTER:
723          notify_orient = ELM_NOTIFY_ORIENT_CENTER;
724          break;
725       case ELM_POPUP_ORIENT_BOTTOM:
726          notify_orient = ELM_NOTIFY_ORIENT_BOTTOM;
727          break;
728       case ELM_POPUP_ORIENT_LEFT:
729          notify_orient = ELM_NOTIFY_ORIENT_LEFT;
730          break;
731       case ELM_POPUP_ORIENT_RIGHT:
732          notify_orient = ELM_NOTIFY_ORIENT_RIGHT;
733          break;
734       case ELM_POPUP_ORIENT_TOP_LEFT:
735          notify_orient = ELM_NOTIFY_ORIENT_TOP_LEFT;
736          break;
737       case ELM_POPUP_ORIENT_TOP_RIGHT:
738          notify_orient = ELM_NOTIFY_ORIENT_TOP_RIGHT;
739          break;
740       case ELM_POPUP_ORIENT_BOTTOM_LEFT:
741          notify_orient = ELM_NOTIFY_ORIENT_BOTTOM_LEFT;
742          break;
743       case ELM_POPUP_ORIENT_BOTTOM_RIGHT:
744          notify_orient = ELM_NOTIFY_ORIENT_BOTTOM_RIGHT;
745          break;
746      }
747    wd->notify_orient = notify_orient;
748    elm_notify_orient_set(wd->notify, notify_orient);
749 }
750
751 /**
752  * Blocks in a main loop until popup either emits response signal or is exited due
753  * to exit signal, when exit signal is received dialog responds with ELM_POPUP_RESPONSE_NONE
754  * response ID else returns the response ID from response signal emission.
755  * before entering the main loop popup calls evas_object_show on the popup for you.
756  * you can force popup to return at any time by calling elm_popup_responsec to emit the
757  * response signal. destroying the popup during elm_popup_run is a very bad idea.
758  * typical usage of this function may be
759  * int result = elm_popup_run(popup);
760  * switch(result)
761  * {
762  * case ELM_POPUP_RESPONSE_OK:
763  * do_something_specific_to_app();
764  * evas_object_del(popup);
765  * break;
766  * case ELM_POPUP_RESPONSE_CANCEL:
767  * do_nothing_popup_was_cancelled();
768  * evas_object_del(popup);
769  * break;
770  * case ELM_POPUP_RESPONSE_NONE:
771  * default:
772  * evas_object_del(popup);
773  * elm_exit();
774  * }
775  * do not run elm_popup_run in a timer/idler callback.
776  * when popup returns with signal ELM_POPUP_RESPONSE_NONE, then exit the application using elm_exit
777  * by calling any post exit application code.
778  *
779  * @param[in] obj The popup object
780  * @ingroup Popup
781  */
782 EAPI int
783 elm_popup_run(Evas_Object *obj)
784 {
785    int response_id=0;
786    Ecore_Event_Handler *_elm_exit_handler = NULL;
787
788    /*Finger waggle warning*/
789    _elm_dangerous_call_check(__FUNCTION__);
790    evas_object_show(obj);
791    evas_object_smart_callback_add(obj, "response", response_cb, &response_id);
792    _elm_exit_handler = ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, _elm_signal_exit, &response_id);
793    ecore_main_loop_begin();
794    if (_elm_exit_handler)
795      {
796         ecore_event_handler_del(_elm_exit_handler);
797         _elm_exit_handler = NULL;
798      }
799    return response_id;
800 }