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 *);
36 static Eina_Bool _paging_is_enabled(Elm_Scrollable_Smart_Interface_Data *sid);
38 _elm_scroll_page_x_get(Elm_Scrollable_Smart_Interface_Data *sid, int offset);
40 _elm_scroll_page_y_get(Elm_Scrollable_Smart_Interface_Data *sid, int offset);
42 EAPI const Elm_Pan_Smart_Class *
43 elm_pan_smart_class_get(void)
45 static Elm_Pan_Smart_Class _sc =
46 ELM_PAN_SMART_CLASS_INIT_NAME_VERSION(PAN_SMART_NAME);
47 static const Elm_Pan_Smart_Class *class = NULL;
48 Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
53 _elm_pan_smart_set(&_sc);
54 esc->callbacks = _smart_callbacks;
61 _elm_pan_update(Elm_Pan_Smart_Data *psd)
63 if (!psd->gravity_x && !psd->gravity_y)
65 evas_object_move(psd->content, psd->x - psd->px, psd->y - psd->py);
69 if ((!psd->px) && (!psd->py))
71 psd->px = psd->delta_posx * psd->gravity_x;
72 psd->py = psd->delta_posy * psd->gravity_y;
74 psd->delta_posx += psd->content_w - psd->prev_cw;
75 psd->prev_cw = psd->content_w;
76 psd->delta_posy += psd->content_h - psd->prev_ch;
77 psd->prev_ch = psd->content_h;
79 evas_object_move(psd->content, psd->x - psd->px, psd->y - psd->py);
80 psd->px = psd->delta_posx * psd->gravity_x;
81 psd->py = psd->delta_posy * psd->gravity_y;
85 _elm_pan_smart_add(Evas_Object *obj)
87 const Evas_Smart_Class *sc;
88 const Evas_Smart *smart;
90 EVAS_SMART_DATA_ALLOC(obj, Elm_Pan_Smart_Data);
92 _elm_pan_parent_sc->add(obj);
100 priv->gravity_x = 0.0;
101 priv->gravity_y = 0.0;
103 smart = evas_object_smart_smart_get(obj);
104 sc = evas_smart_class_get(smart);
105 priv->api = (const Elm_Pan_Smart_Class *)sc;
109 _elm_pan_smart_del(Evas_Object *obj)
111 _elm_pan_content_set(obj, NULL);
113 _elm_pan_parent_sc->del(obj);
117 _elm_pan_smart_move(Evas_Object *obj,
121 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
123 /* we don't want the clipped smart object version here */
128 _elm_pan_update(psd);
132 _elm_pan_smart_resize(Evas_Object *obj,
136 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
141 _elm_pan_update(psd);
142 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
146 _elm_pan_smart_show(Evas_Object *obj)
148 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
150 _elm_pan_parent_sc->show(obj);
153 evas_object_show(psd->content);
157 _elm_pan_smart_hide(Evas_Object *obj)
159 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
161 _elm_pan_parent_sc->hide(obj);
164 evas_object_hide(psd->content);
168 _elm_pan_pos_set(Evas_Object *obj,
172 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
174 if ((x == psd->px) && (y == psd->py)) return;
178 _elm_pan_update(psd);
179 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
183 _elm_pan_pos_get(const Evas_Object *obj,
187 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
194 _elm_pan_pos_max_get(const Evas_Object *obj,
198 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
202 if (psd->w < psd->content_w) *x = psd->content_w - psd->w;
207 if (psd->h < psd->content_h) *y = psd->content_h - psd->h;
213 _elm_pan_pos_min_get(const Evas_Object *obj __UNUSED__,
224 _elm_pan_content_size_get(const Evas_Object *obj,
228 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
230 if (w) *w = psd->content_w;
231 if (h) *h = psd->content_h;
235 _elm_pan_gravity_set(Evas_Object *obj,
239 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
243 psd->prev_cw = psd->content_w;
244 psd->prev_ch = psd->content_h;
250 _elm_pan_gravity_get(const Evas_Object *obj,
254 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
256 if (x) *x = psd->gravity_x;
257 if (y) *y = psd->gravity_y;
261 _elm_pan_smart_set_user(Elm_Pan_Smart_Class *sc)
263 sc->base.add = _elm_pan_smart_add;
264 sc->base.del = _elm_pan_smart_del;
265 sc->base.move = _elm_pan_smart_move;
266 sc->base.resize = _elm_pan_smart_resize;
267 sc->base.show = _elm_pan_smart_show;
268 sc->base.hide = _elm_pan_smart_hide;
270 sc->pos_set = _elm_pan_pos_set;
271 sc->pos_get = _elm_pan_pos_get;
272 sc->pos_max_get = _elm_pan_pos_max_get;
273 sc->pos_min_get = _elm_pan_pos_min_get;
274 sc->content_size_get = _elm_pan_content_size_get;
275 sc->gravity_set = _elm_pan_gravity_set;
276 sc->gravity_get = _elm_pan_gravity_get;
280 _elm_pan_add(Evas *evas)
282 return evas_object_smart_add(evas, _elm_pan_smart_class_new());
286 _elm_pan_content_del_cb(void *data,
288 Evas_Object *obj __UNUSED__,
289 void *event_info __UNUSED__)
291 Elm_Pan_Smart_Data *psd;
295 psd->content_w = psd->content_h = psd->px = psd->py =
296 psd->prev_cw = psd->prev_ch = psd->delta_posx = psd->delta_posy = 0;
297 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
301 _elm_pan_content_resize_cb(void *data,
303 Evas_Object *obj __UNUSED__,
304 void *event_info __UNUSED__)
306 Elm_Pan_Smart_Data *psd;
310 evas_object_geometry_get(psd->content, NULL, NULL, &w, &h);
311 if ((w != psd->content_w) || (h != psd->content_h))
315 _elm_pan_update(psd);
317 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
321 _elm_pan_content_set(Evas_Object *obj,
322 Evas_Object *content)
326 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
328 if (content == psd->content) return;
331 evas_object_smart_member_del(psd->content);
332 evas_object_event_callback_del_full
333 (psd->content, EVAS_CALLBACK_DEL, _elm_pan_content_del_cb, psd);
334 evas_object_event_callback_del_full
335 (psd->content, EVAS_CALLBACK_RESIZE, _elm_pan_content_resize_cb,
339 if (!content) goto end;
341 psd->content = content;
342 evas_object_smart_member_add(psd->content, psd->self);
343 evas_object_geometry_get(psd->content, NULL, NULL, &w, &h);
346 evas_object_event_callback_add
347 (content, EVAS_CALLBACK_DEL, _elm_pan_content_del_cb, psd);
348 evas_object_event_callback_add
349 (content, EVAS_CALLBACK_RESIZE, _elm_pan_content_resize_cb, psd);
351 if (evas_object_visible_get(psd->self))
352 evas_object_show(psd->content);
354 evas_object_hide(psd->content);
356 _elm_pan_update(psd);
359 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
362 /* pan smart object on top, scroller interface on bottom */
363 /* ============================================================ */
365 static const char SCROLL_SMART_NAME[] = "elm_scroll";
367 #define ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(o, ptr) \
368 Elm_Scrollable_Smart_Interface_Data *ptr = \
369 evas_object_smart_interface_data_get(o, &(ELM_SCROLLABLE_IFACE.base)); \
372 CRITICAL("No interface data for object %p (%s)", \
373 o, evas_object_type_get(o)); \
377 #define ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
378 Elm_Scrollable_Smart_Interface_Data *ptr = \
379 evas_object_smart_interface_data_get(o, &(ELM_SCROLLABLE_IFACE.base)); \
382 CRITICAL("No interface data for object %p (%s)", \
383 o, evas_object_type_get(o)); \
387 static void _elm_scroll_scroll_bar_size_adjust(
388 Elm_Scrollable_Smart_Interface_Data *);
389 static void _elm_scroll_wanted_region_set(Evas_Object *);
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);
1611 y = _elm_scroll_page_y_get(sid, ny - py);
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,
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;
1911 dx = (sid->pagesize_h * ((double)sid->page_limit_h - 0.5));
1914 x += (abs(offset) < dx ? offset : dx);
1916 x += (abs(offset) < dx ? offset : -dx);
1918 if (sid->pagesize_h > 0)
1920 x = x + (sid->pagesize_h * 0.5);
1921 x = x / (sid->pagesize_h);
1922 x = x * (sid->pagesize_h);
1924 if ((x + w) > cw) x = cw - w;
1925 if (x < minx) x = minx;
1931 _elm_scroll_page_y_get(Elm_Scrollable_Smart_Interface_Data *sid,
1934 Evas_Coord x, y, w, h, dy, cw, ch, miny = 0;
1936 if (!sid->pan_obj) return 0;
1938 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, 0);
1940 _elm_scroll_content_pos_get(sid->obj, &x, &y);
1941 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
1942 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1943 psd->api->pos_min_get(sid->pan_obj, NULL, &miny);
1945 if (sid->pagerel_v > 0.0)
1946 sid->pagesize_v = h * sid->pagerel_v;
1948 dy = (sid->pagesize_v * ((double)sid->page_limit_v - 0.5));
1951 y += (abs(offset) < dy ? offset : dy);
1953 y += (abs(offset) < dy ? offset : -dy);
1955 if (sid->pagesize_v > 0)
1957 y = y + (sid->pagesize_v * 0.5);
1958 y = y / (sid->pagesize_v);
1959 y = y * (sid->pagesize_v);
1961 if ((y + h) > ch) y = ch - h;
1962 if (y < miny) y = miny;
1968 _elm_scroll_scroll_to_x_animator(void *data)
1970 Elm_Scrollable_Smart_Interface_Data *sid = data;
1974 if (!sid->pan_obj) return ECORE_CALLBACK_CANCEL;
1976 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, ECORE_CALLBACK_CANCEL);
1978 t = ecore_loop_time_get();
1979 tt = (t - sid->scrollto.x.t_start) /
1980 (sid->scrollto.x.t_end - sid->scrollto.x.t_start);
1982 tt = 1.0 - (tt * tt);
1983 psd->api->pos_get(sid->pan_obj, &px, &py);
1984 px = (sid->scrollto.x.start * (1.0 - tt)) +
1985 (sid->scrollto.x.end * tt);
1986 if (t >= sid->scrollto.x.t_end)
1988 px = sid->scrollto.x.end;
1989 _elm_scroll_content_pos_set(sid->obj, px, py, EINA_TRUE);
1991 sid->down.x = sid->down.history[0].x;
1992 _elm_scroll_wanted_coordinates_update(sid, px, py);
1993 sid->scrollto.x.animator = NULL;
1994 if ((!sid->scrollto.y.animator) && (!sid->down.bounce_y_animator))
1995 _elm_scroll_anim_stop(sid);
1996 return ECORE_CALLBACK_CANCEL;
1998 _elm_scroll_content_pos_set(sid->obj, px, py, EINA_TRUE);
1999 _elm_scroll_wanted_coordinates_update(sid, px, py);
2000 return ECORE_CALLBACK_RENEW;
2004 _elm_scroll_scroll_to_y_animator(void *data)
2006 Elm_Scrollable_Smart_Interface_Data *sid = data;
2010 if (!sid->pan_obj) return EINA_FALSE;
2012 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, EINA_FALSE);
2014 t = ecore_loop_time_get();
2015 tt = (t - sid->scrollto.y.t_start) /
2016 (sid->scrollto.y.t_end - sid->scrollto.y.t_start);
2018 tt = 1.0 - (tt * tt);
2019 psd->api->pos_get(sid->pan_obj, &px, &py);
2020 py = (sid->scrollto.y.start * (1.0 - tt)) +
2021 (sid->scrollto.y.end * tt);
2022 if (t >= sid->scrollto.y.t_end)
2024 py = sid->scrollto.y.end;
2025 _elm_scroll_content_pos_set(sid->obj, px, py, EINA_TRUE);
2027 sid->down.y = sid->down.history[0].y;
2028 _elm_scroll_wanted_coordinates_update(sid, px, py);
2029 sid->scrollto.y.animator = NULL;
2030 if ((!sid->scrollto.x.animator) && (!sid->down.bounce_x_animator))
2031 _elm_scroll_anim_stop(sid);
2032 return ECORE_CALLBACK_CANCEL;
2034 _elm_scroll_content_pos_set(sid->obj, px, py, EINA_TRUE);
2035 _elm_scroll_wanted_coordinates_update(sid, px, py);
2037 return ECORE_CALLBACK_RENEW;
2041 _elm_scroll_scroll_to_y(Elm_Scrollable_Smart_Interface_Data *sid,
2045 Evas_Coord px, py, x, y, w, h;
2048 if (!sid->pan_obj) return;
2050 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2052 if (sid->freeze) return;
2055 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2056 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
2058 _elm_scroll_content_region_set(sid->obj, x, y, w, h);
2061 t = ecore_loop_time_get();
2062 psd->api->pos_get(sid->pan_obj, &px, &py);
2063 sid->scrollto.y.start = py;
2064 sid->scrollto.y.end = pos_y;
2065 sid->scrollto.y.t_start = t;
2066 sid->scrollto.y.t_end = t + t_in;
2067 if (!sid->scrollto.y.animator)
2069 sid->scrollto.y.animator =
2070 ecore_animator_add(_elm_scroll_scroll_to_y_animator, sid);
2071 if (!sid->scrollto.x.animator)
2072 _elm_scroll_anim_start(sid);
2074 if (sid->down.bounce_y_animator)
2076 ecore_animator_del(sid->down.bounce_y_animator);
2077 sid->down.bounce_y_animator = NULL;
2078 _elm_scroll_momentum_end(sid);
2079 if (sid->content_info.resized)
2080 _elm_scroll_wanted_region_set(sid->obj);
2082 sid->bouncemey = EINA_FALSE;
2086 _elm_scroll_scroll_to_x(Elm_Scrollable_Smart_Interface_Data *sid,
2090 Evas_Coord px, py, x, y, w, h;
2093 if (!sid->pan_obj) return;
2095 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2097 if (sid->freeze) return;
2100 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2101 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
2103 _elm_scroll_content_region_set(sid->obj, x, y, w, h);
2106 t = ecore_loop_time_get();
2107 psd->api->pos_get(sid->pan_obj, &px, &py);
2108 sid->scrollto.x.start = px;
2109 sid->scrollto.x.end = pos_x;
2110 sid->scrollto.x.t_start = t;
2111 sid->scrollto.x.t_end = t + t_in;
2112 if (!sid->scrollto.x.animator)
2114 sid->scrollto.x.animator =
2115 ecore_animator_add(_elm_scroll_scroll_to_x_animator, sid);
2116 if (!sid->scrollto.y.animator)
2117 _elm_scroll_anim_start(sid);
2119 if (sid->down.bounce_x_animator)
2121 ecore_animator_del(sid->down.bounce_x_animator);
2122 sid->down.bounce_x_animator = NULL;
2123 _elm_scroll_momentum_end(sid);
2124 if (sid->content_info.resized)
2125 _elm_scroll_wanted_region_set(sid->obj);
2127 sid->bouncemex = EINA_FALSE;
2131 _elm_scroll_mouse_up_event_cb(void *data,
2133 Evas_Object *obj __UNUSED__,
2136 Elm_Scrollable_Smart_Interface_Data *sid = data;
2137 Evas_Coord x = 0, y = 0, ox = 0, oy = 0;
2138 Evas_Event_Mouse_Down *ev;
2140 if (!sid->pan_obj) return;
2142 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2145 sid->down.hold_parent = EINA_FALSE;
2148 evas_post_event_callback_push(e, _elm_scroll_post_event_up, sid);
2150 // FIXME: respect elm_widget_scroll_hold_get of parent container
2151 if (!_elm_config->thumbscroll_enable) return;
2153 if (ev->button == 1)
2155 if (sid->down.onhold_animator)
2157 ecore_animator_del(sid->down.onhold_animator);
2158 sid->down.onhold_animator = NULL;
2159 if (sid->content_info.resized)
2160 _elm_scroll_wanted_region_set(sid->obj);
2162 x = ev->canvas.x - sid->down.x;
2163 y = ev->canvas.y - sid->down.y;
2164 if (sid->down.dragged)
2166 _elm_scroll_drag_stop(sid);
2167 if ((!sid->hold) && (!sid->freeze))
2171 Evas_Coord ax, ay, dx, dy, vel;
2174 t = ev->timestamp / 1000.0;
2176 t = ecore_loop_time_get();
2179 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2184 DBG("------ %i %i\n", ev->canvas.x, ev->canvas.y);
2186 for (i = 0; i < 60; i++)
2188 dt = t - sid->down.history[i].timestamp;
2189 if (dt > 0.2) break;
2191 DBG("H: %i %i @ %1.3f\n",
2192 sid->down.history[i].x,
2193 sid->down.history[i].y, dt);
2196 ax += sid->down.history[i].x;
2197 ay += sid->down.history[i].y;
2202 at /= _elm_config->thumbscroll_sensitivity_friction;
2203 dx = ev->canvas.x - ax;
2204 dy = ev->canvas.y - ay;
2207 vel = sqrt((dx * dx) + (dy * dy)) / at;
2208 if ((_elm_config->thumbscroll_friction > 0.0) &&
2209 (vel > _elm_config->thumbscroll_momentum_threshold))
2211 sid->down.dx = ((double)dx / at);
2212 sid->down.dy = ((double)dy / at);
2213 sid->down.extra_time = 0.0;
2214 sid->down.pdx = sid->down.dx;
2215 sid->down.pdy = sid->down.dy;
2218 if (!_paging_is_enabled(sid))
2220 if ((!sid->down.momentum_animator) &&
2221 (!sid->momentum_animator_disabled) &&
2223 (!elm_widget_drag_child_locked_y_get
2226 sid->down.momentum_animator =
2228 (_elm_scroll_momentum_animator, sid);
2230 EVAS_EVENT_FLAG_ON_SCROLL;
2231 _elm_scroll_anim_start(sid);
2233 sid->down.anim_start = ecore_loop_time_get();
2234 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2248 evas_event_feed_hold(e, 0, ev->timestamp, ev->data);
2249 if (_paging_is_enabled(sid))
2251 Evas_Coord pgx, pgy;
2253 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2255 (!elm_widget_drag_child_locked_x_get
2258 pgx = _elm_scroll_page_x_get(sid, ox);
2261 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2262 _elm_scroll_scroll_to_x
2263 (sid, _elm_config->page_scroll_friction, pgx);
2267 (!elm_widget_drag_child_locked_y_get
2270 pgy = _elm_scroll_page_y_get(sid, oy);
2273 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2274 _elm_scroll_scroll_to_y
2275 (sid, _elm_config->page_scroll_friction, pgy);
2284 if (_paging_is_enabled(sid))
2286 Evas_Coord pgx, pgy;
2288 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2290 (!elm_widget_drag_child_locked_x_get
2293 pgx = _elm_scroll_page_x_get(sid, ox);
2295 _elm_scroll_scroll_to_x
2296 (sid, _elm_config->page_scroll_friction, pgx);
2299 (!elm_widget_drag_child_locked_y_get
2302 pgy = _elm_scroll_page_y_get(sid, oy);
2304 _elm_scroll_scroll_to_y
2305 (sid, _elm_config->page_scroll_friction, pgy);
2309 if (sid->down.hold_animator)
2311 ecore_animator_del(sid->down.hold_animator);
2312 sid->down.hold_animator = NULL;
2313 if (sid->content_info.resized)
2314 _elm_scroll_wanted_region_set(sid->obj);
2316 if (sid->down.scroll)
2318 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2319 sid->down.scroll = EINA_FALSE;
2323 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2324 sid->down.hold = EINA_FALSE;
2326 sid->down.dragged_began = EINA_FALSE;
2327 sid->down.dir_x = EINA_FALSE;
2328 sid->down.dir_y = EINA_FALSE;
2329 sid->down.want_dragged = EINA_FALSE;
2330 sid->down.dragged = EINA_FALSE;
2331 sid->down.now = EINA_FALSE;
2332 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2333 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
2334 _elm_scroll_wanted_coordinates_update(sid, x, y);
2336 if (sid->content_info.resized)
2337 _elm_scroll_wanted_region_set(sid->obj);
2339 if (!_paging_is_enabled(sid))
2340 _elm_scroll_bounce_eval(sid);
2345 _elm_scroll_mouse_down_event_cb(void *data,
2347 Evas_Object *obj __UNUSED__,
2350 Elm_Scrollable_Smart_Interface_Data *sid;
2351 Evas_Event_Mouse_Down *ev;
2352 Evas_Coord x = 0, y = 0;
2357 if (_elm_config->thumbscroll_enable)
2359 sid->down.hold = EINA_FALSE;
2360 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
2361 (sid->down.momentum_animator) || (sid->scrollto.x.animator) ||
2362 (sid->scrollto.y.animator))
2364 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL |
2365 EVAS_EVENT_FLAG_ON_HOLD;
2366 sid->down.scroll = EINA_TRUE;
2367 sid->down.hold = EINA_TRUE;
2368 _elm_scroll_anim_stop(sid);
2370 if (sid->scrollto.x.animator)
2372 ecore_animator_del(sid->scrollto.x.animator);
2373 sid->scrollto.x.animator = NULL;
2375 if (sid->scrollto.y.animator)
2377 ecore_animator_del(sid->scrollto.y.animator);
2378 sid->scrollto.y.animator = NULL;
2380 if (sid->down.bounce_x_animator)
2382 ecore_animator_del(sid->down.bounce_x_animator);
2383 sid->down.bounce_x_animator = NULL;
2384 sid->bouncemex = EINA_FALSE;
2385 if (sid->content_info.resized)
2386 _elm_scroll_wanted_region_set(sid->obj);
2388 if (sid->down.bounce_y_animator)
2390 ecore_animator_del(sid->down.bounce_y_animator);
2391 sid->down.bounce_y_animator = NULL;
2392 sid->bouncemey = EINA_FALSE;
2393 if (sid->content_info.resized)
2394 _elm_scroll_wanted_region_set(sid->obj);
2396 if (sid->down.hold_animator)
2398 ecore_animator_del(sid->down.hold_animator);
2399 sid->down.hold_animator = NULL;
2400 _elm_scroll_drag_stop(sid);
2401 if (sid->content_info.resized)
2402 _elm_scroll_wanted_region_set(sid->obj);
2404 if (sid->down.momentum_animator)
2406 ecore_animator_del(sid->down.momentum_animator);
2407 sid->down.momentum_animator = NULL;
2408 sid->down.bounce_x_hold = EINA_FALSE;
2409 sid->down.bounce_y_hold = EINA_FALSE;
2412 if (sid->content_info.resized)
2413 _elm_scroll_wanted_region_set(sid->obj);
2415 if (ev->button == 1)
2417 sid->down.hist.est_timestamp_diff =
2418 ecore_loop_time_get() - ((double)ev->timestamp / 1000.0);
2419 sid->down.hist.tadd = 0.0;
2420 sid->down.hist.dxsum = 0.0;
2421 sid->down.hist.dysum = 0.0;
2422 sid->down.now = EINA_TRUE;
2423 sid->down.dragged = EINA_FALSE;
2424 sid->down.dir_x = EINA_FALSE;
2425 sid->down.dir_y = EINA_FALSE;
2426 sid->down.x = ev->canvas.x;
2427 sid->down.y = ev->canvas.y;
2428 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2431 sid->down.locked = EINA_FALSE;
2432 memset(&(sid->down.history[0]), 0,
2433 sizeof(sid->down.history[0]) * 60);
2435 sid->down.history[0].timestamp = ev->timestamp / 1000.0;
2436 sid->down.history[0].localtimestamp = ecore_loop_time_get();
2438 sid->down.history[0].timestamp = ecore_loop_time_get();
2440 sid->down.history[0].x = ev->canvas.x;
2441 sid->down.history[0].y = ev->canvas.y;
2443 sid->down.dragged_began = EINA_FALSE;
2444 sid->down.hold_parent = EINA_FALSE;
2445 sid->down.cancelled = EINA_FALSE;
2446 if (sid->hold || sid->freeze)
2447 sid->down.want_reset = EINA_TRUE;
2449 sid->down.want_reset = EINA_FALSE;
2454 _elm_scroll_can_scroll(Elm_Scrollable_Smart_Interface_Data *sid,
2457 Evas_Coord mx = 0, my = 0, px = 0, py = 0, minx = 0, miny = 0;
2459 if (!sid->pan_obj) return EINA_FALSE;
2461 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, EINA_FALSE);
2463 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
2464 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
2465 psd->api->pos_get(sid->pan_obj, &px, &py);
2469 if (px > minx) return EINA_TRUE;
2473 if ((px - minx) < mx) return EINA_TRUE;
2477 if (py > miny) return EINA_TRUE;
2481 if ((py - miny) < my) return EINA_TRUE;
2491 _elm_scroll_post_event_move(void *data,
2494 Elm_Scrollable_Smart_Interface_Data *sid = data;
2496 if (sid->down.want_dragged)
2500 if (sid->down.hold_parent)
2502 if ((sid->down.dir_x) &&
2503 !_elm_scroll_can_scroll(sid, sid->down.hdir))
2505 sid->down.dir_x = EINA_FALSE;
2507 if ((sid->down.dir_y) &&
2508 !_elm_scroll_can_scroll(sid, sid->down.vdir))
2510 sid->down.dir_y = EINA_FALSE;
2513 if (sid->down.dir_x)
2516 (!elm_widget_drag_child_locked_x_get(sid->obj)))
2518 sid->down.want_dragged = EINA_FALSE;
2519 sid->down.dragged = EINA_TRUE;
2522 elm_widget_drag_lock_x_set(sid->obj, 1);
2527 sid->down.dir_x = EINA_FALSE;
2529 if (sid->down.dir_y)
2532 (!elm_widget_drag_child_locked_y_get(sid->obj)))
2534 sid->down.want_dragged = EINA_FALSE;
2535 sid->down.dragged = EINA_TRUE;
2538 elm_widget_drag_lock_y_set
2539 (sid->obj, EINA_TRUE);
2544 sid->down.dir_y = EINA_FALSE;
2546 if ((!sid->down.dir_x) && (!sid->down.dir_y))
2548 sid->down.cancelled = EINA_TRUE;
2550 if (start) _elm_scroll_drag_start(sid);
2557 _elm_scroll_down_coord_eval(Elm_Scrollable_Smart_Interface_Data *sid,
2561 Evas_Coord minx, miny;
2563 if (!sid->pan_obj) return;
2565 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2567 if (sid->down.dir_x) *x = sid->down.sx - (*x - sid->down.x);
2568 else *x = sid->down.sx;
2569 if (sid->down.dir_y) *y = sid->down.sy - (*y - sid->down.y);
2570 else *y = sid->down.sy;
2572 if ((sid->down.dir_x) || (sid->down.dir_y))
2574 if (!((sid->down.dir_x) && (sid->down.dir_y)))
2576 if (sid->down.dir_x) *y = sid->down.locked_y;
2577 else *x = sid->down.locked_x;
2581 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
2584 *x += (minx - *x) * _elm_config->thumbscroll_border_friction;
2585 else if (sid->content_info.w <= sid->w)
2586 *x += (sid->down.sx - *x) * _elm_config->thumbscroll_border_friction;
2587 else if ((sid->content_info.w - sid->w + minx) < *x)
2588 *x += (sid->content_info.w - sid->w + minx - *x) *
2589 _elm_config->thumbscroll_border_friction;
2592 *y += (miny - *y) * _elm_config->thumbscroll_border_friction;
2593 else if (sid->content_info.h <= sid->h)
2594 *y += (sid->down.sy - *y) * _elm_config->thumbscroll_border_friction;
2595 else if ((sid->content_info.h - sid->h + miny) < *y)
2596 *y += (sid->content_info.h - sid->h + miny - *y) *
2597 _elm_config->thumbscroll_border_friction;
2601 _elm_scroll_hold_animator(void *data)
2603 Elm_Scrollable_Smart_Interface_Data *sid = data;
2604 Evas_Coord ox = 0, oy = 0, fx = 0, fy = 0;
2606 fx = sid->down.hold_x;
2607 fy = sid->down.hold_y;
2609 _elm_scroll_content_pos_get(sid->obj, &ox, &oy);
2610 if (sid->down.dir_x)
2613 (!elm_widget_drag_child_locked_x_get(sid->obj)))
2616 if (sid->down.dir_y)
2619 (!elm_widget_drag_child_locked_y_get(sid->obj)))
2623 _elm_scroll_content_pos_set(sid->obj, ox, oy, EINA_TRUE);
2625 return ECORE_CALLBACK_RENEW;
2629 _elm_scroll_on_hold_animator(void *data)
2633 Evas_Coord x, y, ox, oy;
2634 Elm_Scrollable_Smart_Interface_Data *sid;
2637 t = ecore_loop_time_get();
2638 if (sid->down.onhold_tlast > 0.0)
2640 td = t - sid->down.onhold_tlast;
2641 vx = sid->down.onhold_vx * td *
2642 (double)_elm_config->thumbscroll_hold_threshold * 2.0;
2643 vy = sid->down.onhold_vy * td *
2644 (double)_elm_config->thumbscroll_hold_threshold * 2.0;
2645 _elm_scroll_content_pos_get(sid->obj, &ox, &oy);
2649 if (sid->down.dir_x)
2652 (!elm_widget_drag_child_locked_x_get(sid->obj)))
2654 sid->down.onhold_vxe += vx;
2655 x = ox + (int)sid->down.onhold_vxe;
2656 sid->down.onhold_vxe -= (int)sid->down.onhold_vxe;
2660 if (sid->down.dir_y)
2663 (!elm_widget_drag_child_locked_y_get(sid->obj)))
2665 sid->down.onhold_vye += vy;
2666 y = oy + (int)sid->down.onhold_vye;
2667 sid->down.onhold_vye -= (int)sid->down.onhold_vye;
2671 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
2673 sid->down.onhold_tlast = t;
2675 return ECORE_CALLBACK_RENEW;
2679 _elm_scroll_mouse_move_event_cb(void *data,
2681 Evas_Object *obj __UNUSED__,
2684 Elm_Scrollable_Smart_Interface_Data *sid = data;
2685 Evas_Event_Mouse_Move *ev;
2686 Evas_Coord x = 0, y = 0;
2688 if (!sid->pan_obj) return;
2690 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2693 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
2694 sid->down.hold_parent = EINA_TRUE;
2695 evas_post_event_callback_push(e, _elm_scroll_post_event_move, sid);
2697 // FIXME: respect elm_widget_scroll_hold_get of parent container
2698 if (_elm_config->thumbscroll_enable)
2704 if ((sid->scrollto.x.animator) && (!sid->hold) && (!sid->freeze))
2707 ecore_animator_del(sid->scrollto.x.animator);
2708 sid->scrollto.x.animator = NULL;
2709 psd->api->pos_get(sid->pan_obj, &px, NULL);
2711 sid->down.x = sid->down.history[0].x;
2714 if ((sid->scrollto.y.animator) && (!sid->hold) && (!sid->freeze))
2717 ecore_animator_del(sid->scrollto.y.animator);
2718 sid->scrollto.y.animator = NULL;
2719 psd->api->pos_get(sid->pan_obj, NULL, &py);
2721 sid->down.y = sid->down.history[0].y;
2725 DBG("::: %i %i\n", ev->cur.canvas.x, ev->cur.canvas.y);
2727 memmove(&(sid->down.history[1]), &(sid->down.history[0]),
2728 sizeof(sid->down.history[0]) * (60 - 1));
2730 sid->down.history[0].timestamp = ev->timestamp / 1000.0;
2731 sid->down.history[0].localtimestamp = ecore_loop_time_get();
2733 sid->down.history[0].timestamp = ecore_loop_time_get();
2735 sid->down.history[0].x = ev->cur.canvas.x;
2736 sid->down.history[0].y = ev->cur.canvas.y;
2738 if (!sid->down.dragged_began)
2740 x = ev->cur.canvas.x - sid->down.x;
2741 y = ev->cur.canvas.y - sid->down.y;
2743 sid->down.hdir = -1;
2744 sid->down.vdir = -1;
2746 if (x > 0) sid->down.hdir = LEFT;
2748 sid->down.hdir = RIGHT;
2749 if (y > 0) sid->down.vdir = UP;
2751 sid->down.vdir = DOWN;
2756 if ((sid->one_direction_at_a_time) &&
2757 (!((sid->down.dir_x) || (sid->down.dir_y))))
2759 if (x > _elm_config->thumbscroll_threshold)
2763 sid->down.dir_x = EINA_TRUE;
2764 sid->down.dir_y = EINA_FALSE;
2768 if (y > _elm_config->thumbscroll_threshold)
2772 sid->down.dir_x = EINA_FALSE;
2773 sid->down.dir_y = EINA_TRUE;
2779 sid->down.dir_x = EINA_TRUE;
2780 sid->down.dir_y = EINA_TRUE;
2785 sid->down.dir_x = EINA_TRUE;
2786 sid->down.dir_y = EINA_TRUE;
2789 if ((!sid->hold) && (!sid->freeze))
2791 if ((sid->down.dragged) ||
2792 (((x * x) + (y * y)) >
2793 (_elm_config->thumbscroll_threshold *
2794 _elm_config->thumbscroll_threshold)))
2796 sid->down.dragged_began = EINA_TRUE;
2797 if (!sid->down.dragged)
2799 sid->down.want_dragged = EINA_TRUE;
2800 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2802 if (sid->down.dragged)
2804 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2806 if (sid->down.dir_x)
2807 x = sid->down.sx - (ev->cur.canvas.x - sid->down.x);
2810 if (sid->down.dir_y)
2811 y = sid->down.sy - (ev->cur.canvas.y - sid->down.y);
2814 if (sid->down.want_reset)
2816 sid->down.x = ev->cur.canvas.x;
2817 sid->down.y = ev->cur.canvas.y;
2818 sid->down.want_reset = EINA_FALSE;
2820 if ((sid->down.dir_x) || (sid->down.dir_y))
2822 if (!sid->down.locked)
2824 sid->down.locked_x = x;
2825 sid->down.locked_y = y;
2826 sid->down.locked = EINA_TRUE;
2828 if (!((sid->down.dir_x) && (sid->down.dir_y)))
2830 if (sid->down.dir_x) y = sid->down.locked_y;
2831 else x = sid->down.locked_x;
2835 Evas_Coord minx, miny, mx, my;
2837 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
2838 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
2841 _elm_config->thumbscroll_border_friction;
2843 y += (sid->down.sy - y) *
2844 _elm_config->thumbscroll_border_friction;
2845 else if ((my + miny) < y)
2846 y += (my + miny - y) *
2847 _elm_config->thumbscroll_border_friction;
2850 _elm_config->thumbscroll_border_friction;
2852 x += (sid->down.sx - x) *
2853 _elm_config->thumbscroll_border_friction;
2854 else if ((mx + minx) < x)
2855 x += (mx + minx - x) *
2856 _elm_config->thumbscroll_border_friction;
2859 sid->down.hold_x = x;
2860 sid->down.hold_y = y;
2861 if (!sid->down.hold_animator)
2862 sid->down.hold_animator =
2863 ecore_animator_add(_elm_scroll_hold_animator, sid);
2867 if (sid->down.dragged_began)
2869 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2870 if (!sid->down.hold)
2872 sid->down.hold = EINA_TRUE;
2873 evas_event_feed_hold
2874 (e, 1, ev->timestamp, ev->data);
2879 else if (!sid->freeze)
2881 double vx = 0.0, vy = 0.0;
2883 x = ev->cur.canvas.x - sid->x;
2884 y = ev->cur.canvas.y - sid->y;
2885 if (x < _elm_config->thumbscroll_hold_threshold)
2887 if (_elm_config->thumbscroll_hold_threshold > 0.0)
2888 vx = -(double)(_elm_config->thumbscroll_hold_threshold - x)
2889 / _elm_config->thumbscroll_hold_threshold;
2893 else if (x > (sid->w - _elm_config->thumbscroll_hold_threshold))
2895 if (_elm_config->thumbscroll_hold_threshold > 0.0)
2896 vx = (double)(_elm_config->thumbscroll_hold_threshold -
2898 _elm_config->thumbscroll_hold_threshold;
2902 if (y < _elm_config->thumbscroll_hold_threshold)
2904 if (_elm_config->thumbscroll_hold_threshold > 0.0)
2905 vy = -(double)(_elm_config->thumbscroll_hold_threshold - y)
2906 / _elm_config->thumbscroll_hold_threshold;
2910 else if (y > (sid->h - _elm_config->thumbscroll_hold_threshold))
2912 if (_elm_config->thumbscroll_hold_threshold > 0.0)
2913 vy = (double)(_elm_config->thumbscroll_hold_threshold -
2915 _elm_config->thumbscroll_hold_threshold;
2919 if ((vx != 0.0) || (vy != 0.0))
2921 sid->down.onhold_vx = vx;
2922 sid->down.onhold_vy = vy;
2923 if (!sid->down.onhold_animator)
2925 sid->down.onhold_vxe = 0.0;
2926 sid->down.onhold_vye = 0.0;
2927 sid->down.onhold_tlast = 0.0;
2928 sid->down.onhold_animator = ecore_animator_add
2929 (_elm_scroll_on_hold_animator, sid);
2934 if (sid->down.onhold_animator)
2936 ecore_animator_del(sid->down.onhold_animator);
2937 sid->down.onhold_animator = NULL;
2938 if (sid->content_info.resized)
2939 _elm_scroll_wanted_region_set(sid->obj);
2948 _elm_scroll_page_adjust(Elm_Scrollable_Smart_Interface_Data *sid)
2950 Evas_Coord x, y, w, h;
2952 if (!_paging_is_enabled(sid)) return;
2954 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
2956 x = _elm_scroll_page_x_get(sid, 0);
2957 y = _elm_scroll_page_y_get(sid, 0);
2959 _elm_scroll_content_region_set(sid->obj, x, y, w, h);
2963 _elm_scroll_reconfigure(Elm_Scrollable_Smart_Interface_Data *sid)
2965 _elm_scroll_scroll_bar_size_adjust(sid);
2966 _elm_scroll_page_adjust(sid);
2970 _on_edje_move(void *data,
2972 Evas_Object *edje_obj,
2973 void *event_info __UNUSED__)
2975 Elm_Scrollable_Smart_Interface_Data *sid = data;
2978 evas_object_geometry_get(edje_obj, &x, &y, NULL, NULL);
2983 _elm_scroll_reconfigure(sid);
2987 _on_edje_resize(void *data,
2989 Evas_Object *edje_obj,
2990 void *event_info __UNUSED__)
2992 Elm_Scrollable_Smart_Interface_Data *sid = data;
2995 evas_object_geometry_get(edje_obj, NULL, NULL, &w, &h);
3000 _elm_scroll_reconfigure(sid);
3001 _elm_scroll_wanted_region_set(sid->obj);
3005 _scroll_edje_object_attach(Evas_Object *obj)
3007 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3009 evas_object_event_callback_add
3010 (sid->edje_obj, EVAS_CALLBACK_RESIZE, _on_edje_resize, sid);
3011 evas_object_event_callback_add
3012 (sid->edje_obj, EVAS_CALLBACK_MOVE, _on_edje_move, sid);
3014 edje_object_signal_callback_add
3015 (sid->edje_obj, "drag", "elm.dragable.vbar", _elm_scroll_vbar_drag_cb,
3017 edje_object_signal_callback_add
3018 (sid->edje_obj, "drag,set", "elm.dragable.vbar",
3019 _elm_scroll_edje_drag_v_cb, sid);
3020 edje_object_signal_callback_add
3021 (sid->edje_obj, "drag,start", "elm.dragable.vbar",
3022 _elm_scroll_edje_drag_v_start_cb, sid);
3023 edje_object_signal_callback_add
3024 (sid->edje_obj, "drag,stop", "elm.dragable.vbar",
3025 _elm_scroll_edje_drag_v_stop_cb, sid);
3026 edje_object_signal_callback_add
3027 (sid->edje_obj, "drag,step", "elm.dragable.vbar",
3028 _elm_scroll_edje_drag_v_cb, sid);
3029 edje_object_signal_callback_add
3030 (sid->edje_obj, "drag,page", "elm.dragable.vbar",
3031 _elm_scroll_edje_drag_v_cb, sid);
3032 edje_object_signal_callback_add
3033 (sid->edje_obj, "elm,vbar,press", "elm",
3034 _elm_scroll_vbar_press_cb, sid);
3035 edje_object_signal_callback_add
3036 (sid->edje_obj, "elm,vbar,unpress", "elm",
3037 _elm_scroll_vbar_unpress_cb, sid);
3038 edje_object_signal_callback_add
3039 (sid->edje_obj, "drag", "elm.dragable.hbar", _elm_scroll_hbar_drag_cb,
3041 edje_object_signal_callback_add
3042 (sid->edje_obj, "drag,set", "elm.dragable.hbar",
3043 _elm_scroll_edje_drag_h_cb, sid);
3044 edje_object_signal_callback_add
3045 (sid->edje_obj, "drag,start", "elm.dragable.hbar",
3046 _elm_scroll_edje_drag_h_start_cb, sid);
3047 edje_object_signal_callback_add
3048 (sid->edje_obj, "drag,stop", "elm.dragable.hbar",
3049 _elm_scroll_edje_drag_h_stop_cb, sid);
3050 edje_object_signal_callback_add
3051 (sid->edje_obj, "drag,step", "elm.dragable.hbar",
3052 _elm_scroll_edje_drag_h_cb, sid);
3053 edje_object_signal_callback_add
3054 (sid->edje_obj, "drag,page", "elm.dragable.hbar",
3055 _elm_scroll_edje_drag_h_cb, sid);
3056 edje_object_signal_callback_add
3057 (sid->edje_obj, "elm,hbar,press", "elm",
3058 _elm_scroll_hbar_press_cb, sid);
3059 edje_object_signal_callback_add
3060 (sid->edje_obj, "elm,hbar,unpress", "elm",
3061 _elm_scroll_hbar_unpress_cb, sid);
3065 _scroll_event_object_attach(Evas_Object *obj)
3067 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3069 evas_object_event_callback_add
3070 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL, _elm_scroll_wheel_event_cb,
3072 evas_object_event_callback_add
3073 (sid->event_rect, EVAS_CALLBACK_MOUSE_DOWN,
3074 _elm_scroll_mouse_down_event_cb, sid);
3075 evas_object_event_callback_add
3076 (sid->event_rect, EVAS_CALLBACK_MOUSE_UP,
3077 _elm_scroll_mouse_up_event_cb, sid);
3078 evas_object_event_callback_add
3079 (sid->event_rect, EVAS_CALLBACK_MOUSE_MOVE,
3080 _elm_scroll_mouse_move_event_cb, sid);
3084 _scroll_edje_object_detach(Evas_Object *obj)
3086 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3088 evas_object_event_callback_del_full
3089 (sid->edje_obj, EVAS_CALLBACK_RESIZE, _on_edje_resize, sid);
3090 evas_object_event_callback_del_full
3091 (sid->edje_obj, EVAS_CALLBACK_MOVE, _on_edje_move, sid);
3093 edje_object_signal_callback_del_full
3094 (sid->edje_obj, "drag", "elm.dragable.vbar", _elm_scroll_vbar_drag_cb,
3096 edje_object_signal_callback_del_full
3097 (sid->edje_obj, "drag,set", "elm.dragable.vbar",
3098 _elm_scroll_edje_drag_v_cb, sid);
3099 edje_object_signal_callback_del_full
3100 (sid->edje_obj, "drag,start", "elm.dragable.vbar",
3101 _elm_scroll_edje_drag_v_start_cb, sid);
3102 edje_object_signal_callback_del_full
3103 (sid->edje_obj, "drag,stop", "elm.dragable.vbar",
3104 _elm_scroll_edje_drag_v_stop_cb, sid);
3105 edje_object_signal_callback_del_full
3106 (sid->edje_obj, "drag,step", "elm.dragable.vbar",
3107 _elm_scroll_edje_drag_v_cb, sid);
3108 edje_object_signal_callback_del_full
3109 (sid->edje_obj, "drag,page", "elm.dragable.vbar",
3110 _elm_scroll_edje_drag_v_cb, sid);
3111 edje_object_signal_callback_del_full
3112 (sid->edje_obj, "elm,vbar,press", "elm",
3113 _elm_scroll_vbar_press_cb, sid);
3114 edje_object_signal_callback_del_full
3115 (sid->edje_obj, "elm,vbar,unpress", "elm",
3116 _elm_scroll_vbar_unpress_cb, sid);
3117 edje_object_signal_callback_del_full
3118 (sid->edje_obj, "drag", "elm.dragable.hbar", _elm_scroll_hbar_drag_cb,
3120 edje_object_signal_callback_del_full
3121 (sid->edje_obj, "drag,set", "elm.dragable.hbar",
3122 _elm_scroll_edje_drag_h_cb, sid);
3123 edje_object_signal_callback_del_full
3124 (sid->edje_obj, "drag,start", "elm.dragable.hbar",
3125 _elm_scroll_edje_drag_h_start_cb, sid);
3126 edje_object_signal_callback_del_full
3127 (sid->edje_obj, "drag,stop", "elm.dragable.hbar",
3128 _elm_scroll_edje_drag_h_stop_cb, sid);
3129 edje_object_signal_callback_del_full
3130 (sid->edje_obj, "drag,step", "elm.dragable.hbar",
3131 _elm_scroll_edje_drag_h_cb, sid);
3132 edje_object_signal_callback_del_full
3133 (sid->edje_obj, "drag,page", "elm.dragable.hbar",
3134 _elm_scroll_edje_drag_h_cb, sid);
3135 edje_object_signal_callback_del_full
3136 (sid->edje_obj, "elm,hbar,press", "elm",
3137 _elm_scroll_hbar_press_cb, sid);
3138 edje_object_signal_callback_del_full
3139 (sid->edje_obj, "elm,hbar,unpress", "elm",
3140 _elm_scroll_hbar_unpress_cb, sid);
3144 _scroll_event_object_detach(Evas_Object *obj)
3146 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3148 evas_object_event_callback_del_full
3149 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL, _elm_scroll_wheel_event_cb,
3151 evas_object_event_callback_del_full
3152 (sid->event_rect, EVAS_CALLBACK_MOUSE_DOWN,
3153 _elm_scroll_mouse_down_event_cb, sid);
3154 evas_object_event_callback_del_full
3155 (sid->event_rect, EVAS_CALLBACK_MOUSE_UP,
3156 _elm_scroll_mouse_up_event_cb, sid);
3157 evas_object_event_callback_del_full
3158 (sid->event_rect, EVAS_CALLBACK_MOUSE_MOVE,
3159 _elm_scroll_mouse_move_event_cb, sid);
3163 _elm_scroll_objects_set(Evas_Object *obj,
3164 Evas_Object *edje_object,
3165 Evas_Object *hit_rectangle)
3169 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3171 if (!edje_object || !hit_rectangle) return;
3174 _scroll_edje_object_detach(obj);
3176 sid->edje_obj = edje_object;
3178 if (sid->event_rect)
3179 _scroll_event_object_detach(obj);
3181 sid->event_rect = hit_rectangle;
3182 evas_object_repeat_events_set(hit_rectangle, EINA_TRUE);
3184 _scroll_edje_object_attach(obj);
3185 _scroll_event_object_attach(obj);
3188 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
3189 if (edje_object_part_exists(sid->edje_obj, "elm.scrollbar.base"))
3193 base = edje_object_part_swallow_get
3194 (sid->edje_obj, "elm.scrollbar.base");
3197 base = evas_object_rectangle_add
3198 (evas_object_evas_get(sid->edje_obj));
3199 evas_object_color_set(base, 0, 0, 0, 0);
3200 edje_object_part_swallow
3201 (sid->edje_obj, "elm.scrollbar.base", base);
3203 if (!_elm_config->thumbscroll_enable)
3204 evas_object_size_hint_min_set(base, mw, mh);
3207 _elm_scroll_scroll_bar_visibility_adjust(sid);
3211 _elm_scroll_scroll_bar_reset(Elm_Scrollable_Smart_Interface_Data *sid)
3213 Evas_Coord px = 0, py = 0, minx = 0, miny = 0;
3215 if (!sid->edje_obj) return;
3217 edje_object_part_drag_value_set
3218 (sid->edje_obj, "elm.dragable.vbar", 0.0, 0.0);
3219 edje_object_part_drag_value_set
3220 (sid->edje_obj, "elm.dragable.hbar", 0.0, 0.0);
3221 if ((!sid->content) && (!sid->extern_pan))
3223 edje_object_part_drag_size_set
3224 (sid->edje_obj, "elm.dragable.vbar", 1.0, 1.0);
3225 edje_object_part_drag_size_set
3226 (sid->edje_obj, "elm.dragable.hbar", 1.0, 1.0);
3230 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
3232 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
3233 psd->api->pos_get(sid->pan_obj, &px, &py);
3234 psd->api->pos_set(sid->pan_obj, minx, miny);
3236 if ((px != minx) || (py != miny))
3237 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
3238 _elm_direction_arrows_eval(sid);
3241 /* even external pan objects get this */
3243 _elm_scroll_pan_changed_cb(void *data,
3244 Evas_Object *obj __UNUSED__,
3245 void *event_info __UNUSED__)
3248 Elm_Scrollable_Smart_Interface_Data *sid = data;
3250 if (!sid->pan_obj) return;
3252 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
3254 psd->api->content_size_get(sid->pan_obj, &w, &h);
3255 if ((w != sid->content_info.w) || (h != sid->content_info.h))
3257 sid->content_info.w = w;
3258 sid->content_info.h = h;
3259 _elm_scroll_scroll_bar_size_adjust(sid);
3261 evas_object_size_hint_min_set
3262 (sid->edje_obj, sid->content_info.w, sid->content_info.h);
3263 sid->content_info.resized = EINA_TRUE;
3264 _elm_scroll_wanted_region_set(sid->obj);
3269 _elm_scroll_content_del_cb(void *data,
3271 Evas_Object *obj __UNUSED__,
3272 void *event_info __UNUSED__)
3274 Elm_Scrollable_Smart_Interface_Data *sid = data;
3276 sid->content = NULL;
3277 _elm_scroll_scroll_bar_size_adjust(sid);
3278 _elm_scroll_scroll_bar_reset(sid);
3282 _elm_scroll_content_set(Evas_Object *obj,
3283 Evas_Object *content)
3288 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3290 if (!sid->edje_obj) return;
3294 /* if we had content, for sure we had a pan object */
3295 _elm_pan_content_set(sid->pan_obj, NULL);
3296 evas_object_event_callback_del_full
3297 (sid->content, EVAS_CALLBACK_DEL, _elm_scroll_content_del_cb, sid);
3300 sid->content = content;
3301 sid->wx = sid->wy = 0;
3302 /* (-1) means want viewports size */
3303 sid->ww = sid->wh = -1;
3304 if (!content) return;
3308 o = _elm_pan_add(evas_object_evas_get(obj));
3310 evas_object_smart_callback_add
3311 (o, SIG_CHANGED, _elm_scroll_pan_changed_cb, sid);
3312 edje_object_part_swallow(sid->edje_obj, "elm.swallow.content", o);
3315 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
3317 evas_object_event_callback_add
3318 (content, EVAS_CALLBACK_DEL, _elm_scroll_content_del_cb, sid);
3320 _elm_pan_content_set(sid->pan_obj, content);
3321 psd->api->content_size_get(sid->pan_obj, &w, &h);
3322 sid->content_info.w = w;
3323 sid->content_info.h = h;
3325 _elm_scroll_scroll_bar_size_adjust(sid);
3326 _elm_scroll_scroll_bar_reset(sid);
3330 _elm_scroll_extern_pan_set(Evas_Object *obj,
3333 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3335 if (!sid->edje_obj) return;
3337 _elm_scroll_content_set(obj, NULL);
3341 evas_object_smart_callback_del
3342 (sid->pan_obj, SIG_CHANGED, _elm_scroll_pan_changed_cb);
3345 if (sid->extern_pan)
3349 /* not owned by scroller, just leave (was external already) */
3350 edje_object_part_unswallow(sid->edje_obj, sid->pan_obj);
3351 sid->pan_obj = NULL;
3358 evas_object_del(sid->pan_obj);
3359 sid->pan_obj = NULL;
3364 sid->extern_pan = EINA_FALSE;
3370 sid->extern_pan = EINA_TRUE;
3371 evas_object_smart_callback_add
3372 (sid->pan_obj, SIG_CHANGED, _elm_scroll_pan_changed_cb, sid);
3373 edje_object_part_swallow
3374 (sid->edje_obj, "elm.swallow.content", sid->pan_obj);
3378 _elm_scroll_drag_start_cb_set(Evas_Object *obj,
3379 void (*drag_start_cb)(Evas_Object *obj,
3382 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3384 sid->cb_func.drag_start = drag_start_cb;
3388 _elm_scroll_drag_stop_cb_set(Evas_Object *obj,
3389 void (*drag_stop_cb)(Evas_Object *obj,
3392 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3394 sid->cb_func.drag_stop = drag_stop_cb;
3398 _elm_scroll_animate_start_cb_set(Evas_Object *obj,
3399 void (*animate_start_cb)(Evas_Object *obj,
3402 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3404 sid->cb_func.animate_start = animate_start_cb;
3408 _elm_scroll_animate_stop_cb_set(Evas_Object *obj,
3409 void (*animate_stop_cb)(Evas_Object *obj,
3412 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3414 sid->cb_func.animate_stop = animate_stop_cb;
3418 _elm_scroll_scroll_cb_set(Evas_Object *obj,
3419 void (*scroll_cb)(Evas_Object *obj,
3422 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3424 sid->cb_func.scroll = scroll_cb;
3428 _elm_scroll_scroll_left_cb_set(Evas_Object *obj,
3429 void (*scroll_left_cb)(Evas_Object *obj,
3432 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3434 sid->cb_func.scroll_left = scroll_left_cb;
3438 _elm_scroll_scroll_right_cb_set(Evas_Object *obj,
3439 void (*scroll_right_cb)(Evas_Object *obj,
3442 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3444 sid->cb_func.scroll_right = scroll_right_cb;
3448 _elm_scroll_scroll_up_cb_set(Evas_Object *obj,
3449 void (*scroll_up_cb)(Evas_Object *obj,
3452 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3454 sid->cb_func.scroll_up = scroll_up_cb;
3458 _elm_scroll_scroll_down_cb_set(Evas_Object *obj,
3459 void (*scroll_down_cb)(Evas_Object *obj,
3462 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3464 sid->cb_func.scroll_down = scroll_down_cb;
3468 _elm_scroll_edge_left_cb_set(Evas_Object *obj,
3469 void (*edge_left_cb)(Evas_Object *obj,
3472 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3474 sid->cb_func.edge_left = edge_left_cb;
3478 _elm_scroll_edge_right_cb_set(Evas_Object *obj,
3479 void (*edge_right_cb)(Evas_Object *obj,
3482 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3484 sid->cb_func.edge_right = edge_right_cb;
3488 _elm_scroll_edge_top_cb_set(Evas_Object *obj,
3489 void (*edge_top_cb)(Evas_Object *obj,
3492 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3494 sid->cb_func.edge_top = edge_top_cb;
3498 _elm_scroll_edge_bottom_cb_set(Evas_Object *obj,
3499 void (*edge_bottom_cb)(Evas_Object *obj,
3502 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3504 sid->cb_func.edge_bottom = edge_bottom_cb;
3508 _elm_scroll_vbar_drag_cb_set(Evas_Object *obj,
3509 void (*vbar_drag_cb)(Evas_Object *obj,
3512 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3514 sid->cb_func.vbar_drag = vbar_drag_cb;
3518 _elm_scroll_vbar_press_cb_set(Evas_Object *obj,
3519 void (*vbar_press_cb)(Evas_Object *obj,
3522 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3524 sid->cb_func.vbar_press = vbar_press_cb;
3528 _elm_scroll_vbar_unpress_cb_set(Evas_Object *obj,
3529 void (*vbar_unpress_cb)(Evas_Object *obj,
3532 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3534 sid->cb_func.vbar_unpress = vbar_unpress_cb;
3538 _elm_scroll_hbar_drag_cb_set(Evas_Object *obj,
3539 void (*hbar_drag_cb)(Evas_Object *obj,
3542 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3544 sid->cb_func.hbar_drag = hbar_drag_cb;
3548 _elm_scroll_hbar_press_cb_set(Evas_Object *obj,
3549 void (*hbar_press_cb)(Evas_Object *obj,
3552 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3554 sid->cb_func.hbar_press = hbar_press_cb;
3558 _elm_scroll_hbar_unpress_cb_set(Evas_Object *obj,
3559 void (*hbar_unpress_cb)(Evas_Object *obj,
3562 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3564 sid->cb_func.hbar_unpress = hbar_unpress_cb;
3568 _elm_scroll_content_min_limit_cb_set(Evas_Object *obj,
3569 void (*c_min_limit_cb)(Evas_Object *obj,
3573 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3575 sid->cb_func.content_min_limit = c_min_limit_cb;
3579 _elm_scroll_momentum_animator_disabled_get(const Evas_Object *obj)
3581 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
3583 return sid->momentum_animator_disabled;
3587 _elm_scroll_momentum_animator_disabled_set(Evas_Object *obj,
3590 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3592 sid->momentum_animator_disabled = disabled;
3593 if (sid->momentum_animator_disabled)
3595 if (sid->down.momentum_animator)
3597 ecore_animator_del(sid->down.momentum_animator);
3598 sid->down.momentum_animator = NULL;
3599 if (sid->content_info.resized)
3600 _elm_scroll_wanted_region_set(sid->obj);
3606 _elm_scroll_bounce_animator_disabled_get(const Evas_Object *obj)
3608 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
3610 return sid->bounce_animator_disabled;
3614 _elm_scroll_bounce_animator_disabled_set(Evas_Object *obj,
3617 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3619 sid->bounce_animator_disabled = disabled;
3620 if (sid->bounce_animator_disabled)
3622 if (sid->scrollto.x.animator)
3624 ecore_animator_del(sid->scrollto.x.animator);
3625 sid->scrollto.x.animator = NULL;
3628 if (sid->scrollto.y.animator)
3630 ecore_animator_del(sid->scrollto.y.animator);
3631 sid->scrollto.y.animator = NULL;
3637 _elm_scroll_wheel_disabled_get(const Evas_Object *obj)
3639 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
3641 return sid->wheel_disabled;
3645 _elm_scroll_wheel_disabled_set(Evas_Object *obj,
3648 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3650 if (!sid->event_rect) return;
3652 if ((!sid->wheel_disabled) && (disabled))
3653 evas_object_event_callback_del_full
3654 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL,
3655 _elm_scroll_wheel_event_cb, sid);
3656 else if ((sid->wheel_disabled) && (!disabled))
3657 evas_object_event_callback_add
3658 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL,
3659 _elm_scroll_wheel_event_cb, sid);
3660 sid->wheel_disabled = disabled;
3664 _elm_scroll_step_size_set(Evas_Object *obj,
3668 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3675 _elm_scroll_scroll_bar_size_adjust(sid);
3679 _elm_scroll_step_size_get(const Evas_Object *obj,
3683 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3685 if (x) *x = sid->step.x;
3686 if (y) *y = sid->step.y;
3690 _elm_scroll_page_size_set(Evas_Object *obj,
3694 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3699 _elm_scroll_scroll_bar_size_adjust(sid);
3703 _elm_scroll_page_size_get(const Evas_Object *obj,
3707 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3709 if (x) *x = sid->page.x;
3710 if (y) *y = sid->page.y;
3714 _elm_scroll_policy_set(Evas_Object *obj,
3715 Elm_Scroller_Policy hbar,
3716 Elm_Scroller_Policy vbar)
3718 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3720 if (!sid->edje_obj) return;
3722 if ((sid->hbar_flags == hbar) && (sid->vbar_flags == vbar)) return;
3724 sid->hbar_flags = hbar;
3725 sid->vbar_flags = vbar;
3726 if (sid->hbar_flags == ELM_SCROLLER_POLICY_ON)
3727 edje_object_signal_emit
3728 (sid->edje_obj, "elm,action,show_always,hbar", "elm");
3729 else if (sid->hbar_flags == ELM_SCROLLER_POLICY_OFF)
3730 edje_object_signal_emit
3731 (sid->edje_obj, "elm,action,hide,hbar", "elm");
3733 edje_object_signal_emit
3734 (sid->edje_obj, "elm,action,show_notalways,hbar", "elm");
3735 if (sid->vbar_flags == ELM_SCROLLER_POLICY_ON)
3736 edje_object_signal_emit
3737 (sid->edje_obj, "elm,action,show_always,vbar", "elm");
3738 else if (sid->vbar_flags == ELM_SCROLLER_POLICY_OFF)
3739 edje_object_signal_emit
3740 (sid->edje_obj, "elm,action,hide,vbar", "elm");
3742 edje_object_signal_emit
3743 (sid->edje_obj, "elm,action,show_notalways,vbar", "elm");
3744 edje_object_message_signal_process(sid->edje_obj);
3745 _elm_scroll_scroll_bar_size_adjust(sid);
3746 if (sid->cb_func.content_min_limit)
3747 sid->cb_func.content_min_limit(sid->obj, sid->min_w, sid->min_h);
3748 _elm_direction_arrows_eval(sid);
3752 _elm_scroll_policy_get(const Evas_Object *obj,
3753 Elm_Scroller_Policy *hbar,
3754 Elm_Scroller_Policy *vbar)
3756 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3758 if (hbar) *hbar = sid->hbar_flags;
3759 if (vbar) *vbar = sid->vbar_flags;
3763 _elm_scroll_single_direction_set(Evas_Object *obj,
3764 Eina_Bool single_dir)
3766 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3768 sid->one_direction_at_a_time = single_dir;
3772 _elm_scroll_single_direction_get(const Evas_Object *obj)
3774 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
3776 return sid->one_direction_at_a_time;
3780 _elm_scroll_repeat_events_set(Evas_Object *obj,
3781 Eina_Bool repeat_events)
3783 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3785 evas_object_repeat_events_set(sid->event_rect, repeat_events);
3789 _elm_scroll_repeat_events_get(Evas_Object *obj)
3791 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3793 return evas_object_repeat_events_get(sid->event_rect);
3797 _elm_scroll_hold_set(Evas_Object *obj,
3800 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3806 _elm_scroll_freeze_set(Evas_Object *obj,
3809 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3811 sid->freeze = freeze;
3814 if (sid->down.onhold_animator)
3816 ecore_animator_del(sid->down.onhold_animator);
3817 sid->down.onhold_animator = NULL;
3818 if (sid->content_info.resized)
3819 _elm_scroll_wanted_region_set(sid->obj);
3823 _elm_scroll_bounce_eval(sid);
3827 _elm_scroll_bounce_allow_set(Evas_Object *obj,
3831 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3833 sid->bounce_horiz = !!horiz;
3834 sid->bounce_vert = !!vert;
3838 _elm_scroll_bounce_allow_get(const Evas_Object *obj,
3842 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3844 if (horiz) *horiz = sid->bounce_horiz;
3845 if (vert) *vert = sid->bounce_vert;
3849 _elm_scroll_paging_set(Evas_Object *obj,
3852 Evas_Coord pagesize_h,
3853 Evas_Coord pagesize_v)
3855 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3857 sid->pagerel_h = pagerel_h;
3858 sid->pagerel_v = pagerel_v;
3859 sid->pagesize_h = pagesize_h;
3860 sid->pagesize_v = pagesize_v;
3862 _elm_scroll_page_adjust(sid);
3866 _elm_scroll_paging_get(const Evas_Object *obj,
3869 Evas_Coord *pagesize_h,
3870 Evas_Coord *pagesize_v)
3872 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3874 if (pagerel_h) *pagerel_h = sid->pagerel_h;
3875 if (pagerel_v) *pagerel_v = sid->pagerel_v;
3876 if (pagesize_h) *pagesize_h = sid->pagesize_h;
3877 if (pagesize_v) *pagesize_v = sid->pagesize_v;
3881 _elm_scroll_page_scroll_limit_set(const Evas_Object *obj,
3885 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3887 sid->page_limit_h = page_limit_h;
3888 sid->page_limit_v = page_limit_v;
3892 _elm_scroll_page_scroll_limit_get(const Evas_Object *obj,
3896 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3898 if (page_limit_h) *page_limit_h = sid->page_limit_h;
3899 if (page_limit_v) *page_limit_v = sid->page_limit_v;
3903 _elm_scroll_current_page_get(const Evas_Object *obj,
3909 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3911 _elm_scroll_content_pos_get(sid->obj, &x, &y);
3914 if (sid->pagesize_h > 0)
3915 *pagenumber_h = (x + sid->pagesize_h - 1) / sid->pagesize_h;
3921 if (sid->pagesize_v > 0)
3922 *pagenumber_v = (y + sid->pagesize_v - 1) / sid->pagesize_v;
3929 _elm_scroll_last_page_get(const Evas_Object *obj,
3935 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3937 if (!sid->pan_obj) return;
3939 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
3941 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
3944 if (sid->pagesize_h > 0)
3945 *pagenumber_h = cw / sid->pagesize_h + 1;
3951 if (sid->pagesize_v > 0)
3952 *pagenumber_v = ch / sid->pagesize_v + 1;
3959 _elm_scroll_page_show(Evas_Object *obj,
3967 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3969 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
3970 if (pagenumber_h >= 0) x = sid->pagesize_h * pagenumber_h;
3971 if (pagenumber_v >= 0) y = sid->pagesize_v * pagenumber_v;
3972 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
3973 _elm_scroll_content_pos_set(obj, x, y, EINA_TRUE);
3977 _elm_scroll_page_bring_in(Evas_Object *obj,
3985 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3987 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
3988 if (pagenumber_h >= 0) x = sid->pagesize_h * pagenumber_h;
3989 if (pagenumber_v >= 0) y = sid->pagesize_v * pagenumber_v;
3990 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
3992 _elm_scroll_scroll_to_x(sid, _elm_config->bring_in_scroll_friction, x);
3993 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, y);
3998 _elm_scroll_region_bring_in(Evas_Object *obj,
4004 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4006 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
4008 _elm_scroll_scroll_to_x(sid, _elm_config->bring_in_scroll_friction, x);
4009 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, y);
4014 _elm_scroll_gravity_set(Evas_Object *obj,
4018 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4020 if (!sid->pan_obj) return;
4022 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
4024 psd->api->gravity_set(sid->pan_obj, x, y);
4028 _elm_scroll_gravity_get(const Evas_Object *obj,
4032 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4034 if (!sid->pan_obj) return;
4036 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
4038 psd->api->gravity_get(sid->pan_obj, x, y);
4042 _elm_scroll_interface_add(Evas_Object *obj)
4044 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
4046 memset(sid, 0, sizeof(*sid));
4058 sid->page_limit_h = 9999;
4059 sid->page_limit_v = 9999;
4060 sid->hbar_flags = ELM_SCROLLER_POLICY_AUTO;
4061 sid->vbar_flags = ELM_SCROLLER_POLICY_AUTO;
4062 sid->hbar_visible = EINA_TRUE;
4063 sid->vbar_visible = EINA_TRUE;
4065 sid->bounce_horiz = EINA_TRUE;
4066 sid->bounce_vert = EINA_TRUE;
4068 sid->one_direction_at_a_time = EINA_TRUE;
4069 sid->momentum_animator_disabled = EINA_FALSE;
4070 sid->bounce_animator_disabled = EINA_FALSE;
4072 _elm_scroll_scroll_bar_reset(sid);
4078 _elm_scroll_interface_del(Evas_Object *obj)
4080 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4082 _elm_scroll_content_set(obj, NULL);
4083 if (!sid->extern_pan) evas_object_del(sid->pan_obj);
4085 if (sid->down.hold_animator)
4086 ecore_animator_del(sid->down.hold_animator);
4087 if (sid->down.onhold_animator)
4088 ecore_animator_del(sid->down.onhold_animator);
4089 if (sid->down.momentum_animator)
4090 ecore_animator_del(sid->down.momentum_animator);
4091 if (sid->down.bounce_x_animator)
4092 ecore_animator_del(sid->down.bounce_x_animator);
4093 if (sid->down.bounce_y_animator)
4094 ecore_animator_del(sid->down.bounce_y_animator);
4095 if (sid->scrollto.x.animator) ecore_animator_del(sid->scrollto.x.animator);
4096 if (sid->scrollto.y.animator) ecore_animator_del(sid->scrollto.y.animator);
4099 EAPI const char ELM_SCROLLABLE_IFACE_NAME[] = "elm_interface_scrollable";
4101 EAPI const Elm_Scrollable_Smart_Interface ELM_SCROLLABLE_IFACE =
4104 ELM_SCROLLABLE_IFACE_NAME,
4105 sizeof(Elm_Scrollable_Smart_Interface_Data),
4106 _elm_scroll_interface_add,
4107 _elm_scroll_interface_del
4110 _elm_scroll_objects_set,
4111 _elm_scroll_content_set,
4112 _elm_scroll_extern_pan_set,
4113 _elm_scroll_drag_start_cb_set,
4114 _elm_scroll_drag_stop_cb_set,
4115 _elm_scroll_animate_start_cb_set,
4116 _elm_scroll_animate_stop_cb_set,
4117 _elm_scroll_scroll_cb_set,
4118 _elm_scroll_scroll_left_cb_set,
4119 _elm_scroll_scroll_right_cb_set,
4120 _elm_scroll_scroll_up_cb_set,
4121 _elm_scroll_scroll_down_cb_set,
4122 _elm_scroll_edge_left_cb_set,
4123 _elm_scroll_edge_right_cb_set,
4124 _elm_scroll_edge_top_cb_set,
4125 _elm_scroll_edge_bottom_cb_set,
4126 _elm_scroll_vbar_drag_cb_set,
4127 _elm_scroll_vbar_press_cb_set,
4128 _elm_scroll_vbar_unpress_cb_set,
4129 _elm_scroll_hbar_drag_cb_set,
4130 _elm_scroll_hbar_press_cb_set,
4131 _elm_scroll_hbar_unpress_cb_set,
4132 _elm_scroll_content_min_limit_cb_set,
4133 _elm_scroll_content_pos_set,
4134 _elm_scroll_content_pos_get,
4135 _elm_scroll_content_region_show,
4136 _elm_scroll_content_region_set,
4137 _elm_scroll_content_size_get,
4138 _elm_scroll_content_viewport_size_get,
4139 _elm_scroll_content_min_limit,
4140 _elm_scroll_step_size_set,
4141 _elm_scroll_step_size_get,
4142 _elm_scroll_page_size_set,
4143 _elm_scroll_page_size_get,
4144 _elm_scroll_policy_set,
4145 _elm_scroll_policy_get,
4146 _elm_scroll_single_direction_set,
4147 _elm_scroll_single_direction_get,
4148 _elm_scroll_repeat_events_set,
4149 _elm_scroll_repeat_events_get,
4150 _elm_scroll_mirrored_set,
4151 _elm_scroll_hold_set,
4152 _elm_scroll_freeze_set,
4153 _elm_scroll_bounce_allow_set,
4154 _elm_scroll_bounce_allow_get,
4155 _elm_scroll_paging_set,
4156 _elm_scroll_paging_get,
4157 _elm_scroll_page_scroll_limit_set,
4158 _elm_scroll_page_scroll_limit_get,
4159 _elm_scroll_current_page_get,
4160 _elm_scroll_last_page_get,
4161 _elm_scroll_page_show,
4162 _elm_scroll_page_bring_in,
4163 _elm_scroll_region_bring_in,
4164 _elm_scroll_gravity_set,
4165 _elm_scroll_gravity_get,
4166 _elm_scroll_momentum_animator_disabled_get,
4167 _elm_scroll_momentum_animator_disabled_set,
4168 _elm_scroll_bounce_animator_disabled_set,
4169 _elm_scroll_bounce_animator_disabled_get,
4170 _elm_scroll_wheel_disabled_get,
4171 _elm_scroll_wheel_disabled_set