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 if (((!_elm_config->thumbscroll_bounce_enable) ||
1363 (!sid->bounce_horiz)) && (sid->scrollto.x.animator) &&
1364 ((px != x) && ((x == minx) || (x == (mx + minx)))))
1366 ecore_animator_del(sid->scrollto.x.animator);
1367 sid->scrollto.x.animator = NULL;
1370 if (((!_elm_config->thumbscroll_bounce_enable) ||
1371 (!sid->bounce_vert)) && (sid->scrollto.y.animator) &&
1372 ((py != y) && ((y == miny) || (y == (my + miny)))))
1374 ecore_animator_del(sid->scrollto.y.animator);
1375 sid->scrollto.y.animator = NULL;
1378 if (((!_elm_config->thumbscroll_bounce_enable) ||
1379 ((!sid->bounce_horiz) && (!sid->bounce_vert))) &&
1380 (sid->down.momentum_animator) &&
1381 ((((px != x) && ((x == minx) || (x == (mx + minx)))) && (py == y)) ||
1382 (((py != y) && ((y == miny) || (y == (my + miny)))) && (px == x))))
1384 ecore_animator_del(sid->down.momentum_animator);
1385 sid->down.momentum_animator = NULL;
1386 sid->down.bounce_x_hold = EINA_FALSE;
1387 sid->down.bounce_y_hold = EINA_FALSE;
1392 if (sid->content_info.resized)
1393 _elm_scroll_wanted_region_set(sid->obj);
1396 psd->api->pos_set(sid->pan_obj, x, y);
1397 psd->api->pos_get(sid->pan_obj, &spx, &spy);
1399 if (mx > 0) vx = (double)(spx - minx) / (double)mx;
1402 if (vx < 0.0) vx = 0.0;
1406 if (my > 0) vy = (double)(spy - miny) / (double)my;
1409 if (vy < 0.0) vy = 0.0;
1413 edje_object_part_drag_value_set
1414 (sid->edje_obj, "elm.dragable.vbar", 0.0, vy);
1415 edje_object_part_drag_value_set
1416 (sid->edje_obj, "elm.dragable.hbar", vx, 0.0);
1418 if (!sid->down.bounce_x_animator)
1420 if (((x < minx) && (0 <= sid->down.dx)) ||
1421 ((x > (mx + minx)) && (0 >= sid->down.dx)))
1423 sid->bouncemex = EINA_TRUE;
1424 _elm_scroll_bounce_eval(sid);
1427 sid->bouncemex = EINA_FALSE;
1429 if (!sid->down.bounce_y_animator)
1431 if (((y < miny) && (0 <= sid->down.dy)) ||
1432 ((y > (my + miny)) && (0 >= sid->down.dy)))
1434 sid->bouncemey = EINA_TRUE;
1435 _elm_scroll_bounce_eval(sid);
1438 sid->bouncemey = EINA_FALSE;
1443 if ((x != px) || (y != py))
1445 if (sid->cb_func.scroll)
1446 sid->cb_func.scroll(obj, NULL);
1447 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
1450 if (sid->cb_func.scroll_left)
1451 sid->cb_func.scroll_left(obj, NULL);
1452 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,left", "elm");
1456 if (sid->cb_func.scroll_right)
1457 sid->cb_func.scroll_right(obj, NULL);
1458 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,right", "elm");
1462 if (sid->cb_func.scroll_up)
1463 sid->cb_func.scroll_up(obj, NULL);
1464 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,up", "elm");
1468 if (sid->cb_func.scroll_down)
1469 sid->cb_func.scroll_down(obj, NULL);
1470 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,down", "elm");
1477 if (sid->cb_func.edge_left)
1478 sid->cb_func.edge_left(obj, NULL);
1479 edje_object_signal_emit(sid->edje_obj, "elm,edge,left", "elm");
1481 if (x == (mx + minx))
1483 if (sid->cb_func.edge_right)
1484 sid->cb_func.edge_right(obj, NULL);
1485 edje_object_signal_emit(sid->edje_obj, "elm,edge,right", "elm");
1492 if (sid->cb_func.edge_top)
1493 sid->cb_func.edge_top(obj, NULL);
1494 edje_object_signal_emit(sid->edje_obj, "elm,edge,top", "elm");
1498 if (sid->cb_func.edge_bottom)
1499 sid->cb_func.edge_bottom(obj, NULL);
1500 edje_object_signal_emit(sid->edje_obj, "elm,edge,bottom", "elm");
1505 _elm_direction_arrows_eval(sid);
1509 _elm_scroll_mirrored_set(Evas_Object *obj,
1514 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1516 if (!sid->edje_obj) return;
1518 mirrored = !!mirrored;
1520 if (sid->is_mirrored == mirrored)
1523 sid->is_mirrored = mirrored;
1524 edje_object_mirrored_set(sid->edje_obj, mirrored);
1526 if (sid->is_mirrored)
1527 wx = _elm_scroll_x_mirrored_get(sid->obj, sid->wx);
1531 _elm_scroll_content_pos_set(sid->obj, wx, sid->wy, EINA_FALSE);
1534 /* returns TRUE when we need to move the scroller, FALSE otherwise.
1535 * Updates w and h either way, so save them if you need them. */
1537 _elm_scroll_content_region_show_internal(Evas_Object *obj,
1543 Evas_Coord mx = 0, my = 0, cw = 0, ch = 0, px = 0, py = 0, nx, ny,
1544 minx = 0, miny = 0, pw = 0, ph = 0, x = *_x, y = *_y;
1546 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
1548 if (!sid->pan_obj) return EINA_FALSE;
1550 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, EINA_FALSE);
1552 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
1553 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
1554 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1555 psd->api->pos_get(sid->pan_obj, &px, &py);
1556 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &pw, &ph);
1559 if ((x < px) && ((x + w) < (px + (cw - mx)))) nx = x;
1560 else if ((x > px) && ((x + w) > (px + (cw - mx))))
1561 nx = x + w - (cw - mx);
1563 if ((y < py) && ((y + h) < (py + (ch - my)))) ny = y;
1564 else if ((y > py) && ((y + h) > (py + (ch - my))))
1565 ny = y + h - (ch - my);
1567 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
1568 (sid->scrollto.x.animator) || (sid->scrollto.y.animator))
1570 _elm_scroll_anim_stop(sid);
1572 if (sid->scrollto.x.animator)
1574 ecore_animator_del(sid->scrollto.x.animator);
1575 sid->scrollto.x.animator = NULL;
1577 if (sid->scrollto.y.animator)
1579 ecore_animator_del(sid->scrollto.y.animator);
1580 sid->scrollto.y.animator = NULL;
1582 if (sid->down.bounce_x_animator)
1584 ecore_animator_del(sid->down.bounce_x_animator);
1585 sid->down.bounce_x_animator = NULL;
1586 sid->bouncemex = EINA_FALSE;
1587 if (sid->content_info.resized)
1588 _elm_scroll_wanted_region_set(sid->obj);
1590 if (sid->down.bounce_y_animator)
1592 ecore_animator_del(sid->down.bounce_y_animator);
1593 sid->down.bounce_y_animator = NULL;
1594 sid->bouncemey = EINA_FALSE;
1595 if (sid->content_info.resized)
1596 _elm_scroll_wanted_region_set(sid->obj);
1598 if (sid->down.hold_animator)
1600 ecore_animator_del(sid->down.hold_animator);
1601 sid->down.hold_animator = NULL;
1602 _elm_scroll_drag_stop(sid);
1603 if (sid->content_info.resized)
1604 _elm_scroll_wanted_region_set(sid->obj);
1606 if (sid->down.momentum_animator)
1608 ecore_animator_del(sid->down.momentum_animator);
1609 sid->down.momentum_animator = NULL;
1610 sid->down.bounce_x_hold = EINA_FALSE;
1611 sid->down.bounce_y_hold = EINA_FALSE;
1616 if (sid->content_info.resized)
1617 _elm_scroll_wanted_region_set(sid->obj);
1620 if (_paging_is_enabled(sid))
1622 x = _elm_scroll_page_x_get(sid, nx - px, EINA_FALSE);
1623 y = _elm_scroll_page_y_get(sid, ny - py, EINA_FALSE);
1630 if ((x + pw) > cw) x = cw - pw;
1631 if (x < minx) x = minx;
1632 if ((y + ph) > ch) y = ch - ph;
1633 if (y < miny) y = miny;
1635 if ((x == px) && (y == py)) return EINA_FALSE;
1641 /* Set should be used for calculated positions, for example, when we move
1642 * because of an animation or because this is the correct position after
1645 _elm_scroll_content_region_set(Evas_Object *obj,
1651 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1653 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
1655 _elm_scroll_content_pos_set(obj, x, y, EINA_FALSE);
1658 sid->down.x = sid->down.history[0].x;
1659 sid->down.y = sid->down.history[0].y;
1663 /* Set should be used for setting the wanted position, for example a
1664 * user scroll or moving the cursor in an entry. */
1666 _elm_scroll_content_region_show(Evas_Object *obj,
1672 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1678 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
1680 _elm_scroll_content_pos_set(obj, x, y, EINA_TRUE);
1683 sid->down.x = sid->down.history[0].x;
1684 sid->down.y = sid->down.history[0].y;
1689 _elm_scroll_wanted_region_set(Evas_Object *obj)
1691 Evas_Coord ww, wh, wx;
1693 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1697 if (sid->down.now || sid->down.momentum_animator ||
1698 sid->down.bounce_x_animator || sid->down.bounce_y_animator ||
1699 sid->down.hold_animator || sid->down.onhold_animator ||
1700 sid->scrollto.x.animator || sid->scrollto.y.animator)
1703 sid->content_info.resized = EINA_FALSE;
1705 /* Flip to RTL cords only if init in RTL mode */
1706 if (sid->is_mirrored)
1707 wx = _elm_scroll_x_mirrored_get(obj, sid->wx);
1711 _elm_scroll_content_viewport_size_get(obj, &ww, &wh);
1719 _elm_scroll_content_region_set(obj, wx, sid->wy, ww, wh);
1723 _elm_scroll_wheel_event_cb(void *data,
1725 Evas_Object *obj __UNUSED__,
1728 Elm_Scrollable_Smart_Interface_Data *sid;
1729 Evas_Event_Mouse_Wheel *ev;
1730 Evas_Coord x = 0, y = 0, vw = 0, vh = 0, cw = 0, ch = 0;
1734 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
1736 direction = ev->direction;
1737 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1738 if ((evas_key_modifier_is_set(ev->modifiers, "Control")) ||
1739 (evas_key_modifier_is_set(ev->modifiers, "Alt")) ||
1740 (evas_key_modifier_is_set(ev->modifiers, "Meta")) ||
1741 (evas_key_modifier_is_set(ev->modifiers, "Hyper")) ||
1742 (evas_key_modifier_is_set(ev->modifiers, "Super")))
1744 else if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
1745 direction = !direction;
1746 _elm_scroll_content_pos_get(sid->obj, &x, &y);
1747 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
1748 (sid->scrollto.x.animator) || (sid->scrollto.y.animator))
1750 _elm_scroll_anim_stop(sid);
1752 if (sid->scrollto.x.animator)
1754 ecore_animator_del(sid->scrollto.x.animator);
1755 sid->scrollto.x.animator = NULL;
1757 if (sid->scrollto.y.animator)
1759 ecore_animator_del(sid->scrollto.y.animator);
1760 sid->scrollto.y.animator = NULL;
1762 if (sid->down.bounce_x_animator)
1764 ecore_animator_del(sid->down.bounce_x_animator);
1765 sid->down.bounce_x_animator = NULL;
1766 sid->bouncemex = EINA_FALSE;
1767 if (sid->content_info.resized)
1768 _elm_scroll_wanted_region_set(sid->obj);
1770 if (sid->down.bounce_y_animator)
1772 ecore_animator_del(sid->down.bounce_y_animator);
1773 sid->down.bounce_y_animator = NULL;
1774 sid->bouncemey = EINA_FALSE;
1775 if (sid->content_info.resized)
1776 _elm_scroll_wanted_region_set(sid->obj);
1778 _elm_scroll_content_viewport_size_get(sid->obj, &vw, &vh);
1779 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1782 if (ch > vh || cw <= vw)
1783 y += ev->z * sid->step.y;
1785 x += ev->z * sid->step.x;
1787 else if (direction == 1)
1789 if (cw > vw || ch <= vh)
1790 x += ev->z * sid->step.x;
1792 y += ev->z * sid->step.y;
1795 if ((!sid->hold) && (!sid->freeze))
1797 _elm_scroll_wanted_coordinates_update(sid, x, y);
1798 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
1803 _elm_scroll_post_event_up(void *data,
1806 Elm_Scrollable_Smart_Interface_Data *sid = data;
1810 if (sid->down.dragged)
1812 elm_widget_drag_lock_x_set(sid->obj, EINA_FALSE);
1813 elm_widget_drag_lock_y_set(sid->obj, EINA_FALSE);
1820 _paging_is_enabled(Elm_Scrollable_Smart_Interface_Data *sid)
1822 if ((sid->pagerel_h == 0.0) && (!sid->pagesize_h) &&
1823 (sid->pagerel_v == 0.0) && (!sid->pagesize_v))
1829 _elm_scroll_momentum_animator(void *data)
1832 Elm_Scrollable_Smart_Interface_Data *sid = data;
1833 Evas_Coord x, y, dx, dy, px, py, maxx, maxy, minx, miny;
1834 Eina_Bool no_bounce_x_end = EINA_FALSE, no_bounce_y_end = EINA_FALSE;
1836 if (!sid->pan_obj) return ECORE_CALLBACK_CANCEL;
1838 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, ECORE_CALLBACK_CANCEL);
1840 t = ecore_loop_time_get();
1841 dt = t - sid->down.anim_start;
1844 dt = dt / (_elm_config->thumbscroll_friction + sid->down.extra_time);
1845 if (dt > 1.0) dt = 1.0;
1846 p = 1.0 - ((1.0 - dt) * (1.0 - dt));
1847 dx = (sid->down.dx * (_elm_config->thumbscroll_friction +
1848 sid->down.extra_time) * p);
1849 dy = (sid->down.dy * (_elm_config->thumbscroll_friction +
1850 sid->down.extra_time) * p);
1853 x = sid->down.sx - dx;
1854 y = sid->down.sy - dy;
1855 _elm_scroll_content_pos_get(sid->obj, &px, &py);
1856 if ((sid->down.bounce_x_animator) ||
1857 (sid->down.bounce_x_hold))
1859 sid->down.bx = sid->down.bx0 - dx + sid->down.b0x;
1862 if ((sid->down.bounce_y_animator) ||
1863 (sid->down.bounce_y_hold))
1865 sid->down.by = sid->down.by0 - dy + sid->down.b0y;
1868 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
1869 _elm_scroll_wanted_coordinates_update(sid, x, y);
1870 psd->api->pos_max_get(sid->pan_obj, &maxx, &maxy);
1871 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
1872 if (!sid->bounce_horiz)
1874 if (x <= minx) no_bounce_x_end = EINA_TRUE;
1875 if ((x - minx) >= maxx) no_bounce_x_end = EINA_TRUE;
1877 if (!sid->bounce_vert)
1879 if (y <= miny) no_bounce_y_end = EINA_TRUE;
1880 if ((y - miny) >= maxy) no_bounce_y_end = EINA_TRUE;
1883 ((sid->down.bounce_x_hold) && (sid->down.bounce_y_hold)) ||
1884 (no_bounce_x_end && no_bounce_y_end))
1886 _elm_scroll_anim_stop(sid);
1888 sid->down.momentum_animator = NULL;
1889 sid->down.bounce_x_hold = EINA_FALSE;
1890 sid->down.bounce_y_hold = EINA_FALSE;
1895 if (sid->content_info.resized)
1896 _elm_scroll_wanted_region_set(sid->obj);
1898 return ECORE_CALLBACK_CANCEL;
1902 return ECORE_CALLBACK_RENEW;
1906 _elm_scroll_page_x_get(Elm_Scrollable_Smart_Interface_Data *sid,
1907 int offset, Eina_Bool limit)
1909 Evas_Coord x, y, w, h, dx, cw, ch, minx = 0;
1911 if (!sid->pan_obj) return 0;
1913 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, 0);
1915 _elm_scroll_content_pos_get(sid->obj, &x, &y);
1916 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
1917 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1918 psd->api->pos_min_get(sid->pan_obj, &minx, NULL);
1920 if (sid->pagerel_h > 0.0)
1921 sid->pagesize_h = w * sid->pagerel_h;
1927 dx = (sid->pagesize_h * ((double)sid->page_limit_h - 0.5));
1930 x += (abs(offset) < dx ? offset : dx);
1932 x += (abs(offset) < dx ? offset : -dx);
1935 if (sid->pagesize_h > 0)
1937 x = x + (sid->pagesize_h * 0.5);
1938 x = x / (sid->pagesize_h);
1939 x = x * (sid->pagesize_h);
1941 if ((x + w) > cw) x = cw - w;
1942 if (x < minx) x = minx;
1948 _elm_scroll_page_y_get(Elm_Scrollable_Smart_Interface_Data *sid,
1949 int offset, Eina_Bool limit)
1951 Evas_Coord x, y, w, h, dy, cw, ch, miny = 0;
1953 if (!sid->pan_obj) return 0;
1955 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, 0);
1957 _elm_scroll_content_pos_get(sid->obj, &x, &y);
1958 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
1959 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1960 psd->api->pos_min_get(sid->pan_obj, NULL, &miny);
1962 if (sid->pagerel_v > 0.0)
1963 sid->pagesize_v = h * sid->pagerel_v;
1969 dy = (sid->pagesize_v * ((double)sid->page_limit_v - 0.5));
1972 y += (abs(offset) < dy ? offset : dy);
1974 y += (abs(offset) < dy ? offset : -dy);
1977 if (sid->pagesize_v > 0)
1979 y = y + (sid->pagesize_v * 0.5);
1980 y = y / (sid->pagesize_v);
1981 y = y * (sid->pagesize_v);
1983 if ((y + h) > ch) y = ch - h;
1984 if (y < miny) y = miny;
1990 _elm_scroll_scroll_to_x_animator(void *data)
1992 Elm_Scrollable_Smart_Interface_Data *sid = data;
1996 if (!sid->pan_obj) return ECORE_CALLBACK_CANCEL;
1998 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, ECORE_CALLBACK_CANCEL);
2000 t = ecore_loop_time_get();
2001 tt = (t - sid->scrollto.x.t_start) /
2002 (sid->scrollto.x.t_end - sid->scrollto.x.t_start);
2004 tt = 1.0 - (tt * tt);
2005 psd->api->pos_get(sid->pan_obj, &px, &py);
2006 px = (sid->scrollto.x.start * (1.0 - tt)) +
2007 (sid->scrollto.x.end * tt);
2008 if (t >= sid->scrollto.x.t_end)
2010 px = sid->scrollto.x.end;
2011 _elm_scroll_content_pos_set(sid->obj, px, py, EINA_TRUE);
2013 sid->down.x = sid->down.history[0].x;
2014 _elm_scroll_wanted_coordinates_update(sid, px, py);
2015 sid->scrollto.x.animator = NULL;
2016 if ((!sid->scrollto.y.animator) && (!sid->down.bounce_y_animator))
2017 _elm_scroll_anim_stop(sid);
2018 return ECORE_CALLBACK_CANCEL;
2020 _elm_scroll_content_pos_set(sid->obj, px, py, EINA_TRUE);
2021 _elm_scroll_wanted_coordinates_update(sid, px, py);
2022 return ECORE_CALLBACK_RENEW;
2026 _elm_scroll_scroll_to_y_animator(void *data)
2028 Elm_Scrollable_Smart_Interface_Data *sid = data;
2032 if (!sid->pan_obj) return EINA_FALSE;
2034 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, EINA_FALSE);
2036 t = ecore_loop_time_get();
2037 tt = (t - sid->scrollto.y.t_start) /
2038 (sid->scrollto.y.t_end - sid->scrollto.y.t_start);
2040 tt = 1.0 - (tt * tt);
2041 psd->api->pos_get(sid->pan_obj, &px, &py);
2042 py = (sid->scrollto.y.start * (1.0 - tt)) +
2043 (sid->scrollto.y.end * tt);
2044 if (t >= sid->scrollto.y.t_end)
2046 py = sid->scrollto.y.end;
2047 _elm_scroll_content_pos_set(sid->obj, px, py, EINA_TRUE);
2049 sid->down.y = sid->down.history[0].y;
2050 _elm_scroll_wanted_coordinates_update(sid, px, py);
2051 sid->scrollto.y.animator = NULL;
2052 if ((!sid->scrollto.x.animator) && (!sid->down.bounce_x_animator))
2053 _elm_scroll_anim_stop(sid);
2054 return ECORE_CALLBACK_CANCEL;
2056 _elm_scroll_content_pos_set(sid->obj, px, py, EINA_TRUE);
2057 _elm_scroll_wanted_coordinates_update(sid, px, py);
2059 return ECORE_CALLBACK_RENEW;
2063 _elm_scroll_scroll_to_y(Elm_Scrollable_Smart_Interface_Data *sid,
2067 Evas_Coord px, py, x, y, w, h;
2070 if (!sid->pan_obj) return;
2072 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2074 if (sid->freeze) return;
2077 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2078 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
2080 _elm_scroll_content_region_set(sid->obj, x, y, w, h);
2083 t = ecore_loop_time_get();
2084 psd->api->pos_get(sid->pan_obj, &px, &py);
2085 sid->scrollto.y.start = py;
2086 sid->scrollto.y.end = pos_y;
2087 sid->scrollto.y.t_start = t;
2088 sid->scrollto.y.t_end = t + t_in;
2089 if (!sid->scrollto.y.animator)
2091 sid->scrollto.y.animator =
2092 ecore_animator_add(_elm_scroll_scroll_to_y_animator, sid);
2093 if (!sid->scrollto.x.animator)
2094 _elm_scroll_anim_start(sid);
2096 if (sid->down.bounce_y_animator)
2098 ecore_animator_del(sid->down.bounce_y_animator);
2099 sid->down.bounce_y_animator = NULL;
2100 _elm_scroll_momentum_end(sid);
2101 if (sid->content_info.resized)
2102 _elm_scroll_wanted_region_set(sid->obj);
2104 sid->bouncemey = EINA_FALSE;
2108 _elm_scroll_scroll_to_x(Elm_Scrollable_Smart_Interface_Data *sid,
2112 Evas_Coord px, py, x, y, w, h;
2115 if (!sid->pan_obj) return;
2117 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2119 if (sid->freeze) return;
2122 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2123 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
2125 _elm_scroll_content_region_set(sid->obj, x, y, w, h);
2128 t = ecore_loop_time_get();
2129 psd->api->pos_get(sid->pan_obj, &px, &py);
2130 sid->scrollto.x.start = px;
2131 sid->scrollto.x.end = pos_x;
2132 sid->scrollto.x.t_start = t;
2133 sid->scrollto.x.t_end = t + t_in;
2134 if (!sid->scrollto.x.animator)
2136 sid->scrollto.x.animator =
2137 ecore_animator_add(_elm_scroll_scroll_to_x_animator, sid);
2138 if (!sid->scrollto.y.animator)
2139 _elm_scroll_anim_start(sid);
2141 if (sid->down.bounce_x_animator)
2143 ecore_animator_del(sid->down.bounce_x_animator);
2144 sid->down.bounce_x_animator = NULL;
2145 _elm_scroll_momentum_end(sid);
2146 if (sid->content_info.resized)
2147 _elm_scroll_wanted_region_set(sid->obj);
2149 sid->bouncemex = EINA_FALSE;
2153 _elm_scroll_mouse_up_event_cb(void *data,
2155 Evas_Object *obj __UNUSED__,
2158 Elm_Scrollable_Smart_Interface_Data *sid = data;
2159 Evas_Coord x = 0, y = 0, ox = 0, oy = 0;
2160 Evas_Event_Mouse_Down *ev;
2162 if (!sid->pan_obj) return;
2164 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2167 sid->down.hold_parent = EINA_FALSE;
2170 evas_post_event_callback_push(e, _elm_scroll_post_event_up, sid);
2172 // FIXME: respect elm_widget_scroll_hold_get of parent container
2173 if (!_elm_config->thumbscroll_enable) return;
2175 if (ev->button == 1)
2177 if (sid->down.onhold_animator)
2179 ecore_animator_del(sid->down.onhold_animator);
2180 sid->down.onhold_animator = NULL;
2181 if (sid->content_info.resized)
2182 _elm_scroll_wanted_region_set(sid->obj);
2184 x = ev->canvas.x - sid->down.x;
2185 y = ev->canvas.y - sid->down.y;
2186 if (sid->down.dragged)
2188 _elm_scroll_drag_stop(sid);
2189 if ((!sid->hold) && (!sid->freeze))
2193 Evas_Coord ax, ay, dx, dy, vel;
2196 t = ev->timestamp / 1000.0;
2198 t = ecore_loop_time_get();
2201 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2206 DBG("------ %i %i\n", ev->canvas.x, ev->canvas.y);
2208 for (i = 0; i < 60; i++)
2210 dt = t - sid->down.history[i].timestamp;
2211 if (dt > 0.2) break;
2213 DBG("H: %i %i @ %1.3f\n",
2214 sid->down.history[i].x,
2215 sid->down.history[i].y, dt);
2218 ax += sid->down.history[i].x;
2219 ay += sid->down.history[i].y;
2224 at /= _elm_config->thumbscroll_sensitivity_friction;
2225 dx = ev->canvas.x - ax;
2226 dy = ev->canvas.y - ay;
2229 vel = sqrt((dx * dx) + (dy * dy)) / at;
2230 if ((_elm_config->thumbscroll_friction > 0.0) &&
2231 (vel > _elm_config->thumbscroll_momentum_threshold))
2233 sid->down.dx = ((double)dx / at);
2234 sid->down.dy = ((double)dy / at);
2235 sid->down.extra_time = 0.0;
2236 sid->down.pdx = sid->down.dx;
2237 sid->down.pdy = sid->down.dy;
2240 if (!_paging_is_enabled(sid))
2242 if ((!sid->down.momentum_animator) &&
2243 (!sid->momentum_animator_disabled) &&
2245 (!elm_widget_drag_child_locked_y_get
2248 sid->down.momentum_animator =
2250 (_elm_scroll_momentum_animator, sid);
2252 EVAS_EVENT_FLAG_ON_SCROLL;
2253 _elm_scroll_anim_start(sid);
2255 sid->down.anim_start = ecore_loop_time_get();
2256 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2270 evas_event_feed_hold(e, 0, ev->timestamp, ev->data);
2271 if (_paging_is_enabled(sid))
2273 Evas_Coord pgx, pgy;
2275 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2277 (!elm_widget_drag_child_locked_x_get
2280 pgx = _elm_scroll_page_x_get(sid, ox, EINA_TRUE);
2283 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2284 _elm_scroll_scroll_to_x
2285 (sid, _elm_config->page_scroll_friction, pgx);
2289 (!elm_widget_drag_child_locked_y_get
2292 pgy = _elm_scroll_page_y_get(sid, oy, EINA_TRUE);
2295 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2296 _elm_scroll_scroll_to_y
2297 (sid, _elm_config->page_scroll_friction, pgy);
2306 if (_paging_is_enabled(sid))
2308 Evas_Coord pgx, pgy;
2310 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2312 (!elm_widget_drag_child_locked_x_get
2315 pgx = _elm_scroll_page_x_get(sid, ox, EINA_TRUE);
2317 _elm_scroll_scroll_to_x
2318 (sid, _elm_config->page_scroll_friction, pgx);
2321 (!elm_widget_drag_child_locked_y_get
2324 pgy = _elm_scroll_page_y_get(sid, oy, EINA_TRUE);
2326 _elm_scroll_scroll_to_y
2327 (sid, _elm_config->page_scroll_friction, pgy);
2331 if (sid->down.hold_animator)
2333 ecore_animator_del(sid->down.hold_animator);
2334 sid->down.hold_animator = NULL;
2335 if (sid->content_info.resized)
2336 _elm_scroll_wanted_region_set(sid->obj);
2338 if (sid->down.scroll)
2340 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2341 sid->down.scroll = EINA_FALSE;
2345 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2346 sid->down.hold = EINA_FALSE;
2348 sid->down.dragged_began = EINA_FALSE;
2349 sid->down.dir_x = EINA_FALSE;
2350 sid->down.dir_y = EINA_FALSE;
2351 sid->down.want_dragged = EINA_FALSE;
2352 sid->down.dragged = EINA_FALSE;
2353 sid->down.now = EINA_FALSE;
2354 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2355 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
2356 _elm_scroll_wanted_coordinates_update(sid, x, y);
2358 if (sid->content_info.resized)
2359 _elm_scroll_wanted_region_set(sid->obj);
2361 if (!_paging_is_enabled(sid))
2362 _elm_scroll_bounce_eval(sid);
2367 _elm_scroll_mouse_down_event_cb(void *data,
2369 Evas_Object *obj __UNUSED__,
2372 Elm_Scrollable_Smart_Interface_Data *sid;
2373 Evas_Event_Mouse_Down *ev;
2374 Evas_Coord x = 0, y = 0;
2379 if (_elm_config->thumbscroll_enable)
2381 sid->down.hold = EINA_FALSE;
2382 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
2383 (sid->down.momentum_animator) || (sid->scrollto.x.animator) ||
2384 (sid->scrollto.y.animator))
2386 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL |
2387 EVAS_EVENT_FLAG_ON_HOLD;
2388 sid->down.scroll = EINA_TRUE;
2389 sid->down.hold = EINA_TRUE;
2390 _elm_scroll_anim_stop(sid);
2392 if (sid->scrollto.x.animator)
2394 ecore_animator_del(sid->scrollto.x.animator);
2395 sid->scrollto.x.animator = NULL;
2397 if (sid->scrollto.y.animator)
2399 ecore_animator_del(sid->scrollto.y.animator);
2400 sid->scrollto.y.animator = NULL;
2402 if (sid->down.bounce_x_animator)
2404 ecore_animator_del(sid->down.bounce_x_animator);
2405 sid->down.bounce_x_animator = NULL;
2406 sid->bouncemex = EINA_FALSE;
2407 if (sid->content_info.resized)
2408 _elm_scroll_wanted_region_set(sid->obj);
2410 if (sid->down.bounce_y_animator)
2412 ecore_animator_del(sid->down.bounce_y_animator);
2413 sid->down.bounce_y_animator = NULL;
2414 sid->bouncemey = EINA_FALSE;
2415 if (sid->content_info.resized)
2416 _elm_scroll_wanted_region_set(sid->obj);
2418 if (sid->down.hold_animator)
2420 ecore_animator_del(sid->down.hold_animator);
2421 sid->down.hold_animator = NULL;
2422 _elm_scroll_drag_stop(sid);
2423 if (sid->content_info.resized)
2424 _elm_scroll_wanted_region_set(sid->obj);
2426 if (sid->down.momentum_animator)
2428 ecore_animator_del(sid->down.momentum_animator);
2429 sid->down.momentum_animator = NULL;
2430 sid->down.bounce_x_hold = EINA_FALSE;
2431 sid->down.bounce_y_hold = EINA_FALSE;
2434 if (sid->content_info.resized)
2435 _elm_scroll_wanted_region_set(sid->obj);
2437 if (ev->button == 1)
2439 sid->down.hist.est_timestamp_diff =
2440 ecore_loop_time_get() - ((double)ev->timestamp / 1000.0);
2441 sid->down.hist.tadd = 0.0;
2442 sid->down.hist.dxsum = 0.0;
2443 sid->down.hist.dysum = 0.0;
2444 sid->down.now = EINA_TRUE;
2445 sid->down.dragged = EINA_FALSE;
2446 sid->down.dir_x = EINA_FALSE;
2447 sid->down.dir_y = EINA_FALSE;
2448 sid->down.x = ev->canvas.x;
2449 sid->down.y = ev->canvas.y;
2450 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2453 sid->down.locked = EINA_FALSE;
2454 memset(&(sid->down.history[0]), 0,
2455 sizeof(sid->down.history[0]) * 60);
2457 sid->down.history[0].timestamp = ev->timestamp / 1000.0;
2458 sid->down.history[0].localtimestamp = ecore_loop_time_get();
2460 sid->down.history[0].timestamp = ecore_loop_time_get();
2462 sid->down.history[0].x = ev->canvas.x;
2463 sid->down.history[0].y = ev->canvas.y;
2465 sid->down.dragged_began = EINA_FALSE;
2466 sid->down.hold_parent = EINA_FALSE;
2467 sid->down.cancelled = EINA_FALSE;
2468 if (sid->hold || sid->freeze)
2469 sid->down.want_reset = EINA_TRUE;
2471 sid->down.want_reset = EINA_FALSE;
2476 _elm_scroll_can_scroll(Elm_Scrollable_Smart_Interface_Data *sid,
2479 Evas_Coord mx = 0, my = 0, px = 0, py = 0, minx = 0, miny = 0;
2481 if (!sid->pan_obj) return EINA_FALSE;
2483 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, EINA_FALSE);
2485 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
2486 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
2487 psd->api->pos_get(sid->pan_obj, &px, &py);
2491 if (px > minx) return EINA_TRUE;
2495 if ((px - minx) < mx) return EINA_TRUE;
2499 if (py > miny) return EINA_TRUE;
2503 if ((py - miny) < my) return EINA_TRUE;
2513 _elm_scroll_post_event_move(void *data,
2516 Elm_Scrollable_Smart_Interface_Data *sid = data;
2518 if (sid->down.want_dragged)
2522 if (sid->down.hold_parent)
2524 if ((sid->down.dir_x) &&
2525 !_elm_scroll_can_scroll(sid, sid->down.hdir))
2527 sid->down.dir_x = EINA_FALSE;
2529 if ((sid->down.dir_y) &&
2530 !_elm_scroll_can_scroll(sid, sid->down.vdir))
2532 sid->down.dir_y = EINA_FALSE;
2535 if (sid->down.dir_x)
2538 (!elm_widget_drag_child_locked_x_get(sid->obj)))
2540 sid->down.want_dragged = EINA_FALSE;
2541 sid->down.dragged = EINA_TRUE;
2544 elm_widget_drag_lock_x_set(sid->obj, 1);
2549 sid->down.dir_x = EINA_FALSE;
2551 if (sid->down.dir_y)
2554 (!elm_widget_drag_child_locked_y_get(sid->obj)))
2556 sid->down.want_dragged = EINA_FALSE;
2557 sid->down.dragged = EINA_TRUE;
2560 elm_widget_drag_lock_y_set
2561 (sid->obj, EINA_TRUE);
2566 sid->down.dir_y = EINA_FALSE;
2568 if ((!sid->down.dir_x) && (!sid->down.dir_y))
2570 sid->down.cancelled = EINA_TRUE;
2572 if (start) _elm_scroll_drag_start(sid);
2579 _elm_scroll_down_coord_eval(Elm_Scrollable_Smart_Interface_Data *sid,
2583 Evas_Coord minx, miny;
2585 if (!sid->pan_obj) return;
2587 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2589 if (sid->down.dir_x) *x = sid->down.sx - (*x - sid->down.x);
2590 else *x = sid->down.sx;
2591 if (sid->down.dir_y) *y = sid->down.sy - (*y - sid->down.y);
2592 else *y = sid->down.sy;
2594 if ((sid->down.dir_x) || (sid->down.dir_y))
2596 if (!((sid->down.dir_x) && (sid->down.dir_y)))
2598 if (sid->down.dir_x) *y = sid->down.locked_y;
2599 else *x = sid->down.locked_x;
2603 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
2606 *x += (minx - *x) * _elm_config->thumbscroll_border_friction;
2607 else if (sid->content_info.w <= sid->w)
2608 *x += (sid->down.sx - *x) * _elm_config->thumbscroll_border_friction;
2609 else if ((sid->content_info.w - sid->w + minx) < *x)
2610 *x += (sid->content_info.w - sid->w + minx - *x) *
2611 _elm_config->thumbscroll_border_friction;
2614 *y += (miny - *y) * _elm_config->thumbscroll_border_friction;
2615 else if (sid->content_info.h <= sid->h)
2616 *y += (sid->down.sy - *y) * _elm_config->thumbscroll_border_friction;
2617 else if ((sid->content_info.h - sid->h + miny) < *y)
2618 *y += (sid->content_info.h - sid->h + miny - *y) *
2619 _elm_config->thumbscroll_border_friction;
2623 _elm_scroll_hold_animator(void *data)
2625 Elm_Scrollable_Smart_Interface_Data *sid = data;
2626 Evas_Coord ox = 0, oy = 0, fx = 0, fy = 0;
2628 fx = sid->down.hold_x;
2629 fy = sid->down.hold_y;
2631 _elm_scroll_content_pos_get(sid->obj, &ox, &oy);
2632 if (sid->down.dir_x)
2635 (!elm_widget_drag_child_locked_x_get(sid->obj)))
2638 if (sid->down.dir_y)
2641 (!elm_widget_drag_child_locked_y_get(sid->obj)))
2645 _elm_scroll_content_pos_set(sid->obj, ox, oy, EINA_TRUE);
2647 return ECORE_CALLBACK_RENEW;
2651 _elm_scroll_on_hold_animator(void *data)
2655 Evas_Coord x, y, ox, oy;
2656 Elm_Scrollable_Smart_Interface_Data *sid;
2659 t = ecore_loop_time_get();
2660 if (sid->down.onhold_tlast > 0.0)
2662 td = t - sid->down.onhold_tlast;
2663 vx = sid->down.onhold_vx * td *
2664 (double)_elm_config->thumbscroll_hold_threshold * 2.0;
2665 vy = sid->down.onhold_vy * td *
2666 (double)_elm_config->thumbscroll_hold_threshold * 2.0;
2667 _elm_scroll_content_pos_get(sid->obj, &ox, &oy);
2671 if (sid->down.dir_x)
2674 (!elm_widget_drag_child_locked_x_get(sid->obj)))
2676 sid->down.onhold_vxe += vx;
2677 x = ox + (int)sid->down.onhold_vxe;
2678 sid->down.onhold_vxe -= (int)sid->down.onhold_vxe;
2682 if (sid->down.dir_y)
2685 (!elm_widget_drag_child_locked_y_get(sid->obj)))
2687 sid->down.onhold_vye += vy;
2688 y = oy + (int)sid->down.onhold_vye;
2689 sid->down.onhold_vye -= (int)sid->down.onhold_vye;
2693 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
2695 sid->down.onhold_tlast = t;
2697 return ECORE_CALLBACK_RENEW;
2701 _elm_scroll_mouse_move_event_cb(void *data,
2703 Evas_Object *obj __UNUSED__,
2706 Elm_Scrollable_Smart_Interface_Data *sid = data;
2707 Evas_Event_Mouse_Move *ev;
2708 Evas_Coord x = 0, y = 0;
2710 if (!sid->pan_obj) return;
2712 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2715 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
2716 sid->down.hold_parent = EINA_TRUE;
2717 evas_post_event_callback_push(e, _elm_scroll_post_event_move, sid);
2719 // FIXME: respect elm_widget_scroll_hold_get of parent container
2720 if (_elm_config->thumbscroll_enable)
2724 if ((sid->scrollto.x.animator) && (!sid->hold) && (!sid->freeze))
2727 ecore_animator_del(sid->scrollto.x.animator);
2728 sid->scrollto.x.animator = NULL;
2729 psd->api->pos_get(sid->pan_obj, &px, NULL);
2731 sid->down.x = sid->down.history[0].x;
2734 if ((sid->scrollto.y.animator) && (!sid->hold) && (!sid->freeze))
2737 ecore_animator_del(sid->scrollto.y.animator);
2738 sid->scrollto.y.animator = NULL;
2739 psd->api->pos_get(sid->pan_obj, NULL, &py);
2741 sid->down.y = sid->down.history[0].y;
2745 DBG("::: %i %i\n", ev->cur.canvas.x, ev->cur.canvas.y);
2747 memmove(&(sid->down.history[1]), &(sid->down.history[0]),
2748 sizeof(sid->down.history[0]) * (60 - 1));
2750 sid->down.history[0].timestamp = ev->timestamp / 1000.0;
2751 sid->down.history[0].localtimestamp = ecore_loop_time_get();
2753 sid->down.history[0].timestamp = ecore_loop_time_get();
2755 sid->down.history[0].x = ev->cur.canvas.x;
2756 sid->down.history[0].y = ev->cur.canvas.y;
2758 if (!sid->down.dragged_began)
2760 x = ev->cur.canvas.x - sid->down.x;
2761 y = ev->cur.canvas.y - sid->down.y;
2763 sid->down.hdir = -1;
2764 sid->down.vdir = -1;
2766 if (x > 0) sid->down.hdir = LEFT;
2768 sid->down.hdir = RIGHT;
2769 if (y > 0) sid->down.vdir = UP;
2771 sid->down.vdir = DOWN;
2776 if (sid->one_direction_at_a_time)
2778 if (!((sid->down.dir_x) || (sid->down.dir_y)) &&
2779 (((x * x) + (y * y)) >
2780 (_elm_config->thumbscroll_threshold *
2781 _elm_config->thumbscroll_threshold)))
2783 if (sid->one_direction_at_a_time ==
2784 ELM_SCROLLER_SINGLE_DIRECTION_SOFT)
2789 sid->down.dir_x = EINA_TRUE;
2790 sid->down.dir_y = EINA_FALSE;
2795 sid->down.dir_x = EINA_FALSE;
2796 sid->down.dir_y = EINA_TRUE;
2801 sid->down.dir_x = EINA_TRUE;
2802 sid->down.dir_y = EINA_TRUE;
2805 else if (sid->one_direction_at_a_time ==
2806 ELM_SCROLLER_SINGLE_DIRECTION_HARD)
2810 sid->down.dir_x = EINA_TRUE;
2811 sid->down.dir_y = EINA_FALSE;
2815 sid->down.dir_x = EINA_FALSE;
2816 sid->down.dir_y = EINA_TRUE;
2823 sid->down.dir_x = EINA_TRUE;
2824 sid->down.dir_y = EINA_TRUE;
2827 if ((!sid->hold) && (!sid->freeze))
2829 if ((sid->down.dragged) ||
2830 (((x * x) + (y * y)) >
2831 (_elm_config->thumbscroll_threshold *
2832 _elm_config->thumbscroll_threshold)))
2834 sid->down.dragged_began = EINA_TRUE;
2835 if (!sid->down.dragged)
2837 sid->down.want_dragged = EINA_TRUE;
2838 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2840 if (sid->down.dragged)
2842 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2844 if (sid->down.dir_x)
2845 x = sid->down.sx - (ev->cur.canvas.x - sid->down.x);
2848 if (sid->down.dir_y)
2849 y = sid->down.sy - (ev->cur.canvas.y - sid->down.y);
2852 if (sid->down.want_reset)
2854 sid->down.x = ev->cur.canvas.x;
2855 sid->down.y = ev->cur.canvas.y;
2856 sid->down.want_reset = EINA_FALSE;
2858 if ((sid->down.dir_x) || (sid->down.dir_y))
2860 if (!sid->down.locked)
2862 sid->down.locked_x = x;
2863 sid->down.locked_y = y;
2864 sid->down.locked = EINA_TRUE;
2866 if (!((sid->down.dir_x) && (sid->down.dir_y)))
2868 if (sid->down.dir_x) y = sid->down.locked_y;
2869 else x = sid->down.locked_x;
2873 Evas_Coord minx, miny, mx, my;
2875 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
2876 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
2879 _elm_config->thumbscroll_border_friction;
2881 y += (sid->down.sy - y) *
2882 _elm_config->thumbscroll_border_friction;
2883 else if ((my + miny) < y)
2884 y += (my + miny - y) *
2885 _elm_config->thumbscroll_border_friction;
2888 _elm_config->thumbscroll_border_friction;
2890 x += (sid->down.sx - x) *
2891 _elm_config->thumbscroll_border_friction;
2892 else if ((mx + minx) < x)
2893 x += (mx + minx - x) *
2894 _elm_config->thumbscroll_border_friction;
2897 sid->down.hold_x = x;
2898 sid->down.hold_y = y;
2899 if (!sid->down.hold_animator)
2900 sid->down.hold_animator =
2901 ecore_animator_add(_elm_scroll_hold_animator, sid);
2905 if (sid->down.dragged_began)
2907 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2908 if (!sid->down.hold)
2910 sid->down.hold = EINA_TRUE;
2911 evas_event_feed_hold
2912 (e, 1, ev->timestamp, ev->data);
2917 else if (!sid->freeze)
2919 double vx = 0.0, vy = 0.0;
2921 x = ev->cur.canvas.x - sid->x;
2922 y = ev->cur.canvas.y - sid->y;
2923 if (x < _elm_config->thumbscroll_hold_threshold)
2925 if (_elm_config->thumbscroll_hold_threshold > 0.0)
2926 vx = -(double)(_elm_config->thumbscroll_hold_threshold - x)
2927 / _elm_config->thumbscroll_hold_threshold;
2931 else if (x > (sid->w - _elm_config->thumbscroll_hold_threshold))
2933 if (_elm_config->thumbscroll_hold_threshold > 0.0)
2934 vx = (double)(_elm_config->thumbscroll_hold_threshold -
2936 _elm_config->thumbscroll_hold_threshold;
2940 if (y < _elm_config->thumbscroll_hold_threshold)
2942 if (_elm_config->thumbscroll_hold_threshold > 0.0)
2943 vy = -(double)(_elm_config->thumbscroll_hold_threshold - y)
2944 / _elm_config->thumbscroll_hold_threshold;
2948 else if (y > (sid->h - _elm_config->thumbscroll_hold_threshold))
2950 if (_elm_config->thumbscroll_hold_threshold > 0.0)
2951 vy = (double)(_elm_config->thumbscroll_hold_threshold -
2953 _elm_config->thumbscroll_hold_threshold;
2957 if ((vx != 0.0) || (vy != 0.0))
2959 sid->down.onhold_vx = vx;
2960 sid->down.onhold_vy = vy;
2961 if (!sid->down.onhold_animator)
2963 sid->down.onhold_vxe = 0.0;
2964 sid->down.onhold_vye = 0.0;
2965 sid->down.onhold_tlast = 0.0;
2966 sid->down.onhold_animator = ecore_animator_add
2967 (_elm_scroll_on_hold_animator, sid);
2972 if (sid->down.onhold_animator)
2974 ecore_animator_del(sid->down.onhold_animator);
2975 sid->down.onhold_animator = NULL;
2976 if (sid->content_info.resized)
2977 _elm_scroll_wanted_region_set(sid->obj);
2986 _elm_scroll_page_adjust(Elm_Scrollable_Smart_Interface_Data *sid)
2988 Evas_Coord x, y, w, h;
2990 if (!_paging_is_enabled(sid)) return;
2992 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
2994 x = _elm_scroll_page_x_get(sid, 0, EINA_TRUE);
2995 y = _elm_scroll_page_y_get(sid, 0, EINA_TRUE);
2997 _elm_scroll_content_region_set(sid->obj, x, y, w, h);
3001 _elm_scroll_reconfigure(Elm_Scrollable_Smart_Interface_Data *sid)
3003 _elm_scroll_scroll_bar_size_adjust(sid);
3004 _elm_scroll_page_adjust(sid);
3008 _on_edje_move(void *data,
3010 Evas_Object *edje_obj,
3011 void *event_info __UNUSED__)
3013 Elm_Scrollable_Smart_Interface_Data *sid = data;
3016 evas_object_geometry_get(edje_obj, &x, &y, NULL, NULL);
3021 _elm_scroll_reconfigure(sid);
3025 _on_edje_resize(void *data,
3027 Evas_Object *edje_obj,
3028 void *event_info __UNUSED__)
3030 Elm_Scrollable_Smart_Interface_Data *sid = data;
3033 evas_object_geometry_get(edje_obj, NULL, NULL, &w, &h);
3038 _elm_scroll_reconfigure(sid);
3039 _elm_scroll_wanted_region_set(sid->obj);
3043 _scroll_edje_object_attach(Evas_Object *obj)
3045 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3047 evas_object_event_callback_add
3048 (sid->edje_obj, EVAS_CALLBACK_RESIZE, _on_edje_resize, sid);
3049 evas_object_event_callback_add
3050 (sid->edje_obj, EVAS_CALLBACK_MOVE, _on_edje_move, sid);
3052 edje_object_signal_callback_add
3053 (sid->edje_obj, "drag", "elm.dragable.vbar", _elm_scroll_vbar_drag_cb,
3055 edje_object_signal_callback_add
3056 (sid->edje_obj, "drag,set", "elm.dragable.vbar",
3057 _elm_scroll_edje_drag_v_cb, sid);
3058 edje_object_signal_callback_add
3059 (sid->edje_obj, "drag,start", "elm.dragable.vbar",
3060 _elm_scroll_edje_drag_v_start_cb, sid);
3061 edje_object_signal_callback_add
3062 (sid->edje_obj, "drag,stop", "elm.dragable.vbar",
3063 _elm_scroll_edje_drag_v_stop_cb, sid);
3064 edje_object_signal_callback_add
3065 (sid->edje_obj, "drag,step", "elm.dragable.vbar",
3066 _elm_scroll_edje_drag_v_cb, sid);
3067 edje_object_signal_callback_add
3068 (sid->edje_obj, "drag,page", "elm.dragable.vbar",
3069 _elm_scroll_edje_drag_v_cb, sid);
3070 edje_object_signal_callback_add
3071 (sid->edje_obj, "elm,vbar,press", "elm",
3072 _elm_scroll_vbar_press_cb, sid);
3073 edje_object_signal_callback_add
3074 (sid->edje_obj, "elm,vbar,unpress", "elm",
3075 _elm_scroll_vbar_unpress_cb, sid);
3076 edje_object_signal_callback_add
3077 (sid->edje_obj, "drag", "elm.dragable.hbar", _elm_scroll_hbar_drag_cb,
3079 edje_object_signal_callback_add
3080 (sid->edje_obj, "drag,set", "elm.dragable.hbar",
3081 _elm_scroll_edje_drag_h_cb, sid);
3082 edje_object_signal_callback_add
3083 (sid->edje_obj, "drag,start", "elm.dragable.hbar",
3084 _elm_scroll_edje_drag_h_start_cb, sid);
3085 edje_object_signal_callback_add
3086 (sid->edje_obj, "drag,stop", "elm.dragable.hbar",
3087 _elm_scroll_edje_drag_h_stop_cb, sid);
3088 edje_object_signal_callback_add
3089 (sid->edje_obj, "drag,step", "elm.dragable.hbar",
3090 _elm_scroll_edje_drag_h_cb, sid);
3091 edje_object_signal_callback_add
3092 (sid->edje_obj, "drag,page", "elm.dragable.hbar",
3093 _elm_scroll_edje_drag_h_cb, sid);
3094 edje_object_signal_callback_add
3095 (sid->edje_obj, "elm,hbar,press", "elm",
3096 _elm_scroll_hbar_press_cb, sid);
3097 edje_object_signal_callback_add
3098 (sid->edje_obj, "elm,hbar,unpress", "elm",
3099 _elm_scroll_hbar_unpress_cb, sid);
3103 _scroll_event_object_attach(Evas_Object *obj)
3105 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3107 evas_object_event_callback_add
3108 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL, _elm_scroll_wheel_event_cb,
3110 evas_object_event_callback_add
3111 (sid->event_rect, EVAS_CALLBACK_MOUSE_DOWN,
3112 _elm_scroll_mouse_down_event_cb, sid);
3113 evas_object_event_callback_add
3114 (sid->event_rect, EVAS_CALLBACK_MOUSE_UP,
3115 _elm_scroll_mouse_up_event_cb, sid);
3116 evas_object_event_callback_add
3117 (sid->event_rect, EVAS_CALLBACK_MOUSE_MOVE,
3118 _elm_scroll_mouse_move_event_cb, sid);
3122 _scroll_edje_object_detach(Evas_Object *obj)
3124 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3126 evas_object_event_callback_del_full
3127 (sid->edje_obj, EVAS_CALLBACK_RESIZE, _on_edje_resize, sid);
3128 evas_object_event_callback_del_full
3129 (sid->edje_obj, EVAS_CALLBACK_MOVE, _on_edje_move, sid);
3131 edje_object_signal_callback_del_full
3132 (sid->edje_obj, "drag", "elm.dragable.vbar", _elm_scroll_vbar_drag_cb,
3134 edje_object_signal_callback_del_full
3135 (sid->edje_obj, "drag,set", "elm.dragable.vbar",
3136 _elm_scroll_edje_drag_v_cb, sid);
3137 edje_object_signal_callback_del_full
3138 (sid->edje_obj, "drag,start", "elm.dragable.vbar",
3139 _elm_scroll_edje_drag_v_start_cb, sid);
3140 edje_object_signal_callback_del_full
3141 (sid->edje_obj, "drag,stop", "elm.dragable.vbar",
3142 _elm_scroll_edje_drag_v_stop_cb, sid);
3143 edje_object_signal_callback_del_full
3144 (sid->edje_obj, "drag,step", "elm.dragable.vbar",
3145 _elm_scroll_edje_drag_v_cb, sid);
3146 edje_object_signal_callback_del_full
3147 (sid->edje_obj, "drag,page", "elm.dragable.vbar",
3148 _elm_scroll_edje_drag_v_cb, sid);
3149 edje_object_signal_callback_del_full
3150 (sid->edje_obj, "elm,vbar,press", "elm",
3151 _elm_scroll_vbar_press_cb, sid);
3152 edje_object_signal_callback_del_full
3153 (sid->edje_obj, "elm,vbar,unpress", "elm",
3154 _elm_scroll_vbar_unpress_cb, sid);
3155 edje_object_signal_callback_del_full
3156 (sid->edje_obj, "drag", "elm.dragable.hbar", _elm_scroll_hbar_drag_cb,
3158 edje_object_signal_callback_del_full
3159 (sid->edje_obj, "drag,set", "elm.dragable.hbar",
3160 _elm_scroll_edje_drag_h_cb, sid);
3161 edje_object_signal_callback_del_full
3162 (sid->edje_obj, "drag,start", "elm.dragable.hbar",
3163 _elm_scroll_edje_drag_h_start_cb, sid);
3164 edje_object_signal_callback_del_full
3165 (sid->edje_obj, "drag,stop", "elm.dragable.hbar",
3166 _elm_scroll_edje_drag_h_stop_cb, sid);
3167 edje_object_signal_callback_del_full
3168 (sid->edje_obj, "drag,step", "elm.dragable.hbar",
3169 _elm_scroll_edje_drag_h_cb, sid);
3170 edje_object_signal_callback_del_full
3171 (sid->edje_obj, "drag,page", "elm.dragable.hbar",
3172 _elm_scroll_edje_drag_h_cb, sid);
3173 edje_object_signal_callback_del_full
3174 (sid->edje_obj, "elm,hbar,press", "elm",
3175 _elm_scroll_hbar_press_cb, sid);
3176 edje_object_signal_callback_del_full
3177 (sid->edje_obj, "elm,hbar,unpress", "elm",
3178 _elm_scroll_hbar_unpress_cb, sid);
3182 _scroll_event_object_detach(Evas_Object *obj)
3184 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3186 evas_object_event_callback_del_full
3187 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL, _elm_scroll_wheel_event_cb,
3189 evas_object_event_callback_del_full
3190 (sid->event_rect, EVAS_CALLBACK_MOUSE_DOWN,
3191 _elm_scroll_mouse_down_event_cb, sid);
3192 evas_object_event_callback_del_full
3193 (sid->event_rect, EVAS_CALLBACK_MOUSE_UP,
3194 _elm_scroll_mouse_up_event_cb, sid);
3195 evas_object_event_callback_del_full
3196 (sid->event_rect, EVAS_CALLBACK_MOUSE_MOVE,
3197 _elm_scroll_mouse_move_event_cb, sid);
3201 _elm_scroll_objects_set(Evas_Object *obj,
3202 Evas_Object *edje_object,
3203 Evas_Object *hit_rectangle)
3207 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3209 if (!edje_object || !hit_rectangle) return;
3212 _scroll_edje_object_detach(obj);
3214 sid->edje_obj = edje_object;
3216 if (sid->event_rect)
3217 _scroll_event_object_detach(obj);
3219 sid->event_rect = hit_rectangle;
3220 evas_object_repeat_events_set(hit_rectangle, EINA_TRUE);
3222 _scroll_edje_object_attach(obj);
3223 _scroll_event_object_attach(obj);
3226 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
3227 if (edje_object_part_exists(sid->edje_obj, "elm.scrollbar.base"))
3231 base = edje_object_part_swallow_get
3232 (sid->edje_obj, "elm.scrollbar.base");
3235 base = evas_object_rectangle_add
3236 (evas_object_evas_get(sid->edje_obj));
3237 evas_object_color_set(base, 0, 0, 0, 0);
3238 edje_object_part_swallow
3239 (sid->edje_obj, "elm.scrollbar.base", base);
3241 if (!_elm_config->thumbscroll_enable)
3242 evas_object_size_hint_min_set(base, mw, mh);
3245 _elm_scroll_scroll_bar_visibility_adjust(sid);
3249 _elm_scroll_scroll_bar_reset(Elm_Scrollable_Smart_Interface_Data *sid)
3251 Evas_Coord px = 0, py = 0, minx = 0, miny = 0;
3253 if (!sid->edje_obj) return;
3255 edje_object_part_drag_value_set
3256 (sid->edje_obj, "elm.dragable.vbar", 0.0, 0.0);
3257 edje_object_part_drag_value_set
3258 (sid->edje_obj, "elm.dragable.hbar", 0.0, 0.0);
3259 if ((!sid->content) && (!sid->extern_pan))
3261 edje_object_part_drag_size_set
3262 (sid->edje_obj, "elm.dragable.vbar", 1.0, 1.0);
3263 edje_object_part_drag_size_set
3264 (sid->edje_obj, "elm.dragable.hbar", 1.0, 1.0);
3268 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
3270 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
3271 psd->api->pos_get(sid->pan_obj, &px, &py);
3272 psd->api->pos_set(sid->pan_obj, minx, miny);
3274 if ((px != minx) || (py != miny))
3275 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
3276 _elm_direction_arrows_eval(sid);
3279 /* even external pan objects get this */
3281 _elm_scroll_pan_changed_cb(void *data,
3282 Evas_Object *obj __UNUSED__,
3283 void *event_info __UNUSED__)
3286 Elm_Scrollable_Smart_Interface_Data *sid = data;
3288 if (!sid->pan_obj) return;
3290 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
3292 psd->api->content_size_get(sid->pan_obj, &w, &h);
3293 if ((w != sid->content_info.w) || (h != sid->content_info.h))
3295 sid->content_info.w = w;
3296 sid->content_info.h = h;
3297 _elm_scroll_scroll_bar_size_adjust(sid);
3299 evas_object_size_hint_min_set
3300 (sid->edje_obj, sid->content_info.w, sid->content_info.h);
3301 sid->content_info.resized = EINA_TRUE;
3302 _elm_scroll_wanted_region_set(sid->obj);
3307 _elm_scroll_content_del_cb(void *data,
3309 Evas_Object *obj __UNUSED__,
3310 void *event_info __UNUSED__)
3312 Elm_Scrollable_Smart_Interface_Data *sid = data;
3314 sid->content = NULL;
3315 _elm_scroll_scroll_bar_size_adjust(sid);
3316 _elm_scroll_scroll_bar_reset(sid);
3320 _elm_scroll_content_set(Evas_Object *obj,
3321 Evas_Object *content)
3326 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3328 if (!sid->edje_obj) return;
3332 /* if we had content, for sure we had a pan object */
3333 _elm_pan_content_set(sid->pan_obj, NULL);
3334 evas_object_event_callback_del_full
3335 (sid->content, EVAS_CALLBACK_DEL, _elm_scroll_content_del_cb, sid);
3338 sid->content = content;
3339 sid->wx = sid->wy = 0;
3340 /* (-1) means want viewports size */
3341 sid->ww = sid->wh = -1;
3342 if (!content) return;
3346 o = _elm_pan_add(evas_object_evas_get(obj));
3348 evas_object_smart_callback_add
3349 (o, SIG_CHANGED, _elm_scroll_pan_changed_cb, sid);
3350 edje_object_part_swallow(sid->edje_obj, "elm.swallow.content", o);
3353 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
3355 evas_object_event_callback_add
3356 (content, EVAS_CALLBACK_DEL, _elm_scroll_content_del_cb, sid);
3358 _elm_pan_content_set(sid->pan_obj, content);
3359 psd->api->content_size_get(sid->pan_obj, &w, &h);
3360 sid->content_info.w = w;
3361 sid->content_info.h = h;
3363 _elm_scroll_scroll_bar_size_adjust(sid);
3364 _elm_scroll_scroll_bar_reset(sid);
3368 _elm_scroll_extern_pan_set(Evas_Object *obj,
3371 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3373 if (!sid->edje_obj) return;
3375 _elm_scroll_content_set(obj, NULL);
3379 evas_object_smart_callback_del
3380 (sid->pan_obj, SIG_CHANGED, _elm_scroll_pan_changed_cb);
3383 if (sid->extern_pan)
3387 /* not owned by scroller, just leave (was external already) */
3388 edje_object_part_unswallow(sid->edje_obj, sid->pan_obj);
3389 sid->pan_obj = NULL;
3396 evas_object_del(sid->pan_obj);
3397 sid->pan_obj = NULL;
3402 sid->extern_pan = EINA_FALSE;
3408 sid->extern_pan = EINA_TRUE;
3409 evas_object_smart_callback_add
3410 (sid->pan_obj, SIG_CHANGED, _elm_scroll_pan_changed_cb, sid);
3411 edje_object_part_swallow
3412 (sid->edje_obj, "elm.swallow.content", sid->pan_obj);
3416 _elm_scroll_drag_start_cb_set(Evas_Object *obj,
3417 void (*drag_start_cb)(Evas_Object *obj,
3420 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3422 sid->cb_func.drag_start = drag_start_cb;
3426 _elm_scroll_drag_stop_cb_set(Evas_Object *obj,
3427 void (*drag_stop_cb)(Evas_Object *obj,
3430 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3432 sid->cb_func.drag_stop = drag_stop_cb;
3436 _elm_scroll_animate_start_cb_set(Evas_Object *obj,
3437 void (*animate_start_cb)(Evas_Object *obj,
3440 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3442 sid->cb_func.animate_start = animate_start_cb;
3446 _elm_scroll_animate_stop_cb_set(Evas_Object *obj,
3447 void (*animate_stop_cb)(Evas_Object *obj,
3450 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3452 sid->cb_func.animate_stop = animate_stop_cb;
3456 _elm_scroll_scroll_cb_set(Evas_Object *obj,
3457 void (*scroll_cb)(Evas_Object *obj,
3460 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3462 sid->cb_func.scroll = scroll_cb;
3466 _elm_scroll_scroll_left_cb_set(Evas_Object *obj,
3467 void (*scroll_left_cb)(Evas_Object *obj,
3470 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3472 sid->cb_func.scroll_left = scroll_left_cb;
3476 _elm_scroll_scroll_right_cb_set(Evas_Object *obj,
3477 void (*scroll_right_cb)(Evas_Object *obj,
3480 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3482 sid->cb_func.scroll_right = scroll_right_cb;
3486 _elm_scroll_scroll_up_cb_set(Evas_Object *obj,
3487 void (*scroll_up_cb)(Evas_Object *obj,
3490 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3492 sid->cb_func.scroll_up = scroll_up_cb;
3496 _elm_scroll_scroll_down_cb_set(Evas_Object *obj,
3497 void (*scroll_down_cb)(Evas_Object *obj,
3500 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3502 sid->cb_func.scroll_down = scroll_down_cb;
3506 _elm_scroll_edge_left_cb_set(Evas_Object *obj,
3507 void (*edge_left_cb)(Evas_Object *obj,
3510 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3512 sid->cb_func.edge_left = edge_left_cb;
3516 _elm_scroll_edge_right_cb_set(Evas_Object *obj,
3517 void (*edge_right_cb)(Evas_Object *obj,
3520 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3522 sid->cb_func.edge_right = edge_right_cb;
3526 _elm_scroll_edge_top_cb_set(Evas_Object *obj,
3527 void (*edge_top_cb)(Evas_Object *obj,
3530 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3532 sid->cb_func.edge_top = edge_top_cb;
3536 _elm_scroll_edge_bottom_cb_set(Evas_Object *obj,
3537 void (*edge_bottom_cb)(Evas_Object *obj,
3540 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3542 sid->cb_func.edge_bottom = edge_bottom_cb;
3546 _elm_scroll_vbar_drag_cb_set(Evas_Object *obj,
3547 void (*vbar_drag_cb)(Evas_Object *obj,
3550 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3552 sid->cb_func.vbar_drag = vbar_drag_cb;
3556 _elm_scroll_vbar_press_cb_set(Evas_Object *obj,
3557 void (*vbar_press_cb)(Evas_Object *obj,
3560 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3562 sid->cb_func.vbar_press = vbar_press_cb;
3566 _elm_scroll_vbar_unpress_cb_set(Evas_Object *obj,
3567 void (*vbar_unpress_cb)(Evas_Object *obj,
3570 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3572 sid->cb_func.vbar_unpress = vbar_unpress_cb;
3576 _elm_scroll_hbar_drag_cb_set(Evas_Object *obj,
3577 void (*hbar_drag_cb)(Evas_Object *obj,
3580 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3582 sid->cb_func.hbar_drag = hbar_drag_cb;
3586 _elm_scroll_hbar_press_cb_set(Evas_Object *obj,
3587 void (*hbar_press_cb)(Evas_Object *obj,
3590 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3592 sid->cb_func.hbar_press = hbar_press_cb;
3596 _elm_scroll_hbar_unpress_cb_set(Evas_Object *obj,
3597 void (*hbar_unpress_cb)(Evas_Object *obj,
3600 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3602 sid->cb_func.hbar_unpress = hbar_unpress_cb;
3606 _elm_scroll_content_min_limit_cb_set(Evas_Object *obj,
3607 void (*c_min_limit_cb)(Evas_Object *obj,
3611 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3613 sid->cb_func.content_min_limit = c_min_limit_cb;
3617 _elm_scroll_momentum_animator_disabled_get(const Evas_Object *obj)
3619 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
3621 return sid->momentum_animator_disabled;
3625 _elm_scroll_momentum_animator_disabled_set(Evas_Object *obj,
3628 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3630 sid->momentum_animator_disabled = disabled;
3631 if (sid->momentum_animator_disabled)
3633 if (sid->down.momentum_animator)
3635 ecore_animator_del(sid->down.momentum_animator);
3636 sid->down.momentum_animator = NULL;
3637 if (sid->content_info.resized)
3638 _elm_scroll_wanted_region_set(sid->obj);
3644 _elm_scroll_bounce_animator_disabled_get(const Evas_Object *obj)
3646 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
3648 return sid->bounce_animator_disabled;
3652 _elm_scroll_bounce_animator_disabled_set(Evas_Object *obj,
3655 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3657 sid->bounce_animator_disabled = disabled;
3658 if (sid->bounce_animator_disabled)
3660 if (sid->scrollto.x.animator)
3662 ecore_animator_del(sid->scrollto.x.animator);
3663 sid->scrollto.x.animator = NULL;
3666 if (sid->scrollto.y.animator)
3668 ecore_animator_del(sid->scrollto.y.animator);
3669 sid->scrollto.y.animator = NULL;
3675 _elm_scroll_wheel_disabled_get(const Evas_Object *obj)
3677 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
3679 return sid->wheel_disabled;
3683 _elm_scroll_wheel_disabled_set(Evas_Object *obj,
3686 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3688 if (!sid->event_rect) return;
3690 if ((!sid->wheel_disabled) && (disabled))
3691 evas_object_event_callback_del_full
3692 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL,
3693 _elm_scroll_wheel_event_cb, sid);
3694 else if ((sid->wheel_disabled) && (!disabled))
3695 evas_object_event_callback_add
3696 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL,
3697 _elm_scroll_wheel_event_cb, sid);
3698 sid->wheel_disabled = disabled;
3702 _elm_scroll_step_size_set(Evas_Object *obj,
3706 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3713 _elm_scroll_scroll_bar_size_adjust(sid);
3717 _elm_scroll_step_size_get(const Evas_Object *obj,
3721 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3723 if (x) *x = sid->step.x;
3724 if (y) *y = sid->step.y;
3728 _elm_scroll_page_size_set(Evas_Object *obj,
3732 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3737 _elm_scroll_scroll_bar_size_adjust(sid);
3741 _elm_scroll_page_size_get(const Evas_Object *obj,
3745 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3747 if (x) *x = sid->page.x;
3748 if (y) *y = sid->page.y;
3752 _elm_scroll_policy_set(Evas_Object *obj,
3753 Elm_Scroller_Policy hbar,
3754 Elm_Scroller_Policy vbar)
3756 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3758 if (!sid->edje_obj) return;
3760 if ((sid->hbar_flags == hbar) && (sid->vbar_flags == vbar)) return;
3762 sid->hbar_flags = hbar;
3763 sid->vbar_flags = vbar;
3764 if (sid->hbar_flags == ELM_SCROLLER_POLICY_ON)
3765 edje_object_signal_emit
3766 (sid->edje_obj, "elm,action,show_always,hbar", "elm");
3767 else if (sid->hbar_flags == ELM_SCROLLER_POLICY_OFF)
3768 edje_object_signal_emit
3769 (sid->edje_obj, "elm,action,hide,hbar", "elm");
3771 edje_object_signal_emit
3772 (sid->edje_obj, "elm,action,show_notalways,hbar", "elm");
3773 if (sid->vbar_flags == ELM_SCROLLER_POLICY_ON)
3774 edje_object_signal_emit
3775 (sid->edje_obj, "elm,action,show_always,vbar", "elm");
3776 else if (sid->vbar_flags == ELM_SCROLLER_POLICY_OFF)
3777 edje_object_signal_emit
3778 (sid->edje_obj, "elm,action,hide,vbar", "elm");
3780 edje_object_signal_emit
3781 (sid->edje_obj, "elm,action,show_notalways,vbar", "elm");
3782 edje_object_message_signal_process(sid->edje_obj);
3783 _elm_scroll_scroll_bar_size_adjust(sid);
3784 if (sid->cb_func.content_min_limit)
3785 sid->cb_func.content_min_limit(sid->obj, sid->min_w, sid->min_h);
3786 _elm_direction_arrows_eval(sid);
3790 _elm_scroll_policy_get(const Evas_Object *obj,
3791 Elm_Scroller_Policy *hbar,
3792 Elm_Scroller_Policy *vbar)
3794 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3796 if (hbar) *hbar = sid->hbar_flags;
3797 if (vbar) *vbar = sid->vbar_flags;
3801 _elm_scroll_single_direction_set(Evas_Object *obj,
3802 Elm_Scroller_Single_Direction single_dir)
3804 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3806 sid->one_direction_at_a_time = single_dir;
3809 static Elm_Scroller_Single_Direction
3810 _elm_scroll_single_direction_get(const Evas_Object *obj)
3812 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, ELM_SCROLLER_SINGLE_DIRECTION_SOFT);
3814 return sid->one_direction_at_a_time;
3818 _elm_scroll_repeat_events_set(Evas_Object *obj,
3819 Eina_Bool repeat_events)
3821 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3823 evas_object_repeat_events_set(sid->event_rect, repeat_events);
3827 _elm_scroll_repeat_events_get(const Evas_Object *obj)
3829 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
3831 return evas_object_repeat_events_get(sid->event_rect);
3835 _elm_scroll_hold_set(Evas_Object *obj,
3838 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3844 _elm_scroll_freeze_set(Evas_Object *obj,
3847 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3849 sid->freeze = freeze;
3852 if (sid->down.onhold_animator)
3854 ecore_animator_del(sid->down.onhold_animator);
3855 sid->down.onhold_animator = NULL;
3856 if (sid->content_info.resized)
3857 _elm_scroll_wanted_region_set(sid->obj);
3861 _elm_scroll_bounce_eval(sid);
3865 _elm_scroll_bounce_allow_set(Evas_Object *obj,
3869 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3871 sid->bounce_horiz = !!horiz;
3872 sid->bounce_vert = !!vert;
3876 _elm_scroll_bounce_allow_get(const Evas_Object *obj,
3880 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3882 if (horiz) *horiz = sid->bounce_horiz;
3883 if (vert) *vert = sid->bounce_vert;
3887 _elm_scroll_paging_set(Evas_Object *obj,
3890 Evas_Coord pagesize_h,
3891 Evas_Coord pagesize_v)
3893 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3895 sid->pagerel_h = pagerel_h;
3896 sid->pagerel_v = pagerel_v;
3897 sid->pagesize_h = pagesize_h;
3898 sid->pagesize_v = pagesize_v;
3900 _elm_scroll_page_adjust(sid);
3904 _elm_scroll_paging_get(const Evas_Object *obj,
3907 Evas_Coord *pagesize_h,
3908 Evas_Coord *pagesize_v)
3910 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3912 if (pagerel_h) *pagerel_h = sid->pagerel_h;
3913 if (pagerel_v) *pagerel_v = sid->pagerel_v;
3914 if (pagesize_h) *pagesize_h = sid->pagesize_h;
3915 if (pagesize_v) *pagesize_v = sid->pagesize_v;
3919 _elm_scroll_page_scroll_limit_set(const Evas_Object *obj,
3923 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3925 sid->page_limit_h = page_limit_h;
3926 sid->page_limit_v = page_limit_v;
3930 _elm_scroll_page_scroll_limit_get(const Evas_Object *obj,
3934 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3936 if (page_limit_h) *page_limit_h = sid->page_limit_h;
3937 if (page_limit_v) *page_limit_v = sid->page_limit_v;
3941 _elm_scroll_current_page_get(const Evas_Object *obj,
3947 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3949 _elm_scroll_content_pos_get(sid->obj, &x, &y);
3952 if (sid->pagesize_h > 0)
3953 *pagenumber_h = (x + sid->pagesize_h - 1) / sid->pagesize_h;
3959 if (sid->pagesize_v > 0)
3960 *pagenumber_v = (y + sid->pagesize_v - 1) / sid->pagesize_v;
3967 _elm_scroll_last_page_get(const Evas_Object *obj,
3973 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3975 if (!sid->pan_obj) return;
3977 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
3979 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
3982 if (sid->pagesize_h > 0)
3983 *pagenumber_h = cw / sid->pagesize_h + 1;
3989 if (sid->pagesize_v > 0)
3990 *pagenumber_v = ch / sid->pagesize_v + 1;
3997 _elm_scroll_page_show(Evas_Object *obj,
4005 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4007 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
4008 if (pagenumber_h >= 0) x = sid->pagesize_h * pagenumber_h;
4009 if (pagenumber_v >= 0) y = sid->pagesize_v * pagenumber_v;
4010 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
4011 _elm_scroll_content_pos_set(obj, x, y, EINA_TRUE);
4015 _elm_scroll_page_bring_in(Evas_Object *obj,
4023 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4025 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
4026 if (pagenumber_h >= 0) x = sid->pagesize_h * pagenumber_h;
4027 if (pagenumber_v >= 0) y = sid->pagesize_v * pagenumber_v;
4028 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
4030 _elm_scroll_scroll_to_x(sid, _elm_config->bring_in_scroll_friction, x);
4031 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, y);
4036 _elm_scroll_region_bring_in(Evas_Object *obj,
4042 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4044 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
4046 _elm_scroll_scroll_to_x(sid, _elm_config->bring_in_scroll_friction, x);
4047 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, y);
4052 _elm_scroll_gravity_set(Evas_Object *obj,
4056 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4058 if (!sid->pan_obj) return;
4060 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
4062 psd->api->gravity_set(sid->pan_obj, x, y);
4066 _elm_scroll_gravity_get(const Evas_Object *obj,
4070 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4072 if (!sid->pan_obj) return;
4074 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
4076 psd->api->gravity_get(sid->pan_obj, x, y);
4080 _elm_scroll_interface_add(Evas_Object *obj)
4082 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
4084 memset(sid, 0, sizeof(*sid));
4096 sid->page_limit_h = 9999;
4097 sid->page_limit_v = 9999;
4098 sid->hbar_flags = ELM_SCROLLER_POLICY_AUTO;
4099 sid->vbar_flags = ELM_SCROLLER_POLICY_AUTO;
4100 sid->hbar_visible = EINA_TRUE;
4101 sid->vbar_visible = EINA_TRUE;
4103 sid->bounce_horiz = EINA_TRUE;
4104 sid->bounce_vert = EINA_TRUE;
4106 sid->one_direction_at_a_time = ELM_SCROLLER_SINGLE_DIRECTION_SOFT;
4107 sid->momentum_animator_disabled = EINA_FALSE;
4108 sid->bounce_animator_disabled = EINA_FALSE;
4110 _elm_scroll_scroll_bar_reset(sid);
4116 _elm_scroll_interface_del(Evas_Object *obj)
4118 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4120 _elm_scroll_content_set(obj, NULL);
4121 if (!sid->extern_pan) evas_object_del(sid->pan_obj);
4123 if (sid->down.hold_animator)
4124 ecore_animator_del(sid->down.hold_animator);
4125 if (sid->down.onhold_animator)
4126 ecore_animator_del(sid->down.onhold_animator);
4127 if (sid->down.momentum_animator)
4128 ecore_animator_del(sid->down.momentum_animator);
4129 if (sid->down.bounce_x_animator)
4130 ecore_animator_del(sid->down.bounce_x_animator);
4131 if (sid->down.bounce_y_animator)
4132 ecore_animator_del(sid->down.bounce_y_animator);
4133 if (sid->scrollto.x.animator) ecore_animator_del(sid->scrollto.x.animator);
4134 if (sid->scrollto.y.animator) ecore_animator_del(sid->scrollto.y.animator);
4137 EAPI const char ELM_SCROLLABLE_IFACE_NAME[] = "elm_interface_scrollable";
4139 EAPI const Elm_Scrollable_Smart_Interface ELM_SCROLLABLE_IFACE =
4142 ELM_SCROLLABLE_IFACE_NAME,
4143 sizeof(Elm_Scrollable_Smart_Interface_Data),
4144 _elm_scroll_interface_add,
4145 _elm_scroll_interface_del
4148 _elm_scroll_objects_set,
4149 _elm_scroll_content_set,
4150 _elm_scroll_extern_pan_set,
4151 _elm_scroll_drag_start_cb_set,
4152 _elm_scroll_drag_stop_cb_set,
4153 _elm_scroll_animate_start_cb_set,
4154 _elm_scroll_animate_stop_cb_set,
4155 _elm_scroll_scroll_cb_set,
4156 _elm_scroll_scroll_left_cb_set,
4157 _elm_scroll_scroll_right_cb_set,
4158 _elm_scroll_scroll_up_cb_set,
4159 _elm_scroll_scroll_down_cb_set,
4160 _elm_scroll_edge_left_cb_set,
4161 _elm_scroll_edge_right_cb_set,
4162 _elm_scroll_edge_top_cb_set,
4163 _elm_scroll_edge_bottom_cb_set,
4164 _elm_scroll_vbar_drag_cb_set,
4165 _elm_scroll_vbar_press_cb_set,
4166 _elm_scroll_vbar_unpress_cb_set,
4167 _elm_scroll_hbar_drag_cb_set,
4168 _elm_scroll_hbar_press_cb_set,
4169 _elm_scroll_hbar_unpress_cb_set,
4170 _elm_scroll_content_min_limit_cb_set,
4171 _elm_scroll_content_pos_set,
4172 _elm_scroll_content_pos_get,
4173 _elm_scroll_content_region_show,
4174 _elm_scroll_content_region_set,
4175 _elm_scroll_content_size_get,
4176 _elm_scroll_content_viewport_size_get,
4177 _elm_scroll_content_min_limit,
4178 _elm_scroll_step_size_set,
4179 _elm_scroll_step_size_get,
4180 _elm_scroll_page_size_set,
4181 _elm_scroll_page_size_get,
4182 _elm_scroll_policy_set,
4183 _elm_scroll_policy_get,
4184 _elm_scroll_single_direction_set,
4185 _elm_scroll_single_direction_get,
4186 _elm_scroll_repeat_events_set,
4187 _elm_scroll_repeat_events_get,
4188 _elm_scroll_mirrored_set,
4189 _elm_scroll_hold_set,
4190 _elm_scroll_freeze_set,
4191 _elm_scroll_bounce_allow_set,
4192 _elm_scroll_bounce_allow_get,
4193 _elm_scroll_paging_set,
4194 _elm_scroll_paging_get,
4195 _elm_scroll_page_scroll_limit_set,
4196 _elm_scroll_page_scroll_limit_get,
4197 _elm_scroll_current_page_get,
4198 _elm_scroll_last_page_get,
4199 _elm_scroll_page_show,
4200 _elm_scroll_page_bring_in,
4201 _elm_scroll_region_bring_in,
4202 _elm_scroll_gravity_set,
4203 _elm_scroll_gravity_get,
4204 _elm_scroll_momentum_animator_disabled_get,
4205 _elm_scroll_momentum_animator_disabled_set,
4206 _elm_scroll_bounce_animator_disabled_set,
4207 _elm_scroll_bounce_animator_disabled_get,
4208 _elm_scroll_wheel_disabled_get,
4209 _elm_scroll_wheel_disabled_set