Merge "[*][elm_main] fix wrong return + wrong function call"
[framework/uifw/elementary.git] / src / lib / elc_popup.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 #define ELM_POPUP_ACTION_BUTTON_MAX 3
5 typedef struct _Widget_Data Widget_Data;
6 typedef struct _Elm_Popup_Content_Item Elm_Popup_Content_Item;
7 typedef struct _Action_Area_Data Action_Area_Data;
8
9 struct _Widget_Data
10 {
11    Evas_Object *base;
12    Evas_Object *notify;
13    Evas_Object *title_icon;
14    Evas_Object *content_area;
15    Evas_Object *content_text_obj;
16    Evas_Object *action_area;
17    Evas_Object *box;
18    Evas_Object *scr;
19    Evas_Object *content;
20    Eina_List *items;
21    const char *title_text;
22    Action_Area_Data *buttons[ELM_POPUP_ACTION_BUTTON_MAX];
23    Elm_Wrap_Type content_text_wrap_type;
24    unsigned int button_count;
25    Evas_Coord max_sc_w;
26    Evas_Coord max_sc_h;
27    Eina_Bool scr_size_recalc:1;
28 };
29
30 struct _Elm_Popup_Content_Item
31 {
32    Elm_Widget_Item base;
33    const char *label;
34    Evas_Object *icon;
35    Evas_Smart_Cb func;
36    Eina_Bool disabled:1;
37 };
38
39 struct _Action_Area_Data
40 {
41    Evas_Object *obj;
42    Evas_Object *btn;
43    Eina_Bool delete_me;
44 };
45
46 static const char *widtype = NULL;
47 static void _del_hook(Evas_Object *obj);
48 static void _theme_hook(Evas_Object *obj);
49 static void _text_set_hook(Evas_Object *obj, const char *part,
50                                           const char *label);
51 static const char *_text_get_hook(const Evas_Object *obj,
52                                                  const char *part);
53 static void _content_set_hook(Evas_Object *obj, const char *part,
54                                              Evas_Object *content);
55 static Evas_Object *_content_get_hook(Evas_Object *obj,
56                                                      const char *part);
57 static Evas_Object *_content_unset_hook(Evas_Object *obj,
58                                                        const char *part);
59 static void _item_text_set_hook(Elm_Object_Item *it, const char *part,
60                                 const char *label);
61 static const char *_item_text_get_hook(const Elm_Object_Item *it,
62                                        const char *part);
63 static void _item_content_set_hook(Elm_Object_Item *it, const char *part,
64                                    Evas_Object *content);
65 static Evas_Object *_item_content_unset_hook(const Elm_Object_Item *it,
66                                              const char *part);
67 static Evas_Object *_item_content_get_hook(const Elm_Object_Item *it,
68                                            const char *part);
69 static void _item_disable_hook(Elm_Object_Item *it);
70 static void _item_del_pre_hook(Elm_Object_Item *it);
71 static void _item_signal_emit_hook(Elm_Object_Item *it, const char *emission,
72                                    const char *source);
73 static void _sizing_eval(Evas_Object *obj);
74 static void _block_clicked_cb(void *data, Evas_Object *obj, void *event_info);
75 static void _notify_resize(void *data, Evas *e, Evas_Object *obj,
76                            void *event_info);
77 static void _scroller_resize(void *data, Evas *e, Evas_Object *obj,
78                              void *event_info);
79 static void _timeout(void *data, Evas_Object *obj , void *event_info);
80 static void _sub_del(void *data, Evas_Object *obj, void *event_info);
81 static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
82 static void _restack(void *data, Evas *e, Evas_Object *obj, void *event_info);
83 static void _layout_change_cb(void *data, Evas_Object *obj __UNUSED__,
84                               const char *emission __UNUSED__,
85                               const char *source __UNUSED__);
86 static void _item_new(Elm_Popup_Content_Item *item);
87 static void _remove_items(Widget_Data *wd);
88 static void _list_new(Evas_Object *obj);
89 static void _list_del(Widget_Data *wd);
90 static void _item_sizing_eval(Elm_Popup_Content_Item *item);
91 static void _item_select_cb(void *data, Evas_Object *obj __UNUSED__,
92                             const char *emission __UNUSED__,
93                             const char *source __UNUSED__);
94 static void _scroller_size_calc(Evas_Object *obj);
95 static void _action_button_set(Evas_Object *obj, Evas_Object *btn,
96                                unsigned int idx);
97 static Evas_Object *_action_button_get(Evas_Object *obj, unsigned int idx);
98 static Evas_Object *_action_button_unset(Evas_Object *obj, unsigned int idx);
99 static void _button_remove(Evas_Object *obj, Evas_Object *content,
100                            Eina_Bool delete);
101 static const char SIG_BLOCK_CLICKED[] = "block,clicked";
102 static const char SIG_TIMEOUT[] = "timeout";
103 static const Evas_Smart_Cb_Description _signals[] = {
104        {SIG_BLOCK_CLICKED, ""},
105        {SIG_TIMEOUT, ""},
106        {NULL, NULL}
107 };
108
109 #define ELM_POPUP_CONTENT_ITEM_CHECK_RETURN(it, ...)                        \
110   ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
111   ELM_CHECK_WIDTYPE(WIDGET(item), widtype) __VA_ARGS__;
112
113 static void
114 _layout_set(Evas_Object *obj)
115 {
116    Widget_Data *wd = elm_widget_data_get(obj);
117
118    if (!wd) return;
119    if ((!(wd->title_text)) && (!(wd->title_icon)))
120      elm_object_signal_emit(wd->base, "elm,state,title_area,hidden", "elm");
121    else
122      elm_object_signal_emit(wd->base, "elm,state,title_area,visible", "elm");
123    if (wd->button_count)
124      elm_object_signal_emit(wd->base, "elm,state,action_area,visible", "elm");
125    else
126      elm_object_signal_emit(wd->base, "elm,state,action_area,hidden", "elm");
127 }
128
129 static void
130 _del_hook(Evas_Object *obj)
131 {
132    Widget_Data *wd = elm_widget_data_get(obj);
133
134    if (!wd) return;
135    free(wd);
136 }
137
138 static void
139 _del_pre_hook(Evas_Object *obj)
140 {
141    unsigned int i;
142    Widget_Data *wd = elm_widget_data_get(obj);
143
144    if (!wd) return;
145    evas_object_smart_callback_del(wd->notify, "block,clicked",
146                                   _block_clicked_cb);
147    evas_object_smart_callback_del(wd->notify, "timeout", _timeout);
148    evas_object_event_callback_del(wd->notify, EVAS_CALLBACK_RESIZE,
149                                   _notify_resize);
150    wd->button_count = 0;
151    for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
152      if (wd->buttons[i])
153        {
154           evas_object_del(wd->buttons[i]->btn);
155           free(wd->buttons[i]);
156           wd->buttons[i] = NULL;
157        }
158    if (wd->items)
159      {
160         _remove_items(wd);
161         _list_del(wd);
162      }
163 }
164
165 static void
166 _theme_hook(Evas_Object *obj)
167 {
168    Eina_List *elist;
169    Elm_Popup_Content_Item *item;
170    char buf[128];
171    unsigned int i = 0;
172    Widget_Data *wd = elm_widget_data_get(obj);
173
174    if (!wd) return;
175    elm_layout_theme_set(wd->base, "popup", "base", elm_widget_style_get(obj));
176    elm_widget_scale_set(wd->base, elm_widget_scale_get(obj));
177    _elm_widget_mirrored_reload(obj);
178    _mirrored_set(obj, elm_widget_mirrored_get(obj));
179    if (wd->button_count)
180      {
181         snprintf(buf, sizeof(buf), "buttons%u", wd->button_count);
182         elm_layout_theme_set(wd->action_area, "popup", buf,
183                              elm_widget_style_get(obj));
184         for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
185           {
186              if (!wd->buttons[i]) continue;
187              elm_object_style_set(wd->buttons[i]->btn, buf);
188           }
189      }
190    elm_layout_theme_set(wd->content_area, "popup", "content",
191                         elm_widget_style_get(obj));
192    if (wd->content_text_obj)
193      {
194         snprintf(buf, sizeof(buf), "popup/%s", elm_widget_style_get(obj));
195         elm_object_style_set(wd->content_text_obj, buf);
196      }
197    else if (wd->items)
198      {
199         EINA_LIST_FOREACH(wd->items, elist, item)
200           {
201              _elm_theme_object_set(obj, VIEW(item), "popup",
202                                    "item", elm_widget_style_get(obj));
203              if (item->label)
204                {
205                   edje_object_part_text_set(VIEW(item), "elm.text",
206                                             item->label);
207                   edje_object_signal_emit(VIEW(item),
208                                           "elm,state,item,text,visible", "elm");
209                }
210              if (item->icon)
211                edje_object_signal_emit(VIEW(item),
212                                        "elm,state,item,icon,visible", "elm");
213              if (item->disabled)
214                edje_object_signal_emit(VIEW(item),
215                                        "elm,state,item,disabled", "elm");
216              evas_object_show(VIEW(item));
217              edje_object_message_signal_process(VIEW(item));
218           }
219         _scroller_size_calc(obj);
220      }
221    if (wd->title_text)
222      {
223         elm_object_part_text_set(wd->base, "elm.text.title", wd->title_text);
224         elm_object_signal_emit(wd->base, "elm,state,title,text,visible", "elm");
225      }
226    if (wd->title_icon)
227      elm_object_signal_emit(wd->base, "elm,state,title,icon,visible", "elm");
228    _layout_set(obj);
229    edje_object_message_signal_process(elm_layout_edje_get(wd->base));
230    _sizing_eval(obj);
231 }
232
233 static void
234 _item_sizing_eval(Elm_Popup_Content_Item *item)
235 {
236    Evas_Coord min_w = -1, min_h = -1, max_w = -1, max_h = -1;
237
238    edje_object_size_min_restricted_calc(VIEW(item), &min_w, &min_h, min_w,
239                                         min_h);
240    evas_object_size_hint_min_set(VIEW(item), min_w, min_h);
241    evas_object_size_hint_max_set(VIEW(item), max_w, max_h);
242 }
243
244 static void
245 _sizing_eval(Evas_Object *obj)
246 {
247    Eina_List *elist;
248    Elm_Popup_Content_Item *item;
249    Evas_Coord w_box = 0, h_box = 0;
250    Evas_Coord minw_box = 0, minh_box = 0;
251    Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
252    Widget_Data *wd = elm_widget_data_get(obj);
253
254    if (!wd) return;
255    if (wd->items)
256      {
257         EINA_LIST_FOREACH(wd->items, elist, item)
258           {
259              _item_sizing_eval(item);
260              evas_object_size_hint_min_get(VIEW(item), &minw_box,
261                                            &minh_box);
262              if (minw_box > w_box)
263                w_box = minw_box;
264              if (minh_box != -1)
265                h_box += minh_box;
266           }
267         evas_object_size_hint_min_set(wd->box, w_box, h_box);
268         evas_object_size_hint_min_set(wd->scr, w_box, MIN(h_box, wd->max_sc_h));
269         evas_object_size_hint_max_set(wd->scr, w_box, wd->max_sc_h);
270         evas_object_smart_calculate(wd->scr);
271      }
272    edje_object_size_min_calc(elm_layout_edje_get(wd->base), &minw, &minh);
273    evas_object_size_hint_min_set(wd->base, minw, minh);
274    evas_object_size_hint_max_set(wd->base, maxw, maxh);
275    evas_object_size_hint_min_set(obj, minw, minh);
276    evas_object_size_hint_max_set(obj, maxw, maxh);
277    elm_layout_sizing_eval(wd->base);
278 }
279
280 static void
281 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
282                     void *event_info __UNUSED__)
283 {
284    _sizing_eval(data);
285 }
286
287 static void
288 _sub_del(void *data, Evas_Object *obj, void *event_info)
289 {
290    Elm_Popup_Content_Item *item;
291    unsigned int i;
292    Evas_Object *sub = event_info;
293    Widget_Data *wd = elm_widget_data_get(data);
294
295    if (!wd) return;
296    if (obj == data)
297      {
298         if ((item = evas_object_data_get(sub, "_popup_content_item")) != NULL)
299           {
300              if (sub == item->icon)
301                {
302                   edje_object_part_unswallow(VIEW(item), sub);
303                   edje_object_signal_emit(VIEW(item),
304                                           "elm,state,item,icon,hidden", "elm");
305                   item->icon = NULL;
306                }
307           }
308      }
309    else if (obj == wd->content_area)
310      {
311         if (sub == wd->content)
312           {
313              wd->content = NULL;
314              elm_object_part_content_unset(wd->base, "elm.swallow.content");
315              _sizing_eval(data);
316           }
317         else if (sub == wd->content_text_obj)
318           {
319              wd->content_text_obj = NULL;
320              elm_object_part_content_unset(wd->base, "elm.swallow.content");
321              _sizing_eval(data);
322           }
323         else if (sub == wd->scr)
324           {
325              wd->scr = NULL;
326              wd->box = NULL;
327              elm_object_part_content_unset(wd->base, "elm.swallow.content");
328              _sizing_eval(data);
329           }
330      }
331    else if (obj == wd->action_area)
332      {
333         for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
334           {
335              if (wd->buttons[i] && sub == wd->buttons[i]->btn &&
336                       wd->buttons[i]->delete_me == EINA_TRUE)
337                {
338                   _button_remove(data, sub, EINA_FALSE);
339                   break;
340                }
341           }
342      }
343    else if (obj == wd->base)
344      {
345         if (sub == wd->title_icon)
346           {
347              elm_object_signal_emit(wd->base, "elm,state,title,icon,hidden",
348                                     "elm");
349              edje_object_message_signal_process(wd->base);
350              wd->title_icon = NULL;
351           }
352      }
353 }
354
355 static void
356 _block_clicked_cb(void *data, Evas_Object *obj __UNUSED__,
357                   void *event_info __UNUSED__)
358 {
359    Widget_Data *wd = elm_widget_data_get(data);
360
361    if (!wd) return;
362    evas_object_smart_callback_call(data, SIG_BLOCK_CLICKED, NULL);
363 }
364
365 static void
366 _timeout(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
367 {
368    evas_object_hide(data);
369    evas_object_smart_callback_call(data, SIG_TIMEOUT, NULL);
370 }
371
372 static void
373 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
374 {
375    Eina_List *elist;
376    Elm_Popup_Content_Item *item;
377    Widget_Data *wd = elm_widget_data_get(obj);
378
379    if (!wd) return;
380    elm_object_mirrored_set(wd->notify, rtl);
381    if (wd->items)
382      EINA_LIST_FOREACH(wd->items, elist, item)
383        edje_object_mirrored_set(VIEW(item), rtl);
384 }
385
386 static void
387 _layout_change_cb(void *data, Evas_Object *obj __UNUSED__,
388                   const char *emission __UNUSED__,
389                   const char *source __UNUSED__)
390 {
391    Widget_Data *wd = elm_widget_data_get((Evas_Object*)data);
392
393    if (!wd) return;
394    if (wd->base)
395      elm_layout_sizing_eval(wd->base);
396 }
397
398 static void
399 _restack(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
400          void *event_info __UNUSED__)
401 {
402    Widget_Data *wd = elm_widget_data_get(obj);
403
404    if (!wd) return;
405    evas_object_layer_set(wd->notify, evas_object_layer_get(obj));
406 }
407
408 static void
409 _scroller_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj,
410                  void *event_info __UNUSED__)
411 {
412    Evas_Coord w, h;
413    Widget_Data *wd = elm_widget_data_get(data);
414
415    if (!wd || wd->scr_size_recalc) return;
416    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
417    if (w && h)
418      {
419         if ((w <= wd->max_sc_w) && (h <= wd->max_sc_h))
420           {
421              _sizing_eval(data);
422              wd->scr_size_recalc = EINA_TRUE;
423              return;
424           }
425      }
426    if (wd->max_sc_w < w)
427      wd->max_sc_w = w;
428    if (wd->max_sc_h < h)
429      wd->max_sc_h = h;
430    _sizing_eval(data);
431 }
432
433 static void
434 _list_new(Evas_Object *obj)
435 {
436    Widget_Data *wd = elm_widget_data_get(obj);
437
438    if (!wd) return;
439    //Scroller
440    wd->scr = elm_scroller_add(obj);
441    elm_scroller_bounce_set(wd->scr, EINA_FALSE, EINA_TRUE);
442    elm_object_content_set(wd->scr, wd->box);
443    evas_object_size_hint_weight_set(wd->scr, EVAS_HINT_EXPAND,
444                                     EVAS_HINT_EXPAND);
445    evas_object_size_hint_align_set(wd->scr, EVAS_HINT_FILL, EVAS_HINT_FILL);
446    evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_RESIZE,
447                                   _scroller_resize, obj);
448    evas_object_event_callback_add(wd->scr,
449                                   EVAS_CALLBACK_CHANGED_SIZE_HINTS,
450                                   _changed_size_hints, obj);
451    elm_object_part_content_set(wd->base, "elm.swallow.content", wd->scr);
452
453    //Box
454    wd->box = elm_box_add(obj);
455    evas_object_size_hint_weight_set(wd->box, EVAS_HINT_EXPAND,
456                                     EVAS_HINT_EXPAND);
457    evas_object_size_hint_align_set(wd->box, EVAS_HINT_FILL, EVAS_HINT_FILL);
458
459    elm_object_content_set(wd->scr, wd->box);
460 }
461
462 static void
463 _list_del(Widget_Data *wd)
464 {
465    if (!wd->scr) return;
466    elm_object_part_content_unset(wd->base, "elm.swallow.content");
467    evas_object_event_callback_del(wd->scr, EVAS_CALLBACK_RESIZE,
468                                   _scroller_resize);
469    evas_object_event_callback_del(wd->scr, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
470                                   _changed_size_hints);
471    evas_object_del(wd->scr);
472    wd->scr = NULL;
473    wd->box = NULL;
474 }
475
476 static void
477 _scroller_size_calc(Evas_Object *obj)
478 {
479    Evas_Coord h;
480    Evas_Coord h_title = 0;
481    Evas_Coord h_action_area = 0;
482    Evas_Coord h_content = 0;
483    const char *action_area_height;
484    Widget_Data *wd = elm_widget_data_get(obj);
485
486    if (!wd || !wd->items) return;
487    wd->scr_size_recalc = EINA_FALSE;
488    wd->max_sc_h = -1;
489    wd->max_sc_w = -1;
490    evas_object_geometry_get(wd->notify, NULL, NULL, NULL, &h);
491    if (wd->title_text || wd->title_icon)
492      edje_object_part_geometry_get(elm_layout_edje_get(wd->base),
493                                    "elm.bg.title", NULL, NULL, NULL, &h_title);
494    if (wd->button_count)
495      {
496         action_area_height = edje_object_data_get(
497                  elm_layout_edje_get(wd->action_area), "action_area_height");
498         if (action_area_height) h_action_area = (int)(atoi(action_area_height)
499                  * _elm_config->scale * elm_object_scale_get(obj));
500      }
501    h_content = h - (h_title + h_action_area);
502    wd->max_sc_h = h_content;
503 }
504
505 static void
506 _item_select_cb(void *data, Evas_Object *obj __UNUSED__,
507                 const char *emission __UNUSED__, const char *source __UNUSED__)
508 {
509    Elm_Popup_Content_Item *item = data;
510
511    if (!item || item->disabled) return;
512    if (item->func)
513      item->func((void*)item->base.data, WIDGET(item), data);
514 }
515
516 static void
517 _item_new(Elm_Popup_Content_Item *item)
518 {
519    Widget_Data *wd = elm_widget_data_get(WIDGET(item));
520
521    if (!wd) return;
522    elm_widget_item_text_set_hook_set(item, _item_text_set_hook);
523    elm_widget_item_text_get_hook_set(item, _item_text_get_hook);
524    elm_widget_item_content_set_hook_set(item, _item_content_set_hook);
525    elm_widget_item_content_get_hook_set(item, _item_content_get_hook);
526    elm_widget_item_content_unset_hook_set(item, _item_content_unset_hook);
527    elm_widget_item_disable_hook_set(item, _item_disable_hook);
528    elm_widget_item_del_pre_hook_set(item, _item_del_pre_hook);
529    elm_widget_item_signal_emit_hook_set(item, _item_signal_emit_hook);
530    VIEW(item) = edje_object_add(evas_object_evas_get(wd->base));
531    _elm_theme_object_set(WIDGET(item), VIEW(item), "popup", "item",
532                          elm_widget_style_get(WIDGET(item)));
533    edje_object_mirrored_set(VIEW(item), elm_widget_mirrored_get(WIDGET(item)));
534    edje_object_signal_callback_add(VIEW(item), "elm,action,click", "",
535                                    _item_select_cb, item);
536    evas_object_size_hint_align_set(VIEW(item), EVAS_HINT_FILL,
537                                    EVAS_HINT_FILL);
538    evas_object_show(VIEW(item));
539 }
540
541 static void
542 _remove_items(Widget_Data *wd)
543 {
544    Eina_List *elist;
545    Elm_Popup_Content_Item *item;
546
547    if (!wd->items) return;
548    EINA_LIST_FOREACH(wd->items, elist, item)
549      {
550         if (item->label)
551           eina_stringshare_del(item->label);
552         if (item->icon)
553           {
554              evas_object_del(item->icon);
555              item->icon = NULL;
556           }
557         evas_object_del(VIEW(item));
558         wd->items = eina_list_remove(wd->items, item);
559         free(item);
560      }
561    wd->items = NULL;
562 }
563
564 static void
565 _notify_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
566                void *event_info __UNUSED__)
567 {
568    Widget_Data *wd = elm_widget_data_get(data);
569
570    if (wd->items)
571      _scroller_size_calc(data);
572    _sizing_eval(data);
573 }
574
575 static void
576 _title_text_set(Evas_Object *obj, const char *text)
577 {
578    ELM_CHECK_WIDTYPE(obj, widtype);
579    Eina_Bool title_visibility_old, title_visibility_current;
580    Widget_Data *wd = elm_widget_data_get(obj);
581
582    if (!wd) return;
583    if (wd->title_text == text) return;
584    title_visibility_old = (wd->title_text) || (wd->title_icon);
585    eina_stringshare_replace(&wd->title_text, text);
586    elm_object_part_text_set(wd->base, "elm.text.title", text);
587    if (wd->title_text)
588      elm_object_signal_emit(wd->base, "elm,state,title,text,visible", "elm");
589    else
590      elm_object_signal_emit(wd->base, "elm,state,title,text,hidden", "elm");
591    title_visibility_current = (wd->title_text) || (wd->title_icon);
592    if (title_visibility_old != title_visibility_current)
593      _layout_set(obj);
594    edje_object_message_signal_process(wd->base);
595    _sizing_eval(obj);
596 }
597
598 static void
599 _content_text_set(Evas_Object *obj, const char *text)
600 {
601    ELM_CHECK_WIDTYPE(obj, widtype);
602    Evas_Object *prev_content;
603    char buf[128];
604    Widget_Data *wd = elm_widget_data_get(obj);
605
606    if (!wd) return;
607    if (wd->items)
608      {
609         _remove_items(wd);
610         _list_del(wd);
611      }
612    prev_content = elm_object_part_content_get(wd->content_area,
613                                               "elm.swallow.content");
614    if (prev_content)
615      evas_object_del(prev_content);
616    if (text)
617      {
618         elm_object_part_content_set(wd->base, "elm.swallow.content",
619                                     wd->content_area);
620         wd->content_text_obj = elm_label_add(obj);
621         snprintf(buf, sizeof(buf), "popup/%s",
622                  elm_widget_style_get(obj));
623         elm_object_style_set(wd->content_text_obj, buf);
624         elm_label_line_wrap_set(wd->content_text_obj,
625                                 wd->content_text_wrap_type);
626         elm_object_text_set(wd->content_text_obj, text);
627         evas_object_size_hint_weight_set(wd->content_text_obj, EVAS_HINT_EXPAND,
628                                          0.0);
629         evas_object_size_hint_align_set(wd->content_text_obj, EVAS_HINT_FILL,
630                                         EVAS_HINT_FILL);
631         elm_object_part_content_set(wd->content_area, "elm.swallow.content",
632                                     wd->content_text_obj);
633      }
634    _sizing_eval(obj);
635 }
636
637 static void
638 _text_set_hook(Evas_Object *obj, const char *part,
639                               const char *label)
640 {
641    ELM_CHECK_WIDTYPE(obj, widtype);
642    Widget_Data *wd = elm_widget_data_get(obj);
643
644    if (!wd) return;
645    if (!part || !strcmp(part, "default"))
646      _content_text_set(obj, label);
647    else if (!strcmp(part, "title,text"))
648      _title_text_set(obj, label);
649    else
650      WRN("The part name is invalid! : popup=%p", obj);
651 }
652
653 static const char*
654 _title_text_get(const Evas_Object *obj)
655 {
656    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
657    Widget_Data *wd = elm_widget_data_get(obj);
658
659    if (!wd) return NULL;
660    return wd->title_text;
661 }
662
663 static const char*
664 _content_text_get(const Evas_Object *obj)
665 {
666    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
667    const char *str = NULL;
668    Widget_Data *wd = elm_widget_data_get(obj);
669
670    if (!wd) return NULL;
671    if (wd->content_text_obj)
672      str = elm_object_text_get(wd->content_text_obj);
673    return str;
674 }
675
676 static const char *
677 _text_get_hook(const Evas_Object *obj, const char *part)
678 {
679    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
680    const char *str = NULL;
681    Widget_Data *wd = elm_widget_data_get(obj);
682
683    if (!wd) return NULL;
684    if (!part || !strcmp(part, "default"))
685      str = _content_text_get(obj);
686    else if (!strcmp(part, "title,text"))
687      str = _title_text_get(obj);
688    else
689      WRN("The part name is invalid! : popup=%p", obj);
690    return str;
691 }
692
693 static void
694 _title_icon_set(Evas_Object *obj, Evas_Object *icon)
695 {
696    ELM_CHECK_WIDTYPE(obj, widtype);
697    Eina_Bool title_visibility_old, title_visibility_current;
698    Widget_Data *wd = elm_widget_data_get(obj);
699
700    if (!wd) return;
701    if (wd->title_icon == icon) return;
702    title_visibility_old = (wd->title_text) || (wd->title_icon);
703    if (wd->title_icon)
704      {
705         evas_object_del(wd->title_icon);
706         wd->title_icon = NULL;
707      }
708    wd->title_icon = icon;
709    title_visibility_current = (wd->title_text) || (wd->title_icon);
710    elm_object_part_content_set(wd->base, "elm.swallow.title.icon",
711                                wd->title_icon);
712    if (wd->title_icon)
713      elm_object_signal_emit(wd->base, "elm,state,title,icon,visible", "elm");
714    if (title_visibility_old != title_visibility_current) _layout_set(obj);
715    edje_object_message_signal_process(wd->base);
716    _sizing_eval(obj);
717 }
718
719 static void
720 _content_set(Evas_Object *obj, Evas_Object *content)
721 {
722    ELM_CHECK_WIDTYPE(obj, widtype);
723    Evas_Object *prev_content;
724    Widget_Data *wd = elm_widget_data_get(obj);
725
726    if (!wd) return;
727    if (wd->content && wd->content == content) return;
728    if (wd->items)
729      {
730         _remove_items(wd);
731         _list_del(wd);
732      }
733    prev_content = elm_object_part_content_get(wd->content_area,
734                                               "elm.swallow.content");
735    if (prev_content)
736      evas_object_del(prev_content);
737    wd->content = content;
738    if (content)
739      {
740         elm_object_part_content_set(wd->base, "elm.swallow.content",
741                                     wd->content_area);
742         elm_object_part_content_set(wd->content_area, "elm.swallow.content",
743                                     content);
744      }
745    _sizing_eval(obj);
746 }
747
748 static void
749 _button_remove(Evas_Object *obj, Evas_Object *content, Eina_Bool delete)
750 {
751    unsigned int i = 0, position = 0;
752    char buf[128];
753    Widget_Data *wd = elm_widget_data_get(obj);
754
755    if (!wd->button_count) return;
756    for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
757     {
758        if (wd->buttons[i])
759          {
760             position++;
761             wd->buttons[i]->delete_me = EINA_FALSE;
762             if (wd->buttons[i]->btn == content)
763               {
764                  snprintf(buf, sizeof(buf), "actionbtn%u", position);
765                  elm_object_part_content_unset(wd->action_area, buf);
766                  evas_object_hide(content);
767                  if (delete) evas_object_del(content);
768                  free(wd->buttons[i]);
769                  wd->buttons[i] = NULL;
770                  wd->button_count -= 1;
771                }
772          }
773     }
774    position = 0;
775    for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
776     {
777        if (!wd->buttons[i]) continue;
778        position++;
779        snprintf(buf, sizeof(buf), "actionbtn%u", position);
780        elm_object_part_content_unset(wd->action_area, buf);
781        elm_object_part_content_set(wd->action_area, buf,
782                                    wd->buttons[i]->btn);
783        wd->buttons[i]->delete_me = EINA_TRUE;
784     }
785    if (!wd->button_count)
786     {
787        _layout_set(obj);
788        edje_object_message_signal_process(elm_layout_edje_get(wd->base));
789     }
790    else
791     {
792        snprintf(buf, sizeof(buf), "buttons%u", wd->button_count);
793        elm_layout_theme_set(wd->action_area, "popup", buf,
794                             elm_widget_style_get(obj));
795     }
796 }
797
798 static void
799 _action_button_set(Evas_Object *obj, Evas_Object *btn, unsigned int idx)
800 {
801    Action_Area_Data *adata;
802    char buf[128];
803    unsigned int num = idx - 1, i = 0, position = 0;
804    Widget_Data *wd = elm_widget_data_get(obj);
805
806    if (!wd) return;
807    if (num >= ELM_POPUP_ACTION_BUTTON_MAX) return;
808    if (wd->buttons[num])
809      _button_remove(obj, wd->buttons[num]->btn, EINA_TRUE);
810    if (btn)
811      {
812         wd->button_count++;
813         snprintf(buf, sizeof(buf), "buttons%u", wd->button_count);
814         elm_layout_theme_set(wd->action_area, "popup", buf,
815                              elm_widget_style_get(obj));
816         adata = ELM_NEW(Action_Area_Data);
817         adata->obj = obj;
818         adata->btn = btn;
819         wd->buttons[num] = adata;
820         /* Adding delete_me state inside action data as unset calls _sub_del
821            too and before setting a new content, the previous one needs to
822            be unset in order to avoid unwanted deletion. This way rearrangement
823             of buttons can be achieved in action area.
824          */
825         for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
826           if (wd->buttons[i])
827             wd->buttons[i]->delete_me = EINA_FALSE;
828         for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
829           {
830              if (!wd->buttons[i]) continue;
831              position++;
832              snprintf(buf, sizeof(buf), "actionbtn%u", position);
833              elm_object_part_content_unset(wd->action_area, buf);
834              elm_object_part_content_set(wd->action_area, buf,
835                                          wd->buttons[i]->btn);
836              /* Setting delete_me to TRUE in order to let _sub_del handle it
837                 if deleted externally and update the buttons array after freeing
838                 action data allocated earlier.
839               */
840              wd->buttons[i]->delete_me = EINA_TRUE;
841           }
842         elm_object_part_content_set(wd->base, "elm.swallow.action_area",
843                                     wd->action_area);
844         if (wd->button_count == 1)
845           _layout_set(obj);
846         edje_object_message_signal_process(wd->base);
847         if (wd->items)
848           _scroller_size_calc(obj);
849         _sizing_eval(obj);
850      }
851 }
852
853 static void
854 _content_set_hook(Evas_Object *obj, const char *part,
855                                  Evas_Object *content)
856 {
857    ELM_CHECK_WIDTYPE(obj, widtype);
858    char buff[3];
859    unsigned int i;
860    Widget_Data *wd = elm_widget_data_get(obj);
861
862    if (!wd) return;
863    if (!part || !strcmp(part, "default"))
864      _content_set(obj, content);
865    else if (!strcmp(part, "title,icon"))
866      _title_icon_set(obj, content);
867    else if (!strncmp(part, "button", 6))
868      {
869         part += 6;
870         for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
871           {
872              snprintf(buff, sizeof(buff), "%u", i+1);
873              if (!strncmp(part, buff, sizeof(buff)))
874                {
875                   _action_button_set(obj, content, i+1);
876                   break;
877                }
878           }
879       }
880    else
881      WRN("The part name is invalid! : popup=%p", obj);
882 }
883
884 static Evas_Object *
885 _title_icon_get(Evas_Object *obj)
886 {
887    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
888    Widget_Data *wd = elm_widget_data_get(obj);
889
890    if (!wd) return NULL;
891    return wd->title_icon;
892 }
893
894 static Evas_Object *
895 _content_get(Evas_Object *obj)
896 {
897    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
898    Widget_Data *wd = elm_widget_data_get(obj);
899
900    if (!wd) return NULL;
901    return wd->content;
902 }
903
904 static Evas_Object *
905 _action_button_get(Evas_Object *obj, unsigned int idx)
906 {
907    unsigned int num = idx - 1;
908    Evas_Object *button = NULL;
909    Widget_Data *wd = elm_widget_data_get(obj);
910
911    if (!wd || !wd->button_count) return NULL;
912    if (wd->buttons[num])
913      button = wd->buttons[num]->btn;
914    return button;
915 }
916
917 static Evas_Object *
918 _content_get_hook(Evas_Object *obj, const char *part)
919 {
920    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
921    Evas_Object *content = NULL;
922    char buff[3];
923    unsigned int i;
924    Widget_Data *wd = elm_widget_data_get(obj);
925
926    if (!wd) return NULL;
927    if (!part || !strcmp(part, "default"))
928      content = _content_get(obj);
929    else if (!strcmp(part, "title,text"))
930      content = _title_icon_get(obj);
931    else if (!strncmp(part, "button", 6))
932      {
933         part += 6;
934         for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
935           {
936              snprintf(buff, sizeof(buff), "%u", i+1);
937              if (!strncmp(part, buff, sizeof(buff)))
938                {
939                   content = _action_button_get(obj, i+1);
940                   break;
941                }
942           }
943       }
944    else
945      WRN("The part name is invalid! : popup=%p", obj);
946    return content;
947 }
948
949 static Evas_Object *
950 _content_unset(Evas_Object *obj)
951 {
952    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
953    Evas_Object *content;
954    Widget_Data *wd = elm_widget_data_get(obj);
955
956    if (!wd || !wd->content) return NULL;
957    content = elm_object_part_content_unset(wd->content_area,
958                                            "elm.swallow.content");
959    wd->content = NULL;
960    _sizing_eval(obj);
961    return content;
962 }
963
964 static Evas_Object *
965 _title_icon_unset(Evas_Object *obj)
966 {
967    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
968    Evas_Object *icon;
969    Widget_Data *wd = elm_widget_data_get(obj);
970
971    if (!wd || !wd->title_icon) return NULL;
972    icon = elm_object_part_content_unset(wd->base, "elm.swallow.title.icon");
973    wd->title_icon = NULL;
974    return icon;
975 }
976
977 static Evas_Object *
978 _action_button_unset(Evas_Object *obj, unsigned int idx)
979 {
980    unsigned int num = idx -1;
981    Evas_Object *button = NULL;
982    Widget_Data *wd = elm_widget_data_get(obj);
983
984    if (!wd) return NULL;
985    if ((!wd->button_count) || (num >= ELM_POPUP_ACTION_BUTTON_MAX))
986      return NULL;
987
988    if (wd->buttons[num])
989      {
990         button = wd->buttons[num]->btn;
991         _button_remove(obj, button, EINA_FALSE);
992       }
993    return button;
994 }
995
996 static Evas_Object *
997 _content_unset_hook(Evas_Object *obj, const char *part)
998 {
999    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1000    Evas_Object *content = NULL;
1001    char buff[3];
1002    unsigned int i;
1003    Widget_Data *wd = elm_widget_data_get(obj);
1004
1005    if (!wd) return NULL;
1006    if (!part || !strcmp(part, "default"))
1007      content = _content_unset(obj);
1008    else if (!strcmp(part, "title,icon"))
1009      content = _title_icon_unset(obj);
1010    else if (!strncmp(part, "button", 6))
1011      {
1012         part += 6;
1013         for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
1014           {
1015              snprintf(buff, sizeof(buff), "%u", i+1);
1016              if (!strncmp(part, buff, sizeof(buff)))
1017                {
1018                   content = _action_button_unset(obj, i+1);
1019                   break;
1020                }
1021           }
1022       }
1023    else
1024      WRN("The part name is invalid! : popup=%p", obj);
1025    return content;
1026 }
1027
1028 static Eina_Bool
1029 _focus_next_hook(const Evas_Object *obj __UNUSED__,
1030                  Elm_Focus_Direction dir __UNUSED__,
1031                  Evas_Object **next __UNUSED__)
1032 {
1033    //TODO: Implement Focus chanin Handling in Popup for action area buttons
1034    return EINA_FALSE;
1035 }
1036 static void
1037 _item_text_set(Elm_Popup_Content_Item *item, const char *label)
1038 {
1039    if (!eina_stringshare_replace(&item->label, label)) return;
1040    edje_object_part_text_set(VIEW(item), "elm.text", label);
1041    if (item->label)
1042      edje_object_signal_emit(VIEW(item),
1043                              "elm,state,item,text,visible", "elm");
1044    else
1045      edje_object_signal_emit(VIEW(item),
1046                              "elm,state,item,text,hidden", "elm");
1047    edje_object_message_signal_process(VIEW(item));
1048 }
1049
1050 static void
1051 _item_text_set_hook(Elm_Object_Item *it, const char *part, const char *label)
1052 {
1053    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1054    Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *)it;
1055
1056    if ((!part) || (!strcmp(part, "default")))
1057      {
1058         _item_text_set(item, label);
1059         return;
1060      }
1061    WRN("The part name is invalid! : popup=%p", WIDGET(item));
1062 }
1063
1064 static const char *
1065 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
1066 {
1067    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1068    Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *)it;
1069
1070    if ((!part) || (!strcmp(part, "default")))
1071      return item->label;
1072    WRN("The part name is invalid! : popup=%p", WIDGET(item));
1073    return NULL;
1074 }
1075
1076 static void
1077 _item_icon_set(Elm_Popup_Content_Item *item, Evas_Object *icon)
1078 {
1079    if (item->icon == icon) return;
1080    if (item->icon)
1081      {
1082         elm_widget_sub_object_del(WIDGET(item), item->icon);
1083         evas_object_data_del(item->icon, "_popup_content_item");
1084         evas_object_del(item->icon);
1085      }
1086    item->icon = icon;
1087    if (item->icon)
1088      {
1089         elm_widget_sub_object_add(WIDGET(item), item->icon);
1090         evas_object_data_set(item->icon, "_popup_content_item", item);
1091         edje_object_part_swallow(VIEW(item), "elm.swallow.content",
1092                                  item->icon);
1093         edje_object_signal_emit(VIEW(item),
1094                                 "elm,state,item,icon,visible", "elm");
1095      }
1096    else
1097      edje_object_signal_emit(VIEW(item),
1098                              "elm,state,item,icon,hidden", "elm");
1099    edje_object_message_signal_process(item->base.view);
1100 }
1101
1102 static void
1103 _item_content_set_hook(Elm_Object_Item *it, const char *part,
1104                        Evas_Object *content)
1105 {
1106    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1107    Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *)it;
1108
1109    if ((!(part)) || (!strcmp(part, "default")))
1110      _item_icon_set(item, content);
1111    else
1112      WRN("The part name is invalid! : popup=%p", WIDGET(item));
1113 }
1114
1115 static Evas_Object *
1116 _item_content_get_hook(const Elm_Object_Item *it,
1117                        const char *part)
1118 {
1119    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1120    Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *)it;
1121
1122    if ((!(part)) || (!strcmp(part, "default")))
1123      return item->icon;
1124    WRN("The part name is invalid! : popup=%p", WIDGET(item));
1125    return NULL;
1126 }
1127
1128 static Evas_Object *
1129 _item_icon_unset(Elm_Popup_Content_Item *item)
1130 {
1131    Evas_Object *icon = item->icon;
1132
1133    if (!item->icon) return NULL;
1134    elm_widget_sub_object_del(WIDGET(item), icon);
1135    evas_object_data_del(icon, "_popup_content_item");
1136    edje_object_part_unswallow(item->base.view, icon);
1137    edje_object_signal_emit(VIEW(item),
1138                            "elm,state,item,icon,hidden", "elm");
1139    item->icon = NULL;
1140    return icon;
1141 }
1142
1143 static Evas_Object *
1144 _item_content_unset_hook(const Elm_Object_Item *it,
1145                          const char *part)
1146 {
1147    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1148    Evas_Object *content = NULL;
1149    Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *)it;
1150
1151    if ((!(part)) || (!strcmp(part, "default")))
1152      content = _item_icon_unset(item);
1153    else
1154      WRN("The part name is invalid! : popup=%p", WIDGET(item));
1155    return content;
1156 }
1157
1158 static void
1159 _item_disable_hook(Elm_Object_Item *it)
1160 {
1161    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1162    Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *)it;
1163    Widget_Data *wd = elm_widget_data_get(WIDGET(item));
1164
1165    if (!wd) return;
1166    if (elm_widget_item_disabled_get(it))
1167      edje_object_signal_emit(VIEW(item), "elm,state,item,disabled", "elm");
1168    else
1169      edje_object_signal_emit(VIEW(item), "elm,state,item,enabled", "elm");
1170 }
1171
1172 static void
1173 _item_del_pre_hook(Elm_Object_Item *it)
1174 {
1175    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1176    Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *)it;
1177    Widget_Data *wd = elm_widget_data_get(WIDGET(item));
1178
1179    if (!wd) return;
1180    if (item->icon)
1181      evas_object_del(item->icon);
1182    eina_stringshare_del(item->label);
1183    wd->items = eina_list_remove(wd->items, item);
1184    if (!eina_list_count(wd->items))
1185      {
1186         wd->items = NULL;
1187         _list_del(wd);
1188      }
1189 }
1190
1191 static void
1192 _item_signal_emit_hook(Elm_Object_Item *it, const char *emission,
1193                        const char *source)
1194 {
1195    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1196    Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *)it;
1197
1198    edje_object_signal_emit(VIEW(item), emission, source);
1199 }
1200
1201 EAPI Evas_Object *
1202 elm_popup_add(Evas_Object *parent)
1203 {
1204    Evas_Object *obj;
1205    Evas *e;
1206    int i = 0;
1207    Widget_Data *wd;
1208
1209    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1210    ELM_SET_WIDTYPE(widtype, "popup");
1211    elm_widget_type_set(obj, widtype);
1212    elm_widget_sub_object_add(parent, obj);
1213    elm_widget_data_set(obj, wd);
1214    elm_widget_del_pre_hook_set(obj, _del_pre_hook);
1215    elm_widget_del_hook_set(obj, _del_hook);
1216    elm_widget_theme_hook_set(obj, _theme_hook);
1217    elm_widget_text_set_hook_set(obj, _text_set_hook);
1218    elm_widget_text_get_hook_set(obj, _text_get_hook);
1219    elm_widget_content_set_hook_set(obj, _content_set_hook);
1220    elm_widget_content_get_hook_set(obj, _content_get_hook);
1221    elm_widget_content_unset_hook_set(obj,_content_unset_hook);
1222    elm_widget_focus_next_hook_set(obj, _focus_next_hook);
1223    evas_object_smart_callbacks_descriptions_set(obj, _signals);
1224
1225    wd->notify = elm_notify_add(obj);
1226    elm_widget_resize_object_set(obj, wd->notify);
1227    elm_notify_parent_set(wd->notify, parent);
1228    elm_notify_orient_set(wd->notify, ELM_NOTIFY_ORIENT_CENTER);
1229    elm_notify_allow_events_set(wd->notify, EINA_FALSE);
1230    evas_object_size_hint_weight_set(wd->notify,
1231                                     EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1232    evas_object_size_hint_align_set(wd->notify, EVAS_HINT_FILL, EVAS_HINT_FILL);
1233    elm_object_style_set(wd->notify, "popup");
1234
1235    evas_object_event_callback_add(wd->notify, EVAS_CALLBACK_RESIZE,
1236                                   _notify_resize, obj);
1237    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESTACK, _restack, NULL);
1238    wd->base = elm_layout_add(obj);
1239    evas_object_size_hint_weight_set(wd->base, EVAS_HINT_EXPAND,
1240                                     EVAS_HINT_EXPAND);
1241    evas_object_size_hint_align_set(wd->base, EVAS_HINT_FILL, EVAS_HINT_FILL);
1242
1243    elm_layout_theme_set(wd->base, "popup", "base", elm_widget_style_get(obj));
1244    elm_object_content_set(wd->notify, wd->base);
1245
1246    elm_object_signal_callback_add(wd->base, "elm,state,title_area,visible",
1247                                   "elm", _layout_change_cb, obj);
1248    elm_object_signal_callback_add(wd->base, "elm,state,title_area,hidden",
1249                                   "elm", _layout_change_cb, obj);
1250    elm_object_signal_callback_add(wd->base, "elm,state,action_area,visible",
1251                                   "elm", _layout_change_cb, obj);
1252    elm_object_signal_callback_add(wd->base, "elm,state,action_area,hidden",
1253                                   "elm", _layout_change_cb, obj);
1254    wd->content_area = elm_layout_add(obj);
1255    elm_layout_theme_set(wd->content_area, "popup", "content",
1256                         elm_widget_style_get(obj));
1257    wd->action_area = elm_layout_add(obj);
1258    evas_object_size_hint_weight_set(wd->action_area, EVAS_HINT_EXPAND,
1259                                     EVAS_HINT_EXPAND);
1260    evas_object_size_hint_align_set(wd->action_area, EVAS_HINT_FILL,
1261                                    EVAS_HINT_FILL);
1262    evas_object_event_callback_add(wd->action_area,
1263                                   EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1264                                   _changed_size_hints, obj);
1265    evas_object_event_callback_add(wd->content_area,
1266                                   EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1267                                   _changed_size_hints, obj);
1268    evas_object_smart_callback_add(wd->base, "sub-object-del",
1269                                   _sub_del, obj);
1270    evas_object_smart_callback_add(wd->content_area, "sub-object-del",
1271                                   _sub_del, obj);
1272    evas_object_smart_callback_add(wd->action_area, "sub-object-del",
1273                                   _sub_del, obj);
1274    evas_object_smart_callback_add(obj, "sub-object-del",
1275                                   _sub_del, obj);
1276
1277    wd->content_text_wrap_type = ELM_WRAP_MIXED;
1278    evas_object_smart_callback_add(wd->notify, "block,clicked",
1279                                   _block_clicked_cb, obj);
1280    evas_object_smart_callback_add(wd->notify, "timeout", _timeout, obj);
1281    for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
1282      wd->buttons[i] = NULL;
1283    _layout_set(obj);
1284    //TODO: To use scroller for description also
1285    return obj;
1286 }
1287
1288 EAPI void
1289 elm_popup_content_text_wrap_type_set(Evas_Object *obj, Elm_Wrap_Type wrap)
1290 {
1291    ELM_CHECK_WIDTYPE(obj, widtype);
1292    Evas_Object *content_text_obj;
1293    Widget_Data *wd = elm_widget_data_get(obj);
1294
1295    if (!wd) return;
1296    if (wd->content_text_wrap_type == ELM_WRAP_NONE) return;
1297    //Need to wrap the content text, so not allowing ELM_WRAP_NONE
1298    wd->content_text_wrap_type = wrap;
1299    if (wd->content_text_obj)
1300      {
1301         content_text_obj = elm_object_part_content_get(wd->content_area,
1302                                                        "elm.swallow.content");
1303         elm_label_line_wrap_set(content_text_obj, wrap);
1304      }
1305 }
1306
1307 EAPI Elm_Wrap_Type
1308 elm_popup_content_text_wrap_type_get(const Evas_Object *obj)
1309 {
1310    ELM_CHECK_WIDTYPE(obj, widtype) ELM_WRAP_LAST;
1311    Widget_Data *wd = elm_widget_data_get(obj);
1312
1313    if (!wd) return ELM_WRAP_LAST;
1314    return wd->content_text_wrap_type;
1315 }
1316
1317 EAPI void
1318 elm_popup_orient_set(Evas_Object *obj, Elm_Popup_Orient orient)
1319 {
1320    ELM_CHECK_WIDTYPE(obj, widtype);
1321    Widget_Data *wd = elm_widget_data_get(obj);
1322
1323    if (!wd) return;
1324    if (orient >= ELM_POPUP_ORIENT_LAST) return;
1325    elm_notify_orient_set(wd->notify, (Elm_Notify_Orient)orient);
1326 }
1327
1328 EAPI Elm_Popup_Orient
1329 elm_popup_orient_get(const Evas_Object *obj)
1330 {
1331    ELM_CHECK_WIDTYPE(obj, widtype) -1;
1332    Widget_Data *wd = elm_widget_data_get(obj);
1333
1334    if (!wd) return ELM_POPUP_ORIENT_LAST;
1335    return (Elm_Popup_Orient)elm_notify_orient_get(wd->notify);
1336 }
1337
1338 EAPI void
1339 elm_popup_timeout_set(Evas_Object *obj, double timeout)
1340 {
1341    ELM_CHECK_WIDTYPE(obj, widtype);
1342    Widget_Data *wd = elm_widget_data_get(obj);
1343
1344    if (!wd) return;
1345    elm_notify_timeout_set(wd->notify, timeout);
1346 }
1347
1348 EAPI double
1349 elm_popup_timeout_get(const Evas_Object *obj)
1350 {
1351    ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
1352    Widget_Data *wd = elm_widget_data_get(obj);
1353
1354    if (!wd) return 0.0;
1355    return elm_notify_timeout_get(wd->notify);
1356 }
1357
1358 EAPI void
1359 elm_popup_allow_events_set(Evas_Object *obj, Eina_Bool allow)
1360 {
1361    ELM_CHECK_WIDTYPE(obj, widtype);
1362    Eina_Bool allow_events = !!allow;
1363    Widget_Data *wd = elm_widget_data_get(obj);
1364
1365    if (!wd) return;
1366    elm_notify_allow_events_set(wd->notify, allow_events);
1367 }
1368
1369 EAPI Eina_Bool
1370 elm_popup_allow_events_get(const Evas_Object *obj)
1371 {
1372    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1373    Widget_Data *wd = elm_widget_data_get(obj);
1374
1375    if (!wd) return EINA_FALSE;
1376    return elm_notify_allow_events_get(wd->notify);
1377 }
1378
1379 EAPI Elm_Object_Item *
1380 elm_popup_item_append(Evas_Object *obj, const char *label,
1381                               Evas_Object *icon, Evas_Smart_Cb func,
1382                               const void *data)
1383 {
1384    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1385    Evas_Object *prev_content;
1386    Elm_Popup_Content_Item *item;
1387    Widget_Data *wd = elm_widget_data_get(obj);
1388
1389    if (!wd) return NULL;
1390    item = elm_widget_item_new(obj, Elm_Popup_Content_Item);
1391    if (!item) return NULL;
1392    if (wd->content || wd->content_text_obj)
1393      {
1394         prev_content = elm_object_part_content_get(wd->content_area,
1395                                                    "elm.swallow.content");
1396         if (prev_content)
1397           evas_object_del(prev_content);
1398      }
1399
1400    //The first item is appended.
1401    if (!wd->items)
1402      _list_new(obj);
1403
1404    item->func = func;
1405    item->base.data = data;
1406
1407    _item_new(item);
1408    _item_icon_set(item, icon);
1409    _item_text_set(item, label);
1410    elm_box_pack_end(wd->box, VIEW(item));
1411    wd->items = eina_list_append(wd->items, item);
1412
1413    _scroller_size_calc(obj);
1414    _sizing_eval(obj);
1415    return (Elm_Object_Item *)item;
1416 }