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