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 Eina_Bool _paging_is_enabled(Elm_Scrollable_Smart_Interface_Data *sid);
386 static Evas_Coord _elm_scroll_page_x_get(
387 Elm_Scrollable_Smart_Interface_Data *sid, int offset, Eina_Bool limit);
388 static Evas_Coord _elm_scroll_page_y_get(
389 Elm_Scrollable_Smart_Interface_Data *sid, int offset, Eina_Bool limit);
390 static void _elm_scroll_content_pos_get(const Evas_Object *,
393 static void _elm_scroll_content_pos_set(Evas_Object *,
405 _elm_direction_arrows_eval(Elm_Scrollable_Smart_Interface_Data *sid)
407 Eina_Bool go_left = EINA_TRUE, go_right = EINA_TRUE;
408 Eina_Bool go_up = EINA_TRUE, go_down = EINA_TRUE;
409 Evas_Coord x = 0, y = 0, mx = 0, my = 0, minx = 0, miny = 0;
411 if (!sid->edje_obj || !sid->pan_obj) return;
412 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
414 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
415 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
416 psd->api->pos_get(sid->pan_obj, &x, &y);
418 if (x == minx) go_left = EINA_FALSE;
419 if (x == (mx + minx)) go_right = EINA_FALSE;
420 if (y == miny) go_up = EINA_FALSE;
421 if (y == (my + miny)) go_down = EINA_FALSE;
422 if (go_left != sid->go_left)
425 edje_object_signal_emit(sid->edje_obj, "elm,action,show,left", "elm");
427 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,left", "elm");
428 sid->go_left = go_left;
430 if (go_right != sid->go_right)
433 edje_object_signal_emit(sid->edje_obj, "elm,action,show,right", "elm");
435 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,right", "elm");
436 sid->go_right= go_right;
438 if (go_up != sid->go_up)
441 edje_object_signal_emit(sid->edje_obj, "elm,action,show,up", "elm");
443 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,up", "elm");
446 if (go_down != sid->go_down)
449 edje_object_signal_emit(sid->edje_obj, "elm,action,show,down", "elm");
451 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,down", "elm");
452 sid->go_down= go_down;
457 _elm_scroll_scroll_bar_h_visibility_adjust(
458 Elm_Scrollable_Smart_Interface_Data *sid)
460 int scroll_h_vis_change = 0;
461 Evas_Coord w, vw = 0, vh = 0;
463 if (!sid->edje_obj) return 0;
465 w = sid->content_info.w;
467 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &vw, &vh);
468 if (sid->hbar_visible)
472 scroll_h_vis_change = 1;
473 sid->hbar_visible = EINA_FALSE;
477 if (sid->hbar_flags == ELM_SCROLLER_POLICY_AUTO)
479 if ((sid->content) || (sid->extern_pan))
483 scroll_h_vis_change = 1;
484 sid->hbar_visible = EINA_FALSE;
489 scroll_h_vis_change = 1;
490 sid->hbar_visible = EINA_FALSE;
493 else if (sid->hbar_flags == ELM_SCROLLER_POLICY_OFF)
495 scroll_h_vis_change = 1;
496 sid->hbar_visible = EINA_FALSE;
504 if (sid->hbar_flags == ELM_SCROLLER_POLICY_AUTO)
506 if ((sid->content) || (sid->extern_pan))
510 scroll_h_vis_change = 1;
511 sid->hbar_visible = EINA_TRUE;
515 else if (sid->hbar_flags == ELM_SCROLLER_POLICY_ON)
517 scroll_h_vis_change = 1;
518 sid->hbar_visible = EINA_TRUE;
522 if (scroll_h_vis_change)
524 if (sid->hbar_flags != ELM_SCROLLER_POLICY_OFF)
526 if (sid->hbar_visible)
527 edje_object_signal_emit
528 (sid->edje_obj, "elm,action,show,hbar", "elm");
530 edje_object_signal_emit
531 (sid->edje_obj, "elm,action,hide,hbar", "elm");
534 edje_object_signal_emit
535 (sid->edje_obj, "elm,action,hide,hbar", "elm");
536 edje_object_message_signal_process(sid->edje_obj);
537 _elm_scroll_scroll_bar_size_adjust(sid);
538 if (sid->cb_func.content_min_limit)
539 sid->cb_func.content_min_limit(sid->obj, sid->min_w, sid->min_h);
542 _elm_direction_arrows_eval(sid);
543 return scroll_h_vis_change;
547 _elm_scroll_scroll_bar_v_visibility_adjust(
548 Elm_Scrollable_Smart_Interface_Data *sid)
550 int scroll_v_vis_change = 0;
551 Evas_Coord h, vw = 0, vh = 0;
553 if (!sid->edje_obj) return 0;
555 h = sid->content_info.h;
557 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &vw, &vh);
558 if (sid->vbar_visible)
562 scroll_v_vis_change = 1;
563 sid->vbar_visible = EINA_FALSE;
567 if (sid->vbar_flags == ELM_SCROLLER_POLICY_AUTO)
569 if ((sid->content) || (sid->extern_pan))
573 scroll_v_vis_change = 1;
574 sid->vbar_visible = EINA_FALSE;
579 scroll_v_vis_change = 1;
580 sid->vbar_visible = EINA_FALSE;
583 else if (sid->vbar_flags == ELM_SCROLLER_POLICY_OFF)
585 scroll_v_vis_change = 1;
586 sid->vbar_visible = EINA_FALSE;
594 if (sid->vbar_flags == ELM_SCROLLER_POLICY_AUTO)
596 if ((sid->content) || (sid->extern_pan))
600 scroll_v_vis_change = 1;
601 sid->vbar_visible = EINA_TRUE;
605 else if (sid->vbar_flags == ELM_SCROLLER_POLICY_ON)
607 scroll_v_vis_change = 1;
608 sid->vbar_visible = EINA_TRUE;
612 if (scroll_v_vis_change)
614 if (sid->vbar_flags != ELM_SCROLLER_POLICY_OFF)
616 if (sid->vbar_visible)
617 edje_object_signal_emit
618 (sid->edje_obj, "elm,action,show,vbar", "elm");
620 edje_object_signal_emit
621 (sid->edje_obj, "elm,action,hide,vbar", "elm");
624 edje_object_signal_emit
625 (sid->edje_obj, "elm,action,hide,vbar", "elm");
626 edje_object_message_signal_process(sid->edje_obj);
627 _elm_scroll_scroll_bar_size_adjust(sid);
628 if (sid->cb_func.content_min_limit)
629 sid->cb_func.content_min_limit(sid->obj, sid->min_w, sid->min_h);
632 _elm_direction_arrows_eval(sid);
633 return scroll_v_vis_change;
637 _elm_scroll_scroll_bar_visibility_adjust(
638 Elm_Scrollable_Smart_Interface_Data *sid)
642 changed |= _elm_scroll_scroll_bar_h_visibility_adjust(sid);
643 changed |= _elm_scroll_scroll_bar_v_visibility_adjust(sid);
647 _elm_scroll_scroll_bar_h_visibility_adjust(sid);
648 _elm_scroll_scroll_bar_v_visibility_adjust(sid);
653 _elm_scroll_scroll_bar_size_adjust(Elm_Scrollable_Smart_Interface_Data *sid)
655 if (!sid->pan_obj || !sid->edje_obj) return;
657 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
659 if ((sid->content) || (sid->extern_pan))
661 Evas_Coord x, y, w, h, mx = 0, my = 0, vw = 0, vh = 0, px, py,
665 edje_object_part_geometry_get
666 (sid->edje_obj, "elm.swallow.content", NULL, NULL, &vw, &vh);
667 w = sid->content_info.w;
669 size = (double)vw / (double)w;
674 edje_object_part_drag_value_set
675 (sid->edje_obj, "elm.dragable.hbar", 0.0, 0.0);
677 edje_object_part_drag_size_set
678 (sid->edje_obj, "elm.dragable.hbar", size, 1.0);
680 h = sid->content_info.h;
682 size = (double)vh / (double)h;
686 edje_object_part_drag_value_set
687 (sid->edje_obj, "elm.dragable.vbar", 0.0, 0.0);
689 edje_object_part_drag_size_set
690 (sid->edje_obj, "elm.dragable.vbar", 1.0, size);
692 edje_object_part_drag_value_get
693 (sid->edje_obj, "elm.dragable.hbar", &vx, NULL);
694 edje_object_part_drag_value_get
695 (sid->edje_obj, "elm.dragable.vbar", NULL, &vy);
697 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
698 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
702 edje_object_part_drag_step_set
703 (sid->edje_obj, "elm.dragable.hbar", (double)sid->step.x /
705 edje_object_part_drag_step_set
706 (sid->edje_obj, "elm.dragable.vbar", 0.0, (double)sid->step.y /
709 edje_object_part_drag_page_set
710 (sid->edje_obj, "elm.dragable.hbar", (double)sid->page.x /
713 edje_object_part_drag_page_set
714 (sid->edje_obj, "elm.dragable.hbar",
715 -((double)sid->page.x * ((double)vw / (double)w)) / 100.0, 0.0);
717 edje_object_part_drag_page_set
718 (sid->edje_obj, "elm.dragable.vbar", 0.0,
719 (double)sid->page.y / (double)h);
721 edje_object_part_drag_page_set
722 (sid->edje_obj, "elm.dragable.vbar", 0.0,
723 -((double)sid->page.y * ((double)vh / (double)h)) / 100.0);
725 psd->api->pos_get(sid->pan_obj, &px, &py);
726 if (vx != mx) x = px;
727 if (vy != my) y = py;
728 psd->api->pos_set(sid->pan_obj, x, y);
732 Evas_Coord px = 0, py = 0, minx = 0, miny = 0;
734 edje_object_part_drag_size_set
735 (sid->edje_obj, "elm.dragable.vbar", 1.0, 1.0);
736 edje_object_part_drag_size_set
737 (sid->edje_obj, "elm.dragable.hbar", 1.0, 1.0);
738 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
739 psd->api->pos_get(sid->pan_obj, &px, &py);
740 psd->api->pos_set(sid->pan_obj, minx, miny);
741 if ((px != minx) || (py != miny))
742 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
744 _elm_scroll_scroll_bar_visibility_adjust(sid);
748 _elm_scroll_scroll_bar_read_and_update(
749 Elm_Scrollable_Smart_Interface_Data *sid)
751 Evas_Coord x, y, mx = 0, my = 0, px, py, minx = 0, miny = 0;
754 if (!sid->edje_obj || !sid->pan_obj) return;
756 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
758 if ((sid->down.dragged) || (sid->down.bounce_x_animator)
759 || (sid->down.bounce_y_animator) || (sid->down.momentum_animator)
760 || (sid->scrollto.x.animator) || (sid->scrollto.y.animator))
762 edje_object_part_drag_value_get
763 (sid->edje_obj, "elm.dragable.vbar", NULL, &vy);
764 edje_object_part_drag_value_get
765 (sid->edje_obj, "elm.dragable.hbar", &vx, NULL);
766 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
767 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
768 x = vx * (double)mx + minx;
769 y = vy * (double)my + miny;
770 psd->api->pos_get(sid->pan_obj, &px, &py);
771 psd->api->pos_set(sid->pan_obj, x, y);
772 if ((px != x) || (py != y))
774 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
779 _elm_scroll_drag_start(Elm_Scrollable_Smart_Interface_Data *sid)
781 if (sid->cb_func.drag_start)
782 sid->cb_func.drag_start(sid->obj, NULL);
786 _elm_scroll_drag_stop(Elm_Scrollable_Smart_Interface_Data *sid)
788 if (sid->cb_func.drag_stop)
789 sid->cb_func.drag_stop(sid->obj, NULL);
793 _elm_scroll_anim_start(Elm_Scrollable_Smart_Interface_Data *sid)
795 if (sid->cb_func.animate_start)
796 sid->cb_func.animate_start(sid->obj, NULL);
800 _elm_scroll_anim_stop(Elm_Scrollable_Smart_Interface_Data *sid)
802 if (sid->cb_func.animate_stop)
803 sid->cb_func.animate_stop(sid->obj, NULL);
807 _elm_scroll_vbar_drag_cb(void *data,
808 Evas_Object *obj __UNUSED__,
809 const char *emission __UNUSED__,
810 const char *source __UNUSED__)
812 Elm_Scrollable_Smart_Interface_Data *sid = data;
814 if (sid->cb_func.vbar_drag)
815 sid->cb_func.vbar_drag(sid->obj, NULL);
817 _elm_scroll_scroll_bar_read_and_update(sid);
821 _elm_scroll_vbar_press_cb(void *data,
822 Evas_Object *obj __UNUSED__,
823 const char *emission __UNUSED__,
824 const char *source __UNUSED__)
826 Elm_Scrollable_Smart_Interface_Data *sid = data;
828 if (sid->cb_func.vbar_press)
829 sid->cb_func.vbar_press(sid->obj, NULL);
833 _elm_scroll_vbar_unpress_cb(void *data,
834 Evas_Object *obj __UNUSED__,
835 const char *emission __UNUSED__,
836 const char *source __UNUSED__)
838 Elm_Scrollable_Smart_Interface_Data *sid = data;
840 if (sid->cb_func.vbar_unpress)
841 sid->cb_func.vbar_unpress(sid->obj, NULL);
845 _elm_scroll_edje_drag_v_start_cb(void *data,
846 Evas_Object *obj __UNUSED__,
847 const char *emission __UNUSED__,
848 const char *source __UNUSED__)
850 Elm_Scrollable_Smart_Interface_Data *sid = data;
852 _elm_scroll_scroll_bar_read_and_update(sid);
853 _elm_scroll_drag_start(sid);
854 sid->freeze = EINA_TRUE;
858 _elm_scroll_edje_drag_v_stop_cb(void *data,
859 Evas_Object *obj __UNUSED__,
860 const char *emission __UNUSED__,
861 const char *source __UNUSED__)
863 Elm_Scrollable_Smart_Interface_Data *sid = data;
865 _elm_scroll_scroll_bar_read_and_update(sid);
866 _elm_scroll_drag_stop(sid);
867 sid->freeze = EINA_FALSE;
871 _elm_scroll_edje_drag_v_cb(void *data,
872 Evas_Object *obj __UNUSED__,
873 const char *emission __UNUSED__,
874 const char *source __UNUSED__)
876 Elm_Scrollable_Smart_Interface_Data *sid = data;
878 _elm_scroll_scroll_bar_read_and_update(sid);
882 _elm_scroll_hbar_drag_cb(void *data,
883 Evas_Object *obj __UNUSED__,
884 const char *emission __UNUSED__,
885 const char *source __UNUSED__)
887 Elm_Scrollable_Smart_Interface_Data *sid = data;
889 if (sid->cb_func.hbar_drag)
890 sid->cb_func.hbar_drag(sid->obj, NULL);
892 _elm_scroll_scroll_bar_read_and_update(sid);
896 _elm_scroll_hbar_press_cb(void *data,
897 Evas_Object *obj __UNUSED__,
898 const char *emission __UNUSED__,
899 const char *source __UNUSED__)
901 Elm_Scrollable_Smart_Interface_Data *sid = data;
903 if (sid->cb_func.hbar_press)
904 sid->cb_func.hbar_press(sid->obj, NULL);
908 _elm_scroll_hbar_unpress_cb(void *data,
909 Evas_Object *obj __UNUSED__,
910 const char *emission __UNUSED__,
911 const char *source __UNUSED__)
913 Elm_Scrollable_Smart_Interface_Data *sid = data;
915 if (sid->cb_func.hbar_unpress)
916 sid->cb_func.hbar_unpress(sid->obj, NULL);
920 _elm_scroll_edje_drag_h_start_cb(void *data,
921 Evas_Object *obj __UNUSED__,
922 const char *emission __UNUSED__,
923 const char *source __UNUSED__)
925 Elm_Scrollable_Smart_Interface_Data *sid = data;
927 _elm_scroll_scroll_bar_read_and_update(sid);
928 _elm_scroll_drag_start(sid);
929 sid->freeze = EINA_TRUE;
933 _elm_scroll_edje_drag_h_stop_cb(void *data,
934 Evas_Object *obj __UNUSED__,
935 const char *emission __UNUSED__,
936 const char *source __UNUSED__)
938 Elm_Scrollable_Smart_Interface_Data *sid = data;
940 _elm_scroll_scroll_bar_read_and_update(sid);
941 _elm_scroll_drag_stop(sid);
942 sid->freeze = EINA_FALSE;
946 _elm_scroll_edje_drag_h_cb(void *data,
947 Evas_Object *obj __UNUSED__,
948 const char *emission __UNUSED__,
949 const char *source __UNUSED__)
951 Elm_Scrollable_Smart_Interface_Data *sid = data;
953 _elm_scroll_scroll_bar_read_and_update(sid);
957 _elm_scroll_content_size_get(const Evas_Object *obj,
961 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
963 if (!sid->content) return;
965 evas_object_geometry_get(sid->content, NULL, NULL, w, h);
969 _elm_scroll_content_viewport_size_get(const Evas_Object *obj,
973 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
975 if (!sid->pan_obj || !sid->edje_obj) return;
977 edje_object_calc_force(sid->edje_obj);
978 evas_object_geometry_get(sid->pan_obj, NULL, NULL, w, h);
982 _elm_scroll_content_min_limit(Evas_Object *obj,
986 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
988 if (!sid->edje_obj) return;
990 if (!sid->cb_func.content_min_limit)
992 ERR("Content minimim size limiting is unimplemented -- you "
993 "must provide it yourself\n");
999 sid->cb_func.content_min_limit(sid->obj, w, h);
1003 _elm_scroll_x_mirrored_get(const Evas_Object *obj,
1006 Evas_Coord cw, ch, w, ret;
1008 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, x);
1010 if (!sid->pan_obj) return 0;
1012 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, 0);
1014 _elm_scroll_content_viewport_size_get(obj, &w, NULL);
1015 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1016 ret = (cw - (x + w));
1018 return (ret >= 0) ? ret : 0;
1021 /* Update the wanted coordinates according to the x, y passed
1022 * widget directionality, content size and etc. */
1024 _elm_scroll_wanted_coordinates_update(Elm_Scrollable_Smart_Interface_Data *sid,
1030 if (!sid->pan_obj) return;
1032 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
1034 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1036 /* Update wx/y/w/h - and if the requested positions aren't legal
1038 _elm_scroll_content_viewport_size_get(sid->obj, &sid->ww, &sid->wh);
1041 else if ((x + sid->ww) > cw)
1042 sid->wx = cw - sid->ww;
1043 else if (sid->is_mirrored)
1044 sid->wx = _elm_scroll_x_mirrored_get(sid->obj, x);
1047 if (y < 0) sid->wy = 0;
1048 else if ((y + sid->wh) > ch)
1049 sid->wy = ch - sid->wh;
1054 _elm_scroll_momentum_end(Elm_Scrollable_Smart_Interface_Data *sid)
1056 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator)) return;
1057 if (sid->down.momentum_animator)
1060 _elm_scroll_content_pos_get(sid->obj, &px, &py);
1061 _elm_scroll_wanted_coordinates_update(sid, px, py);
1063 ecore_animator_del(sid->down.momentum_animator);
1064 sid->down.momentum_animator = NULL;
1065 sid->down.bounce_x_hold = EINA_FALSE;
1066 sid->down.bounce_y_hold = EINA_FALSE;
1073 if (sid->content_info.resized)
1074 _elm_scroll_wanted_region_set(sid->obj);
1079 _elm_scroll_bounce_x_animator(void *data)
1081 Elm_Scrollable_Smart_Interface_Data *sid;
1082 Evas_Coord x, y, dx, w, odx, ed, md;
1083 double t, p, dt, pd, r;
1086 t = ecore_loop_time_get();
1087 dt = t - sid->down.anim_start2;
1090 dt = dt / _elm_config->thumbscroll_bounce_friction;
1091 odx = sid->down.b2x - sid->down.bx;
1092 _elm_scroll_content_viewport_size_get(sid->obj, &w, NULL);
1093 if (!sid->down.momentum_animator && (w > abs(odx)))
1095 pd = (double)odx / (double)w;
1096 pd = (pd > 0) ? pd : -pd;
1097 pd = 1.0 - ((1.0 - pd) * (1.0 - pd));
1100 if (dt > 1.0) dt = 1.0;
1101 p = 1.0 - ((1.0 - dt) * (1.0 - dt));
1102 _elm_scroll_content_pos_get(sid->obj, &x, &y);
1105 if (sid->down.momentum_animator)
1107 ed = abs(sid->down.dx * (_elm_config->thumbscroll_friction +
1108 sid->down.extra_time) - sid->down.b0x);
1109 md = abs(_elm_config->thumbscroll_friction * 5 * w);
1110 if (ed > md) r = (double)(md) / (double)ed;
1112 x = sid->down.b2x + (int)((double)(dx - odx) * r);
1113 if (!sid->down.cancelled)
1114 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
1117 if (sid->down.momentum_animator)
1118 sid->down.bounce_x_hold = EINA_TRUE;
1119 if ((!sid->down.bounce_y_animator) &&
1120 (!sid->scrollto.y.animator))
1121 _elm_scroll_anim_stop(sid);
1122 sid->down.bounce_x_animator = NULL;
1124 sid->bouncemex = EINA_FALSE;
1125 _elm_scroll_momentum_end(sid);
1126 if (sid->content_info.resized)
1127 _elm_scroll_wanted_region_set(sid->obj);
1128 return ECORE_CALLBACK_CANCEL;
1131 return ECORE_CALLBACK_RENEW;
1135 _elm_scroll_bounce_y_animator(void *data)
1137 Elm_Scrollable_Smart_Interface_Data *sid;
1138 Evas_Coord x, y, dy, h, ody, ed, md;
1139 double t, p, dt, pd, r;
1142 t = ecore_loop_time_get();
1143 dt = t - sid->down.anim_start3;
1146 dt = dt / _elm_config->thumbscroll_bounce_friction;
1147 ody = sid->down.b2y - sid->down.by;
1148 _elm_scroll_content_viewport_size_get(sid->obj, NULL, &h);
1149 if (!sid->down.momentum_animator && (h > abs(ody)))
1151 pd = (double)ody / (double)h;
1152 pd = (pd > 0) ? pd : -pd;
1153 pd = 1.0 - ((1.0 - pd) * (1.0 - pd));
1156 if (dt > 1.0) dt = 1.0;
1157 p = 1.0 - ((1.0 - dt) * (1.0 - dt));
1158 _elm_scroll_content_pos_get(sid->obj, &x, &y);
1161 if (sid->down.momentum_animator)
1163 ed = abs(sid->down.dy * (_elm_config->thumbscroll_friction +
1164 sid->down.extra_time) - sid->down.b0y);
1165 md = abs(_elm_config->thumbscroll_friction * 5 * h);
1166 if (ed > md) r = (double)(md) / (double)ed;
1168 y = sid->down.b2y + (int)((double)(dy - ody) * r);
1169 if (!sid->down.cancelled)
1170 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
1173 if (sid->down.momentum_animator)
1174 sid->down.bounce_y_hold = EINA_TRUE;
1175 if ((!sid->down.bounce_x_animator) &&
1176 (!sid->scrollto.y.animator))
1177 _elm_scroll_anim_stop(sid);
1178 sid->down.bounce_y_animator = NULL;
1180 sid->bouncemey = EINA_FALSE;
1181 _elm_scroll_momentum_end(sid);
1182 if (sid->content_info.resized)
1183 _elm_scroll_wanted_region_set(sid->obj);
1184 return ECORE_CALLBACK_CANCEL;
1188 return ECORE_CALLBACK_RENEW;
1192 _elm_scroll_bounce_eval(Elm_Scrollable_Smart_Interface_Data *sid)
1194 Evas_Coord mx, my, px, py, bx, by, b2x, b2y, minx = 0, miny = 0;
1196 if (!sid->pan_obj) return;
1198 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
1200 if (sid->freeze) return;
1201 if ((!sid->bouncemex) && (!sid->bouncemey)) return;
1202 if (sid->down.now) return; // down bounce while still held down
1203 if (sid->down.onhold_animator)
1205 ecore_animator_del(sid->down.onhold_animator);
1206 sid->down.onhold_animator = NULL;
1207 if (sid->content_info.resized)
1208 _elm_scroll_wanted_region_set(sid->obj);
1210 if (sid->down.hold_animator)
1212 ecore_animator_del(sid->down.hold_animator);
1213 sid->down.hold_animator = NULL;
1214 if (sid->content_info.resized)
1215 _elm_scroll_wanted_region_set(sid->obj);
1217 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
1218 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
1219 psd->api->pos_get(sid->pan_obj, &px, &py);
1222 if (px < minx) px = minx;
1223 if ((px - minx) > mx) px = mx + minx;
1224 if (py < miny) py = miny;
1225 if ((py - miny) > my) py = my + miny;
1229 (!elm_widget_drag_child_locked_x_get(sid->obj)))
1231 if ((!sid->down.bounce_x_animator) && (!sid->bounce_animator_disabled))
1235 if (sid->scrollto.x.animator)
1237 ecore_animator_del(sid->scrollto.x.animator);
1238 sid->scrollto.x.animator = NULL;
1240 sid->down.bounce_x_animator =
1241 ecore_animator_add(_elm_scroll_bounce_x_animator, sid);
1242 sid->down.anim_start2 = ecore_loop_time_get();
1245 sid->down.b2x = b2x;
1246 if (sid->down.momentum_animator)
1247 sid->down.b0x = sid->down.ax;
1248 else sid->down.b0x = 0;
1253 (!elm_widget_drag_child_locked_y_get(sid->obj)))
1255 if ((!sid->down.bounce_y_animator) && (!sid->bounce_animator_disabled))
1259 if (sid->scrollto.y.animator)
1261 ecore_animator_del(sid->scrollto.y.animator);
1262 sid->scrollto.y.animator = NULL;
1264 sid->down.bounce_y_animator =
1265 ecore_animator_add(_elm_scroll_bounce_y_animator, sid);
1266 sid->down.anim_start3 = ecore_loop_time_get();
1269 sid->down.b2y = b2y;
1270 if (sid->down.momentum_animator)
1271 sid->down.b0y = sid->down.ay;
1272 else sid->down.b0y = 0;
1279 _elm_scroll_content_pos_get(const Evas_Object *obj,
1283 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1285 if (!sid->pan_obj) return;
1287 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
1289 psd->api->pos_get(sid->pan_obj, x, y);
1293 _elm_scroll_content_pos_set(Evas_Object *obj,
1298 Evas_Coord mx = 0, my = 0, px = 0, py = 0, spx = 0, spy = 0, minx = 0, miny = 0;
1299 Evas_Coord cw =0, ch = 0, ww = 0, wh = 0; //// TIZEN ONLY
1302 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1304 if (!sid->edje_obj || !sid->pan_obj) return;
1306 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
1308 // FIXME: allow for bounce outside of range
1309 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
1310 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
1311 psd->api->content_size_get(sid->pan_obj, &cw, &ch); //// TIZEN ONLY
1312 _elm_scroll_content_viewport_size_get(obj, &ww, &wh); //// TIZEN ONLY
1314 psd->api->pos_get(sid->pan_obj, &px, &py);
1319 edje_object_signal_emit(sid->edje_obj, "elm,edge,left", "elm");
1320 if ((x - minx) > mx)
1321 edje_object_signal_emit(sid->edje_obj, "elm,edge,right", "elm");
1326 edje_object_signal_emit(sid->edje_obj, "elm,edge,top", "elm");
1327 if ((y - miny) > my)
1328 edje_object_signal_emit(sid->edje_obj, "elm,edge,bottom", "elm");
1331 if (!_elm_config->thumbscroll_bounce_enable)
1333 if (x < minx) x = minx;
1334 if ((x - minx) > mx) x = mx + minx;
1335 if (y < miny) y = miny;
1336 if ((y - miny) > my) y = my + miny;
1339 if (!sid->bounce_horiz)
1341 if (x < minx) x = minx;
1342 if ((x - minx) > mx) x = mx + minx;
1344 if (!sid->bounce_vert)
1346 if (y < miny) y = miny;
1347 if (y - miny > my) y = my + miny;
1350 if (((!_elm_config->thumbscroll_bounce_enable) ||
1351 (!sid->bounce_horiz)) && (sid->scrollto.x.animator) &&
1352 ((px != x) && ((x == minx) || (x == (mx + minx)))))
1354 ecore_animator_del(sid->scrollto.x.animator);
1355 sid->scrollto.x.animator = NULL;
1358 if (((!_elm_config->thumbscroll_bounce_enable) ||
1359 (!sid->bounce_vert)) && (sid->scrollto.y.animator) &&
1360 ((py != y) && ((y == miny) || (y == (my + miny)))))
1362 ecore_animator_del(sid->scrollto.y.animator);
1363 sid->scrollto.y.animator = NULL;
1366 if (((!_elm_config->thumbscroll_bounce_enable) ||
1367 ((!sid->bounce_horiz) && (!sid->bounce_vert))) &&
1368 (sid->down.momentum_animator) &&
1369 ((((px != x) && ((x == minx) || (x == (mx + minx)))) && (py == y)) ||
1370 (((py != y) && ((y == miny) || (y == (my + miny)))) && (px == x))))
1372 ecore_animator_del(sid->down.momentum_animator);
1373 sid->down.momentum_animator = NULL;
1374 sid->down.bounce_x_hold = EINA_FALSE;
1375 sid->down.bounce_y_hold = EINA_FALSE;
1380 if (sid->content_info.resized)
1381 _elm_scroll_wanted_region_set(sid->obj);
1384 psd->api->pos_set(sid->pan_obj, x, y);
1385 psd->api->pos_get(sid->pan_obj, &spx, &spy);
1387 if (mx > 0) vx = (double)(spx - minx) / (double)mx;
1390 if (vx < 0.0) vx = 0.0;
1394 if (my > 0) vy = (double)(spy - miny) / (double)my;
1397 if (vy < 0.0) vy = 0.0;
1401 edje_object_part_drag_value_set
1402 (sid->edje_obj, "elm.dragable.vbar", 0.0, vy);
1403 edje_object_part_drag_value_set
1404 (sid->edje_obj, "elm.dragable.hbar", vx, 0.0);
1406 if (!sid->down.bounce_x_animator)
1408 if (((x < minx) && (0 <= sid->down.dx)) ||
1409 ((x > (mx + minx)) && (0 >= sid->down.dx)))
1411 sid->bouncemex = EINA_TRUE;
1412 _elm_scroll_bounce_eval(sid);
1415 sid->bouncemex = EINA_FALSE;
1417 if (!sid->down.bounce_y_animator)
1419 if (((y < miny) && (0 <= sid->down.dy)) ||
1420 ((y > (my + miny)) && (0 >= sid->down.dy)))
1422 sid->bouncemey = EINA_TRUE;
1423 _elm_scroll_bounce_eval(sid);
1426 sid->bouncemey = EINA_FALSE;
1431 if ((x != px) || (y != py))
1433 if (sid->cb_func.scroll)
1434 sid->cb_func.scroll(obj, NULL);
1435 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
1438 if (sid->cb_func.scroll_left)
1439 sid->cb_func.scroll_left(obj, NULL);
1440 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,left", "elm");
1444 if (sid->cb_func.scroll_right)
1445 sid->cb_func.scroll_right(obj, NULL);
1446 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,right", "elm");
1450 if (sid->cb_func.scroll_up)
1451 sid->cb_func.scroll_up(obj, NULL);
1452 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,up", "elm");
1456 if (sid->cb_func.scroll_down)
1457 sid->cb_func.scroll_down(obj, NULL);
1458 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,down", "elm");
1465 if (sid->cb_func.edge_left)
1466 sid->cb_func.edge_left(obj, NULL);
1467 edje_object_signal_emit(sid->edje_obj, "elm,edge,left", "elm");
1469 if (x == (mx + minx))
1471 if (sid->cb_func.edge_right)
1472 sid->cb_func.edge_right(obj, NULL);
1473 edje_object_signal_emit(sid->edje_obj, "elm,edge,right", "elm");
1480 if (sid->cb_func.edge_top)
1481 sid->cb_func.edge_top(obj, NULL);
1482 edje_object_signal_emit(sid->edje_obj, "elm,edge,top", "elm");
1486 if (sid->cb_func.edge_bottom)
1487 sid->cb_func.edge_bottom(obj, NULL);
1488 edje_object_signal_emit(sid->edje_obj, "elm,edge,bottom", "elm");
1493 _elm_direction_arrows_eval(sid);
1497 _elm_scroll_mirrored_set(Evas_Object *obj,
1502 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1504 if (!sid->edje_obj) return;
1506 mirrored = !!mirrored;
1508 if (sid->is_mirrored == mirrored)
1511 sid->is_mirrored = mirrored;
1512 edje_object_mirrored_set(sid->edje_obj, mirrored);
1514 if (sid->is_mirrored)
1515 wx = _elm_scroll_x_mirrored_get(sid->obj, sid->wx);
1519 _elm_scroll_content_pos_set(sid->obj, wx, sid->wy, EINA_FALSE);
1522 /* returns TRUE when we need to move the scroller, FALSE otherwise.
1523 * Updates w and h either way, so save them if you need them. */
1525 _elm_scroll_content_region_show_internal(Evas_Object *obj,
1531 Evas_Coord mx = 0, my = 0, cw = 0, ch = 0, px = 0, py = 0, nx, ny,
1532 minx = 0, miny = 0, pw = 0, ph = 0, x = *_x, y = *_y;
1534 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
1536 if (!sid->pan_obj) return EINA_FALSE;
1538 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, EINA_FALSE);
1540 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
1541 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
1542 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1543 psd->api->pos_get(sid->pan_obj, &px, &py);
1544 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &pw, &ph);
1547 if ((x < px) && ((x + w) < (px + (cw - mx)))) nx = x;
1548 else if ((x > px) && ((x + w) > (px + (cw - mx))))
1549 nx = x + w - (cw - mx);
1551 if ((y < py) && ((y + h) < (py + (ch - my)))) ny = y;
1552 else if ((y > py) && ((y + h) > (py + (ch - my))))
1553 ny = y + h - (ch - my);
1555 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
1556 (sid->scrollto.x.animator) || (sid->scrollto.y.animator))
1558 _elm_scroll_anim_stop(sid);
1560 if (sid->scrollto.x.animator)
1562 ecore_animator_del(sid->scrollto.x.animator);
1563 sid->scrollto.x.animator = NULL;
1565 if (sid->scrollto.y.animator)
1567 ecore_animator_del(sid->scrollto.y.animator);
1568 sid->scrollto.y.animator = NULL;
1570 if (sid->down.bounce_x_animator)
1572 ecore_animator_del(sid->down.bounce_x_animator);
1573 sid->down.bounce_x_animator = NULL;
1574 sid->bouncemex = EINA_FALSE;
1575 if (sid->content_info.resized)
1576 _elm_scroll_wanted_region_set(sid->obj);
1578 if (sid->down.bounce_y_animator)
1580 ecore_animator_del(sid->down.bounce_y_animator);
1581 sid->down.bounce_y_animator = NULL;
1582 sid->bouncemey = EINA_FALSE;
1583 if (sid->content_info.resized)
1584 _elm_scroll_wanted_region_set(sid->obj);
1586 if (sid->down.hold_animator)
1588 ecore_animator_del(sid->down.hold_animator);
1589 sid->down.hold_animator = NULL;
1590 _elm_scroll_drag_stop(sid);
1591 if (sid->content_info.resized)
1592 _elm_scroll_wanted_region_set(sid->obj);
1594 if (sid->down.momentum_animator)
1596 ecore_animator_del(sid->down.momentum_animator);
1597 sid->down.momentum_animator = NULL;
1598 sid->down.bounce_x_hold = EINA_FALSE;
1599 sid->down.bounce_y_hold = EINA_FALSE;
1604 if (sid->content_info.resized)
1605 _elm_scroll_wanted_region_set(sid->obj);
1608 if (_paging_is_enabled(sid))
1610 x = _elm_scroll_page_x_get(sid, nx - px, EINA_FALSE);
1611 y = _elm_scroll_page_y_get(sid, ny - py, EINA_FALSE);
1618 if ((x + pw) > cw) x = cw - pw;
1619 if (x < minx) x = minx;
1620 if ((y + ph) > ch) y = ch - ph;
1621 if (y < miny) y = miny;
1623 if ((x == px) && (y == py)) return EINA_FALSE;
1629 /* Set should be used for calculated positions, for example, when we move
1630 * because of an animation or because this is the correct position after
1633 _elm_scroll_content_region_set(Evas_Object *obj,
1639 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1641 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
1643 _elm_scroll_content_pos_set(obj, x, y, EINA_FALSE);
1646 sid->down.x = sid->down.history[0].x;
1647 sid->down.y = sid->down.history[0].y;
1651 /* Set should be used for setting the wanted position, for example a
1652 * user scroll or moving the cursor in an entry. */
1654 _elm_scroll_content_region_show(Evas_Object *obj,
1660 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1666 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
1668 _elm_scroll_content_pos_set(obj, x, y, EINA_TRUE);
1671 sid->down.x = sid->down.history[0].x;
1672 sid->down.y = sid->down.history[0].y;
1677 _elm_scroll_wanted_region_set(Evas_Object *obj)
1679 Evas_Coord ww, wh, wx;
1681 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1685 if (sid->down.now || sid->down.momentum_animator ||
1686 sid->down.bounce_x_animator || sid->down.bounce_y_animator ||
1687 sid->down.hold_animator || sid->down.onhold_animator ||
1688 sid->scrollto.x.animator || sid->scrollto.y.animator)
1691 sid->content_info.resized = EINA_FALSE;
1693 /* Flip to RTL cords only if init in RTL mode */
1694 if (sid->is_mirrored)
1695 wx = _elm_scroll_x_mirrored_get(obj, sid->wx);
1699 _elm_scroll_content_viewport_size_get(obj, &ww, &wh);
1707 _elm_scroll_content_region_set(obj, wx, sid->wy, ww, wh);
1711 _elm_scroll_wheel_event_cb(void *data,
1713 Evas_Object *obj __UNUSED__,
1716 Elm_Scrollable_Smart_Interface_Data *sid;
1717 Evas_Event_Mouse_Wheel *ev;
1718 Evas_Coord x = 0, y = 0, vw = 0, vh = 0, cw = 0, ch = 0;
1722 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
1724 direction = ev->direction;
1725 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1726 if ((evas_key_modifier_is_set(ev->modifiers, "Control")) ||
1727 (evas_key_modifier_is_set(ev->modifiers, "Alt")) ||
1728 (evas_key_modifier_is_set(ev->modifiers, "Meta")) ||
1729 (evas_key_modifier_is_set(ev->modifiers, "Hyper")) ||
1730 (evas_key_modifier_is_set(ev->modifiers, "Super")))
1732 else if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
1733 direction = !direction;
1734 _elm_scroll_content_pos_get(sid->obj, &x, &y);
1735 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
1736 (sid->scrollto.x.animator) || (sid->scrollto.y.animator))
1738 _elm_scroll_anim_stop(sid);
1740 if (sid->scrollto.x.animator)
1742 ecore_animator_del(sid->scrollto.x.animator);
1743 sid->scrollto.x.animator = NULL;
1745 if (sid->scrollto.y.animator)
1747 ecore_animator_del(sid->scrollto.y.animator);
1748 sid->scrollto.y.animator = NULL;
1750 if (sid->down.bounce_x_animator)
1752 ecore_animator_del(sid->down.bounce_x_animator);
1753 sid->down.bounce_x_animator = NULL;
1754 sid->bouncemex = EINA_FALSE;
1755 if (sid->content_info.resized)
1756 _elm_scroll_wanted_region_set(sid->obj);
1758 if (sid->down.bounce_y_animator)
1760 ecore_animator_del(sid->down.bounce_y_animator);
1761 sid->down.bounce_y_animator = NULL;
1762 sid->bouncemey = EINA_FALSE;
1763 if (sid->content_info.resized)
1764 _elm_scroll_wanted_region_set(sid->obj);
1766 _elm_scroll_content_viewport_size_get(sid->obj, &vw, &vh);
1767 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1770 if (ch > vh || cw <= vw)
1771 y += ev->z * sid->step.y;
1773 x += ev->z * sid->step.x;
1775 else if (direction == 1)
1777 if (cw > vw || ch <= vh)
1778 x += ev->z * sid->step.x;
1780 y += ev->z * sid->step.y;
1783 if ((!sid->hold) && (!sid->freeze))
1785 _elm_scroll_wanted_coordinates_update(sid, x, y);
1786 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
1791 _elm_scroll_post_event_up(void *data,
1794 Elm_Scrollable_Smart_Interface_Data *sid = data;
1798 if (sid->down.dragged)
1800 elm_widget_drag_lock_x_set(sid->obj, EINA_FALSE);
1801 elm_widget_drag_lock_y_set(sid->obj, EINA_FALSE);
1808 _paging_is_enabled(Elm_Scrollable_Smart_Interface_Data *sid)
1810 if ((sid->pagerel_h == 0.0) && (!sid->pagesize_h) &&
1811 (sid->pagerel_v == 0.0) && (!sid->pagesize_v))
1817 _elm_scroll_momentum_animator(void *data)
1820 Elm_Scrollable_Smart_Interface_Data *sid = data;
1821 Evas_Coord x, y, dx, dy, px, py, maxx, maxy, minx, miny;
1822 Eina_Bool no_bounce_x_end = EINA_FALSE, no_bounce_y_end = EINA_FALSE;
1824 if (!sid->pan_obj) return ECORE_CALLBACK_CANCEL;
1826 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, ECORE_CALLBACK_CANCEL);
1828 t = ecore_loop_time_get();
1829 dt = t - sid->down.anim_start;
1832 dt = dt / (_elm_config->thumbscroll_friction + sid->down.extra_time);
1833 if (dt > 1.0) dt = 1.0;
1834 p = 1.0 - ((1.0 - dt) * (1.0 - dt));
1835 dx = (sid->down.dx * (_elm_config->thumbscroll_friction +
1836 sid->down.extra_time) * p);
1837 dy = (sid->down.dy * (_elm_config->thumbscroll_friction +
1838 sid->down.extra_time) * p);
1841 x = sid->down.sx - dx;
1842 y = sid->down.sy - dy;
1843 _elm_scroll_content_pos_get(sid->obj, &px, &py);
1844 if ((sid->down.bounce_x_animator) ||
1845 (sid->down.bounce_x_hold))
1847 sid->down.bx = sid->down.bx0 - dx + sid->down.b0x;
1850 if ((sid->down.bounce_y_animator) ||
1851 (sid->down.bounce_y_hold))
1853 sid->down.by = sid->down.by0 - dy + sid->down.b0y;
1856 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
1857 _elm_scroll_wanted_coordinates_update(sid, x, y);
1858 psd->api->pos_max_get(sid->pan_obj, &maxx, &maxy);
1859 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
1860 if (!sid->bounce_horiz)
1862 if (x <= minx) no_bounce_x_end = EINA_TRUE;
1863 if ((x - minx) >= maxx) no_bounce_x_end = EINA_TRUE;
1865 if (!sid->bounce_vert)
1867 if (y <= miny) no_bounce_y_end = EINA_TRUE;
1868 if ((y - miny) >= maxy) no_bounce_y_end = EINA_TRUE;
1871 ((sid->down.bounce_x_hold) && (sid->down.bounce_y_hold)) ||
1872 (no_bounce_x_end && no_bounce_y_end))
1874 _elm_scroll_anim_stop(sid);
1876 sid->down.momentum_animator = NULL;
1877 sid->down.bounce_x_hold = EINA_FALSE;
1878 sid->down.bounce_y_hold = EINA_FALSE;
1883 if (sid->content_info.resized)
1884 _elm_scroll_wanted_region_set(sid->obj);
1886 return ECORE_CALLBACK_CANCEL;
1890 return ECORE_CALLBACK_RENEW;
1894 _elm_scroll_page_x_get(Elm_Scrollable_Smart_Interface_Data *sid,
1895 int offset, Eina_Bool limit)
1897 Evas_Coord x, y, w, h, dx, cw, ch, minx = 0;
1899 if (!sid->pan_obj) return 0;
1901 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, 0);
1903 _elm_scroll_content_pos_get(sid->obj, &x, &y);
1904 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
1905 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1906 psd->api->pos_min_get(sid->pan_obj, &minx, NULL);
1908 if (sid->pagerel_h > 0.0)
1909 sid->pagesize_h = w * sid->pagerel_h;
1915 dx = (sid->pagesize_h * ((double)sid->page_limit_h - 0.5));
1918 x += (abs(offset) < dx ? offset : dx);
1920 x += (abs(offset) < dx ? offset : -dx);
1923 if (sid->pagesize_h > 0)
1925 x = x + (sid->pagesize_h * 0.5);
1926 x = x / (sid->pagesize_h);
1927 x = x * (sid->pagesize_h);
1929 if ((x + w) > cw) x = cw - w;
1930 if (x < minx) x = minx;
1936 _elm_scroll_page_y_get(Elm_Scrollable_Smart_Interface_Data *sid,
1937 int offset, Eina_Bool limit)
1939 Evas_Coord x, y, w, h, dy, cw, ch, miny = 0;
1941 if (!sid->pan_obj) return 0;
1943 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, 0);
1945 _elm_scroll_content_pos_get(sid->obj, &x, &y);
1946 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
1947 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1948 psd->api->pos_min_get(sid->pan_obj, NULL, &miny);
1950 if (sid->pagerel_v > 0.0)
1951 sid->pagesize_v = h * sid->pagerel_v;
1957 dy = (sid->pagesize_v * ((double)sid->page_limit_v - 0.5));
1960 y += (abs(offset) < dy ? offset : dy);
1962 y += (abs(offset) < dy ? offset : -dy);
1965 if (sid->pagesize_v > 0)
1967 y = y + (sid->pagesize_v * 0.5);
1968 y = y / (sid->pagesize_v);
1969 y = y * (sid->pagesize_v);
1971 if ((y + h) > ch) y = ch - h;
1972 if (y < miny) y = miny;
1978 _elm_scroll_scroll_to_x_animator(void *data)
1980 Elm_Scrollable_Smart_Interface_Data *sid = data;
1984 if (!sid->pan_obj) return ECORE_CALLBACK_CANCEL;
1986 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, ECORE_CALLBACK_CANCEL);
1988 t = ecore_loop_time_get();
1989 tt = (t - sid->scrollto.x.t_start) /
1990 (sid->scrollto.x.t_end - sid->scrollto.x.t_start);
1992 tt = 1.0 - (tt * tt);
1993 psd->api->pos_get(sid->pan_obj, &px, &py);
1994 px = (sid->scrollto.x.start * (1.0 - tt)) +
1995 (sid->scrollto.x.end * tt);
1996 if (t >= sid->scrollto.x.t_end)
1998 px = sid->scrollto.x.end;
1999 _elm_scroll_content_pos_set(sid->obj, px, py, EINA_TRUE);
2001 sid->down.x = sid->down.history[0].x;
2002 _elm_scroll_wanted_coordinates_update(sid, px, py);
2003 sid->scrollto.x.animator = NULL;
2004 if ((!sid->scrollto.y.animator) && (!sid->down.bounce_y_animator))
2005 _elm_scroll_anim_stop(sid);
2006 return ECORE_CALLBACK_CANCEL;
2008 _elm_scroll_content_pos_set(sid->obj, px, py, EINA_TRUE);
2009 _elm_scroll_wanted_coordinates_update(sid, px, py);
2010 return ECORE_CALLBACK_RENEW;
2014 _elm_scroll_scroll_to_y_animator(void *data)
2016 Elm_Scrollable_Smart_Interface_Data *sid = data;
2020 if (!sid->pan_obj) return EINA_FALSE;
2022 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, EINA_FALSE);
2024 t = ecore_loop_time_get();
2025 tt = (t - sid->scrollto.y.t_start) /
2026 (sid->scrollto.y.t_end - sid->scrollto.y.t_start);
2028 tt = 1.0 - (tt * tt);
2029 psd->api->pos_get(sid->pan_obj, &px, &py);
2030 py = (sid->scrollto.y.start * (1.0 - tt)) +
2031 (sid->scrollto.y.end * tt);
2032 if (t >= sid->scrollto.y.t_end)
2034 py = sid->scrollto.y.end;
2035 _elm_scroll_content_pos_set(sid->obj, px, py, EINA_TRUE);
2037 sid->down.y = sid->down.history[0].y;
2038 _elm_scroll_wanted_coordinates_update(sid, px, py);
2039 sid->scrollto.y.animator = NULL;
2040 if ((!sid->scrollto.x.animator) && (!sid->down.bounce_x_animator))
2041 _elm_scroll_anim_stop(sid);
2042 return ECORE_CALLBACK_CANCEL;
2044 _elm_scroll_content_pos_set(sid->obj, px, py, EINA_TRUE);
2045 _elm_scroll_wanted_coordinates_update(sid, px, py);
2047 return ECORE_CALLBACK_RENEW;
2051 _elm_scroll_scroll_to_y(Elm_Scrollable_Smart_Interface_Data *sid,
2055 Evas_Coord px, py, x, y, w, h;
2058 if (!sid->pan_obj) return;
2060 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2062 if (sid->freeze) return;
2065 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2066 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
2068 _elm_scroll_content_region_set(sid->obj, x, y, w, h);
2071 t = ecore_loop_time_get();
2072 psd->api->pos_get(sid->pan_obj, &px, &py);
2073 sid->scrollto.y.start = py;
2074 sid->scrollto.y.end = pos_y;
2075 sid->scrollto.y.t_start = t;
2076 sid->scrollto.y.t_end = t + t_in;
2077 if (!sid->scrollto.y.animator)
2079 sid->scrollto.y.animator =
2080 ecore_animator_add(_elm_scroll_scroll_to_y_animator, sid);
2081 if (!sid->scrollto.x.animator)
2082 _elm_scroll_anim_start(sid);
2084 if (sid->down.bounce_y_animator)
2086 ecore_animator_del(sid->down.bounce_y_animator);
2087 sid->down.bounce_y_animator = NULL;
2088 _elm_scroll_momentum_end(sid);
2089 if (sid->content_info.resized)
2090 _elm_scroll_wanted_region_set(sid->obj);
2092 sid->bouncemey = EINA_FALSE;
2096 _elm_scroll_scroll_to_x(Elm_Scrollable_Smart_Interface_Data *sid,
2100 Evas_Coord px, py, x, y, w, h;
2103 if (!sid->pan_obj) return;
2105 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2107 if (sid->freeze) return;
2110 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2111 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
2113 _elm_scroll_content_region_set(sid->obj, x, y, w, h);
2116 t = ecore_loop_time_get();
2117 psd->api->pos_get(sid->pan_obj, &px, &py);
2118 sid->scrollto.x.start = px;
2119 sid->scrollto.x.end = pos_x;
2120 sid->scrollto.x.t_start = t;
2121 sid->scrollto.x.t_end = t + t_in;
2122 if (!sid->scrollto.x.animator)
2124 sid->scrollto.x.animator =
2125 ecore_animator_add(_elm_scroll_scroll_to_x_animator, sid);
2126 if (!sid->scrollto.y.animator)
2127 _elm_scroll_anim_start(sid);
2129 if (sid->down.bounce_x_animator)
2131 ecore_animator_del(sid->down.bounce_x_animator);
2132 sid->down.bounce_x_animator = NULL;
2133 _elm_scroll_momentum_end(sid);
2134 if (sid->content_info.resized)
2135 _elm_scroll_wanted_region_set(sid->obj);
2137 sid->bouncemex = EINA_FALSE;
2141 _elm_scroll_mouse_up_event_cb(void *data,
2143 Evas_Object *obj __UNUSED__,
2146 Elm_Scrollable_Smart_Interface_Data *sid = data;
2147 Evas_Coord x = 0, y = 0, ox = 0, oy = 0;
2148 Evas_Event_Mouse_Down *ev;
2150 if (!sid->pan_obj) return;
2152 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2155 sid->down.hold_parent = EINA_FALSE;
2158 evas_post_event_callback_push(e, _elm_scroll_post_event_up, sid);
2160 // FIXME: respect elm_widget_scroll_hold_get of parent container
2161 if (!_elm_config->thumbscroll_enable) return;
2163 if (ev->button == 1)
2165 if (sid->down.onhold_animator)
2167 ecore_animator_del(sid->down.onhold_animator);
2168 sid->down.onhold_animator = NULL;
2169 if (sid->content_info.resized)
2170 _elm_scroll_wanted_region_set(sid->obj);
2172 x = ev->canvas.x - sid->down.x;
2173 y = ev->canvas.y - sid->down.y;
2174 if (sid->down.dragged)
2176 _elm_scroll_drag_stop(sid);
2177 if ((!sid->hold) && (!sid->freeze))
2181 Evas_Coord ax, ay, dx, dy, vel;
2184 t = ev->timestamp / 1000.0;
2186 t = ecore_loop_time_get();
2189 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2194 DBG("------ %i %i\n", ev->canvas.x, ev->canvas.y);
2196 for (i = 0; i < 60; i++)
2198 dt = t - sid->down.history[i].timestamp;
2199 if (dt > 0.2) break;
2201 DBG("H: %i %i @ %1.3f\n",
2202 sid->down.history[i].x,
2203 sid->down.history[i].y, dt);
2206 ax += sid->down.history[i].x;
2207 ay += sid->down.history[i].y;
2212 at /= _elm_config->thumbscroll_sensitivity_friction;
2213 dx = ev->canvas.x - ax;
2214 dy = ev->canvas.y - ay;
2217 vel = sqrt((dx * dx) + (dy * dy)) / at;
2218 if ((_elm_config->thumbscroll_friction > 0.0) &&
2219 (vel > _elm_config->thumbscroll_momentum_threshold))
2221 sid->down.dx = ((double)dx / at);
2222 sid->down.dy = ((double)dy / at);
2223 sid->down.extra_time = 0.0;
2224 sid->down.pdx = sid->down.dx;
2225 sid->down.pdy = sid->down.dy;
2228 if (!_paging_is_enabled(sid))
2230 if ((!sid->down.momentum_animator) &&
2231 (!sid->momentum_animator_disabled) &&
2233 (!elm_widget_drag_child_locked_y_get
2236 sid->down.momentum_animator =
2238 (_elm_scroll_momentum_animator, sid);
2240 EVAS_EVENT_FLAG_ON_SCROLL;
2241 _elm_scroll_anim_start(sid);
2243 sid->down.anim_start = ecore_loop_time_get();
2244 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2258 evas_event_feed_hold(e, 0, ev->timestamp, ev->data);
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, EINA_TRUE);
2271 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2272 _elm_scroll_scroll_to_x
2273 (sid, _elm_config->page_scroll_friction, pgx);
2277 (!elm_widget_drag_child_locked_y_get
2280 pgy = _elm_scroll_page_y_get(sid, oy, EINA_TRUE);
2283 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2284 _elm_scroll_scroll_to_y
2285 (sid, _elm_config->page_scroll_friction, pgy);
2294 if (_paging_is_enabled(sid))
2296 Evas_Coord pgx, pgy;
2298 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2300 (!elm_widget_drag_child_locked_x_get
2303 pgx = _elm_scroll_page_x_get(sid, ox, EINA_TRUE);
2305 _elm_scroll_scroll_to_x
2306 (sid, _elm_config->page_scroll_friction, pgx);
2309 (!elm_widget_drag_child_locked_y_get
2312 pgy = _elm_scroll_page_y_get(sid, oy, EINA_TRUE);
2314 _elm_scroll_scroll_to_y
2315 (sid, _elm_config->page_scroll_friction, pgy);
2319 if (sid->down.hold_animator)
2321 ecore_animator_del(sid->down.hold_animator);
2322 sid->down.hold_animator = NULL;
2323 if (sid->content_info.resized)
2324 _elm_scroll_wanted_region_set(sid->obj);
2326 if (sid->down.scroll)
2328 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2329 sid->down.scroll = EINA_FALSE;
2333 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2334 sid->down.hold = EINA_FALSE;
2336 sid->down.dragged_began = EINA_FALSE;
2337 sid->down.dir_x = EINA_FALSE;
2338 sid->down.dir_y = EINA_FALSE;
2339 sid->down.want_dragged = EINA_FALSE;
2340 sid->down.dragged = EINA_FALSE;
2341 sid->down.now = EINA_FALSE;
2342 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2343 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
2344 _elm_scroll_wanted_coordinates_update(sid, x, y);
2346 if (sid->content_info.resized)
2347 _elm_scroll_wanted_region_set(sid->obj);
2349 if (!_paging_is_enabled(sid))
2350 _elm_scroll_bounce_eval(sid);
2355 _elm_scroll_mouse_down_event_cb(void *data,
2357 Evas_Object *obj __UNUSED__,
2360 Elm_Scrollable_Smart_Interface_Data *sid;
2361 Evas_Event_Mouse_Down *ev;
2362 Evas_Coord x = 0, y = 0;
2367 if (_elm_config->thumbscroll_enable)
2369 sid->down.hold = EINA_FALSE;
2370 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
2371 (sid->down.momentum_animator) || (sid->scrollto.x.animator) ||
2372 (sid->scrollto.y.animator))
2374 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL |
2375 EVAS_EVENT_FLAG_ON_HOLD;
2376 sid->down.scroll = EINA_TRUE;
2377 sid->down.hold = EINA_TRUE;
2378 _elm_scroll_anim_stop(sid);
2380 if (sid->scrollto.x.animator)
2382 ecore_animator_del(sid->scrollto.x.animator);
2383 sid->scrollto.x.animator = NULL;
2385 if (sid->scrollto.y.animator)
2387 ecore_animator_del(sid->scrollto.y.animator);
2388 sid->scrollto.y.animator = NULL;
2390 if (sid->down.bounce_x_animator)
2392 ecore_animator_del(sid->down.bounce_x_animator);
2393 sid->down.bounce_x_animator = NULL;
2394 sid->bouncemex = EINA_FALSE;
2395 if (sid->content_info.resized)
2396 _elm_scroll_wanted_region_set(sid->obj);
2398 if (sid->down.bounce_y_animator)
2400 ecore_animator_del(sid->down.bounce_y_animator);
2401 sid->down.bounce_y_animator = NULL;
2402 sid->bouncemey = EINA_FALSE;
2403 if (sid->content_info.resized)
2404 _elm_scroll_wanted_region_set(sid->obj);
2406 if (sid->down.hold_animator)
2408 ecore_animator_del(sid->down.hold_animator);
2409 sid->down.hold_animator = NULL;
2410 _elm_scroll_drag_stop(sid);
2411 if (sid->content_info.resized)
2412 _elm_scroll_wanted_region_set(sid->obj);
2414 if (sid->down.momentum_animator)
2416 ecore_animator_del(sid->down.momentum_animator);
2417 sid->down.momentum_animator = NULL;
2418 sid->down.bounce_x_hold = EINA_FALSE;
2419 sid->down.bounce_y_hold = EINA_FALSE;
2422 if (sid->content_info.resized)
2423 _elm_scroll_wanted_region_set(sid->obj);
2425 if (ev->button == 1)
2427 sid->down.hist.est_timestamp_diff =
2428 ecore_loop_time_get() - ((double)ev->timestamp / 1000.0);
2429 sid->down.hist.tadd = 0.0;
2430 sid->down.hist.dxsum = 0.0;
2431 sid->down.hist.dysum = 0.0;
2432 sid->down.now = EINA_TRUE;
2433 sid->down.dragged = EINA_FALSE;
2434 sid->down.dir_x = EINA_FALSE;
2435 sid->down.dir_y = EINA_FALSE;
2436 sid->down.x = ev->canvas.x;
2437 sid->down.y = ev->canvas.y;
2438 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2441 sid->down.locked = EINA_FALSE;
2442 memset(&(sid->down.history[0]), 0,
2443 sizeof(sid->down.history[0]) * 60);
2445 sid->down.history[0].timestamp = ev->timestamp / 1000.0;
2446 sid->down.history[0].localtimestamp = ecore_loop_time_get();
2448 sid->down.history[0].timestamp = ecore_loop_time_get();
2450 sid->down.history[0].x = ev->canvas.x;
2451 sid->down.history[0].y = ev->canvas.y;
2453 sid->down.dragged_began = EINA_FALSE;
2454 sid->down.hold_parent = EINA_FALSE;
2455 sid->down.cancelled = EINA_FALSE;
2456 if (sid->hold || sid->freeze)
2457 sid->down.want_reset = EINA_TRUE;
2459 sid->down.want_reset = EINA_FALSE;
2464 _elm_scroll_can_scroll(Elm_Scrollable_Smart_Interface_Data *sid,
2467 Evas_Coord mx = 0, my = 0, px = 0, py = 0, minx = 0, miny = 0;
2469 if (!sid->pan_obj) return EINA_FALSE;
2471 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, EINA_FALSE);
2473 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
2474 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
2475 psd->api->pos_get(sid->pan_obj, &px, &py);
2479 if (px > minx) return EINA_TRUE;
2483 if ((px - minx) < mx) return EINA_TRUE;
2487 if (py > miny) return EINA_TRUE;
2491 if ((py - miny) < my) return EINA_TRUE;
2501 _elm_scroll_post_event_move(void *data,
2504 Elm_Scrollable_Smart_Interface_Data *sid = data;
2506 if (sid->down.want_dragged)
2510 if (sid->down.hold_parent)
2512 if ((sid->down.dir_x) &&
2513 !_elm_scroll_can_scroll(sid, sid->down.hdir))
2515 sid->down.dir_x = EINA_FALSE;
2517 if ((sid->down.dir_y) &&
2518 !_elm_scroll_can_scroll(sid, sid->down.vdir))
2520 sid->down.dir_y = EINA_FALSE;
2523 if (sid->down.dir_x)
2526 (!elm_widget_drag_child_locked_x_get(sid->obj)))
2528 sid->down.want_dragged = EINA_FALSE;
2529 sid->down.dragged = EINA_TRUE;
2532 elm_widget_drag_lock_x_set(sid->obj, 1);
2537 sid->down.dir_x = EINA_FALSE;
2539 if (sid->down.dir_y)
2542 (!elm_widget_drag_child_locked_y_get(sid->obj)))
2544 sid->down.want_dragged = EINA_FALSE;
2545 sid->down.dragged = EINA_TRUE;
2548 elm_widget_drag_lock_y_set
2549 (sid->obj, EINA_TRUE);
2554 sid->down.dir_y = EINA_FALSE;
2556 if ((!sid->down.dir_x) && (!sid->down.dir_y))
2558 sid->down.cancelled = EINA_TRUE;
2560 if (start) _elm_scroll_drag_start(sid);
2567 _elm_scroll_down_coord_eval(Elm_Scrollable_Smart_Interface_Data *sid,
2571 Evas_Coord minx, miny;
2573 if (!sid->pan_obj) return;
2575 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2577 if (sid->down.dir_x) *x = sid->down.sx - (*x - sid->down.x);
2578 else *x = sid->down.sx;
2579 if (sid->down.dir_y) *y = sid->down.sy - (*y - sid->down.y);
2580 else *y = sid->down.sy;
2582 if ((sid->down.dir_x) || (sid->down.dir_y))
2584 if (!((sid->down.dir_x) && (sid->down.dir_y)))
2586 if (sid->down.dir_x) *y = sid->down.locked_y;
2587 else *x = sid->down.locked_x;
2591 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
2594 *x += (minx - *x) * _elm_config->thumbscroll_border_friction;
2595 else if (sid->content_info.w <= sid->w)
2596 *x += (sid->down.sx - *x) * _elm_config->thumbscroll_border_friction;
2597 else if ((sid->content_info.w - sid->w + minx) < *x)
2598 *x += (sid->content_info.w - sid->w + minx - *x) *
2599 _elm_config->thumbscroll_border_friction;
2602 *y += (miny - *y) * _elm_config->thumbscroll_border_friction;
2603 else if (sid->content_info.h <= sid->h)
2604 *y += (sid->down.sy - *y) * _elm_config->thumbscroll_border_friction;
2605 else if ((sid->content_info.h - sid->h + miny) < *y)
2606 *y += (sid->content_info.h - sid->h + miny - *y) *
2607 _elm_config->thumbscroll_border_friction;
2611 _elm_scroll_hold_animator(void *data)
2613 Elm_Scrollable_Smart_Interface_Data *sid = data;
2614 Evas_Coord ox = 0, oy = 0, fx = 0, fy = 0;
2616 fx = sid->down.hold_x;
2617 fy = sid->down.hold_y;
2619 _elm_scroll_content_pos_get(sid->obj, &ox, &oy);
2620 if (sid->down.dir_x)
2623 (!elm_widget_drag_child_locked_x_get(sid->obj)))
2626 if (sid->down.dir_y)
2629 (!elm_widget_drag_child_locked_y_get(sid->obj)))
2633 _elm_scroll_content_pos_set(sid->obj, ox, oy, EINA_TRUE);
2635 return ECORE_CALLBACK_RENEW;
2639 _elm_scroll_on_hold_animator(void *data)
2643 Evas_Coord x, y, ox, oy;
2644 Elm_Scrollable_Smart_Interface_Data *sid;
2647 t = ecore_loop_time_get();
2648 if (sid->down.onhold_tlast > 0.0)
2650 td = t - sid->down.onhold_tlast;
2651 vx = sid->down.onhold_vx * td *
2652 (double)_elm_config->thumbscroll_hold_threshold * 2.0;
2653 vy = sid->down.onhold_vy * td *
2654 (double)_elm_config->thumbscroll_hold_threshold * 2.0;
2655 _elm_scroll_content_pos_get(sid->obj, &ox, &oy);
2659 if (sid->down.dir_x)
2662 (!elm_widget_drag_child_locked_x_get(sid->obj)))
2664 sid->down.onhold_vxe += vx;
2665 x = ox + (int)sid->down.onhold_vxe;
2666 sid->down.onhold_vxe -= (int)sid->down.onhold_vxe;
2670 if (sid->down.dir_y)
2673 (!elm_widget_drag_child_locked_y_get(sid->obj)))
2675 sid->down.onhold_vye += vy;
2676 y = oy + (int)sid->down.onhold_vye;
2677 sid->down.onhold_vye -= (int)sid->down.onhold_vye;
2681 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
2683 sid->down.onhold_tlast = t;
2685 return ECORE_CALLBACK_RENEW;
2689 _elm_scroll_mouse_move_event_cb(void *data,
2691 Evas_Object *obj __UNUSED__,
2694 Elm_Scrollable_Smart_Interface_Data *sid = data;
2695 Evas_Event_Mouse_Move *ev;
2696 Evas_Coord x = 0, y = 0;
2698 if (!sid->pan_obj) return;
2700 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2703 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
2704 sid->down.hold_parent = EINA_TRUE;
2705 evas_post_event_callback_push(e, _elm_scroll_post_event_move, sid);
2707 // FIXME: respect elm_widget_scroll_hold_get of parent container
2708 if (_elm_config->thumbscroll_enable)
2714 if ((sid->scrollto.x.animator) && (!sid->hold) && (!sid->freeze))
2717 ecore_animator_del(sid->scrollto.x.animator);
2718 sid->scrollto.x.animator = NULL;
2719 psd->api->pos_get(sid->pan_obj, &px, NULL);
2721 sid->down.x = sid->down.history[0].x;
2724 if ((sid->scrollto.y.animator) && (!sid->hold) && (!sid->freeze))
2727 ecore_animator_del(sid->scrollto.y.animator);
2728 sid->scrollto.y.animator = NULL;
2729 psd->api->pos_get(sid->pan_obj, NULL, &py);
2731 sid->down.y = sid->down.history[0].y;
2735 DBG("::: %i %i\n", ev->cur.canvas.x, ev->cur.canvas.y);
2737 memmove(&(sid->down.history[1]), &(sid->down.history[0]),
2738 sizeof(sid->down.history[0]) * (60 - 1));
2740 sid->down.history[0].timestamp = ev->timestamp / 1000.0;
2741 sid->down.history[0].localtimestamp = ecore_loop_time_get();
2743 sid->down.history[0].timestamp = ecore_loop_time_get();
2745 sid->down.history[0].x = ev->cur.canvas.x;
2746 sid->down.history[0].y = ev->cur.canvas.y;
2748 if (!sid->down.dragged_began)
2750 x = ev->cur.canvas.x - sid->down.x;
2751 y = ev->cur.canvas.y - sid->down.y;
2753 sid->down.hdir = -1;
2754 sid->down.vdir = -1;
2756 if (x > 0) sid->down.hdir = LEFT;
2758 sid->down.hdir = RIGHT;
2759 if (y > 0) sid->down.vdir = UP;
2761 sid->down.vdir = DOWN;
2766 if ((sid->one_direction_at_a_time) &&
2767 (!((sid->down.dir_x) || (sid->down.dir_y))))
2769 if (x > _elm_config->thumbscroll_threshold)
2773 sid->down.dir_x = EINA_TRUE;
2774 sid->down.dir_y = EINA_FALSE;
2778 if (y > _elm_config->thumbscroll_threshold)
2782 sid->down.dir_x = EINA_FALSE;
2783 sid->down.dir_y = EINA_TRUE;
2789 sid->down.dir_x = EINA_TRUE;
2790 sid->down.dir_y = EINA_TRUE;
2795 sid->down.dir_x = EINA_TRUE;
2796 sid->down.dir_y = EINA_TRUE;
2799 if ((!sid->hold) && (!sid->freeze))
2801 if ((sid->down.dragged) ||
2802 (((x * x) + (y * y)) >
2803 (_elm_config->thumbscroll_threshold *
2804 _elm_config->thumbscroll_threshold)))
2806 sid->down.dragged_began = EINA_TRUE;
2807 if (!sid->down.dragged)
2809 sid->down.want_dragged = EINA_TRUE;
2810 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2812 if (sid->down.dragged)
2814 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2816 if (sid->down.dir_x)
2817 x = sid->down.sx - (ev->cur.canvas.x - sid->down.x);
2820 if (sid->down.dir_y)
2821 y = sid->down.sy - (ev->cur.canvas.y - sid->down.y);
2824 if (sid->down.want_reset)
2826 sid->down.x = ev->cur.canvas.x;
2827 sid->down.y = ev->cur.canvas.y;
2828 sid->down.want_reset = EINA_FALSE;
2830 if ((sid->down.dir_x) || (sid->down.dir_y))
2832 if (!sid->down.locked)
2834 sid->down.locked_x = x;
2835 sid->down.locked_y = y;
2836 sid->down.locked = EINA_TRUE;
2838 if (!((sid->down.dir_x) && (sid->down.dir_y)))
2840 if (sid->down.dir_x) y = sid->down.locked_y;
2841 else x = sid->down.locked_x;
2845 Evas_Coord minx, miny, mx, my;
2847 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
2848 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
2851 _elm_config->thumbscroll_border_friction;
2853 y += (sid->down.sy - y) *
2854 _elm_config->thumbscroll_border_friction;
2855 else if ((my + miny) < y)
2856 y += (my + miny - y) *
2857 _elm_config->thumbscroll_border_friction;
2860 _elm_config->thumbscroll_border_friction;
2862 x += (sid->down.sx - x) *
2863 _elm_config->thumbscroll_border_friction;
2864 else if ((mx + minx) < x)
2865 x += (mx + minx - x) *
2866 _elm_config->thumbscroll_border_friction;
2869 sid->down.hold_x = x;
2870 sid->down.hold_y = y;
2871 if (!sid->down.hold_animator)
2872 sid->down.hold_animator =
2873 ecore_animator_add(_elm_scroll_hold_animator, sid);
2877 if (sid->down.dragged_began)
2879 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2880 if (!sid->down.hold)
2882 sid->down.hold = EINA_TRUE;
2883 evas_event_feed_hold
2884 (e, 1, ev->timestamp, ev->data);
2889 else if (!sid->freeze)
2891 double vx = 0.0, vy = 0.0;
2893 x = ev->cur.canvas.x - sid->x;
2894 y = ev->cur.canvas.y - sid->y;
2895 if (x < _elm_config->thumbscroll_hold_threshold)
2897 if (_elm_config->thumbscroll_hold_threshold > 0.0)
2898 vx = -(double)(_elm_config->thumbscroll_hold_threshold - x)
2899 / _elm_config->thumbscroll_hold_threshold;
2903 else if (x > (sid->w - _elm_config->thumbscroll_hold_threshold))
2905 if (_elm_config->thumbscroll_hold_threshold > 0.0)
2906 vx = (double)(_elm_config->thumbscroll_hold_threshold -
2908 _elm_config->thumbscroll_hold_threshold;
2912 if (y < _elm_config->thumbscroll_hold_threshold)
2914 if (_elm_config->thumbscroll_hold_threshold > 0.0)
2915 vy = -(double)(_elm_config->thumbscroll_hold_threshold - y)
2916 / _elm_config->thumbscroll_hold_threshold;
2920 else if (y > (sid->h - _elm_config->thumbscroll_hold_threshold))
2922 if (_elm_config->thumbscroll_hold_threshold > 0.0)
2923 vy = (double)(_elm_config->thumbscroll_hold_threshold -
2925 _elm_config->thumbscroll_hold_threshold;
2929 if ((vx != 0.0) || (vy != 0.0))
2931 sid->down.onhold_vx = vx;
2932 sid->down.onhold_vy = vy;
2933 if (!sid->down.onhold_animator)
2935 sid->down.onhold_vxe = 0.0;
2936 sid->down.onhold_vye = 0.0;
2937 sid->down.onhold_tlast = 0.0;
2938 sid->down.onhold_animator = ecore_animator_add
2939 (_elm_scroll_on_hold_animator, sid);
2944 if (sid->down.onhold_animator)
2946 ecore_animator_del(sid->down.onhold_animator);
2947 sid->down.onhold_animator = NULL;
2948 if (sid->content_info.resized)
2949 _elm_scroll_wanted_region_set(sid->obj);
2958 _elm_scroll_page_adjust(Elm_Scrollable_Smart_Interface_Data *sid)
2960 Evas_Coord x, y, w, h;
2962 if (!_paging_is_enabled(sid)) return;
2964 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
2966 x = _elm_scroll_page_x_get(sid, 0, EINA_TRUE);
2967 y = _elm_scroll_page_y_get(sid, 0, EINA_TRUE);
2969 _elm_scroll_content_region_set(sid->obj, x, y, w, h);
2973 _elm_scroll_reconfigure(Elm_Scrollable_Smart_Interface_Data *sid)
2975 _elm_scroll_scroll_bar_size_adjust(sid);
2976 _elm_scroll_page_adjust(sid);
2980 _on_edje_move(void *data,
2982 Evas_Object *edje_obj,
2983 void *event_info __UNUSED__)
2985 Elm_Scrollable_Smart_Interface_Data *sid = data;
2988 evas_object_geometry_get(edje_obj, &x, &y, NULL, NULL);
2993 _elm_scroll_reconfigure(sid);
2997 _on_edje_resize(void *data,
2999 Evas_Object *edje_obj,
3000 void *event_info __UNUSED__)
3002 Elm_Scrollable_Smart_Interface_Data *sid = data;
3005 evas_object_geometry_get(edje_obj, NULL, NULL, &w, &h);
3010 _elm_scroll_reconfigure(sid);
3011 _elm_scroll_wanted_region_set(sid->obj);
3015 _scroll_edje_object_attach(Evas_Object *obj)
3017 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3019 evas_object_event_callback_add
3020 (sid->edje_obj, EVAS_CALLBACK_RESIZE, _on_edje_resize, sid);
3021 evas_object_event_callback_add
3022 (sid->edje_obj, EVAS_CALLBACK_MOVE, _on_edje_move, sid);
3024 edje_object_signal_callback_add
3025 (sid->edje_obj, "drag", "elm.dragable.vbar", _elm_scroll_vbar_drag_cb,
3027 edje_object_signal_callback_add
3028 (sid->edje_obj, "drag,set", "elm.dragable.vbar",
3029 _elm_scroll_edje_drag_v_cb, sid);
3030 edje_object_signal_callback_add
3031 (sid->edje_obj, "drag,start", "elm.dragable.vbar",
3032 _elm_scroll_edje_drag_v_start_cb, sid);
3033 edje_object_signal_callback_add
3034 (sid->edje_obj, "drag,stop", "elm.dragable.vbar",
3035 _elm_scroll_edje_drag_v_stop_cb, sid);
3036 edje_object_signal_callback_add
3037 (sid->edje_obj, "drag,step", "elm.dragable.vbar",
3038 _elm_scroll_edje_drag_v_cb, sid);
3039 edje_object_signal_callback_add
3040 (sid->edje_obj, "drag,page", "elm.dragable.vbar",
3041 _elm_scroll_edje_drag_v_cb, sid);
3042 edje_object_signal_callback_add
3043 (sid->edje_obj, "elm,vbar,press", "elm",
3044 _elm_scroll_vbar_press_cb, sid);
3045 edje_object_signal_callback_add
3046 (sid->edje_obj, "elm,vbar,unpress", "elm",
3047 _elm_scroll_vbar_unpress_cb, sid);
3048 edje_object_signal_callback_add
3049 (sid->edje_obj, "drag", "elm.dragable.hbar", _elm_scroll_hbar_drag_cb,
3051 edje_object_signal_callback_add
3052 (sid->edje_obj, "drag,set", "elm.dragable.hbar",
3053 _elm_scroll_edje_drag_h_cb, sid);
3054 edje_object_signal_callback_add
3055 (sid->edje_obj, "drag,start", "elm.dragable.hbar",
3056 _elm_scroll_edje_drag_h_start_cb, sid);
3057 edje_object_signal_callback_add
3058 (sid->edje_obj, "drag,stop", "elm.dragable.hbar",
3059 _elm_scroll_edje_drag_h_stop_cb, sid);
3060 edje_object_signal_callback_add
3061 (sid->edje_obj, "drag,step", "elm.dragable.hbar",
3062 _elm_scroll_edje_drag_h_cb, sid);
3063 edje_object_signal_callback_add
3064 (sid->edje_obj, "drag,page", "elm.dragable.hbar",
3065 _elm_scroll_edje_drag_h_cb, sid);
3066 edje_object_signal_callback_add
3067 (sid->edje_obj, "elm,hbar,press", "elm",
3068 _elm_scroll_hbar_press_cb, sid);
3069 edje_object_signal_callback_add
3070 (sid->edje_obj, "elm,hbar,unpress", "elm",
3071 _elm_scroll_hbar_unpress_cb, sid);
3075 _scroll_event_object_attach(Evas_Object *obj)
3077 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3079 evas_object_event_callback_add
3080 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL, _elm_scroll_wheel_event_cb,
3082 evas_object_event_callback_add
3083 (sid->event_rect, EVAS_CALLBACK_MOUSE_DOWN,
3084 _elm_scroll_mouse_down_event_cb, sid);
3085 evas_object_event_callback_add
3086 (sid->event_rect, EVAS_CALLBACK_MOUSE_UP,
3087 _elm_scroll_mouse_up_event_cb, sid);
3088 evas_object_event_callback_add
3089 (sid->event_rect, EVAS_CALLBACK_MOUSE_MOVE,
3090 _elm_scroll_mouse_move_event_cb, sid);
3094 _scroll_edje_object_detach(Evas_Object *obj)
3096 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3098 evas_object_event_callback_del_full
3099 (sid->edje_obj, EVAS_CALLBACK_RESIZE, _on_edje_resize, sid);
3100 evas_object_event_callback_del_full
3101 (sid->edje_obj, EVAS_CALLBACK_MOVE, _on_edje_move, sid);
3103 edje_object_signal_callback_del_full
3104 (sid->edje_obj, "drag", "elm.dragable.vbar", _elm_scroll_vbar_drag_cb,
3106 edje_object_signal_callback_del_full
3107 (sid->edje_obj, "drag,set", "elm.dragable.vbar",
3108 _elm_scroll_edje_drag_v_cb, sid);
3109 edje_object_signal_callback_del_full
3110 (sid->edje_obj, "drag,start", "elm.dragable.vbar",
3111 _elm_scroll_edje_drag_v_start_cb, sid);
3112 edje_object_signal_callback_del_full
3113 (sid->edje_obj, "drag,stop", "elm.dragable.vbar",
3114 _elm_scroll_edje_drag_v_stop_cb, sid);
3115 edje_object_signal_callback_del_full
3116 (sid->edje_obj, "drag,step", "elm.dragable.vbar",
3117 _elm_scroll_edje_drag_v_cb, sid);
3118 edje_object_signal_callback_del_full
3119 (sid->edje_obj, "drag,page", "elm.dragable.vbar",
3120 _elm_scroll_edje_drag_v_cb, sid);
3121 edje_object_signal_callback_del_full
3122 (sid->edje_obj, "elm,vbar,press", "elm",
3123 _elm_scroll_vbar_press_cb, sid);
3124 edje_object_signal_callback_del_full
3125 (sid->edje_obj, "elm,vbar,unpress", "elm",
3126 _elm_scroll_vbar_unpress_cb, sid);
3127 edje_object_signal_callback_del_full
3128 (sid->edje_obj, "drag", "elm.dragable.hbar", _elm_scroll_hbar_drag_cb,
3130 edje_object_signal_callback_del_full
3131 (sid->edje_obj, "drag,set", "elm.dragable.hbar",
3132 _elm_scroll_edje_drag_h_cb, sid);
3133 edje_object_signal_callback_del_full
3134 (sid->edje_obj, "drag,start", "elm.dragable.hbar",
3135 _elm_scroll_edje_drag_h_start_cb, sid);
3136 edje_object_signal_callback_del_full
3137 (sid->edje_obj, "drag,stop", "elm.dragable.hbar",
3138 _elm_scroll_edje_drag_h_stop_cb, sid);
3139 edje_object_signal_callback_del_full
3140 (sid->edje_obj, "drag,step", "elm.dragable.hbar",
3141 _elm_scroll_edje_drag_h_cb, sid);
3142 edje_object_signal_callback_del_full
3143 (sid->edje_obj, "drag,page", "elm.dragable.hbar",
3144 _elm_scroll_edje_drag_h_cb, sid);
3145 edje_object_signal_callback_del_full
3146 (sid->edje_obj, "elm,hbar,press", "elm",
3147 _elm_scroll_hbar_press_cb, sid);
3148 edje_object_signal_callback_del_full
3149 (sid->edje_obj, "elm,hbar,unpress", "elm",
3150 _elm_scroll_hbar_unpress_cb, sid);
3154 _scroll_event_object_detach(Evas_Object *obj)
3156 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3158 evas_object_event_callback_del_full
3159 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL, _elm_scroll_wheel_event_cb,
3161 evas_object_event_callback_del_full
3162 (sid->event_rect, EVAS_CALLBACK_MOUSE_DOWN,
3163 _elm_scroll_mouse_down_event_cb, sid);
3164 evas_object_event_callback_del_full
3165 (sid->event_rect, EVAS_CALLBACK_MOUSE_UP,
3166 _elm_scroll_mouse_up_event_cb, sid);
3167 evas_object_event_callback_del_full
3168 (sid->event_rect, EVAS_CALLBACK_MOUSE_MOVE,
3169 _elm_scroll_mouse_move_event_cb, sid);
3173 _elm_scroll_objects_set(Evas_Object *obj,
3174 Evas_Object *edje_object,
3175 Evas_Object *hit_rectangle)
3179 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3181 if (!edje_object || !hit_rectangle) return;
3184 _scroll_edje_object_detach(obj);
3186 sid->edje_obj = edje_object;
3188 if (sid->event_rect)
3189 _scroll_event_object_detach(obj);
3191 sid->event_rect = hit_rectangle;
3192 evas_object_repeat_events_set(hit_rectangle, EINA_TRUE);
3194 _scroll_edje_object_attach(obj);
3195 _scroll_event_object_attach(obj);
3198 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
3199 if (edje_object_part_exists(sid->edje_obj, "elm.scrollbar.base"))
3203 base = edje_object_part_swallow_get
3204 (sid->edje_obj, "elm.scrollbar.base");
3207 base = evas_object_rectangle_add
3208 (evas_object_evas_get(sid->edje_obj));
3209 evas_object_color_set(base, 0, 0, 0, 0);
3210 edje_object_part_swallow
3211 (sid->edje_obj, "elm.scrollbar.base", base);
3213 if (!_elm_config->thumbscroll_enable)
3214 evas_object_size_hint_min_set(base, mw, mh);
3217 _elm_scroll_scroll_bar_visibility_adjust(sid);
3221 _elm_scroll_scroll_bar_reset(Elm_Scrollable_Smart_Interface_Data *sid)
3223 Evas_Coord px = 0, py = 0, minx = 0, miny = 0;
3225 if (!sid->edje_obj) return;
3227 edje_object_part_drag_value_set
3228 (sid->edje_obj, "elm.dragable.vbar", 0.0, 0.0);
3229 edje_object_part_drag_value_set
3230 (sid->edje_obj, "elm.dragable.hbar", 0.0, 0.0);
3231 if ((!sid->content) && (!sid->extern_pan))
3233 edje_object_part_drag_size_set
3234 (sid->edje_obj, "elm.dragable.vbar", 1.0, 1.0);
3235 edje_object_part_drag_size_set
3236 (sid->edje_obj, "elm.dragable.hbar", 1.0, 1.0);
3240 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
3242 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
3243 psd->api->pos_get(sid->pan_obj, &px, &py);
3244 psd->api->pos_set(sid->pan_obj, minx, miny);
3246 if ((px != minx) || (py != miny))
3247 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
3248 _elm_direction_arrows_eval(sid);
3251 /* even external pan objects get this */
3253 _elm_scroll_pan_changed_cb(void *data,
3254 Evas_Object *obj __UNUSED__,
3255 void *event_info __UNUSED__)
3258 Elm_Scrollable_Smart_Interface_Data *sid = data;
3260 if (!sid->pan_obj) return;
3262 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
3264 psd->api->content_size_get(sid->pan_obj, &w, &h);
3265 if ((w != sid->content_info.w) || (h != sid->content_info.h))
3267 sid->content_info.w = w;
3268 sid->content_info.h = h;
3269 _elm_scroll_scroll_bar_size_adjust(sid);
3271 evas_object_size_hint_min_set
3272 (sid->edje_obj, sid->content_info.w, sid->content_info.h);
3273 sid->content_info.resized = EINA_TRUE;
3274 _elm_scroll_wanted_region_set(sid->obj);
3279 _elm_scroll_content_del_cb(void *data,
3281 Evas_Object *obj __UNUSED__,
3282 void *event_info __UNUSED__)
3284 Elm_Scrollable_Smart_Interface_Data *sid = data;
3286 sid->content = NULL;
3287 _elm_scroll_scroll_bar_size_adjust(sid);
3288 _elm_scroll_scroll_bar_reset(sid);
3292 _elm_scroll_content_set(Evas_Object *obj,
3293 Evas_Object *content)
3298 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3300 if (!sid->edje_obj) return;
3304 /* if we had content, for sure we had a pan object */
3305 _elm_pan_content_set(sid->pan_obj, NULL);
3306 evas_object_event_callback_del_full
3307 (sid->content, EVAS_CALLBACK_DEL, _elm_scroll_content_del_cb, sid);
3310 sid->content = content;
3311 sid->wx = sid->wy = 0;
3312 /* (-1) means want viewports size */
3313 sid->ww = sid->wh = -1;
3314 if (!content) return;
3318 o = _elm_pan_add(evas_object_evas_get(obj));
3320 evas_object_smart_callback_add
3321 (o, SIG_CHANGED, _elm_scroll_pan_changed_cb, sid);
3322 edje_object_part_swallow(sid->edje_obj, "elm.swallow.content", o);
3325 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
3327 evas_object_event_callback_add
3328 (content, EVAS_CALLBACK_DEL, _elm_scroll_content_del_cb, sid);
3330 _elm_pan_content_set(sid->pan_obj, content);
3331 psd->api->content_size_get(sid->pan_obj, &w, &h);
3332 sid->content_info.w = w;
3333 sid->content_info.h = h;
3335 _elm_scroll_scroll_bar_size_adjust(sid);
3336 _elm_scroll_scroll_bar_reset(sid);
3340 _elm_scroll_extern_pan_set(Evas_Object *obj,
3343 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3345 if (!sid->edje_obj) return;
3347 _elm_scroll_content_set(obj, NULL);
3351 evas_object_smart_callback_del
3352 (sid->pan_obj, SIG_CHANGED, _elm_scroll_pan_changed_cb);
3355 if (sid->extern_pan)
3359 /* not owned by scroller, just leave (was external already) */
3360 edje_object_part_unswallow(sid->edje_obj, sid->pan_obj);
3361 sid->pan_obj = NULL;
3368 evas_object_del(sid->pan_obj);
3369 sid->pan_obj = NULL;
3374 sid->extern_pan = EINA_FALSE;
3380 sid->extern_pan = EINA_TRUE;
3381 evas_object_smart_callback_add
3382 (sid->pan_obj, SIG_CHANGED, _elm_scroll_pan_changed_cb, sid);
3383 edje_object_part_swallow
3384 (sid->edje_obj, "elm.swallow.content", sid->pan_obj);
3388 _elm_scroll_drag_start_cb_set(Evas_Object *obj,
3389 void (*drag_start_cb)(Evas_Object *obj,
3392 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3394 sid->cb_func.drag_start = drag_start_cb;
3398 _elm_scroll_drag_stop_cb_set(Evas_Object *obj,
3399 void (*drag_stop_cb)(Evas_Object *obj,
3402 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3404 sid->cb_func.drag_stop = drag_stop_cb;
3408 _elm_scroll_animate_start_cb_set(Evas_Object *obj,
3409 void (*animate_start_cb)(Evas_Object *obj,
3412 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3414 sid->cb_func.animate_start = animate_start_cb;
3418 _elm_scroll_animate_stop_cb_set(Evas_Object *obj,
3419 void (*animate_stop_cb)(Evas_Object *obj,
3422 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3424 sid->cb_func.animate_stop = animate_stop_cb;
3428 _elm_scroll_scroll_cb_set(Evas_Object *obj,
3429 void (*scroll_cb)(Evas_Object *obj,
3432 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3434 sid->cb_func.scroll = scroll_cb;
3438 _elm_scroll_scroll_left_cb_set(Evas_Object *obj,
3439 void (*scroll_left_cb)(Evas_Object *obj,
3442 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3444 sid->cb_func.scroll_left = scroll_left_cb;
3448 _elm_scroll_scroll_right_cb_set(Evas_Object *obj,
3449 void (*scroll_right_cb)(Evas_Object *obj,
3452 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3454 sid->cb_func.scroll_right = scroll_right_cb;
3458 _elm_scroll_scroll_up_cb_set(Evas_Object *obj,
3459 void (*scroll_up_cb)(Evas_Object *obj,
3462 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3464 sid->cb_func.scroll_up = scroll_up_cb;
3468 _elm_scroll_scroll_down_cb_set(Evas_Object *obj,
3469 void (*scroll_down_cb)(Evas_Object *obj,
3472 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3474 sid->cb_func.scroll_down = scroll_down_cb;
3478 _elm_scroll_edge_left_cb_set(Evas_Object *obj,
3479 void (*edge_left_cb)(Evas_Object *obj,
3482 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3484 sid->cb_func.edge_left = edge_left_cb;
3488 _elm_scroll_edge_right_cb_set(Evas_Object *obj,
3489 void (*edge_right_cb)(Evas_Object *obj,
3492 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3494 sid->cb_func.edge_right = edge_right_cb;
3498 _elm_scroll_edge_top_cb_set(Evas_Object *obj,
3499 void (*edge_top_cb)(Evas_Object *obj,
3502 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3504 sid->cb_func.edge_top = edge_top_cb;
3508 _elm_scroll_edge_bottom_cb_set(Evas_Object *obj,
3509 void (*edge_bottom_cb)(Evas_Object *obj,
3512 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3514 sid->cb_func.edge_bottom = edge_bottom_cb;
3518 _elm_scroll_vbar_drag_cb_set(Evas_Object *obj,
3519 void (*vbar_drag_cb)(Evas_Object *obj,
3522 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3524 sid->cb_func.vbar_drag = vbar_drag_cb;
3528 _elm_scroll_vbar_press_cb_set(Evas_Object *obj,
3529 void (*vbar_press_cb)(Evas_Object *obj,
3532 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3534 sid->cb_func.vbar_press = vbar_press_cb;
3538 _elm_scroll_vbar_unpress_cb_set(Evas_Object *obj,
3539 void (*vbar_unpress_cb)(Evas_Object *obj,
3542 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3544 sid->cb_func.vbar_unpress = vbar_unpress_cb;
3548 _elm_scroll_hbar_drag_cb_set(Evas_Object *obj,
3549 void (*hbar_drag_cb)(Evas_Object *obj,
3552 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3554 sid->cb_func.hbar_drag = hbar_drag_cb;
3558 _elm_scroll_hbar_press_cb_set(Evas_Object *obj,
3559 void (*hbar_press_cb)(Evas_Object *obj,
3562 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3564 sid->cb_func.hbar_press = hbar_press_cb;
3568 _elm_scroll_hbar_unpress_cb_set(Evas_Object *obj,
3569 void (*hbar_unpress_cb)(Evas_Object *obj,
3572 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3574 sid->cb_func.hbar_unpress = hbar_unpress_cb;
3578 _elm_scroll_content_min_limit_cb_set(Evas_Object *obj,
3579 void (*c_min_limit_cb)(Evas_Object *obj,
3583 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3585 sid->cb_func.content_min_limit = c_min_limit_cb;
3589 _elm_scroll_momentum_animator_disabled_get(const Evas_Object *obj)
3591 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
3593 return sid->momentum_animator_disabled;
3597 _elm_scroll_momentum_animator_disabled_set(Evas_Object *obj,
3600 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3602 sid->momentum_animator_disabled = disabled;
3603 if (sid->momentum_animator_disabled)
3605 if (sid->down.momentum_animator)
3607 ecore_animator_del(sid->down.momentum_animator);
3608 sid->down.momentum_animator = NULL;
3609 if (sid->content_info.resized)
3610 _elm_scroll_wanted_region_set(sid->obj);
3616 _elm_scroll_bounce_animator_disabled_get(const Evas_Object *obj)
3618 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
3620 return sid->bounce_animator_disabled;
3624 _elm_scroll_bounce_animator_disabled_set(Evas_Object *obj,
3627 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3629 sid->bounce_animator_disabled = disabled;
3630 if (sid->bounce_animator_disabled)
3632 if (sid->scrollto.x.animator)
3634 ecore_animator_del(sid->scrollto.x.animator);
3635 sid->scrollto.x.animator = NULL;
3638 if (sid->scrollto.y.animator)
3640 ecore_animator_del(sid->scrollto.y.animator);
3641 sid->scrollto.y.animator = NULL;
3647 _elm_scroll_wheel_disabled_get(const Evas_Object *obj)
3649 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
3651 return sid->wheel_disabled;
3655 _elm_scroll_wheel_disabled_set(Evas_Object *obj,
3658 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3660 if (!sid->event_rect) return;
3662 if ((!sid->wheel_disabled) && (disabled))
3663 evas_object_event_callback_del_full
3664 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL,
3665 _elm_scroll_wheel_event_cb, sid);
3666 else if ((sid->wheel_disabled) && (!disabled))
3667 evas_object_event_callback_add
3668 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL,
3669 _elm_scroll_wheel_event_cb, sid);
3670 sid->wheel_disabled = disabled;
3674 _elm_scroll_step_size_set(Evas_Object *obj,
3678 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3685 _elm_scroll_scroll_bar_size_adjust(sid);
3689 _elm_scroll_step_size_get(const Evas_Object *obj,
3693 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3695 if (x) *x = sid->step.x;
3696 if (y) *y = sid->step.y;
3700 _elm_scroll_page_size_set(Evas_Object *obj,
3704 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3709 _elm_scroll_scroll_bar_size_adjust(sid);
3713 _elm_scroll_page_size_get(const Evas_Object *obj,
3717 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3719 if (x) *x = sid->page.x;
3720 if (y) *y = sid->page.y;
3724 _elm_scroll_policy_set(Evas_Object *obj,
3725 Elm_Scroller_Policy hbar,
3726 Elm_Scroller_Policy vbar)
3728 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3730 if (!sid->edje_obj) return;
3732 if ((sid->hbar_flags == hbar) && (sid->vbar_flags == vbar)) return;
3734 sid->hbar_flags = hbar;
3735 sid->vbar_flags = vbar;
3736 if (sid->hbar_flags == ELM_SCROLLER_POLICY_ON)
3737 edje_object_signal_emit
3738 (sid->edje_obj, "elm,action,show_always,hbar", "elm");
3739 else if (sid->hbar_flags == ELM_SCROLLER_POLICY_OFF)
3740 edje_object_signal_emit
3741 (sid->edje_obj, "elm,action,hide,hbar", "elm");
3743 edje_object_signal_emit
3744 (sid->edje_obj, "elm,action,show_notalways,hbar", "elm");
3745 if (sid->vbar_flags == ELM_SCROLLER_POLICY_ON)
3746 edje_object_signal_emit
3747 (sid->edje_obj, "elm,action,show_always,vbar", "elm");
3748 else if (sid->vbar_flags == ELM_SCROLLER_POLICY_OFF)
3749 edje_object_signal_emit
3750 (sid->edje_obj, "elm,action,hide,vbar", "elm");
3752 edje_object_signal_emit
3753 (sid->edje_obj, "elm,action,show_notalways,vbar", "elm");
3754 edje_object_message_signal_process(sid->edje_obj);
3755 _elm_scroll_scroll_bar_size_adjust(sid);
3756 if (sid->cb_func.content_min_limit)
3757 sid->cb_func.content_min_limit(sid->obj, sid->min_w, sid->min_h);
3758 _elm_direction_arrows_eval(sid);
3762 _elm_scroll_policy_get(const Evas_Object *obj,
3763 Elm_Scroller_Policy *hbar,
3764 Elm_Scroller_Policy *vbar)
3766 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3768 if (hbar) *hbar = sid->hbar_flags;
3769 if (vbar) *vbar = sid->vbar_flags;
3773 _elm_scroll_single_direction_set(Evas_Object *obj,
3774 Eina_Bool single_dir)
3776 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3778 sid->one_direction_at_a_time = single_dir;
3782 _elm_scroll_single_direction_get(const Evas_Object *obj)
3784 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
3786 return sid->one_direction_at_a_time;
3790 _elm_scroll_repeat_events_set(Evas_Object *obj,
3791 Eina_Bool repeat_events)
3793 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3795 evas_object_repeat_events_set(sid->event_rect, repeat_events);
3799 _elm_scroll_repeat_events_get(Evas_Object *obj)
3801 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
3803 return evas_object_repeat_events_get(sid->event_rect);
3807 _elm_scroll_hold_set(Evas_Object *obj,
3810 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3816 _elm_scroll_freeze_set(Evas_Object *obj,
3819 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3821 sid->freeze = freeze;
3824 if (sid->down.onhold_animator)
3826 ecore_animator_del(sid->down.onhold_animator);
3827 sid->down.onhold_animator = NULL;
3828 if (sid->content_info.resized)
3829 _elm_scroll_wanted_region_set(sid->obj);
3833 _elm_scroll_bounce_eval(sid);
3837 _elm_scroll_bounce_allow_set(Evas_Object *obj,
3841 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3843 sid->bounce_horiz = !!horiz;
3844 sid->bounce_vert = !!vert;
3848 _elm_scroll_bounce_allow_get(const Evas_Object *obj,
3852 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3854 if (horiz) *horiz = sid->bounce_horiz;
3855 if (vert) *vert = sid->bounce_vert;
3859 _elm_scroll_paging_set(Evas_Object *obj,
3862 Evas_Coord pagesize_h,
3863 Evas_Coord pagesize_v)
3865 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3867 sid->pagerel_h = pagerel_h;
3868 sid->pagerel_v = pagerel_v;
3869 sid->pagesize_h = pagesize_h;
3870 sid->pagesize_v = pagesize_v;
3872 _elm_scroll_page_adjust(sid);
3876 _elm_scroll_paging_get(const Evas_Object *obj,
3879 Evas_Coord *pagesize_h,
3880 Evas_Coord *pagesize_v)
3882 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3884 if (pagerel_h) *pagerel_h = sid->pagerel_h;
3885 if (pagerel_v) *pagerel_v = sid->pagerel_v;
3886 if (pagesize_h) *pagesize_h = sid->pagesize_h;
3887 if (pagesize_v) *pagesize_v = sid->pagesize_v;
3891 _elm_scroll_page_scroll_limit_set(const Evas_Object *obj,
3895 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3897 sid->page_limit_h = page_limit_h;
3898 sid->page_limit_v = page_limit_v;
3902 _elm_scroll_page_scroll_limit_get(const Evas_Object *obj,
3906 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3908 if (page_limit_h) *page_limit_h = sid->page_limit_h;
3909 if (page_limit_v) *page_limit_v = sid->page_limit_v;
3913 _elm_scroll_current_page_get(const Evas_Object *obj,
3919 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3921 _elm_scroll_content_pos_get(sid->obj, &x, &y);
3924 if (sid->pagesize_h > 0)
3925 *pagenumber_h = (x + sid->pagesize_h - 1) / sid->pagesize_h;
3931 if (sid->pagesize_v > 0)
3932 *pagenumber_v = (y + sid->pagesize_v - 1) / sid->pagesize_v;
3939 _elm_scroll_last_page_get(const Evas_Object *obj,
3945 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3947 if (!sid->pan_obj) return;
3949 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
3951 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
3954 if (sid->pagesize_h > 0)
3955 *pagenumber_h = cw / sid->pagesize_h + 1;
3961 if (sid->pagesize_v > 0)
3962 *pagenumber_v = ch / sid->pagesize_v + 1;
3969 _elm_scroll_page_show(Evas_Object *obj,
3977 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3979 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
3980 if (pagenumber_h >= 0) x = sid->pagesize_h * pagenumber_h;
3981 if (pagenumber_v >= 0) y = sid->pagesize_v * pagenumber_v;
3982 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
3983 _elm_scroll_content_pos_set(obj, x, y, EINA_TRUE);
3987 _elm_scroll_page_bring_in(Evas_Object *obj,
3995 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3997 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
3998 if (pagenumber_h >= 0) x = sid->pagesize_h * pagenumber_h;
3999 if (pagenumber_v >= 0) y = sid->pagesize_v * pagenumber_v;
4000 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
4002 _elm_scroll_scroll_to_x(sid, _elm_config->bring_in_scroll_friction, x);
4003 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, y);
4008 _elm_scroll_region_bring_in(Evas_Object *obj,
4014 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4016 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
4018 _elm_scroll_scroll_to_x(sid, _elm_config->bring_in_scroll_friction, x);
4019 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, y);
4024 _elm_scroll_gravity_set(Evas_Object *obj,
4028 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4030 if (!sid->pan_obj) return;
4032 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
4034 psd->api->gravity_set(sid->pan_obj, x, y);
4038 _elm_scroll_gravity_get(const Evas_Object *obj,
4042 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4044 if (!sid->pan_obj) return;
4046 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
4048 psd->api->gravity_get(sid->pan_obj, x, y);
4052 _elm_scroll_interface_add(Evas_Object *obj)
4054 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
4056 memset(sid, 0, sizeof(*sid));
4068 sid->page_limit_h = 9999;
4069 sid->page_limit_v = 9999;
4070 sid->hbar_flags = ELM_SCROLLER_POLICY_AUTO;
4071 sid->vbar_flags = ELM_SCROLLER_POLICY_AUTO;
4072 sid->hbar_visible = EINA_TRUE;
4073 sid->vbar_visible = EINA_TRUE;
4075 sid->bounce_horiz = EINA_TRUE;
4076 sid->bounce_vert = EINA_TRUE;
4078 sid->one_direction_at_a_time = EINA_TRUE;
4079 sid->momentum_animator_disabled = EINA_FALSE;
4080 sid->bounce_animator_disabled = EINA_FALSE;
4082 _elm_scroll_scroll_bar_reset(sid);
4088 _elm_scroll_interface_del(Evas_Object *obj)
4090 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4092 _elm_scroll_content_set(obj, NULL);
4093 if (!sid->extern_pan) evas_object_del(sid->pan_obj);
4095 if (sid->down.hold_animator)
4096 ecore_animator_del(sid->down.hold_animator);
4097 if (sid->down.onhold_animator)
4098 ecore_animator_del(sid->down.onhold_animator);
4099 if (sid->down.momentum_animator)
4100 ecore_animator_del(sid->down.momentum_animator);
4101 if (sid->down.bounce_x_animator)
4102 ecore_animator_del(sid->down.bounce_x_animator);
4103 if (sid->down.bounce_y_animator)
4104 ecore_animator_del(sid->down.bounce_y_animator);
4105 if (sid->scrollto.x.animator) ecore_animator_del(sid->scrollto.x.animator);
4106 if (sid->scrollto.y.animator) ecore_animator_del(sid->scrollto.y.animator);
4109 EAPI const char ELM_SCROLLABLE_IFACE_NAME[] = "elm_interface_scrollable";
4111 EAPI const Elm_Scrollable_Smart_Interface ELM_SCROLLABLE_IFACE =
4114 ELM_SCROLLABLE_IFACE_NAME,
4115 sizeof(Elm_Scrollable_Smart_Interface_Data),
4116 _elm_scroll_interface_add,
4117 _elm_scroll_interface_del
4120 _elm_scroll_objects_set,
4121 _elm_scroll_content_set,
4122 _elm_scroll_extern_pan_set,
4123 _elm_scroll_drag_start_cb_set,
4124 _elm_scroll_drag_stop_cb_set,
4125 _elm_scroll_animate_start_cb_set,
4126 _elm_scroll_animate_stop_cb_set,
4127 _elm_scroll_scroll_cb_set,
4128 _elm_scroll_scroll_left_cb_set,
4129 _elm_scroll_scroll_right_cb_set,
4130 _elm_scroll_scroll_up_cb_set,
4131 _elm_scroll_scroll_down_cb_set,
4132 _elm_scroll_edge_left_cb_set,
4133 _elm_scroll_edge_right_cb_set,
4134 _elm_scroll_edge_top_cb_set,
4135 _elm_scroll_edge_bottom_cb_set,
4136 _elm_scroll_vbar_drag_cb_set,
4137 _elm_scroll_vbar_press_cb_set,
4138 _elm_scroll_vbar_unpress_cb_set,
4139 _elm_scroll_hbar_drag_cb_set,
4140 _elm_scroll_hbar_press_cb_set,
4141 _elm_scroll_hbar_unpress_cb_set,
4142 _elm_scroll_content_min_limit_cb_set,
4143 _elm_scroll_content_pos_set,
4144 _elm_scroll_content_pos_get,
4145 _elm_scroll_content_region_show,
4146 _elm_scroll_content_region_set,
4147 _elm_scroll_content_size_get,
4148 _elm_scroll_content_viewport_size_get,
4149 _elm_scroll_content_min_limit,
4150 _elm_scroll_step_size_set,
4151 _elm_scroll_step_size_get,
4152 _elm_scroll_page_size_set,
4153 _elm_scroll_page_size_get,
4154 _elm_scroll_policy_set,
4155 _elm_scroll_policy_get,
4156 _elm_scroll_single_direction_set,
4157 _elm_scroll_single_direction_get,
4158 _elm_scroll_repeat_events_set,
4159 _elm_scroll_repeat_events_get,
4160 _elm_scroll_mirrored_set,
4161 _elm_scroll_hold_set,
4162 _elm_scroll_freeze_set,
4163 _elm_scroll_bounce_allow_set,
4164 _elm_scroll_bounce_allow_get,
4165 _elm_scroll_paging_set,
4166 _elm_scroll_paging_get,
4167 _elm_scroll_page_scroll_limit_set,
4168 _elm_scroll_page_scroll_limit_get,
4169 _elm_scroll_current_page_get,
4170 _elm_scroll_last_page_get,
4171 _elm_scroll_page_show,
4172 _elm_scroll_page_bring_in,
4173 _elm_scroll_region_bring_in,
4174 _elm_scroll_gravity_set,
4175 _elm_scroll_gravity_get,
4176 _elm_scroll_momentum_animator_disabled_get,
4177 _elm_scroll_momentum_animator_disabled_set,
4178 _elm_scroll_bounce_animator_disabled_set,
4179 _elm_scroll_bounce_animator_disabled_get,
4180 _elm_scroll_wheel_disabled_get,
4181 _elm_scroll_wheel_disabled_set