2 # include "elementary_config.h"
5 #define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
6 #define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED
8 #include <Elementary.h>
11 #include "elm_widget_panel.h"
15 #define MY_CLASS ELM_PANEL_CLASS
17 #define MY_CLASS_NAME "Elm_Panel"
18 #define MY_CLASS_NAME_LEGACY "elm_panel"
20 static const char ACCESS_OUTLINE_PART[] = "access.outline";
22 static const char SIG_SCROLL[] = "scroll";
24 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
26 {SIG_LAYOUT_FOCUSED, ""}, /**< handled by elm_layout */
27 {SIG_LAYOUT_UNFOCUSED, ""}, /**< handled by elm_layout */
31 static Eina_Bool _key_action_toggle(Evas_Object *obj, const char *params);
33 static const Elm_Action key_actions[] = {
34 {"toggle", _key_action_toggle},
39 _mirrored_set(Evas_Object *obj,
42 ELM_PANEL_DATA_GET(obj, sd);
44 if ((sd->content) && (eo_isa(sd->content, ELM_WIDGET_CLASS)))
45 elm_widget_mirrored_set(sd->content, rtl);
46 elm_panel_orient_set(obj, elm_panel_orient_get(obj));
50 _elm_panel_elm_layout_sizing_eval(Eo *obj, Elm_Panel_Data *sd)
52 Evas_Coord mw = -1, mh = -1;
54 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
56 if (sd->delete_me) return;
58 evas_object_smart_calculate(sd->bx);
59 edje_object_size_min_calc(wd->resize_obj, &mw, &mh);
60 evas_object_size_hint_min_set(obj, mw, mh);
61 evas_object_size_hint_max_set(obj, -1, -1);
65 _access_state_cb(void *data, Evas_Object *obj EINA_UNUSED)
67 ELM_PANEL_DATA_GET(data, sd);
69 if (!sd->hidden) return strdup(E_("state: opened"));
70 else return strdup(E_("state: closed"));
76 _access_object_get(const Evas_Object *obj, const char *part)
79 ELM_PANEL_DATA_GET(obj, sd);
81 po = (Evas_Object *)edje_object_part_object_get
82 (elm_layout_edje_get(sd->scr_ly), part);
83 ao = evas_object_data_get(po, "_part_access_obj");
89 _access_activate_cb(void *data,
90 Evas_Object *part_obj EINA_UNUSED,
91 Elm_Object_Item *item EINA_UNUSED)
93 elm_panel_hidden_set(data, EINA_TRUE);
97 _access_obj_process(Evas_Object *obj, Eina_Bool is_access)
100 ELM_PANEL_DATA_GET(obj, sd);
104 ao = _access_object_get(obj, ACCESS_OUTLINE_PART);
107 ao = _elm_access_edje_object_part_object_register
108 (obj, elm_layout_edje_get(sd->scr_ly), ACCESS_OUTLINE_PART);
109 _elm_access_text_set(_elm_access_info_get(ao),
110 ELM_ACCESS_TYPE, E_("A panel is open"));
111 _elm_access_text_set(_elm_access_info_get(ao),
112 ELM_ACCESS_CONTEXT_INFO, E_("Double tap to close panel menu"));
113 _elm_access_activate_callback_set
114 (_elm_access_info_get(ao), _access_activate_cb, obj);
119 _elm_access_edje_object_part_object_unregister
120 (obj, elm_layout_edje_get(sd->scr_ly), ACCESS_OUTLINE_PART);
125 _orient_set_do(Evas_Object *obj)
127 ELM_PANEL_DATA_GET(obj, sd);
128 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
132 case ELM_PANEL_ORIENT_TOP:
133 if (!elm_layout_theme_set
134 (obj, "panel", "top", elm_widget_style_get(obj)))
135 ERR("Failed to set layout!");
138 case ELM_PANEL_ORIENT_BOTTOM:
139 if (!elm_layout_theme_set
140 (obj, "panel", "bottom", elm_widget_style_get(obj)))
141 ERR("Failed to set layout!");
144 case ELM_PANEL_ORIENT_LEFT:
145 if (!elm_widget_mirrored_get(obj))
147 if (!elm_layout_theme_set
148 (obj, "panel", "left", elm_widget_style_get(obj)))
149 ERR("Failed to set layout!");
153 if (!elm_layout_theme_set
154 (obj, "panel", "right", elm_widget_style_get(obj)))
155 ERR("Failed to set layout!");
159 case ELM_PANEL_ORIENT_RIGHT:
160 if (!elm_widget_mirrored_get(obj))
162 if (!elm_layout_theme_set
163 (obj, "panel", "right", elm_widget_style_get(obj)))
164 ERR("Failed to set layout!");
168 if (!elm_layout_theme_set
169 (obj, "panel", "left", elm_widget_style_get(obj)))
170 ERR("Failed to set layout!");
176 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
179 ao = _elm_access_edje_object_part_object_register
180 (obj, wd->resize_obj, "btn_icon");
181 _elm_access_text_set(_elm_access_info_get(ao),
182 ELM_ACCESS_TYPE, E_("panel button"));
183 _elm_access_callback_set
184 (_elm_access_info_get(ao), ELM_ACCESS_STATE, _access_state_cb, obj);
189 _scrollable_layout_theme_set(Eo *obj, Elm_Panel_Data *sd)
193 case ELM_PANEL_ORIENT_TOP:
194 if (!elm_layout_theme_set(sd->scr_ly, "scroller", "panel/top",
195 elm_widget_style_get(obj)))
196 ERR("Failed to set layout!");
198 case ELM_PANEL_ORIENT_BOTTOM:
199 if (!elm_layout_theme_set(sd->scr_ly, "scroller", "panel/bottom",
200 elm_widget_style_get(obj)))
201 ERR("Failed to set layout!");
203 case ELM_PANEL_ORIENT_LEFT:
204 if (!elm_layout_theme_set(sd->scr_ly, "scroller", "panel/left",
205 elm_widget_style_get(obj)))
206 ERR("Failed to set layout!");
208 case ELM_PANEL_ORIENT_RIGHT:
209 if (!elm_layout_theme_set(sd->scr_ly, "scroller", "panel/right",
210 elm_widget_style_get(obj)))
211 ERR("Failed to set layout!");
216 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
217 _access_obj_process(obj, EINA_TRUE);
220 EOLIAN static Eina_Bool
221 _elm_panel_elm_widget_theme_apply(Eo *obj, Elm_Panel_Data *sd)
224 Evas_Coord minw = 0, minh = 0;
226 Eina_Bool int_ret = EINA_FALSE;
228 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
230 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_theme_apply());
231 if (!int_ret) return EINA_FALSE;
233 _mirrored_set(obj, elm_widget_mirrored_get(obj));
237 const char *handler_size;
238 elm_widget_theme_object_set(obj, sd->scr_edje, "scroller", "panel",
239 elm_widget_style_get(obj));
240 _scrollable_layout_theme_set(obj, sd);
242 handler_size = edje_object_data_get(sd->scr_edje, "handler_size");
244 sd->handler_size = (int) (elm_object_scale_get(obj)) * (atoi(handler_size));
248 str = edje_object_data_get
249 (wd->resize_obj, "focus_highlight");
250 if ((str) && (!strcmp(str, "on")))
251 elm_widget_highlight_in_theme_set(obj, EINA_TRUE);
253 elm_widget_highlight_in_theme_set(obj, EINA_FALSE);
257 evas_object_hide(sd->event);
258 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
259 evas_object_size_hint_min_set(sd->event, minw, minh);
261 if (edje_object_part_exists
262 (wd->resize_obj, "elm.swallow.event"))
263 eo_do_super(obj, MY_CLASS, elm_obj_container_content_set("elm.swallow.event", sd->event));
266 elm_layout_sizing_eval(obj);
271 EOLIAN static Eina_Bool
272 _elm_panel_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Panel_Data *_pd EINA_UNUSED)
277 EOLIAN static Eina_Bool
278 _elm_panel_elm_widget_focus_next(Eo *obj, Elm_Panel_Data *sd, Elm_Focus_Direction dir, Evas_Object **next)
281 Eina_List *items = NULL;
282 Eina_Bool ret = EINA_FALSE;
284 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
286 if (!sd->content) return EINA_FALSE;
290 if (sd->hidden) return EINA_FALSE;
292 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
294 Evas_Object *ao = _access_object_get(obj, ACCESS_OUTLINE_PART);
295 if (ao) items = eina_list_append(items, ao);
296 items = eina_list_append(items, sd->content);
298 ret = elm_widget_focus_list_next_get
299 (obj, items, eina_list_data_get, dir, next);
300 eina_list_free(items);
305 return elm_widget_focus_next_get(sd->content, dir, next);
310 /* Try to Focus cycle in subitem */
311 if (!sd->hidden) return elm_widget_focus_next_get(cur, dir, next);
314 if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF)
316 Evas_Object *ao, *po;
317 po = (Evas_Object *)edje_object_part_object_get
318 (wd->resize_obj, "btn_icon");
319 ao = evas_object_data_get(po, "_part_access_obj");
320 _elm_access_highlight_set(ao);
324 *next = (Evas_Object *)obj;
325 return !elm_widget_focus_get(obj);
329 _box_layout_cb(Evas_Object *o,
330 Evas_Object_Box_Data *priv,
331 void *data EINA_UNUSED)
333 _els_box_layout(o, priv, EINA_TRUE, EINA_FALSE, EINA_FALSE);
337 _handler_open(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
339 ELM_PANEL_DATA_GET(obj, sd);
341 if (sd->handler_size == 0) return;
345 case ELM_PANEL_ORIENT_TOP:
346 eo_do(obj, elm_interface_scrollable_region_bring_in
347 (0, (h * sd->content_size_ratio) - sd->handler_size, w, h));
349 case ELM_PANEL_ORIENT_BOTTOM:
350 eo_do(obj, elm_interface_scrollable_region_bring_in
351 (0, sd->handler_size, w, h));
353 case ELM_PANEL_ORIENT_LEFT:
354 eo_do(obj, elm_interface_scrollable_region_bring_in
355 ((w * sd->content_size_ratio) - sd->handler_size, 0, w, h));
357 case ELM_PANEL_ORIENT_RIGHT:
358 eo_do(obj, elm_interface_scrollable_region_bring_in
359 (sd->handler_size, 0, w, h));
365 _drawer_open(Evas_Object *obj, Evas_Coord w, Evas_Coord h, Eina_Bool anim)
367 ELM_PANEL_DATA_GET(obj, sd);
372 eo_do(obj, elm_interface_scrollable_movement_block_set
373 (ELM_SCROLLER_MOVEMENT_NO_BLOCK));
374 sd->freeze = EINA_FALSE;
375 elm_layout_signal_emit(sd->scr_ly, "elm,state,content,visible", "elm");
380 case ELM_PANEL_ORIENT_TOP:
381 case ELM_PANEL_ORIENT_LEFT:
384 case ELM_PANEL_ORIENT_BOTTOM:
385 y = h * sd->content_size_ratio;
388 case ELM_PANEL_ORIENT_RIGHT:
389 x = w * sd->content_size_ratio;
394 eo_do(obj, elm_interface_scrollable_region_bring_in
397 eo_do(obj, elm_interface_scrollable_content_region_show
402 _drawer_close(Evas_Object *obj, Evas_Coord w, Evas_Coord h, Eina_Bool anim)
404 ELM_PANEL_DATA_GET(obj, sd);
406 Eina_Bool horizontal = EINA_FALSE;
410 case ELM_PANEL_ORIENT_TOP:
411 y = h * sd->content_size_ratio;
414 case ELM_PANEL_ORIENT_LEFT:
415 x = w * sd->content_size_ratio;
416 horizontal = EINA_TRUE;
419 case ELM_PANEL_ORIENT_BOTTOM:
421 case ELM_PANEL_ORIENT_RIGHT:
422 horizontal = EINA_TRUE;
430 eo_do(obj, elm_interface_scrollable_movement_block_set
431 (ELM_SCROLLER_MOVEMENT_NO_BLOCK));
432 sd->freeze = EINA_FALSE;
433 elm_layout_signal_emit(sd->scr_ly, "elm,state,content,visible", "elm");
435 eo_do(obj, elm_interface_scrollable_region_bring_in(x, y, w, h));
439 eo_do(obj, elm_interface_scrollable_content_region_show(x, y, w, h));
443 eo_do(obj, elm_interface_scrollable_movement_block_set
444 (ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL));
446 eo_do(obj, elm_interface_scrollable_movement_block_set
447 (ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL));
448 sd->freeze = EINA_TRUE;
449 elm_layout_signal_emit(sd->scr_ly, "elm,state,content,hidden", "elm");
455 _panel_toggle(void *data EINA_UNUSED,
457 const char *emission EINA_UNUSED,
458 const char *source EINA_UNUSED)
460 ELM_PANEL_DATA_GET(obj, sd);
461 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
466 if (elm_widget_disabled_get(obj)) return;
468 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
471 sd->hidden = EINA_FALSE;
472 _drawer_open(obj, w, h, EINA_TRUE);
476 sd->hidden = EINA_TRUE;
477 _drawer_close(obj, w, h, EINA_TRUE);
484 elm_layout_signal_emit(obj, "elm,action,show", "elm");
485 sd->hidden = EINA_FALSE;
486 evas_object_repeat_events_set(obj, EINA_FALSE);
490 elm_layout_signal_emit(obj, "elm,action,hide", "elm");
491 sd->hidden = EINA_TRUE;
492 evas_object_repeat_events_set(obj, EINA_TRUE);
493 if (sd->content && elm_widget_focus_get(sd->content))
495 elm_widget_focused_object_clear(obj);
496 elm_widget_focus_steal(obj);
500 edje_object_message_signal_process(wd->resize_obj);
505 _state_sync(Evas_Object *obj)
507 ELM_PANEL_DATA_GET(obj, sd);
509 Evas_Coord pos, panel_size, w, h;
510 Eina_Bool open = EINA_FALSE, horizontal = EINA_FALSE;
511 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
515 case ELM_PANEL_ORIENT_TOP:
516 panel_size = h * sd->content_size_ratio;
517 eo_do(obj, elm_interface_scrollable_content_pos_get(NULL, &pos));
519 if (pos == 0) open = EINA_TRUE;
520 else if (pos == panel_size) open = EINA_FALSE;
521 else return EINA_FALSE;
524 case ELM_PANEL_ORIENT_BOTTOM:
525 panel_size = h * sd->content_size_ratio;
526 eo_do(obj, elm_interface_scrollable_content_pos_get(NULL, &pos));
528 if (pos == panel_size) open = EINA_TRUE;
529 else if (pos == 0) open = EINA_FALSE;
530 else return EINA_FALSE;
533 case ELM_PANEL_ORIENT_LEFT:
534 panel_size = w * sd->content_size_ratio;
535 eo_do(obj, elm_interface_scrollable_content_pos_get(&pos, NULL));
536 horizontal = EINA_TRUE;
538 if (pos == 0) open = EINA_TRUE;
539 else if (pos == panel_size) open = EINA_FALSE;
540 else return EINA_FALSE;
543 case ELM_PANEL_ORIENT_RIGHT:
544 panel_size = w * sd->content_size_ratio;
545 eo_do(obj, elm_interface_scrollable_content_pos_get(&pos, NULL));
546 horizontal = EINA_TRUE;
548 if (pos == panel_size) open = EINA_TRUE;
549 else if (pos == 0) open = EINA_FALSE;
550 else return EINA_FALSE;
556 if (sd->hidden) sd->hidden = EINA_FALSE;
557 eo_do(obj, elm_interface_scrollable_single_direction_set
558 (ELM_SCROLLER_SINGLE_DIRECTION_HARD));
561 elm_object_tree_focus_allow_set(obj, EINA_TRUE);
562 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
564 ao = _access_object_get(obj, ACCESS_OUTLINE_PART);
565 evas_object_show(ao);
566 _elm_access_highlight_set(ao);
569 elm_object_focus_set(obj, EINA_TRUE);
573 if (!sd->hidden) sd->hidden = EINA_TRUE;
576 eo_do(obj, elm_interface_scrollable_movement_block_set
577 (ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL));
579 eo_do(obj, elm_interface_scrollable_movement_block_set
580 (ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL));
581 sd->freeze = EINA_TRUE;
582 elm_layout_signal_emit(sd->scr_ly, "elm,state,content,hidden", "elm");
584 eo_do(obj, elm_interface_scrollable_single_direction_set
585 (ELM_SCROLLER_SINGLE_DIRECTION_NONE));
588 elm_object_tree_focus_allow_set(obj, EINA_FALSE);
589 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
591 ao = _access_object_get(obj, ACCESS_OUTLINE_PART);
592 evas_object_hide(ao);
600 _timer_cb(void *data)
602 ELM_PANEL_DATA_GET(data, sd);
603 Evas_Object *obj = data;
610 eo_do(obj, elm_interface_scrollable_movement_block_set
611 (ELM_SCROLLER_MOVEMENT_NO_BLOCK));
612 sd->freeze = EINA_FALSE;
613 elm_layout_signal_emit(sd->scr_ly, "elm,state,content,visible", "elm");
614 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
615 _handler_open(obj, w, h);
618 return ECORE_CALLBACK_CANCEL;
622 _event_mouse_up(void *data,
624 Evas_Object *obj EINA_UNUSED,
627 ELM_PANEL_DATA_GET(data, sd);
628 Evas_Event_Mouse_Up *ev = event_info;
629 Evas_Coord x, y, up_x, up_y, minw = 0, minh = 0;
630 evas_object_geometry_get(data, &x, &y, NULL, NULL);
632 up_x = ev->canvas.x - x;
633 up_y = ev->canvas.y - y;
635 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
637 if ((!sd->hidden) && (up_x == sd->down_x) && (up_y == sd->down_y))
638 elm_panel_hidden_set(data, EINA_TRUE);
642 _on_mouse_down(void *data,
647 Elm_Panel_Data *sd = data;
648 Evas_Event_Mouse_Down *ev = event_info;
649 Evas_Coord finger_size = elm_config_finger_size_get();
650 Evas_Coord x, y, w, h;
651 evas_object_geometry_get(obj, &x, &y, &w, &h);
653 sd->down_x = ev->canvas.x - x;
654 sd->down_y = ev->canvas.y - y;
656 // if freeze state & mouse down on the edge
657 // then set timer for un-freeze
660 case ELM_PANEL_ORIENT_TOP:
661 if ((sd->freeze) && (sd->down_y >= 0) && (sd->down_y < finger_size))
663 ecore_timer_del(sd->timer);
664 sd->timer = ecore_timer_add(0.2, _timer_cb, obj);
667 case ELM_PANEL_ORIENT_BOTTOM:
668 if ((sd->freeze) && (sd->down_y <= h) && (sd->down_y > (h - finger_size)))
670 ecore_timer_del(sd->timer);
671 sd->timer = ecore_timer_add(0.2, _timer_cb, obj);
674 case ELM_PANEL_ORIENT_LEFT:
675 if ((sd->freeze) && (sd->down_x >= 0) && (sd->down_x < finger_size))
677 ecore_timer_del(sd->timer);
678 sd->timer = ecore_timer_add(0.2, _timer_cb, obj);
681 case ELM_PANEL_ORIENT_RIGHT:
682 if ((sd->freeze) && (sd->down_x <= w) && (sd->down_x > (w - finger_size)))
684 ecore_timer_del(sd->timer);
685 sd->timer = ecore_timer_add(0.2, _timer_cb, obj);
692 _on_mouse_move(void *data,
697 Elm_Panel_Data *sd = data;
698 Evas_Event_Mouse_Move *ev = event_info;
699 Evas_Coord x, y, w, h, cur_x, cur_y, finger_size;
700 evas_object_geometry_get(obj, &x, &y, &w, &h);
701 finger_size = elm_config_finger_size_get();
703 cur_x = ev->cur.canvas.x - x;
704 cur_y = ev->cur.canvas.y - y;
706 // if mouse down on the edge (it means sd->timer is not null)
707 // and move more than finger size
711 case ELM_PANEL_ORIENT_TOP:
712 if (sd->timer && ((cur_y - sd->down_y) > finger_size))
714 eo_do(obj, elm_interface_scrollable_freeze_set(EINA_FALSE));
715 sd->freeze = EINA_FALSE;
716 elm_layout_signal_emit(sd->scr_ly, "elm,state,content,visible", "elm");
719 case ELM_PANEL_ORIENT_BOTTOM:
720 if (sd->timer && ((sd->down_y - cur_y) > finger_size))
722 eo_do(obj, elm_interface_scrollable_freeze_set(EINA_FALSE));
723 sd->freeze = EINA_FALSE;
724 elm_layout_signal_emit(sd->scr_ly, "elm,state,content,visible", "elm");
727 case ELM_PANEL_ORIENT_LEFT:
728 if (sd->timer && ((cur_x - sd->down_x) > finger_size))
730 eo_do(obj, elm_interface_scrollable_freeze_set(EINA_FALSE));
731 sd->freeze = EINA_FALSE;
732 elm_layout_signal_emit(sd->scr_ly, "elm,state,content,visible", "elm");
735 case ELM_PANEL_ORIENT_RIGHT:
736 if (sd->timer && ((sd->down_x - cur_x) > finger_size))
738 eo_do(obj, elm_interface_scrollable_freeze_set(EINA_FALSE));
739 sd->freeze = EINA_FALSE;
740 elm_layout_signal_emit(sd->scr_ly, "elm,state,content,visible", "elm");
745 if (!sd->freeze && sd->hidden)
746 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
750 _on_mouse_up(void *data,
755 Elm_Panel_Data *sd = data;
756 Evas_Event_Mouse_Up *ev = event_info;
757 Evas_Coord panel_size, threshold, pos, w, h;
759 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
761 ELM_SAFE_FREE(sd->timer, ecore_timer_del);
763 if (_state_sync(obj)) return;
767 case ELM_PANEL_ORIENT_TOP:
768 panel_size = h * sd->content_size_ratio;
769 threshold = panel_size / 4;
770 eo_do(obj, elm_interface_scrollable_content_pos_get(NULL, &pos));
774 if (pos < (panel_size - threshold)) _drawer_open(obj, w, h, EINA_TRUE);
775 else _drawer_close(obj, w, h, EINA_TRUE);
779 if (pos < threshold) _drawer_open(obj, w, h, EINA_TRUE);
780 else _drawer_close(obj, w, h, EINA_TRUE);
784 case ELM_PANEL_ORIENT_BOTTOM:
785 panel_size = h * sd->content_size_ratio;
786 threshold = panel_size / 4;
787 eo_do(obj, elm_interface_scrollable_content_pos_get(NULL, &pos));
791 if (pos > threshold) _drawer_open(obj, w, h, EINA_TRUE);
792 else _drawer_close(obj, w, h, EINA_TRUE);
796 if (pos > (panel_size - threshold)) _drawer_open(obj, w, h, EINA_TRUE);
797 else _drawer_close(obj, w, h, EINA_TRUE);
801 case ELM_PANEL_ORIENT_LEFT:
802 panel_size = w * sd->content_size_ratio;
803 threshold = panel_size / 4;
804 eo_do(obj, elm_interface_scrollable_content_pos_get(&pos, NULL));
808 if (pos < (panel_size - threshold)) _drawer_open(obj, w, h, EINA_TRUE);
809 else _drawer_close(obj, w, h, EINA_TRUE);
813 if (pos < threshold) _drawer_open(obj, w, h, EINA_TRUE);
814 else _drawer_close(obj, w, h, EINA_TRUE);
818 case ELM_PANEL_ORIENT_RIGHT:
819 panel_size = w * sd->content_size_ratio;
820 threshold = panel_size / 4;
821 eo_do(obj, elm_interface_scrollable_content_pos_get(&pos, NULL));
825 if (pos > threshold) _drawer_open(obj, w, h, EINA_TRUE);
826 else _drawer_close(obj, w, h, EINA_TRUE);
830 if (pos > (panel_size - threshold)) _drawer_open(obj, w, h, EINA_TRUE);
831 else _drawer_close(obj, w, h, EINA_TRUE);
836 if (!sd->freeze && sd->hidden)
837 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
841 _key_action_toggle(Evas_Object *obj, const char *params EINA_UNUSED)
843 _panel_toggle(NULL, obj, NULL, NULL);
847 EOLIAN static Eina_Bool
848 _elm_panel_elm_widget_event(Eo *obj, Elm_Panel_Data *_pd EINA_UNUSED, Evas_Object *src, Evas_Callback_Type type, void *event_info)
850 Evas_Event_Key_Down *ev = event_info;
851 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
852 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
853 if (src != obj) return EINA_FALSE;
855 if (!_elm_config_key_binding_call(obj, ev, key_actions)) return EINA_FALSE;
857 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
861 EOLIAN static Eina_Bool
862 _elm_panel_elm_container_content_set(Eo *obj, Elm_Panel_Data *sd, const char *part, Evas_Object *content)
866 // "elm.swallow.event" part is used for internal needs and should not be changed.
867 if (!strcmp(part, "elm.swallow.event"))
869 ERR("elm.swallow.event is being used for panel internally. Don't touch this part!");
872 if (strcmp(part, "default"))
874 Eina_Bool int_ret = EINA_TRUE;
875 eo_do_super(obj, MY_CLASS,
876 int_ret = elm_obj_container_content_set(part, content));
881 if (sd->content == content) return EINA_TRUE;
883 evas_object_box_remove_all(sd->bx, EINA_TRUE);
884 sd->content = content;
887 evas_object_box_append(sd->bx, sd->content);
888 evas_object_show(sd->content);
891 elm_layout_sizing_eval(obj);
896 EOLIAN static Evas_Object*
897 _elm_panel_elm_container_content_get(Eo *obj, Elm_Panel_Data *sd, const char *part)
901 // "elm.swallow.event" part is used for internal needs and should not be changed.
902 if (!strcmp(part, "elm.swallow.event"))
904 ERR("elm.swallow.event is being used for panel internally. Don't touch this part!");
907 if (strcmp(part, "default"))
909 Evas_Object *ret = NULL;
910 eo_do_super(obj, MY_CLASS, ret = elm_obj_container_content_get(part));
918 EOLIAN static Evas_Object*
919 _elm_panel_elm_container_content_unset(Eo *obj, Elm_Panel_Data *sd, const char *part)
921 Evas_Object *ret = NULL;
925 // "elm.swallow.event" part is used for internal needs and should not be changed.
926 if (!strcmp(part, "elm.swallow.event"))
928 ERR("elm.swallow.event is being used for panel internally. Don't touch this part!");
931 if (strcmp(part, "default"))
933 eo_do_super(obj, MY_CLASS,
934 ret = elm_obj_container_content_unset(part));
939 if (!sd->content) return NULL;
942 evas_object_box_remove_all(sd->bx, EINA_FALSE);
949 _elm_panel_evas_object_smart_add(Eo *obj, Elm_Panel_Data *priv)
951 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
953 eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
954 elm_widget_sub_object_parent_add(obj);
955 elm_widget_can_focus_set(obj, EINA_TRUE);
957 priv->panel_edje = wd->resize_obj;
959 eo_do(obj, elm_obj_widget_theme_apply());
961 priv->bx = evas_object_box_add(evas_object_evas_get(obj));
962 evas_object_box_layout_set(priv->bx, _box_layout_cb, priv, NULL);
963 evas_object_show(priv->bx);
965 elm_layout_signal_callback_add
966 (obj, "elm,action,panel,toggle", "*", _panel_toggle, obj);
968 _mirrored_set(obj, elm_widget_mirrored_get(obj));
970 priv->event = evas_object_rectangle_add(evas_object_evas_get(obj));
971 evas_object_color_set(priv->event, 0, 0, 0, 0);
972 evas_object_pass_events_set(priv->event, EINA_TRUE);
973 elm_widget_sub_object_add(obj, priv->event);
975 /* just to bootstrap and have theme hook to work */
976 if (!elm_layout_theme_set(obj, "panel", "top", elm_widget_style_get(obj)))
977 ERR("Failed to set layout!");
980 elm_layout_content_set(obj, "elm.swallow.content", priv->bx);
982 if (edje_object_part_exists
983 (wd->resize_obj, "elm.swallow.event"))
985 Evas_Coord minw = 0, minh = 0;
987 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
988 evas_object_size_hint_min_set(priv->event, minw, minh);
989 eo_do_super(obj, MY_CLASS, elm_obj_container_content_set("elm.swallow.event", priv->event));
993 elm_layout_sizing_eval(obj);
997 _elm_panel_evas_object_smart_del(Eo *obj, Elm_Panel_Data *sd)
1002 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1004 sd->delete_me = EINA_TRUE;
1006 ELM_SAFE_FREE(sd->timer, ecore_timer_del);
1008 /* let's make our panel object the *last* to be processed, since it
1009 * may (smart) parent other sub objects here */
1010 EINA_LIST_FOREACH(wd->subobjs, l, child)
1012 if (child == sd->bx)
1015 eina_list_demote_list(wd->subobjs, l);
1020 eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
1023 // TIZEN_ONLY(20150128): Panel implementation merge into 2.4
1025 _elm_panel_elm_widget_orientation_set(Eo *obj, Elm_Panel_Data *sd EINA_UNUSED, int orient_mode)
1027 eo_do_super(obj, MY_CLASS, elm_obj_widget_orientation_set(orient_mode));
1028 if (orient_mode == 90 || orient_mode == 270)
1029 elm_panel_scrollable_content_size_set(obj, 0.45);
1031 elm_panel_scrollable_content_size_set(obj, 0.80);
1033 ////////////////////////////////////////////////////////////
1036 _elm_panel_evas_object_smart_move(Eo *obj, Elm_Panel_Data *sd, Evas_Coord x, Evas_Coord y)
1038 eo_do_super(obj, MY_CLASS, evas_obj_smart_move(x, y));
1040 evas_object_move(sd->hit_rect, x, y);
1044 _elm_panel_anim_cb(void *data)
1046 Evas_Object *obj = data;
1047 ELM_PANEL_DATA_GET(obj, sd);
1050 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
1052 if (sd->hidden) _drawer_close(obj, w, h, EINA_FALSE);
1053 else _drawer_open(obj, w, h, EINA_FALSE);
1055 return ECORE_CALLBACK_CANCEL;
1059 _elm_panel_evas_object_smart_resize(Eo *obj, Elm_Panel_Data *sd, Evas_Coord w, Evas_Coord h)
1061 eo_do_super(obj, MY_CLASS, evas_obj_smart_resize(w, h));
1063 if (!sd->scrollable) return;
1065 evas_object_resize(sd->hit_rect, w, h);
1069 case ELM_PANEL_ORIENT_TOP:
1070 case ELM_PANEL_ORIENT_BOTTOM:
1072 evas_object_resize(sd->scr_ly, w, (1 + sd->content_size_ratio) * h);
1073 evas_object_size_hint_min_set(sd->scr_panel, w, (sd->content_size_ratio * h));
1074 evas_object_size_hint_min_set(sd->scr_event, w, h);
1076 case ELM_PANEL_ORIENT_LEFT:
1077 case ELM_PANEL_ORIENT_RIGHT:
1079 evas_object_resize(sd->scr_ly, (1 + sd->content_size_ratio) * w, h);
1080 evas_object_size_hint_min_set(sd->scr_panel, (sd->content_size_ratio * w), h);
1081 evas_object_size_hint_min_set(sd->scr_event, w, h);
1085 ecore_animator_add(_elm_panel_anim_cb, obj);
1089 _elm_panel_evas_object_smart_member_add(Eo *obj, Elm_Panel_Data *sd, Evas_Object *member)
1091 eo_do_super(obj, MY_CLASS, evas_obj_smart_member_add(member));
1093 if (sd->hit_rect) evas_object_raise(sd->hit_rect);
1097 _elm_panel_elm_widget_access(Eo *obj, Elm_Panel_Data *_pd, Eina_Bool is_access)
1099 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1100 Elm_Panel_Data *sd = _pd;
1104 _access_obj_process(obj, is_access);
1109 _elm_access_edje_object_part_object_register
1110 (obj, wd->resize_obj, "btn_icon");
1112 _elm_access_edje_object_part_object_unregister
1113 (obj, wd->resize_obj, "btn_icon");
1117 elm_panel_add(Evas_Object *parent)
1119 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
1120 Evas_Object *obj = eo_add(MY_CLASS, parent);
1122 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
1123 wd->highlight_root = EINA_TRUE;
1129 _elm_panel_eo_base_constructor(Eo *obj, Elm_Panel_Data *_pd EINA_UNUSED)
1131 eo_do_super(obj, MY_CLASS, eo_constructor());
1133 evas_obj_type_set(MY_CLASS_NAME_LEGACY),
1134 evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
1135 elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_PANEL));
1139 _elm_panel_orient_set(Eo *obj, Elm_Panel_Data *sd, Elm_Panel_Orient orient)
1141 if (sd->orient == orient) return;
1142 sd->orient = orient;
1144 if (sd->scrollable) _scrollable_layout_theme_set(obj, sd);
1145 else _orient_set_do(obj);
1147 elm_layout_sizing_eval(obj);
1150 EOLIAN static Elm_Panel_Orient
1151 _elm_panel_orient_get(Eo *obj EINA_UNUSED, Elm_Panel_Data *sd)
1157 _elm_panel_hidden_set(Eo *obj, Elm_Panel_Data *sd, Eina_Bool hidden)
1159 if (sd->hidden == !!hidden)
1161 if (sd->scrollable && sd->hidden && !sd->freeze)
1164 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
1165 _drawer_close(obj, w, h, EINA_TRUE);
1170 _panel_toggle(NULL, obj, NULL, NULL);
1173 EOLIAN static Eina_Bool
1174 _elm_panel_hidden_get(Eo *obj EINA_UNUSED, Elm_Panel_Data *sd)
1180 _elm_panel_toggle(Eo *obj, Elm_Panel_Data *_pd EINA_UNUSED)
1182 _panel_toggle(NULL, obj, NULL, NULL);
1185 EOLIAN static Eina_Bool
1186 _elm_panel_elm_widget_on_focus_region(Eo *obj,
1193 eo_do(obj, elm_interface_scrollable_content_pos_get(x, y));
1194 evas_object_geometry_get(obj, NULL, NULL, w, h);
1197 case ELM_PANEL_ORIENT_TOP:
1198 case ELM_PANEL_ORIENT_BOTTOM:
1199 *h = *h * sd->content_size_ratio;
1201 case ELM_PANEL_ORIENT_LEFT:
1202 case ELM_PANEL_ORIENT_RIGHT:
1203 *w = *w * sd->content_size_ratio;
1210 _anim_stop_cb(Evas_Object *obj, void *data EINA_UNUSED)
1212 if (elm_widget_disabled_get(obj)) return;
1217 _scroll_cb(Evas_Object *obj, void *data EINA_UNUSED)
1219 ELM_PANEL_DATA_GET(obj, sd);
1220 Elm_Panel_Scroll_Info event;
1221 Evas_Coord x, y, w, h;
1223 if (elm_widget_disabled_get(obj)) return;
1225 // freeze_set(FALSE) -> mouse_up -> freeze_set(TRUE) -> scroll
1228 eo_do(obj, elm_interface_scrollable_movement_block_set
1229 (ELM_SCROLLER_MOVEMENT_NO_BLOCK));
1230 sd->freeze = EINA_FALSE;
1231 elm_layout_signal_emit(sd->scr_ly, "elm,state,content,visible", "elm");
1234 eo_do(obj, elm_interface_scrollable_content_pos_get(&x, &y));
1235 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
1239 case ELM_PANEL_ORIENT_TOP:
1241 event.rel_y = 1 - ((double) y / (double) ((sd->content_size_ratio) * h));
1243 case ELM_PANEL_ORIENT_BOTTOM:
1245 event.rel_y = (double) y / (double) ((sd->content_size_ratio) * h);
1247 case ELM_PANEL_ORIENT_LEFT:
1248 event.rel_x = 1 - ((double) x / (double) ((sd->content_size_ratio) * w));
1251 case ELM_PANEL_ORIENT_RIGHT:
1252 event.rel_x = (double) x / (double) ((sd->content_size_ratio) * w);
1256 evas_object_smart_callback_call(obj, SIG_SCROLL, (void *) &event);
1259 EOLIAN static Eina_Bool
1260 _elm_panel_elm_widget_disable(Eo *obj, Elm_Panel_Data *sd)
1262 Eina_Bool int_ret = EINA_FALSE;
1263 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_disable());
1264 if (!int_ret) return EINA_FALSE;
1268 if (elm_widget_disabled_get(obj))
1270 evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_DOWN,
1272 evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_MOVE,
1274 evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_UP,
1276 evas_object_event_callback_del(sd->scr_event, EVAS_CALLBACK_MOUSE_UP,
1281 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN,
1282 _on_mouse_down, sd);
1283 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_MOVE,
1284 _on_mouse_move, sd);
1285 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_UP,
1287 evas_object_event_callback_add(sd->scr_event, EVAS_CALLBACK_MOUSE_UP,
1288 _event_mouse_up, obj);
1296 _elm_panel_scrollable_content_size_set(Eo *obj, Elm_Panel_Data *sd, double ratio)
1299 sd->content_size_ratio = ratio;
1300 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
1304 case ELM_PANEL_ORIENT_TOP:
1305 case ELM_PANEL_ORIENT_BOTTOM:
1307 evas_object_resize(sd->scr_ly, w, (1 + sd->content_size_ratio) * h);
1308 evas_object_size_hint_min_set(sd->scr_panel, w, (sd->content_size_ratio * h));
1309 evas_object_size_hint_min_set(sd->scr_event, w, h);
1311 case ELM_PANEL_ORIENT_LEFT:
1312 case ELM_PANEL_ORIENT_RIGHT:
1314 evas_object_resize(sd->scr_ly, (1 + sd->content_size_ratio) * w, h);
1315 evas_object_size_hint_min_set(sd->scr_panel, (sd->content_size_ratio * w), h);
1316 evas_object_size_hint_min_set(sd->scr_event, w, h);
1320 ecore_animator_add(_elm_panel_anim_cb, obj);
1323 EOLIAN static Eina_Bool
1324 _elm_panel_scrollable_get(Eo *obj EINA_UNUSED, Elm_Panel_Data *sd)
1326 return sd->scrollable;
1330 _elm_panel_scrollable_set(Eo *obj, Elm_Panel_Data *sd, Eina_Bool scrollable)
1332 scrollable = !!scrollable;
1333 if (sd->scrollable == scrollable) return;
1334 sd->scrollable = scrollable;
1338 elm_layout_content_unset(obj, "elm.swallow.content");
1340 elm_widget_resize_object_set(obj, NULL, EINA_TRUE);
1341 elm_widget_sub_object_add(obj, sd->panel_edje);
1345 const char *handler_size;
1347 sd->scr_edje = edje_object_add(evas_object_evas_get(obj));
1348 elm_widget_theme_object_set(obj, sd->scr_edje, "scroller", "panel",
1349 elm_widget_style_get(obj));
1350 evas_object_size_hint_weight_set
1351 (sd->scr_edje, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1352 evas_object_size_hint_align_set
1353 (sd->scr_edje, EVAS_HINT_FILL, EVAS_HINT_FILL);
1355 handler_size = edje_object_data_get(sd->scr_edje, "handler_size");
1357 sd->handler_size = (int) (elm_object_scale_get(obj)) * (atoi(handler_size));
1360 elm_widget_resize_object_set(obj, sd->scr_edje, EINA_TRUE);
1362 // TIZEN_ONLY(20150128): Panel implementation merge into 2.4
1363 if (elm_win_rotation_get(elm_widget_top_get(obj)) == 90 || elm_win_rotation_get(elm_widget_top_get(obj)) == 270)
1364 elm_panel_scrollable_content_size_set(obj, 0.45);
1366 elm_panel_scrollable_content_size_set(obj, 0.80);
1367 ////////////////////////////////////////////////////////////
1371 sd->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
1372 evas_object_smart_member_add(sd->hit_rect, obj);
1373 elm_widget_sub_object_add(obj, sd->hit_rect);
1374 evas_object_color_set(sd->hit_rect, 0, 0, 0, 0);
1375 evas_object_show(sd->hit_rect);
1376 evas_object_repeat_events_set(sd->hit_rect, EINA_TRUE);
1379 elm_interface_scrollable_objects_set(sd->scr_edje, sd->hit_rect),
1380 elm_interface_scrollable_animate_stop_cb_set(_anim_stop_cb),
1381 elm_interface_scrollable_scroll_cb_set(_scroll_cb));
1386 sd->scr_ly = elm_layout_add(obj);
1387 evas_object_smart_member_add(sd->scr_ly, obj);
1388 elm_widget_sub_object_add(obj, sd->scr_ly);
1389 _scrollable_layout_theme_set(obj, sd);
1391 sd->scr_panel = evas_object_rectangle_add(evas_object_evas_get(obj));
1392 evas_object_color_set(sd->scr_panel, 0, 0, 0, 0);
1393 elm_widget_sub_object_add(obj, sd->scr_panel);
1394 elm_layout_content_set(sd->scr_ly, "panel_area", sd->scr_panel);
1396 sd->scr_event = evas_object_rectangle_add(evas_object_evas_get(obj));
1397 evas_object_color_set(sd->scr_event, 0, 0, 0, 0);
1398 elm_widget_sub_object_add(obj, sd->scr_event);
1399 elm_layout_content_set(sd->scr_ly, "event_area", sd->scr_event);
1403 elm_interface_scrollable_content_set(sd->scr_ly));
1404 sd->freeze = EINA_TRUE;
1405 elm_layout_content_set(sd->scr_ly, "elm.swallow.content", sd->bx);
1409 case ELM_PANEL_ORIENT_TOP:
1410 case ELM_PANEL_ORIENT_BOTTOM:
1411 eo_do(obj, elm_interface_scrollable_movement_block_set
1412 (ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL));
1414 case ELM_PANEL_ORIENT_LEFT:
1415 case ELM_PANEL_ORIENT_RIGHT:
1416 eo_do(obj, elm_interface_scrollable_movement_block_set
1417 (ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL));
1421 eo_do(obj, elm_interface_scrollable_single_direction_set
1422 (ELM_SCROLLER_SINGLE_DIRECTION_NONE));
1424 if (!elm_widget_disabled_get(obj))
1426 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN,
1427 _on_mouse_down, sd);
1428 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_MOVE,
1429 _on_mouse_move, sd);
1430 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_UP,
1432 evas_object_event_callback_add(sd->scr_event, EVAS_CALLBACK_MOUSE_UP,
1433 _event_mouse_up, obj);
1439 eo_do(obj, elm_interface_scrollable_content_set(NULL));
1441 evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_DOWN, _on_mouse_down);
1442 evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_MOVE, _on_mouse_move);
1443 evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_UP, _on_mouse_up);
1444 evas_object_event_callback_del(sd->scr_event, EVAS_CALLBACK_MOUSE_UP,
1447 elm_widget_resize_object_set(obj, NULL, EINA_TRUE);
1448 elm_widget_sub_object_add(obj, sd->scr_edje);
1450 elm_widget_resize_object_set(obj, sd->panel_edje, EINA_TRUE);
1452 elm_layout_content_unset(sd->scr_ly, "elm.swallow.content");
1453 elm_layout_content_set(obj, "elm.swallow.content", sd->bx);
1458 _elm_panel_class_constructor(Eo_Class *klass)
1460 evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
1463 EOLIAN const Elm_Atspi_Action *
1464 _elm_panel_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Panel_Data *pd EINA_UNUSED)
1466 static Elm_Atspi_Action atspi_actions[] = {
1467 { "toggle", "toggle", NULL, _key_action_toggle},
1468 { NULL, NULL, NULL, NULL }
1470 return &atspi_actions[0];
1473 #include "elm_panel.eo.c"