1 #include <Elementary.h>
3 #include "elm_interface_scrollable.h"
5 static const char PAN_SMART_NAME[] = "elm_pan";
7 #define ELM_PAN_DATA_GET_OR_RETURN(o, ptr) \
8 Elm_Pan_Smart_Data *ptr = evas_object_smart_data_get(o); \
11 CRITICAL("No smart data for object %p (%s)", \
12 o, evas_object_type_get(o)); \
16 #define ELM_PAN_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
17 Elm_Pan_Smart_Data *ptr = evas_object_smart_data_get(o); \
20 CRITICAL("No smart data for object %p (%s)", \
21 o, evas_object_type_get(o)); \
25 static const char SIG_CHANGED[] = "changed";
26 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
31 ELM_INTERNAL_SMART_SUBCLASS_NEW
32 (PAN_SMART_NAME, _elm_pan, Elm_Pan_Smart_Class, Evas_Smart_Class,
33 evas_object_smart_clipped_class_get, _smart_callbacks);
35 static void _elm_pan_content_set(Evas_Object *, Evas_Object *);
37 EAPI const Elm_Pan_Smart_Class *
38 elm_pan_smart_class_get(void)
40 static Elm_Pan_Smart_Class _sc =
41 ELM_PAN_SMART_CLASS_INIT_NAME_VERSION(PAN_SMART_NAME);
42 static const Elm_Pan_Smart_Class *class = NULL;
43 Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
48 _elm_pan_smart_set(&_sc);
49 esc->callbacks = _smart_callbacks;
56 _elm_pan_update(Elm_Pan_Smart_Data *psd)
58 if (!psd->gravity_x && !psd->gravity_y)
60 evas_object_move(psd->content, psd->x - psd->px, psd->y - psd->py);
64 if ((!psd->px) && (!psd->py))
66 psd->px = psd->delta_posx * psd->gravity_x;
67 psd->py = psd->delta_posy * psd->gravity_y;
69 psd->delta_posx += psd->content_w - psd->prev_cw;
70 psd->prev_cw = psd->content_w;
71 psd->delta_posy += psd->content_h - psd->prev_ch;
72 psd->prev_ch = psd->content_h;
74 evas_object_move(psd->content, psd->x - psd->px, psd->y - psd->py);
75 psd->px = psd->delta_posx * psd->gravity_x;
76 psd->py = psd->delta_posy * psd->gravity_y;
80 _elm_pan_smart_add(Evas_Object *obj)
82 const Evas_Smart_Class *sc;
83 const Evas_Smart *smart;
85 EVAS_SMART_DATA_ALLOC(obj, Elm_Pan_Smart_Data);
87 _elm_pan_parent_sc->add(obj);
95 priv->gravity_x = 0.0;
96 priv->gravity_y = 0.0;
98 smart = evas_object_smart_smart_get(obj);
99 sc = evas_smart_class_get(smart);
100 priv->api = (const Elm_Pan_Smart_Class *)sc;
104 _elm_pan_smart_del(Evas_Object *obj)
106 _elm_pan_content_set(obj, NULL);
108 _elm_pan_parent_sc->del(obj);
112 _elm_pan_smart_move(Evas_Object *obj,
116 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
118 /* we don't want the clipped smart object version here */
123 _elm_pan_update(psd);
127 _elm_pan_smart_resize(Evas_Object *obj,
131 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
136 _elm_pan_update(psd);
137 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
141 _elm_pan_smart_show(Evas_Object *obj)
143 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
145 _elm_pan_parent_sc->show(obj);
148 evas_object_show(psd->content);
152 _elm_pan_smart_hide(Evas_Object *obj)
154 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
156 _elm_pan_parent_sc->hide(obj);
159 evas_object_hide(psd->content);
163 _elm_pan_pos_set(Evas_Object *obj,
167 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
169 if ((x == psd->px) && (y == psd->py)) return;
173 _elm_pan_update(psd);
174 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
178 _elm_pan_pos_get(const Evas_Object *obj,
182 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
189 _elm_pan_pos_max_get(const Evas_Object *obj,
193 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
197 if (psd->w < psd->content_w) *x = psd->content_w - psd->w;
202 if (psd->h < psd->content_h) *y = psd->content_h - psd->h;
208 _elm_pan_pos_min_get(const Evas_Object *obj __UNUSED__,
219 _elm_pan_content_size_get(const Evas_Object *obj,
223 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
225 if (w) *w = psd->content_w;
226 if (h) *h = psd->content_h;
230 _elm_pan_gravity_set(Evas_Object *obj,
234 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
238 psd->prev_cw = psd->content_w;
239 psd->prev_ch = psd->content_h;
245 _elm_pan_gravity_get(const Evas_Object *obj,
249 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
251 if (x) *x = psd->gravity_x;
252 if (y) *y = psd->gravity_y;
256 _elm_pan_smart_set_user(Elm_Pan_Smart_Class *sc)
258 sc->base.add = _elm_pan_smart_add;
259 sc->base.del = _elm_pan_smart_del;
260 sc->base.move = _elm_pan_smart_move;
261 sc->base.resize = _elm_pan_smart_resize;
262 sc->base.show = _elm_pan_smart_show;
263 sc->base.hide = _elm_pan_smart_hide;
265 sc->pos_set = _elm_pan_pos_set;
266 sc->pos_get = _elm_pan_pos_get;
267 sc->pos_max_get = _elm_pan_pos_max_get;
268 sc->pos_min_get = _elm_pan_pos_min_get;
269 sc->content_size_get = _elm_pan_content_size_get;
270 sc->gravity_set = _elm_pan_gravity_set;
271 sc->gravity_get = _elm_pan_gravity_get;
275 _elm_pan_add(Evas *evas)
277 return evas_object_smart_add(evas, _elm_pan_smart_class_new());
281 _elm_pan_content_del_cb(void *data,
283 Evas_Object *obj __UNUSED__,
284 void *event_info __UNUSED__)
286 Elm_Pan_Smart_Data *psd;
290 psd->content_w = psd->content_h = psd->px = psd->py =
291 psd->prev_cw = psd->prev_ch = psd->delta_posx = psd->delta_posy = 0;
292 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
296 _elm_pan_content_resize_cb(void *data,
298 Evas_Object *obj __UNUSED__,
299 void *event_info __UNUSED__)
301 Elm_Pan_Smart_Data *psd;
305 evas_object_geometry_get(psd->content, NULL, NULL, &w, &h);
306 if ((w != psd->content_w) || (h != psd->content_h))
310 _elm_pan_update(psd);
312 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
316 _elm_pan_content_set(Evas_Object *obj,
317 Evas_Object *content)
321 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
323 if (content == psd->content) return;
326 evas_object_smart_member_del(psd->content);
327 evas_object_event_callback_del_full
328 (psd->content, EVAS_CALLBACK_DEL, _elm_pan_content_del_cb, psd);
329 evas_object_event_callback_del_full
330 (psd->content, EVAS_CALLBACK_RESIZE, _elm_pan_content_resize_cb,
334 if (!content) goto end;
336 psd->content = content;
337 evas_object_smart_member_add(psd->content, psd->self);
338 evas_object_geometry_get(psd->content, NULL, NULL, &w, &h);
341 evas_object_event_callback_add
342 (content, EVAS_CALLBACK_DEL, _elm_pan_content_del_cb, psd);
343 evas_object_event_callback_add
344 (content, EVAS_CALLBACK_RESIZE, _elm_pan_content_resize_cb, psd);
346 if (evas_object_visible_get(psd->self))
347 evas_object_show(psd->content);
349 evas_object_hide(psd->content);
351 _elm_pan_update(psd);
354 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
357 /* pan smart object on top, scroller interface on bottom */
358 /* ============================================================ */
360 static const char SCROLL_SMART_NAME[] = "elm_scroll";
362 #define ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(o, ptr) \
363 Elm_Scrollable_Smart_Interface_Data *ptr = \
364 evas_object_smart_interface_data_get(o, &(ELM_SCROLLABLE_IFACE.base)); \
367 CRITICAL("No interface data for object %p (%s)", \
368 o, evas_object_type_get(o)); \
372 #define ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
373 Elm_Scrollable_Smart_Interface_Data *ptr = \
374 evas_object_smart_interface_data_get(o, &(ELM_SCROLLABLE_IFACE.base)); \
377 CRITICAL("No interface data for object %p (%s)", \
378 o, evas_object_type_get(o)); \
382 static void _elm_scroll_scroll_bar_size_adjust(
383 Elm_Scrollable_Smart_Interface_Data *);
384 static void _elm_scroll_wanted_region_set(Evas_Object *);
385 static void _elm_scroll_content_pos_get(const Evas_Object *,
388 static void _elm_scroll_content_pos_set(Evas_Object *,
400 _elm_direction_arrows_eval(Elm_Scrollable_Smart_Interface_Data *sid)
402 Eina_Bool go_left = EINA_TRUE, go_right = EINA_TRUE;
403 Eina_Bool go_up = EINA_TRUE, go_down = EINA_TRUE;
404 Evas_Coord x = 0, y = 0, mx = 0, my = 0, minx = 0, miny = 0;
406 if (!sid->edje_obj || !sid->pan_obj) return;
407 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
409 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
410 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
411 psd->api->pos_get(sid->pan_obj, &x, &y);
413 if (x == minx) go_left = EINA_FALSE;
414 if (x == (mx + minx)) go_right = EINA_FALSE;
415 if (y == miny) go_up = EINA_FALSE;
416 if (y == (my + miny)) go_down = EINA_FALSE;
417 if (go_left != sid->go_left)
420 edje_object_signal_emit(sid->edje_obj, "elm,action,show,left", "elm");
422 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,left", "elm");
423 sid->go_left = go_left;
425 if (go_right != sid->go_right)
428 edje_object_signal_emit(sid->edje_obj, "elm,action,show,right", "elm");
430 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,right", "elm");
431 sid->go_right= go_right;
433 if (go_up != sid->go_up)
436 edje_object_signal_emit(sid->edje_obj, "elm,action,show,up", "elm");
438 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,up", "elm");
441 if (go_down != sid->go_down)
444 edje_object_signal_emit(sid->edje_obj, "elm,action,show,down", "elm");
446 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,down", "elm");
447 sid->go_down= go_down;
452 _elm_scroll_scroll_bar_h_visibility_adjust(
453 Elm_Scrollable_Smart_Interface_Data *sid)
455 int scroll_h_vis_change = 0;
456 Evas_Coord w, vw = 0, vh = 0;
458 if (!sid->edje_obj) return 0;
460 w = sid->content_info.w;
462 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &vw, &vh);
463 if (sid->hbar_visible)
467 scroll_h_vis_change = 1;
468 sid->hbar_visible = EINA_FALSE;
472 if (sid->hbar_flags == ELM_SCROLLER_POLICY_AUTO)
474 if ((sid->content) || (sid->extern_pan))
478 scroll_h_vis_change = 1;
479 sid->hbar_visible = EINA_FALSE;
484 scroll_h_vis_change = 1;
485 sid->hbar_visible = EINA_FALSE;
488 else if (sid->hbar_flags == ELM_SCROLLER_POLICY_OFF)
490 scroll_h_vis_change = 1;
491 sid->hbar_visible = EINA_FALSE;
499 if (sid->hbar_flags == ELM_SCROLLER_POLICY_AUTO)
501 if ((sid->content) || (sid->extern_pan))
505 scroll_h_vis_change = 1;
506 sid->hbar_visible = EINA_TRUE;
510 else if (sid->hbar_flags == ELM_SCROLLER_POLICY_ON)
512 scroll_h_vis_change = 1;
513 sid->hbar_visible = EINA_TRUE;
517 if (scroll_h_vis_change)
519 if (sid->hbar_flags != ELM_SCROLLER_POLICY_OFF)
521 if (sid->hbar_visible)
522 edje_object_signal_emit
523 (sid->edje_obj, "elm,action,show,hbar", "elm");
525 edje_object_signal_emit
526 (sid->edje_obj, "elm,action,hide,hbar", "elm");
529 edje_object_signal_emit
530 (sid->edje_obj, "elm,action,hide,hbar", "elm");
531 edje_object_message_signal_process(sid->edje_obj);
532 _elm_scroll_scroll_bar_size_adjust(sid);
533 if (sid->cb_func.content_min_limit)
534 sid->cb_func.content_min_limit(sid->obj, sid->min_w, sid->min_h);
537 _elm_direction_arrows_eval(sid);
538 return scroll_h_vis_change;
542 _elm_scroll_scroll_bar_v_visibility_adjust(
543 Elm_Scrollable_Smart_Interface_Data *sid)
545 int scroll_v_vis_change = 0;
546 Evas_Coord h, vw = 0, vh = 0;
548 if (!sid->edje_obj) return 0;
550 h = sid->content_info.h;
552 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &vw, &vh);
553 if (sid->vbar_visible)
557 scroll_v_vis_change = 1;
558 sid->vbar_visible = EINA_FALSE;
562 if (sid->vbar_flags == ELM_SCROLLER_POLICY_AUTO)
564 if ((sid->content) || (sid->extern_pan))
568 scroll_v_vis_change = 1;
569 sid->vbar_visible = EINA_FALSE;
574 scroll_v_vis_change = 1;
575 sid->vbar_visible = EINA_FALSE;
578 else if (sid->vbar_flags == ELM_SCROLLER_POLICY_OFF)
580 scroll_v_vis_change = 1;
581 sid->vbar_visible = EINA_FALSE;
589 if (sid->vbar_flags == ELM_SCROLLER_POLICY_AUTO)
591 if ((sid->content) || (sid->extern_pan))
595 scroll_v_vis_change = 1;
596 sid->vbar_visible = EINA_TRUE;
600 else if (sid->vbar_flags == ELM_SCROLLER_POLICY_ON)
602 scroll_v_vis_change = 1;
603 sid->vbar_visible = EINA_TRUE;
607 if (scroll_v_vis_change)
609 if (sid->vbar_flags != ELM_SCROLLER_POLICY_OFF)
611 if (sid->vbar_visible)
612 edje_object_signal_emit
613 (sid->edje_obj, "elm,action,show,vbar", "elm");
615 edje_object_signal_emit
616 (sid->edje_obj, "elm,action,hide,vbar", "elm");
619 edje_object_signal_emit
620 (sid->edje_obj, "elm,action,hide,vbar", "elm");
621 edje_object_message_signal_process(sid->edje_obj);
622 _elm_scroll_scroll_bar_size_adjust(sid);
623 if (sid->cb_func.content_min_limit)
624 sid->cb_func.content_min_limit(sid->obj, sid->min_w, sid->min_h);
627 _elm_direction_arrows_eval(sid);
628 return scroll_v_vis_change;
632 _elm_scroll_scroll_bar_visibility_adjust(
633 Elm_Scrollable_Smart_Interface_Data *sid)
637 changed |= _elm_scroll_scroll_bar_h_visibility_adjust(sid);
638 changed |= _elm_scroll_scroll_bar_v_visibility_adjust(sid);
642 _elm_scroll_scroll_bar_h_visibility_adjust(sid);
643 _elm_scroll_scroll_bar_v_visibility_adjust(sid);
648 _elm_scroll_scroll_bar_size_adjust(Elm_Scrollable_Smart_Interface_Data *sid)
650 if (!sid->pan_obj || !sid->edje_obj) return;
652 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
654 if ((sid->content) || (sid->extern_pan))
656 Evas_Coord x, y, w, h, mx = 0, my = 0, vw = 0, vh = 0, px, py,
660 edje_object_part_geometry_get
661 (sid->edje_obj, "elm.swallow.content", NULL, NULL, &vw, &vh);
662 w = sid->content_info.w;
664 size = (double)vw / (double)w;
669 edje_object_part_drag_value_set
670 (sid->edje_obj, "elm.dragable.hbar", 0.0, 0.0);
672 edje_object_part_drag_size_set
673 (sid->edje_obj, "elm.dragable.hbar", size, 1.0);
675 h = sid->content_info.h;
677 size = (double)vh / (double)h;
681 edje_object_part_drag_value_set
682 (sid->edje_obj, "elm.dragable.vbar", 0.0, 0.0);
684 edje_object_part_drag_size_set
685 (sid->edje_obj, "elm.dragable.vbar", 1.0, size);
687 edje_object_part_drag_value_get
688 (sid->edje_obj, "elm.dragable.hbar", &vx, NULL);
689 edje_object_part_drag_value_get
690 (sid->edje_obj, "elm.dragable.vbar", NULL, &vy);
692 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
693 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
697 edje_object_part_drag_step_set
698 (sid->edje_obj, "elm.dragable.hbar", (double)sid->step.x /
700 edje_object_part_drag_step_set
701 (sid->edje_obj, "elm.dragable.vbar", 0.0, (double)sid->step.y /
704 edje_object_part_drag_page_set
705 (sid->edje_obj, "elm.dragable.hbar", (double)sid->page.x /
708 edje_object_part_drag_page_set
709 (sid->edje_obj, "elm.dragable.hbar",
710 -((double)sid->page.x * ((double)vw / (double)w)) / 100.0, 0.0);
712 edje_object_part_drag_page_set
713 (sid->edje_obj, "elm.dragable.vbar", 0.0,
714 (double)sid->page.y / (double)h);
716 edje_object_part_drag_page_set
717 (sid->edje_obj, "elm.dragable.vbar", 0.0,
718 -((double)sid->page.y * ((double)vh / (double)h)) / 100.0);
720 psd->api->pos_get(sid->pan_obj, &px, &py);
721 if (vx != mx) x = px;
722 if (vy != my) y = py;
723 psd->api->pos_set(sid->pan_obj, x, y);
727 Evas_Coord px = 0, py = 0, minx = 0, miny = 0;
729 edje_object_part_drag_size_set
730 (sid->edje_obj, "elm.dragable.vbar", 1.0, 1.0);
731 edje_object_part_drag_size_set
732 (sid->edje_obj, "elm.dragable.hbar", 1.0, 1.0);
733 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
734 psd->api->pos_get(sid->pan_obj, &px, &py);
735 psd->api->pos_set(sid->pan_obj, minx, miny);
736 if ((px != minx) || (py != miny))
737 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
739 _elm_scroll_scroll_bar_visibility_adjust(sid);
743 _elm_scroll_scroll_bar_read_and_update(
744 Elm_Scrollable_Smart_Interface_Data *sid)
746 Evas_Coord x, y, mx = 0, my = 0, px, py, minx = 0, miny = 0;
749 if (!sid->edje_obj || !sid->pan_obj) return;
751 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
753 if ((sid->down.dragged) || (sid->down.bounce_x_animator)
754 || (sid->down.bounce_y_animator) || (sid->down.momentum_animator)
755 || (sid->scrollto.x.animator) || (sid->scrollto.y.animator))
757 edje_object_part_drag_value_get
758 (sid->edje_obj, "elm.dragable.vbar", NULL, &vy);
759 edje_object_part_drag_value_get
760 (sid->edje_obj, "elm.dragable.hbar", &vx, NULL);
761 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
762 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
763 x = vx * (double)mx + minx;
764 y = vy * (double)my + miny;
765 psd->api->pos_get(sid->pan_obj, &px, &py);
766 psd->api->pos_set(sid->pan_obj, x, y);
767 if ((px != x) || (py != y))
769 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
774 _elm_scroll_drag_start(Elm_Scrollable_Smart_Interface_Data *sid)
776 if (sid->cb_func.drag_start)
777 sid->cb_func.drag_start(sid->obj, NULL);
781 _elm_scroll_drag_stop(Elm_Scrollable_Smart_Interface_Data *sid)
783 if (sid->cb_func.drag_stop)
784 sid->cb_func.drag_stop(sid->obj, NULL);
788 _elm_scroll_anim_start(Elm_Scrollable_Smart_Interface_Data *sid)
790 if (sid->cb_func.animate_start)
791 sid->cb_func.animate_start(sid->obj, NULL);
795 _elm_scroll_anim_stop(Elm_Scrollable_Smart_Interface_Data *sid)
797 if (sid->cb_func.animate_stop)
798 sid->cb_func.animate_stop(sid->obj, NULL);
802 _elm_scroll_vbar_drag_cb(void *data,
803 Evas_Object *obj __UNUSED__,
804 const char *emission __UNUSED__,
805 const char *source __UNUSED__)
807 Elm_Scrollable_Smart_Interface_Data *sid = data;
809 if (sid->cb_func.vbar_drag)
810 sid->cb_func.vbar_drag(sid->obj, NULL);
812 _elm_scroll_scroll_bar_read_and_update(sid);
816 _elm_scroll_vbar_press_cb(void *data,
817 Evas_Object *obj __UNUSED__,
818 const char *emission __UNUSED__,
819 const char *source __UNUSED__)
821 Elm_Scrollable_Smart_Interface_Data *sid = data;
823 if (sid->cb_func.vbar_press)
824 sid->cb_func.vbar_press(sid->obj, NULL);
828 _elm_scroll_vbar_unpress_cb(void *data,
829 Evas_Object *obj __UNUSED__,
830 const char *emission __UNUSED__,
831 const char *source __UNUSED__)
833 Elm_Scrollable_Smart_Interface_Data *sid = data;
835 if (sid->cb_func.vbar_unpress)
836 sid->cb_func.vbar_unpress(sid->obj, NULL);
840 _elm_scroll_edje_drag_v_start_cb(void *data,
841 Evas_Object *obj __UNUSED__,
842 const char *emission __UNUSED__,
843 const char *source __UNUSED__)
845 Elm_Scrollable_Smart_Interface_Data *sid = data;
847 _elm_scroll_scroll_bar_read_and_update(sid);
848 _elm_scroll_drag_start(sid);
849 sid->freeze = EINA_TRUE;
853 _elm_scroll_edje_drag_v_stop_cb(void *data,
854 Evas_Object *obj __UNUSED__,
855 const char *emission __UNUSED__,
856 const char *source __UNUSED__)
858 Elm_Scrollable_Smart_Interface_Data *sid = data;
860 _elm_scroll_scroll_bar_read_and_update(sid);
861 _elm_scroll_drag_stop(sid);
862 sid->freeze = EINA_FALSE;
866 _elm_scroll_edje_drag_v_cb(void *data,
867 Evas_Object *obj __UNUSED__,
868 const char *emission __UNUSED__,
869 const char *source __UNUSED__)
871 Elm_Scrollable_Smart_Interface_Data *sid = data;
873 _elm_scroll_scroll_bar_read_and_update(sid);
877 _elm_scroll_hbar_drag_cb(void *data,
878 Evas_Object *obj __UNUSED__,
879 const char *emission __UNUSED__,
880 const char *source __UNUSED__)
882 Elm_Scrollable_Smart_Interface_Data *sid = data;
884 if (sid->cb_func.hbar_drag)
885 sid->cb_func.hbar_drag(sid->obj, NULL);
887 _elm_scroll_scroll_bar_read_and_update(sid);
891 _elm_scroll_hbar_press_cb(void *data,
892 Evas_Object *obj __UNUSED__,
893 const char *emission __UNUSED__,
894 const char *source __UNUSED__)
896 Elm_Scrollable_Smart_Interface_Data *sid = data;
898 if (sid->cb_func.hbar_press)
899 sid->cb_func.hbar_press(sid->obj, NULL);
903 _elm_scroll_hbar_unpress_cb(void *data,
904 Evas_Object *obj __UNUSED__,
905 const char *emission __UNUSED__,
906 const char *source __UNUSED__)
908 Elm_Scrollable_Smart_Interface_Data *sid = data;
910 if (sid->cb_func.hbar_unpress)
911 sid->cb_func.hbar_unpress(sid->obj, NULL);
915 _elm_scroll_edje_drag_h_start_cb(void *data,
916 Evas_Object *obj __UNUSED__,
917 const char *emission __UNUSED__,
918 const char *source __UNUSED__)
920 Elm_Scrollable_Smart_Interface_Data *sid = data;
922 _elm_scroll_scroll_bar_read_and_update(sid);
923 _elm_scroll_drag_start(sid);
924 sid->freeze = EINA_TRUE;
928 _elm_scroll_edje_drag_h_stop_cb(void *data,
929 Evas_Object *obj __UNUSED__,
930 const char *emission __UNUSED__,
931 const char *source __UNUSED__)
933 Elm_Scrollable_Smart_Interface_Data *sid = data;
935 _elm_scroll_scroll_bar_read_and_update(sid);
936 _elm_scroll_drag_stop(sid);
937 sid->freeze = EINA_FALSE;
941 _elm_scroll_edje_drag_h_cb(void *data,
942 Evas_Object *obj __UNUSED__,
943 const char *emission __UNUSED__,
944 const char *source __UNUSED__)
946 Elm_Scrollable_Smart_Interface_Data *sid = data;
948 _elm_scroll_scroll_bar_read_and_update(sid);
952 _elm_scroll_content_size_get(const Evas_Object *obj,
956 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
958 if (!sid->content) return;
960 evas_object_geometry_get(sid->content, NULL, NULL, w, h);
964 _elm_scroll_content_viewport_size_get(const Evas_Object *obj,
968 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
970 if (!sid->pan_obj || !sid->edje_obj) return;
972 edje_object_calc_force(sid->edje_obj);
973 evas_object_geometry_get(sid->pan_obj, NULL, NULL, w, h);
977 _elm_scroll_content_min_limit(Evas_Object *obj,
981 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
983 if (!sid->edje_obj) return;
985 if (!sid->cb_func.content_min_limit)
987 ERR("Content minimim size limiting is unimplemented -- you "
988 "must provide it yourself\n");
994 sid->cb_func.content_min_limit(sid->obj, w, h);
998 _elm_scroll_x_mirrored_get(const Evas_Object *obj,
1001 Evas_Coord cw, ch, w, ret;
1003 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, x);
1005 if (!sid->pan_obj) return 0;
1007 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, 0);
1009 _elm_scroll_content_viewport_size_get(obj, &w, NULL);
1010 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1011 ret = (cw - (x + w));
1013 return (ret >= 0) ? ret : 0;
1016 /* Update the wanted coordinates according to the x, y passed
1017 * widget directionality, content size and etc. */
1019 _elm_scroll_wanted_coordinates_update(Elm_Scrollable_Smart_Interface_Data *sid,
1025 if (!sid->pan_obj) return;
1027 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
1029 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1031 /* Update wx/y/w/h - and if the requested positions aren't legal
1033 _elm_scroll_content_viewport_size_get(sid->obj, &sid->ww, &sid->wh);
1036 else if ((x + sid->ww) > cw)
1037 sid->wx = cw - sid->ww;
1038 else if (sid->is_mirrored)
1039 sid->wx = _elm_scroll_x_mirrored_get(sid->obj, x);
1042 if (y < 0) sid->wy = 0;
1043 else if ((y + sid->wh) > ch)
1044 sid->wy = ch - sid->wh;
1049 _elm_scroll_momentum_end(Elm_Scrollable_Smart_Interface_Data *sid)
1051 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator)) return;
1052 if (sid->down.momentum_animator)
1055 _elm_scroll_content_pos_get(sid->obj, &px, &py);
1056 _elm_scroll_wanted_coordinates_update(sid, px, py);
1058 ecore_animator_del(sid->down.momentum_animator);
1059 sid->down.momentum_animator = NULL;
1060 sid->down.bounce_x_hold = EINA_FALSE;
1061 sid->down.bounce_y_hold = EINA_FALSE;
1068 if (sid->content_info.resized)
1069 _elm_scroll_wanted_region_set(sid->obj);
1074 _elm_scroll_bounce_x_animator(void *data)
1076 Elm_Scrollable_Smart_Interface_Data *sid;
1077 Evas_Coord x, y, dx, w, odx, ed, md;
1078 double t, p, dt, pd, r;
1081 t = ecore_loop_time_get();
1082 dt = t - sid->down.anim_start2;
1085 dt = dt / _elm_config->thumbscroll_bounce_friction;
1086 odx = sid->down.b2x - sid->down.bx;
1087 _elm_scroll_content_viewport_size_get(sid->obj, &w, NULL);
1088 if (!sid->down.momentum_animator && (w > abs(odx)))
1090 pd = (double)odx / (double)w;
1091 pd = (pd > 0) ? pd : -pd;
1092 pd = 1.0 - ((1.0 - pd) * (1.0 - pd));
1095 if (dt > 1.0) dt = 1.0;
1096 p = 1.0 - ((1.0 - dt) * (1.0 - dt));
1097 _elm_scroll_content_pos_get(sid->obj, &x, &y);
1100 if (sid->down.momentum_animator)
1102 ed = abs(sid->down.dx * (_elm_config->thumbscroll_friction +
1103 sid->down.extra_time) - sid->down.b0x);
1104 md = abs(_elm_config->thumbscroll_friction * 5 * w);
1105 if (ed > md) r = (double)(md) / (double)ed;
1107 x = sid->down.b2x + (int)((double)(dx - odx) * r);
1108 if (!sid->down.cancelled)
1109 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
1112 if (sid->down.momentum_animator)
1113 sid->down.bounce_x_hold = EINA_TRUE;
1114 if ((!sid->down.bounce_y_animator) &&
1115 (!sid->scrollto.y.animator))
1116 _elm_scroll_anim_stop(sid);
1117 sid->down.bounce_x_animator = NULL;
1119 sid->bouncemex = EINA_FALSE;
1120 _elm_scroll_momentum_end(sid);
1121 if (sid->content_info.resized)
1122 _elm_scroll_wanted_region_set(sid->obj);
1123 return ECORE_CALLBACK_CANCEL;
1126 return ECORE_CALLBACK_RENEW;
1130 _elm_scroll_bounce_y_animator(void *data)
1132 Elm_Scrollable_Smart_Interface_Data *sid;
1133 Evas_Coord x, y, dy, h, ody, ed, md;
1134 double t, p, dt, pd, r;
1137 t = ecore_loop_time_get();
1138 dt = t - sid->down.anim_start3;
1141 dt = dt / _elm_config->thumbscroll_bounce_friction;
1142 ody = sid->down.b2y - sid->down.by;
1143 _elm_scroll_content_viewport_size_get(sid->obj, NULL, &h);
1144 if (!sid->down.momentum_animator && (h > abs(ody)))
1146 pd = (double)ody / (double)h;
1147 pd = (pd > 0) ? pd : -pd;
1148 pd = 1.0 - ((1.0 - pd) * (1.0 - pd));
1151 if (dt > 1.0) dt = 1.0;
1152 p = 1.0 - ((1.0 - dt) * (1.0 - dt));
1153 _elm_scroll_content_pos_get(sid->obj, &x, &y);
1156 if (sid->down.momentum_animator)
1158 ed = abs(sid->down.dy * (_elm_config->thumbscroll_friction +
1159 sid->down.extra_time) - sid->down.b0y);
1160 md = abs(_elm_config->thumbscroll_friction * 5 * h);
1161 if (ed > md) r = (double)(md) / (double)ed;
1163 y = sid->down.b2y + (int)((double)(dy - ody) * r);
1164 if (!sid->down.cancelled)
1165 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
1168 if (sid->down.momentum_animator)
1169 sid->down.bounce_y_hold = EINA_TRUE;
1170 if ((!sid->down.bounce_x_animator) &&
1171 (!sid->scrollto.y.animator))
1172 _elm_scroll_anim_stop(sid);
1173 sid->down.bounce_y_animator = NULL;
1175 sid->bouncemey = EINA_FALSE;
1176 _elm_scroll_momentum_end(sid);
1177 if (sid->content_info.resized)
1178 _elm_scroll_wanted_region_set(sid->obj);
1179 return ECORE_CALLBACK_CANCEL;
1183 return ECORE_CALLBACK_RENEW;
1187 _elm_scroll_bounce_eval(Elm_Scrollable_Smart_Interface_Data *sid)
1189 Evas_Coord mx, my, px, py, bx, by, b2x, b2y, minx = 0, miny = 0;
1191 if (!sid->pan_obj) return;
1193 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
1195 if (sid->freeze) return;
1196 if ((!sid->bouncemex) && (!sid->bouncemey)) return;
1197 if (sid->down.now) return; // down bounce while still held down
1198 if (sid->down.onhold_animator)
1200 ecore_animator_del(sid->down.onhold_animator);
1201 sid->down.onhold_animator = NULL;
1202 if (sid->content_info.resized)
1203 _elm_scroll_wanted_region_set(sid->obj);
1205 if (sid->down.hold_animator)
1207 ecore_animator_del(sid->down.hold_animator);
1208 sid->down.hold_animator = NULL;
1209 if (sid->content_info.resized)
1210 _elm_scroll_wanted_region_set(sid->obj);
1212 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
1213 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
1214 psd->api->pos_get(sid->pan_obj, &px, &py);
1217 if (px < minx) px = minx;
1218 if ((px - minx) > mx) px = mx + minx;
1219 if (py < miny) py = miny;
1220 if ((py - miny) > my) py = my + miny;
1224 (!elm_widget_drag_child_locked_x_get(sid->obj)))
1226 if ((!sid->down.bounce_x_animator) && (!sid->bounce_animator_disabled))
1230 if (sid->scrollto.x.animator)
1232 ecore_animator_del(sid->scrollto.x.animator);
1233 sid->scrollto.x.animator = NULL;
1235 sid->down.bounce_x_animator =
1236 ecore_animator_add(_elm_scroll_bounce_x_animator, sid);
1237 sid->down.anim_start2 = ecore_loop_time_get();
1240 sid->down.b2x = b2x;
1241 if (sid->down.momentum_animator)
1242 sid->down.b0x = sid->down.ax;
1243 else sid->down.b0x = 0;
1248 (!elm_widget_drag_child_locked_y_get(sid->obj)))
1250 if ((!sid->down.bounce_y_animator) && (!sid->bounce_animator_disabled))
1254 if (sid->scrollto.y.animator)
1256 ecore_animator_del(sid->scrollto.y.animator);
1257 sid->scrollto.y.animator = NULL;
1259 sid->down.bounce_y_animator =
1260 ecore_animator_add(_elm_scroll_bounce_y_animator, sid);
1261 sid->down.anim_start3 = ecore_loop_time_get();
1264 sid->down.b2y = b2y;
1265 if (sid->down.momentum_animator)
1266 sid->down.b0y = sid->down.ay;
1267 else sid->down.b0y = 0;
1274 _elm_scroll_content_pos_get(const Evas_Object *obj,
1278 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1280 if (!sid->pan_obj) return;
1282 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
1284 psd->api->pos_get(sid->pan_obj, x, y);
1288 _elm_scroll_content_pos_set(Evas_Object *obj,
1293 Evas_Coord mx = 0, my = 0, px = 0, py = 0, spx = 0, spy = 0, minx = 0, miny = 0;
1294 Evas_Coord cw =0, ch = 0, ww = 0, wh = 0; //// TIZEN ONLY
1297 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1299 if (!sid->edje_obj || !sid->pan_obj) return;
1301 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
1303 // FIXME: allow for bounce outside of range
1304 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
1305 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
1306 psd->api->content_size_get(sid->pan_obj, &cw, &ch); //// TIZEN ONLY
1307 _elm_scroll_content_viewport_size_get(obj, &ww, &wh); //// TIZEN ONLY
1309 psd->api->pos_get(sid->pan_obj, &px, &py);
1314 edje_object_signal_emit(sid->edje_obj, "elm,edge,left", "elm");
1315 if ((x - minx) > mx)
1316 edje_object_signal_emit(sid->edje_obj, "elm,edge,right", "elm");
1321 edje_object_signal_emit(sid->edje_obj, "elm,edge,top", "elm");
1322 if ((y - miny) > my)
1323 edje_object_signal_emit(sid->edje_obj, "elm,edge,bottom", "elm");
1326 if (!_elm_config->thumbscroll_bounce_enable)
1328 if (x < minx) x = minx;
1329 if ((x - minx) > mx) x = mx + minx;
1330 if (y < miny) y = miny;
1331 if ((y - miny) > my) y = my + miny;
1334 if (!sid->bounce_horiz)
1336 if (x < minx) x = minx;
1337 if ((x - minx) > mx) x = mx + minx;
1339 if (!sid->bounce_vert)
1341 if (y < miny) y = miny;
1342 if (y - miny > my) y = my + miny;
1345 if (((!_elm_config->thumbscroll_bounce_enable) ||
1346 (!sid->bounce_horiz)) && (sid->scrollto.x.animator) &&
1347 ((px != x) && ((x == minx) || (x == (mx + minx)))))
1349 ecore_animator_del(sid->scrollto.x.animator);
1350 sid->scrollto.x.animator = NULL;
1353 if (((!_elm_config->thumbscroll_bounce_enable) ||
1354 (!sid->bounce_vert)) && (sid->scrollto.y.animator) &&
1355 ((py != y) && ((y == miny) || (y == (my + miny)))))
1357 ecore_animator_del(sid->scrollto.y.animator);
1358 sid->scrollto.y.animator = NULL;
1361 if (((!_elm_config->thumbscroll_bounce_enable) ||
1362 ((!sid->bounce_horiz) && (!sid->bounce_vert))) &&
1363 (sid->down.momentum_animator) &&
1364 ((((px != x) && ((x == minx) || (x == (mx + minx)))) && (py == y)) ||
1365 (((py != y) && ((y == miny) || (y == (my + miny)))) && (px == x))))
1367 ecore_animator_del(sid->down.momentum_animator);
1368 sid->down.momentum_animator = NULL;
1369 sid->down.bounce_x_hold = EINA_FALSE;
1370 sid->down.bounce_y_hold = EINA_FALSE;
1375 if (sid->content_info.resized)
1376 _elm_scroll_wanted_region_set(sid->obj);
1379 psd->api->pos_set(sid->pan_obj, x, y);
1380 psd->api->pos_get(sid->pan_obj, &spx, &spy);
1382 if (mx > 0) vx = (double)(spx - minx) / (double)mx;
1385 if (vx < 0.0) vx = 0.0;
1389 if (my > 0) vy = (double)(spy - miny) / (double)my;
1392 if (vy < 0.0) vy = 0.0;
1396 edje_object_part_drag_value_set
1397 (sid->edje_obj, "elm.dragable.vbar", 0.0, vy);
1398 edje_object_part_drag_value_set
1399 (sid->edje_obj, "elm.dragable.hbar", vx, 0.0);
1401 if (!sid->down.bounce_x_animator)
1403 if (((x < minx) && (0 <= sid->down.dx)) ||
1404 ((x > (mx + minx)) && (0 >= sid->down.dx)))
1406 sid->bouncemex = EINA_TRUE;
1407 _elm_scroll_bounce_eval(sid);
1410 sid->bouncemex = EINA_FALSE;
1412 if (!sid->down.bounce_y_animator)
1414 if (((y < miny) && (0 <= sid->down.dy)) ||
1415 ((y > (my + miny)) && (0 >= sid->down.dy)))
1417 sid->bouncemey = EINA_TRUE;
1418 _elm_scroll_bounce_eval(sid);
1421 sid->bouncemey = EINA_FALSE;
1426 if ((x != px) || (y != py))
1428 if (sid->cb_func.scroll)
1429 sid->cb_func.scroll(obj, NULL);
1430 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
1433 if (sid->cb_func.scroll_left)
1434 sid->cb_func.scroll_left(obj, NULL);
1435 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,left", "elm");
1439 if (sid->cb_func.scroll_right)
1440 sid->cb_func.scroll_right(obj, NULL);
1441 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,right", "elm");
1445 if (sid->cb_func.scroll_up)
1446 sid->cb_func.scroll_up(obj, NULL);
1447 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,up", "elm");
1451 if (sid->cb_func.scroll_down)
1452 sid->cb_func.scroll_down(obj, NULL);
1453 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,down", "elm");
1460 if (sid->cb_func.edge_left)
1461 sid->cb_func.edge_left(obj, NULL);
1462 edje_object_signal_emit(sid->edje_obj, "elm,edge,left", "elm");
1464 if (x == (mx + minx))
1466 if (sid->cb_func.edge_right)
1467 sid->cb_func.edge_right(obj, NULL);
1468 edje_object_signal_emit(sid->edje_obj, "elm,edge,right", "elm");
1475 if (sid->cb_func.edge_top)
1476 sid->cb_func.edge_top(obj, NULL);
1477 edje_object_signal_emit(sid->edje_obj, "elm,edge,top", "elm");
1481 if (sid->cb_func.edge_bottom)
1482 sid->cb_func.edge_bottom(obj, NULL);
1483 edje_object_signal_emit(sid->edje_obj, "elm,edge,bottom", "elm");
1488 _elm_direction_arrows_eval(sid);
1492 _elm_scroll_mirrored_set(Evas_Object *obj,
1497 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1499 if (!sid->edje_obj) return;
1501 mirrored = !!mirrored;
1503 if (sid->is_mirrored == mirrored)
1506 sid->is_mirrored = mirrored;
1507 edje_object_mirrored_set(sid->edje_obj, mirrored);
1509 if (sid->is_mirrored)
1510 wx = _elm_scroll_x_mirrored_get(sid->obj, sid->wx);
1514 _elm_scroll_content_pos_set(sid->obj, wx, sid->wy, EINA_FALSE);
1517 /* returns TRUE when we need to move the scroller, FALSE otherwise.
1518 * Updates w and h either way, so save them if you need them. */
1520 _elm_scroll_content_region_show_internal(Evas_Object *obj,
1526 Evas_Coord mx = 0, my = 0, cw = 0, ch = 0, px = 0, py = 0, nx, ny,
1527 minx = 0, miny = 0, pw = 0, ph = 0, x = *_x, y = *_y;
1529 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
1531 if (!sid->pan_obj) return EINA_FALSE;
1533 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, EINA_FALSE);
1535 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
1536 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
1537 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1538 psd->api->pos_get(sid->pan_obj, &px, &py);
1539 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &pw, &ph);
1542 if ((x < px) && ((x + w) < (px + (cw - mx)))) nx = x;
1543 else if ((x > px) && ((x + w) > (px + (cw - mx))))
1544 nx = x + w - (cw - mx);
1546 if ((y < py) && ((y + h) < (py + (ch - my)))) ny = y;
1547 else if ((y > py) && ((y + h) > (py + (ch - my))))
1548 ny = y + h - (ch - my);
1550 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
1551 (sid->scrollto.x.animator) || (sid->scrollto.y.animator))
1553 _elm_scroll_anim_stop(sid);
1555 if (sid->scrollto.x.animator)
1557 ecore_animator_del(sid->scrollto.x.animator);
1558 sid->scrollto.x.animator = NULL;
1560 if (sid->scrollto.y.animator)
1562 ecore_animator_del(sid->scrollto.y.animator);
1563 sid->scrollto.y.animator = NULL;
1565 if (sid->down.bounce_x_animator)
1567 ecore_animator_del(sid->down.bounce_x_animator);
1568 sid->down.bounce_x_animator = NULL;
1569 sid->bouncemex = EINA_FALSE;
1570 if (sid->content_info.resized)
1571 _elm_scroll_wanted_region_set(sid->obj);
1573 if (sid->down.bounce_y_animator)
1575 ecore_animator_del(sid->down.bounce_y_animator);
1576 sid->down.bounce_y_animator = NULL;
1577 sid->bouncemey = EINA_FALSE;
1578 if (sid->content_info.resized)
1579 _elm_scroll_wanted_region_set(sid->obj);
1581 if (sid->down.hold_animator)
1583 ecore_animator_del(sid->down.hold_animator);
1584 sid->down.hold_animator = NULL;
1585 _elm_scroll_drag_stop(sid);
1586 if (sid->content_info.resized)
1587 _elm_scroll_wanted_region_set(sid->obj);
1589 if (sid->down.momentum_animator)
1591 ecore_animator_del(sid->down.momentum_animator);
1592 sid->down.momentum_animator = NULL;
1593 sid->down.bounce_x_hold = EINA_FALSE;
1594 sid->down.bounce_y_hold = EINA_FALSE;
1599 if (sid->content_info.resized)
1600 _elm_scroll_wanted_region_set(sid->obj);
1604 if ((x + pw) > cw) x = cw - pw;
1605 if (x < minx) x = minx;
1607 if ((y + ph) > ch) y = ch - ph;
1608 if (y < miny) y = miny;
1610 if ((x == px) && (y == py)) return EINA_FALSE;
1616 /* Set should be used for calculated positions, for example, when we move
1617 * because of an animation or because this is the correct position after
1620 _elm_scroll_content_region_set(Evas_Object *obj,
1626 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1628 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
1630 _elm_scroll_content_pos_set(obj, x, y, EINA_FALSE);
1633 sid->down.x = sid->down.history[0].x;
1634 sid->down.y = sid->down.history[0].y;
1638 /* Set should be used for setting the wanted position, for example a
1639 * user scroll or moving the cursor in an entry. */
1641 _elm_scroll_content_region_show(Evas_Object *obj,
1647 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1653 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
1655 _elm_scroll_content_pos_set(obj, x, y, EINA_TRUE);
1658 sid->down.x = sid->down.history[0].x;
1659 sid->down.y = sid->down.history[0].y;
1664 _elm_scroll_wanted_region_set(Evas_Object *obj)
1666 Evas_Coord ww, wh, wx;
1668 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1672 if (sid->down.now || sid->down.momentum_animator ||
1673 sid->down.bounce_x_animator || sid->down.bounce_y_animator ||
1674 sid->down.hold_animator || sid->down.onhold_animator ||
1675 sid->scrollto.x.animator || sid->scrollto.y.animator)
1678 sid->content_info.resized = EINA_FALSE;
1680 /* Flip to RTL cords only if init in RTL mode */
1681 if (sid->is_mirrored)
1682 wx = _elm_scroll_x_mirrored_get(obj, sid->wx);
1686 _elm_scroll_content_viewport_size_get(obj, &ww, &wh);
1694 _elm_scroll_content_region_set(obj, wx, sid->wy, ww, wh);
1698 _elm_scroll_wheel_event_cb(void *data,
1700 Evas_Object *obj __UNUSED__,
1703 Elm_Scrollable_Smart_Interface_Data *sid;
1704 Evas_Event_Mouse_Wheel *ev;
1705 Evas_Coord x = 0, y = 0, vw = 0, vh = 0, cw = 0, ch = 0;
1709 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
1711 direction = ev->direction;
1712 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1713 if ((evas_key_modifier_is_set(ev->modifiers, "Control")) ||
1714 (evas_key_modifier_is_set(ev->modifiers, "Alt")) ||
1715 (evas_key_modifier_is_set(ev->modifiers, "Meta")) ||
1716 (evas_key_modifier_is_set(ev->modifiers, "Hyper")) ||
1717 (evas_key_modifier_is_set(ev->modifiers, "Super")))
1719 else if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
1720 direction = !direction;
1721 _elm_scroll_content_pos_get(sid->obj, &x, &y);
1722 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
1723 (sid->scrollto.x.animator) || (sid->scrollto.y.animator))
1725 _elm_scroll_anim_stop(sid);
1727 if (sid->scrollto.x.animator)
1729 ecore_animator_del(sid->scrollto.x.animator);
1730 sid->scrollto.x.animator = NULL;
1732 if (sid->scrollto.y.animator)
1734 ecore_animator_del(sid->scrollto.y.animator);
1735 sid->scrollto.y.animator = NULL;
1737 if (sid->down.bounce_x_animator)
1739 ecore_animator_del(sid->down.bounce_x_animator);
1740 sid->down.bounce_x_animator = NULL;
1741 sid->bouncemex = EINA_FALSE;
1742 if (sid->content_info.resized)
1743 _elm_scroll_wanted_region_set(sid->obj);
1745 if (sid->down.bounce_y_animator)
1747 ecore_animator_del(sid->down.bounce_y_animator);
1748 sid->down.bounce_y_animator = NULL;
1749 sid->bouncemey = EINA_FALSE;
1750 if (sid->content_info.resized)
1751 _elm_scroll_wanted_region_set(sid->obj);
1753 _elm_scroll_content_viewport_size_get(sid->obj, &vw, &vh);
1754 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1757 if (ch > vh || cw <= vw)
1758 y += ev->z * sid->step.y;
1760 x += ev->z * sid->step.x;
1762 else if (direction == 1)
1764 if (cw > vw || ch <= vh)
1765 x += ev->z * sid->step.x;
1767 y += ev->z * sid->step.y;
1770 if ((!sid->hold) && (!sid->freeze))
1772 _elm_scroll_wanted_coordinates_update(sid, x, y);
1773 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
1778 _elm_scroll_post_event_up(void *data,
1781 Elm_Scrollable_Smart_Interface_Data *sid = data;
1785 if (sid->down.dragged)
1787 elm_widget_drag_lock_x_set(sid->obj, EINA_FALSE);
1788 elm_widget_drag_lock_y_set(sid->obj, EINA_FALSE);
1795 _paging_is_enabled(Elm_Scrollable_Smart_Interface_Data *sid)
1797 if ((sid->pagerel_h == 0.0) && (!sid->pagesize_h) &&
1798 (sid->pagerel_v == 0.0) && (!sid->pagesize_v))
1804 _elm_scroll_momentum_animator(void *data)
1807 Elm_Scrollable_Smart_Interface_Data *sid = data;
1808 Evas_Coord x, y, dx, dy, px, py, maxx, maxy, minx, miny;
1809 Eina_Bool no_bounce_x_end = EINA_FALSE, no_bounce_y_end = EINA_FALSE;
1811 if (!sid->pan_obj) return ECORE_CALLBACK_CANCEL;
1813 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, ECORE_CALLBACK_CANCEL);
1815 t = ecore_loop_time_get();
1816 dt = t - sid->down.anim_start;
1819 dt = dt / (_elm_config->thumbscroll_friction + sid->down.extra_time);
1820 if (dt > 1.0) dt = 1.0;
1821 p = 1.0 - ((1.0 - dt) * (1.0 - dt));
1822 dx = (sid->down.dx * (_elm_config->thumbscroll_friction +
1823 sid->down.extra_time) * p);
1824 dy = (sid->down.dy * (_elm_config->thumbscroll_friction +
1825 sid->down.extra_time) * p);
1828 x = sid->down.sx - dx;
1829 y = sid->down.sy - dy;
1830 _elm_scroll_content_pos_get(sid->obj, &px, &py);
1831 if ((sid->down.bounce_x_animator) ||
1832 (sid->down.bounce_x_hold))
1834 sid->down.bx = sid->down.bx0 - dx + sid->down.b0x;
1837 if ((sid->down.bounce_y_animator) ||
1838 (sid->down.bounce_y_hold))
1840 sid->down.by = sid->down.by0 - dy + sid->down.b0y;
1843 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
1844 _elm_scroll_wanted_coordinates_update(sid, x, y);
1845 psd->api->pos_max_get(sid->pan_obj, &maxx, &maxy);
1846 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
1847 if (!sid->bounce_horiz)
1849 if (x <= minx) no_bounce_x_end = EINA_TRUE;
1850 if ((x - minx) >= maxx) no_bounce_x_end = EINA_TRUE;
1852 if (!sid->bounce_vert)
1854 if (y <= miny) no_bounce_y_end = EINA_TRUE;
1855 if ((y - miny) >= maxy) no_bounce_y_end = EINA_TRUE;
1858 ((sid->down.bounce_x_hold) && (sid->down.bounce_y_hold)) ||
1859 (no_bounce_x_end && no_bounce_y_end))
1861 _elm_scroll_anim_stop(sid);
1863 sid->down.momentum_animator = NULL;
1864 sid->down.bounce_x_hold = EINA_FALSE;
1865 sid->down.bounce_y_hold = EINA_FALSE;
1870 if (sid->content_info.resized)
1871 _elm_scroll_wanted_region_set(sid->obj);
1873 return ECORE_CALLBACK_CANCEL;
1877 return ECORE_CALLBACK_RENEW;
1881 _elm_scroll_page_x_get(Elm_Scrollable_Smart_Interface_Data *sid,
1884 Evas_Coord x, y, w, h, cw, ch, minx = 0;
1886 if (!sid->pan_obj) return 0;
1888 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, 0);
1890 _elm_scroll_content_pos_get(sid->obj, &x, &y);
1891 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
1892 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1893 psd->api->pos_min_get(sid->pan_obj, &minx, NULL);
1897 if (sid->pagerel_h > 0.0)
1898 sid->pagesize_h = w * sid->pagerel_h;
1899 if (sid->pagesize_h > 0)
1901 x = x + (sid->pagesize_h * 0.5);
1902 x = x / (sid->pagesize_h);
1903 x = x * (sid->pagesize_h);
1905 if ((x + w) > cw) x = cw - w;
1906 if (x < minx) x = minx;
1912 _elm_scroll_page_y_get(Elm_Scrollable_Smart_Interface_Data *sid,
1915 Evas_Coord x, y, w, h, cw, ch, miny = 0;
1917 if (!sid->pan_obj) return 0;
1919 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, 0);
1921 _elm_scroll_content_pos_get(sid->obj, &x, &y);
1922 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
1923 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1924 psd->api->pos_min_get(sid->pan_obj, NULL, &miny);
1928 if (sid->pagerel_v > 0.0)
1929 sid->pagesize_v = h * sid->pagerel_v;
1930 if (sid->pagesize_v > 0)
1932 y = y + (sid->pagesize_v * 0.5);
1933 y = y / (sid->pagesize_v);
1934 y = y * (sid->pagesize_v);
1936 if ((y + h) > ch) y = ch - h;
1937 if (y < miny) y = miny;
1943 _elm_scroll_scroll_to_x_animator(void *data)
1945 Elm_Scrollable_Smart_Interface_Data *sid = data;
1949 if (!sid->pan_obj) return ECORE_CALLBACK_CANCEL;
1951 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, ECORE_CALLBACK_CANCEL);
1953 t = ecore_loop_time_get();
1954 tt = (t - sid->scrollto.x.t_start) /
1955 (sid->scrollto.x.t_end - sid->scrollto.x.t_start);
1957 tt = 1.0 - (tt * tt);
1958 psd->api->pos_get(sid->pan_obj, &px, &py);
1959 px = (sid->scrollto.x.start * (1.0 - tt)) +
1960 (sid->scrollto.x.end * tt);
1961 if (t >= sid->scrollto.x.t_end)
1963 px = sid->scrollto.x.end;
1964 _elm_scroll_content_pos_set(sid->obj, px, py, EINA_TRUE);
1966 sid->down.x = sid->down.history[0].x;
1967 _elm_scroll_wanted_coordinates_update(sid, px, py);
1968 sid->scrollto.x.animator = NULL;
1969 if ((!sid->scrollto.y.animator) && (!sid->down.bounce_y_animator))
1970 _elm_scroll_anim_stop(sid);
1971 return ECORE_CALLBACK_CANCEL;
1973 _elm_scroll_content_pos_set(sid->obj, px, py, EINA_TRUE);
1974 _elm_scroll_wanted_coordinates_update(sid, px, py);
1975 return ECORE_CALLBACK_RENEW;
1979 _elm_scroll_scroll_to_y_animator(void *data)
1981 Elm_Scrollable_Smart_Interface_Data *sid = data;
1985 if (!sid->pan_obj) return EINA_FALSE;
1987 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, EINA_FALSE);
1989 t = ecore_loop_time_get();
1990 tt = (t - sid->scrollto.y.t_start) /
1991 (sid->scrollto.y.t_end - sid->scrollto.y.t_start);
1993 tt = 1.0 - (tt * tt);
1994 psd->api->pos_get(sid->pan_obj, &px, &py);
1995 py = (sid->scrollto.y.start * (1.0 - tt)) +
1996 (sid->scrollto.y.end * tt);
1997 if (t >= sid->scrollto.y.t_end)
1999 py = sid->scrollto.y.end;
2000 _elm_scroll_content_pos_set(sid->obj, px, py, EINA_TRUE);
2002 sid->down.y = sid->down.history[0].y;
2003 _elm_scroll_wanted_coordinates_update(sid, px, py);
2004 sid->scrollto.y.animator = NULL;
2005 if ((!sid->scrollto.x.animator) && (!sid->down.bounce_x_animator))
2006 _elm_scroll_anim_stop(sid);
2007 return ECORE_CALLBACK_CANCEL;
2009 _elm_scroll_content_pos_set(sid->obj, px, py, EINA_TRUE);
2010 _elm_scroll_wanted_coordinates_update(sid, px, py);
2012 return ECORE_CALLBACK_RENEW;
2016 _elm_scroll_scroll_to_y(Elm_Scrollable_Smart_Interface_Data *sid,
2020 Evas_Coord px, py, x, y, w, h;
2023 if (!sid->pan_obj) return;
2025 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2027 if (sid->freeze) return;
2030 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2031 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
2033 _elm_scroll_content_region_set(sid->obj, x, y, w, h);
2036 t = ecore_loop_time_get();
2037 psd->api->pos_get(sid->pan_obj, &px, &py);
2038 sid->scrollto.y.start = py;
2039 sid->scrollto.y.end = pos_y;
2040 sid->scrollto.y.t_start = t;
2041 sid->scrollto.y.t_end = t + t_in;
2042 if (!sid->scrollto.y.animator)
2044 sid->scrollto.y.animator =
2045 ecore_animator_add(_elm_scroll_scroll_to_y_animator, sid);
2046 if (!sid->scrollto.x.animator)
2047 _elm_scroll_anim_start(sid);
2049 if (sid->down.bounce_y_animator)
2051 ecore_animator_del(sid->down.bounce_y_animator);
2052 sid->down.bounce_y_animator = NULL;
2053 _elm_scroll_momentum_end(sid);
2054 if (sid->content_info.resized)
2055 _elm_scroll_wanted_region_set(sid->obj);
2057 sid->bouncemey = EINA_FALSE;
2061 _elm_scroll_scroll_to_x(Elm_Scrollable_Smart_Interface_Data *sid,
2065 Evas_Coord px, py, x, y, w, h;
2068 if (!sid->pan_obj) return;
2070 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2072 if (sid->freeze) return;
2075 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2076 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
2078 _elm_scroll_content_region_set(sid->obj, x, y, w, h);
2081 t = ecore_loop_time_get();
2082 psd->api->pos_get(sid->pan_obj, &px, &py);
2083 sid->scrollto.x.start = px;
2084 sid->scrollto.x.end = pos_x;
2085 sid->scrollto.x.t_start = t;
2086 sid->scrollto.x.t_end = t + t_in;
2087 if (!sid->scrollto.x.animator)
2089 sid->scrollto.x.animator =
2090 ecore_animator_add(_elm_scroll_scroll_to_x_animator, sid);
2091 if (!sid->scrollto.y.animator)
2092 _elm_scroll_anim_start(sid);
2094 if (sid->down.bounce_x_animator)
2096 ecore_animator_del(sid->down.bounce_x_animator);
2097 sid->down.bounce_x_animator = NULL;
2098 _elm_scroll_momentum_end(sid);
2099 if (sid->content_info.resized)
2100 _elm_scroll_wanted_region_set(sid->obj);
2102 sid->bouncemex = EINA_FALSE;
2106 _elm_scroll_mouse_up_event_cb(void *data,
2108 Evas_Object *obj __UNUSED__,
2111 Elm_Scrollable_Smart_Interface_Data *sid = data;
2112 Evas_Coord x = 0, y = 0, ox = 0, oy = 0;
2113 Evas_Event_Mouse_Down *ev;
2115 if (!sid->pan_obj) return;
2117 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2120 sid->down.hold_parent = EINA_FALSE;
2123 evas_post_event_callback_push(e, _elm_scroll_post_event_up, sid);
2125 // FIXME: respect elm_widget_scroll_hold_get of parent container
2126 if (!_elm_config->thumbscroll_enable) return;
2128 if (ev->button == 1)
2130 if (sid->down.onhold_animator)
2132 ecore_animator_del(sid->down.onhold_animator);
2133 sid->down.onhold_animator = NULL;
2134 if (sid->content_info.resized)
2135 _elm_scroll_wanted_region_set(sid->obj);
2137 x = ev->canvas.x - sid->down.x;
2138 y = ev->canvas.y - sid->down.y;
2139 if (sid->down.dragged)
2141 _elm_scroll_drag_stop(sid);
2142 if ((!sid->hold) && (!sid->freeze))
2146 Evas_Coord ax, ay, dx, dy, vel;
2149 t = ev->timestamp / 1000.0;
2151 t = ecore_loop_time_get();
2154 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2159 DBG("------ %i %i\n", ev->canvas.x, ev->canvas.y);
2161 for (i = 0; i < 60; i++)
2163 dt = t - sid->down.history[i].timestamp;
2164 if (dt > 0.2) break;
2166 DBG("H: %i %i @ %1.3f\n",
2167 sid->down.history[i].x,
2168 sid->down.history[i].y, dt);
2171 ax += sid->down.history[i].x;
2172 ay += sid->down.history[i].y;
2177 at /= _elm_config->thumbscroll_sensitivity_friction;
2178 dx = ev->canvas.x - ax;
2179 dy = ev->canvas.y - ay;
2182 vel = sqrt((dx * dx) + (dy * dy)) / at;
2183 if ((_elm_config->thumbscroll_friction > 0.0) &&
2184 (vel > _elm_config->thumbscroll_momentum_threshold))
2186 sid->down.dx = ((double)dx / at);
2187 sid->down.dy = ((double)dy / at);
2188 sid->down.extra_time = 0.0;
2189 sid->down.pdx = sid->down.dx;
2190 sid->down.pdy = sid->down.dy;
2193 if (!_paging_is_enabled(sid))
2195 if ((!sid->down.momentum_animator) &&
2196 (!sid->momentum_animator_disabled) &&
2198 (!elm_widget_drag_child_locked_y_get
2201 sid->down.momentum_animator =
2203 (_elm_scroll_momentum_animator, sid);
2205 EVAS_EVENT_FLAG_ON_SCROLL;
2206 _elm_scroll_anim_start(sid);
2208 sid->down.anim_start = ecore_loop_time_get();
2209 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2223 evas_event_feed_hold(e, 0, ev->timestamp, ev->data);
2224 if (_paging_is_enabled(sid))
2226 Evas_Coord pgx, pgy;
2228 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2230 (!elm_widget_drag_child_locked_x_get
2233 pgx = _elm_scroll_page_x_get(sid, ox);
2236 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2237 _elm_scroll_scroll_to_x
2238 (sid, _elm_config->page_scroll_friction, pgx);
2242 (!elm_widget_drag_child_locked_y_get
2245 pgy = _elm_scroll_page_y_get(sid, oy);
2248 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2249 _elm_scroll_scroll_to_y
2250 (sid, _elm_config->page_scroll_friction, pgy);
2259 if (_paging_is_enabled(sid))
2261 Evas_Coord pgx, pgy;
2263 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2265 (!elm_widget_drag_child_locked_x_get
2268 pgx = _elm_scroll_page_x_get(sid, ox);
2270 _elm_scroll_scroll_to_x
2271 (sid, _elm_config->page_scroll_friction, pgx);
2274 (!elm_widget_drag_child_locked_y_get
2277 pgy = _elm_scroll_page_y_get(sid, oy);
2279 _elm_scroll_scroll_to_y
2280 (sid, _elm_config->page_scroll_friction, pgy);
2284 if (sid->down.hold_animator)
2286 ecore_animator_del(sid->down.hold_animator);
2287 sid->down.hold_animator = NULL;
2288 if (sid->content_info.resized)
2289 _elm_scroll_wanted_region_set(sid->obj);
2291 if (sid->down.scroll)
2293 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2294 sid->down.scroll = EINA_FALSE;
2298 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2299 sid->down.hold = EINA_FALSE;
2301 sid->down.dragged_began = EINA_FALSE;
2302 sid->down.dir_x = EINA_FALSE;
2303 sid->down.dir_y = EINA_FALSE;
2304 sid->down.want_dragged = EINA_FALSE;
2305 sid->down.dragged = EINA_FALSE;
2306 sid->down.now = EINA_FALSE;
2307 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2308 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
2309 _elm_scroll_wanted_coordinates_update(sid, x, y);
2311 if (sid->content_info.resized)
2312 _elm_scroll_wanted_region_set(sid->obj);
2314 if (!_paging_is_enabled(sid))
2315 _elm_scroll_bounce_eval(sid);
2320 _elm_scroll_mouse_down_event_cb(void *data,
2322 Evas_Object *obj __UNUSED__,
2325 Elm_Scrollable_Smart_Interface_Data *sid;
2326 Evas_Event_Mouse_Down *ev;
2327 Evas_Coord x = 0, y = 0;
2332 if (_elm_config->thumbscroll_enable)
2334 sid->down.hold = EINA_FALSE;
2335 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
2336 (sid->down.momentum_animator) || (sid->scrollto.x.animator) ||
2337 (sid->scrollto.y.animator))
2339 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL |
2340 EVAS_EVENT_FLAG_ON_HOLD;
2341 sid->down.scroll = EINA_TRUE;
2342 sid->down.hold = EINA_TRUE;
2343 _elm_scroll_anim_stop(sid);
2345 if (sid->scrollto.x.animator)
2347 ecore_animator_del(sid->scrollto.x.animator);
2348 sid->scrollto.x.animator = NULL;
2350 if (sid->scrollto.y.animator)
2352 ecore_animator_del(sid->scrollto.y.animator);
2353 sid->scrollto.y.animator = NULL;
2355 if (sid->down.bounce_x_animator)
2357 ecore_animator_del(sid->down.bounce_x_animator);
2358 sid->down.bounce_x_animator = NULL;
2359 sid->bouncemex = EINA_FALSE;
2360 if (sid->content_info.resized)
2361 _elm_scroll_wanted_region_set(sid->obj);
2363 if (sid->down.bounce_y_animator)
2365 ecore_animator_del(sid->down.bounce_y_animator);
2366 sid->down.bounce_y_animator = NULL;
2367 sid->bouncemey = EINA_FALSE;
2368 if (sid->content_info.resized)
2369 _elm_scroll_wanted_region_set(sid->obj);
2371 if (sid->down.hold_animator)
2373 ecore_animator_del(sid->down.hold_animator);
2374 sid->down.hold_animator = NULL;
2375 _elm_scroll_drag_stop(sid);
2376 if (sid->content_info.resized)
2377 _elm_scroll_wanted_region_set(sid->obj);
2379 if (sid->down.momentum_animator)
2381 ecore_animator_del(sid->down.momentum_animator);
2382 sid->down.momentum_animator = NULL;
2383 sid->down.bounce_x_hold = EINA_FALSE;
2384 sid->down.bounce_y_hold = EINA_FALSE;
2387 if (sid->content_info.resized)
2388 _elm_scroll_wanted_region_set(sid->obj);
2390 if (ev->button == 1)
2392 sid->down.hist.est_timestamp_diff =
2393 ecore_loop_time_get() - ((double)ev->timestamp / 1000.0);
2394 sid->down.hist.tadd = 0.0;
2395 sid->down.hist.dxsum = 0.0;
2396 sid->down.hist.dysum = 0.0;
2397 sid->down.now = EINA_TRUE;
2398 sid->down.dragged = EINA_FALSE;
2399 sid->down.dir_x = EINA_FALSE;
2400 sid->down.dir_y = EINA_FALSE;
2401 sid->down.x = ev->canvas.x;
2402 sid->down.y = ev->canvas.y;
2403 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2406 sid->down.locked = EINA_FALSE;
2407 memset(&(sid->down.history[0]), 0,
2408 sizeof(sid->down.history[0]) * 60);
2410 sid->down.history[0].timestamp = ev->timestamp / 1000.0;
2411 sid->down.history[0].localtimestamp = ecore_loop_time_get();
2413 sid->down.history[0].timestamp = ecore_loop_time_get();
2415 sid->down.history[0].x = ev->canvas.x;
2416 sid->down.history[0].y = ev->canvas.y;
2418 sid->down.dragged_began = EINA_FALSE;
2419 sid->down.hold_parent = EINA_FALSE;
2420 sid->down.cancelled = EINA_FALSE;
2421 if (sid->hold || sid->freeze)
2422 sid->down.want_reset = EINA_TRUE;
2424 sid->down.want_reset = EINA_FALSE;
2429 _elm_scroll_can_scroll(Elm_Scrollable_Smart_Interface_Data *sid,
2432 Evas_Coord mx = 0, my = 0, px = 0, py = 0, minx = 0, miny = 0;
2434 if (!sid->pan_obj) return EINA_FALSE;
2436 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, EINA_FALSE);
2438 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
2439 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
2440 psd->api->pos_get(sid->pan_obj, &px, &py);
2444 if (px > minx) return EINA_TRUE;
2448 if ((px - minx) < mx) return EINA_TRUE;
2452 if (py > miny) return EINA_TRUE;
2456 if ((py - miny) < my) return EINA_TRUE;
2466 _elm_scroll_post_event_move(void *data,
2469 Elm_Scrollable_Smart_Interface_Data *sid = data;
2471 if (sid->down.want_dragged)
2475 if (sid->down.hold_parent)
2477 if ((sid->down.dir_x) &&
2478 !_elm_scroll_can_scroll(sid, sid->down.hdir))
2480 sid->down.dir_x = EINA_FALSE;
2482 if ((sid->down.dir_y) &&
2483 !_elm_scroll_can_scroll(sid, sid->down.vdir))
2485 sid->down.dir_y = EINA_FALSE;
2488 if (sid->down.dir_x)
2491 (!elm_widget_drag_child_locked_x_get(sid->obj)))
2493 sid->down.want_dragged = EINA_FALSE;
2494 sid->down.dragged = EINA_TRUE;
2497 elm_widget_drag_lock_x_set(sid->obj, 1);
2502 sid->down.dir_x = EINA_FALSE;
2504 if (sid->down.dir_y)
2507 (!elm_widget_drag_child_locked_y_get(sid->obj)))
2509 sid->down.want_dragged = EINA_FALSE;
2510 sid->down.dragged = EINA_TRUE;
2513 elm_widget_drag_lock_y_set
2514 (sid->obj, EINA_TRUE);
2519 sid->down.dir_y = EINA_FALSE;
2521 if ((!sid->down.dir_x) && (!sid->down.dir_y))
2523 sid->down.cancelled = EINA_TRUE;
2525 if (start) _elm_scroll_drag_start(sid);
2532 _elm_scroll_down_coord_eval(Elm_Scrollable_Smart_Interface_Data *sid,
2536 Evas_Coord minx, miny;
2538 if (!sid->pan_obj) return;
2540 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2542 if (sid->down.dir_x) *x = sid->down.sx - (*x - sid->down.x);
2543 else *x = sid->down.sx;
2544 if (sid->down.dir_y) *y = sid->down.sy - (*y - sid->down.y);
2545 else *y = sid->down.sy;
2547 if ((sid->down.dir_x) || (sid->down.dir_y))
2549 if (!((sid->down.dir_x) && (sid->down.dir_y)))
2551 if (sid->down.dir_x) *y = sid->down.locked_y;
2552 else *x = sid->down.locked_x;
2556 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
2559 *x += (minx - *x) * _elm_config->thumbscroll_border_friction;
2560 else if (sid->content_info.w <= sid->w)
2561 *x += (sid->down.sx - *x) * _elm_config->thumbscroll_border_friction;
2562 else if ((sid->content_info.w - sid->w + minx) < *x)
2563 *x += (sid->content_info.w - sid->w + minx - *x) *
2564 _elm_config->thumbscroll_border_friction;
2567 *y += (miny - *y) * _elm_config->thumbscroll_border_friction;
2568 else if (sid->content_info.h <= sid->h)
2569 *y += (sid->down.sy - *y) * _elm_config->thumbscroll_border_friction;
2570 else if ((sid->content_info.h - sid->h + miny) < *y)
2571 *y += (sid->content_info.h - sid->h + miny - *y) *
2572 _elm_config->thumbscroll_border_friction;
2576 _elm_scroll_hold_animator(void *data)
2578 Elm_Scrollable_Smart_Interface_Data *sid = data;
2579 Evas_Coord ox = 0, oy = 0, fx = 0, fy = 0;
2581 fx = sid->down.hold_x;
2582 fy = sid->down.hold_y;
2584 _elm_scroll_content_pos_get(sid->obj, &ox, &oy);
2585 if (sid->down.dir_x)
2588 (!elm_widget_drag_child_locked_x_get(sid->obj)))
2591 if (sid->down.dir_y)
2594 (!elm_widget_drag_child_locked_y_get(sid->obj)))
2598 _elm_scroll_content_pos_set(sid->obj, ox, oy, EINA_TRUE);
2600 return ECORE_CALLBACK_RENEW;
2604 _elm_scroll_on_hold_animator(void *data)
2608 Evas_Coord x, y, ox, oy;
2609 Elm_Scrollable_Smart_Interface_Data *sid;
2612 t = ecore_loop_time_get();
2613 if (sid->down.onhold_tlast > 0.0)
2615 td = t - sid->down.onhold_tlast;
2616 vx = sid->down.onhold_vx * td *
2617 (double)_elm_config->thumbscroll_hold_threshold * 2.0;
2618 vy = sid->down.onhold_vy * td *
2619 (double)_elm_config->thumbscroll_hold_threshold * 2.0;
2620 _elm_scroll_content_pos_get(sid->obj, &ox, &oy);
2624 if (sid->down.dir_x)
2627 (!elm_widget_drag_child_locked_x_get(sid->obj)))
2629 sid->down.onhold_vxe += vx;
2630 x = ox + (int)sid->down.onhold_vxe;
2631 sid->down.onhold_vxe -= (int)sid->down.onhold_vxe;
2635 if (sid->down.dir_y)
2638 (!elm_widget_drag_child_locked_y_get(sid->obj)))
2640 sid->down.onhold_vye += vy;
2641 y = oy + (int)sid->down.onhold_vye;
2642 sid->down.onhold_vye -= (int)sid->down.onhold_vye;
2646 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
2648 sid->down.onhold_tlast = t;
2650 return ECORE_CALLBACK_RENEW;
2654 _elm_scroll_mouse_move_event_cb(void *data,
2656 Evas_Object *obj __UNUSED__,
2659 Elm_Scrollable_Smart_Interface_Data *sid = data;
2660 Evas_Event_Mouse_Move *ev;
2661 Evas_Coord x = 0, y = 0;
2663 if (!sid->pan_obj) return;
2665 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2668 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
2669 sid->down.hold_parent = EINA_TRUE;
2670 evas_post_event_callback_push(e, _elm_scroll_post_event_move, sid);
2672 // FIXME: respect elm_widget_scroll_hold_get of parent container
2673 if (_elm_config->thumbscroll_enable)
2679 if ((sid->scrollto.x.animator) && (!sid->hold) && (!sid->freeze))
2682 ecore_animator_del(sid->scrollto.x.animator);
2683 sid->scrollto.x.animator = NULL;
2684 psd->api->pos_get(sid->pan_obj, &px, NULL);
2686 sid->down.x = sid->down.history[0].x;
2689 if ((sid->scrollto.y.animator) && (!sid->hold) && (!sid->freeze))
2692 ecore_animator_del(sid->scrollto.y.animator);
2693 sid->scrollto.y.animator = NULL;
2694 psd->api->pos_get(sid->pan_obj, NULL, &py);
2696 sid->down.y = sid->down.history[0].y;
2700 DBG("::: %i %i\n", ev->cur.canvas.x, ev->cur.canvas.y);
2702 memmove(&(sid->down.history[1]), &(sid->down.history[0]),
2703 sizeof(sid->down.history[0]) * (60 - 1));
2705 sid->down.history[0].timestamp = ev->timestamp / 1000.0;
2706 sid->down.history[0].localtimestamp = ecore_loop_time_get();
2708 sid->down.history[0].timestamp = ecore_loop_time_get();
2710 sid->down.history[0].x = ev->cur.canvas.x;
2711 sid->down.history[0].y = ev->cur.canvas.y;
2713 if (!sid->down.dragged_began)
2715 x = ev->cur.canvas.x - sid->down.x;
2716 y = ev->cur.canvas.y - sid->down.y;
2718 sid->down.hdir = -1;
2719 sid->down.vdir = -1;
2721 if (x > 0) sid->down.hdir = LEFT;
2723 sid->down.hdir = RIGHT;
2724 if (y > 0) sid->down.vdir = UP;
2726 sid->down.vdir = DOWN;
2731 if ((sid->one_direction_at_a_time) &&
2732 (!((sid->down.dir_x) || (sid->down.dir_y))))
2734 if (x > _elm_config->thumbscroll_threshold)
2738 sid->down.dir_x = EINA_TRUE;
2739 sid->down.dir_y = EINA_FALSE;
2743 if (y > _elm_config->thumbscroll_threshold)
2747 sid->down.dir_x = EINA_FALSE;
2748 sid->down.dir_y = EINA_TRUE;
2754 sid->down.dir_x = EINA_TRUE;
2755 sid->down.dir_y = EINA_TRUE;
2760 sid->down.dir_x = EINA_TRUE;
2761 sid->down.dir_y = EINA_TRUE;
2764 if ((!sid->hold) && (!sid->freeze))
2766 if ((sid->down.dragged) ||
2767 (((x * x) + (y * y)) >
2768 (_elm_config->thumbscroll_threshold *
2769 _elm_config->thumbscroll_threshold)))
2771 sid->down.dragged_began = EINA_TRUE;
2772 if (!sid->down.dragged)
2774 sid->down.want_dragged = EINA_TRUE;
2775 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2777 if (sid->down.dragged)
2779 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2781 if (sid->down.dir_x)
2782 x = sid->down.sx - (ev->cur.canvas.x - sid->down.x);
2785 if (sid->down.dir_y)
2786 y = sid->down.sy - (ev->cur.canvas.y - sid->down.y);
2789 if (sid->down.want_reset)
2791 sid->down.x = ev->cur.canvas.x;
2792 sid->down.y = ev->cur.canvas.y;
2793 sid->down.want_reset = EINA_FALSE;
2795 if ((sid->down.dir_x) || (sid->down.dir_y))
2797 if (!sid->down.locked)
2799 sid->down.locked_x = x;
2800 sid->down.locked_y = y;
2801 sid->down.locked = EINA_TRUE;
2803 if (!((sid->down.dir_x) && (sid->down.dir_y)))
2805 if (sid->down.dir_x) y = sid->down.locked_y;
2806 else x = sid->down.locked_x;
2810 Evas_Coord minx, miny, mx, my;
2812 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
2813 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
2816 _elm_config->thumbscroll_border_friction;
2818 y += (sid->down.sy - y) *
2819 _elm_config->thumbscroll_border_friction;
2820 else if ((my + miny) < y)
2821 y += (my + miny - y) *
2822 _elm_config->thumbscroll_border_friction;
2825 _elm_config->thumbscroll_border_friction;
2827 x += (sid->down.sx - x) *
2828 _elm_config->thumbscroll_border_friction;
2829 else if ((mx + minx) < x)
2830 x += (mx + minx - x) *
2831 _elm_config->thumbscroll_border_friction;
2834 sid->down.hold_x = x;
2835 sid->down.hold_y = y;
2836 if (!sid->down.hold_animator)
2837 sid->down.hold_animator =
2838 ecore_animator_add(_elm_scroll_hold_animator, sid);
2842 if (sid->down.dragged_began)
2844 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2845 if (!sid->down.hold)
2847 sid->down.hold = EINA_TRUE;
2848 evas_event_feed_hold
2849 (e, 1, ev->timestamp, ev->data);
2854 else if (!sid->freeze)
2856 double vx = 0.0, vy = 0.0;
2858 x = ev->cur.canvas.x - sid->x;
2859 y = ev->cur.canvas.y - sid->y;
2860 if (x < _elm_config->thumbscroll_hold_threshold)
2862 if (_elm_config->thumbscroll_hold_threshold > 0.0)
2863 vx = -(double)(_elm_config->thumbscroll_hold_threshold - x)
2864 / _elm_config->thumbscroll_hold_threshold;
2868 else if (x > (sid->w - _elm_config->thumbscroll_hold_threshold))
2870 if (_elm_config->thumbscroll_hold_threshold > 0.0)
2871 vx = (double)(_elm_config->thumbscroll_hold_threshold -
2873 _elm_config->thumbscroll_hold_threshold;
2877 if (y < _elm_config->thumbscroll_hold_threshold)
2879 if (_elm_config->thumbscroll_hold_threshold > 0.0)
2880 vy = -(double)(_elm_config->thumbscroll_hold_threshold - y)
2881 / _elm_config->thumbscroll_hold_threshold;
2885 else if (y > (sid->h - _elm_config->thumbscroll_hold_threshold))
2887 if (_elm_config->thumbscroll_hold_threshold > 0.0)
2888 vy = (double)(_elm_config->thumbscroll_hold_threshold -
2890 _elm_config->thumbscroll_hold_threshold;
2894 if ((vx != 0.0) || (vy != 0.0))
2896 sid->down.onhold_vx = vx;
2897 sid->down.onhold_vy = vy;
2898 if (!sid->down.onhold_animator)
2900 sid->down.onhold_vxe = 0.0;
2901 sid->down.onhold_vye = 0.0;
2902 sid->down.onhold_tlast = 0.0;
2903 sid->down.onhold_animator = ecore_animator_add
2904 (_elm_scroll_on_hold_animator, sid);
2909 if (sid->down.onhold_animator)
2911 ecore_animator_del(sid->down.onhold_animator);
2912 sid->down.onhold_animator = NULL;
2913 if (sid->content_info.resized)
2914 _elm_scroll_wanted_region_set(sid->obj);
2923 _elm_scroll_page_adjust(Elm_Scrollable_Smart_Interface_Data *sid)
2925 Evas_Coord x, y, w, h;
2927 if (!_paging_is_enabled(sid)) return;
2929 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
2931 x = _elm_scroll_page_x_get(sid, 0);
2932 y = _elm_scroll_page_y_get(sid, 0);
2934 _elm_scroll_content_region_set(sid->obj, x, y, w, h);
2938 _elm_scroll_reconfigure(Elm_Scrollable_Smart_Interface_Data *sid)
2940 _elm_scroll_scroll_bar_size_adjust(sid);
2941 _elm_scroll_page_adjust(sid);
2945 _on_edje_move(void *data,
2947 Evas_Object *edje_obj,
2948 void *event_info __UNUSED__)
2950 Elm_Scrollable_Smart_Interface_Data *sid = data;
2953 evas_object_geometry_get(edje_obj, &x, &y, NULL, NULL);
2958 _elm_scroll_reconfigure(sid);
2962 _on_edje_resize(void *data,
2964 Evas_Object *edje_obj,
2965 void *event_info __UNUSED__)
2967 Elm_Scrollable_Smart_Interface_Data *sid = data;
2970 evas_object_geometry_get(edje_obj, NULL, NULL, &w, &h);
2975 _elm_scroll_reconfigure(sid);
2976 _elm_scroll_wanted_region_set(sid->obj);
2980 _scroll_edje_object_attach(Evas_Object *obj)
2982 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
2984 evas_object_event_callback_add
2985 (sid->edje_obj, EVAS_CALLBACK_RESIZE, _on_edje_resize, sid);
2986 evas_object_event_callback_add
2987 (sid->edje_obj, EVAS_CALLBACK_MOVE, _on_edje_move, sid);
2989 edje_object_signal_callback_add
2990 (sid->edje_obj, "drag", "elm.dragable.vbar", _elm_scroll_vbar_drag_cb,
2992 edje_object_signal_callback_add
2993 (sid->edje_obj, "drag,set", "elm.dragable.vbar",
2994 _elm_scroll_edje_drag_v_cb, sid);
2995 edje_object_signal_callback_add
2996 (sid->edje_obj, "drag,start", "elm.dragable.vbar",
2997 _elm_scroll_edje_drag_v_start_cb, sid);
2998 edje_object_signal_callback_add
2999 (sid->edje_obj, "drag,stop", "elm.dragable.vbar",
3000 _elm_scroll_edje_drag_v_stop_cb, sid);
3001 edje_object_signal_callback_add
3002 (sid->edje_obj, "drag,step", "elm.dragable.vbar",
3003 _elm_scroll_edje_drag_v_cb, sid);
3004 edje_object_signal_callback_add
3005 (sid->edje_obj, "drag,page", "elm.dragable.vbar",
3006 _elm_scroll_edje_drag_v_cb, sid);
3007 edje_object_signal_callback_add
3008 (sid->edje_obj, "elm,vbar,press", "elm",
3009 _elm_scroll_vbar_press_cb, sid);
3010 edje_object_signal_callback_add
3011 (sid->edje_obj, "elm,vbar,unpress", "elm",
3012 _elm_scroll_vbar_unpress_cb, sid);
3013 edje_object_signal_callback_add
3014 (sid->edje_obj, "drag", "elm.dragable.hbar", _elm_scroll_hbar_drag_cb,
3016 edje_object_signal_callback_add
3017 (sid->edje_obj, "drag,set", "elm.dragable.hbar",
3018 _elm_scroll_edje_drag_h_cb, sid);
3019 edje_object_signal_callback_add
3020 (sid->edje_obj, "drag,start", "elm.dragable.hbar",
3021 _elm_scroll_edje_drag_h_start_cb, sid);
3022 edje_object_signal_callback_add
3023 (sid->edje_obj, "drag,stop", "elm.dragable.hbar",
3024 _elm_scroll_edje_drag_h_stop_cb, sid);
3025 edje_object_signal_callback_add
3026 (sid->edje_obj, "drag,step", "elm.dragable.hbar",
3027 _elm_scroll_edje_drag_h_cb, sid);
3028 edje_object_signal_callback_add
3029 (sid->edje_obj, "drag,page", "elm.dragable.hbar",
3030 _elm_scroll_edje_drag_h_cb, sid);
3031 edje_object_signal_callback_add
3032 (sid->edje_obj, "elm,hbar,press", "elm",
3033 _elm_scroll_hbar_press_cb, sid);
3034 edje_object_signal_callback_add
3035 (sid->edje_obj, "elm,hbar,unpress", "elm",
3036 _elm_scroll_hbar_unpress_cb, sid);
3040 _scroll_event_object_attach(Evas_Object *obj)
3042 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3044 evas_object_event_callback_add
3045 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL, _elm_scroll_wheel_event_cb,
3047 evas_object_event_callback_add
3048 (sid->event_rect, EVAS_CALLBACK_MOUSE_DOWN,
3049 _elm_scroll_mouse_down_event_cb, sid);
3050 evas_object_event_callback_add
3051 (sid->event_rect, EVAS_CALLBACK_MOUSE_UP,
3052 _elm_scroll_mouse_up_event_cb, sid);
3053 evas_object_event_callback_add
3054 (sid->event_rect, EVAS_CALLBACK_MOUSE_MOVE,
3055 _elm_scroll_mouse_move_event_cb, sid);
3059 _scroll_edje_object_detach(Evas_Object *obj)
3061 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3063 evas_object_event_callback_del_full
3064 (sid->edje_obj, EVAS_CALLBACK_RESIZE, _on_edje_resize, sid);
3065 evas_object_event_callback_del_full
3066 (sid->edje_obj, EVAS_CALLBACK_MOVE, _on_edje_move, sid);
3068 edje_object_signal_callback_del_full
3069 (sid->edje_obj, "drag", "elm.dragable.vbar", _elm_scroll_vbar_drag_cb,
3071 edje_object_signal_callback_del_full
3072 (sid->edje_obj, "drag,set", "elm.dragable.vbar",
3073 _elm_scroll_edje_drag_v_cb, sid);
3074 edje_object_signal_callback_del_full
3075 (sid->edje_obj, "drag,start", "elm.dragable.vbar",
3076 _elm_scroll_edje_drag_v_start_cb, sid);
3077 edje_object_signal_callback_del_full
3078 (sid->edje_obj, "drag,stop", "elm.dragable.vbar",
3079 _elm_scroll_edje_drag_v_stop_cb, sid);
3080 edje_object_signal_callback_del_full
3081 (sid->edje_obj, "drag,step", "elm.dragable.vbar",
3082 _elm_scroll_edje_drag_v_cb, sid);
3083 edje_object_signal_callback_del_full
3084 (sid->edje_obj, "drag,page", "elm.dragable.vbar",
3085 _elm_scroll_edje_drag_v_cb, sid);
3086 edje_object_signal_callback_del_full
3087 (sid->edje_obj, "elm,vbar,press", "elm",
3088 _elm_scroll_vbar_press_cb, sid);
3089 edje_object_signal_callback_del_full
3090 (sid->edje_obj, "elm,vbar,unpress", "elm",
3091 _elm_scroll_vbar_unpress_cb, sid);
3092 edje_object_signal_callback_del_full
3093 (sid->edje_obj, "drag", "elm.dragable.hbar", _elm_scroll_hbar_drag_cb,
3095 edje_object_signal_callback_del_full
3096 (sid->edje_obj, "drag,set", "elm.dragable.hbar",
3097 _elm_scroll_edje_drag_h_cb, sid);
3098 edje_object_signal_callback_del_full
3099 (sid->edje_obj, "drag,start", "elm.dragable.hbar",
3100 _elm_scroll_edje_drag_h_start_cb, sid);
3101 edje_object_signal_callback_del_full
3102 (sid->edje_obj, "drag,stop", "elm.dragable.hbar",
3103 _elm_scroll_edje_drag_h_stop_cb, sid);
3104 edje_object_signal_callback_del_full
3105 (sid->edje_obj, "drag,step", "elm.dragable.hbar",
3106 _elm_scroll_edje_drag_h_cb, sid);
3107 edje_object_signal_callback_del_full
3108 (sid->edje_obj, "drag,page", "elm.dragable.hbar",
3109 _elm_scroll_edje_drag_h_cb, sid);
3110 edje_object_signal_callback_del_full
3111 (sid->edje_obj, "elm,hbar,press", "elm",
3112 _elm_scroll_hbar_press_cb, sid);
3113 edje_object_signal_callback_del_full
3114 (sid->edje_obj, "elm,hbar,unpress", "elm",
3115 _elm_scroll_hbar_unpress_cb, sid);
3119 _scroll_event_object_detach(Evas_Object *obj)
3121 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3123 evas_object_event_callback_del_full
3124 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL, _elm_scroll_wheel_event_cb,
3126 evas_object_event_callback_del_full
3127 (sid->event_rect, EVAS_CALLBACK_MOUSE_DOWN,
3128 _elm_scroll_mouse_down_event_cb, sid);
3129 evas_object_event_callback_del_full
3130 (sid->event_rect, EVAS_CALLBACK_MOUSE_UP,
3131 _elm_scroll_mouse_up_event_cb, sid);
3132 evas_object_event_callback_del_full
3133 (sid->event_rect, EVAS_CALLBACK_MOUSE_MOVE,
3134 _elm_scroll_mouse_move_event_cb, sid);
3138 _elm_scroll_objects_set(Evas_Object *obj,
3139 Evas_Object *edje_object,
3140 Evas_Object *hit_rectangle)
3144 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3146 if (!edje_object || !hit_rectangle) return;
3149 _scroll_edje_object_detach(obj);
3151 sid->edje_obj = edje_object;
3153 if (sid->event_rect)
3154 _scroll_event_object_detach(obj);
3156 sid->event_rect = hit_rectangle;
3157 evas_object_repeat_events_set(hit_rectangle, EINA_TRUE);
3159 _scroll_edje_object_attach(obj);
3160 _scroll_event_object_attach(obj);
3163 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
3164 if (edje_object_part_exists(sid->edje_obj, "elm.scrollbar.base"))
3168 base = edje_object_part_swallow_get
3169 (sid->edje_obj, "elm.scrollbar.base");
3172 base = evas_object_rectangle_add
3173 (evas_object_evas_get(sid->edje_obj));
3174 evas_object_color_set(base, 0, 0, 0, 0);
3175 edje_object_part_swallow
3176 (sid->edje_obj, "elm.scrollbar.base", base);
3178 if (!_elm_config->thumbscroll_enable)
3179 evas_object_size_hint_min_set(base, mw, mh);
3182 _elm_scroll_scroll_bar_visibility_adjust(sid);
3186 _elm_scroll_scroll_bar_reset(Elm_Scrollable_Smart_Interface_Data *sid)
3188 Evas_Coord px = 0, py = 0, minx = 0, miny = 0;
3190 if (!sid->edje_obj) return;
3192 edje_object_part_drag_value_set
3193 (sid->edje_obj, "elm.dragable.vbar", 0.0, 0.0);
3194 edje_object_part_drag_value_set
3195 (sid->edje_obj, "elm.dragable.hbar", 0.0, 0.0);
3196 if ((!sid->content) && (!sid->extern_pan))
3198 edje_object_part_drag_size_set
3199 (sid->edje_obj, "elm.dragable.vbar", 1.0, 1.0);
3200 edje_object_part_drag_size_set
3201 (sid->edje_obj, "elm.dragable.hbar", 1.0, 1.0);
3205 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
3207 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
3208 psd->api->pos_get(sid->pan_obj, &px, &py);
3209 psd->api->pos_set(sid->pan_obj, minx, miny);
3211 if ((px != minx) || (py != miny))
3212 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
3213 _elm_direction_arrows_eval(sid);
3216 /* even external pan objects get this */
3218 _elm_scroll_pan_changed_cb(void *data,
3219 Evas_Object *obj __UNUSED__,
3220 void *event_info __UNUSED__)
3223 Elm_Scrollable_Smart_Interface_Data *sid = data;
3225 if (!sid->pan_obj) return;
3227 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
3229 psd->api->content_size_get(sid->pan_obj, &w, &h);
3230 if ((w != sid->content_info.w) || (h != sid->content_info.h))
3232 sid->content_info.w = w;
3233 sid->content_info.h = h;
3234 _elm_scroll_scroll_bar_size_adjust(sid);
3236 evas_object_size_hint_min_set
3237 (sid->edje_obj, sid->content_info.w, sid->content_info.h);
3238 sid->content_info.resized = EINA_TRUE;
3239 _elm_scroll_wanted_region_set(sid->obj);
3244 _elm_scroll_content_del_cb(void *data,
3246 Evas_Object *obj __UNUSED__,
3247 void *event_info __UNUSED__)
3249 Elm_Scrollable_Smart_Interface_Data *sid = data;
3251 sid->content = NULL;
3252 _elm_scroll_scroll_bar_size_adjust(sid);
3253 _elm_scroll_scroll_bar_reset(sid);
3257 _elm_scroll_content_set(Evas_Object *obj,
3258 Evas_Object *content)
3263 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3265 if (!sid->edje_obj) return;
3269 /* if we had content, for sure we had a pan object */
3270 _elm_pan_content_set(sid->pan_obj, NULL);
3271 evas_object_event_callback_del_full
3272 (sid->content, EVAS_CALLBACK_DEL, _elm_scroll_content_del_cb, sid);
3275 sid->content = content;
3276 sid->wx = sid->wy = 0;
3277 /* (-1) means want viewports size */
3278 sid->ww = sid->wh = -1;
3279 if (!content) return;
3283 o = _elm_pan_add(evas_object_evas_get(obj));
3285 evas_object_smart_callback_add
3286 (o, SIG_CHANGED, _elm_scroll_pan_changed_cb, sid);
3287 edje_object_part_swallow(sid->edje_obj, "elm.swallow.content", o);
3290 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
3292 evas_object_event_callback_add
3293 (content, EVAS_CALLBACK_DEL, _elm_scroll_content_del_cb, sid);
3295 _elm_pan_content_set(sid->pan_obj, content);
3296 psd->api->content_size_get(sid->pan_obj, &w, &h);
3297 sid->content_info.w = w;
3298 sid->content_info.h = h;
3300 _elm_scroll_scroll_bar_size_adjust(sid);
3301 _elm_scroll_scroll_bar_reset(sid);
3305 _elm_scroll_extern_pan_set(Evas_Object *obj,
3308 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3310 if (!sid->edje_obj) return;
3312 _elm_scroll_content_set(obj, NULL);
3316 evas_object_smart_callback_del
3317 (sid->pan_obj, SIG_CHANGED, _elm_scroll_pan_changed_cb);
3320 if (sid->extern_pan)
3324 /* not owned by scroller, just leave (was external already) */
3325 edje_object_part_unswallow(sid->edje_obj, sid->pan_obj);
3326 sid->pan_obj = NULL;
3333 evas_object_del(sid->pan_obj);
3334 sid->pan_obj = NULL;
3339 sid->extern_pan = EINA_FALSE;
3345 sid->extern_pan = EINA_TRUE;
3346 evas_object_smart_callback_add
3347 (sid->pan_obj, SIG_CHANGED, _elm_scroll_pan_changed_cb, sid);
3348 edje_object_part_swallow
3349 (sid->edje_obj, "elm.swallow.content", sid->pan_obj);
3353 _elm_scroll_drag_start_cb_set(Evas_Object *obj,
3354 void (*drag_start_cb)(Evas_Object *obj,
3357 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3359 sid->cb_func.drag_start = drag_start_cb;
3363 _elm_scroll_drag_stop_cb_set(Evas_Object *obj,
3364 void (*drag_stop_cb)(Evas_Object *obj,
3367 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3369 sid->cb_func.drag_stop = drag_stop_cb;
3373 _elm_scroll_animate_start_cb_set(Evas_Object *obj,
3374 void (*animate_start_cb)(Evas_Object *obj,
3377 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3379 sid->cb_func.animate_start = animate_start_cb;
3383 _elm_scroll_animate_stop_cb_set(Evas_Object *obj,
3384 void (*animate_stop_cb)(Evas_Object *obj,
3387 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3389 sid->cb_func.animate_stop = animate_stop_cb;
3393 _elm_scroll_scroll_cb_set(Evas_Object *obj,
3394 void (*scroll_cb)(Evas_Object *obj,
3397 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3399 sid->cb_func.scroll = scroll_cb;
3403 _elm_scroll_scroll_left_cb_set(Evas_Object *obj,
3404 void (*scroll_left_cb)(Evas_Object *obj,
3407 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3409 sid->cb_func.scroll_left = scroll_left_cb;
3413 _elm_scroll_scroll_right_cb_set(Evas_Object *obj,
3414 void (*scroll_right_cb)(Evas_Object *obj,
3417 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3419 sid->cb_func.scroll_right = scroll_right_cb;
3423 _elm_scroll_scroll_up_cb_set(Evas_Object *obj,
3424 void (*scroll_up_cb)(Evas_Object *obj,
3427 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3429 sid->cb_func.scroll_up = scroll_up_cb;
3433 _elm_scroll_scroll_down_cb_set(Evas_Object *obj,
3434 void (*scroll_down_cb)(Evas_Object *obj,
3437 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3439 sid->cb_func.scroll_down = scroll_down_cb;
3443 _elm_scroll_edge_left_cb_set(Evas_Object *obj,
3444 void (*edge_left_cb)(Evas_Object *obj,
3447 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3449 sid->cb_func.edge_left = edge_left_cb;
3453 _elm_scroll_edge_right_cb_set(Evas_Object *obj,
3454 void (*edge_right_cb)(Evas_Object *obj,
3457 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3459 sid->cb_func.edge_right = edge_right_cb;
3463 _elm_scroll_edge_top_cb_set(Evas_Object *obj,
3464 void (*edge_top_cb)(Evas_Object *obj,
3467 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3469 sid->cb_func.edge_top = edge_top_cb;
3473 _elm_scroll_edge_bottom_cb_set(Evas_Object *obj,
3474 void (*edge_bottom_cb)(Evas_Object *obj,
3477 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3479 sid->cb_func.edge_bottom = edge_bottom_cb;
3483 _elm_scroll_vbar_drag_cb_set(Evas_Object *obj,
3484 void (*vbar_drag_cb)(Evas_Object *obj,
3487 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3489 sid->cb_func.vbar_drag = vbar_drag_cb;
3493 _elm_scroll_vbar_press_cb_set(Evas_Object *obj,
3494 void (*vbar_press_cb)(Evas_Object *obj,
3497 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3499 sid->cb_func.vbar_press = vbar_press_cb;
3503 _elm_scroll_vbar_unpress_cb_set(Evas_Object *obj,
3504 void (*vbar_unpress_cb)(Evas_Object *obj,
3507 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3509 sid->cb_func.vbar_unpress = vbar_unpress_cb;
3513 _elm_scroll_hbar_drag_cb_set(Evas_Object *obj,
3514 void (*hbar_drag_cb)(Evas_Object *obj,
3517 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3519 sid->cb_func.hbar_drag = hbar_drag_cb;
3523 _elm_scroll_hbar_press_cb_set(Evas_Object *obj,
3524 void (*hbar_press_cb)(Evas_Object *obj,
3527 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3529 sid->cb_func.hbar_press = hbar_press_cb;
3533 _elm_scroll_hbar_unpress_cb_set(Evas_Object *obj,
3534 void (*hbar_unpress_cb)(Evas_Object *obj,
3537 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3539 sid->cb_func.hbar_unpress = hbar_unpress_cb;
3543 _elm_scroll_content_min_limit_cb_set(Evas_Object *obj,
3544 void (*c_min_limit_cb)(Evas_Object *obj,
3548 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3550 sid->cb_func.content_min_limit = c_min_limit_cb;
3554 _elm_scroll_momentum_animator_disabled_get(const Evas_Object *obj)
3556 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
3558 return sid->momentum_animator_disabled;
3562 _elm_scroll_momentum_animator_disabled_set(Evas_Object *obj,
3565 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3567 sid->momentum_animator_disabled = disabled;
3568 if (sid->momentum_animator_disabled)
3570 if (sid->down.momentum_animator)
3572 ecore_animator_del(sid->down.momentum_animator);
3573 sid->down.momentum_animator = NULL;
3574 if (sid->content_info.resized)
3575 _elm_scroll_wanted_region_set(sid->obj);
3581 _elm_scroll_bounce_animator_disabled_get(const Evas_Object *obj)
3583 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
3585 return sid->bounce_animator_disabled;
3589 _elm_scroll_bounce_animator_disabled_set(Evas_Object *obj,
3592 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3594 sid->bounce_animator_disabled = disabled;
3595 if (sid->bounce_animator_disabled)
3597 if (sid->scrollto.x.animator)
3599 ecore_animator_del(sid->scrollto.x.animator);
3600 sid->scrollto.x.animator = NULL;
3603 if (sid->scrollto.y.animator)
3605 ecore_animator_del(sid->scrollto.y.animator);
3606 sid->scrollto.y.animator = NULL;
3612 _elm_scroll_wheel_disabled_get(const Evas_Object *obj)
3614 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
3616 return sid->wheel_disabled;
3620 _elm_scroll_wheel_disabled_set(Evas_Object *obj,
3623 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3625 if (!sid->event_rect) return;
3627 if ((!sid->wheel_disabled) && (disabled))
3628 evas_object_event_callback_del_full
3629 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL,
3630 _elm_scroll_wheel_event_cb, sid);
3631 else if ((sid->wheel_disabled) && (!disabled))
3632 evas_object_event_callback_add
3633 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL,
3634 _elm_scroll_wheel_event_cb, sid);
3635 sid->wheel_disabled = disabled;
3639 _elm_scroll_step_size_set(Evas_Object *obj,
3643 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3650 _elm_scroll_scroll_bar_size_adjust(sid);
3654 _elm_scroll_step_size_get(const Evas_Object *obj,
3658 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3660 if (x) *x = sid->step.x;
3661 if (y) *y = sid->step.y;
3665 _elm_scroll_page_size_set(Evas_Object *obj,
3669 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3674 _elm_scroll_scroll_bar_size_adjust(sid);
3678 _elm_scroll_page_size_get(const Evas_Object *obj,
3682 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3684 if (x) *x = sid->page.x;
3685 if (y) *y = sid->page.y;
3689 _elm_scroll_policy_set(Evas_Object *obj,
3690 Elm_Scroller_Policy hbar,
3691 Elm_Scroller_Policy vbar)
3693 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3695 if (!sid->edje_obj) return;
3697 if ((sid->hbar_flags == hbar) && (sid->vbar_flags == vbar)) return;
3699 sid->hbar_flags = hbar;
3700 sid->vbar_flags = vbar;
3701 if (sid->hbar_flags == ELM_SCROLLER_POLICY_ON)
3702 edje_object_signal_emit
3703 (sid->edje_obj, "elm,action,show_always,hbar", "elm");
3704 else if (sid->hbar_flags == ELM_SCROLLER_POLICY_OFF)
3705 edje_object_signal_emit
3706 (sid->edje_obj, "elm,action,hide,hbar", "elm");
3708 edje_object_signal_emit
3709 (sid->edje_obj, "elm,action,show_notalways,hbar", "elm");
3710 if (sid->vbar_flags == ELM_SCROLLER_POLICY_ON)
3711 edje_object_signal_emit
3712 (sid->edje_obj, "elm,action,show_always,vbar", "elm");
3713 else if (sid->vbar_flags == ELM_SCROLLER_POLICY_OFF)
3714 edje_object_signal_emit
3715 (sid->edje_obj, "elm,action,hide,vbar", "elm");
3717 edje_object_signal_emit
3718 (sid->edje_obj, "elm,action,show_notalways,vbar", "elm");
3719 edje_object_message_signal_process(sid->edje_obj);
3720 _elm_scroll_scroll_bar_size_adjust(sid);
3721 if (sid->cb_func.content_min_limit)
3722 sid->cb_func.content_min_limit(sid->obj, sid->min_w, sid->min_h);
3723 _elm_direction_arrows_eval(sid);
3727 _elm_scroll_policy_get(const Evas_Object *obj,
3728 Elm_Scroller_Policy *hbar,
3729 Elm_Scroller_Policy *vbar)
3731 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3733 if (hbar) *hbar = sid->hbar_flags;
3734 if (vbar) *vbar = sid->vbar_flags;
3738 _elm_scroll_single_direction_set(Evas_Object *obj,
3739 Eina_Bool single_dir)
3741 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3743 sid->one_direction_at_a_time = single_dir;
3747 _elm_scroll_single_direction_get(const Evas_Object *obj)
3749 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
3751 return sid->one_direction_at_a_time;
3755 _elm_scroll_repeat_events_set(Evas_Object *obj,
3756 Eina_Bool repeat_events)
3758 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3760 evas_object_repeat_events_set(sid->event_rect, repeat_events);
3764 _elm_scroll_repeat_events_get(Evas_Object *obj)
3766 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3768 return evas_object_repeat_events_get(sid->event_rect);
3772 _elm_scroll_hold_set(Evas_Object *obj,
3775 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3781 _elm_scroll_freeze_set(Evas_Object *obj,
3784 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3786 sid->freeze = freeze;
3789 if (sid->down.onhold_animator)
3791 ecore_animator_del(sid->down.onhold_animator);
3792 sid->down.onhold_animator = NULL;
3793 if (sid->content_info.resized)
3794 _elm_scroll_wanted_region_set(sid->obj);
3798 _elm_scroll_bounce_eval(sid);
3802 _elm_scroll_bounce_allow_set(Evas_Object *obj,
3806 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3808 sid->bounce_horiz = !!horiz;
3809 sid->bounce_vert = !!vert;
3813 _elm_scroll_bounce_allow_get(const Evas_Object *obj,
3817 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3819 if (horiz) *horiz = sid->bounce_horiz;
3820 if (vert) *vert = sid->bounce_vert;
3824 _elm_scroll_paging_set(Evas_Object *obj,
3827 Evas_Coord pagesize_h,
3828 Evas_Coord pagesize_v)
3830 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3832 sid->pagerel_h = pagerel_h;
3833 sid->pagerel_v = pagerel_v;
3834 sid->pagesize_h = pagesize_h;
3835 sid->pagesize_v = pagesize_v;
3837 _elm_scroll_page_adjust(sid);
3841 _elm_scroll_paging_get(const Evas_Object *obj,
3844 Evas_Coord *pagesize_h,
3845 Evas_Coord *pagesize_v)
3847 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3849 if (pagerel_h) *pagerel_h = sid->pagerel_h;
3850 if (pagerel_v) *pagerel_v = sid->pagerel_v;
3851 if (pagesize_h) *pagesize_h = sid->pagesize_h;
3852 if (pagesize_v) *pagesize_v = sid->pagesize_v;
3856 _elm_scroll_current_page_get(const Evas_Object *obj,
3862 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3864 _elm_scroll_content_pos_get(sid->obj, &x, &y);
3867 if (sid->pagesize_h > 0)
3868 *pagenumber_h = (x + sid->pagesize_h - 1) / sid->pagesize_h;
3874 if (sid->pagesize_v > 0)
3875 *pagenumber_v = (y + sid->pagesize_v - 1) / sid->pagesize_v;
3882 _elm_scroll_last_page_get(const Evas_Object *obj,
3888 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3890 if (!sid->pan_obj) return;
3892 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
3894 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
3897 if (sid->pagesize_h > 0)
3898 *pagenumber_h = cw / sid->pagesize_h + 1;
3904 if (sid->pagesize_v > 0)
3905 *pagenumber_v = ch / sid->pagesize_v + 1;
3912 _elm_scroll_page_show(Evas_Object *obj,
3920 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3922 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
3923 if (pagenumber_h >= 0) x = sid->pagesize_h * pagenumber_h;
3924 if (pagenumber_v >= 0) y = sid->pagesize_v * pagenumber_v;
3925 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
3926 _elm_scroll_content_pos_set(obj, x, y, EINA_TRUE);
3930 _elm_scroll_page_bring_in(Evas_Object *obj,
3938 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3940 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
3941 if (pagenumber_h >= 0) x = sid->pagesize_h * pagenumber_h;
3942 if (pagenumber_v >= 0) y = sid->pagesize_v * pagenumber_v;
3943 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
3945 _elm_scroll_scroll_to_x(sid, _elm_config->bring_in_scroll_friction, x);
3946 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, y);
3951 _elm_scroll_region_bring_in(Evas_Object *obj,
3957 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3959 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
3961 _elm_scroll_scroll_to_x(sid, _elm_config->bring_in_scroll_friction, x);
3962 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, y);
3967 _elm_scroll_gravity_set(Evas_Object *obj,
3971 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3973 if (!sid->pan_obj) return;
3975 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
3977 psd->api->gravity_set(sid->pan_obj, x, y);
3981 _elm_scroll_gravity_get(const Evas_Object *obj,
3985 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3987 if (!sid->pan_obj) return;
3989 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
3991 psd->api->gravity_get(sid->pan_obj, x, y);
3995 _elm_scroll_interface_add(Evas_Object *obj)
3997 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
3999 memset(sid, 0, sizeof(*sid));
4011 sid->hbar_flags = ELM_SCROLLER_POLICY_AUTO;
4012 sid->vbar_flags = ELM_SCROLLER_POLICY_AUTO;
4013 sid->hbar_visible = EINA_TRUE;
4014 sid->vbar_visible = EINA_TRUE;
4016 sid->bounce_horiz = EINA_TRUE;
4017 sid->bounce_vert = EINA_TRUE;
4019 sid->one_direction_at_a_time = EINA_TRUE;
4020 sid->momentum_animator_disabled = EINA_FALSE;
4021 sid->bounce_animator_disabled = EINA_FALSE;
4023 _elm_scroll_scroll_bar_reset(sid);
4029 _elm_scroll_interface_del(Evas_Object *obj)
4031 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4033 _elm_scroll_content_set(obj, NULL);
4034 if (!sid->extern_pan) evas_object_del(sid->pan_obj);
4036 if (sid->down.hold_animator)
4037 ecore_animator_del(sid->down.hold_animator);
4038 if (sid->down.onhold_animator)
4039 ecore_animator_del(sid->down.onhold_animator);
4040 if (sid->down.momentum_animator)
4041 ecore_animator_del(sid->down.momentum_animator);
4042 if (sid->down.bounce_x_animator)
4043 ecore_animator_del(sid->down.bounce_x_animator);
4044 if (sid->down.bounce_y_animator)
4045 ecore_animator_del(sid->down.bounce_y_animator);
4046 if (sid->scrollto.x.animator) ecore_animator_del(sid->scrollto.x.animator);
4047 if (sid->scrollto.y.animator) ecore_animator_del(sid->scrollto.y.animator);
4050 EAPI const char ELM_SCROLLABLE_IFACE_NAME[] = "elm_interface_scrollable";
4052 EAPI const Elm_Scrollable_Smart_Interface ELM_SCROLLABLE_IFACE =
4055 ELM_SCROLLABLE_IFACE_NAME,
4056 sizeof(Elm_Scrollable_Smart_Interface_Data),
4057 _elm_scroll_interface_add,
4058 _elm_scroll_interface_del
4061 _elm_scroll_objects_set,
4062 _elm_scroll_content_set,
4063 _elm_scroll_extern_pan_set,
4064 _elm_scroll_drag_start_cb_set,
4065 _elm_scroll_drag_stop_cb_set,
4066 _elm_scroll_animate_start_cb_set,
4067 _elm_scroll_animate_stop_cb_set,
4068 _elm_scroll_scroll_cb_set,
4069 _elm_scroll_scroll_left_cb_set,
4070 _elm_scroll_scroll_right_cb_set,
4071 _elm_scroll_scroll_up_cb_set,
4072 _elm_scroll_scroll_down_cb_set,
4073 _elm_scroll_edge_left_cb_set,
4074 _elm_scroll_edge_right_cb_set,
4075 _elm_scroll_edge_top_cb_set,
4076 _elm_scroll_edge_bottom_cb_set,
4077 _elm_scroll_vbar_drag_cb_set,
4078 _elm_scroll_vbar_press_cb_set,
4079 _elm_scroll_vbar_unpress_cb_set,
4080 _elm_scroll_hbar_drag_cb_set,
4081 _elm_scroll_hbar_press_cb_set,
4082 _elm_scroll_hbar_unpress_cb_set,
4083 _elm_scroll_content_min_limit_cb_set,
4084 _elm_scroll_content_pos_set,
4085 _elm_scroll_content_pos_get,
4086 _elm_scroll_content_region_show,
4087 _elm_scroll_content_region_set,
4088 _elm_scroll_content_size_get,
4089 _elm_scroll_content_viewport_size_get,
4090 _elm_scroll_content_min_limit,
4091 _elm_scroll_step_size_set,
4092 _elm_scroll_step_size_get,
4093 _elm_scroll_page_size_set,
4094 _elm_scroll_page_size_get,
4095 _elm_scroll_policy_set,
4096 _elm_scroll_policy_get,
4097 _elm_scroll_single_direction_set,
4098 _elm_scroll_single_direction_get,
4099 _elm_scroll_repeat_events_set,
4100 _elm_scroll_repeat_events_get,
4101 _elm_scroll_mirrored_set,
4102 _elm_scroll_hold_set,
4103 _elm_scroll_freeze_set,
4104 _elm_scroll_bounce_allow_set,
4105 _elm_scroll_bounce_allow_get,
4106 _elm_scroll_paging_set,
4107 _elm_scroll_paging_get,
4108 _elm_scroll_current_page_get,
4109 _elm_scroll_last_page_get,
4110 _elm_scroll_page_show,
4111 _elm_scroll_page_bring_in,
4112 _elm_scroll_region_bring_in,
4113 _elm_scroll_gravity_set,
4114 _elm_scroll_gravity_get,
4115 _elm_scroll_momentum_animator_disabled_get,
4116 _elm_scroll_momentum_animator_disabled_set,
4117 _elm_scroll_bounce_animator_disabled_set,
4118 _elm_scroll_bounce_animator_disabled_get,
4119 _elm_scroll_wheel_disabled_get,
4120 _elm_scroll_wheel_disabled_set