0662227a95c581a3ebbb19d2680fad0fb890a5b0
[platform/upstream/elementary.git] / src / lib / elm_panel.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_WIDGET_ACTION_PROTECTED
7
8 #include <Elementary.h>
9
10 #include "elm_priv.h"
11 #include "elm_widget_panel.h"
12
13 #include "els_box.h"
14
15 #define MY_CLASS ELM_PANEL_CLASS
16
17 #define MY_CLASS_NAME "Elm_Panel"
18 #define MY_CLASS_NAME_LEGACY "elm_panel"
19
20 static const char ACCESS_OUTLINE_PART[] = "access.outline";
21
22 static const char SIG_TOGGLED[] = "toggled";
23 static const char SIG_SCROLL[] = "scroll";
24
25 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
26    {SIG_TOGGLED, ""},
27    {SIG_SCROLL, ""},
28    {SIG_LAYOUT_FOCUSED, ""}, /**< handled by elm_layout */
29    {SIG_LAYOUT_UNFOCUSED, ""}, /**< handled by elm_layout */
30    {NULL, NULL}
31 };
32 static void _panel_toggle(void *, Evas_Object *, const char *,const char *);
33 static Eina_Bool _key_action_toggle(Evas_Object *obj, const char *params);
34 static void _drawer_open(Evas_Object *, Evas_Coord , Evas_Coord , Eina_Bool );
35 static void _drawer_close(Evas_Object *, Evas_Coord , Evas_Coord , Eina_Bool);
36
37 static const Elm_Action key_actions[] = {
38    {"toggle", _key_action_toggle},
39    {NULL, NULL}
40 };
41
42 static void
43 _mirrored_set(Evas_Object *obj,
44               Eina_Bool rtl)
45 {
46    ELM_PANEL_DATA_GET(obj, sd);
47
48    if ((sd->content) && (eo_isa(sd->content, ELM_WIDGET_CLASS)))
49      elm_widget_mirrored_set(sd->content, rtl);
50    elm_panel_orient_set(obj, elm_panel_orient_get(obj));
51 }
52
53 EOLIAN static void
54 _elm_panel_elm_layout_sizing_eval(Eo *obj, Elm_Panel_Data *sd)
55 {
56    Evas_Coord mw = -1, mh = -1;
57
58    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
59
60    if (sd->delete_me) return;
61
62    if (sd->scrollable)
63      {
64         if (sd->hidden) _drawer_close(obj, wd->w, wd->h, EINA_FALSE);
65         else _drawer_open(obj, wd->w, wd->h, EINA_FALSE);
66      }
67
68    evas_object_smart_calculate(sd->bx);
69    edje_object_size_min_calc(wd->resize_obj, &mw, &mh);
70    evas_object_size_hint_min_set(obj, mw, mh);
71    evas_object_size_hint_max_set(obj, -1, -1);
72 }
73
74 static char *
75 _access_state_cb(void *data, Evas_Object *obj EINA_UNUSED)
76 {
77    ELM_PANEL_DATA_GET(data, sd);
78
79    if (!sd->hidden) return strdup(E_("state: opened"));
80    else return strdup(E_("state: closed"));
81
82    return NULL;
83 }
84
85 static Evas_Object *
86 _access_object_get(const Evas_Object *obj, const char *part)
87 {
88    Evas_Object *po, *ao;
89    ELM_PANEL_DATA_GET(obj, sd);
90
91    po = (Evas_Object *)edje_object_part_object_get
92       (elm_layout_edje_get(sd->scr_ly), part);
93    ao = evas_object_data_get(po, "_part_access_obj");
94
95    return ao;
96 }
97
98 static void
99 _access_activate_cb(void *data,
100                     Evas_Object *part_obj EINA_UNUSED,
101                     Elm_Object_Item *item EINA_UNUSED)
102 {
103    elm_panel_hidden_set(data, EINA_TRUE);
104 }
105
106 static void
107 _access_obj_process(Evas_Object *obj, Eina_Bool is_access)
108 {
109    Evas_Object *ao;
110    ELM_PANEL_DATA_GET(obj, sd);
111
112    if (is_access)
113      {
114         ao = _access_object_get(obj, ACCESS_OUTLINE_PART);
115         if (!ao)
116           {
117              ao = _elm_access_edje_object_part_object_register
118                 (obj, elm_layout_edje_get(sd->scr_ly), ACCESS_OUTLINE_PART);
119              _elm_access_text_set(_elm_access_info_get(ao),
120                                   ELM_ACCESS_TYPE, E_("A panel is open"));
121              _elm_access_text_set(_elm_access_info_get(ao),
122                                   ELM_ACCESS_CONTEXT_INFO, E_("Double tap to close panel menu"));
123              _elm_access_activate_callback_set
124                 (_elm_access_info_get(ao), _access_activate_cb, obj);
125           }
126      }
127    else
128      {
129         _elm_access_edje_object_part_object_unregister
130            (obj, elm_layout_edje_get(sd->scr_ly), ACCESS_OUTLINE_PART);
131      }
132 }
133
134 // TIZEN_ONLY(20170829): [atspi][panel] Adds accessibility support for the panel widget.
135 static void
136 _accessible_panel_hidden_set(Evas_Object* obj, Eina_Bool is_hidden)
137 {
138    is_hidden = !!is_hidden;
139    elm_atspi_accessible_can_highlight_set(obj, !is_hidden);
140    elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_SHOWING, !is_hidden);
141 }
142 //
143
144 static void
145 _orient_set_do(Evas_Object *obj)
146 {
147    ELM_PANEL_DATA_GET(obj, sd);
148    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
149
150    switch (sd->orient)
151      {
152       case ELM_PANEL_ORIENT_TOP:
153         if (!elm_layout_theme_set
154               (obj, "panel", "top", elm_widget_style_get(obj)))
155           CRI("Failed to set layout!");
156         break;
157
158       case ELM_PANEL_ORIENT_BOTTOM:
159         if (!elm_layout_theme_set
160               (obj, "panel", "bottom", elm_widget_style_get(obj)))
161           CRI("Failed to set layout!");
162         break;
163
164       case ELM_PANEL_ORIENT_LEFT:
165         if (!elm_layout_theme_set(obj, "panel", "left",
166                 elm_widget_style_get(obj)))
167             CRI("Failed to set layout!");
168         break;
169
170       case ELM_PANEL_ORIENT_RIGHT:
171         if (!elm_layout_theme_set(obj, "panel", "right",
172                 elm_widget_style_get(obj)))
173             CRI("Failed to set layout!");
174         break;
175      }
176
177    /* access */
178    if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
179      {
180         Evas_Object *ao;
181         ao = _elm_access_edje_object_part_object_register
182             (obj, wd->resize_obj, "btn_icon");
183         _elm_access_text_set(_elm_access_info_get(ao),
184                              ELM_ACCESS_TYPE, E_("panel button"));
185         _elm_access_callback_set
186           (_elm_access_info_get(ao), ELM_ACCESS_STATE, _access_state_cb, obj);
187      }
188 }
189
190 static void
191 _scrollable_layout_theme_set(Eo *obj, Elm_Panel_Data *sd)
192 {
193    switch (sd->orient)
194      {
195       case ELM_PANEL_ORIENT_TOP:
196          if (!elm_layout_theme_set(sd->scr_ly, "scroller", "panel/top",
197                                    elm_widget_style_get(obj)))
198            CRI("Failed to set layout!");
199          break;
200       case ELM_PANEL_ORIENT_BOTTOM:
201          if (!elm_layout_theme_set(sd->scr_ly, "scroller", "panel/bottom",
202                                    elm_widget_style_get(obj)))
203            CRI("Failed to set layout!");
204          break;
205       case ELM_PANEL_ORIENT_LEFT:
206          if (!elm_layout_theme_set(sd->scr_ly, "scroller", "panel/left",
207                                    elm_widget_style_get(obj)))
208            CRI("Failed to set layout!");
209          break;
210       case ELM_PANEL_ORIENT_RIGHT:
211          if (!elm_layout_theme_set(sd->scr_ly, "scroller", "panel/right",
212                                    elm_widget_style_get(obj)))
213            CRI("Failed to set layout!");
214          break;
215      }
216
217    /* access */
218    if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
219      _access_obj_process(obj, EINA_TRUE);
220 }
221
222 EOLIAN static Elm_Theme_Apply
223 _elm_panel_elm_widget_theme_apply(Eo *obj, Elm_Panel_Data *sd)
224 {
225    const char *str;
226    // TIZEN_ONLY(20170316): set hidden property when panel is close/open
227    //int w, h;
228    //
229    Evas_Coord minw = 0, minh = 0;
230
231    Elm_Theme_Apply int_ret = ELM_THEME_APPLY_FAILED;
232
233    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, ELM_THEME_APPLY_FAILED);
234
235    eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_theme_apply());
236    if (!int_ret) return ELM_THEME_APPLY_FAILED;
237
238    _mirrored_set(obj, elm_widget_mirrored_get(obj));
239
240    if (sd->scrollable)
241      {
242         const char *handler_size;
243         elm_widget_theme_object_set(obj, sd->scr_edje, "scroller", "panel",
244                                     elm_widget_style_get(obj));
245         _scrollable_layout_theme_set(obj, sd);
246         // TIZEN_ONLY(20170316): set hidden property when panel is close/open
247         /*evas_object_geometry_get(obj, NULL, NULL, &w, &h);
248         if (!sd->hidden) _drawer_open(obj, w, h, EINA_FALSE);
249         else _drawer_close(obj, w, h, EINA_FALSE);*/
250         //
251         handler_size = edje_object_data_get(sd->scr_edje, "handler_size");
252         if (handler_size)
253           sd->handler_size = (int) (elm_object_scale_get(obj)) * (atoi(handler_size));
254      }
255    else
256      {
257         str = edje_object_data_get
258            (wd->resize_obj, "focus_highlight");
259         if ((str) && (!strcmp(str, "on")))
260           elm_widget_highlight_in_theme_set(obj, EINA_TRUE);
261         else
262           elm_widget_highlight_in_theme_set(obj, EINA_FALSE);
263
264         _orient_set_do(obj);
265
266         evas_object_hide(sd->event);
267         elm_coords_finger_size_adjust(1, &minw, 1, &minh);
268         evas_object_size_hint_min_set(sd->event, minw, minh);
269
270         if (edje_object_part_exists
271             (wd->resize_obj, "elm.swallow.event"))
272           eo_do_super(obj, MY_CLASS, elm_obj_container_content_set("elm.swallow.event", sd->event));
273      }
274
275    elm_layout_sizing_eval(obj);
276
277    return int_ret;
278 }
279
280 EOLIAN static Eina_Bool
281 _elm_panel_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Panel_Data *_pd EINA_UNUSED)
282 {
283    return EINA_TRUE;
284 }
285
286 EOLIAN static Eina_Bool
287 _elm_panel_elm_widget_focus_next(Eo *obj, Elm_Panel_Data *sd, Elm_Focus_Direction dir, Evas_Object **next, Elm_Object_Item **next_item)
288 {
289    Evas_Object *cur;
290    Eina_List *items = NULL;
291    Eina_Bool ret = EINA_FALSE;
292
293    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
294
295    if (!sd->content) return EINA_FALSE;
296
297    if (sd->scrollable)
298      {
299         if (sd->hidden) return EINA_FALSE;
300
301         if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
302           {
303              Evas_Object *ao = _access_object_get(obj, ACCESS_OUTLINE_PART);
304              if (ao) items = eina_list_append(items, ao);
305              items = eina_list_append(items, sd->content);
306
307              ret = elm_widget_focus_list_next_get
308                 (obj, items, eina_list_data_get, dir, next, next_item);
309              eina_list_free(items);
310
311              return ret;
312           }
313
314         return elm_widget_focus_next_get(sd->content, dir, next, next_item);
315      }
316
317    cur = sd->content;
318
319    /* Try to Focus cycle in subitem */
320    if (!sd->hidden) return elm_widget_focus_next_get(cur, dir, next, next_item);
321
322    /* access */
323    if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF)
324      {
325         Evas_Object *ao, *po;
326         po = (Evas_Object *)edje_object_part_object_get
327                (wd->resize_obj, "btn_icon");
328         ao = evas_object_data_get(po, "_part_access_obj");
329         _elm_access_highlight_set(ao);
330      }
331
332    /* Return */
333    *next = (Evas_Object *)obj;
334    return !elm_widget_focus_get(obj);
335 }
336
337 static void
338 _box_layout_cb(Evas_Object *o,
339                Evas_Object_Box_Data *priv,
340                void *data EINA_UNUSED)
341 {
342    _els_box_layout(o, priv, EINA_TRUE, EINA_FALSE, EINA_FALSE);
343 }
344
345 static void
346 _handler_open(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
347 {
348    ELM_PANEL_DATA_GET(obj, sd);
349
350    if (sd->handler_size == 0) return;
351
352    switch (sd->orient)
353      {
354       case ELM_PANEL_ORIENT_TOP:
355          eo_do(obj, elm_interface_scrollable_region_bring_in
356                (0, (h * sd->content_size_ratio) - sd->handler_size, w, h));
357          break;
358       case ELM_PANEL_ORIENT_BOTTOM:
359          eo_do(obj, elm_interface_scrollable_region_bring_in
360                (0, sd->handler_size, w, h));
361          break;
362       case ELM_PANEL_ORIENT_LEFT:
363          eo_do(obj, elm_interface_scrollable_region_bring_in
364                ((w * sd->content_size_ratio) - sd->handler_size, 0, w, h));
365          break;
366       case ELM_PANEL_ORIENT_RIGHT:
367          eo_do(obj, elm_interface_scrollable_region_bring_in
368                (sd->handler_size, 0, w, h));
369          break;
370      }
371 }
372
373 static void
374 _drawer_open(Evas_Object *obj, Evas_Coord w, Evas_Coord h, Eina_Bool anim)
375 {
376    ELM_PANEL_DATA_GET(obj, sd);
377    int x = 0, y = 0;
378
379    if (sd->freeze)
380      {
381         eo_do(obj, elm_interface_scrollable_movement_block_set
382               (ELM_SCROLLER_MOVEMENT_NO_BLOCK));
383         sd->freeze = EINA_FALSE;
384         elm_layout_signal_emit(sd->scr_ly, "elm,state,content,visible", "elm");
385         // TIZEN_ONLY(20170613): emit signal when panel becomes draggable
386         elm_object_signal_emit(obj, "elm,state,unhold", "elm");
387         //
388      }
389
390    switch (sd->orient)
391      {
392       case ELM_PANEL_ORIENT_TOP:
393          break;
394       case ELM_PANEL_ORIENT_LEFT:
395          if (elm_widget_mirrored_get(obj))
396            x = w * sd->content_size_ratio;
397          break;
398
399       case ELM_PANEL_ORIENT_BOTTOM:
400          y = h * sd->content_size_ratio;
401          break;
402
403       case ELM_PANEL_ORIENT_RIGHT:
404          if (!elm_widget_mirrored_get(obj))
405            x = w * sd->content_size_ratio;
406          break;
407      }
408
409    if (anim)
410      eo_do(obj, elm_interface_scrollable_region_bring_in
411            (x, y, w, h));
412    else
413      eo_do(obj, elm_interface_scrollable_content_region_show
414            (x, y, w, h));
415
416    // TIZEN_ONLY(20170829): [atspi][panel] Adds accessibility support for the panel widget.
417    _accessible_panel_hidden_set(obj, EINA_FALSE);
418    //
419 }
420
421 static void
422 _drawer_close(Evas_Object *obj, Evas_Coord w, Evas_Coord h, Eina_Bool anim)
423 {
424    ELM_PANEL_DATA_GET(obj, sd);
425    int x = 0, y = 0;
426    Eina_Bool horizontal = EINA_FALSE;
427
428    elm_widget_tree_unfocusable_set(obj, EINA_TRUE);
429    switch (sd->orient)
430      {
431       case ELM_PANEL_ORIENT_TOP:
432          y = h * sd->content_size_ratio;
433          break;
434
435       case ELM_PANEL_ORIENT_LEFT:
436          if (!elm_widget_mirrored_get(obj))
437            x = w * sd->content_size_ratio;
438          horizontal = EINA_TRUE;
439          break;
440
441       case ELM_PANEL_ORIENT_BOTTOM:
442          break;
443
444       case ELM_PANEL_ORIENT_RIGHT:
445          if (elm_widget_mirrored_get(obj))
446            x = w * sd->content_size_ratio;
447          horizontal = EINA_TRUE;
448          break;
449      }
450
451    if (anim)
452      {
453         if (sd->freeze)
454           {
455              eo_do(obj, elm_interface_scrollable_movement_block_set
456                    (ELM_SCROLLER_MOVEMENT_NO_BLOCK));
457              sd->freeze = EINA_FALSE;
458              elm_layout_signal_emit(sd->scr_ly, "elm,state,content,visible", "elm");
459              // TIZEN_ONLY(20170613): emit signal when panel becomes draggable
460              elm_object_signal_emit(obj, "elm,state,unhold", "elm");
461              //
462           }
463         eo_do(obj, elm_interface_scrollable_region_bring_in(x, y, w, h));
464      }
465    else
466      {
467         eo_do(obj, elm_interface_scrollable_content_region_show(x, y, w, h));
468         if (!sd->freeze)
469           {
470              if (horizontal)
471                eo_do(obj, elm_interface_scrollable_movement_block_set
472                      (ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL));
473              else
474                eo_do(obj, elm_interface_scrollable_movement_block_set
475                      (ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL));
476              sd->freeze = EINA_TRUE;
477              elm_layout_signal_emit(sd->scr_ly, "elm,state,content,hidden", "elm");
478              // TIZEN_ONLY(20170613): emit signal when panel is hidden
479              elm_object_signal_emit(obj, "elm,state,hold", "elm");
480              //
481           }
482      }
483    // TIZEN_ONLY(20170829) : [atspi][panel] Adds accessibility support for the panel widget.
484    _accessible_panel_hidden_set(obj, EINA_TRUE);
485    //
486 }
487
488 static void
489 _panel_toggle(void *data EINA_UNUSED,
490               Evas_Object *obj,
491               const char *emission EINA_UNUSED,
492               const char *source EINA_UNUSED)
493 {
494    ELM_PANEL_DATA_GET(obj, sd);
495    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
496    int w, h;
497
498    if (sd->scrollable)
499      {
500         if (elm_widget_disabled_get(obj)) return;
501
502         evas_object_geometry_get(obj, NULL, NULL, &w, &h);
503         if (sd->hidden)
504           {
505              sd->hidden = EINA_FALSE;
506              _drawer_open(obj, w, h, EINA_TRUE);
507           }
508         else
509           {
510              sd->hidden = EINA_TRUE;
511              _drawer_close(obj, w, h, EINA_TRUE);
512           }
513      }
514    else
515      {
516         if (sd->hidden)
517           {
518              elm_layout_signal_emit(obj, "elm,action,show", "elm");
519              sd->hidden = EINA_FALSE;
520              evas_object_repeat_events_set(obj, EINA_FALSE);
521              // TIZEN_ONLY(20170829) : [atspi][panel] Adds accessibility support for the panel widget.
522              _accessible_panel_hidden_set(obj, sd->hidden);
523              //
524           }
525         else
526           {
527              elm_layout_signal_emit(obj, "elm,action,hide", "elm");
528              sd->hidden = EINA_TRUE;
529              evas_object_repeat_events_set(obj, EINA_TRUE);
530              if (sd->content && elm_widget_focus_get(sd->content))
531                {
532                   elm_widget_focused_object_clear(obj);
533                   elm_widget_focus_steal(obj, NULL);
534                }
535              // TIZEN_ONLY(20170829) : [atspi][panel] Adds accessibility support for the panel widget.
536              _accessible_panel_hidden_set(obj, sd->hidden);
537              //
538           }
539
540         edje_object_message_signal_process(wd->resize_obj);
541      }
542
543    eo_do(obj, eo_event_callback_call(ELM_PANEL_EVENT_TOGGLED, NULL));
544 }
545
546 static Eina_Bool
547 _state_sync(Evas_Object *obj)
548 {
549    ELM_PANEL_DATA_GET(obj, sd);
550    // TIZEN_ONLY(20170316): set hidden property when panel is close/open
551    /*Evas_Object *ao;
552    Evas_Coord pos, panel_size, w, h;
553    Eina_Bool open = EINA_FALSE, horizontal = EINA_FALSE;*/
554    Evas_Coord pos, panel_size, w, h, threshold;
555    Eina_Bool horizontal = EINA_FALSE, reverse = EINA_FALSE;
556    //
557    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
558
559    if (!evas_object_visible_get(sd->bx)) return EINA_TRUE;
560
561    switch (sd->orient)
562      {
563       // TIZEN_ONLY(20170316): set hidden property when panel is close/open
564       /*case ELM_PANEL_ORIENT_TOP:
565          if (h <= 0) return EINA_TRUE;
566
567          panel_size = h * sd->content_size_ratio;
568          eo_do(obj, elm_interface_scrollable_content_pos_get(NULL, &pos));
569
570          if (pos == 0) open = EINA_TRUE;
571          else if (pos == panel_size) open = EINA_FALSE;
572          else return EINA_FALSE;
573          break;
574
575       case ELM_PANEL_ORIENT_BOTTOM:
576          if (h <= 0) return EINA_TRUE;
577
578          panel_size = h * sd->content_size_ratio;
579          eo_do(obj, elm_interface_scrollable_content_pos_get(NULL, &pos));
580
581          if (pos == panel_size) open = EINA_TRUE;
582          else if (pos == 0) open = EINA_FALSE;
583          else return EINA_FALSE;
584          break;
585
586       case ELM_PANEL_ORIENT_LEFT:
587          if (w <= 0) return EINA_TRUE;
588
589          panel_size = w * sd->content_size_ratio;
590          eo_do(obj, elm_interface_scrollable_content_pos_get(&pos, NULL));
591          horizontal = EINA_TRUE;
592
593          if (!elm_widget_mirrored_get(obj))
594            {
595               if (pos == 0) open = EINA_TRUE;
596               else if (pos == panel_size) open = EINA_FALSE;
597               else return EINA_FALSE;
598            }
599          else
600            {
601               if (pos == panel_size) open = EINA_TRUE;
602               else if (pos == 0) open = EINA_FALSE;
603               else return EINA_FALSE;
604            }
605          break;
606
607       case ELM_PANEL_ORIENT_RIGHT:
608          if (w <= 0) return EINA_TRUE;
609
610          panel_size = w * sd->content_size_ratio;
611          eo_do(obj, elm_interface_scrollable_content_pos_get(&pos, NULL));
612          horizontal = EINA_TRUE;
613
614          if (elm_widget_mirrored_get(obj))
615            {
616               if (pos == 0) open = EINA_TRUE;
617               else if (pos == panel_size) open = EINA_FALSE;
618               else return EINA_FALSE;
619            }
620          else
621            {
622               if (pos == panel_size) open = EINA_TRUE;
623               else if (pos == 0) open = EINA_FALSE;
624               else return EINA_FALSE;
625            }
626          break;*/
627        case ELM_PANEL_ORIENT_BOTTOM:
628           reverse = EINA_TRUE;
629        case ELM_PANEL_ORIENT_TOP:
630           break;
631
632        case ELM_PANEL_ORIENT_RIGHT:
633           reverse = EINA_TRUE;
634        case ELM_PANEL_ORIENT_LEFT:
635           horizontal = EINA_TRUE;
636           break;
637        //
638      }
639
640    // TIZEN_ONLY(20170316): set hidden property when panel is close/open
641    /*if (open)
642      {
643         if (sd->hidden)
644           {
645              sd->hidden = EINA_FALSE;
646              eo_do(obj, eo_event_callback_call(ELM_PANEL_EVENT_TOGGLED, NULL));
647           }
648         eo_do(obj, elm_interface_scrollable_single_direction_set
649               (ELM_SCROLLER_SINGLE_DIRECTION_HARD));
650
651         //focus & access
652         elm_object_tree_focus_allow_set(obj, EINA_TRUE);
653         if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
654           {
655              ao = _access_object_get(obj, ACCESS_OUTLINE_PART);
656              evas_object_show(ao);
657              _elm_access_highlight_set(ao);
658           }
659         else
660           elm_object_focus_set(obj, EINA_TRUE);
661      }
662    else
663      {
664         if (!sd->hidden)
665           {
666              sd->hidden = EINA_TRUE;
667              eo_do(obj, eo_event_callback_call(ELM_PANEL_EVENT_TOGGLED, NULL));
668           }
669
670         if (horizontal)
671           eo_do(obj, elm_interface_scrollable_movement_block_set
672                 (ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL));
673         else
674           eo_do(obj, elm_interface_scrollable_movement_block_set
675                 (ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL));
676         sd->freeze = EINA_TRUE;
677         elm_layout_signal_emit(sd->scr_ly, "elm,state,content,hidden", "elm");
678
679         eo_do(obj, elm_interface_scrollable_single_direction_set
680               (ELM_SCROLLER_SINGLE_DIRECTION_NONE));
681
682         //focus & access
683         elm_object_tree_focus_allow_set(obj, EINA_FALSE);
684         if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
685           {
686              ao = _access_object_get(obj, ACCESS_OUTLINE_PART);
687              evas_object_hide(ao);
688           }
689      }
690
691    return EINA_TRUE;*/
692
693    if (horizontal)
694      {
695         if (w <= 0) return EINA_TRUE;
696
697         panel_size = w * sd->content_size_ratio;
698         eo_do(obj, elm_interface_scrollable_content_pos_get(&pos, NULL));
699         reverse ^= elm_widget_mirrored_get(obj);
700      }
701    else
702      {
703         if (h <= 0) return EINA_TRUE;
704
705         panel_size = h * sd->content_size_ratio;
706         eo_do(obj, elm_interface_scrollable_content_pos_get(NULL, &pos));
707      }
708    threshold = (sd->hidden) ? panel_size - (panel_size / 4) : (panel_size / 4);
709
710    if (reverse)
711      {
712         if (pos > panel_size - threshold) sd->hidden = EINA_FALSE;
713         else sd->hidden = EINA_TRUE;
714      }
715    else
716      {
717         if (pos < threshold) sd->hidden = EINA_FALSE;
718         else sd->hidden = EINA_TRUE;
719      }
720
721    return EINA_FALSE;
722    //
723 }
724
725 static Eina_Bool
726 _timer_cb(void *data)
727 {
728    ELM_PANEL_DATA_GET(data, sd);
729    Evas_Object *obj = data;
730    Evas_Coord w, h;
731
732    sd->timer = NULL;
733
734    if (sd->freeze)
735      {
736         eo_do(obj, elm_interface_scrollable_movement_block_set
737               (ELM_SCROLLER_MOVEMENT_NO_BLOCK));
738         sd->freeze = EINA_FALSE;
739         elm_layout_signal_emit(sd->scr_ly, "elm,state,content,visible", "elm");
740         // TIZEN_ONLY(20170613): emit signal when panel becomes draggable
741         elm_object_signal_emit(obj, "elm,state,unhold", "elm");
742         //
743         evas_object_geometry_get(obj, NULL, NULL, &w, &h);
744         _handler_open(obj, w, h);
745      }
746
747    return ECORE_CALLBACK_CANCEL;
748 }
749
750 static void
751 _event_mouse_up(void *data,
752                 Evas *e EINA_UNUSED,
753                 Evas_Object *obj EINA_UNUSED,
754                 void *event_info)
755 {
756    ELM_PANEL_DATA_GET(data, sd);
757    Evas_Event_Mouse_Up *ev = event_info;
758    Evas_Coord x, y, up_x, up_y, minw = 0, minh = 0;
759    evas_object_geometry_get(data, &x, &y, NULL, NULL);
760
761    up_x = ev->canvas.x - x;
762    up_y = ev->canvas.y - y;
763
764    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
765
766    if ((!sd->hidden) && (up_x == sd->down_x) && (up_y == sd->down_y))
767      elm_panel_hidden_set(data, EINA_TRUE);
768 }
769
770 static void
771 _on_mouse_down(void *data,
772                Evas *e EINA_UNUSED,
773                Evas_Object *obj,
774                void *event_info)
775 {
776    Elm_Panel_Data *sd = data;
777    Evas_Event_Mouse_Down *ev = event_info;
778    Evas_Coord finger_size = elm_config_finger_size_get();
779    Evas_Coord x, y, w, h;
780    evas_object_geometry_get(obj, &x, &y, &w, &h);
781    Eina_Bool is_mirrored = elm_widget_mirrored_get(obj);
782
783    sd->down_x = ev->canvas.x - x;
784    sd->down_y = ev->canvas.y - y;
785
786    // if freeze state & mouse down on the edge
787    // then set timer for un-freeze
788    switch (sd->orient)
789      {
790       case ELM_PANEL_ORIENT_TOP:
791          if ((sd->freeze) && (sd->down_y >= 0) && (sd->down_y < finger_size))
792            {
793               ecore_timer_del(sd->timer);
794               sd->timer = ecore_timer_add(0.2, _timer_cb, obj);
795            }
796          break;
797       case ELM_PANEL_ORIENT_BOTTOM:
798          if ((sd->freeze) && (sd->down_y <= h) && (sd->down_y > (h - finger_size)))
799            {
800               ecore_timer_del(sd->timer);
801               sd->timer = ecore_timer_add(0.2, _timer_cb, obj);
802            }
803          break;
804       case ELM_PANEL_ORIENT_LEFT:
805          if ((!is_mirrored && (sd->freeze) && (sd->down_x >= 0) && (sd->down_x < finger_size)) ||
806               ((is_mirrored && (sd->freeze) && (sd->down_x <= w) && (sd->down_x > (w - finger_size)))))
807            {
808               ecore_timer_del(sd->timer);
809               sd->timer = ecore_timer_add(0.2, _timer_cb, obj);
810            }
811          break;
812       case ELM_PANEL_ORIENT_RIGHT:
813          if ((is_mirrored && (sd->freeze) && (sd->down_x >= 0) && (sd->down_x < finger_size)) ||
814               (!is_mirrored && (sd->freeze) && (sd->down_x <= w) && (sd->down_x > (w - finger_size))))
815            {
816               ecore_timer_del(sd->timer);
817               sd->timer = ecore_timer_add(0.2, _timer_cb, obj);
818            }
819          break;
820      }
821 }
822
823 static void
824 _on_mouse_move(void *data,
825                Evas *e EINA_UNUSED,
826                Evas_Object *obj,
827                void *event_info)
828 {
829    Elm_Panel_Data *sd = data;
830    Evas_Event_Mouse_Move *ev = event_info;
831    Evas_Coord x, y, w, h, cur_x, cur_y, finger_size;
832    evas_object_geometry_get(obj, &x, &y, &w, &h);
833    finger_size = elm_config_finger_size_get();
834    Eina_Bool is_mirrored = elm_widget_mirrored_get(obj);
835
836    cur_x = ev->cur.canvas.x - x;
837    cur_y = ev->cur.canvas.y - y;
838
839    // if mouse down on the edge (it means sd->timer is not null)
840    //    and move more than finger size
841    // then un-freeze
842    switch (sd->orient)
843      {
844       case ELM_PANEL_ORIENT_TOP:
845          if (sd->timer && ((cur_y - sd->down_y) > finger_size))
846            {
847               eo_do(obj, elm_interface_scrollable_movement_block_set
848                     (ELM_SCROLLER_MOVEMENT_NO_BLOCK));
849               sd->freeze = EINA_FALSE;
850               elm_layout_signal_emit(sd->scr_ly, "elm,state,content,visible", "elm");
851               // TIZEN_ONLY(20170613): emit signal when panel becomes draggable
852               elm_object_signal_emit(obj, "elm,state,unhold", "elm");
853               //
854            }
855          break;
856       case ELM_PANEL_ORIENT_BOTTOM:
857          if (sd->timer && ((sd->down_y - cur_y) > finger_size))
858            {
859               eo_do(obj, elm_interface_scrollable_movement_block_set
860                     (ELM_SCROLLER_MOVEMENT_NO_BLOCK));
861               sd->freeze = EINA_FALSE;
862               elm_layout_signal_emit(sd->scr_ly, "elm,state,content,visible", "elm");
863               // TIZEN_ONLY(20170613): emit signal when panel becomes draggable
864               elm_object_signal_emit(obj, "elm,state,unhold", "elm");
865               //
866            }
867          break;
868       case ELM_PANEL_ORIENT_LEFT:
869          if ((!is_mirrored && (sd->timer) && ((cur_x - sd->down_x) > finger_size)) ||
870               ((is_mirrored) && (sd->timer) && ((sd->down_x - cur_x) > finger_size)))
871            {
872               eo_do(obj, elm_interface_scrollable_movement_block_set
873                     (ELM_SCROLLER_MOVEMENT_NO_BLOCK));
874               sd->freeze = EINA_FALSE;
875               elm_layout_signal_emit(sd->scr_ly, "elm,state,content,visible", "elm");
876               // TIZEN_ONLY(20170613): emit signal when panel becomes draggable
877               elm_object_signal_emit(obj, "elm,state,unhold", "elm");
878               //
879            }
880          break;
881       case ELM_PANEL_ORIENT_RIGHT:
882          if ((is_mirrored && (sd->timer) && ((cur_x - sd->down_x) > finger_size)) ||
883               (!is_mirrored && (sd->timer) && ((sd->down_x - cur_x) > finger_size)))
884            {
885               eo_do(obj, elm_interface_scrollable_movement_block_set
886                     (ELM_SCROLLER_MOVEMENT_NO_BLOCK));
887               sd->freeze = EINA_FALSE;
888               elm_layout_signal_emit(sd->scr_ly, "elm,state,content,visible", "elm");
889               // TIZEN_ONLY(20170613): emit signal when panel becomes draggable
890               elm_object_signal_emit(obj, "elm,state,unhold", "elm");
891               //
892            }
893          break;
894      }
895
896    if (!sd->freeze && sd->hidden)
897      ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
898 }
899
900 static void
901 _on_mouse_up(void *data,
902              Evas *e EINA_UNUSED,
903              Evas_Object *obj,
904              void *event_info)
905 {
906    Elm_Panel_Data *sd = data;
907    Evas_Event_Mouse_Up *ev = event_info;
908    // TIZEN_ONLY(20170316): set hidden property when panel is close/open
909    //Evas_Coord panel_size, threshold, pos, w, h;
910    Evas_Coord w, h;
911    Eina_Bool hidden;
912
913    hidden = sd->hidden;
914    //
915
916    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
917
918    ELM_SAFE_FREE(sd->timer, ecore_timer_del);
919
920    if (_state_sync(obj)) return;
921
922    // TIZEN_ONLY(20170316): set hidden property when panel is close/open
923    /*switch (sd->orient)
924      {
925       case ELM_PANEL_ORIENT_TOP:
926          panel_size = h * sd->content_size_ratio;
927          threshold = panel_size / 4;
928          eo_do(obj, elm_interface_scrollable_content_pos_get(NULL, &pos));
929
930          if (sd->hidden)
931            {
932               if (pos < (panel_size - threshold)) _drawer_open(obj, w, h, EINA_TRUE);
933               else _drawer_close(obj, w, h, EINA_TRUE);
934            }
935          else
936            {
937               if (pos < threshold) _drawer_open(obj, w, h, EINA_TRUE);
938               else _drawer_close(obj, w, h, EINA_TRUE);
939            }
940          break;
941
942       case ELM_PANEL_ORIENT_BOTTOM:
943          panel_size = h * sd->content_size_ratio;
944          threshold = panel_size / 4;
945          eo_do(obj, elm_interface_scrollable_content_pos_get(NULL, &pos));
946
947          if (sd->hidden)
948            {
949               if (pos > threshold) _drawer_open(obj, w, h, EINA_TRUE);
950               else _drawer_close(obj, w, h, EINA_TRUE);
951            }
952          else
953            {
954               if (pos > (panel_size - threshold)) _drawer_open(obj, w, h, EINA_TRUE);
955               else _drawer_close(obj, w, h, EINA_TRUE);
956            }
957          break;
958
959       case ELM_PANEL_ORIENT_LEFT:
960          panel_size = w * sd->content_size_ratio;
961          threshold = panel_size / 4;
962          eo_do(obj, elm_interface_scrollable_content_pos_get(&pos, NULL));
963
964          if (elm_widget_mirrored_get(obj))
965            {
966               if (sd->hidden)
967                 {
968                    if (pos > threshold) _drawer_open(obj, w, h, EINA_TRUE);
969                    else _drawer_close(obj, w, h, EINA_TRUE);
970                 }
971               else
972                 {
973                    if (pos > (panel_size - threshold)) _drawer_open(obj, w, h, EINA_TRUE);
974                    else _drawer_close(obj, w, h, EINA_TRUE);
975                 }
976            }
977          else
978            {
979               if (sd->hidden)
980                 {
981                    if (pos < (panel_size - threshold)) _drawer_open(obj, w, h, EINA_TRUE);
982                    else _drawer_close(obj, w, h, EINA_TRUE);
983                 }
984               else
985                 {
986                    if (pos < threshold) _drawer_open(obj, w, h, EINA_TRUE);
987                    else _drawer_close(obj, w, h, EINA_TRUE);
988                 }
989            }
990          break;
991
992       case ELM_PANEL_ORIENT_RIGHT:
993          panel_size = w * sd->content_size_ratio;
994          threshold = panel_size / 4;
995          eo_do(obj, elm_interface_scrollable_content_pos_get(&pos, NULL));
996
997          if (!elm_widget_mirrored_get(obj))
998            {
999               if (sd->hidden)
1000                 {
1001                    if (pos > threshold) _drawer_open(obj, w, h, EINA_TRUE);
1002                    else _drawer_close(obj, w, h, EINA_TRUE);
1003                 }
1004               else
1005                 {
1006                    if (pos > (panel_size - threshold)) _drawer_open(obj, w, h, EINA_TRUE);
1007                    else _drawer_close(obj, w, h, EINA_TRUE);
1008                 }
1009            }
1010          else
1011            {
1012               if (sd->hidden)
1013                 {
1014                    if (pos < (panel_size - threshold)) _drawer_open(obj, w, h, EINA_TRUE);
1015                    else _drawer_close(obj, w, h, EINA_TRUE);
1016                 }
1017               else
1018                 {
1019                    if (pos < threshold) _drawer_open(obj, w, h, EINA_TRUE);
1020                    else _drawer_close(obj, w, h, EINA_TRUE);
1021                 }
1022            }
1023          break;
1024      }*/
1025    if (sd->hidden) _drawer_close(obj, w, h, EINA_TRUE);
1026    else _drawer_open(obj, w, h, EINA_TRUE);
1027
1028    if (sd->hidden != hidden)
1029      eo_do(obj, eo_event_callback_call(ELM_PANEL_EVENT_TOGGLED, NULL));
1030    //
1031
1032    if (!sd->freeze && sd->hidden)
1033      ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1034 }
1035
1036 static Eina_Bool
1037 _key_action_toggle(Evas_Object *obj, const char *params EINA_UNUSED)
1038 {
1039    _panel_toggle(NULL, obj, NULL, NULL);
1040    return EINA_TRUE;
1041 }
1042
1043 EOLIAN static Eina_Bool
1044 _elm_panel_elm_widget_event(Eo *obj, Elm_Panel_Data *_pd EINA_UNUSED, Evas_Object *src, Evas_Callback_Type type, void *event_info)
1045 {
1046    Evas_Event_Key_Down *ev = event_info;
1047    if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
1048    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
1049    if (src != obj) return EINA_FALSE;
1050
1051    if (!_elm_config_key_binding_call(obj, ev, key_actions)) return EINA_FALSE;
1052
1053    ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1054    return EINA_TRUE;
1055 }
1056
1057 EOLIAN static Eina_Bool
1058 _elm_panel_elm_container_content_set(Eo *obj, Elm_Panel_Data *sd, const char *part, Evas_Object *content)
1059 {
1060    if (part)
1061      {
1062         // "elm.swallow.event" part is used for internal needs and should not be changed.
1063         if (!strcmp(part, "elm.swallow.event"))
1064           {
1065              ERR("elm.swallow.event is being used for panel internally. Don't touch this part!");
1066              return EINA_FALSE;
1067           }
1068         if (strcmp(part, "default"))
1069           {
1070              Eina_Bool int_ret = EINA_TRUE;
1071              eo_do_super(obj, MY_CLASS,
1072                          int_ret = elm_obj_container_content_set(part, content));
1073
1074              return int_ret;
1075           }
1076      }
1077
1078    if (sd->content == content) return EINA_TRUE;
1079    if (sd->content)
1080      evas_object_box_remove_all(sd->bx, EINA_TRUE);
1081    sd->content = content;
1082    if (content)
1083      {
1084         evas_object_box_append(sd->bx, sd->content);
1085         evas_object_show(sd->content);
1086         if (sd->scrollable)
1087           elm_widget_sub_object_add(sd->scr_ly, sd->content);
1088         else
1089           elm_widget_sub_object_add(obj, sd->content);
1090      }
1091
1092    elm_layout_sizing_eval(obj);
1093
1094    return EINA_TRUE;
1095 }
1096
1097 EOLIAN static Evas_Object*
1098 _elm_panel_elm_container_content_get(Eo *obj, Elm_Panel_Data *sd, const char *part)
1099 {
1100    if (part)
1101      {
1102         // "elm.swallow.event" part is used for internal needs and should not be changed.
1103         if (!strcmp(part, "elm.swallow.event"))
1104           {
1105              ERR("elm.swallow.event is being used for panel internally. Don't touch this part!");
1106              return NULL;
1107           }
1108         if (strcmp(part, "default"))
1109           {
1110              Evas_Object *ret = NULL;
1111              eo_do_super(obj, MY_CLASS, ret = elm_obj_container_content_get(part));
1112              return ret;
1113           }
1114      }
1115
1116    return sd->content;
1117 }
1118
1119 EOLIAN static Evas_Object*
1120 _elm_panel_elm_container_content_unset(Eo *obj, Elm_Panel_Data *sd, const char *part)
1121 {
1122    Evas_Object *ret = NULL;
1123
1124    if (part)
1125      {
1126         // "elm.swallow.event" part is used for internal needs and should not be changed.
1127         if (!strcmp(part, "elm.swallow.event"))
1128           {
1129              ERR("elm.swallow.event is being used for panel internally. Don't touch this part!");
1130              return NULL;
1131           }
1132         if (strcmp(part, "default"))
1133           {
1134              eo_do_super(obj, MY_CLASS,
1135                          ret = elm_obj_container_content_unset(part));
1136              return ret;
1137           }
1138      }
1139
1140    if (!sd->content) return NULL;
1141    ret = sd->content;
1142
1143    evas_object_box_remove_all(sd->bx, EINA_FALSE);
1144    if (sd->scrollable)
1145      _elm_widget_sub_object_redirect_to_top(sd->scr_ly, sd->content);
1146    sd->content = NULL;
1147
1148    return ret;
1149 }
1150
1151 EOLIAN static void
1152 _elm_panel_evas_object_smart_add(Eo *obj, Elm_Panel_Data *priv)
1153 {
1154    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1155
1156    eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
1157    elm_widget_sub_object_parent_add(obj);
1158    elm_widget_can_focus_set(obj, EINA_TRUE);
1159
1160    priv->panel_edje = wd->resize_obj;
1161    // TIZEN_ONLY(20170105): scrollable panel content size ratio refactoring (for 2.4 UX)
1162    if ((elm_win_rotation_get(elm_widget_top_get(obj)) == 90) || (elm_win_rotation_get(elm_widget_top_get(obj)) == 270))
1163      priv->content_size_ratio = 0.45;
1164    else
1165      priv->content_size_ratio = 0.80;
1166    //
1167
1168    eo_do(obj, elm_obj_widget_theme_apply());
1169
1170    priv->bx = evas_object_box_add(evas_object_evas_get(obj));
1171    evas_object_box_layout_set(priv->bx, _box_layout_cb, priv, NULL);
1172    evas_object_show(priv->bx);
1173
1174    elm_layout_signal_callback_add
1175      (obj, "elm,action,panel,toggle", "*", _panel_toggle, obj);
1176
1177    _mirrored_set(obj, elm_widget_mirrored_get(obj));
1178
1179    priv->event = evas_object_rectangle_add(evas_object_evas_get(obj));
1180    evas_object_color_set(priv->event, 0, 0, 0, 0);
1181    evas_object_pass_events_set(priv->event, EINA_TRUE);
1182    elm_widget_sub_object_add(obj, priv->event);
1183
1184    /* just to bootstrap and have theme hook to work */
1185    if (!elm_layout_theme_set(obj, "panel", "top", elm_widget_style_get(obj)))
1186      CRI("Failed to set layout!");
1187    else
1188      {
1189         elm_layout_content_set(obj, "elm.swallow.content", priv->bx);
1190
1191         if (edje_object_part_exists
1192             (wd->resize_obj, "elm.swallow.event"))
1193           {
1194              Evas_Coord minw = 0, minh = 0;
1195
1196              elm_coords_finger_size_adjust(1, &minw, 1, &minh);
1197              evas_object_size_hint_min_set(priv->event, minw, minh);
1198              eo_do_super(obj, MY_CLASS, elm_obj_container_content_set("elm.swallow.event", priv->event));
1199           }
1200      }
1201
1202    elm_layout_sizing_eval(obj);
1203 }
1204
1205 EOLIAN static void
1206 _elm_panel_evas_object_smart_del(Eo *obj, Elm_Panel_Data *sd)
1207 {
1208    Evas_Object *child;
1209    Eina_List *l;
1210
1211    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1212
1213    sd->delete_me = EINA_TRUE;
1214
1215    ELM_SAFE_FREE(sd->timer, ecore_timer_del);
1216
1217    /* let's make our panel object the *last* to be processed, since it
1218     * may (smart) parent other sub objects here */
1219    EINA_LIST_FOREACH(wd->subobjs, l, child)
1220      {
1221         if (child == sd->bx)
1222           {
1223              wd->subobjs =
1224                eina_list_demote_list(wd->subobjs, l);
1225              break;
1226           }
1227      }
1228
1229    eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
1230 }
1231
1232 EOLIAN static void
1233 _elm_panel_evas_object_smart_move(Eo *obj, Elm_Panel_Data *sd, Evas_Coord x, Evas_Coord y)
1234 {
1235    eo_do_super(obj, MY_CLASS, evas_obj_smart_move(x, y));
1236
1237    evas_object_move(sd->hit_rect, x, y);
1238 }
1239
1240 static void
1241 _scrollable_layout_resize(Eo *obj, Elm_Panel_Data *sd, Evas_Coord w, Evas_Coord h)
1242 {
1243    switch (sd->orient)
1244      {
1245       case ELM_PANEL_ORIENT_TOP:
1246       case ELM_PANEL_ORIENT_BOTTOM:
1247          // vertical
1248          evas_object_resize(sd->scr_ly, w, (1 + sd->content_size_ratio) * h);
1249          evas_object_size_hint_min_set(sd->scr_panel, w, (sd->content_size_ratio * h));
1250          evas_object_size_hint_min_set(sd->scr_event, w, h);
1251          break;
1252       case ELM_PANEL_ORIENT_LEFT:
1253       case ELM_PANEL_ORIENT_RIGHT:
1254          // horizontal
1255          evas_object_resize(sd->scr_ly, (1 + sd->content_size_ratio) * w, h);
1256          evas_object_size_hint_min_set(sd->scr_panel, (sd->content_size_ratio * w), h);
1257          evas_object_size_hint_min_set(sd->scr_event, w, h);
1258          break;
1259      }
1260
1261    elm_layout_sizing_eval(obj);
1262 }
1263
1264 EOLIAN static void
1265 _elm_panel_evas_object_smart_resize(Eo *obj, Elm_Panel_Data *sd, Evas_Coord w, Evas_Coord h)
1266 {
1267    eo_do_super(obj, MY_CLASS, evas_obj_smart_resize(w, h));
1268
1269    if (!sd->scrollable) return;
1270
1271    evas_object_resize(sd->hit_rect, w, h);
1272
1273    _scrollable_layout_resize(obj, sd, w, h);
1274 }
1275
1276 EOLIAN static void
1277 _elm_panel_evas_object_smart_member_add(Eo *obj, Elm_Panel_Data *sd, Evas_Object *member)
1278 {
1279    eo_do_super(obj, MY_CLASS, evas_obj_smart_member_add(member));
1280
1281    if (sd->hit_rect) evas_object_raise(sd->hit_rect);
1282 }
1283
1284 // TIZEN_ONLY(20170105): scrollable panel content size ratio refactoring (for 2.4 UX)
1285 EOLIAN static void
1286 _elm_panel_elm_widget_orientation_set(Eo *obj, Elm_Panel_Data *sd, int orient_mode)
1287 {
1288    eo_do_super(obj, MY_CLASS, elm_obj_widget_orientation_set(orient_mode));
1289
1290    if (!sd->content_size_manual_set)
1291      {
1292         if (orient_mode == 90 || orient_mode == 270)
1293           sd->content_size_ratio = 0.45;
1294         else
1295           sd->content_size_ratio = 0.80;
1296      }
1297
1298    if (sd->scrollable)
1299      {
1300         Evas_Coord w, h;
1301         evas_object_geometry_get(obj, NULL, NULL, &w, &h);
1302
1303         _scrollable_layout_resize(obj, sd, w, h);
1304      }
1305 }
1306 //
1307
1308 EOLIAN static void
1309 _elm_panel_elm_widget_access(Eo *obj, Elm_Panel_Data *_pd, Eina_Bool is_access)
1310 {
1311    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1312    Elm_Panel_Data *sd = _pd;
1313
1314    if (sd->scrollable)
1315      {
1316         _access_obj_process(obj, is_access);
1317         return;
1318      }
1319
1320    if (is_access)
1321      _elm_access_edje_object_part_object_register
1322        (obj, wd->resize_obj, "btn_icon");
1323    else
1324      _elm_access_edje_object_part_object_unregister
1325        (obj, wd->resize_obj, "btn_icon");
1326 }
1327
1328 EAPI Evas_Object *
1329 elm_panel_add(Evas_Object *parent)
1330 {
1331    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
1332    Evas_Object *obj = eo_add(MY_CLASS, parent);
1333
1334    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
1335    wd->highlight_root = EINA_TRUE;
1336
1337    return obj;
1338 }
1339
1340 EOLIAN static Eo *
1341 _elm_panel_eo_base_constructor(Eo *obj, Elm_Panel_Data *_pd EINA_UNUSED)
1342 {
1343    obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
1344    eo_do(obj,
1345          evas_obj_type_set(MY_CLASS_NAME_LEGACY),
1346          evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
1347          elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_PANEL));
1348
1349    return obj;
1350 }
1351
1352 EOLIAN static void
1353 _elm_panel_orient_set(Eo *obj, Elm_Panel_Data *sd, Elm_Panel_Orient orient)
1354 {
1355    if (sd->orient == orient) return;
1356    sd->orient = orient;
1357
1358    if (sd->scrollable)
1359      {
1360         _scrollable_layout_theme_set(obj, sd);
1361
1362         if (!sd->freeze)
1363           {
1364              switch (sd->orient)
1365                {
1366                   case ELM_PANEL_ORIENT_TOP:
1367                   case ELM_PANEL_ORIENT_BOTTOM:
1368                      eo_do(obj, elm_interface_scrollable_movement_block_set
1369                            (ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL));
1370                      break;
1371                   case ELM_PANEL_ORIENT_LEFT:
1372                   case ELM_PANEL_ORIENT_RIGHT:
1373                      eo_do(obj, elm_interface_scrollable_movement_block_set
1374                            (ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL));
1375                      break;
1376                }
1377
1378              sd->freeze = EINA_TRUE;
1379              elm_layout_signal_emit(sd->scr_ly, "elm,state,content,hidden", "elm");
1380              // TIZEN_ONLY(20170613): emit signal when panel is hidden
1381              elm_object_signal_emit(obj, "elm,state,hold", "elm");
1382              //
1383           }
1384
1385         // TIZEN_ONLY(20170105): scrollable panel content size ratio refactoring (for 2.4 UX)
1386         //elm_panel_scrollable_content_size_set(obj, sd->content_size_ratio);
1387         Evas_Coord w, h;
1388         evas_object_geometry_get(obj, NULL, NULL, &w, &h);
1389
1390         _scrollable_layout_resize(obj, sd, w, h);
1391         //
1392      }
1393    else
1394      _orient_set_do(obj);
1395
1396    elm_layout_sizing_eval(obj);
1397 }
1398
1399 EOLIAN static Elm_Panel_Orient
1400 _elm_panel_orient_get(Eo *obj EINA_UNUSED, Elm_Panel_Data *sd)
1401 {
1402    return sd->orient;
1403 }
1404
1405 EOLIAN static void
1406 _elm_panel_hidden_set(Eo *obj, Elm_Panel_Data *sd, Eina_Bool hidden)
1407 {
1408    if (sd->hidden == !!hidden)
1409      {
1410         if (sd->scrollable && sd->hidden && !sd->freeze)
1411           {
1412              Evas_Coord w, h;
1413              evas_object_geometry_get(obj, NULL, NULL, &w, &h);
1414              _drawer_close(obj, w, h, EINA_TRUE);
1415           }
1416         return;
1417      }
1418
1419    _panel_toggle(NULL, obj, NULL, NULL);
1420 }
1421
1422 EOLIAN static Eina_Bool
1423 _elm_panel_hidden_get(Eo *obj EINA_UNUSED, Elm_Panel_Data *sd)
1424 {
1425    return sd->hidden;
1426 }
1427
1428 EOLIAN static void
1429 _elm_panel_toggle(Eo *obj, Elm_Panel_Data *_pd EINA_UNUSED)
1430 {
1431    _panel_toggle(NULL, obj, NULL, NULL);
1432 }
1433
1434 EOLIAN static Eina_Bool
1435 _elm_panel_elm_widget_on_focus_region(Eo *obj,
1436                                       Elm_Panel_Data *sd,
1437                                       Evas_Coord *x,
1438                                       Evas_Coord *y,
1439                                       Evas_Coord *w,
1440                                       Evas_Coord *h)
1441 {
1442    eo_do(obj, elm_interface_scrollable_content_pos_get(x, y));
1443    evas_object_geometry_get(obj, NULL, NULL, w, h);
1444    switch (sd->orient)
1445      {
1446       case ELM_PANEL_ORIENT_TOP:
1447       case ELM_PANEL_ORIENT_BOTTOM:
1448          *h = *h * sd->content_size_ratio;
1449          break;
1450       case ELM_PANEL_ORIENT_LEFT:
1451       case ELM_PANEL_ORIENT_RIGHT:
1452          *w = *w * sd->content_size_ratio;
1453          break;
1454      }
1455    return EINA_TRUE;
1456 }
1457
1458 static void
1459 _anim_stop_cb(Evas_Object *obj, void *data EINA_UNUSED)
1460 {
1461    // TIZEN_ONLY(20170316): set hidden property when panel is close/open
1462    /*if (elm_widget_disabled_get(obj)) return;
1463    _state_sync(obj);*/
1464
1465    ELM_PANEL_DATA_GET(obj, sd);
1466    Evas_Object *ao;
1467    Evas_Coord pos, w, h, panel_size = 0;
1468    Eina_Bool open = EINA_FALSE, horizontal = EINA_FALSE, reverse = EINA_FALSE;
1469
1470    if (elm_widget_disabled_get(obj)) return;
1471
1472    switch (sd->orient)
1473      {
1474       case ELM_PANEL_ORIENT_BOTTOM:
1475          reverse = EINA_TRUE;
1476       case ELM_PANEL_ORIENT_TOP:
1477          break;
1478
1479       case ELM_PANEL_ORIENT_RIGHT:
1480          reverse = EINA_TRUE;
1481       case ELM_PANEL_ORIENT_LEFT:
1482          horizontal = EINA_TRUE;
1483          break;
1484      }
1485
1486    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
1487    if (horizontal)
1488      {
1489          if (w <= 0) return;
1490
1491          panel_size = w * sd->content_size_ratio;
1492          eo_do(obj, elm_interface_scrollable_content_pos_get(&pos, NULL));
1493          reverse ^= elm_widget_mirrored_get(obj);
1494      }
1495    else
1496      {
1497          if (h <= 0) return;
1498
1499          panel_size = h * sd->content_size_ratio;
1500          eo_do(obj, elm_interface_scrollable_content_pos_get(NULL, &pos));
1501      }
1502
1503    if (pos == 0) open = !reverse;
1504    else if (pos == panel_size) open = reverse;
1505    else return;
1506
1507    if (open)
1508      {
1509         eo_do(obj, elm_interface_scrollable_single_direction_set
1510               (ELM_SCROLLER_SINGLE_DIRECTION_HARD));
1511
1512         //focus & access
1513         elm_object_tree_focus_allow_set(obj, EINA_TRUE);
1514         if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
1515           {
1516              ao = _access_object_get(obj, ACCESS_OUTLINE_PART);
1517              evas_object_show(ao);
1518              _elm_access_highlight_set(ao);
1519           }
1520         else
1521           elm_object_focus_set(obj, EINA_TRUE);
1522      }
1523    else
1524      {
1525         if (horizontal)
1526           eo_do(obj, elm_interface_scrollable_movement_block_set
1527                 (ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL));
1528         else
1529           eo_do(obj, elm_interface_scrollable_movement_block_set
1530                 (ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL));
1531         sd->freeze = EINA_TRUE;
1532         elm_layout_signal_emit(sd->scr_ly, "elm,state,content,hidden", "elm");
1533         // TIZEN_ONLY(20170613): emit signal when panel is hidden
1534         elm_object_signal_emit(obj, "elm,state,hold", "elm");
1535         //
1536
1537         eo_do(obj, elm_interface_scrollable_single_direction_set
1538               (ELM_SCROLLER_SINGLE_DIRECTION_NONE));
1539
1540         //focus & access
1541         elm_object_tree_focus_allow_set(obj, EINA_FALSE);
1542         if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
1543           {
1544              ao = _access_object_get(obj, ACCESS_OUTLINE_PART);
1545              evas_object_hide(ao);
1546           }
1547      }
1548    //
1549 }
1550
1551 static void
1552 _scroll_cb(Evas_Object *obj, void *data EINA_UNUSED)
1553 {
1554    ELM_PANEL_DATA_GET(obj, sd);
1555    Elm_Panel_Scroll_Info event;
1556    Evas_Coord x, y, w, h;
1557
1558    if (elm_widget_disabled_get(obj)) return;
1559    // in the case of
1560    // freeze_set(FALSE) -> mouse_up -> freeze_set(TRUE) -> scroll
1561    if (sd->freeze)
1562      {
1563         eo_do(obj, elm_interface_scrollable_movement_block_set
1564               (ELM_SCROLLER_MOVEMENT_NO_BLOCK));
1565         sd->freeze = EINA_FALSE;
1566         elm_layout_signal_emit(sd->scr_ly, "elm,state,content,visible", "elm");
1567         // TIZEN_ONLY(20170613): emit signal when panel becomes draggable
1568         elm_object_signal_emit(obj, "elm,state,unhold", "elm");
1569         //
1570      }
1571
1572    eo_do(obj, elm_interface_scrollable_content_pos_get(&x, &y));
1573    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
1574
1575    switch (sd->orient)
1576      {
1577       case ELM_PANEL_ORIENT_TOP:
1578          event.rel_x = 1;
1579          event.rel_y = 1 - ((double) y / (double) ((sd->content_size_ratio) * h));
1580         break;
1581       case ELM_PANEL_ORIENT_BOTTOM:
1582          event.rel_x = 1;
1583          event.rel_y = (double) y / (double) ((sd->content_size_ratio) * h);
1584         break;
1585       case ELM_PANEL_ORIENT_LEFT:
1586         if (!elm_widget_mirrored_get(obj))
1587           {
1588              event.rel_x = 1 - ((double) x / (double) ((sd->content_size_ratio) * w));
1589              event.rel_y = 1;
1590           }
1591         else
1592           {
1593              event.rel_x = (double) x / (double) ((sd->content_size_ratio) * w);
1594              event.rel_y = 1;
1595            }
1596         break;
1597       case ELM_PANEL_ORIENT_RIGHT:
1598         if (elm_widget_mirrored_get(obj))
1599           {
1600              event.rel_x = 1 - ((double) x / (double) ((sd->content_size_ratio) * w));
1601              event.rel_y = 1;
1602           }
1603         else
1604           {
1605              event.rel_x = (double) x / (double) ((sd->content_size_ratio) * w);
1606              event.rel_y = 1;
1607           }
1608         break;
1609      }
1610    eo_do(obj, eo_event_callback_call
1611      (EVAS_SCROLLABLE_INTERFACE_EVENT_SCROLL, (void *) &event));
1612 }
1613
1614 EOLIAN static Eina_Bool
1615 _elm_panel_elm_widget_disable(Eo *obj, Elm_Panel_Data *sd)
1616 {
1617    Eina_Bool int_ret = EINA_FALSE;
1618    eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_disable());
1619    if (!int_ret) return EINA_FALSE;
1620
1621    if (sd->scrollable)
1622      {
1623         if (elm_widget_disabled_get(obj))
1624           {
1625              evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_DOWN,
1626                                             _on_mouse_down);
1627              evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_MOVE,
1628                                             _on_mouse_move);
1629              evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_UP,
1630                                             _on_mouse_up);
1631              evas_object_event_callback_del(sd->scr_event, EVAS_CALLBACK_MOUSE_UP,
1632                                             _event_mouse_up);
1633           }
1634         else
1635           {
1636              evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN,
1637                                             _on_mouse_down, sd);
1638              evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_MOVE,
1639                                             _on_mouse_move, sd);
1640              evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_UP,
1641                                             _on_mouse_up, sd);
1642              evas_object_event_callback_add(sd->scr_event, EVAS_CALLBACK_MOUSE_UP,
1643                                             _event_mouse_up, obj);
1644           }
1645      }
1646
1647    return EINA_TRUE;
1648 }
1649
1650 EOLIAN static double
1651 _elm_panel_scrollable_content_size_get(Eo *obj EINA_UNUSED, Elm_Panel_Data *sd)
1652 {
1653    return sd->content_size_ratio;
1654 }
1655
1656 EOLIAN static void
1657 _elm_panel_scrollable_content_size_set(Eo *obj, Elm_Panel_Data *sd, double ratio)
1658 {
1659    if (ratio < 0) ratio = 0;
1660    else if (ratio > 1.0) ratio = 1.0;
1661
1662    sd->content_size_ratio = ratio;
1663    // TIZEN_ONLY(20170105): scrollable panel content size ratio refactoring (for 2.4 UX)
1664    sd->content_size_manual_set = EINA_TRUE;
1665    //
1666
1667    if (sd->scrollable)
1668      {
1669         Evas_Coord w, h;
1670         evas_object_geometry_get(obj, NULL, NULL, &w, &h);
1671
1672         _scrollable_layout_resize(obj, sd, w, h);
1673      }
1674 }
1675
1676 EOLIAN static Eina_Bool
1677 _elm_panel_scrollable_get(Eo *obj EINA_UNUSED, Elm_Panel_Data *sd)
1678 {
1679    return sd->scrollable;
1680 }
1681
1682 EOLIAN static void
1683 _elm_panel_scrollable_set(Eo *obj, Elm_Panel_Data *sd, Eina_Bool scrollable)
1684 {
1685    scrollable = !!scrollable;
1686    if (sd->scrollable == scrollable) return;
1687    sd->scrollable = scrollable;
1688
1689    if (scrollable)
1690      {
1691         // TIZEN_ONLY(20170309): initialize repeat_events when scrollable is set.
1692         evas_object_repeat_events_set(obj, EINA_FALSE);
1693         //
1694         elm_layout_content_unset(obj, "elm.swallow.content");
1695
1696         elm_widget_resize_object_set(obj, NULL, EINA_TRUE);
1697         elm_widget_sub_object_add(obj, sd->panel_edje);
1698
1699         if (!sd->scr_edje)
1700           {
1701              const char *handler_size;
1702
1703              sd->scr_edje = edje_object_add(evas_object_evas_get(obj));
1704              elm_widget_theme_object_set(obj, sd->scr_edje, "scroller", "panel",
1705                                          elm_widget_style_get(obj));
1706              evas_object_size_hint_weight_set
1707                 (sd->scr_edje, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1708              evas_object_size_hint_align_set
1709                 (sd->scr_edje, EVAS_HINT_FILL, EVAS_HINT_FILL);
1710
1711              handler_size = edje_object_data_get(sd->scr_edje, "handler_size");
1712              if (handler_size)
1713                sd->handler_size = (int) (elm_object_scale_get(obj)) * (atoi(handler_size));
1714           }
1715
1716         elm_widget_resize_object_set(obj, sd->scr_edje, EINA_TRUE);
1717
1718         if (!sd->hit_rect)
1719           {
1720              sd->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
1721              evas_object_smart_member_add(sd->hit_rect, obj);
1722              elm_widget_sub_object_add(obj, sd->hit_rect);
1723              evas_object_color_set(sd->hit_rect, 0, 0, 0, 0);
1724              evas_object_show(sd->hit_rect);
1725              evas_object_repeat_events_set(sd->hit_rect, EINA_TRUE);
1726
1727              eo_do(obj,
1728                    elm_interface_scrollable_objects_set(sd->scr_edje, sd->hit_rect),
1729                    elm_interface_scrollable_animate_stop_cb_set(_anim_stop_cb),
1730                    elm_interface_scrollable_scroll_cb_set(_scroll_cb));
1731           }
1732
1733         if (!sd->scr_ly)
1734           {
1735              sd->scr_ly = elm_layout_add(obj);
1736              evas_object_smart_member_add(sd->scr_ly, obj);
1737              elm_widget_sub_object_add(obj, sd->scr_ly);
1738              _scrollable_layout_theme_set(obj, sd);
1739
1740              sd->scr_panel = evas_object_rectangle_add(evas_object_evas_get(obj));
1741              evas_object_color_set(sd->scr_panel, 0, 0, 0, 0);
1742              elm_widget_sub_object_add(obj, sd->scr_panel);
1743              elm_layout_content_set(sd->scr_ly, "panel_area", sd->scr_panel);
1744
1745              sd->scr_event = evas_object_rectangle_add(evas_object_evas_get(obj));
1746              evas_object_color_set(sd->scr_event, 0, 0, 0, 0);
1747              elm_widget_sub_object_add(obj, sd->scr_event);
1748              elm_layout_content_set(sd->scr_ly, "event_area", sd->scr_event);
1749           }
1750
1751         eo_do(obj,
1752               elm_interface_scrollable_content_set(sd->scr_ly));
1753         sd->freeze = EINA_TRUE;
1754         elm_layout_content_set(sd->scr_ly, "elm.swallow.content", sd->bx);
1755         if (sd->content) elm_widget_sub_object_add(sd->scr_ly, sd->content);
1756
1757         // TIZEN_ONLY(20170105): scrollable panel content size ratio refactoring (for 2.4 UX)
1758         Evas_Coord w, h;
1759         evas_object_geometry_get(obj, NULL, NULL, &w, &h);
1760
1761         _scrollable_layout_resize(obj, sd, w, h);
1762         //
1763
1764         switch (sd->orient)
1765           {
1766            case ELM_PANEL_ORIENT_TOP:
1767            case ELM_PANEL_ORIENT_BOTTOM:
1768               eo_do(obj, elm_interface_scrollable_movement_block_set
1769                     (ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL));
1770               break;
1771            case ELM_PANEL_ORIENT_LEFT:
1772            case ELM_PANEL_ORIENT_RIGHT:
1773               eo_do(obj, elm_interface_scrollable_movement_block_set
1774                     (ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL));
1775               break;
1776           }
1777
1778         eo_do(obj, elm_interface_scrollable_single_direction_set
1779               (ELM_SCROLLER_SINGLE_DIRECTION_NONE));
1780
1781         if (!elm_widget_disabled_get(obj))
1782           {
1783              evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN,
1784                                             _on_mouse_down, sd);
1785              evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_MOVE,
1786                                             _on_mouse_move, sd);
1787              evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_UP,
1788                                             _on_mouse_up, sd);
1789              evas_object_event_callback_add(sd->scr_event, EVAS_CALLBACK_MOUSE_UP,
1790                                             _event_mouse_up, obj);
1791           }
1792
1793      }
1794    else
1795      {
1796         eo_do(obj, elm_interface_scrollable_content_set(NULL));
1797
1798         evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_DOWN, _on_mouse_down);
1799         evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_MOVE, _on_mouse_move);
1800         evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_UP, _on_mouse_up);
1801         evas_object_event_callback_del(sd->scr_event, EVAS_CALLBACK_MOUSE_UP,
1802                                        _event_mouse_up);
1803
1804         elm_widget_resize_object_set(obj, NULL, EINA_TRUE);
1805         elm_widget_sub_object_add(obj, sd->scr_edje);
1806
1807         elm_widget_resize_object_set(obj, sd->panel_edje, EINA_TRUE);
1808
1809         elm_layout_content_unset(sd->scr_ly, "elm.swallow.content");
1810         elm_layout_content_set(obj, "elm.swallow.content", sd->bx);
1811         if (sd->content) elm_widget_sub_object_add(obj, sd->content);
1812      }
1813 }
1814
1815 static void
1816 _elm_panel_class_constructor(Eo_Class *klass)
1817 {
1818    evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
1819 }
1820
1821 EOLIAN const Elm_Atspi_Action *
1822 _elm_panel_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Panel_Data *pd EINA_UNUSED)
1823 {
1824    static Elm_Atspi_Action atspi_actions[] = {
1825           { "toggle", "toggle", NULL, _key_action_toggle},
1826           { NULL, NULL, NULL, NULL }
1827    };
1828    return &atspi_actions[0];
1829 }
1830
1831 // TIZEN_ONLY(20170829) : [atspi][panel] Adds accessibility support for the panel widget.
1832 EOLIAN static Elm_Atspi_State_Set
1833 _elm_panel_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Panel_Data *sd EINA_UNUSED)
1834 {
1835    Elm_Atspi_State_Set ret;
1836    eo_do_super(obj, MY_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
1837
1838    if (!sd->hidden)
1839       STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SHOWING);
1840    else
1841       STATE_TYPE_UNSET(ret, ELM_ATSPI_STATE_SHOWING);
1842
1843    STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MODAL);
1844
1845    return ret;
1846 }
1847 //
1848 #include "elm_panel.eo.c"