atspi: Handle default label object on toolkit side
[platform/upstream/elementary.git] / src / lib / elc_popup.c
1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4
5 #define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
6 #define ELM_INTERFACE_ATSPI_COMPONENT_PROTECTED
7 #define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED
8 #define ELM_WIDGET_ITEM_PROTECTED
9
10 #include <Elementary.h>
11 #include "elm_priv.h"
12 #include "elm_widget_popup.h"
13
14 #include "elm_popup_item.eo.h"
15
16 #define MY_CLASS ELM_POPUP_CLASS
17
18 #define MY_CLASS_NAME "Elm_Popup"
19 #define MY_CLASS_NAME_LEGACY "elm_popup"
20
21 static void _button_remove(Evas_Object *, int, Eina_Bool);
22
23 static const char ACCESS_TITLE_PART[] = "access.title";
24 static const char ACCESS_BODY_PART[] = "access.body";
25 static const char CONTENT_PART[] = "elm.swallow.content";
26
27 static const char SIG_BLOCK_CLICKED[] = "block,clicked";
28 static const char SIG_TIMEOUT[] = "timeout";
29 static const char SIG_ITEM_FOCUSED[] = "item,focused";
30 static const char SIG_ITEM_UNFOCUSED[] = "item,unfocused";
31
32 //TIZEN_ONLY(20161213): apply screen_reader_changed callback
33 static const char SIG_ATSPI_SCREEN_READER_CHANGED[] = "atspi,screen,reader,changed";
34 //
35 //TIZEN_ONLY(20161109): check theme compatibility more precise
36 static const char STYLE_PRIORITY[4][15] = { "%s", "popup/%s", "default", "popup/default" };
37 //
38
39 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
40    {SIG_BLOCK_CLICKED, ""},
41    {SIG_TIMEOUT, ""},
42    {SIG_ITEM_FOCUSED, ""},
43    {SIG_ITEM_UNFOCUSED, ""},
44    {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
45    {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */
46    {SIG_LAYOUT_FOCUSED, ""}, /**< handled by elm_layout */
47    {SIG_LAYOUT_UNFOCUSED, ""}, /**< handled by elm_layout */
48    //TIZEN_ONLY(20161213): apply screen_reader_changed callback
49    {SIG_ATSPI_SCREEN_READER_CHANGED, ""},
50    //
51    {NULL, NULL}
52 };
53
54 static Eina_Bool _key_action_move(Evas_Object *obj, const char *params);
55 static void _parent_geom_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED);
56 static Eina_Bool
57 _block_clicked_cb(void *data, Eo *obj EINA_UNUSED,
58                   const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED);
59 static Eina_Bool
60 _timeout_cb(void *data, Eo *obj EINA_UNUSED,
61             const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED);
62
63 //TIZEN_ONLY(20160629) : add "show,finished" internal callback
64 static Eina_Bool
65 _show_finished_cb(void *data, Eo *obj EINA_UNUSED,
66             const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED);
67 //
68 static Eina_Bool
69 _hide_effect_finished_cb(void *data, Eo *obj EINA_UNUSED,
70             const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED);
71
72 //TIZEN_ONLY(20150709) : add keybinding for elm_popup "block,clicked" action
73 static Eina_Bool _key_action_escape(Evas_Object *obj, const char *params);
74 ///
75
76 static const Elm_Action key_actions[] = {
77    {"move", _key_action_move},
78 //TIZEN_ONLY(20150709) : add keybinding for elm_popup "block,clicked" action
79    {"escape", _key_action_escape},
80 ///
81    {NULL, NULL}
82 };
83
84 EO_CALLBACKS_ARRAY_DEFINE(_notify_cb,
85    { ELM_NOTIFY_EVENT_BLOCK_CLICKED, _block_clicked_cb },
86    { ELM_NOTIFY_EVENT_TIMEOUT, _timeout_cb },
87    { ELM_NOTIFY_EVENT_DISMISSED, _hide_effect_finished_cb },
88 //TIZEN_ONLY(20160629) : add "show,finished" internal callback
89    { ELM_NOTIFY_EVENT_SHOW_FINISHED, _show_finished_cb }
90 //
91 );
92
93 static void  _on_content_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
94
95 EOLIAN static Eina_Bool
96 _elm_popup_elm_widget_translate(Eo *obj EINA_UNUSED, Elm_Popup_Data *sd)
97 {
98    Elm_Popup_Item_Data *it;
99    Eina_List *l;
100
101    EINA_LIST_FOREACH(sd->items, l, it)
102       eo_do(EO_OBJ(it), elm_wdg_item_translate());
103
104    eo_do_super(obj, MY_CLASS, elm_obj_widget_translate());
105    eo_do(sd->main_layout, elm_obj_widget_translate());
106
107    return EINA_TRUE;
108 }
109
110 static void
111 _visuals_set(Evas_Object *obj)
112 {
113    ELM_POPUP_DATA_GET(obj, sd);
114
115    if (!sd->title_text && !sd->title_icon)
116      elm_layout_signal_emit(sd->main_layout, "elm,state,title_area,hidden", "elm");
117    else
118      elm_layout_signal_emit(sd->main_layout, "elm,state,title_area,visible", "elm");
119
120    if (sd->action_area)
121      {
122         elm_layout_signal_emit(sd->main_layout, "elm,state,action_area,visible", "elm");
123         evas_object_show(sd->action_area);
124      }
125    else
126      elm_layout_signal_emit(sd->main_layout, "elm,state,action_area,hidden", "elm");
127
128    edje_object_message_signal_process(elm_layout_edje_get(sd->main_layout));
129 }
130
131 static Eina_Bool
132 _block_clicked_cb(void *data,
133       Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
134 {
135    eo_do(data, eo_event_callback_call(ELM_POPUP_EVENT_BLOCK_CLICKED, NULL));
136
137    return EINA_TRUE;
138 }
139
140 static Eina_Bool
141 _timeout_cb(void *data,
142       Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
143 {
144    evas_object_hide(data);
145    eo_do(data, eo_event_callback_call(ELM_POPUP_EVENT_TIMEOUT, NULL));
146
147    return EINA_TRUE;
148 }
149
150 //TIZEN_ONLY(20160629) : add "show,finished" internal callback
151 static Eina_Bool
152 _show_finished_cb(void *data,
153       Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
154 {
155    //TIZEN_ONLY(20170919): Handle default label object
156    _elm_win_default_label_obj_append(data);
157    //
158    eo_do(data, eo_event_callback_call(ELM_POPUP_EVENT_SHOW_FINISHED, NULL));
159
160    return EINA_TRUE;
161 }
162 //
163
164 static Eina_Bool
165 _hide_effect_finished_cb(void *data,
166       Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
167 {
168    evas_object_hide(data);
169    eo_do(data, eo_event_callback_call(ELM_POPUP_EVENT_DISMISSED, NULL));
170
171    return EINA_TRUE;
172 }
173
174
175 static Evas_Object *
176 _access_object_get(const Evas_Object *obj, const char* part)
177 {
178    Evas_Object *po, *ao;
179    ELM_POPUP_DATA_GET(obj, sd);
180
181    po = (Evas_Object *)edje_object_part_object_get
182       (elm_layout_edje_get(sd->main_layout), part);
183    ao = evas_object_data_get(po, "_part_access_obj");
184
185    return ao;
186 }
187
188 static void
189 _on_show(void *data EINA_UNUSED,
190          Evas *e EINA_UNUSED,
191          Evas_Object *obj,
192          void *event_info EINA_UNUSED)
193 {
194    elm_object_focus_set(obj, EINA_TRUE);
195 }
196
197 static void
198 _scroller_size_calc(Evas_Object *obj)
199 {
200    Evas_Coord h;
201    Evas_Coord h_title = 0;
202    Evas_Coord h_action_area = 0;
203    const char *action_area_height;
204    //TIZEN_ONLY(20160624): add outside padding
205    const char *outside_pad;
206    Evas_Coord h_pad = 0;
207    //
208    /* TIZEN_ONLY(20170202): fix popup max height */
209    Evas_Coord y, wy;
210    /* END */
211
212    ELM_POPUP_DATA_GET(obj, sd);
213    //TIZEN_ONLY(20160623):Apply popup compress mode UX
214    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
215    //
216
217    if (!sd->scroll && !sd->items) return;
218
219    sd->scr_size_recalc = EINA_FALSE;
220    sd->max_sc_h = -1;
221    /* TIZEN_ONLY(20170202): fix popup max height
222       adjust notify's height in case height of popup's parent is smaller than window's
223       and there is indicator below the popup
224    evas_object_geometry_get(sd->notify, NULL, NULL, NULL, &h);
225    */
226    evas_object_geometry_get(sd->notify, NULL, &y, NULL, &h);
227
228    evas_object_geometry_get(elm_widget_top_get(sd->notify), NULL, &wy, NULL, NULL);
229    h += (y - wy);
230    /* END */
231
232    if (sd->title_text || sd->title_icon)
233      edje_object_part_geometry_get(elm_layout_edje_get(sd->main_layout),
234                                    "elm.bg.title", NULL, NULL, NULL, &h_title);
235    if (sd->action_area)
236      {
237         action_area_height = edje_object_data_get(
238             elm_layout_edje_get(sd->action_area), "action_area_height");
239         if (action_area_height)
240           h_action_area =
241             (int)(atoi(action_area_height)
242                   * elm_config_scale_get() * elm_object_scale_get(obj))
243                   / edje_object_base_scale_get(elm_layout_edje_get(sd->action_area));
244      }
245
246    //TIZEN_ONLY(20160624): add out side padding
247    outside_pad = edje_object_data_get(elm_layout_edje_get(sd->main_layout), "popup_outside_pad");
248
249    if (outside_pad) h_pad = (int)(atoi(outside_pad)
250                             * elm_config_scale_get()
251                             * elm_object_scale_get(obj)
252                             / edje_object_base_scale_get(elm_layout_edje_get(sd->main_layout)));
253    //
254
255    //TIZEN_ONLY(20160623):Apply popup compress mode UX
256    //sd->max_sc_h = h - (h_title + h_action_area);
257    if ((sd->dispmode == EVAS_DISPLAY_MODE_COMPRESS) &&
258        ((wd->orient_mode == 90) || (wd->orient_mode == 270)))
259       sd->max_sc_h = h - h_action_area;
260    else
261       sd->max_sc_h = h - (h_title + h_action_area + h_pad);
262    //
263 }
264
265 //TIZEN_ONLY(20160623):Apply popup compress mode UX
266 static void
267 _on_obj_size_hints_changed(void *data EINA_UNUSED, Evas *e EINA_UNUSED,
268                            Evas_Object *obj, void *event_info EINA_UNUSED)
269 {
270    Evas_Display_Mode dispmode;
271
272    ELM_POPUP_DATA_GET(obj, sd);
273
274    dispmode = evas_object_size_hint_display_mode_get(obj);
275    if (sd->dispmode == dispmode) return;
276
277    sd->dispmode = dispmode;
278
279    _scroller_size_calc(obj);
280    elm_layout_sizing_eval(obj);
281 }
282 //
283
284 static void
285 _size_hints_changed_cb(void *data,
286                        Evas *e EINA_UNUSED,
287                        Evas_Object *obj EINA_UNUSED,
288                        void *event_info EINA_UNUSED)
289 {
290    elm_layout_sizing_eval(data);
291 }
292
293 static void
294 _notify_resize_cb(void *data,
295                   Evas *e EINA_UNUSED,
296                   Evas_Object *obj EINA_UNUSED,
297                   void *event_info EINA_UNUSED)
298 {
299    Evas_Object *popup = data;
300
301    ELM_POPUP_CHECK(popup);
302
303    _scroller_size_calc(popup);
304    elm_layout_sizing_eval(popup);
305 }
306
307 static void
308 _list_del(Elm_Popup_Data *sd)
309 {
310    if (!sd->scr) return;
311
312    evas_object_event_callback_del
313      (sd->scr, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _size_hints_changed_cb);
314
315    ELM_SAFE_FREE(sd->tbl, evas_object_del);
316    sd->scr = NULL;
317    sd->box = NULL;
318    sd->spacer = NULL;
319 }
320
321 static void
322 _items_remove(Elm_Popup_Data *sd)
323 {
324    Elm_Popup_Item_Data *it;
325
326    if (!sd->items) return;
327
328    EINA_LIST_FREE(sd->items, it)
329      eo_do(EO_OBJ(it), elm_wdg_item_del());
330
331    sd->items = NULL;
332 }
333
334 EOLIAN static void
335 _elm_popup_evas_object_smart_del(Eo *obj, Elm_Popup_Data *sd)
336 {
337    unsigned int i;
338
339    evas_object_event_callback_del_full(sd->parent, EVAS_CALLBACK_RESIZE, _parent_geom_cb, obj);
340    evas_object_event_callback_del_full(sd->parent, EVAS_CALLBACK_MOVE, _parent_geom_cb, obj);
341    evas_object_event_callback_del_full(sd->notify, EVAS_CALLBACK_RESIZE, _notify_resize_cb, obj);
342
343    eo_do(sd->notify,
344          eo_event_callback_array_del(_notify_cb(), obj));
345    evas_object_event_callback_del
346      (sd->content, EVAS_CALLBACK_DEL, _on_content_del);
347    evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _on_show);
348
349    sd->last_button_number = 0;
350
351    for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
352      {
353         if (sd->buttons[i])
354           {
355              evas_object_del(sd->buttons[i]->btn);
356              ELM_SAFE_FREE(sd->buttons[i], free);
357           }
358      }
359    if (sd->items)
360      {
361         _items_remove(sd);
362         _list_del(sd);
363      }
364
365    // XXX? delete other objects? just to be sure.
366    ELM_SAFE_FREE(sd->main_layout, evas_object_del);
367    ELM_SAFE_FREE(sd->notify, evas_object_del);
368    ELM_SAFE_FREE(sd->title_icon, evas_object_del);
369    ELM_SAFE_FREE(sd->content_area, evas_object_del);
370    ELM_SAFE_FREE(sd->text_content_obj, evas_object_del);
371    ELM_SAFE_FREE(sd->action_area, evas_object_del);
372    ELM_SAFE_FREE(sd->box, evas_object_del);
373    ELM_SAFE_FREE(sd->tbl, evas_object_del);
374    ELM_SAFE_FREE(sd->spacer, evas_object_del);
375    ELM_SAFE_FREE(sd->scr, evas_object_del);
376    ELM_SAFE_FREE(sd->content, evas_object_del);
377    ELM_SAFE_FREE(sd->title_text, eina_stringshare_del);
378    //TIZEN_ONLY(20160922): add subtitle text
379    ELM_SAFE_FREE(sd->subtitle_text, eina_stringshare_del);
380    //
381
382    eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
383 }
384
385 static void
386 _mirrored_set(Evas_Object *obj,
387               Eina_Bool rtl)
388 {
389    ELM_POPUP_DATA_GET(obj, sd);
390
391    elm_object_mirrored_set(sd->notify, rtl);
392    elm_object_mirrored_set(sd->main_layout, rtl);
393    if (sd->scr) elm_object_mirrored_set(sd->scr, rtl);
394    if (sd->action_area) elm_object_mirrored_set(sd->action_area, rtl);
395    if (sd->items)
396      {
397         Elm_Popup_Item_Data *it;
398         Eina_List *l;
399
400         EINA_LIST_FOREACH(sd->items, l, it)
401           elm_object_mirrored_set(VIEW(it), rtl);
402      }
403 }
404
405 //TIZEN ONLY(20150717): expose title as at-spi object
406 static char *
407 _access_info_cb(void *data, Evas_Object *obj EINA_UNUSED)
408 {
409    Eina_Strbuf *buf;
410    Elm_Popup_Data *priv = data;
411    char *ret = NULL;
412    if (priv->title_text)
413      {
414         buf = eina_strbuf_new();
415         eina_strbuf_append_printf(buf, "%s, %s", priv->title_text, N_("Title"));
416         ret = eina_strbuf_string_steal(buf);
417         eina_strbuf_free(buf);
418         return strdup(ret);
419      }
420    return NULL;
421 }
422 //
423
424 //TIZEN_ONLY(20160822): When atspi mode is dynamically switched on/off,
425 //register/unregister access objects accordingly.
426 static void
427 _atspi_expose_title(Eo *obj, Eina_Bool is_atspi)
428 {
429    Evas_Object *ao = NULL;
430    ELM_POPUP_DATA_GET(obj, sd);
431
432    if (sd->title_text && is_atspi)
433      {
434         ao = _access_object_get(obj, ACCESS_TITLE_PART);
435         if (!ao)
436           {
437              ao = _elm_access_edje_object_part_object_register
438                    (sd->main_layout, elm_layout_edje_get(sd->main_layout), ACCESS_TITLE_PART);
439              elm_atspi_accessible_role_set(ao, ELM_ATSPI_ROLE_HEADING);
440              _elm_access_callback_set(_elm_access_info_get(ao),
441                                        ELM_ACCESS_INFO, _access_info_cb, sd);
442           }
443      }
444    else
445      {
446         ao = _access_object_get(obj, ACCESS_TITLE_PART);
447         if (ao)
448           _elm_access_object_unregister(ao, NULL);
449      }
450 }
451 //
452
453 //TIZEN_ONLY(20170314): expose part-text as at-spi object
454 static char *
455 _access_name_set_cb(void *data, Evas_Object *obj EINA_UNUSED)
456 {
457    char *text = NULL;
458    if (data) text = _elm_util_mkup_to_text((char*)data);
459    if (text) return text;
460    return NULL;
461 }
462
463 static void
464 _atspi_part_text_expose(Eo *obj, const char *part, Eina_Bool is_atspi)
465 {
466    Evas_Object *ao = NULL;
467    ELM_POPUP_DATA_GET(obj, sd);
468    const char *text = NULL;
469    text = elm_layout_text_get(sd->main_layout, part);
470
471    if (text && is_atspi)
472      {
473         ao = _access_object_get(obj, part);
474         if (!ao)
475           {
476              ao = _elm_access_edje_object_part_object_register
477                    (sd->main_layout, elm_layout_edje_get(sd->main_layout), part);
478              elm_atspi_accessible_role_set(ao, ELM_ATSPI_ROLE_LABEL);
479              elm_atspi_accessible_name_cb_set(ao, _access_name_set_cb, text);
480           }
481      }
482    else
483      {
484         ao = _access_object_get(obj, part);
485         if (ao)
486           _elm_access_object_unregister(ao, NULL);
487      }
488 }
489 //
490
491 static void
492 _access_obj_process(Eo *obj, Eina_Bool is_access)
493 {
494    Evas_Object *ao;
495
496    ELM_POPUP_DATA_GET(obj, sd);
497
498    if (is_access)
499      {
500         if (sd->title_text)
501           {
502              ao = _elm_access_edje_object_part_object_register
503                     (obj, elm_layout_edje_get(sd->main_layout), ACCESS_TITLE_PART);
504              _elm_access_text_set(_elm_access_info_get(ao),
505                                   ELM_ACCESS_TYPE, E_("Popup Title"));
506              _elm_access_text_set(_elm_access_info_get(ao),
507                                   ELM_ACCESS_INFO, sd->title_text);
508           }
509
510         if (sd->text_content_obj)
511           {
512              ao = _elm_access_edje_object_part_object_register
513                     (obj, elm_layout_edje_get(sd->main_layout), ACCESS_BODY_PART);
514              _elm_access_text_set(_elm_access_info_get(ao),
515                                   ELM_ACCESS_TYPE, E_("Popup Body Text"));
516              _elm_access_text_set(_elm_access_info_get(ao),
517                ELM_ACCESS_INFO, elm_object_text_get(sd->text_content_obj));
518           }
519      }
520    else
521      {
522         if (sd->title_text)
523           {
524              _elm_access_edje_object_part_object_unregister
525                     (obj, elm_layout_edje_get(sd->main_layout), ACCESS_TITLE_PART);
526           }
527
528         if (sd->text_content_obj)
529           {
530              _elm_access_edje_object_part_object_unregister
531                     (obj, elm_layout_edje_get(sd->main_layout), ACCESS_BODY_PART);
532           }
533      }
534 }
535
536 static void
537 _populate_theme_scroll(Elm_Popup_Data *sd)
538 {
539    if (sd->content_area)
540      {
541         const char *content_area_width =
542           edje_object_data_get(elm_layout_edje_get(sd->content_area),
543                                "scroller_enable");
544         if ((content_area_width) && (!strcmp(content_area_width, "on")))
545           {
546              sd->theme_scroll = EINA_TRUE;
547              return;
548           }
549      }
550    sd->theme_scroll = EINA_FALSE;
551 }
552
553 EOLIAN static Elm_Theme_Apply
554 _elm_popup_elm_widget_theme_apply(Eo *obj, Elm_Popup_Data *sd)
555 {
556    Elm_Popup_Item_Data *it;
557    Eina_List *elist;
558    char buf[1024], style[1024];
559    //TIZEN_ONLY(20161109): check theme compatibility more precise
560    int i;
561    //
562
563    _mirrored_set(obj, elm_widget_mirrored_get(obj));
564
565    snprintf(style, sizeof(style), "popup/%s", elm_widget_style_get(obj));
566    /* TIZEN_ONLY(20160318): Support legacy group and swallow part names
567    elm_widget_style_set(sd->notify, style);
568     */
569      {
570         Elm_Theme_Apply ret;
571         const char *obj_style = elm_widget_style_get(obj);
572
573         if (obj_style && !strcmp(obj_style, "default"))
574           ret = _elm_widget_style_set_internal(sd->notify, "popup");
575         else
576           ret = _elm_widget_style_set_internal(sd->notify, obj_style);
577
578         if (ret != ELM_THEME_APPLY_SUCCESS)
579           if (_elm_widget_style_set_internal(sd->notify, style) != ELM_THEME_APPLY_SUCCESS)
580             if (_elm_widget_style_set_internal(sd->notify, "popup") != ELM_THEME_APPLY_SUCCESS)
581               _elm_widget_style_set_internal(sd->notify, "popup/default");
582      }
583    /* END */
584
585    if (!elm_layout_theme_set(sd->main_layout, "popup", "base",
586                              elm_widget_style_get(obj)))
587      CRI("Failed to set layout!");
588
589    if (sd->action_area)
590      {
591         /* TIZEN_ONLY(20160328): Support legacy groups
592         snprintf(buf, sizeof(buf), "buttons%i", sd->last_button_number);
593         if (!elm_layout_theme_set(sd->action_area, "popup", buf, style))
594           CRI("Failed to set layout!");
595          */
596         snprintf(buf, sizeof(buf), "buttons%i", sd->last_button_number);
597         for (i = 0; i < 4; i++)
598           {
599              snprintf(style, sizeof(style), STYLE_PRIORITY[i], elm_widget_style_get(obj));
600              if (_elm_layout_theme_set_internal(sd->action_area, "popup", buf, style) == ELM_THEME_APPLY_SUCCESS)
601                break;
602           }
603         if (i == 4)
604           CRI("Failed to set layout!");
605         /* END */
606      }
607    /* TIZEN_ONLY(20160328): Support legacy groups
608    if (!elm_layout_theme_set(sd->content_area, "popup", "content", style))
609      CRI("Failed to set layout!");
610     */
611    for (i = 0; i < 4; i++)
612      {
613         snprintf(style, sizeof(style), STYLE_PRIORITY[i], elm_widget_style_get(obj));
614         if (_elm_layout_theme_set_internal(sd->content_area, "popup", "content", style) == ELM_THEME_APPLY_SUCCESS)
615           break;
616      }
617    if (i == 4)
618      CRI("Failed to set layout!");
619    snprintf(style, sizeof(style), "popup/%s", elm_widget_style_get(obj));
620    /* END */
621    if (sd->text_content_obj)
622      // TIZEN_ONLY(20160704): fix label theme problem
623      //elm_object_style_set(sd->text_content_obj, style);
624      {
625         if (elm_widget_style_set(sd->text_content_obj, style) != ELM_THEME_APPLY_SUCCESS)
626           {
627              elm_widget_style_set(sd->text_content_obj, "popup/default");
628           }
629      }
630      //
631    else if (sd->items)
632      {
633         EINA_LIST_FOREACH(sd->items, elist, it)
634           {
635              if (!elm_layout_theme_set(VIEW(it), "popup", "item", style))
636                CRI("Failed to set layout!");
637              else
638                {
639                   if (it->label)
640                     {
641                        elm_layout_text_set(VIEW(it), "elm.text", it->label);
642                        elm_layout_signal_emit(VIEW(it),
643                                               "elm,state,item,text,visible",
644                                               "elm");
645                     }
646                   if (it->icon)
647                     elm_layout_signal_emit(VIEW(it),
648                                            "elm,state,item,icon,visible",
649                                            "elm");
650                   if (it->disabled)
651                     elm_layout_signal_emit(VIEW(it),
652                                            "elm,state,item,disabled", "elm");
653                   evas_object_show(VIEW(it));
654                   edje_object_message_signal_process(
655                      elm_layout_edje_get(VIEW(it)));
656                }
657           }
658      }
659    if (sd->title_text)
660      {
661         elm_layout_text_set(sd->main_layout, "elm.text.title", sd->title_text);
662         elm_layout_signal_emit(sd->main_layout, "elm,state,title,text,visible", "elm");
663      }
664    if (sd->title_icon)
665      elm_layout_signal_emit(sd->main_layout, "elm,state,title,icon,visible", "elm");
666    //TIZEN_ONLY(20160922): add subtitle text
667    if (sd->subtitle_text)
668      {
669         elm_layout_text_set(sd->main_layout, "elm,text,subtitle", sd->subtitle_text);
670         elm_layout_signal_emit(sd->main_layout, "elm,state,subtitle,text,visible", "elm");
671      }
672    //
673
674    _populate_theme_scroll(sd);
675    if (!sd->scroll && sd->theme_scroll)
676      elm_layout_signal_emit(sd->content_area, "elm,scroll,disable", "elm");
677    else if (sd->scroll && sd->theme_scroll)
678      elm_layout_signal_emit(sd->content_area, "elm,scroll,enable", "elm");
679
680    _visuals_set(obj);
681    _scroller_size_calc(obj);
682    elm_layout_sizing_eval(obj);
683
684    /* access */
685    if (_elm_config->access_mode) _access_obj_process(obj, EINA_TRUE);
686
687    return ELM_THEME_APPLY_SUCCESS;
688 }
689
690 static void
691 _item_sizing_eval(Elm_Popup_Item_Data *it)
692 {
693    Evas_Coord min_w = -1, min_h = -1, max_w = -1, max_h = -1;
694    Evas_Object *edje = elm_layout_edje_get(VIEW(it));
695
696    edje_object_size_min_restricted_calc
697      (edje, &min_w, &min_h, min_w, min_h);
698    evas_object_size_hint_min_set(edje, min_w, min_h);
699    evas_object_size_hint_max_set(edje, max_w, max_h);
700 }
701
702 EOLIAN static void
703 _elm_popup_elm_layout_sizing_eval(Eo *obj, Elm_Popup_Data *sd)
704 {
705    Eina_List *elist;
706    Elm_Popup_Item_Data *it;
707    Evas_Coord h_box = 0, minh_box = 0;
708    Evas_Coord minw = -1, minh = -1;
709
710    //TIZEN_ONLY(20160624): add a allow eval flag not to call another sizing eval during sizing eval
711    if (!sd->allow_eval) return;
712
713    sd->allow_eval = EINA_FALSE;
714    //
715
716    if (sd->items)
717      {
718         EINA_LIST_FOREACH(sd->items, elist, it)
719           {
720              _item_sizing_eval(it);
721              evas_object_size_hint_min_get(elm_layout_edje_get(VIEW(it)),
722                                            NULL, &minh_box);
723              if (minh_box != -1) h_box += minh_box;
724           }
725         evas_object_size_hint_min_set(sd->spacer, 0, MIN(h_box, sd->max_sc_h));
726         evas_object_size_hint_max_set(sd->spacer, -1, sd->max_sc_h);
727
728         evas_object_size_hint_min_get(sd->scr, &minw, &minh);
729         evas_object_size_hint_max_get(sd->scr, &minw, &minh);
730      }
731    else if (sd->scroll)
732      {
733         double horizontal, vertical;
734         Evas_Coord w, h;
735         //TIZEN_ONLY(20160405): fix popup size problem in landscape mode
736         int rotation = -1;
737         int w_content_area = 9999;
738         const char *str;
739         //
740
741         edje_object_message_signal_process(elm_layout_edje_get(sd->content_area));
742
743         elm_popup_align_get(obj, &horizontal, &vertical);
744         evas_object_geometry_get(sd->parent, NULL, NULL, &w, &h);
745
746         //TIZEN_ONLY(20161117): fix content area height problem when vertical align fill is set
747         if (sd->max_sc_h != -1)
748           h = sd->max_sc_h;
749         //
750
751         //TIZEN_ONLY(20160405): fix popup size problem in landscape mode
752         str = edje_object_data_get(elm_layout_edje_get(sd->content_area), "content_area_width");
753         if (str) w_content_area = (int)(atoi(str)
754                                     * elm_config_scale_get()
755                                     * elm_object_scale_get(obj)
756                                     / edje_object_base_scale_get(elm_layout_edje_get(sd->content_area)));
757         //
758
759         if (horizontal == ELM_NOTIFY_ALIGN_FILL)
760           minw = w;
761         if (vertical == ELM_NOTIFY_ALIGN_FILL)
762           minh = h;
763
764         //TIZEN_ONLY(20160405): fix popup size problem in landscape mode
765         rotation = elm_win_rotation_get(elm_widget_top_get(elm_widget_parent_get(sd->notify)));
766         if ((rotation == 90 || rotation == 270) && (horizontal == ELM_NOTIFY_ALIGN_FILL))
767           minw = w_content_area;
768         //
769
770         edje_object_size_min_restricted_calc(elm_layout_edje_get(sd->content_area),
771                                              &minw, &minh, minw, minh);
772
773         evas_object_size_hint_min_set(sd->content_area, minw, minh);
774
775         //TIZEN_ONLY(20161107): supprot scrollable content
776         //FIXME: genlist only now, it should be changed to support other scrollable.
777         if (sd->scrollable_content)
778           minh = sd->min_scrollable_content_h;
779         //
780
781
782         if (minh > sd->max_sc_h)
783           evas_object_size_hint_min_set(sd->spacer, minw, sd->max_sc_h);
784         else
785           evas_object_size_hint_min_set(sd->spacer, minw, minh);
786
787         //TIZEN_ONLY(20160624): add a allow eval flag not to call another sizing eval during sizing eval
788         sd->allow_eval = EINA_TRUE;
789         //
790
791         return;
792      }
793
794    edje_object_size_min_calc(elm_layout_edje_get(sd->main_layout), &minw, &minh);
795
796    evas_object_size_hint_min_set(obj, minw, minh);
797    evas_object_size_hint_max_set(obj, -1, -1);
798
799    //TIZEN_ONLY(20160624): add a allow eval flag not to call another sizing eval during sizing eval
800    sd->allow_eval = EINA_TRUE;
801    //
802 }
803
804 EOLIAN static void
805 _elm_popup_elm_layout_signal_emit(Eo *obj EINA_UNUSED, Elm_Popup_Data *sd, const char *emission, const char *source)
806 {
807    elm_layout_signal_emit(sd->main_layout, emission, source);
808 }
809
810 EOLIAN static Eina_Bool
811 _elm_popup_elm_widget_sub_object_del(Eo *obj, Elm_Popup_Data *sd, Evas_Object *sobj)
812 {
813    Elm_Popup_Item_Data *it;
814    Eina_Bool int_ret = EINA_FALSE;
815
816    eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_del(sobj));
817    if (!int_ret) return EINA_FALSE;
818
819    if (sobj == sd->title_icon)
820      {
821         elm_layout_signal_emit(sd->main_layout, "elm,state,title,icon,hidden", "elm");
822      }
823    else if ((it =
824                evas_object_data_get(sobj, "_popup_icon_parent_item")) != NULL)
825      {
826         if (sobj == it->icon)
827           {
828              eo_do(VIEW(it), elm_obj_container_content_unset(CONTENT_PART));
829              elm_layout_signal_emit(VIEW(it),
830                                     "elm,state,item,icon,hidden", "elm");
831              it->icon = NULL;
832           }
833      }
834
835    return EINA_TRUE;
836 }
837
838 static void
839 _on_content_del(void *data,
840                 Evas *e EINA_UNUSED,
841                 Evas_Object *obj EINA_UNUSED,
842                 void *event_info EINA_UNUSED)
843 {
844    ELM_POPUP_DATA_GET(data, sd);
845
846    sd->content = NULL;
847    elm_layout_sizing_eval(data);
848 }
849
850 static void
851 _on_text_content_del(void *data,
852                      Evas *e EINA_UNUSED,
853                      Evas_Object *obj EINA_UNUSED,
854                      void *event_info EINA_UNUSED)
855 {
856    ELM_POPUP_DATA_GET(data, sd);
857
858    sd->text_content_obj = NULL;
859    elm_layout_sizing_eval(data);
860 }
861
862 static void
863 _on_table_del(void *data,
864               Evas *e EINA_UNUSED,
865               Evas_Object *obj EINA_UNUSED,
866               void *event_info EINA_UNUSED)
867 {
868    ELM_POPUP_DATA_GET(data, sd);
869
870    sd->tbl = NULL;
871    sd->spacer = NULL;
872    sd->scr = NULL;
873    sd->box = NULL;
874    elm_layout_sizing_eval(data);
875 }
876
877 static void
878 _on_button_del(void *data,
879                Evas *e EINA_UNUSED,
880                Evas_Object *obj,
881                void *event_info EINA_UNUSED)
882 {
883    int i;
884
885    ELM_POPUP_DATA_GET(data, sd);
886
887    for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
888      {
889         if (sd->buttons[i] && obj == sd->buttons[i]->btn &&
890             sd->buttons[i]->delete_me == EINA_TRUE)
891           {
892              _button_remove(data, i, EINA_FALSE);
893              break;
894           }
895      }
896 }
897
898 static void
899 _button_remove(Evas_Object *obj,
900                int pos,
901                Eina_Bool delete)
902 {
903    int i = 0;
904    char buf[128];
905
906    ELM_POPUP_DATA_GET(obj, sd);
907
908    if (!sd->last_button_number) return;
909
910    if (!sd->buttons[pos]) return;
911
912    if (delete)
913      {
914         evas_object_del(sd->buttons[pos]->btn);
915      }
916    else
917      {
918         evas_object_event_callback_del
919           (sd->buttons[pos]->btn, EVAS_CALLBACK_DEL, _on_button_del);
920         /* TIZEN_ONLY(20160318): Support legacy group and swallow part names
921         snprintf(buf, sizeof(buf), "elm.swallow.content.button%i", pos + 1);
922         elm_object_part_content_unset(sd->action_area, buf);
923          */
924         snprintf(buf, sizeof(buf), "actionbtn%i", pos + 1);
925         if (edje_object_part_exists(elm_layout_edje_get(sd->action_area), buf))
926           {
927              elm_object_part_content_unset(sd->action_area, buf);
928           }
929         else
930           {
931              snprintf(buf, sizeof(buf), "elm.swallow.content.button%i", pos + 1);
932              elm_object_part_content_unset(sd->action_area, buf);
933           }
934         /* END */
935      }
936
937    ELM_SAFE_FREE(sd->buttons[pos], free);
938
939    sd->last_button_number = 0;
940
941    for (i = ELM_POPUP_ACTION_BUTTON_MAX - 1; i >= 0; i--)
942      {
943         if (sd->buttons[i])
944           {
945              sd->last_button_number = i + 1;
946              break;
947           }
948      }
949
950    if (!sd->last_button_number)
951      {
952         ELM_SAFE_FREE(sd->action_area, evas_object_del);
953         _visuals_set(obj);
954      }
955    else
956      {
957         /* TIZEN_ONLY(20160328): Support legacy groups
958         char style[1024];
959
960         snprintf(style, sizeof(style), "popup/%s", elm_widget_style_get(obj));
961         snprintf(buf, sizeof(buf), "buttons%i", sd->last_button_number);
962
963         if (!elm_layout_theme_set(sd->action_area, "popup", buf, style))
964           CRI("Failed to set layout!");
965          */
966         char style[1024];
967
968         snprintf(buf, sizeof(buf), "buttons%i", sd->last_button_number);
969         for (i = 0 ; i < 4; i++)
970           {
971              snprintf(style, sizeof(style), STYLE_PRIORITY[i], elm_widget_style_get(obj));
972              if (_elm_layout_theme_set_internal(sd->action_area, "popup", buf, style) == ELM_THEME_APPLY_SUCCESS)
973                break;
974           }
975         if (i == 4)
976           CRI("Failed to set layout!");
977         /* END */
978      }
979 }
980
981 static void
982 _layout_change_cb(void *data EINA_UNUSED,
983                   Evas_Object *obj,
984                   const char *emission EINA_UNUSED,
985                   const char *source EINA_UNUSED)
986 {
987    elm_layout_sizing_eval(obj);
988 }
989
990 static void
991 _create_scroller(Evas_Object *obj)
992 {
993    char style[1024];
994
995    ELM_POPUP_DATA_GET(obj, sd);
996
997    //table
998    sd->tbl = elm_table_add(sd->main_layout);
999    evas_object_event_callback_add(sd->tbl, EVAS_CALLBACK_DEL,
1000                                   _on_table_del, obj);
1001    if (!sd->scroll)
1002      {
1003         if (sd->content || sd->text_content_obj) eo_do(sd->content_area, elm_obj_container_content_unset(CONTENT_PART));
1004         eo_do(sd->content_area, elm_obj_container_content_set(CONTENT_PART, sd->tbl));
1005         eo_do(sd->main_layout, elm_obj_container_content_set(CONTENT_PART, sd->content_area));
1006      }
1007
1008    //spacer
1009    sd->spacer = evas_object_rectangle_add(evas_object_evas_get(obj));
1010    evas_object_color_set(sd->spacer, 0, 0, 0, 0);
1011    elm_table_pack(sd->tbl, sd->spacer, 0, 0, 1, 1);
1012
1013    //Scroller
1014    sd->scr = elm_scroller_add(sd->tbl);
1015    /* TIZEN_ONLY(20161031): apply color_class parent-child relationship to all widgets */
1016    _elm_widget_color_class_parent_set(sd->scr, obj);
1017    /* END */
1018    /* TIZEN_ONLY(20160318): Support legacy group and swallow part names
1019    if (!sd->scroll)
1020      {
1021         snprintf(style, sizeof(style), "popup/%s", elm_widget_style_get(obj));
1022         elm_object_style_set(sd->scr, style);
1023      }
1024    else
1025      elm_object_style_set(sd->scr, "popup/no_inset_shadow");
1026     */
1027    if (!elm_layout_theme_set(sd->scr, "scroller", "base", "effect"))
1028      {
1029         if (!sd->scroll)
1030           {
1031              snprintf(style, sizeof(style), "popup/%s", elm_widget_style_get(obj));
1032              elm_object_style_set(sd->scr, style);
1033           }
1034         else
1035           elm_object_style_set(sd->scr, "popup/no_inset_shadow");
1036      }
1037    /* END */
1038    evas_object_size_hint_weight_set(sd->scr, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1039    evas_object_size_hint_align_set(sd->scr, EVAS_HINT_FILL, EVAS_HINT_FILL);
1040    elm_scroller_policy_set(sd->scr, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
1041    elm_scroller_content_min_limit(sd->scr, EINA_TRUE, EINA_FALSE);
1042    elm_scroller_bounce_set(sd->scr, EINA_FALSE, EINA_TRUE);
1043    evas_object_event_callback_add(sd->scr, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1044                                   _size_hints_changed_cb, obj);
1045    elm_widget_mirrored_automatic_set(sd->scr, EINA_FALSE);
1046    elm_object_mirrored_set(sd->scr, elm_object_mirrored_get(obj));
1047    elm_table_pack(sd->tbl, sd->scr, 0, 0, 1, 1);
1048    evas_object_show(sd->scr);
1049 }
1050
1051 static void
1052 _list_add(Evas_Object *obj)
1053 {
1054    ELM_POPUP_DATA_GET(obj, sd);
1055
1056    if (!sd->scr)
1057      _create_scroller(obj);
1058    //Box
1059    sd->box = elm_box_add(sd->scr);
1060    evas_object_size_hint_weight_set(sd->box, EVAS_HINT_EXPAND, 0.0);
1061    evas_object_size_hint_align_set(sd->box, EVAS_HINT_FILL, 0.0);
1062    elm_object_content_set(sd->scr, sd->box);
1063    evas_object_show(sd->box);
1064 }
1065
1066 static void
1067 _item_select_cb(void *data,
1068                 Evas_Object *obj EINA_UNUSED,
1069                 const char *emission EINA_UNUSED,
1070                 const char *source EINA_UNUSED)
1071 {
1072    Elm_Popup_Item_Data *it = data;
1073
1074    if (!it || it->disabled) return;
1075    if (it->func)
1076      it->func((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), EO_OBJ(it));
1077 }
1078
1079 static void
1080 _item_text_set(Elm_Popup_Item_Data *it,
1081                const char *label)
1082 {
1083    if (!eina_stringshare_replace(&it->label, label)) return;
1084
1085    elm_layout_text_set(VIEW(it), "elm.text", label);
1086
1087    if (it->label)
1088      elm_layout_signal_emit(VIEW(it),
1089                             "elm,state,item,text,visible", "elm");
1090    else
1091      elm_layout_signal_emit(VIEW(it),
1092                             "elm,state,item,text,hidden", "elm");
1093
1094    edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1095 }
1096
1097 EOLIAN static void
1098 _elm_popup_item_elm_widget_item_part_text_set(Eo *eo_it EINA_UNUSED, Elm_Popup_Item_Data *it,
1099                     const char *part,
1100                     const char *label)
1101 {
1102    ELM_POPUP_ITEM_CHECK_OR_RETURN(it);
1103
1104    if ((!part) || (!strcmp(part, "default")))
1105      {
1106         _item_text_set(it, label);
1107         return;
1108      }
1109
1110    WRN("The part name is invalid! : popup=%p", WIDGET(it));
1111 }
1112
1113 EOLIAN static const char *
1114 _elm_popup_item_elm_widget_item_part_text_get(Eo *eo_it EINA_UNUSED, Elm_Popup_Item_Data *it,
1115                     const char *part)
1116 {
1117    ELM_POPUP_ITEM_CHECK_OR_RETURN(it, NULL);
1118
1119    if ((!part) || (!strcmp(part, "default")))
1120      return it->label;
1121
1122    WRN("The part name is invalid! : popup=%p", WIDGET(it));
1123
1124    return NULL;
1125 }
1126
1127 static void
1128 _item_icon_set(Elm_Popup_Item_Data *it,
1129                Evas_Object *icon)
1130 {
1131    if (it->icon == icon) return;
1132
1133    evas_object_del(it->icon);
1134    it->icon = icon;
1135    if (it->icon)
1136      {
1137         elm_widget_sub_object_add(WIDGET(it), it->icon);
1138         evas_object_data_set(it->icon, "_popup_icon_parent_item", it);
1139         eo_do(VIEW(it), elm_obj_container_content_set(CONTENT_PART, it->icon));
1140         elm_layout_signal_emit(VIEW(it), "elm,state,item,icon,visible", "elm");
1141      }
1142    else
1143      elm_layout_signal_emit(VIEW(it), "elm,state,item,icon,hidden", "elm");
1144
1145    edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1146 }
1147
1148 EOLIAN static void
1149 _elm_popup_item_elm_widget_item_part_content_set(Eo *eo_it EINA_UNUSED, Elm_Popup_Item_Data *it,
1150                        const char *part,
1151                        Evas_Object *content)
1152 {
1153    ELM_POPUP_ITEM_CHECK_OR_RETURN(it);
1154
1155    if ((!(part)) || (!strcmp(part, "default")))
1156      _item_icon_set(it, content);
1157    else
1158      WRN("The part name is invalid! : popup=%p", WIDGET(it));
1159 }
1160
1161 EOLIAN static Evas_Object *
1162 _elm_popup_item_elm_widget_item_part_content_get(Eo *eo_it EINA_UNUSED, Elm_Popup_Item_Data *it,
1163                        const char *part)
1164 {
1165    ELM_POPUP_ITEM_CHECK_OR_RETURN(it, NULL);
1166
1167    if ((!(part)) || (!strcmp(part, "default")))
1168      return it->icon;
1169
1170    WRN("The part name is invalid! : popup=%p", WIDGET(it));
1171
1172    return NULL;
1173 }
1174
1175 static Evas_Object *
1176 _item_icon_unset(Elm_Popup_Item_Data *it)
1177 {
1178    Evas_Object *icon = it->icon;
1179
1180    if (!it->icon) return NULL;
1181    _elm_widget_sub_object_redirect_to_top(WIDGET(it), icon);
1182    evas_object_data_del(icon, "_popup_icon_parent_item");
1183    eo_do(VIEW(it), elm_obj_container_content_unset(CONTENT_PART));
1184    elm_layout_signal_emit(VIEW(it), "elm,state,item,icon,hidden", "elm");
1185    it->icon = NULL;
1186
1187    return icon;
1188 }
1189
1190 EOLIAN static Evas_Object *
1191 _elm_popup_item_elm_widget_item_part_content_unset(Eo *eo_it EINA_UNUSED, Elm_Popup_Item_Data *it,
1192                          const char *part)
1193 {
1194    Evas_Object *content = NULL;
1195
1196    ELM_POPUP_ITEM_CHECK_OR_RETURN(it, NULL);
1197
1198    if ((!(part)) || (!strcmp(part, "default")))
1199      content = _item_icon_unset(it);
1200    else
1201      WRN("The part name is invalid! : popup=%p", WIDGET(it));
1202
1203    return content;
1204 }
1205
1206 EOLIAN static void
1207 _elm_popup_item_elm_widget_item_disable(Eo *eo_it, Elm_Popup_Item_Data *it)
1208 {
1209    Eina_Bool tmp;
1210    ELM_POPUP_ITEM_CHECK_OR_RETURN(it);
1211
1212    if (eo_do_ret(eo_it, tmp, elm_wdg_item_disabled_get()))
1213      elm_layout_signal_emit(VIEW(it), "elm,state,item,disabled", "elm");
1214    else
1215      elm_layout_signal_emit(VIEW(it), "elm,state,item,enabled", "elm");
1216 }
1217
1218 EOLIAN static void
1219 _elm_popup_item_eo_base_destructor(Eo *eo_it, Elm_Popup_Item_Data *it)
1220 {
1221    ELM_POPUP_ITEM_CHECK_OR_RETURN(it);
1222    ELM_POPUP_DATA_GET(WIDGET(it), sd);
1223
1224    evas_object_del(it->icon);
1225    eina_stringshare_del(it->label);
1226    sd->items = eina_list_remove(sd->items, it);
1227    if (!eina_list_count(sd->items))
1228      {
1229         sd->items = NULL;
1230         _list_del(sd);
1231      }
1232    eo_do_super(eo_it, ELM_POPUP_ITEM_CLASS, eo_destructor());
1233 }
1234
1235 EOLIAN static void
1236 _elm_popup_item_elm_widget_item_signal_emit(Eo *eo_it EINA_UNUSED, Elm_Popup_Item_Data *it,
1237                        const char *emission,
1238                        const char *source)
1239 {
1240    elm_layout_signal_emit(VIEW(it), emission, source);
1241 }
1242
1243 static Eina_Bool
1244 _item_focused_cb(void *data,
1245       Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
1246 {
1247    Elm_Popup_Item_Data *it = data;
1248
1249    eo_do(WIDGET(it), eo_event_callback_call(ELM_POPUP_EVENT_ITEM_FOCUSED, EO_OBJ(it)));
1250
1251    return EINA_TRUE;
1252 }
1253
1254 static Eina_Bool
1255 _item_unfocused_cb(void *data,
1256       Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
1257 {
1258    Elm_Popup_Item_Data *it = data;
1259
1260    eo_do(WIDGET(it), eo_event_callback_call(ELM_POPUP_EVENT_ITEM_UNFOCUSED, EO_OBJ(it)));
1261
1262    return EINA_TRUE;
1263 }
1264
1265 //TIZEN_ONLY(20161107): support scrollable content
1266 //FIXME: genlist only now, it should be changed to support other scrollable.
1267 static void
1268 _scrollable_content_loaded_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
1269 {
1270    ELM_POPUP_DATA_GET(data, sd);
1271
1272    Evas_Coord h;
1273    eo_do(obj, elm_interface_scrollable_content_size_get(NULL, &h));
1274
1275    sd->scrollable_content = EINA_TRUE;
1276    sd->min_scrollable_content_h = h;
1277
1278    elm_layout_sizing_eval(data);
1279 }
1280 //
1281
1282 EOLIAN static Eo *
1283 _elm_popup_item_eo_base_constructor(Eo *eo_it, Elm_Popup_Item_Data *it)
1284 {
1285    eo_it = eo_do_super_ret(eo_it, ELM_POPUP_ITEM_CLASS, eo_it, eo_constructor());
1286    it->base = eo_data_scope_get(eo_it, ELM_WIDGET_ITEM_CLASS);
1287
1288    return eo_it;
1289 }
1290
1291 static void
1292 _item_new(Elm_Popup_Item_Data *it)
1293 {
1294    char style[1024];
1295
1296    VIEW(it) = elm_layout_add(WIDGET(it));
1297    elm_object_focus_allow_set(VIEW(it), EINA_TRUE);
1298    elm_widget_mirrored_automatic_set(VIEW(it), EINA_FALSE);
1299    elm_object_mirrored_set(VIEW(it), elm_object_mirrored_get(WIDGET(it)));
1300
1301    snprintf(style, sizeof(style), "popup/%s", elm_widget_style_get(WIDGET(it)));
1302    if (!elm_layout_theme_set(VIEW(it), "popup", "item", style))
1303      CRI("Failed to set layout!");
1304    else
1305      {
1306         elm_layout_signal_callback_add(VIEW(it), "elm,action,click", "*",
1307                                        _item_select_cb, it);
1308         evas_object_size_hint_align_set(VIEW(it), EVAS_HINT_FILL, EVAS_HINT_FILL);
1309         eo_do(VIEW(it), eo_event_callback_add
1310               (ELM_WIDGET_EVENT_FOCUSED, _item_focused_cb, it));
1311         eo_do(VIEW(it), eo_event_callback_add
1312               (ELM_WIDGET_EVENT_UNFOCUSED, _item_unfocused_cb, it));
1313         evas_object_show(VIEW(it));
1314      }
1315 }
1316
1317 static Eina_Bool
1318 _title_text_set(Evas_Object *obj,
1319                 const char *text)
1320 {
1321    Evas_Object *ao;
1322    Eina_Bool title_visibility_old, title_visibility_current;
1323
1324    ELM_POPUP_DATA_GET(obj, sd);
1325
1326    if (sd->title_text == text) return EINA_TRUE;
1327
1328    title_visibility_old = (sd->title_text) || (sd->title_icon);
1329    eina_stringshare_replace(&sd->title_text, text);
1330
1331    elm_layout_text_set(sd->main_layout, "elm.text.title", text);
1332
1333    /* access */
1334    if (_elm_config->access_mode)
1335      {
1336         ao = _access_object_get(obj, ACCESS_TITLE_PART);
1337         if (!ao)
1338           {
1339              ao = _elm_access_edje_object_part_object_register
1340                     (obj, elm_layout_edje_get(sd->main_layout), ACCESS_TITLE_PART);
1341              _elm_access_text_set(_elm_access_info_get(ao),
1342                                   ELM_ACCESS_TYPE, E_("Popup Title"));
1343           }
1344         _elm_access_text_set(_elm_access_info_get(ao), ELM_ACCESS_INFO, text);
1345      }
1346
1347    //TIZEN ONLY(20150717): expose title as at-spi object
1348    // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
1349    if (elm_atspi_bridge_utils_is_screen_reader_enabled())
1350      _atspi_expose_title(obj, EINA_TRUE);
1351    //
1352    //
1353    if (sd->title_text)
1354      elm_layout_signal_emit(sd->main_layout, "elm,state,title,text,visible", "elm");
1355    else
1356      elm_layout_signal_emit(sd->main_layout, "elm,state,title,text,hidden", "elm");
1357
1358    title_visibility_current = (sd->title_text) || (sd->title_icon);
1359
1360    if (title_visibility_old != title_visibility_current)
1361      _visuals_set(obj);
1362
1363    return EINA_TRUE;
1364 }
1365
1366 //TIZEN_ONLY(20160922): add subtitle text
1367 static Eina_Bool
1368 _subtitle_text_set(Evas_Object *obj,
1369                 const char *text)
1370 {
1371    ELM_POPUP_DATA_GET(obj, sd);
1372
1373    if (sd->subtitle_text == text) return EINA_TRUE;
1374
1375    eina_stringshare_replace(&sd->subtitle_text, text);
1376
1377    //bare edje here because we're inside the hook, already
1378    edje_object_part_text_escaped_set
1379      (elm_layout_edje_get(sd->main_layout), "elm.text.subtitle", text);
1380
1381    if (sd->subtitle_text)
1382      elm_object_signal_emit(sd->main_layout, "elm,state,subtitle,text,visible", "elm");
1383    else
1384      elm_object_signal_emit(sd->main_layout, "elm,state,subtitle,text,hidden", "elm");
1385
1386    edje_object_message_signal_process(elm_layout_edje_get(sd->main_layout));
1387
1388    return EINA_TRUE;
1389 }
1390 //
1391
1392 static Eina_Bool
1393 _content_text_set(Evas_Object *obj,
1394                   const char *text)
1395 {
1396    Evas_Object *ao;
1397    char style[1024];
1398
1399    ELM_POPUP_DATA_GET(obj, sd);
1400
1401    if (sd->items)
1402      {
1403         _items_remove(sd);
1404         _list_del(sd);
1405      }
1406    else
1407      {
1408         if (!sd->scroll)
1409           eo_do(sd->main_layout, elm_obj_container_content_set(CONTENT_PART, sd->content_area));
1410         else
1411           elm_object_content_set(sd->scr, sd->content_area);
1412      }
1413    if (!text) goto end;
1414
1415    if (sd->text_content_obj)
1416      {
1417         eo_do(sd->content_area, sd->text_content_obj = elm_obj_container_content_unset(CONTENT_PART));
1418         evas_object_del(sd->text_content_obj);
1419         sd->text_content_obj = NULL;
1420      }
1421
1422    sd->text_content_obj = elm_label_add(sd->content_area);
1423    /* TIZEN_ONLY(20161031): apply color_class parent-child relationship to all widgets */
1424    _elm_widget_color_class_parent_set(sd->text_content_obj, obj);
1425    /* END */
1426    snprintf(style, sizeof(style), "popup/%s", elm_widget_style_get(obj));
1427    /* TIZEN_ONLY(20160704): fix label theme problem
1428    elm_object_style_set(sd->text_content_obj, style);
1429     */
1430    if (elm_widget_style_set(sd->text_content_obj, style) != ELM_THEME_APPLY_SUCCESS)
1431      elm_widget_style_set(sd->text_content_obj, "popup/default");
1432    //
1433
1434    evas_object_event_callback_add
1435      (sd->text_content_obj, EVAS_CALLBACK_DEL, _on_text_content_del, obj);
1436
1437    elm_label_line_wrap_set(sd->text_content_obj, sd->content_text_wrap_type);
1438    elm_object_text_set(sd->text_content_obj, text);
1439    evas_object_size_hint_weight_set
1440      (sd->text_content_obj, EVAS_HINT_EXPAND, 0.0);
1441    evas_object_size_hint_align_set
1442      (sd->text_content_obj, EVAS_HINT_FILL, EVAS_HINT_FILL);
1443    eo_do(sd->content_area, elm_obj_container_content_set
1444      (CONTENT_PART, sd->text_content_obj));
1445
1446    /* access */
1447    if (_elm_config->access_mode)
1448      {
1449         /* unregister label, ACCESS_BODY_PART will register */
1450         elm_access_object_unregister(sd->text_content_obj);
1451
1452         ao = _access_object_get(obj, ACCESS_BODY_PART);
1453         if (!ao)
1454           {
1455              ao = _elm_access_edje_object_part_object_register
1456                     (obj, elm_layout_edje_get(sd->main_layout), ACCESS_BODY_PART);
1457              _elm_access_text_set(_elm_access_info_get(ao),
1458                                   ELM_ACCESS_TYPE, E_("Popup Body Text"));
1459           }
1460         _elm_access_text_set(_elm_access_info_get(ao), ELM_ACCESS_INFO, text);
1461      }
1462
1463    //TIZEN_ONLY(20161107): support scrollable content
1464    //FIXME: genlist only now, it should be changed to support other scrollable.
1465    sd->scrollable_content = EINA_FALSE;
1466    //
1467 end:
1468    return EINA_TRUE;
1469 }
1470
1471 EOLIAN static Eina_Bool
1472 _elm_popup_elm_layout_text_set(Eo *obj, Elm_Popup_Data *_pd, const char *part, const char *label)
1473 {
1474    Eina_Bool int_ret = EINA_FALSE;
1475
1476    if (!part || !strcmp(part, "default"))
1477      int_ret = _content_text_set(obj, label);
1478    else if (!strcmp(part, "title,text"))
1479      int_ret = _title_text_set(obj, label);
1480    //TIZEN_ONLY(20160922): add subtitle text
1481    else if(!strcmp(part, "subtitle,text"))
1482      int_ret = _subtitle_text_set(obj, label);
1483    //
1484    else
1485      {
1486         int_ret = elm_layout_text_set(_pd->main_layout, part, label);
1487         //TIZEN_ONLY(20170314): expose part-text as at-spi object
1488         // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
1489         _atspi_part_text_expose(obj, part,elm_atspi_bridge_utils_is_screen_reader_enabled());
1490         //
1491         //
1492      }
1493    _scroller_size_calc(obj);
1494    elm_layout_sizing_eval(obj);
1495
1496    return int_ret;
1497 }
1498
1499 static const char *
1500 _title_text_get(const Elm_Popup_Data *sd)
1501 {
1502    return sd->title_text;
1503 }
1504
1505 //TIZEN_ONLY(20160922): add subtitle text
1506 static const char *
1507 _subtitle_text_get(const Elm_Popup_Data *sd)
1508 {
1509    return sd->subtitle_text;
1510 }
1511 //
1512
1513 static const char *
1514 _content_text_get(const Elm_Popup_Data *sd)
1515 {
1516    const char *str = NULL;
1517
1518    if (sd->text_content_obj)
1519      str = elm_object_text_get(sd->text_content_obj);
1520
1521    return str;
1522 }
1523
1524 EOLIAN static const char*
1525 _elm_popup_elm_layout_text_get(const Eo *obj EINA_UNUSED, Elm_Popup_Data *_pd, const char *part)
1526 {
1527    const char *text = NULL;
1528
1529    if (!part || !strcmp(part, "default"))
1530      text = _content_text_get(_pd);
1531    else if (!strcmp(part, "title,text"))
1532      text = _title_text_get(_pd);
1533    //TIZEN_ONLY(20160922): add subtitle text
1534    else if (!strcmp(part, "subtitle,text"))
1535      text = _subtitle_text_get(_pd);
1536    //
1537    else
1538      text = elm_layout_text_get(_pd->main_layout, part);
1539
1540    return text;
1541 }
1542
1543 static Eina_Bool
1544 _title_icon_set(Evas_Object *obj,
1545                 Evas_Object *icon)
1546 {
1547    Eina_Bool title_visibility_old, title_visibility_current;
1548
1549    ELM_POPUP_DATA_GET(obj, sd);
1550
1551    if (sd->title_icon == icon) return EINA_TRUE;
1552    title_visibility_old = (sd->title_text) || (sd->title_icon);
1553    evas_object_del(sd->title_icon);
1554
1555    sd->title_icon = icon;
1556    title_visibility_current = (sd->title_text) || (sd->title_icon);
1557
1558    eo_do(sd->main_layout, elm_obj_container_content_set
1559       ("elm.swallow.title.icon", sd->title_icon));
1560
1561    if (sd->title_icon)
1562      elm_layout_signal_emit(sd->main_layout, "elm,state,title,icon,visible", "elm");
1563    if (title_visibility_old != title_visibility_current) _visuals_set(obj);
1564
1565    return EINA_TRUE;
1566 }
1567
1568 static Eina_Bool
1569 _content_set(Evas_Object *obj,
1570              Evas_Object *content)
1571 {
1572    ELM_POPUP_DATA_GET(obj, sd);
1573
1574    //TIZEN_ONLY(20161107): support scrollable content
1575    //FIXME: genlist only now, it should be changed to support other scrollable.
1576    sd->scrollable_content = EINA_FALSE;
1577    //
1578
1579    if (sd->content && sd->content == content) return EINA_TRUE;
1580    if (sd->items)
1581      {
1582         _items_remove(sd);
1583         _list_del(sd);
1584      }
1585
1586    evas_object_del(sd->content);
1587    sd->content = content;
1588
1589    if (content)
1590      {
1591         if (!sd->scroll)
1592           eo_do(sd->main_layout, elm_obj_container_content_set
1593                 (CONTENT_PART, sd->content_area));
1594         else
1595           elm_object_content_set(sd->scr, sd->content_area);
1596
1597         evas_object_show(content);
1598         eo_do(sd->content_area, elm_obj_container_content_set
1599           (CONTENT_PART, content));
1600
1601         //TIZEN_ONLY(20161107): support scrollable content
1602         //FIXME: genlist only now, it should be changed to support other scrollable.
1603         if (eo_isa(content, ELM_INTERFACE_SCROLLABLE_MIXIN))
1604           evas_object_smart_callback_add(content, "loaded", _scrollable_content_loaded_cb, obj);
1605         //
1606
1607         evas_object_event_callback_add
1608           (content, EVAS_CALLBACK_DEL, _on_content_del, obj);
1609      }
1610
1611    return EINA_TRUE;
1612 }
1613
1614 static void
1615 _action_button_set(Evas_Object *obj,
1616                    Evas_Object *btn,
1617                    unsigned int idx)
1618 {
1619    char buf[128], style[1024];
1620    unsigned int i;
1621
1622    ELM_POPUP_DATA_GET(obj, sd);
1623
1624    if (idx >= ELM_POPUP_ACTION_BUTTON_MAX) return;
1625
1626    if (!btn)
1627      {
1628         _button_remove(obj, idx, EINA_TRUE);
1629         return;
1630      }
1631
1632    if (sd->buttons[idx])
1633      {
1634         evas_object_del(sd->buttons[idx]->btn);
1635         free(sd->buttons[idx]);
1636      }
1637
1638    sd->buttons[idx] = ELM_NEW(Action_Area_Data);
1639    sd->buttons[idx]->obj = obj;
1640    sd->buttons[idx]->btn = btn;
1641
1642    evas_object_event_callback_add
1643      (btn, EVAS_CALLBACK_DEL, _on_button_del, obj);
1644
1645    for (i = ELM_POPUP_ACTION_BUTTON_MAX - 1; i >= idx; i--)
1646      {
1647         if (sd->buttons[i])
1648           {
1649              sd->last_button_number = i + 1;
1650              break;
1651           }
1652      }
1653
1654    if (!sd->action_area)
1655      {
1656         sd->action_area = elm_layout_add(sd->main_layout);
1657         /* TIZEN_ONLY(20161031): apply color_class parent-child relationship to all widgets */
1658         _elm_widget_color_class_parent_set(sd->action_area, obj);
1659         /* END */
1660         evas_object_event_callback_add
1661           (sd->action_area, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1662            _size_hints_changed_cb, sd->main_layout);
1663         elm_widget_mirrored_automatic_set(sd->main_layout, EINA_FALSE);
1664         elm_object_mirrored_set(sd->action_area, elm_object_mirrored_get(obj));
1665         eo_do(sd->main_layout, elm_obj_container_content_set
1666           ("elm.swallow.action_area", sd->action_area));
1667
1668         _visuals_set(obj);
1669      }
1670
1671    /* TIZEN_ONLY(20160328): Support legacy groups
1672    snprintf(buf, sizeof(buf), "buttons%i", sd->last_button_number);
1673    snprintf(style, sizeof(style), "popup/%s", elm_widget_style_get(obj));
1674    if (!elm_layout_theme_set(sd->action_area, "popup", buf, style))
1675      CRI("Failed to set layout!");
1676     */
1677    snprintf(buf, sizeof(buf), "buttons%i", sd->last_button_number);
1678    for (i = 0; i < 4; i++)
1679      {
1680         snprintf(style, sizeof(style), STYLE_PRIORITY[i], elm_widget_style_get(obj));
1681         if (_elm_layout_theme_set_internal(sd->action_area, "popup", buf, style) == ELM_THEME_APPLY_SUCCESS)
1682           break;
1683      }
1684    if (i == 4)
1685      CRI("Failed to set layout!");
1686    /* END */
1687
1688    /* TIZEN_ONLY(20160318): Support legacy group and swallow part names
1689    snprintf(buf, sizeof(buf), "elm.swallow.content.button%i", idx + 1);
1690    elm_object_part_content_set
1691      (sd->action_area, buf, sd->buttons[idx]->btn);
1692     */
1693    snprintf(buf, sizeof(buf), "actionbtn%i", idx + 1);
1694    evas_object_show(sd->buttons[idx]->btn);
1695    if (edje_object_part_exists(elm_layout_edje_get(sd->action_area), buf))
1696      {
1697         elm_object_part_content_set
1698            (sd->action_area, buf, sd->buttons[idx]->btn);
1699      }
1700    else
1701      {
1702         snprintf(buf, sizeof(buf), "elm.swallow.content.button%i", idx + 1);
1703         elm_object_part_content_set
1704            (sd->action_area, buf, sd->buttons[idx]->btn);
1705      }
1706    /* END */
1707 }
1708
1709 EOLIAN static Eina_Bool
1710 _elm_popup_elm_container_content_set(Eo *obj, Elm_Popup_Data *_pd EINA_UNUSED, const char *part, Evas_Object *content)
1711 {
1712    Eina_Bool tmp;
1713    unsigned int i;
1714    Eina_Bool ret = EINA_TRUE;
1715
1716    if (!part || !strcmp(part, "default"))
1717      ret = _content_set(obj, content);
1718    else if (!strcmp(part, "title,icon"))
1719      ret = _title_icon_set(obj, content);
1720    else if (!strncmp(part, "button", 6))
1721      {
1722         i = atoi(part + 6) - 1;
1723
1724         if (i >= ELM_POPUP_ACTION_BUTTON_MAX)
1725           {
1726              ERR("The part name is invalid! : popup=%p", obj);
1727              return EINA_FALSE;
1728           }
1729
1730         _action_button_set(obj, content, i);
1731      }
1732    else
1733    /* TIZEN_ONLY(20161206): support tizen custom signal (tizen_2.3)
1734      ret = eo_do_ret(_pd->main_layout, tmp, elm_obj_container_content_set(part, content));
1735     */
1736      {
1737         if (strcmp("elm.swallow.icon", part) != 0 &&
1738             strcmp("elm.swallow.end", part) != 0)
1739           {
1740              const char *type;
1741              char buf[1024];
1742              if (strncmp(part, "elm.swallow.", sizeof("elm.swallow.") - 1) == 0)
1743                type = part + sizeof("elm.swallow.")-1;
1744              else
1745                type = part;
1746
1747              snprintf(buf, sizeof(buf), "elm,state,tizen,%s,show", type);
1748              elm_layout_signal_emit(_pd->main_layout, buf, "elm");
1749           }
1750
1751         ret = eo_do_ret(_pd->main_layout, tmp, elm_obj_container_content_set(part, content));
1752      }
1753    /* END */
1754
1755    _scroller_size_calc(obj);
1756    elm_layout_sizing_eval(obj);
1757
1758    return ret;
1759 }
1760
1761 static Evas_Object *
1762 _title_icon_get(const Elm_Popup_Data *sd)
1763 {
1764    return sd->title_icon;
1765 }
1766
1767 static Evas_Object *
1768 _content_get(const Elm_Popup_Data *sd)
1769 {
1770    Evas_Object *ret;
1771
1772    ret = sd->content ? sd->content : sd->text_content_obj;
1773
1774    return ret;
1775 }
1776
1777 static Evas_Object *
1778 _action_button_get(const Evas_Object *obj,
1779                    unsigned int idx)
1780 {
1781    Evas_Object *button = NULL;
1782
1783    ELM_POPUP_DATA_GET(obj, sd);
1784    if (!sd->action_area) return NULL;
1785
1786    if (sd->buttons[idx])
1787      button = sd->buttons[idx]->btn;
1788
1789    return button;
1790 }
1791
1792 EOLIAN static Evas_Object*
1793 _elm_popup_elm_container_content_get(Eo *obj, Elm_Popup_Data *_pd, const char *part)
1794 {
1795    Evas_Object *content = NULL;
1796    unsigned int i;
1797
1798    if (!part || !strcmp(part, "default"))
1799      content = _content_get(_pd);
1800    else if (!strcmp(part, "title,text"))
1801      content = _title_icon_get(_pd);
1802    else if (!strncmp(part, "button", 6))
1803      {
1804         i = atoi(part + 6) - 1;
1805
1806         if (i >= ELM_POPUP_ACTION_BUTTON_MAX)
1807           goto err;
1808
1809         content = _action_button_get(obj, i);
1810      }
1811    else
1812       eo_do(_pd->main_layout, content = elm_obj_container_content_get(part));
1813
1814    if (!content)
1815      goto err;
1816
1817    return content;
1818
1819 err:
1820    WRN("The part name is invalid! : popup=%p", obj);
1821    return NULL;
1822 }
1823
1824 static Evas_Object *
1825 _content_unset(Evas_Object *obj)
1826 {
1827    Evas_Object *content;
1828
1829    ELM_POPUP_DATA_GET(obj, sd);
1830
1831    if (!sd->content) return NULL;
1832
1833    evas_object_event_callback_del
1834      (sd->content, EVAS_CALLBACK_DEL, _on_content_del);
1835
1836    eo_do(sd->content_area, content = elm_obj_container_content_unset(CONTENT_PART));
1837    sd->content = NULL;
1838
1839    //TIZEN_ONLY(20161107): support scrollable content
1840    //FIXME: genlist only now, it should be changed to support other scrollable.
1841    sd->scrollable_content = EINA_FALSE;
1842    //
1843
1844    elm_layout_sizing_eval(obj);
1845
1846    return content;
1847 }
1848
1849 static Evas_Object *
1850 _title_icon_unset(Evas_Object *obj)
1851 {
1852    Evas_Object *icon;
1853
1854    ELM_POPUP_DATA_GET(obj, sd);
1855
1856    if (!sd->title_icon) return NULL;
1857
1858    icon = sd->title_icon;
1859    eo_do(sd->main_layout, elm_obj_container_content_unset("elm.swallow.title.icon"));
1860    sd->title_icon = NULL;
1861
1862    return icon;
1863 }
1864
1865 EOLIAN static Evas_Object*
1866 _elm_popup_elm_container_content_unset(Eo *obj, Elm_Popup_Data *_pd EINA_UNUSED, const char *part)
1867 {
1868    Evas_Object *content = NULL;
1869    unsigned int i;
1870
1871    if (!part || !strcmp(part, "default"))
1872      content = _content_unset(obj);
1873    else if (!strcmp(part, "title,icon"))
1874      content = _title_icon_unset(obj);
1875    else if (!strncmp(part, "button", 6))
1876      {
1877         i = atoi(part + 6) - 1;
1878
1879         if (i >= ELM_POPUP_ACTION_BUTTON_MAX)
1880           goto err;
1881
1882         _button_remove(obj, i, EINA_FALSE);
1883      }
1884    else
1885    /* TIZEN_ONLY(20161206): support tizen custom signal (tizen_2.3)
1886      goto err;
1887     */
1888      {
1889         if (strcmp("elm.swallow.icon", part) != 0 &&
1890             strcmp("elm.swallow.end", part) != 0)
1891           {
1892              const char *type;
1893              char buf[1024];
1894              if (strncmp(part, "elm.swallow.", sizeof("elm.swallow.") - 1) == 0)
1895                type = part + sizeof("elm.swallow.")-1;
1896              else
1897                type = part;
1898
1899              snprintf(buf, sizeof(buf), "elm,state,tizen,%s,hide", type);
1900              elm_layout_signal_emit(_pd->main_layout, buf, "elm");
1901           }
1902
1903         eo_do(_pd->main_layout, content = elm_obj_container_content_unset(part));
1904      }
1905    /* END */
1906
1907    return content;
1908
1909 err:
1910    ERR("The part name is invalid! : popup=%p", obj);
1911
1912    return NULL;
1913 }
1914
1915 EOLIAN static Eina_Bool
1916 _elm_popup_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Popup_Data *_pd EINA_UNUSED)
1917 {
1918    return EINA_TRUE;
1919 }
1920
1921 EOLIAN static Eina_Bool
1922 _elm_popup_elm_widget_focus_next(Eo *obj EINA_UNUSED, Elm_Popup_Data *sd, Elm_Focus_Direction dir, Evas_Object **next, Elm_Object_Item **next_item)
1923 {
1924    Evas_Object *ao;
1925    Eina_List *items = NULL;
1926    Eina_List *base_items = NULL;
1927
1928    /* access */
1929    if (_elm_config->access_mode)
1930      {
1931         if (sd->title_text)
1932           {
1933              ao = _access_object_get(obj, ACCESS_TITLE_PART);
1934              items = eina_list_append(items, ao);
1935           }
1936
1937         ao = _access_object_get(obj, ACCESS_BODY_PART);
1938         if (ao) items = eina_list_append(items, ao);
1939      }
1940
1941    eo_do(sd->main_layout, base_items = elm_obj_container_content_swallow_list_get());
1942
1943    items = eina_list_merge(items, base_items);
1944
1945    if (!elm_widget_focus_list_next_get(sd->main_layout, items, eina_list_data_get, dir, next, next_item))
1946      *next = sd->main_layout;
1947    eina_list_free(items);
1948
1949    return EINA_TRUE;
1950 }
1951
1952 EOLIAN static Eina_Bool
1953 _elm_popup_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Popup_Data *_pd EINA_UNUSED)
1954 {
1955    return EINA_TRUE;
1956 }
1957
1958 EOLIAN static Eina_Bool
1959 _elm_popup_elm_widget_focus_direction(Eo *obj EINA_UNUSED, Elm_Popup_Data *sd, const Evas_Object *base, double degree, Evas_Object **direction, Elm_Object_Item **direction_item, double *weight)
1960 {
1961    Evas_Object *ao;
1962    Eina_List *items = NULL;
1963    Eina_List *base_items = NULL;
1964
1965    /* access */
1966    if (_elm_config->access_mode)
1967      {
1968         if (sd->title_text)
1969           {
1970              ao = _access_object_get(obj, ACCESS_TITLE_PART);
1971              items = eina_list_append(items, ao);
1972           }
1973
1974         ao = _access_object_get(obj, ACCESS_BODY_PART);
1975         if (ao) items = eina_list_append(items, ao);
1976      }
1977
1978    eo_do(sd->main_layout, base_items = elm_obj_container_content_swallow_list_get());
1979
1980    items = eina_list_merge(items, base_items);
1981
1982    elm_widget_focus_list_direction_get
1983      (sd->main_layout, base, items, eina_list_data_get, degree, direction, direction_item, weight);
1984    eina_list_free(items);
1985
1986    return EINA_TRUE;
1987 }
1988
1989 //TIZEN_ONLY(20150709) : add keybinding for elm_popup "block,clicked" action
1990 static Eina_Bool
1991 _key_action_escape(Evas_Object *obj, const char *params EINA_UNUSED)
1992 {
1993    evas_object_smart_callback_call(obj, SIG_BLOCK_CLICKED, NULL);
1994    return EINA_TRUE;
1995 }
1996 //
1997
1998 static Eina_Bool
1999 _key_action_move(Evas_Object *obj, const char *params)
2000 {
2001    const char *dir = params;
2002
2003    _elm_widget_focus_auto_show(obj);
2004    if (!strcmp(dir, "previous"))
2005      elm_widget_focus_cycle(obj, ELM_FOCUS_PREVIOUS);
2006    else if (!strcmp(dir, "next"))
2007      elm_widget_focus_cycle(obj, ELM_FOCUS_NEXT);
2008    else if (!strcmp(dir, "left"))
2009      elm_widget_focus_cycle(obj, ELM_FOCUS_LEFT);
2010    else if (!strcmp(dir, "right"))
2011      elm_widget_focus_cycle(obj, ELM_FOCUS_RIGHT);
2012    else if (!strcmp(dir, "up"))
2013      elm_widget_focus_cycle(obj, ELM_FOCUS_UP);
2014    else if (!strcmp(dir, "down"))
2015      elm_widget_focus_cycle(obj, ELM_FOCUS_DOWN);
2016    else return EINA_FALSE;
2017
2018    return EINA_TRUE;
2019
2020 }
2021
2022 EOLIAN static Eina_Bool
2023 _elm_popup_elm_widget_event(Eo *obj, Elm_Popup_Data *_pd EINA_UNUSED, Evas_Object *src, Evas_Callback_Type type, void *event_info)
2024 {
2025    (void)src;
2026    Evas_Event_Key_Down *ev = event_info;
2027
2028    if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
2029    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
2030
2031    if (!_elm_config_key_binding_call(obj, ev, key_actions))
2032      return EINA_FALSE;
2033
2034    ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2035    return EINA_TRUE;
2036 }
2037
2038 //TIZEN_ONLY(20160726): add API elm_object_part_access_object_get
2039 EOLIAN static Evas_Object*
2040 _elm_popup_elm_widget_part_access_object_get(const Eo *obj, Elm_Popup_Data *_pd EINA_UNUSED, const char *part)
2041 {
2042    return _access_object_get(obj, part);
2043 }
2044 //
2045
2046 EOLIAN static void
2047 _elm_popup_evas_object_smart_add(Eo *obj, Elm_Popup_Data *priv)
2048 {
2049    char style[1024];
2050    //TIZEN_ONLY(20161109): check theme compatibility more precise
2051    int i;
2052    //
2053
2054    eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
2055    elm_widget_sub_object_parent_add(obj);
2056
2057    //TIZEN_ONLY(20160624): add a allow eval flag not to call another sizing eval during sizing eval
2058    priv->allow_eval = EINA_TRUE;
2059    //
2060    //TIZEN_ONLY(20161107): support scrollable content
2061    //FIXME: genlist only now, it should be changed to support other scrollable.
2062    priv->scrollable_content = EINA_FALSE;
2063    //
2064
2065    snprintf(style, sizeof(style), "popup/%s", elm_widget_style_get(obj));
2066
2067    priv->notify = elm_notify_add(obj);
2068    /* TIZEN_ONLY(20161031): apply color_class parent-child relationship to all widgets */
2069    _elm_widget_color_class_parent_set(priv->notify, obj);
2070    /* END */
2071
2072    //TIZEN_ONLY(20160629): reorder notify align set
2073    elm_notify_align_set(priv->notify,
2074                         _elm_config->popup_horizontal_align,
2075                         _elm_config->popup_vertical_align);
2076    //
2077
2078    /* TIZEN_ONLY(20160328): Support legacy groups
2079    elm_object_style_set(priv->notify, style);
2080     */
2081      {
2082         Elm_Theme_Apply ret;
2083         const char *obj_style = elm_widget_style_get(obj);
2084
2085         if (obj_style && !strcmp(obj_style, "default"))
2086           ret = _elm_widget_style_set_internal(priv->notify, "popup");
2087         else
2088           ret = _elm_widget_style_set_internal(priv->notify, obj_style);
2089
2090         if (ret != ELM_THEME_APPLY_SUCCESS)
2091           if (_elm_widget_style_set_internal(priv->notify, style) != ELM_THEME_APPLY_SUCCESS)
2092             if (_elm_widget_style_set_internal(priv->notify, "popup") != ELM_THEME_APPLY_SUCCESS)
2093               _elm_widget_style_set_internal(priv->notify, "popup/default");
2094      }
2095    /* END */
2096
2097    //TIZEN_ONLY(20160623):Apply popup compress mode UX
2098    priv->dispmode = evas_object_size_hint_display_mode_get(obj);
2099
2100    evas_object_event_callback_add(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
2101                                   _on_obj_size_hints_changed, NULL);
2102    //
2103
2104    /*TIZEN_ONLY(20160629): reorder notify align set
2105    elm_notify_align_set(priv->notify,
2106                         _elm_config->popup_horizontal_align,
2107                         _elm_config->popup_vertical_align);
2108    */
2109    elm_notify_allow_events_set(priv->notify, EINA_FALSE);
2110    evas_object_size_hint_weight_set
2111      (priv->notify, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
2112    evas_object_size_hint_align_set
2113      (priv->notify, EVAS_HINT_FILL, EVAS_HINT_FILL);
2114    evas_object_smart_member_add(priv->notify, obj);
2115    elm_widget_mirrored_automatic_set(priv->notify, EINA_FALSE);
2116    elm_object_mirrored_set(priv->notify, elm_object_mirrored_get(obj));
2117
2118    evas_object_event_callback_add(priv->notify, EVAS_CALLBACK_RESIZE, _notify_resize_cb, obj);
2119
2120    priv->main_layout = elm_layout_add(obj);
2121    /* TIZEN_ONLY(20161031): apply color_class parent-child relationship to all widgets */
2122    _elm_widget_color_class_parent_set(priv->main_layout, obj);
2123    /* END */
2124    if (!elm_layout_theme_set(priv->main_layout, "popup", "base",
2125                              elm_widget_style_get(obj)))
2126      CRI("Failed to set layout!");
2127
2128    elm_object_content_set(priv->notify, priv->main_layout);
2129
2130    evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _on_show, NULL);
2131    elm_widget_mirrored_automatic_set(priv->main_layout, EINA_FALSE);
2132    elm_object_mirrored_set(priv->main_layout, elm_object_mirrored_get(obj));
2133
2134    elm_layout_signal_callback_add
2135      (priv->main_layout, "elm,state,title_area,visible", "elm", _layout_change_cb, NULL);
2136    elm_layout_signal_callback_add
2137      (priv->main_layout, "elm,state,title_area,hidden", "elm", _layout_change_cb, NULL);
2138    elm_layout_signal_callback_add
2139      (priv->main_layout, "elm,state,action_area,visible", "elm", _layout_change_cb, NULL);
2140    elm_layout_signal_callback_add
2141      (priv->main_layout, "elm,state,action_area,hidden", "elm", _layout_change_cb, NULL);
2142
2143    priv->content_area = elm_layout_add(priv->main_layout);
2144    /* TIZEN_ONLY(20161031): apply color_class parent-child relationship to all widgets */
2145    _elm_widget_color_class_parent_set(priv->content_area, obj);
2146    /* END */
2147    /* TIZEN_ONLY(20160328): Support legacy groups
2148    if (!elm_layout_theme_set(priv->content_area, "popup", "content", style))
2149      CRI("Failed to set layout!");
2150    else
2151      evas_object_event_callback_add
2152         (priv->content_area, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
2153          _size_hints_changed_cb, priv->main_layout);
2154     */
2155    for (i = 0 ; i < 4; i++)
2156      {
2157         snprintf(style, sizeof(style), STYLE_PRIORITY[i], elm_widget_style_get(obj));
2158         if (_elm_layout_theme_set_internal(priv->content_area, "popup", "content", style) == ELM_THEME_APPLY_SUCCESS)
2159           break;
2160      }
2161    if (i == 4)
2162      CRI("Failed to set layout!");
2163    else
2164    //TIZEN_ONLY(2016-06-23): fix popup align and size problem
2165    //  evas_object_event_callback_add
2166    //     (priv->content_area, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
2167    //      _size_hints_changed_cb, priv->main_layout);
2168      evas_object_event_callback_add
2169         (priv->content_area, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
2170          _size_hints_changed_cb, obj);
2171    //
2172    /* END */
2173
2174    priv->content_text_wrap_type = ELM_WRAP_MIXED;
2175    eo_do(priv->notify,
2176          eo_event_callback_array_add(_notify_cb(), obj));
2177
2178    elm_widget_can_focus_set(obj, EINA_TRUE);
2179    elm_widget_can_focus_set(priv->main_layout, EINA_TRUE);
2180
2181    _populate_theme_scroll(priv);
2182
2183    _visuals_set(obj);
2184
2185    if (_elm_config->popup_scrollable)
2186      elm_popup_scrollable_set(obj, _elm_config->popup_scrollable);
2187 }
2188
2189 static void
2190 _parent_geom_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2191 {
2192    Evas_Coord x, y, w, h;
2193    Evas_Object *popup = data;
2194
2195    evas_object_geometry_get(obj, &x, &y, &w, &h);
2196
2197    if (eo_isa(obj, ELM_WIN_CLASS))
2198      {
2199         x = 0;
2200         y = 0;
2201      }
2202
2203    evas_object_move(popup, x, y);
2204    evas_object_resize(popup, w, h);
2205 }
2206
2207 EOLIAN static void
2208 _elm_popup_elm_widget_parent_set(Eo *obj, Elm_Popup_Data *sd, Evas_Object *parent)
2209 {
2210    Evas_Coord x, y, w, h;
2211    evas_object_geometry_get(parent, &x, &y, &w, &h);
2212
2213    if (eo_isa(parent, ELM_WIN_CLASS))
2214      {
2215         x = 0;
2216         y = 0;
2217      }
2218    evas_object_move(obj, x, y);
2219    evas_object_resize(obj, w, h);
2220
2221    sd->parent = parent;
2222    evas_object_event_callback_add(parent, EVAS_CALLBACK_RESIZE, _parent_geom_cb, obj);
2223    evas_object_event_callback_add(parent, EVAS_CALLBACK_MOVE, _parent_geom_cb, obj);
2224 }
2225
2226 EOLIAN static void
2227 _elm_popup_elm_widget_access(Eo *obj, Elm_Popup_Data *_pd EINA_UNUSED, Eina_Bool is_access)
2228 {
2229    _access_obj_process(obj, is_access);
2230 }
2231
2232 //TIZEN_ONLY(20160822): When atspi mode is dynamically switched on/off,
2233 //register/unregister access objects accordingly.
2234 // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
2235 EOLIAN static void
2236 _elm_popup_elm_widget_screen_reader(Eo *obj, Elm_Popup_Data *_pd EINA_UNUSED, Eina_Bool is_screen_reader)
2237 {
2238    _atspi_expose_title(obj, is_screen_reader);
2239    //TIZEN_ONLY(20170314): expose part-text as at-spi object
2240    _atspi_part_text_expose(obj, "elm.text", is_screen_reader);
2241    //
2242
2243    //TIZEN_ONLY(20161213): apply screen_reader_changed callback
2244    evas_object_smart_callback_call(obj, SIG_ATSPI_SCREEN_READER_CHANGED, &is_screen_reader);
2245    //
2246 }
2247
2248 EOLIAN static void
2249 _elm_popup_elm_widget_atspi(Eo *obj, Elm_Popup_Data *_pd EINA_UNUSED, Eina_Bool is_atspi)
2250 {
2251    Elm_Atspi_State_Set ss;
2252
2253    if (!is_atspi) return;
2254
2255    eo_do(obj, ss = elm_interface_atspi_accessible_state_set_get());
2256    if (STATE_TYPE_GET(ss, ELM_ATSPI_STATE_SHOWING))
2257      {
2258         elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_SHOWING, EINA_TRUE);
2259      }
2260 }
2261 //
2262 //
2263
2264 EAPI Evas_Object *
2265 elm_popup_add(Evas_Object *parent)
2266 {
2267    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
2268    Evas_Object *obj = eo_add(MY_CLASS, parent);
2269
2270    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
2271    wd->highlight_root = EINA_TRUE;
2272
2273    return obj;
2274 }
2275
2276 EOLIAN static Eo *
2277 _elm_popup_eo_base_constructor(Eo *obj, Elm_Popup_Data *_pd EINA_UNUSED)
2278 {
2279    obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
2280    eo_do(obj,
2281          evas_obj_type_set(MY_CLASS_NAME_LEGACY),
2282          evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
2283          elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_DIALOG));
2284    return obj;
2285 }
2286
2287 EOLIAN static void
2288 _elm_popup_content_text_wrap_type_set(Eo *obj EINA_UNUSED, Elm_Popup_Data *sd, Elm_Wrap_Type wrap)
2289 {
2290    //Need to wrap the content text, so not allowing ELM_WRAP_NONE
2291    if (sd->content_text_wrap_type == ELM_WRAP_NONE) return;
2292
2293    sd->content_text_wrap_type = wrap;
2294    if (sd->text_content_obj)
2295      elm_label_line_wrap_set(sd->text_content_obj, wrap);
2296 }
2297
2298 EOLIAN static Elm_Wrap_Type
2299 _elm_popup_content_text_wrap_type_get(Eo *obj EINA_UNUSED, Elm_Popup_Data *sd)
2300 {
2301    return sd->content_text_wrap_type;
2302 }
2303
2304 /* keeping old externals orient api for notify, but taking away the
2305  * introduced deprecation warning by copying the deprecated code
2306  * here */
2307 static Elm_Notify_Orient
2308 _elm_notify_orient_get(const Evas_Object *obj)
2309 {
2310    Elm_Notify_Orient orient;
2311    double horizontal, vertical;
2312
2313    elm_notify_align_get(obj, &horizontal, &vertical);
2314
2315    if ((horizontal == 0.5) && (vertical == 0.0))
2316      orient = ELM_NOTIFY_ORIENT_TOP;
2317    else if ((horizontal == 0.5) && (vertical == 0.5))
2318      orient = ELM_NOTIFY_ORIENT_CENTER;
2319    else if ((horizontal == 0.5) && (vertical == 1.0))
2320      orient = ELM_NOTIFY_ORIENT_BOTTOM;
2321    else if ((horizontal == 0.0) && (vertical == 0.5))
2322      orient = ELM_NOTIFY_ORIENT_LEFT;
2323    else if ((horizontal == 1.0) && (vertical == 0.5))
2324      orient = ELM_NOTIFY_ORIENT_RIGHT;
2325    else if ((horizontal == 0.0) && (vertical == 0.0))
2326      orient = ELM_NOTIFY_ORIENT_TOP_LEFT;
2327    else if ((horizontal == 1.0) && (vertical == 0.0))
2328      orient = ELM_NOTIFY_ORIENT_TOP_RIGHT;
2329    else if ((horizontal == 0.0) && (vertical == 1.0))
2330      orient = ELM_NOTIFY_ORIENT_BOTTOM_LEFT;
2331    else if ((horizontal == 1.0) && (vertical == 1.0))
2332      orient = ELM_NOTIFY_ORIENT_BOTTOM_RIGHT;
2333    else
2334      orient = ELM_NOTIFY_ORIENT_TOP;
2335    return orient;
2336 }
2337
2338 static void
2339 _elm_notify_orient_set(Evas_Object *obj,
2340                        Elm_Notify_Orient orient)
2341 {
2342    double horizontal = 0, vertical = 0;
2343
2344    switch (orient)
2345      {
2346       case ELM_NOTIFY_ORIENT_TOP:
2347          horizontal = 0.5; vertical = 0.0;
2348         break;
2349
2350       case ELM_NOTIFY_ORIENT_CENTER:
2351          horizontal = 0.5; vertical = 0.5;
2352         break;
2353
2354       case ELM_NOTIFY_ORIENT_BOTTOM:
2355          horizontal = 0.5; vertical = 1.0;
2356         break;
2357
2358       case ELM_NOTIFY_ORIENT_LEFT:
2359          horizontal = 0.0; vertical = 0.5;
2360         break;
2361
2362       case ELM_NOTIFY_ORIENT_RIGHT:
2363          horizontal = 1.0; vertical = 0.5;
2364         break;
2365
2366       case ELM_NOTIFY_ORIENT_TOP_LEFT:
2367          horizontal = 0.0; vertical = 0.0;
2368         break;
2369
2370       case ELM_NOTIFY_ORIENT_TOP_RIGHT:
2371          horizontal = 1.0; vertical = 0.0;
2372         break;
2373
2374       case ELM_NOTIFY_ORIENT_BOTTOM_LEFT:
2375          horizontal = 0.0; vertical = 1.0;
2376         break;
2377
2378       case ELM_NOTIFY_ORIENT_BOTTOM_RIGHT:
2379          horizontal = 1.0; vertical = 1.0;
2380         break;
2381
2382       case ELM_NOTIFY_ORIENT_LAST:
2383         break;
2384      }
2385
2386    elm_notify_align_set(obj, horizontal, vertical);
2387 }
2388
2389 EOLIAN static void
2390 _elm_popup_orient_set(Eo *obj EINA_UNUSED, Elm_Popup_Data *sd, Elm_Popup_Orient orient)
2391 {
2392    if (orient >= ELM_POPUP_ORIENT_LAST) return;
2393    _elm_notify_orient_set(sd->notify, (Elm_Notify_Orient)orient);
2394 }
2395
2396 EOLIAN static Elm_Popup_Orient
2397 _elm_popup_orient_get(Eo *obj EINA_UNUSED, Elm_Popup_Data *sd)
2398 {
2399    return (Elm_Popup_Orient)_elm_notify_orient_get(sd->notify);
2400 }
2401
2402 EOLIAN static void
2403 _elm_popup_align_set(Eo *obj EINA_UNUSED, Elm_Popup_Data *sd, double horizontal, double vertical)
2404 {
2405    elm_notify_align_set(sd->notify, horizontal, vertical);
2406 }
2407
2408 EOLIAN static void
2409 _elm_popup_align_get(Eo *obj EINA_UNUSED, Elm_Popup_Data *sd, double *horizontal, double *vertical)
2410 {
2411    elm_notify_align_get(sd->notify, horizontal, vertical);
2412 }
2413
2414 EOLIAN static void
2415 _elm_popup_timeout_set(Eo *obj EINA_UNUSED, Elm_Popup_Data *sd, double timeout)
2416 {
2417    elm_notify_timeout_set(sd->notify, timeout);
2418 }
2419
2420 EOLIAN static double
2421 _elm_popup_timeout_get(Eo *obj EINA_UNUSED, Elm_Popup_Data *sd)
2422 {
2423    return elm_notify_timeout_get(sd->notify);
2424 }
2425
2426 EOLIAN static void
2427 _elm_popup_allow_events_set(Eo *obj EINA_UNUSED, Elm_Popup_Data *sd, Eina_Bool allow)
2428 {
2429    Eina_Bool allow_events = !!allow;
2430
2431    elm_notify_allow_events_set(sd->notify, allow_events);
2432 }
2433
2434 EOLIAN static Eina_Bool
2435 _elm_popup_allow_events_get(Eo *obj EINA_UNUSED, Elm_Popup_Data *sd)
2436 {
2437    return elm_notify_allow_events_get(sd->notify);
2438 }
2439
2440 EOLIAN static Elm_Object_Item*
2441 _elm_popup_item_append(Eo *obj, Elm_Popup_Data *sd, const char *label, Evas_Object *icon, Evas_Smart_Cb func, const void *data)
2442 {
2443    Evas_Object *prev_content;
2444    Eo *eo_it;
2445
2446    eo_it = eo_add(ELM_POPUP_ITEM_CLASS, obj);
2447    if (!eo_it) return NULL;
2448    ELM_POPUP_ITEM_DATA_GET(eo_it, it);
2449    if (sd->content || sd->text_content_obj)
2450      {
2451         eo_do(sd->content_area, prev_content =
2452                              elm_obj_container_content_get(CONTENT_PART));
2453         evas_object_del(prev_content);
2454      }
2455
2456    //The first item is appended.
2457    if (!sd->items)
2458      _list_add(obj);
2459
2460    it->func = func;
2461    WIDGET_ITEM_DATA_SET(eo_it, data);
2462
2463    _item_new(it);
2464    _item_icon_set(it, icon);
2465    _item_text_set(it, label);
2466
2467    elm_box_pack_end(sd->box, VIEW(it));
2468    sd->items = eina_list_append(sd->items, it);
2469
2470    _scroller_size_calc(obj);
2471    elm_layout_sizing_eval(obj);
2472
2473    return eo_it;
2474 }
2475
2476 EOLIAN void
2477 _elm_popup_scrollable_set(Eo *obj, Elm_Popup_Data *pd, Eina_Bool scroll)
2478 {
2479    scroll = !!scroll;
2480    if (pd->scroll == scroll) return;
2481    pd->scroll = scroll;
2482
2483    if (!pd->scr)
2484      _create_scroller(obj);
2485    else
2486      {
2487         elm_object_content_unset(pd->scr);
2488         ELM_SAFE_FREE(pd->tbl, evas_object_del);
2489         _create_scroller(obj);
2490      }
2491
2492    if (!pd->scroll)
2493      {
2494         eo_do(pd->content_area, elm_obj_container_content_set(CONTENT_PART, pd->tbl));
2495         eo_do(pd->main_layout, elm_obj_container_content_set(CONTENT_PART, pd->content_area));
2496         if (pd->content) eo_do(pd->content_area, elm_obj_container_content_set(CONTENT_PART, pd->content));
2497         else if (pd->text_content_obj) eo_do(pd->content_area, elm_obj_container_content_set(CONTENT_PART, pd->text_content_obj));
2498         if (pd->theme_scroll)
2499           elm_layout_signal_emit(pd->content_area, "elm,scroll,disable", "elm");
2500      }
2501    else
2502      {
2503         if (pd->content || pd->text_content_obj)
2504           {
2505              eo_do(pd->main_layout, elm_obj_container_content_unset(CONTENT_PART));
2506              elm_object_content_set(pd->scr, pd->content_area);
2507           }
2508         eo_do(pd->main_layout, elm_obj_container_content_set(CONTENT_PART, pd->tbl));
2509         if (pd->theme_scroll)
2510           elm_layout_signal_emit(pd->content_area, "elm,scroll,enable", "elm");
2511      }
2512
2513    _scroller_size_calc(obj);
2514    elm_layout_sizing_eval(obj);
2515 }
2516
2517 EOLIAN Eina_Bool
2518 _elm_popup_scrollable_get(Eo *obj EINA_UNUSED, Elm_Popup_Data *pd)
2519 {
2520    return pd->scroll;
2521 }
2522
2523 EOLIAN static void
2524 _elm_popup_dismiss(Eo *obj EINA_UNUSED, Elm_Popup_Data *pd)
2525 {
2526    //TIZEN_ONLY(20170919): Handle default label object
2527    _elm_win_default_label_obj_remove(obj);
2528    //
2529    elm_layout_signal_emit(pd->main_layout, "elm,state,hide", "elm");
2530    elm_notify_dismiss(pd->notify);
2531 }
2532
2533 static void
2534 _elm_popup_class_constructor(Eo_Class *klass)
2535 {
2536    evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
2537 }
2538
2539 //TIZEN ONLY(20160818): name interface added
2540 EOLIAN static const char*
2541 _elm_popup_elm_interface_atspi_accessible_name_get(Eo *obj, Elm_Popup_Data *sd)
2542 {
2543    Eina_Strbuf *buf;
2544    char *accessible_name = NULL;
2545    const char *_parent_name = NULL;
2546    char *utf8_text = NULL;
2547    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
2548
2549    buf = eina_strbuf_new();
2550
2551    eo_do_super(obj, MY_CLASS, _parent_name = elm_interface_atspi_accessible_name_get());
2552
2553    if(_parent_name)
2554      {
2555         eina_strbuf_append_printf(buf, "%s", _parent_name);
2556      }
2557    else
2558      {
2559         eina_strbuf_append_printf(buf, "%s", E_("Alert"));
2560         if (sd->title_text)
2561              utf8_text = _elm_util_mkup_to_text(sd->title_text);
2562         else if (sd->text_content_obj)
2563              utf8_text = _elm_util_mkup_to_text(elm_object_text_get(sd->text_content_obj));
2564         else if (elm_object_part_text_get(obj, "elm.text"))
2565              utf8_text = _elm_util_mkup_to_text(elm_object_part_text_get(obj, "elm.text"));
2566
2567         if (utf8_text)
2568           {
2569              eina_strbuf_append_printf(buf, ", %s", utf8_text);
2570              free(utf8_text);
2571           }
2572      }
2573
2574    accessible_name = eina_strbuf_string_steal(buf);
2575    eina_strbuf_free(buf);
2576
2577    eina_stringshare_del(wd->accessible_name);
2578    wd->accessible_name =  eina_stringshare_add(accessible_name);
2579    free(accessible_name);
2580    return wd->accessible_name;
2581 }
2582 //
2583
2584 EOLIAN const Elm_Atspi_Action *
2585 _elm_popup_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Popup_Data *pd EINA_UNUSED)
2586 {
2587    static Elm_Atspi_Action atspi_actions[] = {
2588 //TIZEN_ONLY(20150709) : add keybinding for elm_popup "block,clicked" action
2589           { "escape", "escape", NULL, _key_action_escape},
2590           { NULL, NULL, NULL, NULL }
2591    };
2592    if (pd->action_area)
2593      return NULL;
2594 ///
2595
2596    return &atspi_actions[0];
2597 }
2598
2599 EOLIAN static Elm_Atspi_State_Set
2600 _elm_popup_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Popup_Data *sd EINA_UNUSED)
2601 {
2602    Elm_Atspi_State_Set ret;
2603    eo_do_super(obj, MY_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
2604
2605    STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MODAL);
2606
2607    return ret;
2608 }
2609
2610 //TIZEN ONLY(20150708): popup and ctxpopup accessibility highlight impementation
2611 EOLIAN static Eina_Bool
2612 _elm_popup_elm_interface_atspi_component_highlight_grab(Eo *obj EINA_UNUSED, Elm_Popup_Data *sd)
2613 {
2614    if (sd->scr)
2615      {
2616         elm_object_accessibility_highlight_set(sd->main_layout, EINA_TRUE);
2617         return EINA_TRUE;
2618      }
2619    return EINA_FALSE;
2620 }
2621
2622 EOLIAN static Eina_Bool
2623 _elm_popup_elm_interface_atspi_component_highlight_clear(Eo *obj EINA_UNUSED, Elm_Popup_Data *sd)
2624 {
2625    if (sd->scr)
2626      {
2627         elm_object_accessibility_highlight_set(sd->main_layout, EINA_FALSE);
2628         return EINA_TRUE;
2629      }
2630    return EINA_FALSE;
2631 }
2632 //
2633 #include "elm_popup.eo.c"
2634 #include "elm_popup_item.eo.c"