1 #include <Elementary.h>
3 #include "elm_interface_scrollable.h"
5 static const char PAN_SMART_NAME[] = "elm_pan";
7 #define ELM_PAN_DATA_GET_OR_RETURN(o, ptr) \
8 Elm_Pan_Smart_Data *ptr = evas_object_smart_data_get(o); \
11 CRITICAL("No smart data for object %p (%s)", \
12 o, evas_object_type_get(o)); \
16 #define ELM_PAN_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
17 Elm_Pan_Smart_Data *ptr = evas_object_smart_data_get(o); \
20 CRITICAL("No smart data for object %p (%s)", \
21 o, evas_object_type_get(o)); \
25 static const char SIG_CHANGED[] = "changed";
26 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
31 ELM_INTERNAL_SMART_SUBCLASS_NEW
32 (PAN_SMART_NAME, _elm_pan, Elm_Pan_Smart_Class, Evas_Smart_Class,
33 evas_object_smart_clipped_class_get, _smart_callbacks);
35 static void _elm_pan_content_set(Evas_Object *, Evas_Object *);
37 EAPI const Elm_Pan_Smart_Class *
38 elm_pan_smart_class_get(void)
40 static Elm_Pan_Smart_Class _sc =
41 ELM_PAN_SMART_CLASS_INIT_NAME_VERSION(PAN_SMART_NAME);
42 static const Elm_Pan_Smart_Class *class = NULL;
43 Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
48 _elm_pan_smart_set(&_sc);
49 esc->callbacks = _smart_callbacks;
56 _round(double value, int pos)
60 temp = value * pow( 10, pos );
61 temp = floor( temp + 0.5 );
62 temp *= pow( 10, -pos );
68 _elm_pan_update(Elm_Pan_Smart_Data *psd)
70 if (!psd->gravity_x && !psd->gravity_y)
72 evas_object_move(psd->content, psd->x - psd->px, psd->y - psd->py);
76 if ((!psd->px) && (!psd->py))
78 psd->px = psd->delta_posx * psd->gravity_x;
79 psd->py = psd->delta_posy * psd->gravity_y;
81 psd->delta_posx += psd->content_w - psd->prev_cw;
82 psd->prev_cw = psd->content_w;
83 psd->delta_posy += psd->content_h - psd->prev_ch;
84 psd->prev_ch = psd->content_h;
86 evas_object_move(psd->content, psd->x - psd->px, psd->y - psd->py);
87 psd->px = psd->delta_posx * psd->gravity_x;
88 psd->py = psd->delta_posy * psd->gravity_y;
92 _elm_pan_smart_add(Evas_Object *obj)
94 const Evas_Smart_Class *sc;
95 const Evas_Smart *smart;
97 EVAS_SMART_DATA_ALLOC(obj, Elm_Pan_Smart_Data);
99 _elm_pan_parent_sc->add(obj);
107 priv->gravity_x = 0.0;
108 priv->gravity_y = 0.0;
110 smart = evas_object_smart_smart_get(obj);
111 sc = evas_smart_class_get(smart);
112 priv->api = (const Elm_Pan_Smart_Class *)sc;
116 _elm_pan_smart_del(Evas_Object *obj)
118 _elm_pan_content_set(obj, NULL);
120 _elm_pan_parent_sc->del(obj);
124 _elm_pan_smart_move(Evas_Object *obj,
128 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
130 /* we don't want the clipped smart object version here */
135 _elm_pan_update(psd);
139 _elm_pan_smart_resize(Evas_Object *obj,
143 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
148 _elm_pan_update(psd);
149 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
153 _elm_pan_smart_show(Evas_Object *obj)
155 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
157 _elm_pan_parent_sc->show(obj);
160 evas_object_show(psd->content);
164 _elm_pan_smart_hide(Evas_Object *obj)
166 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
168 _elm_pan_parent_sc->hide(obj);
171 evas_object_hide(psd->content);
175 _elm_pan_pos_set(Evas_Object *obj,
179 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
181 if ((x == psd->px) && (y == psd->py)) return;
185 _elm_pan_update(psd);
186 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
190 _elm_pan_pos_get(const Evas_Object *obj,
194 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
201 _elm_pan_pos_max_get(const Evas_Object *obj,
205 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
209 if (psd->w < psd->content_w) *x = psd->content_w - psd->w;
214 if (psd->h < psd->content_h) *y = psd->content_h - psd->h;
220 _elm_pan_pos_min_get(const Evas_Object *obj __UNUSED__,
231 _elm_pan_content_size_get(const Evas_Object *obj,
235 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
237 if (w) *w = psd->content_w;
238 if (h) *h = psd->content_h;
242 _elm_pan_gravity_set(Evas_Object *obj,
246 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
250 psd->prev_cw = psd->content_w;
251 psd->prev_ch = psd->content_h;
257 _elm_pan_gravity_get(const Evas_Object *obj,
261 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
263 if (x) *x = psd->gravity_x;
264 if (y) *y = psd->gravity_y;
268 _elm_pan_smart_set_user(Elm_Pan_Smart_Class *sc)
270 sc->base.add = _elm_pan_smart_add;
271 sc->base.del = _elm_pan_smart_del;
272 sc->base.move = _elm_pan_smart_move;
273 sc->base.resize = _elm_pan_smart_resize;
274 sc->base.show = _elm_pan_smart_show;
275 sc->base.hide = _elm_pan_smart_hide;
277 sc->pos_set = _elm_pan_pos_set;
278 sc->pos_get = _elm_pan_pos_get;
279 sc->pos_max_get = _elm_pan_pos_max_get;
280 sc->pos_min_get = _elm_pan_pos_min_get;
281 sc->content_size_get = _elm_pan_content_size_get;
282 sc->gravity_set = _elm_pan_gravity_set;
283 sc->gravity_get = _elm_pan_gravity_get;
287 _elm_pan_add(Evas *evas)
289 return evas_object_smart_add(evas, _elm_pan_smart_class_new());
293 _elm_pan_content_del_cb(void *data,
295 Evas_Object *obj __UNUSED__,
296 void *event_info __UNUSED__)
298 Elm_Pan_Smart_Data *psd;
302 psd->content_w = psd->content_h = psd->px = psd->py =
303 psd->prev_cw = psd->prev_ch = psd->delta_posx = psd->delta_posy = 0;
304 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
308 _elm_pan_content_resize_cb(void *data,
310 Evas_Object *obj __UNUSED__,
311 void *event_info __UNUSED__)
313 Elm_Pan_Smart_Data *psd;
317 evas_object_geometry_get(psd->content, NULL, NULL, &w, &h);
318 if ((w != psd->content_w) || (h != psd->content_h))
322 _elm_pan_update(psd);
324 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
328 _elm_pan_content_set(Evas_Object *obj,
329 Evas_Object *content)
333 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
335 if (content == psd->content) return;
338 evas_object_smart_member_del(psd->content);
339 evas_object_event_callback_del_full
340 (psd->content, EVAS_CALLBACK_DEL, _elm_pan_content_del_cb, psd);
341 evas_object_event_callback_del_full
342 (psd->content, EVAS_CALLBACK_RESIZE, _elm_pan_content_resize_cb,
346 if (!content) goto end;
348 psd->content = content;
349 evas_object_smart_member_add(psd->content, psd->self);
350 evas_object_geometry_get(psd->content, NULL, NULL, &w, &h);
353 evas_object_event_callback_add
354 (content, EVAS_CALLBACK_DEL, _elm_pan_content_del_cb, psd);
355 evas_object_event_callback_add
356 (content, EVAS_CALLBACK_RESIZE, _elm_pan_content_resize_cb, psd);
358 if (evas_object_visible_get(psd->self))
359 evas_object_show(psd->content);
361 evas_object_hide(psd->content);
363 _elm_pan_update(psd);
366 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
369 /* pan smart object on top, scroller interface on bottom */
370 /* ============================================================ */
372 static const char SCROLL_SMART_NAME[] = "elm_scroll";
374 #define ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(o, ptr) \
375 Elm_Scrollable_Smart_Interface_Data *ptr = \
376 evas_object_smart_interface_data_get(o, &(ELM_SCROLLABLE_IFACE.base)); \
379 CRITICAL("No interface data for object %p (%s)", \
380 o, evas_object_type_get(o)); \
384 #define ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
385 Elm_Scrollable_Smart_Interface_Data *ptr = \
386 evas_object_smart_interface_data_get(o, &(ELM_SCROLLABLE_IFACE.base)); \
389 CRITICAL("No interface data for object %p (%s)", \
390 o, evas_object_type_get(o)); \
394 static void _elm_scroll_scroll_bar_size_adjust(
395 Elm_Scrollable_Smart_Interface_Data *);
396 static void _elm_scroll_wanted_region_set(Evas_Object *);
397 static Eina_Bool _paging_is_enabled(Elm_Scrollable_Smart_Interface_Data *sid);
398 static Evas_Coord _elm_scroll_page_x_get(
399 Elm_Scrollable_Smart_Interface_Data *sid, int offset, Eina_Bool limit);
400 static Evas_Coord _elm_scroll_page_y_get(
401 Elm_Scrollable_Smart_Interface_Data *sid, int offset, Eina_Bool limit);
402 static void _elm_scroll_content_pos_get(const Evas_Object *,
405 static void _elm_scroll_content_pos_set(Evas_Object *,
417 _elm_direction_arrows_eval(Elm_Scrollable_Smart_Interface_Data *sid)
419 Eina_Bool go_left = EINA_TRUE, go_right = EINA_TRUE;
420 Eina_Bool go_up = EINA_TRUE, go_down = EINA_TRUE;
421 Evas_Coord x = 0, y = 0, mx = 0, my = 0, minx = 0, miny = 0;
423 if (!sid->edje_obj || !sid->pan_obj) return;
424 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
426 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
427 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
428 psd->api->pos_get(sid->pan_obj, &x, &y);
430 if (x == minx) go_left = EINA_FALSE;
431 if (x == (mx + minx)) go_right = EINA_FALSE;
432 if (y == miny) go_up = EINA_FALSE;
433 if (y == (my + miny)) go_down = EINA_FALSE;
434 if (go_left != sid->go_left)
437 edje_object_signal_emit(sid->edje_obj, "elm,action,show,left", "elm");
439 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,left", "elm");
440 sid->go_left = go_left;
442 if (go_right != sid->go_right)
445 edje_object_signal_emit(sid->edje_obj, "elm,action,show,right", "elm");
447 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,right", "elm");
448 sid->go_right= go_right;
450 if (go_up != sid->go_up)
453 edje_object_signal_emit(sid->edje_obj, "elm,action,show,up", "elm");
455 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,up", "elm");
458 if (go_down != sid->go_down)
461 edje_object_signal_emit(sid->edje_obj, "elm,action,show,down", "elm");
463 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,down", "elm");
464 sid->go_down= go_down;
469 _elm_scroll_scroll_bar_h_visibility_adjust(
470 Elm_Scrollable_Smart_Interface_Data *sid)
472 int scroll_h_vis_change = 0;
473 Evas_Coord w, vw = 0, vh = 0;
475 if (!sid->edje_obj) return 0;
477 w = sid->content_info.w;
479 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &vw, &vh);
480 if (sid->hbar_visible)
484 scroll_h_vis_change = 1;
485 sid->hbar_visible = EINA_FALSE;
489 if (sid->hbar_flags == ELM_SCROLLER_POLICY_AUTO)
491 if ((sid->content) || (sid->extern_pan))
495 scroll_h_vis_change = 1;
496 sid->hbar_visible = EINA_FALSE;
501 scroll_h_vis_change = 1;
502 sid->hbar_visible = EINA_FALSE;
505 else if (sid->hbar_flags == ELM_SCROLLER_POLICY_OFF)
507 scroll_h_vis_change = 1;
508 sid->hbar_visible = EINA_FALSE;
516 if (sid->hbar_flags == ELM_SCROLLER_POLICY_AUTO)
518 if ((sid->content) || (sid->extern_pan))
522 scroll_h_vis_change = 1;
523 sid->hbar_visible = EINA_TRUE;
527 else if (sid->hbar_flags == ELM_SCROLLER_POLICY_ON)
529 scroll_h_vis_change = 1;
530 sid->hbar_visible = EINA_TRUE;
534 if (scroll_h_vis_change)
536 if (sid->hbar_flags != ELM_SCROLLER_POLICY_OFF)
538 if (sid->hbar_visible)
539 edje_object_signal_emit
540 (sid->edje_obj, "elm,action,show,hbar", "elm");
542 edje_object_signal_emit
543 (sid->edje_obj, "elm,action,hide,hbar", "elm");
546 edje_object_signal_emit
547 (sid->edje_obj, "elm,action,hide,hbar", "elm");
548 edje_object_message_signal_process(sid->edje_obj);
549 _elm_scroll_scroll_bar_size_adjust(sid);
550 if (sid->cb_func.content_min_limit)
551 sid->cb_func.content_min_limit(sid->obj, sid->min_w, sid->min_h);
554 _elm_direction_arrows_eval(sid);
555 return scroll_h_vis_change;
559 _elm_scroll_scroll_bar_v_visibility_adjust(
560 Elm_Scrollable_Smart_Interface_Data *sid)
562 int scroll_v_vis_change = 0;
563 Evas_Coord h, vw = 0, vh = 0;
565 if (!sid->edje_obj) return 0;
567 h = sid->content_info.h;
569 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &vw, &vh);
570 if (sid->vbar_visible)
574 scroll_v_vis_change = 1;
575 sid->vbar_visible = EINA_FALSE;
579 if (sid->vbar_flags == ELM_SCROLLER_POLICY_AUTO)
581 if ((sid->content) || (sid->extern_pan))
585 scroll_v_vis_change = 1;
586 sid->vbar_visible = EINA_FALSE;
591 scroll_v_vis_change = 1;
592 sid->vbar_visible = EINA_FALSE;
595 else if (sid->vbar_flags == ELM_SCROLLER_POLICY_OFF)
597 scroll_v_vis_change = 1;
598 sid->vbar_visible = EINA_FALSE;
606 if (sid->vbar_flags == ELM_SCROLLER_POLICY_AUTO)
608 if ((sid->content) || (sid->extern_pan))
612 scroll_v_vis_change = 1;
613 sid->vbar_visible = EINA_TRUE;
617 else if (sid->vbar_flags == ELM_SCROLLER_POLICY_ON)
619 scroll_v_vis_change = 1;
620 sid->vbar_visible = EINA_TRUE;
624 if (scroll_v_vis_change)
626 if (sid->vbar_flags != ELM_SCROLLER_POLICY_OFF)
628 if (sid->vbar_visible)
629 edje_object_signal_emit
630 (sid->edje_obj, "elm,action,show,vbar", "elm");
632 edje_object_signal_emit
633 (sid->edje_obj, "elm,action,hide,vbar", "elm");
636 edje_object_signal_emit
637 (sid->edje_obj, "elm,action,hide,vbar", "elm");
638 edje_object_message_signal_process(sid->edje_obj);
639 _elm_scroll_scroll_bar_size_adjust(sid);
640 if (sid->cb_func.content_min_limit)
641 sid->cb_func.content_min_limit(sid->obj, sid->min_w, sid->min_h);
644 _elm_direction_arrows_eval(sid);
645 return scroll_v_vis_change;
649 _elm_scroll_scroll_bar_visibility_adjust(
650 Elm_Scrollable_Smart_Interface_Data *sid)
654 changed |= _elm_scroll_scroll_bar_h_visibility_adjust(sid);
655 changed |= _elm_scroll_scroll_bar_v_visibility_adjust(sid);
659 _elm_scroll_scroll_bar_h_visibility_adjust(sid);
660 _elm_scroll_scroll_bar_v_visibility_adjust(sid);
665 _elm_scroll_scroll_bar_size_adjust(Elm_Scrollable_Smart_Interface_Data *sid)
667 if (!sid->pan_obj || !sid->edje_obj) return;
669 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
671 if ((sid->content) || (sid->extern_pan))
673 Evas_Coord x, y, w, h, mx = 0, my = 0, vw = 0, vh = 0, px, py,
677 edje_object_part_geometry_get
678 (sid->edje_obj, "elm.swallow.content", NULL, NULL, &vw, &vh);
679 w = sid->content_info.w;
681 size = (double)vw / (double)w;
686 edje_object_part_drag_value_set
687 (sid->edje_obj, "elm.dragable.hbar", 0.0, 0.0);
689 edje_object_part_drag_size_set
690 (sid->edje_obj, "elm.dragable.hbar", size, 1.0);
692 h = sid->content_info.h;
694 size = (double)vh / (double)h;
698 edje_object_part_drag_value_set
699 (sid->edje_obj, "elm.dragable.vbar", 0.0, 0.0);
701 edje_object_part_drag_size_set
702 (sid->edje_obj, "elm.dragable.vbar", 1.0, size);
704 edje_object_part_drag_value_get
705 (sid->edje_obj, "elm.dragable.hbar", &vx, NULL);
706 edje_object_part_drag_value_get
707 (sid->edje_obj, "elm.dragable.vbar", NULL, &vy);
709 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
710 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
714 edje_object_part_drag_step_set
715 (sid->edje_obj, "elm.dragable.hbar", (double)sid->step.x /
717 edje_object_part_drag_step_set
718 (sid->edje_obj, "elm.dragable.vbar", 0.0, (double)sid->step.y /
721 edje_object_part_drag_page_set
722 (sid->edje_obj, "elm.dragable.hbar", (double)sid->page.x /
725 edje_object_part_drag_page_set
726 (sid->edje_obj, "elm.dragable.hbar",
727 -((double)sid->page.x * ((double)vw / (double)w)) / 100.0, 0.0);
729 edje_object_part_drag_page_set
730 (sid->edje_obj, "elm.dragable.vbar", 0.0,
731 (double)sid->page.y / (double)h);
733 edje_object_part_drag_page_set
734 (sid->edje_obj, "elm.dragable.vbar", 0.0,
735 -((double)sid->page.y * ((double)vh / (double)h)) / 100.0);
737 psd->api->pos_get(sid->pan_obj, &px, &py);
738 if (vx != mx) x = px;
739 if (vy != my) y = py;
740 psd->api->pos_set(sid->pan_obj, x, y);
744 Evas_Coord px = 0, py = 0, minx = 0, miny = 0;
746 edje_object_part_drag_size_set
747 (sid->edje_obj, "elm.dragable.vbar", 1.0, 1.0);
748 edje_object_part_drag_size_set
749 (sid->edje_obj, "elm.dragable.hbar", 1.0, 1.0);
750 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
751 psd->api->pos_get(sid->pan_obj, &px, &py);
752 psd->api->pos_set(sid->pan_obj, minx, miny);
753 if ((px != minx) || (py != miny))
754 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
756 _elm_scroll_scroll_bar_visibility_adjust(sid);
760 _elm_scroll_scroll_bar_read_and_update(
761 Elm_Scrollable_Smart_Interface_Data *sid)
763 Evas_Coord x, y, mx = 0, my = 0, px, py, minx = 0, miny = 0;
766 if (!sid->edje_obj || !sid->pan_obj) return;
768 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
770 if ((sid->down.dragged) || (sid->down.bounce_x_animator)
771 || (sid->down.bounce_y_animator) || (sid->down.momentum_animator)
772 || (sid->scrollto.x.animator) || (sid->scrollto.y.animator))
774 edje_object_part_drag_value_get
775 (sid->edje_obj, "elm.dragable.vbar", NULL, &vy);
776 edje_object_part_drag_value_get
777 (sid->edje_obj, "elm.dragable.hbar", &vx, NULL);
778 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
779 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
780 x = _round(vx * (double)mx + minx, 1);
781 y = _round(vy * (double)my + miny, 1);
782 psd->api->pos_get(sid->pan_obj, &px, &py);
783 psd->api->pos_set(sid->pan_obj, x, y);
784 if ((px != x) || (py != y))
786 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
791 _elm_scroll_drag_start(Elm_Scrollable_Smart_Interface_Data *sid)
793 if (sid->cb_func.drag_start)
794 sid->cb_func.drag_start(sid->obj, NULL);
798 _elm_scroll_drag_stop(Elm_Scrollable_Smart_Interface_Data *sid)
800 if (sid->cb_func.drag_stop)
801 sid->cb_func.drag_stop(sid->obj, NULL);
805 _elm_scroll_anim_start(Elm_Scrollable_Smart_Interface_Data *sid)
807 if (sid->cb_func.animate_start)
808 sid->cb_func.animate_start(sid->obj, NULL);
812 _elm_scroll_anim_stop(Elm_Scrollable_Smart_Interface_Data *sid)
814 if (sid->cb_func.animate_stop)
815 sid->cb_func.animate_stop(sid->obj, NULL);
819 _elm_scroll_vbar_drag_cb(void *data,
820 Evas_Object *obj __UNUSED__,
821 const char *emission __UNUSED__,
822 const char *source __UNUSED__)
824 Elm_Scrollable_Smart_Interface_Data *sid = data;
826 if (sid->cb_func.vbar_drag)
827 sid->cb_func.vbar_drag(sid->obj, NULL);
829 _elm_scroll_scroll_bar_read_and_update(sid);
833 _elm_scroll_vbar_press_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_press)
841 sid->cb_func.vbar_press(sid->obj, NULL);
845 _elm_scroll_vbar_unpress_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 if (sid->cb_func.vbar_unpress)
853 sid->cb_func.vbar_unpress(sid->obj, NULL);
857 _elm_scroll_edje_drag_v_start_cb(void *data,
858 Evas_Object *obj __UNUSED__,
859 const char *emission __UNUSED__,
860 const char *source __UNUSED__)
862 Elm_Scrollable_Smart_Interface_Data *sid = data;
864 _elm_scroll_scroll_bar_read_and_update(sid);
865 _elm_scroll_drag_start(sid);
866 sid->freeze = EINA_TRUE;
870 _elm_scroll_edje_drag_v_stop_cb(void *data,
871 Evas_Object *obj __UNUSED__,
872 const char *emission __UNUSED__,
873 const char *source __UNUSED__)
875 Elm_Scrollable_Smart_Interface_Data *sid = data;
877 _elm_scroll_scroll_bar_read_and_update(sid);
878 _elm_scroll_drag_stop(sid);
879 sid->freeze = EINA_FALSE;
883 _elm_scroll_edje_drag_v_cb(void *data,
884 Evas_Object *obj __UNUSED__,
885 const char *emission __UNUSED__,
886 const char *source __UNUSED__)
888 Elm_Scrollable_Smart_Interface_Data *sid = data;
890 _elm_scroll_scroll_bar_read_and_update(sid);
894 _elm_scroll_hbar_drag_cb(void *data,
895 Evas_Object *obj __UNUSED__,
896 const char *emission __UNUSED__,
897 const char *source __UNUSED__)
899 Elm_Scrollable_Smart_Interface_Data *sid = data;
901 if (sid->cb_func.hbar_drag)
902 sid->cb_func.hbar_drag(sid->obj, NULL);
904 _elm_scroll_scroll_bar_read_and_update(sid);
908 _elm_scroll_hbar_press_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_press)
916 sid->cb_func.hbar_press(sid->obj, NULL);
920 _elm_scroll_hbar_unpress_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 if (sid->cb_func.hbar_unpress)
928 sid->cb_func.hbar_unpress(sid->obj, NULL);
932 _elm_scroll_edje_drag_h_start_cb(void *data,
933 Evas_Object *obj __UNUSED__,
934 const char *emission __UNUSED__,
935 const char *source __UNUSED__)
937 Elm_Scrollable_Smart_Interface_Data *sid = data;
939 _elm_scroll_scroll_bar_read_and_update(sid);
940 _elm_scroll_drag_start(sid);
941 sid->freeze = EINA_TRUE;
945 _elm_scroll_edje_drag_h_stop_cb(void *data,
946 Evas_Object *obj __UNUSED__,
947 const char *emission __UNUSED__,
948 const char *source __UNUSED__)
950 Elm_Scrollable_Smart_Interface_Data *sid = data;
952 _elm_scroll_scroll_bar_read_and_update(sid);
953 _elm_scroll_drag_stop(sid);
954 sid->freeze = EINA_FALSE;
958 _elm_scroll_edje_drag_h_cb(void *data,
959 Evas_Object *obj __UNUSED__,
960 const char *emission __UNUSED__,
961 const char *source __UNUSED__)
963 Elm_Scrollable_Smart_Interface_Data *sid = data;
965 _elm_scroll_scroll_bar_read_and_update(sid);
969 _elm_scroll_content_size_get(const Evas_Object *obj,
973 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
975 if (!sid->content) return;
977 evas_object_geometry_get(sid->content, NULL, NULL, w, h);
981 _elm_scroll_content_viewport_size_get(const Evas_Object *obj,
985 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
987 if (!sid->pan_obj || !sid->edje_obj) return;
989 edje_object_calc_force(sid->edje_obj);
990 evas_object_geometry_get(sid->pan_obj, NULL, NULL, w, h);
994 _elm_scroll_content_min_limit(Evas_Object *obj,
998 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1000 if (!sid->edje_obj) return;
1002 if (!sid->cb_func.content_min_limit)
1004 ERR("Content minimim size limiting is unimplemented -- you "
1005 "must provide it yourself\n");
1011 sid->cb_func.content_min_limit(sid->obj, w, h);
1015 _elm_scroll_x_mirrored_get(const Evas_Object *obj,
1018 Evas_Coord cw, ch, w, ret;
1020 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, x);
1022 if (!sid->pan_obj) return 0;
1024 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, 0);
1026 _elm_scroll_content_viewport_size_get(obj, &w, NULL);
1027 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1028 ret = (cw - (x + w));
1030 return (ret >= 0) ? ret : 0;
1033 /* Update the wanted coordinates according to the x, y passed
1034 * widget directionality, content size and etc. */
1036 _elm_scroll_wanted_coordinates_update(Elm_Scrollable_Smart_Interface_Data *sid,
1042 if (!sid->pan_obj) return;
1044 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
1046 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1048 /* Update wx/y/w/h - and if the requested positions aren't legal
1050 _elm_scroll_content_viewport_size_get(sid->obj, &sid->ww, &sid->wh);
1053 else if ((x + sid->ww) > cw)
1054 sid->wx = cw - sid->ww;
1055 else if (sid->is_mirrored)
1056 sid->wx = _elm_scroll_x_mirrored_get(sid->obj, x);
1059 if (y < 0) sid->wy = 0;
1060 else if ((y + sid->wh) > ch)
1061 sid->wy = ch - sid->wh;
1066 _elm_scroll_momentum_end(Elm_Scrollable_Smart_Interface_Data *sid)
1068 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator)) return;
1069 if (sid->down.momentum_animator)
1072 _elm_scroll_content_pos_get(sid->obj, &px, &py);
1073 _elm_scroll_wanted_coordinates_update(sid, px, py);
1075 ecore_animator_del(sid->down.momentum_animator);
1076 sid->down.momentum_animator = NULL;
1077 sid->down.bounce_x_hold = EINA_FALSE;
1078 sid->down.bounce_y_hold = EINA_FALSE;
1085 if (sid->content_info.resized)
1086 _elm_scroll_wanted_region_set(sid->obj);
1091 _elm_scroll_bounce_x_animator(void *data)
1093 Elm_Scrollable_Smart_Interface_Data *sid;
1094 Evas_Coord x, y, dx, w, odx, ed, md;
1095 double t, p, dt, pd, r;
1098 t = ecore_loop_time_get();
1099 dt = t - sid->down.anim_start2;
1102 dt = dt / _elm_config->thumbscroll_bounce_friction;
1103 odx = sid->down.b2x - sid->down.bx;
1104 _elm_scroll_content_viewport_size_get(sid->obj, &w, NULL);
1105 if (!sid->down.momentum_animator && (w > abs(odx)))
1107 pd = (double)odx / (double)w;
1108 pd = (pd > 0) ? pd : -pd;
1109 pd = 1.0 - ((1.0 - pd) * (1.0 - pd));
1112 if (dt > 1.0) dt = 1.0;
1113 p = 1.0 - ((1.0 - dt) * (1.0 - dt));
1114 _elm_scroll_content_pos_get(sid->obj, &x, &y);
1117 if (sid->down.momentum_animator)
1119 ed = abs(sid->down.dx * (_elm_config->thumbscroll_friction +
1120 sid->down.extra_time) - sid->down.b0x);
1121 md = abs(_elm_config->thumbscroll_friction * 5 * w);
1122 if (ed > md) r = (double)(md) / (double)ed;
1124 x = sid->down.b2x + (int)((double)(dx - odx) * r);
1125 if (!sid->down.cancelled)
1126 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
1129 if (sid->down.momentum_animator)
1130 sid->down.bounce_x_hold = EINA_TRUE;
1131 if ((!sid->down.bounce_y_animator) &&
1132 (!sid->scrollto.y.animator))
1133 _elm_scroll_anim_stop(sid);
1134 sid->down.bounce_x_animator = NULL;
1136 sid->bouncemex = EINA_FALSE;
1137 _elm_scroll_momentum_end(sid);
1138 if (sid->content_info.resized)
1139 _elm_scroll_wanted_region_set(sid->obj);
1140 return ECORE_CALLBACK_CANCEL;
1143 return ECORE_CALLBACK_RENEW;
1147 _elm_scroll_bounce_y_animator(void *data)
1149 Elm_Scrollable_Smart_Interface_Data *sid;
1150 Evas_Coord x, y, dy, h, ody, ed, md;
1151 double t, p, dt, pd, r;
1154 t = ecore_loop_time_get();
1155 dt = t - sid->down.anim_start3;
1158 dt = dt / _elm_config->thumbscroll_bounce_friction;
1159 ody = sid->down.b2y - sid->down.by;
1160 _elm_scroll_content_viewport_size_get(sid->obj, NULL, &h);
1161 if (!sid->down.momentum_animator && (h > abs(ody)))
1163 pd = (double)ody / (double)h;
1164 pd = (pd > 0) ? pd : -pd;
1165 pd = 1.0 - ((1.0 - pd) * (1.0 - pd));
1168 if (dt > 1.0) dt = 1.0;
1169 p = 1.0 - ((1.0 - dt) * (1.0 - dt));
1170 _elm_scroll_content_pos_get(sid->obj, &x, &y);
1173 if (sid->down.momentum_animator)
1175 ed = abs(sid->down.dy * (_elm_config->thumbscroll_friction +
1176 sid->down.extra_time) - sid->down.b0y);
1177 md = abs(_elm_config->thumbscroll_friction * 5 * h);
1178 if (ed > md) r = (double)(md) / (double)ed;
1180 y = sid->down.b2y + (int)((double)(dy - ody) * r);
1181 if (!sid->down.cancelled)
1182 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
1185 if (sid->down.momentum_animator)
1186 sid->down.bounce_y_hold = EINA_TRUE;
1187 if ((!sid->down.bounce_x_animator) &&
1188 (!sid->scrollto.y.animator))
1189 _elm_scroll_anim_stop(sid);
1190 sid->down.bounce_y_animator = NULL;
1192 sid->bouncemey = EINA_FALSE;
1193 _elm_scroll_momentum_end(sid);
1194 if (sid->content_info.resized)
1195 _elm_scroll_wanted_region_set(sid->obj);
1196 return ECORE_CALLBACK_CANCEL;
1200 return ECORE_CALLBACK_RENEW;
1204 _elm_scroll_bounce_eval(Elm_Scrollable_Smart_Interface_Data *sid)
1206 Evas_Coord mx, my, px, py, bx, by, b2x, b2y, minx = 0, miny = 0;
1208 if (!sid->pan_obj) return;
1210 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
1212 if (sid->freeze) return;
1213 if ((!sid->bouncemex) && (!sid->bouncemey)) return;
1214 if (sid->down.now) return; // down bounce while still held down
1215 if (sid->down.onhold_animator)
1217 ecore_animator_del(sid->down.onhold_animator);
1218 sid->down.onhold_animator = NULL;
1219 if (sid->content_info.resized)
1220 _elm_scroll_wanted_region_set(sid->obj);
1222 if (sid->down.hold_animator)
1224 ecore_animator_del(sid->down.hold_animator);
1225 sid->down.hold_animator = NULL;
1226 if (sid->content_info.resized)
1227 _elm_scroll_wanted_region_set(sid->obj);
1229 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
1230 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
1231 psd->api->pos_get(sid->pan_obj, &px, &py);
1234 if (px < minx) px = minx;
1235 if ((px - minx) > mx) px = mx + minx;
1236 if (py < miny) py = miny;
1237 if ((py - miny) > my) py = my + miny;
1241 (!elm_widget_drag_child_locked_x_get(sid->obj)))
1243 if ((!sid->down.bounce_x_animator) && (!sid->bounce_animator_disabled))
1247 if (sid->scrollto.x.animator)
1249 ecore_animator_del(sid->scrollto.x.animator);
1250 sid->scrollto.x.animator = NULL;
1252 sid->down.bounce_x_animator =
1253 ecore_animator_add(_elm_scroll_bounce_x_animator, sid);
1254 sid->down.anim_start2 = ecore_loop_time_get();
1257 sid->down.b2x = b2x;
1258 if (sid->down.momentum_animator)
1259 sid->down.b0x = sid->down.ax;
1260 else sid->down.b0x = 0;
1265 (!elm_widget_drag_child_locked_y_get(sid->obj)))
1267 if ((!sid->down.bounce_y_animator) && (!sid->bounce_animator_disabled))
1271 if (sid->scrollto.y.animator)
1273 ecore_animator_del(sid->scrollto.y.animator);
1274 sid->scrollto.y.animator = NULL;
1276 sid->down.bounce_y_animator =
1277 ecore_animator_add(_elm_scroll_bounce_y_animator, sid);
1278 sid->down.anim_start3 = ecore_loop_time_get();
1281 sid->down.b2y = b2y;
1282 if (sid->down.momentum_animator)
1283 sid->down.b0y = sid->down.ay;
1284 else sid->down.b0y = 0;
1291 _elm_scroll_content_pos_get(const Evas_Object *obj,
1295 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1297 if (!sid->pan_obj) return;
1299 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
1301 psd->api->pos_get(sid->pan_obj, x, y);
1305 _elm_scroll_content_pos_set(Evas_Object *obj,
1310 Evas_Coord mx = 0, my = 0, px = 0, py = 0, spx = 0, spy = 0, minx = 0, miny = 0;
1311 Evas_Coord cw =0, ch = 0, ww = 0, wh = 0; //// TIZEN ONLY
1314 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1316 if (!sid->edje_obj || !sid->pan_obj) return;
1318 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
1320 // FIXME: allow for bounce outside of range
1321 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
1322 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
1323 psd->api->content_size_get(sid->pan_obj, &cw, &ch); //// TIZEN ONLY
1324 _elm_scroll_content_viewport_size_get(obj, &ww, &wh); //// TIZEN ONLY
1326 psd->api->pos_get(sid->pan_obj, &px, &py);
1331 edje_object_signal_emit(sid->edje_obj, "elm,edge,left", "elm");
1332 if ((x - minx) > mx)
1333 edje_object_signal_emit(sid->edje_obj, "elm,edge,right", "elm");
1338 edje_object_signal_emit(sid->edje_obj, "elm,edge,top", "elm");
1339 if ((y - miny) > my)
1340 edje_object_signal_emit(sid->edje_obj, "elm,edge,bottom", "elm");
1343 if (!_elm_config->thumbscroll_bounce_enable)
1345 if (x < minx) x = minx;
1346 if ((x - minx) > mx) x = mx + minx;
1347 if (y < miny) y = miny;
1348 if ((y - miny) > my) y = my + miny;
1351 if (!sid->bounce_horiz)
1353 if (x < minx) x = minx;
1354 if ((x - minx) > mx) x = mx + minx;
1356 if (!sid->bounce_vert)
1358 if (y < miny) y = miny;
1359 if (y - miny > my) y = my + miny;
1362 psd->api->pos_set(sid->pan_obj, x, y);
1363 psd->api->pos_get(sid->pan_obj, &spx, &spy);
1365 if (mx > 0) vx = (double)(spx - minx) / (double)mx;
1368 if (vx < 0.0) vx = 0.0;
1372 if (my > 0) vy = (double)(spy - miny) / (double)my;
1375 if (vy < 0.0) vy = 0.0;
1379 edje_object_part_drag_value_set
1380 (sid->edje_obj, "elm.dragable.vbar", 0.0, vy);
1381 edje_object_part_drag_value_set
1382 (sid->edje_obj, "elm.dragable.hbar", vx, 0.0);
1384 if (!sid->down.bounce_x_animator)
1386 if (((x < minx) && (0 <= sid->down.dx)) ||
1387 ((x > (mx + minx)) && (0 >= sid->down.dx)))
1389 sid->bouncemex = EINA_TRUE;
1390 _elm_scroll_bounce_eval(sid);
1393 sid->bouncemex = EINA_FALSE;
1395 if (!sid->down.bounce_y_animator)
1397 if (((y < miny) && (0 <= sid->down.dy)) ||
1398 ((y > (my + miny)) && (0 >= sid->down.dy)))
1400 sid->bouncemey = EINA_TRUE;
1401 _elm_scroll_bounce_eval(sid);
1404 sid->bouncemey = EINA_FALSE;
1409 if ((x != px) || (y != py))
1411 if (sid->cb_func.scroll)
1412 sid->cb_func.scroll(obj, NULL);
1413 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
1416 if (sid->cb_func.scroll_left)
1417 sid->cb_func.scroll_left(obj, NULL);
1418 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,left", "elm");
1422 if (sid->cb_func.scroll_right)
1423 sid->cb_func.scroll_right(obj, NULL);
1424 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,right", "elm");
1428 if (sid->cb_func.scroll_up)
1429 sid->cb_func.scroll_up(obj, NULL);
1430 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,up", "elm");
1434 if (sid->cb_func.scroll_down)
1435 sid->cb_func.scroll_down(obj, NULL);
1436 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,down", "elm");
1443 if (sid->cb_func.edge_left)
1444 sid->cb_func.edge_left(obj, NULL);
1445 edje_object_signal_emit(sid->edje_obj, "elm,edge,left", "elm");
1447 if (x == (mx + minx))
1449 if (sid->cb_func.edge_right)
1450 sid->cb_func.edge_right(obj, NULL);
1451 edje_object_signal_emit(sid->edje_obj, "elm,edge,right", "elm");
1458 if (sid->cb_func.edge_top)
1459 sid->cb_func.edge_top(obj, NULL);
1460 edje_object_signal_emit(sid->edje_obj, "elm,edge,top", "elm");
1464 if (sid->cb_func.edge_bottom)
1465 sid->cb_func.edge_bottom(obj, NULL);
1466 edje_object_signal_emit(sid->edje_obj, "elm,edge,bottom", "elm");
1471 _elm_direction_arrows_eval(sid);
1475 _elm_scroll_mirrored_set(Evas_Object *obj,
1480 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1482 if (!sid->edje_obj) return;
1484 mirrored = !!mirrored;
1486 if (sid->is_mirrored == mirrored)
1489 sid->is_mirrored = mirrored;
1490 edje_object_mirrored_set(sid->edje_obj, mirrored);
1492 if (sid->is_mirrored)
1493 wx = _elm_scroll_x_mirrored_get(sid->obj, sid->wx);
1497 _elm_scroll_content_pos_set(sid->obj, wx, sid->wy, EINA_FALSE);
1500 /* returns TRUE when we need to move the scroller, FALSE otherwise.
1501 * Updates w and h either way, so save them if you need them. */
1503 _elm_scroll_content_region_show_internal(Evas_Object *obj,
1509 Evas_Coord mx = 0, my = 0, cw = 0, ch = 0, px = 0, py = 0, nx, ny,
1510 minx = 0, miny = 0, pw = 0, ph = 0, x = *_x, y = *_y;
1512 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
1514 if (!sid->pan_obj) return EINA_FALSE;
1516 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, EINA_FALSE);
1518 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
1519 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
1520 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1521 psd->api->pos_get(sid->pan_obj, &px, &py);
1522 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &pw, &ph);
1525 if ((x < px) && ((x + w) < (px + (cw - mx)))) nx = x;
1526 else if ((x > px) && ((x + w) > (px + (cw - mx))))
1527 nx = x + w - (cw - mx);
1529 if ((y < py) && ((y + h) < (py + (ch - my)))) ny = y;
1530 else if ((y > py) && ((y + h) > (py + (ch - my))))
1531 ny = y + h - (ch - my);
1533 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
1534 (sid->scrollto.x.animator) || (sid->scrollto.y.animator))
1536 _elm_scroll_anim_stop(sid);
1538 if (sid->scrollto.x.animator)
1540 ecore_animator_del(sid->scrollto.x.animator);
1541 sid->scrollto.x.animator = NULL;
1543 if (sid->scrollto.y.animator)
1545 ecore_animator_del(sid->scrollto.y.animator);
1546 sid->scrollto.y.animator = NULL;
1548 if (sid->down.bounce_x_animator)
1550 ecore_animator_del(sid->down.bounce_x_animator);
1551 sid->down.bounce_x_animator = NULL;
1552 sid->bouncemex = EINA_FALSE;
1553 if (sid->content_info.resized)
1554 _elm_scroll_wanted_region_set(sid->obj);
1556 if (sid->down.bounce_y_animator)
1558 ecore_animator_del(sid->down.bounce_y_animator);
1559 sid->down.bounce_y_animator = NULL;
1560 sid->bouncemey = EINA_FALSE;
1561 if (sid->content_info.resized)
1562 _elm_scroll_wanted_region_set(sid->obj);
1564 if (sid->down.hold_animator)
1566 ecore_animator_del(sid->down.hold_animator);
1567 sid->down.hold_animator = NULL;
1568 _elm_scroll_drag_stop(sid);
1569 if (sid->content_info.resized)
1570 _elm_scroll_wanted_region_set(sid->obj);
1572 if (sid->down.momentum_animator)
1574 ecore_animator_del(sid->down.momentum_animator);
1575 sid->down.momentum_animator = NULL;
1576 sid->down.bounce_x_hold = EINA_FALSE;
1577 sid->down.bounce_y_hold = EINA_FALSE;
1582 if (sid->content_info.resized)
1583 _elm_scroll_wanted_region_set(sid->obj);
1586 if (_paging_is_enabled(sid))
1588 x = _elm_scroll_page_x_get(sid, nx - px, EINA_FALSE);
1589 y = _elm_scroll_page_y_get(sid, ny - py, EINA_FALSE);
1596 if ((x + pw) > cw) x = cw - pw;
1597 if (x < minx) x = minx;
1598 if ((y + ph) > ch) y = ch - ph;
1599 if (y < miny) y = miny;
1601 if ((x == px) && (y == py)) return EINA_FALSE;
1607 /* Set should be used for calculated positions, for example, when we move
1608 * because of an animation or because this is the correct position after
1611 _elm_scroll_content_region_set(Evas_Object *obj,
1617 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1619 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
1621 _elm_scroll_content_pos_set(obj, x, y, EINA_FALSE);
1624 sid->down.x = sid->down.history[0].x;
1625 sid->down.y = sid->down.history[0].y;
1629 /* Set should be used for setting the wanted position, for example a
1630 * user scroll or moving the cursor in an entry. */
1632 _elm_scroll_content_region_show(Evas_Object *obj,
1638 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1644 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
1646 _elm_scroll_content_pos_set(obj, x, y, EINA_TRUE);
1649 sid->down.x = sid->down.history[0].x;
1650 sid->down.y = sid->down.history[0].y;
1655 _elm_scroll_wanted_region_set(Evas_Object *obj)
1657 Evas_Coord ww, wh, wx;
1659 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1663 if (sid->down.now || sid->down.momentum_animator ||
1664 sid->down.bounce_x_animator || sid->down.bounce_y_animator ||
1665 sid->down.hold_animator || sid->down.onhold_animator ||
1666 sid->scrollto.x.animator || sid->scrollto.y.animator)
1669 sid->content_info.resized = EINA_FALSE;
1671 /* Flip to RTL cords only if init in RTL mode */
1672 if (sid->is_mirrored)
1673 wx = _elm_scroll_x_mirrored_get(obj, sid->wx);
1677 _elm_scroll_content_viewport_size_get(obj, &ww, &wh);
1685 _elm_scroll_content_region_set(obj, wx, sid->wy, ww, wh);
1689 _elm_scroll_wheel_event_cb(void *data,
1691 Evas_Object *obj __UNUSED__,
1694 Elm_Scrollable_Smart_Interface_Data *sid;
1695 Evas_Event_Mouse_Wheel *ev;
1696 Evas_Coord x = 0, y = 0, vw = 0, vh = 0, cw = 0, ch = 0;
1700 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
1702 direction = ev->direction;
1703 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1704 if ((evas_key_modifier_is_set(ev->modifiers, "Control")) ||
1705 (evas_key_modifier_is_set(ev->modifiers, "Alt")) ||
1706 (evas_key_modifier_is_set(ev->modifiers, "Meta")) ||
1707 (evas_key_modifier_is_set(ev->modifiers, "Hyper")) ||
1708 (evas_key_modifier_is_set(ev->modifiers, "Super")))
1710 else if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
1711 direction = !direction;
1712 _elm_scroll_content_pos_get(sid->obj, &x, &y);
1713 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
1714 (sid->scrollto.x.animator) || (sid->scrollto.y.animator))
1716 _elm_scroll_anim_stop(sid);
1718 if (sid->scrollto.x.animator)
1720 ecore_animator_del(sid->scrollto.x.animator);
1721 sid->scrollto.x.animator = NULL;
1723 if (sid->scrollto.y.animator)
1725 ecore_animator_del(sid->scrollto.y.animator);
1726 sid->scrollto.y.animator = NULL;
1728 if (sid->down.bounce_x_animator)
1730 ecore_animator_del(sid->down.bounce_x_animator);
1731 sid->down.bounce_x_animator = NULL;
1732 sid->bouncemex = EINA_FALSE;
1733 if (sid->content_info.resized)
1734 _elm_scroll_wanted_region_set(sid->obj);
1736 if (sid->down.bounce_y_animator)
1738 ecore_animator_del(sid->down.bounce_y_animator);
1739 sid->down.bounce_y_animator = NULL;
1740 sid->bouncemey = EINA_FALSE;
1741 if (sid->content_info.resized)
1742 _elm_scroll_wanted_region_set(sid->obj);
1744 _elm_scroll_content_viewport_size_get(sid->obj, &vw, &vh);
1745 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1748 if (ch > vh || cw <= vw)
1749 y += ev->z * sid->step.y;
1751 x += ev->z * sid->step.x;
1753 else if (direction == 1)
1755 if (cw > vw || ch <= vh)
1756 x += ev->z * sid->step.x;
1758 y += ev->z * sid->step.y;
1761 if ((!sid->hold) && (!sid->freeze))
1763 _elm_scroll_wanted_coordinates_update(sid, x, y);
1764 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
1769 _elm_scroll_post_event_up(void *data,
1772 Elm_Scrollable_Smart_Interface_Data *sid = data;
1776 if (sid->down.dragged)
1778 elm_widget_drag_lock_x_set(sid->obj, EINA_FALSE);
1779 elm_widget_drag_lock_y_set(sid->obj, EINA_FALSE);
1786 _paging_is_enabled(Elm_Scrollable_Smart_Interface_Data *sid)
1788 if ((sid->pagerel_h == 0.0) && (!sid->pagesize_h) &&
1789 (sid->pagerel_v == 0.0) && (!sid->pagesize_v))
1795 _elm_scroll_momentum_animator(void *data)
1798 Elm_Scrollable_Smart_Interface_Data *sid = data;
1799 Evas_Coord x, y, dx, dy, px, py, maxx, maxy, minx, miny;
1800 Eina_Bool no_bounce_x_end = EINA_FALSE, no_bounce_y_end = EINA_FALSE;
1802 if (!sid->pan_obj) return ECORE_CALLBACK_CANCEL;
1804 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, ECORE_CALLBACK_CANCEL);
1806 t = ecore_loop_time_get();
1807 dt = t - sid->down.anim_start;
1810 dt = dt / (_elm_config->thumbscroll_friction + sid->down.extra_time);
1811 if (dt > 1.0) dt = 1.0;
1812 p = 1.0 - ((1.0 - dt) * (1.0 - dt));
1813 dx = (sid->down.dx * (_elm_config->thumbscroll_friction +
1814 sid->down.extra_time) * p);
1815 dy = (sid->down.dy * (_elm_config->thumbscroll_friction +
1816 sid->down.extra_time) * p);
1819 x = sid->down.sx - dx;
1820 y = sid->down.sy - dy;
1821 _elm_scroll_content_pos_get(sid->obj, &px, &py);
1822 if ((sid->down.bounce_x_animator) ||
1823 (sid->down.bounce_x_hold))
1825 sid->down.bx = sid->down.bx0 - dx + sid->down.b0x;
1828 if ((sid->down.bounce_y_animator) ||
1829 (sid->down.bounce_y_hold))
1831 sid->down.by = sid->down.by0 - dy + sid->down.b0y;
1834 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
1835 _elm_scroll_wanted_coordinates_update(sid, x, y);
1836 psd->api->pos_max_get(sid->pan_obj, &maxx, &maxy);
1837 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
1838 if (!_elm_config->thumbscroll_bounce_enable || !sid->bounce_horiz)
1840 if (x <= minx) no_bounce_x_end = EINA_TRUE;
1841 if ((x - minx) >= maxx) no_bounce_x_end = EINA_TRUE;
1843 if (!_elm_config->thumbscroll_bounce_enable || !sid->bounce_vert)
1845 if (y <= miny) no_bounce_y_end = EINA_TRUE;
1846 if ((y - miny) >= maxy) no_bounce_y_end = EINA_TRUE;
1849 ((sid->down.bounce_x_hold) && (sid->down.bounce_y_hold)) ||
1850 (no_bounce_x_end && no_bounce_y_end))
1852 _elm_scroll_anim_stop(sid);
1854 sid->down.momentum_animator = NULL;
1855 sid->down.bounce_x_hold = EINA_FALSE;
1856 sid->down.bounce_y_hold = EINA_FALSE;
1861 if (sid->content_info.resized)
1862 _elm_scroll_wanted_region_set(sid->obj);
1864 return ECORE_CALLBACK_CANCEL;
1868 return ECORE_CALLBACK_RENEW;
1872 _elm_scroll_page_x_get(Elm_Scrollable_Smart_Interface_Data *sid,
1873 int offset, Eina_Bool limit)
1875 Evas_Coord x, y, w, h, dx, cw, ch, minx = 0;
1877 if (!sid->pan_obj) return 0;
1879 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, 0);
1881 _elm_scroll_content_pos_get(sid->obj, &x, &y);
1882 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
1883 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1884 psd->api->pos_min_get(sid->pan_obj, &minx, NULL);
1886 if (sid->pagerel_h > 0.0)
1887 sid->pagesize_h = w * sid->pagerel_h;
1893 dx = (sid->pagesize_h * ((double)sid->page_limit_h - 0.5));
1896 x += (abs(offset) < dx ? offset : dx);
1898 x += (abs(offset) < dx ? offset : -dx);
1901 if (sid->pagesize_h > 0)
1903 x = x + (sid->pagesize_h * 0.5);
1904 x = x / (sid->pagesize_h);
1905 x = x * (sid->pagesize_h);
1907 if ((x + w) > cw) x = cw - w;
1908 if (x < minx) x = minx;
1914 _elm_scroll_page_y_get(Elm_Scrollable_Smart_Interface_Data *sid,
1915 int offset, Eina_Bool limit)
1917 Evas_Coord x, y, w, h, dy, cw, ch, miny = 0;
1919 if (!sid->pan_obj) return 0;
1921 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, 0);
1923 _elm_scroll_content_pos_get(sid->obj, &x, &y);
1924 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
1925 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1926 psd->api->pos_min_get(sid->pan_obj, NULL, &miny);
1928 if (sid->pagerel_v > 0.0)
1929 sid->pagesize_v = h * sid->pagerel_v;
1935 dy = (sid->pagesize_v * ((double)sid->page_limit_v - 0.5));
1938 y += (abs(offset) < dy ? offset : dy);
1940 y += (abs(offset) < dy ? offset : -dy);
1943 if (sid->pagesize_v > 0)
1945 y = y + (sid->pagesize_v * 0.5);
1946 y = y / (sid->pagesize_v);
1947 y = y * (sid->pagesize_v);
1949 if ((y + h) > ch) y = ch - h;
1950 if (y < miny) y = miny;
1956 _elm_scroll_scroll_to_x_animator(void *data)
1958 Elm_Scrollable_Smart_Interface_Data *sid = data;
1962 if (!sid->pan_obj) return ECORE_CALLBACK_CANCEL;
1964 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, ECORE_CALLBACK_CANCEL);
1966 t = ecore_loop_time_get();
1967 tt = (t - sid->scrollto.x.t_start) /
1968 (sid->scrollto.x.t_end - sid->scrollto.x.t_start);
1970 tt = 1.0 - (tt * tt);
1971 psd->api->pos_get(sid->pan_obj, &px, &py);
1972 px = (sid->scrollto.x.start * (1.0 - tt)) +
1973 (sid->scrollto.x.end * tt);
1974 if (t >= sid->scrollto.x.t_end)
1976 px = sid->scrollto.x.end;
1977 _elm_scroll_content_pos_set(sid->obj, px, py, EINA_TRUE);
1979 sid->down.x = sid->down.history[0].x;
1980 _elm_scroll_wanted_coordinates_update(sid, px, py);
1981 sid->scrollto.x.animator = NULL;
1982 if ((!sid->scrollto.y.animator) && (!sid->down.bounce_y_animator))
1983 _elm_scroll_anim_stop(sid);
1984 return ECORE_CALLBACK_CANCEL;
1986 _elm_scroll_content_pos_set(sid->obj, px, py, EINA_TRUE);
1987 _elm_scroll_wanted_coordinates_update(sid, px, py);
1988 return ECORE_CALLBACK_RENEW;
1992 _elm_scroll_scroll_to_y_animator(void *data)
1994 Elm_Scrollable_Smart_Interface_Data *sid = data;
1998 if (!sid->pan_obj) return EINA_FALSE;
2000 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, EINA_FALSE);
2002 t = ecore_loop_time_get();
2003 tt = (t - sid->scrollto.y.t_start) /
2004 (sid->scrollto.y.t_end - sid->scrollto.y.t_start);
2006 tt = 1.0 - (tt * tt);
2007 psd->api->pos_get(sid->pan_obj, &px, &py);
2008 py = (sid->scrollto.y.start * (1.0 - tt)) +
2009 (sid->scrollto.y.end * tt);
2010 if (t >= sid->scrollto.y.t_end)
2012 py = sid->scrollto.y.end;
2013 _elm_scroll_content_pos_set(sid->obj, px, py, EINA_TRUE);
2015 sid->down.y = sid->down.history[0].y;
2016 _elm_scroll_wanted_coordinates_update(sid, px, py);
2017 sid->scrollto.y.animator = NULL;
2018 if ((!sid->scrollto.x.animator) && (!sid->down.bounce_x_animator))
2019 _elm_scroll_anim_stop(sid);
2020 return ECORE_CALLBACK_CANCEL;
2022 _elm_scroll_content_pos_set(sid->obj, px, py, EINA_TRUE);
2023 _elm_scroll_wanted_coordinates_update(sid, px, py);
2025 return ECORE_CALLBACK_RENEW;
2029 _elm_scroll_scroll_to_y(Elm_Scrollable_Smart_Interface_Data *sid,
2033 Evas_Coord px, py, x, y, w, h;
2036 if (!sid->pan_obj) return;
2038 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2040 if (sid->freeze) return;
2043 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2044 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
2046 _elm_scroll_content_region_set(sid->obj, x, y, w, h);
2049 t = ecore_loop_time_get();
2050 psd->api->pos_get(sid->pan_obj, &px, &py);
2051 sid->scrollto.y.start = py;
2052 sid->scrollto.y.end = pos_y;
2053 sid->scrollto.y.t_start = t;
2054 sid->scrollto.y.t_end = t + t_in;
2055 if (!sid->scrollto.y.animator)
2057 sid->scrollto.y.animator =
2058 ecore_animator_add(_elm_scroll_scroll_to_y_animator, sid);
2059 if (!sid->scrollto.x.animator)
2060 _elm_scroll_anim_start(sid);
2062 if (sid->down.bounce_y_animator)
2064 ecore_animator_del(sid->down.bounce_y_animator);
2065 sid->down.bounce_y_animator = NULL;
2066 _elm_scroll_momentum_end(sid);
2067 if (sid->content_info.resized)
2068 _elm_scroll_wanted_region_set(sid->obj);
2070 sid->bouncemey = EINA_FALSE;
2074 _elm_scroll_scroll_to_x(Elm_Scrollable_Smart_Interface_Data *sid,
2078 Evas_Coord px, py, x, y, w, h;
2081 if (!sid->pan_obj) return;
2083 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2085 if (sid->freeze) return;
2088 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2089 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
2091 _elm_scroll_content_region_set(sid->obj, x, y, w, h);
2094 t = ecore_loop_time_get();
2095 psd->api->pos_get(sid->pan_obj, &px, &py);
2096 sid->scrollto.x.start = px;
2097 sid->scrollto.x.end = pos_x;
2098 sid->scrollto.x.t_start = t;
2099 sid->scrollto.x.t_end = t + t_in;
2100 if (!sid->scrollto.x.animator)
2102 sid->scrollto.x.animator =
2103 ecore_animator_add(_elm_scroll_scroll_to_x_animator, sid);
2104 if (!sid->scrollto.y.animator)
2105 _elm_scroll_anim_start(sid);
2107 if (sid->down.bounce_x_animator)
2109 ecore_animator_del(sid->down.bounce_x_animator);
2110 sid->down.bounce_x_animator = NULL;
2111 _elm_scroll_momentum_end(sid);
2112 if (sid->content_info.resized)
2113 _elm_scroll_wanted_region_set(sid->obj);
2115 sid->bouncemex = EINA_FALSE;
2119 _elm_scroll_mouse_up_event_cb(void *data,
2121 Evas_Object *obj __UNUSED__,
2124 Elm_Scrollable_Smart_Interface_Data *sid = data;
2125 Evas_Coord x = 0, y = 0, ox = 0, oy = 0;
2126 Evas_Event_Mouse_Down *ev;
2128 if (!sid->pan_obj) return;
2130 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2133 sid->down.hold_parent = EINA_FALSE;
2136 evas_post_event_callback_push(e, _elm_scroll_post_event_up, sid);
2138 // FIXME: respect elm_widget_scroll_hold_get of parent container
2139 if (!_elm_config->thumbscroll_enable) return;
2141 if (ev->button == 1)
2143 if (sid->down.onhold_animator)
2145 ecore_animator_del(sid->down.onhold_animator);
2146 sid->down.onhold_animator = NULL;
2147 if (sid->content_info.resized)
2148 _elm_scroll_wanted_region_set(sid->obj);
2150 x = ev->canvas.x - sid->down.x;
2151 y = ev->canvas.y - sid->down.y;
2152 if (sid->down.dragged)
2154 _elm_scroll_drag_stop(sid);
2155 if ((!sid->hold) && (!sid->freeze))
2159 Evas_Coord ax, ay, dx, dy, vel;
2162 t = ev->timestamp / 1000.0;
2164 t = ecore_loop_time_get();
2167 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2172 DBG("------ %i %i\n", ev->canvas.x, ev->canvas.y);
2174 for (i = 0; i < 60; i++)
2176 dt = t - sid->down.history[i].timestamp;
2177 if (dt > 0.2) break;
2179 DBG("H: %i %i @ %1.3f\n",
2180 sid->down.history[i].x,
2181 sid->down.history[i].y, dt);
2184 ax += sid->down.history[i].x;
2185 ay += sid->down.history[i].y;
2190 at /= _elm_config->thumbscroll_sensitivity_friction;
2191 dx = ev->canvas.x - ax;
2192 dy = ev->canvas.y - ay;
2195 vel = sqrt((dx * dx) + (dy * dy)) / at;
2196 if ((_elm_config->thumbscroll_friction > 0.0) &&
2197 (vel > _elm_config->thumbscroll_momentum_threshold))
2199 sid->down.dx = ((double)dx / at);
2200 sid->down.dy = ((double)dy / at);
2201 sid->down.extra_time = 0.0;
2202 sid->down.pdx = sid->down.dx;
2203 sid->down.pdy = sid->down.dy;
2206 if (!_paging_is_enabled(sid))
2208 if ((!sid->down.momentum_animator) &&
2209 (!sid->momentum_animator_disabled) &&
2211 (!elm_widget_drag_child_locked_y_get
2214 sid->down.momentum_animator =
2216 (_elm_scroll_momentum_animator, sid);
2218 EVAS_EVENT_FLAG_ON_SCROLL;
2219 _elm_scroll_anim_start(sid);
2221 sid->down.anim_start = ecore_loop_time_get();
2222 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2236 evas_event_feed_hold(e, 0, ev->timestamp, ev->data);
2237 if (_paging_is_enabled(sid))
2239 Evas_Coord pgx, pgy;
2241 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2243 (!elm_widget_drag_child_locked_x_get
2246 pgx = _elm_scroll_page_x_get(sid, ox, EINA_TRUE);
2249 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2250 _elm_scroll_scroll_to_x
2251 (sid, _elm_config->page_scroll_friction, pgx);
2255 (!elm_widget_drag_child_locked_y_get
2258 pgy = _elm_scroll_page_y_get(sid, oy, EINA_TRUE);
2261 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2262 _elm_scroll_scroll_to_y
2263 (sid, _elm_config->page_scroll_friction, pgy);
2272 if (_paging_is_enabled(sid))
2274 Evas_Coord pgx, pgy;
2276 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2278 (!elm_widget_drag_child_locked_x_get
2281 pgx = _elm_scroll_page_x_get(sid, ox, EINA_TRUE);
2283 _elm_scroll_scroll_to_x
2284 (sid, _elm_config->page_scroll_friction, pgx);
2287 (!elm_widget_drag_child_locked_y_get
2290 pgy = _elm_scroll_page_y_get(sid, oy, EINA_TRUE);
2292 _elm_scroll_scroll_to_y
2293 (sid, _elm_config->page_scroll_friction, pgy);
2297 if (sid->down.hold_animator)
2299 ecore_animator_del(sid->down.hold_animator);
2300 sid->down.hold_animator = NULL;
2301 if (sid->content_info.resized)
2302 _elm_scroll_wanted_region_set(sid->obj);
2304 if (sid->down.scroll)
2306 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2307 sid->down.scroll = EINA_FALSE;
2311 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2312 sid->down.hold = EINA_FALSE;
2314 sid->down.dragged_began = EINA_FALSE;
2315 sid->down.dir_x = EINA_FALSE;
2316 sid->down.dir_y = EINA_FALSE;
2317 sid->down.want_dragged = EINA_FALSE;
2318 sid->down.dragged = EINA_FALSE;
2319 sid->down.now = EINA_FALSE;
2320 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2321 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
2322 _elm_scroll_wanted_coordinates_update(sid, x, y);
2324 if (sid->content_info.resized)
2325 _elm_scroll_wanted_region_set(sid->obj);
2327 if (!_paging_is_enabled(sid))
2328 _elm_scroll_bounce_eval(sid);
2333 _elm_scroll_mouse_down_event_cb(void *data,
2335 Evas_Object *obj __UNUSED__,
2338 Elm_Scrollable_Smart_Interface_Data *sid;
2339 Evas_Event_Mouse_Down *ev;
2340 Evas_Coord x = 0, y = 0;
2345 if (_elm_config->thumbscroll_enable)
2347 sid->down.hold = EINA_FALSE;
2348 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
2349 (sid->down.momentum_animator) || (sid->scrollto.x.animator) ||
2350 (sid->scrollto.y.animator))
2352 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL |
2353 EVAS_EVENT_FLAG_ON_HOLD;
2354 sid->down.scroll = EINA_TRUE;
2355 sid->down.hold = EINA_TRUE;
2356 _elm_scroll_anim_stop(sid);
2358 if (sid->scrollto.x.animator)
2360 ecore_animator_del(sid->scrollto.x.animator);
2361 sid->scrollto.x.animator = NULL;
2363 if (sid->scrollto.y.animator)
2365 ecore_animator_del(sid->scrollto.y.animator);
2366 sid->scrollto.y.animator = NULL;
2368 if (sid->down.bounce_x_animator)
2370 ecore_animator_del(sid->down.bounce_x_animator);
2371 sid->down.bounce_x_animator = NULL;
2372 sid->bouncemex = EINA_FALSE;
2373 if (sid->content_info.resized)
2374 _elm_scroll_wanted_region_set(sid->obj);
2376 if (sid->down.bounce_y_animator)
2378 ecore_animator_del(sid->down.bounce_y_animator);
2379 sid->down.bounce_y_animator = NULL;
2380 sid->bouncemey = EINA_FALSE;
2381 if (sid->content_info.resized)
2382 _elm_scroll_wanted_region_set(sid->obj);
2384 if (sid->down.hold_animator)
2386 ecore_animator_del(sid->down.hold_animator);
2387 sid->down.hold_animator = NULL;
2388 _elm_scroll_drag_stop(sid);
2389 if (sid->content_info.resized)
2390 _elm_scroll_wanted_region_set(sid->obj);
2392 if (sid->down.momentum_animator)
2394 ecore_animator_del(sid->down.momentum_animator);
2395 sid->down.momentum_animator = NULL;
2396 sid->down.bounce_x_hold = EINA_FALSE;
2397 sid->down.bounce_y_hold = EINA_FALSE;
2400 if (sid->content_info.resized)
2401 _elm_scroll_wanted_region_set(sid->obj);
2403 if (ev->button == 1)
2405 sid->down.hist.est_timestamp_diff =
2406 ecore_loop_time_get() - ((double)ev->timestamp / 1000.0);
2407 sid->down.hist.tadd = 0.0;
2408 sid->down.hist.dxsum = 0.0;
2409 sid->down.hist.dysum = 0.0;
2410 sid->down.now = EINA_TRUE;
2411 sid->down.dragged = EINA_FALSE;
2412 sid->down.dir_x = EINA_FALSE;
2413 sid->down.dir_y = EINA_FALSE;
2414 sid->down.x = ev->canvas.x;
2415 sid->down.y = ev->canvas.y;
2416 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2419 sid->down.locked = EINA_FALSE;
2420 memset(&(sid->down.history[0]), 0,
2421 sizeof(sid->down.history[0]) * 60);
2423 sid->down.history[0].timestamp = ev->timestamp / 1000.0;
2424 sid->down.history[0].localtimestamp = ecore_loop_time_get();
2426 sid->down.history[0].timestamp = ecore_loop_time_get();
2428 sid->down.history[0].x = ev->canvas.x;
2429 sid->down.history[0].y = ev->canvas.y;
2431 sid->down.dragged_began = EINA_FALSE;
2432 sid->down.hold_parent = EINA_FALSE;
2433 sid->down.cancelled = EINA_FALSE;
2434 if (sid->hold || sid->freeze)
2435 sid->down.want_reset = EINA_TRUE;
2437 sid->down.want_reset = EINA_FALSE;
2442 _elm_scroll_can_scroll(Elm_Scrollable_Smart_Interface_Data *sid,
2445 Evas_Coord mx = 0, my = 0, px = 0, py = 0, minx = 0, miny = 0;
2447 if (!sid->pan_obj) return EINA_FALSE;
2449 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, EINA_FALSE);
2451 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
2452 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
2453 psd->api->pos_get(sid->pan_obj, &px, &py);
2457 if (px > minx) return EINA_TRUE;
2461 if ((px - minx) < mx) return EINA_TRUE;
2465 if (py > miny) return EINA_TRUE;
2469 if ((py - miny) < my) return EINA_TRUE;
2479 _elm_scroll_post_event_move(void *data,
2482 Elm_Scrollable_Smart_Interface_Data *sid = data;
2484 if (sid->down.want_dragged)
2488 if (sid->down.hold_parent)
2490 if ((sid->down.dir_x) &&
2491 !_elm_scroll_can_scroll(sid, sid->down.hdir))
2493 sid->down.dir_x = EINA_FALSE;
2495 if ((sid->down.dir_y) &&
2496 !_elm_scroll_can_scroll(sid, sid->down.vdir))
2498 sid->down.dir_y = EINA_FALSE;
2501 if (sid->down.dir_x)
2504 (!elm_widget_drag_child_locked_x_get(sid->obj)))
2506 sid->down.want_dragged = EINA_FALSE;
2507 sid->down.dragged = EINA_TRUE;
2510 elm_widget_drag_lock_x_set(sid->obj, 1);
2515 sid->down.dir_x = EINA_FALSE;
2517 if (sid->down.dir_y)
2520 (!elm_widget_drag_child_locked_y_get(sid->obj)))
2522 sid->down.want_dragged = EINA_FALSE;
2523 sid->down.dragged = EINA_TRUE;
2526 elm_widget_drag_lock_y_set
2527 (sid->obj, EINA_TRUE);
2532 sid->down.dir_y = EINA_FALSE;
2534 if ((!sid->down.dir_x) && (!sid->down.dir_y))
2536 sid->down.cancelled = EINA_TRUE;
2538 if (start) _elm_scroll_drag_start(sid);
2545 _elm_scroll_down_coord_eval(Elm_Scrollable_Smart_Interface_Data *sid,
2549 Evas_Coord minx, miny;
2551 if (!sid->pan_obj) return;
2553 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2555 if (sid->down.dir_x) *x = sid->down.sx - (*x - sid->down.x);
2556 else *x = sid->down.sx;
2557 if (sid->down.dir_y) *y = sid->down.sy - (*y - sid->down.y);
2558 else *y = sid->down.sy;
2560 if ((sid->down.dir_x) || (sid->down.dir_y))
2562 if (!((sid->down.dir_x) && (sid->down.dir_y)))
2564 if (sid->down.dir_x) *y = sid->down.locked_y;
2565 else *x = sid->down.locked_x;
2569 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
2572 *x += (minx - *x) * _elm_config->thumbscroll_border_friction;
2573 else if (sid->content_info.w <= sid->w)
2574 *x += (sid->down.sx - *x) * _elm_config->thumbscroll_border_friction;
2575 else if ((sid->content_info.w - sid->w + minx) < *x)
2576 *x += (sid->content_info.w - sid->w + minx - *x) *
2577 _elm_config->thumbscroll_border_friction;
2580 *y += (miny - *y) * _elm_config->thumbscroll_border_friction;
2581 else if (sid->content_info.h <= sid->h)
2582 *y += (sid->down.sy - *y) * _elm_config->thumbscroll_border_friction;
2583 else if ((sid->content_info.h - sid->h + miny) < *y)
2584 *y += (sid->content_info.h - sid->h + miny - *y) *
2585 _elm_config->thumbscroll_border_friction;
2589 _elm_scroll_hold_animator(void *data)
2591 Elm_Scrollable_Smart_Interface_Data *sid = data;
2592 Evas_Coord ox = 0, oy = 0, fx = 0, fy = 0;
2594 fx = sid->down.hold_x;
2595 fy = sid->down.hold_y;
2597 _elm_scroll_content_pos_get(sid->obj, &ox, &oy);
2598 if (sid->down.dir_x)
2601 (!elm_widget_drag_child_locked_x_get(sid->obj)))
2604 if (sid->down.dir_y)
2607 (!elm_widget_drag_child_locked_y_get(sid->obj)))
2611 _elm_scroll_content_pos_set(sid->obj, ox, oy, EINA_TRUE);
2613 return ECORE_CALLBACK_RENEW;
2617 _elm_scroll_on_hold_animator(void *data)
2621 Evas_Coord x, y, ox, oy;
2622 Elm_Scrollable_Smart_Interface_Data *sid;
2625 t = ecore_loop_time_get();
2626 if (sid->down.onhold_tlast > 0.0)
2628 td = t - sid->down.onhold_tlast;
2629 vx = sid->down.onhold_vx * td *
2630 (double)_elm_config->thumbscroll_hold_threshold * 2.0;
2631 vy = sid->down.onhold_vy * td *
2632 (double)_elm_config->thumbscroll_hold_threshold * 2.0;
2633 _elm_scroll_content_pos_get(sid->obj, &ox, &oy);
2637 if (sid->down.dir_x)
2640 (!elm_widget_drag_child_locked_x_get(sid->obj)))
2642 sid->down.onhold_vxe += vx;
2643 x = ox + (int)sid->down.onhold_vxe;
2644 sid->down.onhold_vxe -= (int)sid->down.onhold_vxe;
2648 if (sid->down.dir_y)
2651 (!elm_widget_drag_child_locked_y_get(sid->obj)))
2653 sid->down.onhold_vye += vy;
2654 y = oy + (int)sid->down.onhold_vye;
2655 sid->down.onhold_vye -= (int)sid->down.onhold_vye;
2659 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
2661 sid->down.onhold_tlast = t;
2663 return ECORE_CALLBACK_RENEW;
2667 _elm_scroll_mouse_move_event_cb(void *data,
2669 Evas_Object *obj __UNUSED__,
2672 Elm_Scrollable_Smart_Interface_Data *sid = data;
2673 Evas_Event_Mouse_Move *ev;
2674 Evas_Coord x = 0, y = 0;
2676 if (!sid->pan_obj) return;
2678 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2681 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
2682 sid->down.hold_parent = EINA_TRUE;
2683 evas_post_event_callback_push(e, _elm_scroll_post_event_move, sid);
2685 // FIXME: respect elm_widget_scroll_hold_get of parent container
2686 if (_elm_config->thumbscroll_enable)
2690 if ((sid->scrollto.x.animator) && (!sid->hold) && (!sid->freeze))
2693 ecore_animator_del(sid->scrollto.x.animator);
2694 sid->scrollto.x.animator = NULL;
2695 psd->api->pos_get(sid->pan_obj, &px, NULL);
2697 sid->down.x = sid->down.history[0].x;
2700 if ((sid->scrollto.y.animator) && (!sid->hold) && (!sid->freeze))
2703 ecore_animator_del(sid->scrollto.y.animator);
2704 sid->scrollto.y.animator = NULL;
2705 psd->api->pos_get(sid->pan_obj, NULL, &py);
2707 sid->down.y = sid->down.history[0].y;
2711 DBG("::: %i %i\n", ev->cur.canvas.x, ev->cur.canvas.y);
2713 memmove(&(sid->down.history[1]), &(sid->down.history[0]),
2714 sizeof(sid->down.history[0]) * (60 - 1));
2716 sid->down.history[0].timestamp = ev->timestamp / 1000.0;
2717 sid->down.history[0].localtimestamp = ecore_loop_time_get();
2719 sid->down.history[0].timestamp = ecore_loop_time_get();
2721 sid->down.history[0].x = ev->cur.canvas.x;
2722 sid->down.history[0].y = ev->cur.canvas.y;
2724 if (!sid->down.dragged_began)
2726 x = ev->cur.canvas.x - sid->down.x;
2727 y = ev->cur.canvas.y - sid->down.y;
2729 sid->down.hdir = -1;
2730 sid->down.vdir = -1;
2732 if (x > 0) sid->down.hdir = LEFT;
2734 sid->down.hdir = RIGHT;
2735 if (y > 0) sid->down.vdir = UP;
2737 sid->down.vdir = DOWN;
2742 if (sid->one_direction_at_a_time)
2744 if (!((sid->down.dir_x) || (sid->down.dir_y)) &&
2745 (((x * x) + (y * y)) >
2746 (_elm_config->thumbscroll_threshold *
2747 _elm_config->thumbscroll_threshold)))
2749 if (sid->one_direction_at_a_time ==
2750 ELM_SCROLLER_SINGLE_DIRECTION_SOFT)
2755 sid->down.dir_x = EINA_TRUE;
2756 sid->down.dir_y = EINA_FALSE;
2761 sid->down.dir_x = EINA_FALSE;
2762 sid->down.dir_y = EINA_TRUE;
2767 sid->down.dir_x = EINA_TRUE;
2768 sid->down.dir_y = EINA_TRUE;
2771 else if (sid->one_direction_at_a_time ==
2772 ELM_SCROLLER_SINGLE_DIRECTION_HARD)
2776 sid->down.dir_x = EINA_TRUE;
2777 sid->down.dir_y = EINA_FALSE;
2781 sid->down.dir_x = EINA_FALSE;
2782 sid->down.dir_y = EINA_TRUE;
2789 sid->down.dir_x = EINA_TRUE;
2790 sid->down.dir_y = EINA_TRUE;
2793 if ((!sid->hold) && (!sid->freeze))
2795 if ((sid->down.dragged) ||
2796 (((x * x) + (y * y)) >
2797 (_elm_config->thumbscroll_threshold *
2798 _elm_config->thumbscroll_threshold)))
2800 sid->down.dragged_began = EINA_TRUE;
2801 if (!sid->down.dragged)
2803 sid->down.want_dragged = EINA_TRUE;
2804 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2806 if (sid->down.dragged)
2808 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2810 if (sid->down.dir_x)
2811 x = sid->down.sx - (ev->cur.canvas.x - sid->down.x);
2814 if (sid->down.dir_y)
2815 y = sid->down.sy - (ev->cur.canvas.y - sid->down.y);
2818 if (sid->down.want_reset)
2820 sid->down.x = ev->cur.canvas.x;
2821 sid->down.y = ev->cur.canvas.y;
2822 sid->down.want_reset = EINA_FALSE;
2824 if ((sid->down.dir_x) || (sid->down.dir_y))
2826 if (!sid->down.locked)
2828 sid->down.locked_x = x;
2829 sid->down.locked_y = y;
2830 sid->down.locked = EINA_TRUE;
2832 if (!((sid->down.dir_x) && (sid->down.dir_y)))
2834 if (sid->down.dir_x) y = sid->down.locked_y;
2835 else x = sid->down.locked_x;
2839 Evas_Coord minx, miny, mx, my;
2841 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
2842 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
2845 _elm_config->thumbscroll_border_friction;
2847 y += (sid->down.sy - y) *
2848 _elm_config->thumbscroll_border_friction;
2849 else if ((my + miny) < y)
2850 y += (my + miny - y) *
2851 _elm_config->thumbscroll_border_friction;
2854 _elm_config->thumbscroll_border_friction;
2856 x += (sid->down.sx - x) *
2857 _elm_config->thumbscroll_border_friction;
2858 else if ((mx + minx) < x)
2859 x += (mx + minx - x) *
2860 _elm_config->thumbscroll_border_friction;
2863 sid->down.hold_x = x;
2864 sid->down.hold_y = y;
2865 if (!sid->down.hold_animator)
2866 sid->down.hold_animator =
2867 ecore_animator_add(_elm_scroll_hold_animator, sid);
2871 if (sid->down.dragged_began)
2873 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2874 if (!sid->down.hold)
2876 sid->down.hold = EINA_TRUE;
2877 evas_event_feed_hold
2878 (e, 1, ev->timestamp, ev->data);
2883 else if (!sid->freeze)
2885 double vx = 0.0, vy = 0.0;
2887 x = ev->cur.canvas.x - sid->x;
2888 y = ev->cur.canvas.y - sid->y;
2889 if (x < _elm_config->thumbscroll_hold_threshold)
2891 if (_elm_config->thumbscroll_hold_threshold > 0.0)
2892 vx = -(double)(_elm_config->thumbscroll_hold_threshold - x)
2893 / _elm_config->thumbscroll_hold_threshold;
2897 else if (x > (sid->w - _elm_config->thumbscroll_hold_threshold))
2899 if (_elm_config->thumbscroll_hold_threshold > 0.0)
2900 vx = (double)(_elm_config->thumbscroll_hold_threshold -
2902 _elm_config->thumbscroll_hold_threshold;
2906 if (y < _elm_config->thumbscroll_hold_threshold)
2908 if (_elm_config->thumbscroll_hold_threshold > 0.0)
2909 vy = -(double)(_elm_config->thumbscroll_hold_threshold - y)
2910 / _elm_config->thumbscroll_hold_threshold;
2914 else if (y > (sid->h - _elm_config->thumbscroll_hold_threshold))
2916 if (_elm_config->thumbscroll_hold_threshold > 0.0)
2917 vy = (double)(_elm_config->thumbscroll_hold_threshold -
2919 _elm_config->thumbscroll_hold_threshold;
2923 if ((vx != 0.0) || (vy != 0.0))
2925 sid->down.onhold_vx = vx;
2926 sid->down.onhold_vy = vy;
2927 if (!sid->down.onhold_animator)
2929 sid->down.onhold_vxe = 0.0;
2930 sid->down.onhold_vye = 0.0;
2931 sid->down.onhold_tlast = 0.0;
2932 sid->down.onhold_animator = ecore_animator_add
2933 (_elm_scroll_on_hold_animator, sid);
2938 if (sid->down.onhold_animator)
2940 ecore_animator_del(sid->down.onhold_animator);
2941 sid->down.onhold_animator = NULL;
2942 if (sid->content_info.resized)
2943 _elm_scroll_wanted_region_set(sid->obj);
2952 _elm_scroll_page_adjust(Elm_Scrollable_Smart_Interface_Data *sid)
2954 Evas_Coord x, y, w, h;
2956 if (!_paging_is_enabled(sid)) return;
2958 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
2960 x = _elm_scroll_page_x_get(sid, 0, EINA_TRUE);
2961 y = _elm_scroll_page_y_get(sid, 0, EINA_TRUE);
2963 _elm_scroll_content_region_set(sid->obj, x, y, w, h);
2967 _elm_scroll_reconfigure(Elm_Scrollable_Smart_Interface_Data *sid)
2969 _elm_scroll_scroll_bar_size_adjust(sid);
2970 _elm_scroll_page_adjust(sid);
2974 _on_edje_move(void *data,
2976 Evas_Object *edje_obj,
2977 void *event_info __UNUSED__)
2979 Elm_Scrollable_Smart_Interface_Data *sid = data;
2982 evas_object_geometry_get(edje_obj, &x, &y, NULL, NULL);
2987 _elm_scroll_reconfigure(sid);
2991 _on_edje_resize(void *data,
2993 Evas_Object *edje_obj,
2994 void *event_info __UNUSED__)
2996 Elm_Scrollable_Smart_Interface_Data *sid = data;
2999 evas_object_geometry_get(edje_obj, NULL, NULL, &w, &h);
3004 _elm_scroll_reconfigure(sid);
3005 _elm_scroll_wanted_region_set(sid->obj);
3009 _scroll_edje_object_attach(Evas_Object *obj)
3011 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3013 evas_object_event_callback_add
3014 (sid->edje_obj, EVAS_CALLBACK_RESIZE, _on_edje_resize, sid);
3015 evas_object_event_callback_add
3016 (sid->edje_obj, EVAS_CALLBACK_MOVE, _on_edje_move, sid);
3018 edje_object_signal_callback_add
3019 (sid->edje_obj, "drag", "elm.dragable.vbar", _elm_scroll_vbar_drag_cb,
3021 edje_object_signal_callback_add
3022 (sid->edje_obj, "drag,set", "elm.dragable.vbar",
3023 _elm_scroll_edje_drag_v_cb, sid);
3024 edje_object_signal_callback_add
3025 (sid->edje_obj, "drag,start", "elm.dragable.vbar",
3026 _elm_scroll_edje_drag_v_start_cb, sid);
3027 edje_object_signal_callback_add
3028 (sid->edje_obj, "drag,stop", "elm.dragable.vbar",
3029 _elm_scroll_edje_drag_v_stop_cb, sid);
3030 edje_object_signal_callback_add
3031 (sid->edje_obj, "drag,step", "elm.dragable.vbar",
3032 _elm_scroll_edje_drag_v_cb, sid);
3033 edje_object_signal_callback_add
3034 (sid->edje_obj, "drag,page", "elm.dragable.vbar",
3035 _elm_scroll_edje_drag_v_cb, sid);
3036 edje_object_signal_callback_add
3037 (sid->edje_obj, "elm,vbar,press", "elm",
3038 _elm_scroll_vbar_press_cb, sid);
3039 edje_object_signal_callback_add
3040 (sid->edje_obj, "elm,vbar,unpress", "elm",
3041 _elm_scroll_vbar_unpress_cb, sid);
3042 edje_object_signal_callback_add
3043 (sid->edje_obj, "drag", "elm.dragable.hbar", _elm_scroll_hbar_drag_cb,
3045 edje_object_signal_callback_add
3046 (sid->edje_obj, "drag,set", "elm.dragable.hbar",
3047 _elm_scroll_edje_drag_h_cb, sid);
3048 edje_object_signal_callback_add
3049 (sid->edje_obj, "drag,start", "elm.dragable.hbar",
3050 _elm_scroll_edje_drag_h_start_cb, sid);
3051 edje_object_signal_callback_add
3052 (sid->edje_obj, "drag,stop", "elm.dragable.hbar",
3053 _elm_scroll_edje_drag_h_stop_cb, sid);
3054 edje_object_signal_callback_add
3055 (sid->edje_obj, "drag,step", "elm.dragable.hbar",
3056 _elm_scroll_edje_drag_h_cb, sid);
3057 edje_object_signal_callback_add
3058 (sid->edje_obj, "drag,page", "elm.dragable.hbar",
3059 _elm_scroll_edje_drag_h_cb, sid);
3060 edje_object_signal_callback_add
3061 (sid->edje_obj, "elm,hbar,press", "elm",
3062 _elm_scroll_hbar_press_cb, sid);
3063 edje_object_signal_callback_add
3064 (sid->edje_obj, "elm,hbar,unpress", "elm",
3065 _elm_scroll_hbar_unpress_cb, sid);
3069 _scroll_event_object_attach(Evas_Object *obj)
3071 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3073 evas_object_event_callback_add
3074 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL, _elm_scroll_wheel_event_cb,
3076 evas_object_event_callback_add
3077 (sid->event_rect, EVAS_CALLBACK_MOUSE_DOWN,
3078 _elm_scroll_mouse_down_event_cb, sid);
3079 evas_object_event_callback_add
3080 (sid->event_rect, EVAS_CALLBACK_MOUSE_UP,
3081 _elm_scroll_mouse_up_event_cb, sid);
3082 evas_object_event_callback_add
3083 (sid->event_rect, EVAS_CALLBACK_MOUSE_MOVE,
3084 _elm_scroll_mouse_move_event_cb, sid);
3088 _scroll_edje_object_detach(Evas_Object *obj)
3090 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3092 evas_object_event_callback_del_full
3093 (sid->edje_obj, EVAS_CALLBACK_RESIZE, _on_edje_resize, sid);
3094 evas_object_event_callback_del_full
3095 (sid->edje_obj, EVAS_CALLBACK_MOVE, _on_edje_move, sid);
3097 edje_object_signal_callback_del_full
3098 (sid->edje_obj, "drag", "elm.dragable.vbar", _elm_scroll_vbar_drag_cb,
3100 edje_object_signal_callback_del_full
3101 (sid->edje_obj, "drag,set", "elm.dragable.vbar",
3102 _elm_scroll_edje_drag_v_cb, sid);
3103 edje_object_signal_callback_del_full
3104 (sid->edje_obj, "drag,start", "elm.dragable.vbar",
3105 _elm_scroll_edje_drag_v_start_cb, sid);
3106 edje_object_signal_callback_del_full
3107 (sid->edje_obj, "drag,stop", "elm.dragable.vbar",
3108 _elm_scroll_edje_drag_v_stop_cb, sid);
3109 edje_object_signal_callback_del_full
3110 (sid->edje_obj, "drag,step", "elm.dragable.vbar",
3111 _elm_scroll_edje_drag_v_cb, sid);
3112 edje_object_signal_callback_del_full
3113 (sid->edje_obj, "drag,page", "elm.dragable.vbar",
3114 _elm_scroll_edje_drag_v_cb, sid);
3115 edje_object_signal_callback_del_full
3116 (sid->edje_obj, "elm,vbar,press", "elm",
3117 _elm_scroll_vbar_press_cb, sid);
3118 edje_object_signal_callback_del_full
3119 (sid->edje_obj, "elm,vbar,unpress", "elm",
3120 _elm_scroll_vbar_unpress_cb, sid);
3121 edje_object_signal_callback_del_full
3122 (sid->edje_obj, "drag", "elm.dragable.hbar", _elm_scroll_hbar_drag_cb,
3124 edje_object_signal_callback_del_full
3125 (sid->edje_obj, "drag,set", "elm.dragable.hbar",
3126 _elm_scroll_edje_drag_h_cb, sid);
3127 edje_object_signal_callback_del_full
3128 (sid->edje_obj, "drag,start", "elm.dragable.hbar",
3129 _elm_scroll_edje_drag_h_start_cb, sid);
3130 edje_object_signal_callback_del_full
3131 (sid->edje_obj, "drag,stop", "elm.dragable.hbar",
3132 _elm_scroll_edje_drag_h_stop_cb, sid);
3133 edje_object_signal_callback_del_full
3134 (sid->edje_obj, "drag,step", "elm.dragable.hbar",
3135 _elm_scroll_edje_drag_h_cb, sid);
3136 edje_object_signal_callback_del_full
3137 (sid->edje_obj, "drag,page", "elm.dragable.hbar",
3138 _elm_scroll_edje_drag_h_cb, sid);
3139 edje_object_signal_callback_del_full
3140 (sid->edje_obj, "elm,hbar,press", "elm",
3141 _elm_scroll_hbar_press_cb, sid);
3142 edje_object_signal_callback_del_full
3143 (sid->edje_obj, "elm,hbar,unpress", "elm",
3144 _elm_scroll_hbar_unpress_cb, sid);
3148 _scroll_event_object_detach(Evas_Object *obj)
3150 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3152 evas_object_event_callback_del_full
3153 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL, _elm_scroll_wheel_event_cb,
3155 evas_object_event_callback_del_full
3156 (sid->event_rect, EVAS_CALLBACK_MOUSE_DOWN,
3157 _elm_scroll_mouse_down_event_cb, sid);
3158 evas_object_event_callback_del_full
3159 (sid->event_rect, EVAS_CALLBACK_MOUSE_UP,
3160 _elm_scroll_mouse_up_event_cb, sid);
3161 evas_object_event_callback_del_full
3162 (sid->event_rect, EVAS_CALLBACK_MOUSE_MOVE,
3163 _elm_scroll_mouse_move_event_cb, sid);
3167 _elm_scroll_objects_set(Evas_Object *obj,
3168 Evas_Object *edje_object,
3169 Evas_Object *hit_rectangle)
3173 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3175 if (!edje_object || !hit_rectangle) return;
3178 _scroll_edje_object_detach(obj);
3180 sid->edje_obj = edje_object;
3182 if (sid->event_rect)
3183 _scroll_event_object_detach(obj);
3185 sid->event_rect = hit_rectangle;
3186 evas_object_repeat_events_set(hit_rectangle, EINA_TRUE);
3188 _scroll_edje_object_attach(obj);
3189 _scroll_event_object_attach(obj);
3192 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
3193 if (edje_object_part_exists(sid->edje_obj, "elm.scrollbar.base"))
3197 base = edje_object_part_swallow_get
3198 (sid->edje_obj, "elm.scrollbar.base");
3201 base = evas_object_rectangle_add
3202 (evas_object_evas_get(sid->edje_obj));
3203 evas_object_color_set(base, 0, 0, 0, 0);
3204 edje_object_part_swallow
3205 (sid->edje_obj, "elm.scrollbar.base", base);
3207 if (!_elm_config->thumbscroll_enable)
3208 evas_object_size_hint_min_set(base, mw, mh);
3211 _elm_scroll_scroll_bar_visibility_adjust(sid);
3215 _elm_scroll_scroll_bar_reset(Elm_Scrollable_Smart_Interface_Data *sid)
3217 Evas_Coord px = 0, py = 0, minx = 0, miny = 0;
3219 if (!sid->edje_obj) return;
3221 edje_object_part_drag_value_set
3222 (sid->edje_obj, "elm.dragable.vbar", 0.0, 0.0);
3223 edje_object_part_drag_value_set
3224 (sid->edje_obj, "elm.dragable.hbar", 0.0, 0.0);
3225 if ((!sid->content) && (!sid->extern_pan))
3227 edje_object_part_drag_size_set
3228 (sid->edje_obj, "elm.dragable.vbar", 1.0, 1.0);
3229 edje_object_part_drag_size_set
3230 (sid->edje_obj, "elm.dragable.hbar", 1.0, 1.0);
3234 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
3236 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
3237 psd->api->pos_get(sid->pan_obj, &px, &py);
3238 psd->api->pos_set(sid->pan_obj, minx, miny);
3240 if ((px != minx) || (py != miny))
3241 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
3242 _elm_direction_arrows_eval(sid);
3245 /* even external pan objects get this */
3247 _elm_scroll_pan_changed_cb(void *data,
3248 Evas_Object *obj __UNUSED__,
3249 void *event_info __UNUSED__)
3252 Elm_Scrollable_Smart_Interface_Data *sid = data;
3254 if (!sid->pan_obj) return;
3256 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
3258 psd->api->content_size_get(sid->pan_obj, &w, &h);
3259 if ((w != sid->content_info.w) || (h != sid->content_info.h))
3261 sid->content_info.w = w;
3262 sid->content_info.h = h;
3263 _elm_scroll_scroll_bar_size_adjust(sid);
3265 evas_object_size_hint_min_set
3266 (sid->edje_obj, sid->content_info.w, sid->content_info.h);
3267 sid->content_info.resized = EINA_TRUE;
3268 _elm_scroll_wanted_region_set(sid->obj);
3273 _elm_scroll_content_del_cb(void *data,
3275 Evas_Object *obj __UNUSED__,
3276 void *event_info __UNUSED__)
3278 Elm_Scrollable_Smart_Interface_Data *sid = data;
3280 sid->content = NULL;
3281 _elm_scroll_scroll_bar_size_adjust(sid);
3282 _elm_scroll_scroll_bar_reset(sid);
3286 _elm_scroll_content_set(Evas_Object *obj,
3287 Evas_Object *content)
3292 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3294 if (!sid->edje_obj) return;
3298 /* if we had content, for sure we had a pan object */
3299 _elm_pan_content_set(sid->pan_obj, NULL);
3300 evas_object_event_callback_del_full
3301 (sid->content, EVAS_CALLBACK_DEL, _elm_scroll_content_del_cb, sid);
3304 sid->content = content;
3305 sid->wx = sid->wy = 0;
3306 /* (-1) means want viewports size */
3307 sid->ww = sid->wh = -1;
3308 if (!content) return;
3312 o = _elm_pan_add(evas_object_evas_get(obj));
3314 evas_object_smart_callback_add
3315 (o, SIG_CHANGED, _elm_scroll_pan_changed_cb, sid);
3316 edje_object_part_swallow(sid->edje_obj, "elm.swallow.content", o);
3319 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
3321 evas_object_event_callback_add
3322 (content, EVAS_CALLBACK_DEL, _elm_scroll_content_del_cb, sid);
3324 _elm_pan_content_set(sid->pan_obj, content);
3325 psd->api->content_size_get(sid->pan_obj, &w, &h);
3326 sid->content_info.w = w;
3327 sid->content_info.h = h;
3329 _elm_scroll_scroll_bar_size_adjust(sid);
3330 _elm_scroll_scroll_bar_reset(sid);
3334 _elm_scroll_extern_pan_set(Evas_Object *obj,
3337 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3339 if (!sid->edje_obj) return;
3341 _elm_scroll_content_set(obj, NULL);
3345 evas_object_smart_callback_del
3346 (sid->pan_obj, SIG_CHANGED, _elm_scroll_pan_changed_cb);
3349 if (sid->extern_pan)
3353 /* not owned by scroller, just leave (was external already) */
3354 edje_object_part_unswallow(sid->edje_obj, sid->pan_obj);
3355 sid->pan_obj = NULL;
3362 evas_object_del(sid->pan_obj);
3363 sid->pan_obj = NULL;
3368 sid->extern_pan = EINA_FALSE;
3374 sid->extern_pan = EINA_TRUE;
3375 evas_object_smart_callback_add
3376 (sid->pan_obj, SIG_CHANGED, _elm_scroll_pan_changed_cb, sid);
3377 edje_object_part_swallow
3378 (sid->edje_obj, "elm.swallow.content", sid->pan_obj);
3382 _elm_scroll_drag_start_cb_set(Evas_Object *obj,
3383 void (*drag_start_cb)(Evas_Object *obj,
3386 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3388 sid->cb_func.drag_start = drag_start_cb;
3392 _elm_scroll_drag_stop_cb_set(Evas_Object *obj,
3393 void (*drag_stop_cb)(Evas_Object *obj,
3396 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3398 sid->cb_func.drag_stop = drag_stop_cb;
3402 _elm_scroll_animate_start_cb_set(Evas_Object *obj,
3403 void (*animate_start_cb)(Evas_Object *obj,
3406 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3408 sid->cb_func.animate_start = animate_start_cb;
3412 _elm_scroll_animate_stop_cb_set(Evas_Object *obj,
3413 void (*animate_stop_cb)(Evas_Object *obj,
3416 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3418 sid->cb_func.animate_stop = animate_stop_cb;
3422 _elm_scroll_scroll_cb_set(Evas_Object *obj,
3423 void (*scroll_cb)(Evas_Object *obj,
3426 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3428 sid->cb_func.scroll = scroll_cb;
3432 _elm_scroll_scroll_left_cb_set(Evas_Object *obj,
3433 void (*scroll_left_cb)(Evas_Object *obj,
3436 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3438 sid->cb_func.scroll_left = scroll_left_cb;
3442 _elm_scroll_scroll_right_cb_set(Evas_Object *obj,
3443 void (*scroll_right_cb)(Evas_Object *obj,
3446 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3448 sid->cb_func.scroll_right = scroll_right_cb;
3452 _elm_scroll_scroll_up_cb_set(Evas_Object *obj,
3453 void (*scroll_up_cb)(Evas_Object *obj,
3456 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3458 sid->cb_func.scroll_up = scroll_up_cb;
3462 _elm_scroll_scroll_down_cb_set(Evas_Object *obj,
3463 void (*scroll_down_cb)(Evas_Object *obj,
3466 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3468 sid->cb_func.scroll_down = scroll_down_cb;
3472 _elm_scroll_edge_left_cb_set(Evas_Object *obj,
3473 void (*edge_left_cb)(Evas_Object *obj,
3476 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3478 sid->cb_func.edge_left = edge_left_cb;
3482 _elm_scroll_edge_right_cb_set(Evas_Object *obj,
3483 void (*edge_right_cb)(Evas_Object *obj,
3486 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3488 sid->cb_func.edge_right = edge_right_cb;
3492 _elm_scroll_edge_top_cb_set(Evas_Object *obj,
3493 void (*edge_top_cb)(Evas_Object *obj,
3496 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3498 sid->cb_func.edge_top = edge_top_cb;
3502 _elm_scroll_edge_bottom_cb_set(Evas_Object *obj,
3503 void (*edge_bottom_cb)(Evas_Object *obj,
3506 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3508 sid->cb_func.edge_bottom = edge_bottom_cb;
3512 _elm_scroll_vbar_drag_cb_set(Evas_Object *obj,
3513 void (*vbar_drag_cb)(Evas_Object *obj,
3516 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3518 sid->cb_func.vbar_drag = vbar_drag_cb;
3522 _elm_scroll_vbar_press_cb_set(Evas_Object *obj,
3523 void (*vbar_press_cb)(Evas_Object *obj,
3526 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3528 sid->cb_func.vbar_press = vbar_press_cb;
3532 _elm_scroll_vbar_unpress_cb_set(Evas_Object *obj,
3533 void (*vbar_unpress_cb)(Evas_Object *obj,
3536 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3538 sid->cb_func.vbar_unpress = vbar_unpress_cb;
3542 _elm_scroll_hbar_drag_cb_set(Evas_Object *obj,
3543 void (*hbar_drag_cb)(Evas_Object *obj,
3546 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3548 sid->cb_func.hbar_drag = hbar_drag_cb;
3552 _elm_scroll_hbar_press_cb_set(Evas_Object *obj,
3553 void (*hbar_press_cb)(Evas_Object *obj,
3556 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3558 sid->cb_func.hbar_press = hbar_press_cb;
3562 _elm_scroll_hbar_unpress_cb_set(Evas_Object *obj,
3563 void (*hbar_unpress_cb)(Evas_Object *obj,
3566 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3568 sid->cb_func.hbar_unpress = hbar_unpress_cb;
3572 _elm_scroll_content_min_limit_cb_set(Evas_Object *obj,
3573 void (*c_min_limit_cb)(Evas_Object *obj,
3577 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3579 sid->cb_func.content_min_limit = c_min_limit_cb;
3583 _elm_scroll_momentum_animator_disabled_get(const Evas_Object *obj)
3585 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
3587 return sid->momentum_animator_disabled;
3591 _elm_scroll_momentum_animator_disabled_set(Evas_Object *obj,
3594 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3596 sid->momentum_animator_disabled = disabled;
3597 if (sid->momentum_animator_disabled)
3599 if (sid->down.momentum_animator)
3601 ecore_animator_del(sid->down.momentum_animator);
3602 sid->down.momentum_animator = NULL;
3603 if (sid->content_info.resized)
3604 _elm_scroll_wanted_region_set(sid->obj);
3610 _elm_scroll_bounce_animator_disabled_get(const Evas_Object *obj)
3612 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
3614 return sid->bounce_animator_disabled;
3618 _elm_scroll_bounce_animator_disabled_set(Evas_Object *obj,
3621 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3623 sid->bounce_animator_disabled = disabled;
3624 if (sid->bounce_animator_disabled)
3626 if (sid->scrollto.x.animator)
3628 ecore_animator_del(sid->scrollto.x.animator);
3629 sid->scrollto.x.animator = NULL;
3632 if (sid->scrollto.y.animator)
3634 ecore_animator_del(sid->scrollto.y.animator);
3635 sid->scrollto.y.animator = NULL;
3641 _elm_scroll_wheel_disabled_get(const Evas_Object *obj)
3643 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
3645 return sid->wheel_disabled;
3649 _elm_scroll_wheel_disabled_set(Evas_Object *obj,
3652 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3654 if (!sid->event_rect) return;
3656 if ((!sid->wheel_disabled) && (disabled))
3657 evas_object_event_callback_del_full
3658 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL,
3659 _elm_scroll_wheel_event_cb, sid);
3660 else if ((sid->wheel_disabled) && (!disabled))
3661 evas_object_event_callback_add
3662 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL,
3663 _elm_scroll_wheel_event_cb, sid);
3664 sid->wheel_disabled = disabled;
3668 _elm_scroll_step_size_set(Evas_Object *obj,
3672 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3679 _elm_scroll_scroll_bar_size_adjust(sid);
3683 _elm_scroll_step_size_get(const Evas_Object *obj,
3687 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3689 if (x) *x = sid->step.x;
3690 if (y) *y = sid->step.y;
3694 _elm_scroll_page_size_set(Evas_Object *obj,
3698 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3703 _elm_scroll_scroll_bar_size_adjust(sid);
3707 _elm_scroll_page_size_get(const Evas_Object *obj,
3711 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3713 if (x) *x = sid->page.x;
3714 if (y) *y = sid->page.y;
3718 _elm_scroll_policy_set(Evas_Object *obj,
3719 Elm_Scroller_Policy hbar,
3720 Elm_Scroller_Policy vbar)
3722 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3724 if (!sid->edje_obj) return;
3726 if ((sid->hbar_flags == hbar) && (sid->vbar_flags == vbar)) return;
3728 sid->hbar_flags = hbar;
3729 sid->vbar_flags = vbar;
3730 if (sid->hbar_flags == ELM_SCROLLER_POLICY_ON)
3731 edje_object_signal_emit
3732 (sid->edje_obj, "elm,action,show_always,hbar", "elm");
3733 else if (sid->hbar_flags == ELM_SCROLLER_POLICY_OFF)
3734 edje_object_signal_emit
3735 (sid->edje_obj, "elm,action,hide,hbar", "elm");
3737 edje_object_signal_emit
3738 (sid->edje_obj, "elm,action,show_notalways,hbar", "elm");
3739 if (sid->vbar_flags == ELM_SCROLLER_POLICY_ON)
3740 edje_object_signal_emit
3741 (sid->edje_obj, "elm,action,show_always,vbar", "elm");
3742 else if (sid->vbar_flags == ELM_SCROLLER_POLICY_OFF)
3743 edje_object_signal_emit
3744 (sid->edje_obj, "elm,action,hide,vbar", "elm");
3746 edje_object_signal_emit
3747 (sid->edje_obj, "elm,action,show_notalways,vbar", "elm");
3748 edje_object_message_signal_process(sid->edje_obj);
3749 _elm_scroll_scroll_bar_size_adjust(sid);
3750 if (sid->cb_func.content_min_limit)
3751 sid->cb_func.content_min_limit(sid->obj, sid->min_w, sid->min_h);
3752 _elm_direction_arrows_eval(sid);
3756 _elm_scroll_policy_get(const Evas_Object *obj,
3757 Elm_Scroller_Policy *hbar,
3758 Elm_Scroller_Policy *vbar)
3760 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3762 if (hbar) *hbar = sid->hbar_flags;
3763 if (vbar) *vbar = sid->vbar_flags;
3767 _elm_scroll_single_direction_set(Evas_Object *obj,
3768 Elm_Scroller_Single_Direction single_dir)
3770 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3772 sid->one_direction_at_a_time = single_dir;
3775 static Elm_Scroller_Single_Direction
3776 _elm_scroll_single_direction_get(const Evas_Object *obj)
3778 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, ELM_SCROLLER_SINGLE_DIRECTION_SOFT);
3780 return sid->one_direction_at_a_time;
3784 _elm_scroll_repeat_events_set(Evas_Object *obj,
3785 Eina_Bool repeat_events)
3787 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3789 evas_object_repeat_events_set(sid->event_rect, repeat_events);
3793 _elm_scroll_repeat_events_get(const Evas_Object *obj)
3795 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
3797 return evas_object_repeat_events_get(sid->event_rect);
3801 _elm_scroll_hold_set(Evas_Object *obj,
3804 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3810 _elm_scroll_freeze_set(Evas_Object *obj,
3813 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3815 sid->freeze = freeze;
3818 if (sid->down.onhold_animator)
3820 ecore_animator_del(sid->down.onhold_animator);
3821 sid->down.onhold_animator = NULL;
3822 if (sid->content_info.resized)
3823 _elm_scroll_wanted_region_set(sid->obj);
3827 _elm_scroll_bounce_eval(sid);
3831 _elm_scroll_bounce_allow_set(Evas_Object *obj,
3835 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3837 sid->bounce_horiz = !!horiz;
3838 sid->bounce_vert = !!vert;
3842 _elm_scroll_bounce_allow_get(const Evas_Object *obj,
3846 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3848 if (horiz) *horiz = sid->bounce_horiz;
3849 if (vert) *vert = sid->bounce_vert;
3853 _elm_scroll_paging_set(Evas_Object *obj,
3856 Evas_Coord pagesize_h,
3857 Evas_Coord pagesize_v)
3859 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3861 sid->pagerel_h = pagerel_h;
3862 sid->pagerel_v = pagerel_v;
3863 sid->pagesize_h = pagesize_h;
3864 sid->pagesize_v = pagesize_v;
3866 _elm_scroll_page_adjust(sid);
3870 _elm_scroll_paging_get(const Evas_Object *obj,
3873 Evas_Coord *pagesize_h,
3874 Evas_Coord *pagesize_v)
3876 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3878 if (pagerel_h) *pagerel_h = sid->pagerel_h;
3879 if (pagerel_v) *pagerel_v = sid->pagerel_v;
3880 if (pagesize_h) *pagesize_h = sid->pagesize_h;
3881 if (pagesize_v) *pagesize_v = sid->pagesize_v;
3885 _elm_scroll_page_scroll_limit_set(const Evas_Object *obj,
3889 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3891 sid->page_limit_h = page_limit_h;
3892 sid->page_limit_v = page_limit_v;
3896 _elm_scroll_page_scroll_limit_get(const Evas_Object *obj,
3900 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3902 if (page_limit_h) *page_limit_h = sid->page_limit_h;
3903 if (page_limit_v) *page_limit_v = sid->page_limit_v;
3907 _elm_scroll_current_page_get(const Evas_Object *obj,
3913 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3915 _elm_scroll_content_pos_get(sid->obj, &x, &y);
3918 if (sid->pagesize_h > 0)
3919 *pagenumber_h = (x + sid->pagesize_h - 1) / sid->pagesize_h;
3925 if (sid->pagesize_v > 0)
3926 *pagenumber_v = (y + sid->pagesize_v - 1) / sid->pagesize_v;
3933 _elm_scroll_last_page_get(const Evas_Object *obj,
3939 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3941 if (!sid->pan_obj) return;
3943 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
3945 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
3948 if (sid->pagesize_h > 0)
3949 *pagenumber_h = cw / sid->pagesize_h + 1;
3955 if (sid->pagesize_v > 0)
3956 *pagenumber_v = ch / sid->pagesize_v + 1;
3963 _elm_scroll_page_show(Evas_Object *obj,
3971 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3973 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
3974 if (pagenumber_h >= 0) x = sid->pagesize_h * pagenumber_h;
3975 if (pagenumber_v >= 0) y = sid->pagesize_v * pagenumber_v;
3976 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
3977 _elm_scroll_content_pos_set(obj, x, y, EINA_TRUE);
3981 _elm_scroll_page_bring_in(Evas_Object *obj,
3989 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3991 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
3992 if (pagenumber_h >= 0) x = sid->pagesize_h * pagenumber_h;
3993 if (pagenumber_v >= 0) y = sid->pagesize_v * pagenumber_v;
3994 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
3996 _elm_scroll_scroll_to_x(sid, _elm_config->bring_in_scroll_friction, x);
3997 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, y);
4002 _elm_scroll_region_bring_in(Evas_Object *obj,
4008 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4010 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
4012 _elm_scroll_scroll_to_x(sid, _elm_config->bring_in_scroll_friction, x);
4013 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, y);
4018 _elm_scroll_gravity_set(Evas_Object *obj,
4022 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4024 if (!sid->pan_obj) return;
4026 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
4028 psd->api->gravity_set(sid->pan_obj, x, y);
4032 _elm_scroll_gravity_get(const Evas_Object *obj,
4036 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4038 if (!sid->pan_obj) return;
4040 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
4042 psd->api->gravity_get(sid->pan_obj, x, y);
4046 _elm_scroll_interface_add(Evas_Object *obj)
4048 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
4050 memset(sid, 0, sizeof(*sid));
4062 sid->page_limit_h = 9999;
4063 sid->page_limit_v = 9999;
4064 sid->hbar_flags = ELM_SCROLLER_POLICY_AUTO;
4065 sid->vbar_flags = ELM_SCROLLER_POLICY_AUTO;
4066 sid->hbar_visible = EINA_TRUE;
4067 sid->vbar_visible = EINA_TRUE;
4069 sid->bounce_horiz = EINA_TRUE;
4070 sid->bounce_vert = EINA_TRUE;
4072 sid->one_direction_at_a_time = ELM_SCROLLER_SINGLE_DIRECTION_SOFT;
4073 sid->momentum_animator_disabled = EINA_FALSE;
4074 sid->bounce_animator_disabled = EINA_FALSE;
4076 _elm_scroll_scroll_bar_reset(sid);
4082 _elm_scroll_interface_del(Evas_Object *obj)
4084 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4086 _elm_scroll_content_set(obj, NULL);
4087 if (!sid->extern_pan) evas_object_del(sid->pan_obj);
4089 if (sid->down.hold_animator)
4090 ecore_animator_del(sid->down.hold_animator);
4091 if (sid->down.onhold_animator)
4092 ecore_animator_del(sid->down.onhold_animator);
4093 if (sid->down.momentum_animator)
4094 ecore_animator_del(sid->down.momentum_animator);
4095 if (sid->down.bounce_x_animator)
4096 ecore_animator_del(sid->down.bounce_x_animator);
4097 if (sid->down.bounce_y_animator)
4098 ecore_animator_del(sid->down.bounce_y_animator);
4099 if (sid->scrollto.x.animator) ecore_animator_del(sid->scrollto.x.animator);
4100 if (sid->scrollto.y.animator) ecore_animator_del(sid->scrollto.y.animator);
4103 EAPI const char ELM_SCROLLABLE_IFACE_NAME[] = "elm_interface_scrollable";
4105 EAPI const Elm_Scrollable_Smart_Interface ELM_SCROLLABLE_IFACE =
4108 ELM_SCROLLABLE_IFACE_NAME,
4109 sizeof(Elm_Scrollable_Smart_Interface_Data),
4110 _elm_scroll_interface_add,
4111 _elm_scroll_interface_del
4114 _elm_scroll_objects_set,
4115 _elm_scroll_content_set,
4116 _elm_scroll_extern_pan_set,
4117 _elm_scroll_drag_start_cb_set,
4118 _elm_scroll_drag_stop_cb_set,
4119 _elm_scroll_animate_start_cb_set,
4120 _elm_scroll_animate_stop_cb_set,
4121 _elm_scroll_scroll_cb_set,
4122 _elm_scroll_scroll_left_cb_set,
4123 _elm_scroll_scroll_right_cb_set,
4124 _elm_scroll_scroll_up_cb_set,
4125 _elm_scroll_scroll_down_cb_set,
4126 _elm_scroll_edge_left_cb_set,
4127 _elm_scroll_edge_right_cb_set,
4128 _elm_scroll_edge_top_cb_set,
4129 _elm_scroll_edge_bottom_cb_set,
4130 _elm_scroll_vbar_drag_cb_set,
4131 _elm_scroll_vbar_press_cb_set,
4132 _elm_scroll_vbar_unpress_cb_set,
4133 _elm_scroll_hbar_drag_cb_set,
4134 _elm_scroll_hbar_press_cb_set,
4135 _elm_scroll_hbar_unpress_cb_set,
4136 _elm_scroll_content_min_limit_cb_set,
4137 _elm_scroll_content_pos_set,
4138 _elm_scroll_content_pos_get,
4139 _elm_scroll_content_region_show,
4140 _elm_scroll_content_region_set,
4141 _elm_scroll_content_size_get,
4142 _elm_scroll_content_viewport_size_get,
4143 _elm_scroll_content_min_limit,
4144 _elm_scroll_step_size_set,
4145 _elm_scroll_step_size_get,
4146 _elm_scroll_page_size_set,
4147 _elm_scroll_page_size_get,
4148 _elm_scroll_policy_set,
4149 _elm_scroll_policy_get,
4150 _elm_scroll_single_direction_set,
4151 _elm_scroll_single_direction_get,
4152 _elm_scroll_repeat_events_set,
4153 _elm_scroll_repeat_events_get,
4154 _elm_scroll_mirrored_set,
4155 _elm_scroll_hold_set,
4156 _elm_scroll_freeze_set,
4157 _elm_scroll_bounce_allow_set,
4158 _elm_scroll_bounce_allow_get,
4159 _elm_scroll_paging_set,
4160 _elm_scroll_paging_get,
4161 _elm_scroll_page_scroll_limit_set,
4162 _elm_scroll_page_scroll_limit_get,
4163 _elm_scroll_current_page_get,
4164 _elm_scroll_last_page_get,
4165 _elm_scroll_page_show,
4166 _elm_scroll_page_bring_in,
4167 _elm_scroll_region_bring_in,
4168 _elm_scroll_gravity_set,
4169 _elm_scroll_gravity_get,
4170 _elm_scroll_momentum_animator_disabled_get,
4171 _elm_scroll_momentum_animator_disabled_set,
4172 _elm_scroll_bounce_animator_disabled_set,
4173 _elm_scroll_bounce_animator_disabled_get,
4174 _elm_scroll_wheel_disabled_get,
4175 _elm_scroll_wheel_disabled_set