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 _elm_scroll_scroll_to_x(Elm_Scrollable_Smart_Interface_Data *sid,
41 _elm_scroll_scroll_to_y(Elm_Scrollable_Smart_Interface_Data *sid,
45 _elm_scroll_current_page_get(const Evas_Object *obj,
49 _elm_scroll_wanted_coordinates_update(Elm_Scrollable_Smart_Interface_Data *sid,
52 EAPI const Elm_Pan_Smart_Class *
53 elm_pan_smart_class_get(void)
55 static Elm_Pan_Smart_Class _sc =
56 ELM_PAN_SMART_CLASS_INIT_NAME_VERSION(PAN_SMART_NAME);
57 static const Elm_Pan_Smart_Class *class = NULL;
58 Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
63 _elm_pan_smart_set(&_sc);
64 esc->callbacks = _smart_callbacks;
71 _round(double value, int pos)
75 temp = value * pow( 10, pos );
76 temp = floor( temp + 0.5 );
77 temp *= pow( 10, -pos );
83 _elm_pan_update(Elm_Pan_Smart_Data *psd)
85 if (!psd->gravity_x && !psd->gravity_y)
87 evas_object_move(psd->content, psd->x - psd->px, psd->y - psd->py);
91 if ((!psd->px) && (!psd->py))
93 psd->px = psd->delta_posx * psd->gravity_x;
94 psd->py = psd->delta_posy * psd->gravity_y;
96 psd->delta_posx += psd->content_w - psd->prev_cw;
97 psd->prev_cw = psd->content_w;
98 psd->delta_posy += psd->content_h - psd->prev_ch;
99 psd->prev_ch = psd->content_h;
101 evas_object_move(psd->content, psd->x - psd->px, psd->y - psd->py);
102 psd->px = psd->delta_posx * psd->gravity_x;
103 psd->py = psd->delta_posy * psd->gravity_y;
107 _elm_pan_smart_add(Evas_Object *obj)
109 const Evas_Smart_Class *sc;
110 const Evas_Smart *smart;
112 EVAS_SMART_DATA_ALLOC(obj, Elm_Pan_Smart_Data);
114 _elm_pan_parent_sc->add(obj);
122 priv->gravity_x = 0.0;
123 priv->gravity_y = 0.0;
125 smart = evas_object_smart_smart_get(obj);
126 sc = evas_smart_class_get(smart);
127 priv->api = (const Elm_Pan_Smart_Class *)sc;
131 _elm_pan_smart_del(Evas_Object *obj)
133 _elm_pan_content_set(obj, NULL);
135 _elm_pan_parent_sc->del(obj);
139 _elm_pan_smart_move(Evas_Object *obj,
143 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
145 /* we don't want the clipped smart object version here */
150 _elm_pan_update(psd);
154 _elm_pan_smart_resize(Evas_Object *obj,
158 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
163 _elm_pan_update(psd);
164 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
168 _elm_pan_smart_show(Evas_Object *obj)
170 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
172 _elm_pan_parent_sc->show(obj);
175 evas_object_show(psd->content);
179 _elm_pan_smart_hide(Evas_Object *obj)
181 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
183 _elm_pan_parent_sc->hide(obj);
186 evas_object_hide(psd->content);
190 _elm_pan_pos_set(Evas_Object *obj,
194 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
196 if ((x == psd->px) && (y == psd->py)) return;
200 _elm_pan_update(psd);
201 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
205 _elm_pan_pos_get(const Evas_Object *obj,
209 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
216 _elm_pan_pos_max_get(const Evas_Object *obj,
220 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
224 if (psd->w < psd->content_w) *x = psd->content_w - psd->w;
229 if (psd->h < psd->content_h) *y = psd->content_h - psd->h;
235 _elm_pan_pos_min_get(const Evas_Object *obj __UNUSED__,
246 _elm_pan_content_size_get(const Evas_Object *obj,
250 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
252 if (w) *w = psd->content_w;
253 if (h) *h = psd->content_h;
257 _elm_pan_gravity_set(Evas_Object *obj,
261 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
265 psd->prev_cw = psd->content_w;
266 psd->prev_ch = psd->content_h;
272 _elm_pan_gravity_get(const Evas_Object *obj,
276 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
278 if (x) *x = psd->gravity_x;
279 if (y) *y = psd->gravity_y;
283 _elm_pan_smart_set_user(Elm_Pan_Smart_Class *sc)
285 sc->base.add = _elm_pan_smart_add;
286 sc->base.del = _elm_pan_smart_del;
287 sc->base.move = _elm_pan_smart_move;
288 sc->base.resize = _elm_pan_smart_resize;
289 sc->base.show = _elm_pan_smart_show;
290 sc->base.hide = _elm_pan_smart_hide;
291 sc->pos_set = _elm_pan_pos_set;
292 sc->pos_get = _elm_pan_pos_get;
293 sc->pos_max_get = _elm_pan_pos_max_get;
294 sc->pos_min_get = _elm_pan_pos_min_get;
295 sc->content_size_get = _elm_pan_content_size_get;
296 sc->gravity_set = _elm_pan_gravity_set;
297 sc->gravity_get = _elm_pan_gravity_get;
298 sc->pos_adjust = NULL;
302 _elm_pan_add(Evas *evas)
304 return evas_object_smart_add(evas, _elm_pan_smart_class_new());
308 _elm_pan_content_del_cb(void *data,
310 Evas_Object *obj __UNUSED__,
311 void *event_info __UNUSED__)
313 Elm_Pan_Smart_Data *psd;
317 psd->content_w = psd->content_h = psd->px = psd->py =
318 psd->prev_cw = psd->prev_ch = psd->delta_posx = psd->delta_posy = 0;
319 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
323 _elm_pan_content_resize_cb(void *data,
325 Evas_Object *obj __UNUSED__,
326 void *event_info __UNUSED__)
328 Elm_Pan_Smart_Data *psd;
332 evas_object_geometry_get(psd->content, NULL, NULL, &w, &h);
333 if ((w != psd->content_w) || (h != psd->content_h))
337 _elm_pan_update(psd);
339 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
343 _elm_pan_content_set(Evas_Object *obj,
344 Evas_Object *content)
348 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
350 if (content == psd->content) return;
353 evas_object_smart_member_del(psd->content);
354 evas_object_event_callback_del_full
355 (psd->content, EVAS_CALLBACK_DEL, _elm_pan_content_del_cb, psd);
356 evas_object_event_callback_del_full
357 (psd->content, EVAS_CALLBACK_RESIZE, _elm_pan_content_resize_cb,
361 if (!content) goto end;
363 psd->content = content;
364 evas_object_smart_member_add(psd->content, psd->self);
365 evas_object_geometry_get(psd->content, NULL, NULL, &w, &h);
368 evas_object_event_callback_add
369 (content, EVAS_CALLBACK_DEL, _elm_pan_content_del_cb, psd);
370 evas_object_event_callback_add
371 (content, EVAS_CALLBACK_RESIZE, _elm_pan_content_resize_cb, psd);
373 if (evas_object_visible_get(psd->self))
374 evas_object_show(psd->content);
376 evas_object_hide(psd->content);
378 _elm_pan_update(psd);
381 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
384 /* pan smart object on top, scroller interface on bottom */
385 /* ============================================================ */
387 static const char SCROLL_SMART_NAME[] = "elm_scroll";
389 #define ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(o, ptr) \
390 Elm_Scrollable_Smart_Interface_Data *ptr = \
391 evas_object_smart_interface_data_get(o, &(ELM_SCROLLABLE_IFACE.base)); \
394 CRITICAL("No interface data for object %p (%s)", \
395 o, evas_object_type_get(o)); \
399 #define ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
400 Elm_Scrollable_Smart_Interface_Data *ptr = \
401 evas_object_smart_interface_data_get(o, &(ELM_SCROLLABLE_IFACE.base)); \
404 CRITICAL("No interface data for object %p (%s)", \
405 o, evas_object_type_get(o)); \
409 static void _elm_scroll_scroll_bar_size_adjust(
410 Elm_Scrollable_Smart_Interface_Data *);
411 static void _elm_scroll_wanted_region_set(Evas_Object *);
412 static Eina_Bool _paging_is_enabled(Elm_Scrollable_Smart_Interface_Data *sid);
413 static Evas_Coord _elm_scroll_page_x_get(
414 Elm_Scrollable_Smart_Interface_Data *sid, int offset, Eina_Bool limit);
415 static Evas_Coord _elm_scroll_page_y_get(
416 Elm_Scrollable_Smart_Interface_Data *sid, int offset, Eina_Bool limit);
417 static void _elm_scroll_content_pos_get(const Evas_Object *,
420 static void _elm_scroll_content_pos_set(Evas_Object *,
430 //#define SCROLLDBG 1
431 /* smoothness debug calls - for debugging how much smooth your app is */
435 #define SMOOTH_DEBUG_COUNT 100
438 typedef struct _smooth_debug_info smooth_debug_info;
439 struct _smooth_debug_info
448 static smooth_debug_info smooth_x_history[SMOOTH_DEBUG_COUNT];
449 static smooth_debug_info smooth_y_history[SMOOTH_DEBUG_COUNT];
450 static int smooth_info_x_count = 0;
451 static int smooth_info_y_count = 0;
452 static double start_time = 0;
453 static int _elm_scroll_smooth_debug = 0;
454 static const int _elm_scroll_gradient_check_pixel = 30;
458 _elm_scroll_smooth_debug_init(void)
460 start_time = ecore_time_get();
461 smooth_info_x_count = 0;
462 smooth_info_y_count = 0;
464 memset(&(smooth_x_history[0]), 0,
465 sizeof(smooth_x_history[0]) * SMOOTH_DEBUG_COUNT);
466 memset(&(smooth_y_history[0]), 0,
467 sizeof(smooth_y_history[0]) * SMOOTH_DEBUG_COUNT);
473 _elm_scroll_smooth_debug_shutdown(void)
476 int info_x_count = 0;
477 int info_y_count = 0;
478 double x_ave = 0, y_ave = 0;
479 double x_sum = 0, y_sum = 0;
480 double x_dev = 0, y_dev = 0;
481 double x_dev_sum = 0, y_dev_sum = 0;
483 if (smooth_info_x_count >= SMOOTH_DEBUG_COUNT)
484 info_x_count = SMOOTH_DEBUG_COUNT;
486 info_x_count = smooth_info_x_count;
488 if (smooth_info_y_count >= SMOOTH_DEBUG_COUNT)
489 info_y_count = SMOOTH_DEBUG_COUNT;
491 info_y_count = smooth_info_y_count;
493 DBG("\n\n<<< X-axis Smoothness >>>\n");
494 DBG("| Num | t(time) | dt | x | dx |vx(dx/1fps) |\n");
496 for (i = info_x_count - 1; i >= 0; i--)
498 DBG("| %4d | %1.6f | %1.6f | %4d | %4d | %9.3f |\n", info_x_count - i,
499 smooth_x_history[i].t,
500 smooth_x_history[i].dt,
501 smooth_x_history[i].pos,
502 smooth_x_history[i].dpos,
503 smooth_x_history[i].vpos);
504 if (i == info_x_count - 1) continue;
505 x_sum += smooth_x_history[i].vpos;
508 x_ave = x_sum / (info_x_count - 1);
509 for (i = 0; i < info_x_count - 1; i++)
511 x_dev_sum += (smooth_x_history[i].vpos - x_ave) *
512 (smooth_x_history[i].vpos - x_ave);
514 x_dev = x_dev_sum / (info_x_count - 1);
515 DBG(" Standard deviation of X-axis velocity: %9.3f\n", sqrt(x_dev));
517 DBG("\n\n<<< Y-axis Smoothness >>>\n");
518 DBG("| Num | t(time) | dt | y | dy |vy(dy/1fps) |\n");
519 for (i = info_y_count - 1; i >= 0; i--)
521 DBG("| %4d | %1.6f | %1.6f | %4d | %4d | %9.3f |\n", info_y_count - i,
522 smooth_y_history[i].t,
523 smooth_y_history[i].dt,
524 smooth_y_history[i].pos,
525 smooth_y_history[i].dpos,
526 smooth_y_history[i].vpos);
527 if (i == info_y_count - 1) continue;
528 y_sum += smooth_y_history[i].vpos;
530 y_ave = y_sum / (info_y_count - 1);
531 for (i = 0; i < info_y_count - 1; i++)
533 y_dev_sum += (smooth_y_history[i].vpos - y_ave) *
534 (smooth_y_history[i].vpos - y_ave);
536 y_dev = y_dev_sum / (info_y_count - 1);
538 DBG(" Standard deviation of Y-axis velocity: %9.3f\n", sqrt(y_dev));
542 _elm_direction_arrows_eval(Elm_Scrollable_Smart_Interface_Data *sid)
544 Eina_Bool go_left = EINA_TRUE, go_right = EINA_TRUE;
545 Eina_Bool go_up = EINA_TRUE, go_down = EINA_TRUE;
546 Evas_Coord x = 0, y = 0, mx = 0, my = 0, minx = 0, miny = 0;
548 if (!sid->edje_obj || !sid->pan_obj) return;
549 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
551 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
552 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
553 psd->api->pos_get(sid->pan_obj, &x, &y);
555 if (x == minx) go_left = EINA_FALSE;
556 if (x == (mx + minx)) go_right = EINA_FALSE;
557 if (y == miny) go_up = EINA_FALSE;
558 if (y == (my + miny)) go_down = EINA_FALSE;
559 if (go_left != sid->go_left)
562 edje_object_signal_emit(sid->edje_obj, "elm,action,show,left", "elm");
564 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,left", "elm");
565 sid->go_left = go_left;
567 if (go_right != sid->go_right)
570 edje_object_signal_emit(sid->edje_obj, "elm,action,show,right", "elm");
572 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,right", "elm");
573 sid->go_right= go_right;
575 if (go_up != sid->go_up)
578 edje_object_signal_emit(sid->edje_obj, "elm,action,show,up", "elm");
580 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,up", "elm");
583 if (go_down != sid->go_down)
586 edje_object_signal_emit(sid->edje_obj, "elm,action,show,down", "elm");
588 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,down", "elm");
589 sid->go_down= go_down;
594 _elm_scroll_smooth_debug_movetime_add(int x,
601 tim = ecore_time_get();
605 smooth_info_x_count++;
606 memmove(&(smooth_x_history[1]), &(smooth_x_history[0]),
607 sizeof(smooth_x_history[0]) * (SMOOTH_DEBUG_COUNT - 1));
608 smooth_x_history[0].t = tim - start_time;
609 smooth_x_history[0].dt = smooth_x_history[0].t - smooth_x_history[1].t;
610 smooth_x_history[0].pos = x;
611 smooth_x_history[0].dpos =
612 smooth_x_history[0].pos - smooth_x_history[1].pos;
614 if (smooth_x_history[0].dpos >= 0)
615 smooth_x_history[0].vpos = (double)(smooth_x_history[0].dpos) /
616 smooth_x_history[0].dt * FPS;
618 smooth_x_history[0].vpos = -((double)(smooth_x_history[0].dpos) /
619 smooth_x_history[0].dt * FPS);
624 smooth_info_y_count++;
625 memmove(&(smooth_y_history[1]), &(smooth_y_history[0]),
626 sizeof(smooth_y_history[0]) * (SMOOTH_DEBUG_COUNT - 1));
627 smooth_y_history[0].t = tim - start_time;
628 smooth_y_history[0].dt = smooth_y_history[0].t - smooth_y_history[1].t;
629 smooth_y_history[0].pos = y;
630 smooth_y_history[0].dpos = smooth_y_history[0].pos -
631 smooth_y_history[1].pos;
633 if (smooth_y_history[0].dpos >= 0)
634 smooth_y_history[0].vpos = (double)(smooth_y_history[0].dpos) /
635 smooth_y_history[0].dt * FPS;
637 smooth_y_history[0].vpos = -((double)(smooth_y_history[0].dpos) /
638 smooth_y_history[0].dt * FPS);
648 _elm_scroll_scroll_bar_h_visibility_adjust(
649 Elm_Scrollable_Smart_Interface_Data *sid)
651 int scroll_h_vis_change = 0;
652 Evas_Coord w, vw = 0, vh = 0;
654 if (!sid->edje_obj) return 0;
656 w = sid->content_info.w;
658 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &vw, &vh);
659 if (sid->hbar_visible)
663 scroll_h_vis_change = 1;
664 sid->hbar_visible = EINA_FALSE;
668 if (sid->hbar_flags == ELM_SCROLLER_POLICY_AUTO)
670 if ((sid->content) || (sid->extern_pan))
674 scroll_h_vis_change = 1;
675 sid->hbar_visible = EINA_FALSE;
680 scroll_h_vis_change = 1;
681 sid->hbar_visible = EINA_FALSE;
684 else if (sid->hbar_flags == ELM_SCROLLER_POLICY_OFF)
686 scroll_h_vis_change = 1;
687 sid->hbar_visible = EINA_FALSE;
695 if (sid->hbar_flags == ELM_SCROLLER_POLICY_AUTO)
697 if ((sid->content) || (sid->extern_pan))
701 scroll_h_vis_change = 1;
702 sid->hbar_visible = EINA_TRUE;
706 else if (sid->hbar_flags == ELM_SCROLLER_POLICY_ON)
708 scroll_h_vis_change = 1;
709 sid->hbar_visible = EINA_TRUE;
713 if (scroll_h_vis_change)
715 if (sid->hbar_flags != ELM_SCROLLER_POLICY_OFF)
717 if (sid->hbar_visible)
718 edje_object_signal_emit
719 (sid->edje_obj, "elm,action,show,hbar", "elm");
721 edje_object_signal_emit
722 (sid->edje_obj, "elm,action,hide,hbar", "elm");
725 edje_object_signal_emit
726 (sid->edje_obj, "elm,action,hide,hbar", "elm");
727 edje_object_message_signal_process(sid->edje_obj);
728 _elm_scroll_scroll_bar_size_adjust(sid);
729 if (sid->cb_func.content_min_limit)
730 sid->cb_func.content_min_limit(sid->obj, sid->min_w, sid->min_h);
733 _elm_direction_arrows_eval(sid);
734 return scroll_h_vis_change;
738 _elm_scroll_scroll_bar_v_visibility_adjust(
739 Elm_Scrollable_Smart_Interface_Data *sid)
741 int scroll_v_vis_change = 0;
742 Evas_Coord h, vw = 0, vh = 0;
744 if (!sid->edje_obj) return 0;
746 h = sid->content_info.h;
748 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &vw, &vh);
749 if (sid->vbar_visible)
753 scroll_v_vis_change = 1;
754 sid->vbar_visible = EINA_FALSE;
758 if (sid->vbar_flags == ELM_SCROLLER_POLICY_AUTO)
760 if ((sid->content) || (sid->extern_pan))
764 scroll_v_vis_change = 1;
765 sid->vbar_visible = EINA_FALSE;
770 scroll_v_vis_change = 1;
771 sid->vbar_visible = EINA_FALSE;
774 else if (sid->vbar_flags == ELM_SCROLLER_POLICY_OFF)
776 scroll_v_vis_change = 1;
777 sid->vbar_visible = EINA_FALSE;
785 if (sid->vbar_flags == ELM_SCROLLER_POLICY_AUTO)
787 if ((sid->content) || (sid->extern_pan))
791 scroll_v_vis_change = 1;
792 sid->vbar_visible = EINA_TRUE;
796 else if (sid->vbar_flags == ELM_SCROLLER_POLICY_ON)
798 scroll_v_vis_change = 1;
799 sid->vbar_visible = EINA_TRUE;
803 if (scroll_v_vis_change)
805 if (sid->vbar_flags != ELM_SCROLLER_POLICY_OFF)
807 if (sid->vbar_visible)
808 edje_object_signal_emit
809 (sid->edje_obj, "elm,action,show,vbar", "elm");
811 edje_object_signal_emit
812 (sid->edje_obj, "elm,action,hide,vbar", "elm");
815 edje_object_signal_emit
816 (sid->edje_obj, "elm,action,hide,vbar", "elm");
817 edje_object_message_signal_process(sid->edje_obj);
818 _elm_scroll_scroll_bar_size_adjust(sid);
819 if (sid->cb_func.content_min_limit)
820 sid->cb_func.content_min_limit(sid->obj, sid->min_w, sid->min_h);
823 _elm_direction_arrows_eval(sid);
824 return scroll_v_vis_change;
828 _elm_scroll_scroll_bar_visibility_adjust(
829 Elm_Scrollable_Smart_Interface_Data *sid)
833 changed |= _elm_scroll_scroll_bar_h_visibility_adjust(sid);
834 changed |= _elm_scroll_scroll_bar_v_visibility_adjust(sid);
838 _elm_scroll_scroll_bar_h_visibility_adjust(sid);
839 _elm_scroll_scroll_bar_v_visibility_adjust(sid);
844 _elm_scroll_scroll_bar_size_adjust(Elm_Scrollable_Smart_Interface_Data *sid)
846 if (!sid->pan_obj || !sid->edje_obj) return;
848 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
850 if ((sid->content) || (sid->extern_pan))
852 Evas_Coord x, y, w, h, mx = 0, my = 0, vw = 0, vh = 0, px, py,
856 edje_object_calc_force(sid->edje_obj);
857 edje_object_part_geometry_get
858 (sid->edje_obj, "elm.swallow.content", NULL, NULL, &vw, &vh);
859 w = sid->content_info.w;
861 size = (double)vw / (double)w;
866 edje_object_part_drag_value_set
867 (sid->edje_obj, "elm.dragable.hbar", 0.0, 0.0);
869 edje_object_part_drag_size_set
870 (sid->edje_obj, "elm.dragable.hbar", size, 1.0);
872 h = sid->content_info.h;
874 size = (double)vh / (double)h;
878 edje_object_part_drag_value_set
879 (sid->edje_obj, "elm.dragable.vbar", 0.0, 0.0);
881 edje_object_part_drag_size_set
882 (sid->edje_obj, "elm.dragable.vbar", 1.0, size);
884 edje_object_part_drag_value_get
885 (sid->edje_obj, "elm.dragable.hbar", &vx, NULL);
886 edje_object_part_drag_value_get
887 (sid->edje_obj, "elm.dragable.vbar", NULL, &vy);
889 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
890 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
894 edje_object_part_drag_step_set
895 (sid->edje_obj, "elm.dragable.hbar", (double)sid->step.x /
897 edje_object_part_drag_step_set
898 (sid->edje_obj, "elm.dragable.vbar", 0.0, (double)sid->step.y /
901 edje_object_part_drag_page_set
902 (sid->edje_obj, "elm.dragable.hbar", (double)sid->page.x /
905 edje_object_part_drag_page_set
906 (sid->edje_obj, "elm.dragable.hbar",
907 -((double)sid->page.x * ((double)vw / (double)w)) / 100.0, 0.0);
909 edje_object_part_drag_page_set
910 (sid->edje_obj, "elm.dragable.vbar", 0.0,
911 (double)sid->page.y / (double)h);
913 edje_object_part_drag_page_set
914 (sid->edje_obj, "elm.dragable.vbar", 0.0,
915 -((double)sid->page.y * ((double)vh / (double)h)) / 100.0);
917 psd->api->pos_get(sid->pan_obj, &px, &py);
918 if (vx != mx) x = px;
919 if (vy != my) y = py;
920 psd->api->pos_set(sid->pan_obj, x, y);
924 Evas_Coord px = 0, py = 0, minx = 0, miny = 0;
926 edje_object_part_drag_size_set
927 (sid->edje_obj, "elm.dragable.vbar", 1.0, 1.0);
928 edje_object_part_drag_size_set
929 (sid->edje_obj, "elm.dragable.hbar", 1.0, 1.0);
930 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
931 psd->api->pos_get(sid->pan_obj, &px, &py);
932 psd->api->pos_set(sid->pan_obj, minx, miny);
933 if ((px != minx) || (py != miny))
934 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
936 _elm_scroll_scroll_bar_visibility_adjust(sid);
940 _elm_scroll_scroll_bar_read_and_update(
941 Elm_Scrollable_Smart_Interface_Data *sid)
943 Evas_Coord x, y, mx = 0, my = 0, px, py, minx = 0, miny = 0;
946 if (!sid->edje_obj || !sid->pan_obj) return;
948 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
950 if ((sid->down.dragged) || (sid->down.bounce_x_animator)
951 || (sid->down.bounce_y_animator) || (sid->down.momentum_animator)
952 || (sid->scrollto.x.animator) || (sid->scrollto.y.animator))
954 edje_object_part_drag_value_get
955 (sid->edje_obj, "elm.dragable.vbar", NULL, &vy);
956 edje_object_part_drag_value_get
957 (sid->edje_obj, "elm.dragable.hbar", &vx, NULL);
958 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
959 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
960 x = _round(vx * (double)mx + minx, 1);
961 y = _round(vy * (double)my + miny, 1);
962 psd->api->pos_get(sid->pan_obj, &px, &py);
964 if (!sid->freeze && _paging_is_enabled(sid))
966 x = _elm_scroll_page_x_get(sid, 0, EINA_FALSE);
967 y = _elm_scroll_page_y_get(sid, 0, EINA_FALSE);
969 psd->api->pos_set(sid->pan_obj, x, y);
970 if ((px != x) || (py != y))
972 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
977 _elm_scroll_drag_start(Elm_Scrollable_Smart_Interface_Data *sid)
979 if (sid->cb_func.drag_start)
980 sid->cb_func.drag_start(sid->obj, NULL);
984 _elm_scroll_drag_stop(Elm_Scrollable_Smart_Interface_Data *sid)
986 sid->current_page.x = _elm_scroll_page_x_get(sid, 0, EINA_FALSE);
987 sid->current_page.y = _elm_scroll_page_y_get(sid, 0, EINA_FALSE);
989 if (sid->cb_func.drag_stop)
990 sid->cb_func.drag_stop(sid->obj, NULL);
994 _elm_scroll_anim_start(Elm_Scrollable_Smart_Interface_Data *sid)
996 if (sid->cb_func.animate_start)
997 sid->cb_func.animate_start(sid->obj, NULL);
1001 _elm_scroll_anim_stop(Elm_Scrollable_Smart_Interface_Data *sid)
1003 sid->current_page.x = _elm_scroll_page_x_get(sid, 0, EINA_FALSE);
1004 sid->current_page.y = _elm_scroll_page_y_get(sid, 0, EINA_FALSE);
1006 if (sid->cb_func.animate_stop)
1007 sid->cb_func.animate_stop(sid->obj, NULL);
1011 _elm_scroll_policy_signal_emit(Elm_Scrollable_Smart_Interface_Data *sid)
1013 if (sid->hbar_flags == ELM_SCROLLER_POLICY_ON)
1014 edje_object_signal_emit
1015 (sid->edje_obj, "elm,action,show_always,hbar", "elm");
1016 else if (sid->hbar_flags == ELM_SCROLLER_POLICY_OFF)
1017 edje_object_signal_emit
1018 (sid->edje_obj, "elm,action,hide,hbar", "elm");
1020 edje_object_signal_emit
1021 (sid->edje_obj, "elm,action,show_notalways,hbar", "elm");
1022 if (sid->vbar_flags == ELM_SCROLLER_POLICY_ON)
1023 edje_object_signal_emit
1024 (sid->edje_obj, "elm,action,show_always,vbar", "elm");
1025 else if (sid->vbar_flags == ELM_SCROLLER_POLICY_OFF)
1026 edje_object_signal_emit
1027 (sid->edje_obj, "elm,action,hide,vbar", "elm");
1029 edje_object_signal_emit
1030 (sid->edje_obj, "elm,action,show_notalways,vbar", "elm");
1031 edje_object_message_signal_process(sid->edje_obj);
1032 _elm_scroll_scroll_bar_size_adjust(sid);
1036 _elm_scroll_reload_cb(void *data,
1037 Evas_Object *obj __UNUSED__,
1038 const char *emission __UNUSED__,
1039 const char *source __UNUSED__)
1041 Elm_Scrollable_Smart_Interface_Data *sid = data;
1043 // FIXME: refactoring for determining bar's size and visiblity
1044 sid->hbar_visible = EINA_TRUE;
1045 sid->vbar_visible = EINA_TRUE;
1047 _elm_scroll_policy_signal_emit(sid);
1051 _elm_scroll_vbar_drag_cb(void *data,
1052 Evas_Object *obj __UNUSED__,
1053 const char *emission __UNUSED__,
1054 const char *source __UNUSED__)
1056 Elm_Scrollable_Smart_Interface_Data *sid = data;
1058 if (sid->cb_func.vbar_drag)
1059 sid->cb_func.vbar_drag(sid->obj, NULL);
1061 _elm_scroll_scroll_bar_read_and_update(sid);
1065 _elm_scroll_vbar_press_cb(void *data,
1066 Evas_Object *obj __UNUSED__,
1067 const char *emission __UNUSED__,
1068 const char *source __UNUSED__)
1070 Elm_Scrollable_Smart_Interface_Data *sid = data;
1072 if (sid->cb_func.vbar_press)
1073 sid->cb_func.vbar_press(sid->obj, NULL);
1077 _elm_scroll_vbar_unpress_cb(void *data,
1078 Evas_Object *obj __UNUSED__,
1079 const char *emission __UNUSED__,
1080 const char *source __UNUSED__)
1082 Elm_Scrollable_Smart_Interface_Data *sid = data;
1084 if (sid->cb_func.vbar_unpress)
1085 sid->cb_func.vbar_unpress(sid->obj, NULL);
1089 _elm_scroll_edje_drag_v_start_cb(void *data,
1090 Evas_Object *obj __UNUSED__,
1091 const char *emission __UNUSED__,
1092 const char *source __UNUSED__)
1094 Elm_Scrollable_Smart_Interface_Data *sid = data;
1096 _elm_scroll_scroll_bar_read_and_update(sid);
1097 _elm_scroll_drag_start(sid);
1098 sid->freeze = EINA_TRUE;
1102 _elm_scroll_edje_drag_v_stop_cb(void *data,
1103 Evas_Object *obj __UNUSED__,
1104 const char *emission __UNUSED__,
1105 const char *source __UNUSED__)
1107 Elm_Scrollable_Smart_Interface_Data *sid = data;
1109 _elm_scroll_scroll_bar_read_and_update(sid);
1110 _elm_scroll_drag_stop(sid);
1111 sid->freeze = EINA_FALSE;
1115 _elm_scroll_edje_drag_v_cb(void *data,
1116 Evas_Object *obj __UNUSED__,
1117 const char *emission __UNUSED__,
1118 const char *source __UNUSED__)
1120 Elm_Scrollable_Smart_Interface_Data *sid = data;
1122 _elm_scroll_scroll_bar_read_and_update(sid);
1126 _elm_scroll_hbar_drag_cb(void *data,
1127 Evas_Object *obj __UNUSED__,
1128 const char *emission __UNUSED__,
1129 const char *source __UNUSED__)
1131 Elm_Scrollable_Smart_Interface_Data *sid = data;
1133 if (sid->cb_func.hbar_drag)
1134 sid->cb_func.hbar_drag(sid->obj, NULL);
1136 _elm_scroll_scroll_bar_read_and_update(sid);
1140 _elm_scroll_hbar_press_cb(void *data,
1141 Evas_Object *obj __UNUSED__,
1142 const char *emission __UNUSED__,
1143 const char *source __UNUSED__)
1145 Elm_Scrollable_Smart_Interface_Data *sid = data;
1147 if (sid->cb_func.hbar_press)
1148 sid->cb_func.hbar_press(sid->obj, NULL);
1152 _elm_scroll_hbar_unpress_cb(void *data,
1153 Evas_Object *obj __UNUSED__,
1154 const char *emission __UNUSED__,
1155 const char *source __UNUSED__)
1157 Elm_Scrollable_Smart_Interface_Data *sid = data;
1159 if (sid->cb_func.hbar_unpress)
1160 sid->cb_func.hbar_unpress(sid->obj, NULL);
1164 _elm_scroll_edje_drag_h_start_cb(void *data,
1165 Evas_Object *obj __UNUSED__,
1166 const char *emission __UNUSED__,
1167 const char *source __UNUSED__)
1169 Elm_Scrollable_Smart_Interface_Data *sid = data;
1171 _elm_scroll_scroll_bar_read_and_update(sid);
1172 _elm_scroll_drag_start(sid);
1173 sid->freeze = EINA_TRUE;
1177 _elm_scroll_edje_drag_h_stop_cb(void *data,
1178 Evas_Object *obj __UNUSED__,
1179 const char *emission __UNUSED__,
1180 const char *source __UNUSED__)
1182 Elm_Scrollable_Smart_Interface_Data *sid = data;
1184 _elm_scroll_scroll_bar_read_and_update(sid);
1185 _elm_scroll_drag_stop(sid);
1186 sid->freeze = EINA_FALSE;
1190 _elm_scroll_edje_drag_h_cb(void *data,
1191 Evas_Object *obj __UNUSED__,
1192 const char *emission __UNUSED__,
1193 const char *source __UNUSED__)
1195 Elm_Scrollable_Smart_Interface_Data *sid = data;
1197 _elm_scroll_scroll_bar_read_and_update(sid);
1201 _elm_scroll_content_size_get(const Evas_Object *obj,
1205 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1208 evas_object_geometry_get(sid->content, NULL, NULL, w, h);
1209 else if (sid->pan_obj)
1211 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
1212 psd->api->content_size_get(sid->pan_obj, w, h);
1217 _elm_scroll_content_viewport_size_get(const Evas_Object *obj,
1221 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1223 if (!sid->pan_obj || !sid->edje_obj) return;
1225 edje_object_calc_force(sid->edje_obj);
1226 evas_object_geometry_get(sid->pan_obj, NULL, NULL, w, h);
1230 _elm_scroll_content_viewport_pos_get(const Evas_Object *obj,
1234 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1236 if (!sid->pan_obj || !sid->edje_obj) return;
1238 edje_object_calc_force(sid->edje_obj);
1239 evas_object_geometry_get(sid->pan_obj, x, y, NULL, NULL);
1243 _elm_scroll_content_min_limit(Evas_Object *obj,
1247 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1249 if (!sid->edje_obj) return;
1251 if (!sid->cb_func.content_min_limit)
1253 ERR("Content minimim size limiting is unimplemented -- you "
1254 "must provide it yourself\n");
1260 sid->cb_func.content_min_limit(sid->obj, w, h);
1264 _elm_scroll_origin_reverse_set(Evas_Object *obj,
1265 Eina_Bool origin_x, Eina_Bool origin_y)
1269 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1271 sid->origin_x = origin_x;
1272 sid->origin_y = origin_y;
1274 _elm_scroll_content_pos_get(sid->obj, &x, &y);
1275 _elm_scroll_wanted_coordinates_update(sid, x, y);
1279 _elm_scroll_origin_reverse_get(const Evas_Object *obj,
1280 Eina_Bool *origin_x, Eina_Bool *origin_y)
1282 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1284 if (origin_x) *origin_x = sid->origin_x;
1285 if (origin_y) *origin_y = sid->origin_y;
1289 _elm_scroll_x_mirrored_get(const Evas_Object *obj,
1292 Evas_Coord cw, ch, w, ret;
1294 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, x);
1296 if (!sid->pan_obj) return 0;
1298 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, 0);
1300 _elm_scroll_content_viewport_size_get(obj, &w, NULL);
1301 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1302 ret = (cw - (x + w));
1304 return (ret >= 0) ? ret : 0;
1307 /* Update the wanted coordinates according to the x, y passed
1308 * widget directionality, content size and etc. */
1310 _elm_scroll_wanted_coordinates_update(Elm_Scrollable_Smart_Interface_Data *sid,
1316 if (!sid->pan_obj) return;
1318 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
1320 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1322 /* Update wx/y/w/h - and if the requested positions aren't legal
1324 _elm_scroll_content_viewport_size_get(sid->obj, &sid->ww, &sid->wh);
1328 if (!sid->loop_h) sid->wx = 0;
1329 else sid->wx = cw - sid->ww;
1331 else if (!sid->loop_h && (x + sid->ww) > cw)
1332 sid->wx = cw - sid->ww;
1333 else if (sid->loop_h && x >= cw)
1335 else if (sid->is_mirrored)
1336 sid->wx = _elm_scroll_x_mirrored_get(sid->obj, x);
1342 sid->wx = cw - sid->wx;
1343 if (sid->wx < 0) sid->wx = 0;
1348 if (!sid->loop_v) sid->wy = 0;
1349 else sid->wy = ch - sid->wh;
1351 else if (!sid->loop_v && (y + sid->wh) > ch)
1352 sid->wy = ch - sid->wh;
1353 else if (sid->loop_v && y >= ch)
1359 sid->wy = ch - sid->wy;
1360 if (sid->wy < 0) sid->wy = 0;
1365 _elm_scroll_momentum_end(Elm_Scrollable_Smart_Interface_Data *sid)
1367 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator)) return;
1368 if (sid->down.momentum_animator)
1371 _elm_scroll_content_pos_get(sid->obj, &px, &py);
1372 _elm_scroll_wanted_coordinates_update(sid, px, py);
1374 ecore_animator_del(sid->down.momentum_animator);
1375 sid->down.momentum_animator = NULL;
1376 sid->down.bounce_x_hold = EINA_FALSE;
1377 sid->down.bounce_y_hold = EINA_FALSE;
1384 if (sid->content_info.resized)
1385 _elm_scroll_wanted_region_set(sid->obj);
1390 _elm_scroll_bounce_x_animator(void *data)
1392 Elm_Scrollable_Smart_Interface_Data *sid;
1393 Evas_Coord x, y, dx, w, odx, ed, md;
1394 double t, p, dt, pd, r;
1397 t = ecore_loop_time_get();
1398 dt = t - sid->down.anim_start2;
1401 dt = dt / _elm_config->thumbscroll_bounce_friction;
1402 odx = sid->down.b2x - sid->down.bx;
1403 _elm_scroll_content_viewport_size_get(sid->obj, &w, NULL);
1404 if (!sid->down.momentum_animator && (w > abs(odx)))
1406 pd = (double)odx / (double)w;
1407 pd = (pd > 0) ? pd : -pd;
1408 pd = 1.0 - ((1.0 - pd) * (1.0 - pd));
1411 if (dt > 1.0) dt = 1.0;
1412 p = 1.0 - ((1.0 - dt) * (1.0 - dt));
1413 _elm_scroll_content_pos_get(sid->obj, &x, &y);
1416 if (sid->down.momentum_animator)
1418 ed = abs(sid->down.dx * (_elm_config->thumbscroll_friction +
1419 sid->down.extra_time) - sid->down.b0x);
1420 md = abs(_elm_config->thumbscroll_friction * 5 * w);
1421 if (ed > md) r = (double)(md) / (double)ed;
1423 x = sid->down.b2x + (int)((double)(dx - odx) * r);
1424 if (!sid->down.cancelled)
1425 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
1428 if (sid->down.momentum_animator)
1429 sid->down.bounce_x_hold = EINA_TRUE;
1430 if ((!sid->down.bounce_y_animator) &&
1431 (!sid->scrollto.y.animator))
1432 _elm_scroll_anim_stop(sid);
1433 sid->down.bounce_x_animator = NULL;
1435 sid->bouncemex = EINA_FALSE;
1436 _elm_scroll_momentum_end(sid);
1437 if (sid->content_info.resized)
1438 _elm_scroll_wanted_region_set(sid->obj);
1439 return ECORE_CALLBACK_CANCEL;
1442 return ECORE_CALLBACK_RENEW;
1446 _elm_scroll_bounce_y_animator(void *data)
1448 Elm_Scrollable_Smart_Interface_Data *sid;
1449 Evas_Coord x, y, dy, h, ody, ed, md;
1450 double t, p, dt, pd, r;
1453 t = ecore_loop_time_get();
1454 dt = t - sid->down.anim_start3;
1457 dt = dt / _elm_config->thumbscroll_bounce_friction;
1458 ody = sid->down.b2y - sid->down.by;
1459 _elm_scroll_content_viewport_size_get(sid->obj, NULL, &h);
1460 if (!sid->down.momentum_animator && (h > abs(ody)))
1462 pd = (double)ody / (double)h;
1463 pd = (pd > 0) ? pd : -pd;
1464 pd = 1.0 - ((1.0 - pd) * (1.0 - pd));
1467 if (dt > 1.0) dt = 1.0;
1468 p = 1.0 - ((1.0 - dt) * (1.0 - dt));
1469 _elm_scroll_content_pos_get(sid->obj, &x, &y);
1472 if (sid->down.momentum_animator)
1474 ed = abs(sid->down.dy * (_elm_config->thumbscroll_friction +
1475 sid->down.extra_time) - sid->down.b0y);
1476 md = abs(_elm_config->thumbscroll_friction * 5 * h);
1477 if (ed > md) r = (double)(md) / (double)ed;
1479 y = sid->down.b2y + (int)((double)(dy - ody) * r);
1480 if (!sid->down.cancelled)
1481 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
1484 if (sid->down.momentum_animator)
1485 sid->down.bounce_y_hold = EINA_TRUE;
1486 if ((!sid->down.bounce_x_animator) &&
1487 (!sid->scrollto.y.animator))
1488 _elm_scroll_anim_stop(sid);
1489 sid->down.bounce_y_animator = NULL;
1491 sid->bouncemey = EINA_FALSE;
1492 _elm_scroll_momentum_end(sid);
1493 if (sid->content_info.resized)
1494 _elm_scroll_wanted_region_set(sid->obj);
1495 return ECORE_CALLBACK_CANCEL;
1499 return ECORE_CALLBACK_RENEW;
1503 _elm_scroll_bounce_eval(Elm_Scrollable_Smart_Interface_Data *sid)
1505 Evas_Coord mx, my, px, py, bx, by, b2x, b2y, minx = 0, miny = 0;
1507 if (!sid->pan_obj) return;
1509 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
1511 if (sid->freeze) return;
1512 if ((!sid->bouncemex) && (!sid->bouncemey)) return;
1513 if (sid->down.now) return; // down bounce while still held down
1514 if (sid->down.onhold_animator)
1516 ecore_animator_del(sid->down.onhold_animator);
1517 sid->down.onhold_animator = NULL;
1518 if (sid->content_info.resized)
1519 _elm_scroll_wanted_region_set(sid->obj);
1521 if (sid->down.hold_animator)
1523 ecore_animator_del(sid->down.hold_animator);
1524 sid->down.hold_animator = NULL;
1525 if (sid->content_info.resized)
1526 _elm_scroll_wanted_region_set(sid->obj);
1528 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
1529 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
1530 psd->api->pos_get(sid->pan_obj, &px, &py);
1533 if (px < minx) px = minx;
1534 if ((px - minx) > mx) px = mx + minx;
1535 if (py < miny) py = miny;
1536 if ((py - miny) > my) py = my + miny;
1540 (!elm_widget_drag_child_locked_x_get(sid->obj)))
1542 if ((!sid->down.bounce_x_animator) && (!sid->bounce_animator_disabled))
1546 if (sid->scrollto.x.animator)
1548 ecore_animator_del(sid->scrollto.x.animator);
1549 sid->scrollto.x.animator = NULL;
1551 sid->down.bounce_x_animator =
1552 ecore_animator_add(_elm_scroll_bounce_x_animator, sid);
1553 sid->down.anim_start2 = ecore_loop_time_get();
1556 sid->down.b2x = b2x;
1557 if (sid->down.momentum_animator)
1558 sid->down.b0x = sid->down.ax;
1559 else sid->down.b0x = 0;
1564 (!elm_widget_drag_child_locked_y_get(sid->obj)))
1566 if ((!sid->down.bounce_y_animator) && (!sid->bounce_animator_disabled))
1570 if (sid->scrollto.y.animator)
1572 ecore_animator_del(sid->scrollto.y.animator);
1573 sid->scrollto.y.animator = NULL;
1575 sid->down.bounce_y_animator =
1576 ecore_animator_add(_elm_scroll_bounce_y_animator, sid);
1577 sid->down.anim_start3 = ecore_loop_time_get();
1580 sid->down.b2y = b2y;
1581 if (sid->down.momentum_animator)
1582 sid->down.b0y = sid->down.ay;
1583 else sid->down.b0y = 0;
1590 _elm_scroll_content_pos_get(const Evas_Object *obj,
1594 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1596 if (!sid->pan_obj) return;
1598 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
1600 psd->api->pos_get(sid->pan_obj, x, y);
1604 _elm_scroll_content_pos_set(Evas_Object *obj,
1609 Evas_Coord mx = 0, my = 0, px = 0, py = 0, spx = 0, spy = 0, minx = 0, miny = 0, pw = 0, ph = 0;
1610 Evas_Coord cw =0, ch = 0, ww = 0, wh = 0; //// TIZEN ONLY
1613 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1615 if (!sid->edje_obj || !sid->pan_obj) return;
1617 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
1619 psd->api->pos_get(sid->pan_obj, &px, &py);
1621 if ((px == x) && (py == y)) return;
1623 // FIXME: allow for bounce outside of range
1624 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
1625 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
1626 psd->api->content_size_get(sid->pan_obj, &cw, &ch); //// TIZEN ONLY
1627 _elm_scroll_content_viewport_size_get(obj, &ww, &wh); //// TIZEN ONLY
1628 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &pw, &ph);
1630 if (_elm_config->access_mode)
1632 if (((y > 0) && (y % _elm_config->finger_size) < 2 &&
1633 !((py % _elm_config->finger_size) < 2 && abs(py - y) < 2)) ||
1634 ((x > 0) && (x % _elm_config->finger_size) < 2 &&
1635 !((px % _elm_config->finger_size) < 2 && abs(px - x) < 2)))
1636 _elm_access_sound_play(ELM_ACCESS_SOUND_SCROLL);
1639 if (_paging_is_enabled(sid))
1641 //Work when Page Snap is enabled.
1643 //we passed one page to the right
1644 if (x > sid->current_page.x + sid->pagesize_h)
1645 x = sid->current_page.x + sid->pagesize_h;
1646 //we passed one page to the left
1647 if (x < sid->current_page.x - sid->pagesize_h)
1648 x = sid->current_page.x - sid->pagesize_h;
1650 //we passed one page to the bottom
1651 if (y > sid->current_page.y + sid->pagesize_v)
1652 y = sid->current_page.y + sid->pagesize_v;
1653 //we passed one page to the top
1654 if (y < sid->current_page.y - sid->pagesize_v)
1655 y = sid->current_page.y - sid->pagesize_v;
1659 if (sid->loop_h && cw > 0)
1661 if (_paging_is_enabled(sid))
1663 if (x < 0) x = cw + (x % cw);
1664 else if (x >= (pw * sid->pagecount_h)) x = (x % cw);
1668 if (x < 0) x = cw + (x % cw);
1669 else if (x >= cw) x = (x % cw);
1672 if (sid->loop_v && ch > 0)
1674 if (_paging_is_enabled(sid))
1676 if (y < 0) y = ch + (y % ch);
1677 else if (y >= (ph * sid->pagecount_v)) y = (y % ch);
1681 if (y < 0) y = ch + (y % ch);
1682 else if (y >= ch) y = (y % ch);
1690 edje_object_signal_emit(sid->edje_obj, "elm,edge,left", "elm");
1691 if (!sid->loop_h && (x - minx) > mx)
1692 edje_object_signal_emit(sid->edje_obj, "elm,edge,right", "elm");
1697 edje_object_signal_emit(sid->edje_obj, "elm,edge,top", "elm");
1698 if (!sid->loop_v && (y - miny) > my)
1699 edje_object_signal_emit(sid->edje_obj, "elm,edge,bottom", "elm");
1702 if (!_elm_config->thumbscroll_bounce_enable)
1704 if (x < minx) x = minx;
1705 if (!sid->loop_h && (x - minx) > mx) x = mx + minx;
1706 if (y < miny) y = miny;
1707 if (!sid->loop_v && (y - miny) > my) y = my + miny;
1710 if (!sid->bounce_horiz)
1712 if (x < minx) x = minx;
1713 if (!sid->loop_h && ((x - minx) > mx)) x = mx + minx;
1715 if (!sid->bounce_vert)
1717 if (y < miny) y = miny;
1718 if (!sid->loop_v && ((y - miny) > my)) y = my + miny;
1721 psd->api->pos_set(sid->pan_obj, x, y);
1722 psd->api->pos_get(sid->pan_obj, &spx, &spy);
1724 if (mx > 0) vx = (double)(spx - minx) / (double)mx;
1727 if (vx < 0.0) vx = 0.0;
1731 if (my > 0) vy = (double)(spy - miny) / (double)my;
1734 if (vy < 0.0) vy = 0.0;
1738 edje_object_part_drag_value_set
1739 (sid->edje_obj, "elm.dragable.vbar", 0.0, vy);
1740 edje_object_part_drag_value_set
1741 (sid->edje_obj, "elm.dragable.hbar", vx, 0.0);
1743 if (!sid->loop_h && !sid->down.bounce_x_animator)
1745 if (((x < minx) && (0 <= sid->down.dx)) ||
1746 ((x > (mx + minx)) && (0 >= sid->down.dx)))
1748 sid->bouncemex = EINA_TRUE;
1749 _elm_scroll_bounce_eval(sid);
1752 sid->bouncemex = EINA_FALSE;
1754 if (!sid->loop_v && !sid->down.bounce_y_animator)
1756 if (((y < miny) && (0 <= sid->down.dy)) ||
1757 ((y > (my + miny)) && (0 >= sid->down.dy)))
1759 sid->bouncemey = EINA_TRUE;
1760 _elm_scroll_bounce_eval(sid);
1763 sid->bouncemey = EINA_FALSE;
1768 if ((x != px) || (y != py))
1770 if (sid->cb_func.scroll)
1771 sid->cb_func.scroll(obj, NULL);
1772 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
1775 if (sid->cb_func.scroll_left)
1776 sid->cb_func.scroll_left(obj, NULL);
1777 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,left", "elm");
1781 if (sid->cb_func.scroll_right)
1782 sid->cb_func.scroll_right(obj, NULL);
1783 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,right", "elm");
1787 if (sid->cb_func.scroll_up)
1788 sid->cb_func.scroll_up(obj, NULL);
1789 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,up", "elm");
1793 if (sid->cb_func.scroll_down)
1794 sid->cb_func.scroll_down(obj, NULL);
1795 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,down", "elm");
1797 edje_message_signal_process();
1803 if (sid->cb_func.edge_left)
1804 sid->cb_func.edge_left(obj, NULL);
1806 if (x == (mx + minx))
1808 if (sid->cb_func.edge_right)
1809 sid->cb_func.edge_right(obj, NULL);
1816 if (sid->cb_func.edge_top)
1817 sid->cb_func.edge_top(obj, NULL);
1821 if (sid->cb_func.edge_bottom)
1822 sid->cb_func.edge_bottom(obj, NULL);
1827 _elm_direction_arrows_eval(sid);
1831 _elm_scroll_mirrored_set(Evas_Object *obj,
1836 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1838 if (!sid->edje_obj) return;
1840 mirrored = !!mirrored;
1842 if (sid->is_mirrored == mirrored)
1845 sid->is_mirrored = mirrored;
1846 edje_object_mirrored_set(sid->edje_obj, mirrored);
1848 if (sid->is_mirrored)
1849 wx = _elm_scroll_x_mirrored_get(sid->obj, sid->wx);
1853 _elm_scroll_content_pos_set(sid->obj, wx, sid->wy, EINA_FALSE);
1856 /* returns TRUE when we need to move the scroller, FALSE otherwise.
1857 * Updates w and h either way, so save them if you need them. */
1859 _elm_scroll_content_region_show_internal(Evas_Object *obj,
1865 Evas_Coord mx = 0, my = 0, cw = 0, ch = 0, px = 0, py = 0, nx = 0, ny = 0,
1866 minx = 0, miny = 0, pw = 0, ph = 0, x = *_x, y = *_y;
1868 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
1870 if (!sid->pan_obj) return EINA_FALSE;
1872 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, EINA_FALSE);
1874 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
1875 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
1876 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
1877 psd->api->pos_get(sid->pan_obj, &px, &py);
1878 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &pw, &ph);
1881 if ((x < px) && ((x + w) < (px + (cw - mx)))) nx = x;
1882 else if ((x > px) && ((x + w) > (px + (cw - mx))))
1883 nx = x + w - (cw - mx);
1885 if ((y < py) && ((y + h) < (py + (ch - my)))) ny = y;
1886 else if ((y > py) && ((y + h) > (py + (ch - my))))
1887 ny = y + h - (ch - my);
1889 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
1890 (sid->scrollto.x.animator) || (sid->scrollto.y.animator))
1892 if (sid->scrollto.x.animator)
1894 ecore_animator_del(sid->scrollto.x.animator);
1895 sid->scrollto.x.animator = NULL;
1897 if (sid->scrollto.y.animator)
1899 ecore_animator_del(sid->scrollto.y.animator);
1900 sid->scrollto.y.animator = NULL;
1902 if (sid->down.bounce_x_animator)
1904 ecore_animator_del(sid->down.bounce_x_animator);
1905 sid->down.bounce_x_animator = NULL;
1906 sid->bouncemex = EINA_FALSE;
1907 if (sid->content_info.resized)
1908 _elm_scroll_wanted_region_set(sid->obj);
1910 if (sid->down.bounce_y_animator)
1912 ecore_animator_del(sid->down.bounce_y_animator);
1913 sid->down.bounce_y_animator = NULL;
1914 sid->bouncemey = EINA_FALSE;
1915 if (sid->content_info.resized)
1916 _elm_scroll_wanted_region_set(sid->obj);
1918 _elm_scroll_anim_stop(sid);
1920 if (sid->down.hold_animator)
1922 ecore_animator_del(sid->down.hold_animator);
1923 sid->down.hold_animator = NULL;
1924 _elm_scroll_drag_stop(sid);
1925 if (sid->content_info.resized)
1926 _elm_scroll_wanted_region_set(sid->obj);
1928 if (sid->down.momentum_animator)
1930 ecore_animator_del(sid->down.momentum_animator);
1931 sid->down.momentum_animator = NULL;
1932 sid->down.bounce_x_hold = EINA_FALSE;
1933 sid->down.bounce_y_hold = EINA_FALSE;
1938 if (sid->content_info.resized)
1939 _elm_scroll_wanted_region_set(sid->obj);
1942 if (_paging_is_enabled(sid))
1944 x = _elm_scroll_page_x_get(sid, nx - px, EINA_FALSE);
1945 y = _elm_scroll_page_y_get(sid, ny - py, EINA_FALSE);
1946 if ((pw != sid->pagesize_h) && (sid->pagesize_h != 0))
1947 pw = sid->pagesize_h;
1948 if ((ph != sid->pagesize_v) && (sid->pagesize_v != 0))
1949 ph = sid->pagesize_v;
1958 if ((x + pw) > cw) x = cw - pw;
1959 if (x < minx) x = minx;
1963 if ((y + ph) > ch) y = ch - ph;
1964 if (y < miny) y = miny;
1967 if ((x == px) && (y == py)) return EINA_FALSE;
1974 /* Set should be used for calculated positions, for example, when we move
1975 * because of an animation or because this is the correct position after
1978 _elm_scroll_content_region_set(Evas_Object *obj,
1984 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1986 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
1988 _elm_scroll_content_pos_set(obj, x, y, EINA_FALSE);
1991 sid->down.x = sid->down.history[0].x;
1992 sid->down.y = sid->down.history[0].y;
1996 /* Set should be used for setting the wanted position, for example a
1997 * user scroll or moving the cursor in an entry. */
1999 _elm_scroll_content_region_show(Evas_Object *obj,
2005 Evas_Coord cw = 0, ch = 0;
2006 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
2010 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2011 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
2014 if (sid->origin_x && cw > 0)
2017 if (sid->wx < 0) sid->wx = 0;
2022 if (sid->origin_y && ch > 0)
2025 if (sid->wy < 0) sid->wy = 0;
2032 if (_paging_is_enabled(sid))
2034 if (sid->pagesize_h != 0)
2036 x = (int)(x / sid->pagesize_h) * sid->pagesize_h;
2037 if (sid->origin_x && cw > 0)
2040 if (sid->wx < 0) sid->wx = 0;
2044 sid->ww = w = sid->pagesize_h;
2046 if (sid->pagesize_v != 0)
2048 y = (int)(y / sid->pagesize_v) * sid->pagesize_v;
2049 if (sid->origin_y && ch > 0)
2052 if (sid->wy < 0) sid->wy = 0;
2056 sid->wh = h = sid->pagesize_v;
2060 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
2062 _elm_scroll_content_pos_set(obj, x, y, EINA_TRUE);
2065 sid->down.x = sid->down.history[0].x;
2066 sid->down.y = sid->down.history[0].y;
2071 _elm_scroll_wanted_region_set(Evas_Object *obj)
2073 Evas_Coord ww, wh, wx, wy, cw= 0, ch = 0;
2075 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
2080 if (sid->down.now || sid->down.momentum_animator ||
2081 sid->down.bounce_x_animator || sid->down.bounce_y_animator ||
2082 sid->down.hold_animator || sid->down.onhold_animator ||
2083 sid->scrollto.x.animator || sid->scrollto.y.animator)
2088 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2089 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
2092 sid->content_info.resized = EINA_FALSE;
2094 /* Flip to RTL cords only if init in RTL mode */
2095 if (sid->is_mirrored)
2096 wx = _elm_scroll_x_mirrored_get(obj, sid->wx);
2098 if (sid->origin_x && cw > 0)
2104 if (sid->origin_y && ch > 0)
2112 _elm_scroll_content_viewport_size_get(obj, &ww, &wh);
2120 _elm_scroll_content_region_set(obj, wx, wy, ww, wh);
2124 _elm_scroll_wheel_event_cb(void *data,
2126 Evas_Object *obj __UNUSED__,
2129 Elm_Scrollable_Smart_Interface_Data *sid;
2130 Evas_Event_Mouse_Wheel *ev;
2131 Evas_Coord x = 0, y = 0, vw = 0, vh = 0, cw = 0, ch = 0;
2133 int pagenumber_h, pagenumber_v;
2136 if (!sid->pan_obj) return;
2137 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2139 direction = ev->direction;
2141 if (sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL)
2144 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
2145 if ((evas_key_modifier_is_set(ev->modifiers, "Control")) ||
2146 (evas_key_modifier_is_set(ev->modifiers, "Alt")) ||
2147 (evas_key_modifier_is_set(ev->modifiers, "Meta")) ||
2148 (evas_key_modifier_is_set(ev->modifiers, "Hyper")) ||
2149 (evas_key_modifier_is_set(ev->modifiers, "Super")))
2151 else if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
2152 direction = !direction;
2153 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2154 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
2155 (sid->scrollto.x.animator) || (sid->scrollto.y.animator))
2157 _elm_scroll_anim_stop(sid);
2159 if (sid->scrollto.x.animator)
2161 ecore_animator_del(sid->scrollto.x.animator);
2162 sid->scrollto.x.animator = NULL;
2164 if (sid->scrollto.y.animator)
2166 ecore_animator_del(sid->scrollto.y.animator);
2167 sid->scrollto.y.animator = NULL;
2169 if (sid->down.bounce_x_animator)
2171 ecore_animator_del(sid->down.bounce_x_animator);
2172 sid->down.bounce_x_animator = NULL;
2173 sid->bouncemex = EINA_FALSE;
2174 if (sid->content_info.resized)
2175 _elm_scroll_wanted_region_set(sid->obj);
2177 if (sid->down.bounce_y_animator)
2179 ecore_animator_del(sid->down.bounce_y_animator);
2180 sid->down.bounce_y_animator = NULL;
2181 sid->bouncemey = EINA_FALSE;
2182 if (sid->content_info.resized)
2183 _elm_scroll_wanted_region_set(sid->obj);
2185 _elm_scroll_content_viewport_size_get(sid->obj, &vw, &vh);
2186 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
2187 if (!_paging_is_enabled(sid))
2191 if (ch > vh || cw <= vw)
2192 y += ev->z * sid->step.y;
2194 x += ev->z * sid->step.x;
2196 else if (direction == 1)
2198 if (cw > vw || ch <= vh)
2199 x += ev->z * sid->step.x;
2201 y += ev->z * sid->step.y;
2204 if ((!sid->hold) && (!sid->freeze))
2206 _elm_scroll_wanted_coordinates_update(sid, x, y);
2207 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
2212 _elm_scroll_current_page_get(sid->obj, &pagenumber_h, &pagenumber_v);
2215 if (ch > vh || cw <= vw)
2216 y = (pagenumber_v + (1 * ev->z)) * sid->pagesize_v;
2218 x = (pagenumber_h + (1 * ev->z)) * sid->pagesize_h;
2220 else if (direction == 1)
2222 if (cw > vw || ch <= vh)
2223 x = (pagenumber_h + (1 * ev->z)) * sid->pagesize_h;
2225 y = (pagenumber_v + (1 * ev->z)) * sid->pagesize_v;
2228 if ((!sid->hold) && (!sid->freeze))
2230 //_elm_scroll_scroll_to_x(sid, _elm_config->bring_in_scroll_friction, x);
2231 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, y);
2237 _elm_scroll_post_event_up(void *data,
2240 Elm_Scrollable_Smart_Interface_Data *sid = data;
2244 if (sid->down.dragged)
2246 elm_widget_drag_lock_x_set(sid->obj, EINA_FALSE);
2247 elm_widget_drag_lock_y_set(sid->obj, EINA_FALSE);
2254 _paging_is_enabled(Elm_Scrollable_Smart_Interface_Data *sid)
2256 if ((sid->pagerel_h == 0.0) && (!sid->pagesize_h) &&
2257 (sid->pagerel_v == 0.0) && (!sid->pagesize_v))
2263 _elm_scroll_momentum_animator(void *data)
2265 double t, at, dt, p, r;
2266 Elm_Scrollable_Smart_Interface_Data *sid = data;
2267 Evas_Coord x, y, dx, dy, px, py, maxx, maxy, minx, miny;
2268 Eina_Bool no_bounce_x_end = EINA_FALSE, no_bounce_y_end = EINA_FALSE;
2270 if (!sid->pan_obj) return ECORE_CALLBACK_CANCEL;
2272 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, ECORE_CALLBACK_CANCEL);
2274 t = ecore_loop_time_get();
2275 dt = t - sid->down.anim_start;
2278 r = _elm_config->thumbscroll_min_friction / _elm_config->thumbscroll_friction;
2280 (sid->down.dx * sid->down.dx) + (sid->down.dy * sid->down.dy));
2281 at = at < ((1.0 - r) * _elm_config->thumbscroll_friction_standard) ?
2282 at : (1.0 - r) * _elm_config->thumbscroll_friction_standard;
2283 at = ((at / _elm_config->thumbscroll_friction_standard) + r) *
2284 (_elm_config->thumbscroll_friction + sid->down.extra_time);
2286 if (dt > 1.0) dt = 1.0;
2287 p = 1 - powf((1.0) - dt, 3);
2289 if (psd->api->pos_adjust)
2291 dx = sid->down.dx * p;
2292 dy = sid->down.dy * p;
2296 dx = (sid->down.dx * (_elm_config->thumbscroll_friction +
2297 sid->down.extra_time) * p);
2298 dy = (sid->down.dy * (_elm_config->thumbscroll_friction +
2299 sid->down.extra_time) * p);
2304 x = sid->down.sx - dx;
2305 y = sid->down.sy - dy;
2306 _elm_scroll_content_pos_get(sid->obj, &px, &py);
2307 if ((sid->down.bounce_x_animator) ||
2308 (sid->down.bounce_x_hold))
2310 sid->down.bx = sid->down.bx0 - dx + sid->down.b0x;
2313 if ((sid->down.bounce_y_animator) ||
2314 (sid->down.bounce_y_hold))
2316 sid->down.by = sid->down.by0 - dy + sid->down.b0y;
2319 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
2320 _elm_scroll_wanted_coordinates_update(sid, x, y);
2321 psd->api->pos_max_get(sid->pan_obj, &maxx, &maxy);
2322 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
2323 if (!_elm_config->thumbscroll_bounce_enable || !sid->bounce_horiz)
2325 if (x <= minx) no_bounce_x_end = EINA_TRUE;
2326 if (!sid->loop_h && (x - minx) >= maxx) no_bounce_x_end = EINA_TRUE;
2328 if (!_elm_config->thumbscroll_bounce_enable || !sid->bounce_vert)
2330 if (y <= miny) no_bounce_y_end = EINA_TRUE;
2331 if (!sid->loop_v && (y - miny) >= maxy) no_bounce_y_end = EINA_TRUE;
2334 ((sid->down.bounce_x_hold) && (sid->down.bounce_y_hold)) ||
2335 (no_bounce_x_end && no_bounce_y_end))
2337 _elm_scroll_anim_stop(sid);
2339 sid->down.momentum_animator = NULL;
2340 sid->down.bounce_x_hold = EINA_FALSE;
2341 sid->down.bounce_y_hold = EINA_FALSE;
2346 if (sid->content_info.resized)
2347 _elm_scroll_wanted_region_set(sid->obj);
2349 return ECORE_CALLBACK_CANCEL;
2353 return ECORE_CALLBACK_RENEW;
2357 _elm_scroll_page_x_get(Elm_Scrollable_Smart_Interface_Data *sid,
2358 int offset, Eina_Bool limit)
2360 Evas_Coord x, y, w, h, dx, cw, ch, minx = 0;
2362 if (!sid->pan_obj) return 0;
2364 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, 0);
2366 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2367 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
2368 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
2369 psd->api->pos_min_get(sid->pan_obj, &minx, NULL);
2371 if (sid->pagerel_h > 0.0)
2373 if (sid->pagecount_h != 0)
2374 w = cw / (sid->pagecount_h * sid->pagerel_h);
2375 x *= (w * sid->pagerel_h) / sid->pagesize_h;
2376 sid->pagesize_h = w * sid->pagerel_h;
2383 dx = (sid->pagesize_h * ((double)sid->page_limit_h - 0.5));
2386 x += (abs(offset) < dx ? offset : dx);
2388 x += (abs(offset) < dx ? offset : -(dx + 1));
2391 if (sid->pagesize_h > 0)
2393 if (x >= minx) x = x + (sid->pagesize_h * 0.5);
2394 else x = x - (sid->pagesize_h * 0.5);
2395 x = x / (sid->pagesize_h);
2396 x = x * (sid->pagesize_h);
2400 if ((x + w) > cw) x = cw - w;
2401 if (x < minx) x = minx;
2408 _elm_scroll_page_y_get(Elm_Scrollable_Smart_Interface_Data *sid,
2409 int offset, Eina_Bool limit)
2411 Evas_Coord x, y, w, h, dy, cw, ch, miny = 0;
2413 if (!sid->pan_obj) return 0;
2415 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, 0);
2417 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2418 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
2419 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
2420 psd->api->pos_min_get(sid->pan_obj, NULL, &miny);
2422 if (sid->pagerel_v > 0.0)
2424 if (sid->pagecount_v != 0)
2425 h = ch / (sid->pagecount_v * sid->pagerel_v);
2426 y *= (h * sid->pagerel_v) / sid->pagesize_v;
2427 sid->pagesize_v = h * sid->pagerel_v;
2433 dy = (sid->pagesize_v * ((double)sid->page_limit_v - 0.5));
2436 y += (abs(offset) < dy ? offset : dy);
2438 y += (abs(offset) < dy ? offset : -(dy + 1));
2441 if (sid->pagesize_v > 0)
2443 if (y >= miny) y = y + (sid->pagesize_v * 0.5);
2444 else y = y - (sid->pagesize_v * 0.5);
2445 y = y / (sid->pagesize_v);
2446 y = y * (sid->pagesize_v);
2450 if ((y + h) > ch) y = ch - h;
2451 if (y < miny) y = miny;
2458 _elm_scroll_scroll_to_x_animator(void *data)
2460 Elm_Scrollable_Smart_Interface_Data *sid = data;
2464 if (!sid->pan_obj) return ECORE_CALLBACK_CANCEL;
2466 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, ECORE_CALLBACK_CANCEL);
2468 t = ecore_loop_time_get();
2469 tt = (t - sid->scrollto.x.t_start) /
2470 (sid->scrollto.x.t_end - sid->scrollto.x.t_start);
2472 tt = 1.0 - (tt * tt);
2473 psd->api->pos_get(sid->pan_obj, &px, &py);
2474 px = (sid->scrollto.x.start * (1.0 - tt)) +
2475 (sid->scrollto.x.end * tt);
2476 if (t >= sid->scrollto.x.t_end)
2478 px = sid->scrollto.x.end;
2479 _elm_scroll_content_pos_set(sid->obj, px, py, EINA_TRUE);
2481 sid->down.x = sid->down.history[0].x;
2482 _elm_scroll_wanted_coordinates_update(sid, px, py);
2483 sid->scrollto.x.animator = NULL;
2484 if ((!sid->scrollto.y.animator) && (!sid->down.bounce_y_animator))
2485 _elm_scroll_anim_stop(sid);
2486 return ECORE_CALLBACK_CANCEL;
2488 _elm_scroll_content_pos_set(sid->obj, px, py, EINA_TRUE);
2489 _elm_scroll_wanted_coordinates_update(sid, px, py);
2490 return ECORE_CALLBACK_RENEW;
2494 _elm_scroll_scroll_to_y_animator(void *data)
2496 Elm_Scrollable_Smart_Interface_Data *sid = data;
2500 if (!sid->pan_obj) return EINA_FALSE;
2502 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, EINA_FALSE);
2504 t = ecore_loop_time_get();
2505 tt = (t - sid->scrollto.y.t_start) /
2506 (sid->scrollto.y.t_end - sid->scrollto.y.t_start);
2508 tt = 1.0 - (tt * tt);
2509 psd->api->pos_get(sid->pan_obj, &px, &py);
2510 py = (sid->scrollto.y.start * (1.0 - tt)) +
2511 (sid->scrollto.y.end * tt);
2512 if (t >= sid->scrollto.y.t_end)
2514 py = sid->scrollto.y.end;
2515 _elm_scroll_content_pos_set(sid->obj, px, py, EINA_TRUE);
2517 sid->down.y = sid->down.history[0].y;
2518 _elm_scroll_wanted_coordinates_update(sid, px, py);
2519 sid->scrollto.y.animator = NULL;
2520 if ((!sid->scrollto.x.animator) && (!sid->down.bounce_x_animator))
2521 _elm_scroll_anim_stop(sid);
2522 return ECORE_CALLBACK_CANCEL;
2524 _elm_scroll_content_pos_set(sid->obj, px, py, EINA_TRUE);
2525 _elm_scroll_wanted_coordinates_update(sid, px, py);
2527 return ECORE_CALLBACK_RENEW;
2531 _elm_scroll_scroll_to_y(Elm_Scrollable_Smart_Interface_Data *sid,
2535 Evas_Coord px, py, x, y, w, h;
2538 if (!sid->pan_obj) return;
2540 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2542 if (sid->freeze) return;
2545 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2546 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
2548 _elm_scroll_content_region_set(sid->obj, x, y, w, h);
2551 t = ecore_loop_time_get();
2552 psd->api->pos_get(sid->pan_obj, &px, &py);
2553 sid->scrollto.y.start = py;
2554 sid->scrollto.y.end = pos_y;
2555 sid->scrollto.y.t_start = t;
2556 sid->scrollto.y.t_end = t + t_in;
2557 if (!sid->scrollto.y.animator)
2559 sid->scrollto.y.animator =
2560 ecore_animator_add(_elm_scroll_scroll_to_y_animator, sid);
2561 if (!sid->scrollto.x.animator)
2562 _elm_scroll_anim_start(sid);
2564 if (sid->down.bounce_y_animator)
2566 ecore_animator_del(sid->down.bounce_y_animator);
2567 sid->down.bounce_y_animator = NULL;
2568 _elm_scroll_momentum_end(sid);
2569 if (sid->content_info.resized)
2570 _elm_scroll_wanted_region_set(sid->obj);
2572 sid->bouncemey = EINA_FALSE;
2576 _elm_scroll_scroll_to_x(Elm_Scrollable_Smart_Interface_Data *sid,
2580 Evas_Coord px, py, x, y, w, h;
2583 if (!sid->pan_obj) return;
2585 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2587 if (sid->freeze) return;
2590 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2591 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
2593 _elm_scroll_content_region_set(sid->obj, x, y, w, h);
2596 t = ecore_loop_time_get();
2597 psd->api->pos_get(sid->pan_obj, &px, &py);
2598 sid->scrollto.x.start = px;
2599 sid->scrollto.x.end = pos_x;
2600 sid->scrollto.x.t_start = t;
2601 sid->scrollto.x.t_end = t + t_in;
2602 if (!sid->scrollto.x.animator)
2604 sid->scrollto.x.animator =
2605 ecore_animator_add(_elm_scroll_scroll_to_x_animator, sid);
2606 if (!sid->scrollto.y.animator)
2607 _elm_scroll_anim_start(sid);
2609 if (sid->down.bounce_x_animator)
2611 ecore_animator_del(sid->down.bounce_x_animator);
2612 sid->down.bounce_x_animator = NULL;
2613 _elm_scroll_momentum_end(sid);
2614 if (sid->content_info.resized)
2615 _elm_scroll_wanted_region_set(sid->obj);
2617 sid->bouncemex = EINA_FALSE;
2621 _elm_scroll_mouse_up_event_cb(void *data,
2623 Evas_Object *obj __UNUSED__,
2626 Elm_Scrollable_Smart_Interface_Data *sid = data;
2627 Evas_Coord x = 0, y = 0, ox = 0, oy = 0;
2628 Evas_Event_Mouse_Down *ev;
2630 if (!sid->pan_obj) return;
2632 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
2634 if ((sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL) &&
2635 (sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
2639 if (_elm_scroll_smooth_debug) _elm_scroll_smooth_debug_shutdown();
2643 sid->down.hold_parent = EINA_FALSE;
2646 evas_post_event_callback_push(e, _elm_scroll_post_event_up, sid);
2649 edje_object_signal_emit(sid->edje_obj, "elm,state,mouse,up", "elm");
2651 // FIXME: respect elm_widget_scroll_hold_get of parent container
2652 if (!_elm_config->thumbscroll_enable) return;
2654 if (ev->button == 1)
2656 if (sid->down.onhold_animator)
2658 ecore_animator_del(sid->down.onhold_animator);
2659 sid->down.onhold_animator = NULL;
2660 if (sid->content_info.resized)
2661 _elm_scroll_wanted_region_set(sid->obj);
2663 x = ev->canvas.x - sid->down.x;
2664 y = ev->canvas.y - sid->down.y;
2665 if (sid->down.dragged)
2667 _elm_scroll_drag_stop(sid);
2668 if ((!sid->hold) && (!sid->freeze))
2672 Evas_Coord ax, ay, dx, dy, vel;
2675 t = ev->timestamp / 1000.0;
2677 t = ecore_loop_time_get();
2680 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2686 DBG("------ %i %i\n", ev->canvas.x, ev->canvas.y);
2688 for (i = 0; i < 60; i++)
2690 dt = t - sid->down.history[i].timestamp;
2691 if (dt > 0.4) break;
2693 DBG("H: %i %i @ %1.3f\n",
2694 sid->down.history[i].x,
2695 sid->down.history[i].y, dt);
2698 ax += sid->down.history[i].x;
2699 ay += sid->down.history[i].y;
2704 at /= _elm_config->thumbscroll_sensitivity_friction;
2705 dx = ev->canvas.x - ax;
2706 dy = ev->canvas.y - ay;
2709 vel = sqrt((dx * dx) + (dy * dy)) / at;
2710 if ((_elm_config->thumbscroll_friction > 0.0) &&
2711 (vel > _elm_config->thumbscroll_momentum_threshold))
2713 Evas_Coord vw, vh, aw, ah, max_d;
2714 int minx, miny, mx, my, px, py;
2715 double tt = 0.0, dtt = 0.0;
2717 psd->api->pos_min_get
2718 (sid->pan_obj, &minx, &miny);
2719 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
2720 psd->api->pos_get(sid->pan_obj, &px, &py);
2721 max_d = _elm_config->thumbscroll_flick_distance_tolerance;
2723 /* Original scroller used sin graph for calculating flick distance.
2724 But calculated flick distance is so long.
2725 So I divided into two sections. First section use sin grapth divided into 2.
2726 And second section use original logic.
2727 As a result, if flicking velocity is slow, flicking distance will be short.
2731 if (dx > max_d) dx = max_d;
2732 if (0.4 >= ((sin((M_PI * (double)dx / max_d) - (M_PI / 2)) + 1) / 2))
2733 sid->down.dx = ((sin((M_PI * (double)dx / max_d)
2734 - (M_PI / 2)) + 1) / 2) * max_d / at;
2736 sid->down.dx = ((sin((M_PI * (double)dx / max_d)
2737 - (M_PI / 2)) + 1)) * max_d / at;
2741 if (dx < -max_d) dx = -max_d;
2742 if (-0.4 <= ((sin((M_PI * (double)dx / max_d) + (M_PI / 2)) - 1) / 2))
2743 sid->down.dx = ((sin((M_PI * (double)dx / max_d)
2744 + (M_PI / 2)) - 1) / 2) * max_d / at;
2746 sid->down.dx = (sin((M_PI * (double)dx / max_d)
2747 + (M_PI / 2)) - 1) * max_d / at;
2751 if (dy > max_d) dy = max_d;
2752 if (0.4 >= ((sin((M_PI * (double)dy / max_d) - (M_PI / 2)) + 1) / 2))
2753 sid->down.dy = ((sin((M_PI * (double)dy / max_d)
2754 - (M_PI / 2)) + 1) / 2) * max_d / at;
2756 sid->down.dy = (sin((M_PI * (double)dy / max_d)
2757 - (M_PI / 2)) + 1) * max_d / at;
2761 if (dy < -max_d) dy = -max_d;
2762 if (-0.4 <= ((sin((M_PI * (double)dy / max_d) + (M_PI / 2)) - 1) / 2))
2763 sid->down.dy = ((sin((M_PI * (double)dy / max_d)
2764 + (M_PI / 2)) - 1) / 2) * max_d / at;
2766 sid->down.dy = (sin((M_PI * (double)dy / max_d)
2767 + (M_PI / 2)) - 1) * max_d / at;
2769 if (((sid->down.dx > 0) && (sid->down.pdx > 0)) ||
2770 ((sid->down.dx < 0) && (sid->down.pdx < 0)) ||
2771 ((sid->down.dy > 0) && (sid->down.pdy > 0)) ||
2772 ((sid->down.dy < 0) && (sid->down.pdy < 0)))
2774 tt = ecore_loop_time_get();
2775 dtt = tt - sid->down.anim_start;
2777 if (dtt < 0.0) dtt = 0.0;
2779 _elm_config->thumbscroll_friction)
2780 dtt = _elm_config->thumbscroll_friction;
2781 sid->down.extra_time =
2782 _elm_config->thumbscroll_friction - dtt;
2785 sid->down.extra_time = 0.0;
2787 aw = abs(sid->down.dx);
2788 _elm_scroll_content_viewport_size_get(sid->obj, &vw, &vh);
2791 if (sid->down.dx > 0) sid->down.dx = vw * 3;
2792 else sid->down.dx = -(vw * 3);
2794 ah = abs(sid->down.dy);
2797 if (sid->down.dy > 0) sid->down.dy = vh * 3;
2798 else sid->down.dy = -(vh * 3);
2801 if (psd->api->pos_adjust)
2803 Evas_Coord pos_x, pos_y;
2805 pos_x = sid->down.dx;
2806 pos_y = sid->down.dy;
2808 pos_x = _round(pos_x * (_elm_config->thumbscroll_friction +
2809 sid->down.extra_time), 0);
2810 pos_y = _round(pos_y * (_elm_config->thumbscroll_friction +
2811 sid->down.extra_time), 0);
2812 psd->api->pos_adjust(sid, &pos_x, &pos_y);
2814 sid->down.dx = pos_x;
2815 sid->down.dy = pos_y;
2818 sid->down.pdx = sid->down.dx;
2819 sid->down.pdy = sid->down.dy;
2822 if (!_paging_is_enabled(sid))
2824 if ((!sid->down.momentum_animator) &&
2825 (!sid->momentum_animator_disabled) &&
2827 (!elm_widget_drag_child_locked_y_get
2830 sid->down.momentum_animator =
2832 (_elm_scroll_momentum_animator, sid);
2834 EVAS_EVENT_FLAG_ON_SCROLL;
2835 _elm_scroll_anim_start(sid);
2837 sid->down.anim_start = ecore_loop_time_get();
2838 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2847 if (psd->api->pos_adjust)
2849 Evas_Coord pos_x = 0, pos_y = 0;
2850 Evas_Coord adjust_x, adjust_y;
2852 psd->api->pos_adjust(sid, &pos_x, &pos_y);
2854 _elm_scroll_content_pos_get(sid->obj, &adjust_x, &adjust_y);
2858 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, adjust_y);
2864 if (psd->api->pos_adjust)
2866 Evas_Coord pos_x = 0, pos_y = 0;
2867 Evas_Coord adjust_x, adjust_y;
2869 psd->api->pos_adjust(sid, &pos_x, &pos_y);
2871 _elm_scroll_content_pos_get(sid->obj, &adjust_x, &adjust_y);
2875 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, adjust_y);
2884 evas_event_feed_hold(e, 0, ev->timestamp, ev->data);
2885 if (_paging_is_enabled(sid))
2887 Evas_Coord pgx, pgy;
2889 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2891 (!elm_widget_drag_child_locked_x_get
2895 if (sid->down.dir_x && sid->pagesize_h > 0)
2899 if (sid->down.pageflick_h < 0)
2900 ox = sid->pagesize_h + sid->down.pageflick_h;
2902 ox = sid->pagesize_h * 0.5;
2906 if (sid->down.pageflick_h > 0)
2907 ox = -(sid->pagesize_h - sid->down.pageflick_h + 1);
2909 ox = -(sid->pagesize_h * 0.5 + 1);
2912 pgx = _elm_scroll_page_x_get(sid, ox, EINA_TRUE);
2915 ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
2917 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2918 _elm_scroll_scroll_to_x
2919 (sid, _elm_config->page_scroll_friction, pgx);
2923 (!elm_widget_drag_child_locked_y_get
2927 if (sid->down.dir_y && sid->pagesize_v > 0)
2931 if (sid->down.pageflick_v < 0)
2932 oy = sid->pagesize_v + sid->down.pageflick_v;
2934 oy = sid->pagesize_v * 0.5;
2938 if (sid->down.pageflick_v > 0)
2939 oy = -(sid->pagesize_v - sid->down.pageflick_v + 1);
2941 oy = -(sid->pagesize_v * 0.5 + 1);
2944 pgy = _elm_scroll_page_y_get(sid, oy, EINA_TRUE);
2947 ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL))
2949 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2950 _elm_scroll_scroll_to_y
2951 (sid, _elm_config->page_scroll_friction, pgy);
2960 if (_paging_is_enabled(sid))
2962 Evas_Coord pgx, pgy;
2964 _elm_scroll_content_pos_get(sid->obj, &x, &y);
2966 (!elm_widget_drag_child_locked_x_get
2969 pgx = _elm_scroll_page_x_get(sid, ox, EINA_TRUE);
2971 _elm_scroll_scroll_to_x
2972 (sid, _elm_config->page_scroll_friction, pgx);
2975 (!elm_widget_drag_child_locked_y_get
2978 pgy = _elm_scroll_page_y_get(sid, oy, EINA_TRUE);
2980 _elm_scroll_scroll_to_y
2981 (sid, _elm_config->page_scroll_friction, pgy);
2985 if (sid->down.hold_animator)
2987 ecore_animator_del(sid->down.hold_animator);
2988 sid->down.hold_animator = NULL;
2989 if (sid->content_info.resized)
2990 _elm_scroll_wanted_region_set(sid->obj);
2992 if (sid->down.scroll)
2994 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2995 sid->down.scroll = EINA_FALSE;
2999 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3000 sid->down.hold = EINA_FALSE;
3002 sid->down.dragged_began = EINA_FALSE;
3003 sid->down.dir_x = EINA_FALSE;
3004 sid->down.dir_y = EINA_FALSE;
3005 sid->down.want_dragged = EINA_FALSE;
3006 sid->down.dragged = EINA_FALSE;
3007 sid->down.now = EINA_FALSE;
3008 _elm_scroll_content_pos_get(sid->obj, &x, &y);
3009 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
3010 _elm_scroll_wanted_coordinates_update(sid, x, y);
3012 if (sid->content_info.resized)
3013 _elm_scroll_wanted_region_set(sid->obj);
3015 if (!_paging_is_enabled(sid))
3016 _elm_scroll_bounce_eval(sid);
3021 _elm_scroll_mouse_down_event_cb(void *data,
3023 Evas_Object *obj __UNUSED__,
3026 Elm_Scrollable_Smart_Interface_Data *sid;
3027 Evas_Event_Mouse_Down *ev;
3028 Evas_Coord x = 0, y = 0;
3034 if (getenv("ELS_SCROLLER_SMOOTH_DEBUG")) _elm_scroll_smooth_debug = 1;
3035 if (_elm_scroll_smooth_debug) _elm_scroll_smooth_debug_init();
3038 if ((sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL) &&
3039 (sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
3043 edje_object_signal_emit(sid->edje_obj, "elm,state,mouse,down", "elm");
3045 if (_elm_config->thumbscroll_enable)
3047 sid->down.hold = EINA_FALSE;
3048 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
3049 (sid->down.momentum_animator) || (sid->scrollto.x.animator) ||
3050 (sid->scrollto.y.animator))
3052 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL |
3053 EVAS_EVENT_FLAG_ON_HOLD;
3054 sid->down.scroll = EINA_TRUE;
3055 sid->down.hold = EINA_TRUE;
3056 _elm_scroll_anim_stop(sid);
3058 if (sid->scrollto.x.animator)
3060 ecore_animator_del(sid->scrollto.x.animator);
3061 sid->scrollto.x.animator = NULL;
3063 if (sid->scrollto.y.animator)
3065 ecore_animator_del(sid->scrollto.y.animator);
3066 sid->scrollto.y.animator = NULL;
3068 if (sid->down.bounce_x_animator)
3070 ecore_animator_del(sid->down.bounce_x_animator);
3071 sid->down.bounce_x_animator = NULL;
3072 sid->bouncemex = EINA_FALSE;
3073 if (sid->content_info.resized)
3074 _elm_scroll_wanted_region_set(sid->obj);
3076 if (sid->down.bounce_y_animator)
3078 ecore_animator_del(sid->down.bounce_y_animator);
3079 sid->down.bounce_y_animator = NULL;
3080 sid->bouncemey = EINA_FALSE;
3081 if (sid->content_info.resized)
3082 _elm_scroll_wanted_region_set(sid->obj);
3084 if (sid->down.hold_animator)
3086 ecore_animator_del(sid->down.hold_animator);
3087 sid->down.hold_animator = NULL;
3088 _elm_scroll_drag_stop(sid);
3089 if (sid->content_info.resized)
3090 _elm_scroll_wanted_region_set(sid->obj);
3092 if (sid->down.momentum_animator)
3094 ecore_animator_del(sid->down.momentum_animator);
3095 sid->down.momentum_animator = NULL;
3096 sid->down.bounce_x_hold = EINA_FALSE;
3097 sid->down.bounce_y_hold = EINA_FALSE;
3100 if (sid->content_info.resized)
3101 _elm_scroll_wanted_region_set(sid->obj);
3103 if (ev->button == 1)
3105 if (_paging_is_enabled(sid))
3107 sid->down.pageflick_h = 0;
3108 sid->down.pageflick_v = 0;
3110 sid->down.hist.est_timestamp_diff =
3111 ecore_loop_time_get() - ((double)ev->timestamp / 1000.0);
3112 sid->down.hist.tadd = 0.0;
3113 sid->down.hist.dxsum = 0.0;
3114 sid->down.hist.dysum = 0.0;
3115 sid->down.now = EINA_TRUE;
3116 sid->down.dragged = EINA_FALSE;
3117 sid->down.dir_x = EINA_FALSE;
3118 sid->down.dir_y = EINA_FALSE;
3119 sid->down.x = ev->canvas.x;
3120 sid->down.y = ev->canvas.y;
3121 _elm_scroll_content_pos_get(sid->obj, &x, &y);
3124 sid->down.locked = EINA_FALSE;
3125 memset(&(sid->down.history[0]), 0,
3126 sizeof(sid->down.history[0]) * ELM_SCROLL_HISTORY_SIZE);
3128 sid->down.history[0].timestamp = ev->timestamp / 1000.0;
3129 sid->down.history[0].localtimestamp = ecore_loop_time_get();
3131 sid->down.history[0].timestamp = ecore_loop_time_get();
3133 sid->down.dragged_began_timestamp = sid->down.history[0].timestamp;
3134 sid->down.history[0].x = ev->canvas.x;
3135 sid->down.history[0].y = ev->canvas.y;
3137 sid->down.dragged_began = EINA_FALSE;
3138 sid->down.hold_parent = EINA_FALSE;
3139 sid->down.cancelled = EINA_FALSE;
3140 if (sid->hold || sid->freeze)
3141 sid->down.want_reset = EINA_TRUE;
3143 sid->down.want_reset = EINA_FALSE;
3148 _elm_scroll_can_scroll(Elm_Scrollable_Smart_Interface_Data *sid,
3151 Evas_Coord mx = 0, my = 0, px = 0, py = 0, minx = 0, miny = 0;
3153 if (!sid->pan_obj) return EINA_FALSE;
3155 ELM_PAN_DATA_GET_OR_RETURN_VAL(sid->pan_obj, psd, EINA_FALSE);
3157 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
3158 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
3159 psd->api->pos_get(sid->pan_obj, &px, &py);
3163 if (px > minx) return EINA_TRUE;
3167 if ((px - minx) < mx) return EINA_TRUE;
3171 if (py > miny) return EINA_TRUE;
3175 if ((py - miny) < my) return EINA_TRUE;
3185 _elm_scroll_post_event_move(void *data,
3188 Elm_Scrollable_Smart_Interface_Data *sid = data;
3189 Eina_Bool horiz, vert;
3191 if (sid->down.want_dragged)
3195 elm_widget_parents_bounce_get(sid->obj, &horiz, &vert);
3196 if (sid->down.hold_parent)
3198 if ((sid->down.dir_x) && (horiz || !sid->bounce_horiz) &&
3199 !_elm_scroll_can_scroll(sid, sid->down.hdir))
3201 sid->down.dir_x = EINA_FALSE;
3203 if ((sid->down.dir_y) && (vert || !sid->bounce_vert) &&
3204 !_elm_scroll_can_scroll(sid, sid->down.vdir))
3206 sid->down.dir_y = EINA_FALSE;
3208 sid->down.dragged_began = EINA_TRUE;
3210 if (sid->down.dir_x)
3213 (!elm_widget_drag_child_locked_x_get(sid->obj)))
3215 if (sid->down.dragged_began)
3217 sid->down.want_dragged = EINA_FALSE;
3218 sid->down.dragged = EINA_TRUE;
3221 elm_widget_drag_lock_x_set(sid->obj, 1);
3228 sid->down.dragged_began = EINA_TRUE;
3229 sid->down.dir_x = EINA_FALSE;
3232 if (sid->down.dir_y)
3235 (!elm_widget_drag_child_locked_y_get(sid->obj)))
3237 if (sid->down.dragged_began)
3239 sid->down.want_dragged = EINA_FALSE;
3240 sid->down.dragged = EINA_TRUE;
3243 elm_widget_drag_lock_y_set
3244 (sid->obj, EINA_TRUE);
3251 sid->down.dragged_began = EINA_TRUE;
3252 sid->down.dir_y = EINA_FALSE;
3255 if ((!sid->down.dir_x) && (!sid->down.dir_y))
3257 sid->down.cancelled = EINA_TRUE;
3259 if (start) _elm_scroll_drag_start(sid);
3266 _elm_scroll_down_coord_eval(Elm_Scrollable_Smart_Interface_Data *sid,
3270 Evas_Coord minx, miny;
3272 if (!sid->pan_obj) return;
3274 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
3276 if (_paging_is_enabled(sid))
3278 sid->down.pageflick_h = *x - sid->down.x;
3279 sid->down.pageflick_v = *y - sid->down.y;
3282 if (sid->down.dir_x) *x = sid->down.sx - (*x - sid->down.x);
3283 else *x = sid->down.sx;
3284 if (sid->down.dir_y) *y = sid->down.sy - (*y - sid->down.y);
3285 else *y = sid->down.sy;
3287 if ((sid->down.dir_x) || (sid->down.dir_y))
3289 if (!((sid->down.dir_x) && (sid->down.dir_y)))
3291 if (sid->down.dir_x) *y = sid->down.locked_y;
3292 else *x = sid->down.locked_x;
3296 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
3298 if (!sid->loop_h && *x < minx)
3299 *x += (minx - *x) * _elm_config->thumbscroll_border_friction;
3300 else if (!sid->loop_h && sid->content_info.w <= sid->w)
3301 *x += (sid->down.sx - *x) * _elm_config->thumbscroll_border_friction;
3302 else if (!sid->loop_h && (sid->content_info.w - sid->w + minx) < *x)
3303 *x += (sid->content_info.w - sid->w + minx - *x) *
3304 _elm_config->thumbscroll_border_friction;
3306 if (!sid->loop_v && *y < miny)
3307 *y += (miny - *y) * _elm_config->thumbscroll_border_friction;
3308 else if (!sid->loop_v && sid->content_info.h <= sid->h)
3309 *y += (sid->down.sy - *y) * _elm_config->thumbscroll_border_friction;
3310 else if (!sid->loop_v && (sid->content_info.h - sid->h + miny) < *y)
3311 *y += (sid->content_info.h - sid->h + miny - *y) *
3312 _elm_config->thumbscroll_border_friction;
3315 //TIZEN ONLY : for scroll smooth algorithm
3317 #define iround(x) ((x)>=0?(int)((x)+0.5):(int)((x)-0.5))
3319 //> Frequency of move events
3320 #define ELM_MOVE_PER_SECOND (90.75)
3321 //>Time between two subsequent events
3322 #define ELM_MOVE_TIMEOUT (1./ELM_MOVE_PER_SECOND)
3324 //>Quantity of move events in time interval
3325 #define ELM_MOVE_COUNT(t) iround((t)*ELM_MOVE_PER_SECOND)
3327 //>Getting coordinate (x is 0, y is 1) from struct Elm_Scroll_Pos or Elm_Scroll_History_Item.
3328 #define ELM_GET_COORD(p, coord) (*((int *)p + coord))
3330 //>Difference of coordinates of points with indexes ind and ind+inc.
3331 #define ELM_DIFF(p, coord, ind, inc) (ELM_GET_COORD((p + ind), coord) - ELM_GET_COORD((p + ind + inc), coord))
3333 //>Index in array for calculation of smoothed velocity.
3334 #define ELM_SMOOTH_SPEED_INDEX 9
3336 //>in seconds, includes driver to X time gap
3337 #define EXTRA_PREDIOCTION_TIME (-0.005)
3339 //>Calculating current velocity. In normal situation it is (pos[0].x - pos[ELM_SMOOTH_SPEED_INDEX].x) / (pos[0].t - pos[ELM_SMOOTH_SPEED_INDEX].t).
3340 //>But in situations when: 1. Sign of velocity was changes or 2. The acceleration is of constant sign or 3. There was stop of movement
3341 //>The index ELM_SMOOTH_SPEED_INDEX is replaced by 1.
3342 double _elm_scroll_get_v(Elm_Scroll_Pos *pos, int num, int coord,
3343 double *dt, int *pdiff, double *padt, Elm_Scroll_Predict *predict)
3346 int nmeasure_idx = (num > ELM_SMOOTH_SPEED_INDEX) ? ELM_SMOOTH_SPEED_INDEX : (num -1);
3347 // a recent input takes higher priority
3348 #if USE_HISTORY_WEIGHT
3349 if (nmeasure_idx >= 2)
3350 *pdiff = (ELM_DIFF(pos, coord, 0, 1) * 2 + ELM_DIFF(pos, coord, 1, 1))/3;
3353 *pdiff = ELM_DIFF(pos, coord, 0, 1);
3356 #if ADJUST_EVENT_TIME
3357 *dt = -ELM_MOVE_TIMEOUT;
3359 if (nmeasure_idx >= 2)
3360 *dt = -(pos[2].t - pos[0].t)/2.;
3362 *dt = -(pos[1].t - pos[0].t);
3365 *dt = -ELM_MOVE_TIMEOUT;
3367 predict->k[coord] = 0;
3368 *padt = EXTRA_PREDIOCTION_TIME;
3373 static Eina_Bool _elm_scroll_get_pos(Elm_Scrollable_Smart_Interface_Data *sid,
3374 Elm_Scroll_Pos *pos, int num, int *fx, int *fy)
3376 double vx = 0, vy = 0, dt = 0, dtx = 0, dty = 0;
3384 *fx = iround((double)pos[0].x);
3385 *fy = iround((double)pos[0].y);
3390 if (sid->down.dir_y)
3391 vy = _elm_scroll_get_v(pos, num, 1, &dt, &diffy, &dty, &sid->down.predict);
3392 if (sid->down.dir_x)
3393 vx = _elm_scroll_get_v(pos, num, 0, &dt, &diffx, &dtx, &sid->down.predict);
3396 if (sid->down.dir_x)
3398 *fx = iround((double)pos[0].x - (pos[0].t + dtx) * vx);
3399 // don't go back even though over-run is detected.
3400 if (sid->down.anim_vx_prev && sid->down.anim_vx_prev * vx >= 0)
3401 if (vx == 0 || (vx > 0 && *fx > sid->down.anim_x_prev) ||
3402 (vx < 0 && *fx < sid->down.anim_x_prev))
3403 *fx = sid->down.anim_x_prev;
3406 if (sid->down.dir_y)
3408 *fy = iround((double)pos[0].y - (pos[0].t + dty) * vy);
3409 // don't go back even though over-run is detected.
3410 if (sid->down.anim_vy_prev && sid->down.anim_vy_prev * vy >= 0)
3411 if (vy == 0 || (vy > 0 && *fy > sid->down.anim_y_prev) ||
3412 (vy < 0 && *fy < sid->down.anim_y_prev))
3413 *fy = sid->down.anim_y_prev;
3416 sid->down.anim_x_prev = *fx;
3417 sid->down.anim_y_prev = *fy;
3418 sid->down.anim_vx_prev = vx;
3419 sid->down.anim_vy_prev = vy;
3424 #define COMPENSATE_FOR_INITIAL_RENDER_DELAY 0
3425 #define ADJUST_ANIMATOR_TIMING 1
3426 #define SMART_SMOOTH_START 1
3427 #define HOLD_ANIMATOR_DEBUG_LEVEL1 0
3428 #define HOLD_ANIMATOR_DEBUG_LEVEL2 0
3429 #define HOLD_ANIMATOR_DEBUG_X_AXIS 1
3430 #define USE_LOOP_TIME 0
3431 #define ADJUST_EVENT_TIME 0
3432 #define USE_HISTORY_WEIGHT 0
3433 #define PREDICT_WHEN_PAUSED 0
3436 _elm_scroll_hold_animator(void *data)
3438 Elm_Scrollable_Smart_Interface_Data *sid = data;
3439 Evas_Coord ox = 0, oy = 0, fx = 0, fy = 0, x = 0, y = 0, num = 0;
3440 Evas_Coord fx_coord = 0, fy_coord = 0;
3441 fx = sid->down.hold_x;
3442 fy = sid->down.hold_y;
3443 fx_coord = sid->down.anim_x_coord_prev;
3444 fy_coord = sid->down.anim_y_coord_prev;
3445 #define QUEUE_SIZE 3 /* for event queue size */
3446 Elm_Scroll_Pos pos[QUEUE_SIZE];
3448 double now, now_diff, prev;
3449 double animators_frametime=0, d = 0;
3450 double pos_diff = 0;
3452 Ecore_Animator_Source source;
3454 sid->down.anim_count++;
3456 source = ecore_animator_source_get();
3458 // FIXME: assume server and client have the same "timezone"
3459 // (0 timepoint) for now. this needs to be figured out in advance
3462 now = ecore_loop_time_get();
3464 now = ecore_time_get();
3467 // init variables for the first animator run
3468 if (sid->down.anim_count == 1)
3470 sid->down.anim_t_prev = now;
3471 sid->down.anim_x_coord_prev = fx;
3472 sid->down.anim_y_coord_prev = fy;
3476 prev = sid->down.anim_t_prev;
3477 now_diff = now - prev;
3478 animators_frametime = ecore_animator_frametime_get();
3479 #if COMPENSATE_FOR_INITIAL_RENDER_DELAY
3480 if (sid->down.anim_count == 1)
3482 if (source != ECORE_ANIMATOR_SOURCE_CUSTOM)
3483 sid->down.anim_t_delay = fmod(now, animators_frametime);
3488 sid->down.anim_t_delay += now_diff - animators_frametime;
3491 // skip this turn if specified.
3492 if (sid->down.anim_skip > 0)
3494 sid->down.anim_skip--;
3495 #if HOLD_ANIMATOR_DEBUG_LEVEL1
3496 DBG("[%03d/%s] %.4f %.3f/%.3f dt:%.3f = %.3f%+.3f ev: %.4f skip(%d)\n",
3497 sid->down.anim_count, (source == ECORE_ANIMATOR_SOURCE_CUSTOM) ? "V" : "T",
3498 now, sid->down.anim_t_delay * 1000, sid->down.anim_t_adjusted * 1000,
3500 (now_diff - d)*1000,
3502 sid->down.history[0].timestamp,
3503 sid->down.anim_skip);
3505 if ((now_diff * 1000) > 18)
3507 #if ADJUST_ANIMATOR_TIMING
3508 sid->down.anim_t_dont_adjust = 1;
3510 goto update_time_and_quit;
3514 // We don't need to process old events again.
3515 if (sid->down.anim_count != 1 &&
3516 sid->down.anim_pos_t_prev == sid->down.history[0].timestamp)
3518 #if HOLD_ANIMATOR_DEBUG_LEVEL1
3519 DBG("[%03d/%s] %.4f %.3f/%.3f dt:%.3f = %.3f%+.3f ev:%.4f skip(%d) no events.\n",
3520 sid->down.anim_count, (source == ECORE_ANIMATOR_SOURCE_CUSTOM) ? "V" : "T",
3521 now, sid->down.anim_t_delay * 1000, sid->down.anim_t_adjusted * 1000,
3523 (now_diff - d)*1000,
3525 sid->down.history[0].timestamp,
3526 sid->down.anim_skip);
3529 goto update_time_and_quit;
3532 #if ADJUST_ANIMATOR_TIMING
3533 if (sid->down.anim_count != 1 && !sid->down.anim_t_dont_adjust)
3535 if (now_diff < animators_frametime*3/4)
3537 d += animators_frametime/4;
3539 else if (now_diff < animators_frametime)
3541 d = animators_frametime - now_diff;
3543 else if (now_diff < animators_frametime*5/4)
3545 d = -(now_diff - animators_frametime);
3549 d = -animators_frametime/4;
3554 sid->down.anim_t_adjusted += d;
3557 sid->down.anim_t_dont_adjust = 0;
3561 #if COMPENSATE_FOR_INITIAL_RENDER_DELAY
3562 // in case the first animator is called manually to make up for gpu's wake-up time,
3563 // then the second animator should be skipped.
3564 if ((sid->down.anim_count == 1) && (sid->down.anim_skip <= 0))
3565 sid->down.anim_skip++;
3568 if ((!sid->hold) && (!sid->freeze) &&
3569 _elm_config->scroll_smooth_time_interval > 0.0)
3572 int ncur_diff_x=0, ncur_diff_y=0;
3573 int nprev_diff_x=0, nprev_diff_y=0;
3575 for (i = 0; i < QUEUE_SIZE; i++)
3577 if (sid->down.history[i].timestamp >=
3578 sid->down.dragged_began_timestamp)
3580 x = sid->down.history[i].x;
3581 y = sid->down.history[i].y;
3583 //if there is no history value, we don't deal with it if
3584 //there is better wat to know existance of history value
3585 //, I will modify this code to it
3586 if ((x == 0) && (y == 0))
3593 pos[i].t = now - sid->down.history[i].timestamp;
3599 // get rid of histories with different move direction.
3600 if (sid->down.dir_x)
3601 ncur_diff_x = pos[i].x - pos[i-1].x;
3602 if (sid->down.dir_y)
3603 ncur_diff_y = pos[i].y - pos[i-1].y;
3605 if (ncur_diff_x * nprev_diff_x < 0 || ncur_diff_y * nprev_diff_y < 0)
3608 #if HOLD_ANIMATOR_DEBUG_LEVEL2
3609 DBG("[%03d] i=%d a dir change detected. stopped.\n",
3610 sid->down.anim_count, i);
3615 nprev_diff_x = ncur_diff_x;
3616 nprev_diff_y = ncur_diff_y;
3618 #if ADJUST_EVENT_TIME
3619 //> a event is delayed??
3620 if (ELM_MOVE_COUNT(pos[i].t - pos[i-1].t) <= 0)
3622 DBG("[%03d] i=%d a event is delayed (%f) ??????????????????\n",
3623 sid->down.anim_count,
3624 i, pos[i].t - pos[i-1].t);
3627 //> a pause in movement detected
3628 if (ELM_MOVE_COUNT(pos[i].t - pos[i-1].t) >= 2)
3630 #if HOLD_ANIMATOR_DEBUG_LEVEL2
3631 DBG("[%03d] i=%d a pause(%f) in movement detected. stopped.\n",
3632 sid->down.anim_count, i, pos[i].t - pos[i-1].t);
3634 #if PREDICT_WHEN_PAUSED
3635 pos[i].t = pos[i-1].t + ELM_MOVE_TIMEOUT;
3645 #if ADJUST_EVENT_TIME
3646 // X server fills in time in milisecond order and it rounds off.
3647 // let's makt it more precise and this is proven by machine moving at constant speed.
3650 double tmp = sid->down.history[0].timestamp;
3651 for (i = num - 1; i >= 1; i--)
3653 pos[i-1].t = pos[i].t - ELM_MOVE_TIMEOUT;
3654 sid->down.history[i-1].timestamp = now - pos[i-1].t;
3656 pos_diff = sid->down.history[0].timestamp - tmp;
3660 sid->down.anim_pos_t_prev = sid->down.history[0].timestamp;
3662 //TIZEN ONLY : for scroll smooth algorithm
3663 _elm_scroll_get_pos(sid, pos, num, &fx, &fy);
3667 _elm_scroll_down_coord_eval(sid, &fx_coord, &fy_coord);
3671 _elm_scroll_content_pos_get(sid->obj, &ox, &oy);
3672 if (sid->down.dir_x)
3675 (!elm_widget_drag_child_locked_x_get(sid->obj)))
3678 if (sid->down.dir_y)
3681 (!elm_widget_drag_child_locked_y_get(sid->obj)))
3686 if (_elm_scroll_smooth_debug)
3687 _elm_scroll_smooth_debug_movetime_add(ox, oy);
3690 _elm_scroll_content_pos_set(sid->obj, ox, oy, EINA_TRUE);
3692 #if HOLD_ANIMATOR_DEBUG_LEVEL1
3693 #if HOLD_ANIMATOR_DEBUG_X_AXIS
3694 DBG("[%03d/%s] %.4f %.3f/%.3f dt:%.3f = %.3f%+.3f ev:%02d %3.4f/%+.3f p:%d(%d) = %d%+d %d %d\n",
3695 sid->down.anim_count, (source == ECORE_ANIMATOR_SOURCE_CUSTOM) ? "V" : "T",
3696 now, sid->down.anim_t_delay * 1000, sid->down.anim_t_adjusted * 1000,
3698 (now_diff - d)*1000,
3700 num, sid->down.history[0].timestamp, pos_diff*1000,
3702 sid->down.hold_x, ox - sid->down.hold_x,
3703 ox - sid->down.anim_x_coord_prev,
3704 (int)sid->down.anim_vx_prev);
3706 DBG("[%03d/%s] %.4f %.3f/%.3f dt:%.3f = %.3f%+.3f ev:%02d %3.4f/%+.3f p:%d(%d) = %d%+d %d %d\n",
3707 sid->down.anim_count, (source == ECORE_ANIMATOR_SOURCE_CUSTOM) ? "V" : "T",
3708 now, sid->down.anim_t_delay * 1000, sid->down.anim_t_adjusted * 1000,
3710 (now_diff - d)*1000,
3712 num, sid->down.history[0].timestamp, pos_diff*1000,
3714 sid->down.hold_y, oy - sid->down.hold_y,
3715 oy - sid->down.anim_y_coord_prev,
3716 (int)sid->down.anim_vy_prev);
3720 sid->down.anim_x_coord_prev = ox;
3721 sid->down.anim_y_coord_prev = oy;
3723 update_time_and_quit:
3724 sid->down.anim_t_prev = now;
3726 return ECORE_CALLBACK_RENEW;
3730 _elm_scroll_on_hold_animator(void *data)
3734 Evas_Coord x, y, ox, oy;
3735 Elm_Scrollable_Smart_Interface_Data *sid;
3738 t = ecore_loop_time_get();
3739 if (sid->down.onhold_tlast > 0.0)
3741 td = t - sid->down.onhold_tlast;
3742 vx = sid->down.onhold_vx * td *
3743 (double)_elm_config->thumbscroll_hold_threshold * 2.0;
3744 vy = sid->down.onhold_vy * td *
3745 (double)_elm_config->thumbscroll_hold_threshold * 2.0;
3746 _elm_scroll_content_pos_get(sid->obj, &ox, &oy);
3750 if (sid->down.dir_x)
3753 (!elm_widget_drag_child_locked_x_get(sid->obj)))
3755 sid->down.onhold_vxe += vx;
3756 x = ox + (int)sid->down.onhold_vxe;
3757 sid->down.onhold_vxe -= (int)sid->down.onhold_vxe;
3761 if (sid->down.dir_y)
3764 (!elm_widget_drag_child_locked_y_get(sid->obj)))
3766 sid->down.onhold_vye += vy;
3767 y = oy + (int)sid->down.onhold_vye;
3768 sid->down.onhold_vye -= (int)sid->down.onhold_vye;
3772 _elm_scroll_content_pos_set(sid->obj, x, y, EINA_TRUE);
3774 sid->down.onhold_tlast = t;
3776 return ECORE_CALLBACK_RENEW;
3780 _elm_scroll_mouse_move_event_cb(void *data,
3782 Evas_Object *obj __UNUSED__,
3785 Elm_Scrollable_Smart_Interface_Data *sid = data;
3786 Evas_Event_Mouse_Move *ev;
3787 Evas_Coord x = 0, y = 0;
3789 if (!sid->pan_obj) return;
3791 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
3793 if ((sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL) &&
3794 (sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
3798 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
3799 sid->down.hold_parent = EINA_TRUE;
3800 evas_post_event_callback_push(e, _elm_scroll_post_event_move, sid);
3802 // FIXME: respect elm_widget_scroll_hold_get of parent container
3803 if (_elm_config->thumbscroll_enable)
3808 edje_object_signal_emit(sid->edje_obj, "elm,state,mouse,move", "elm");
3810 if ((sid->scrollto.x.animator) && (!sid->hold) && (!sid->freeze) &&
3811 !(sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
3814 ecore_animator_del(sid->scrollto.x.animator);
3815 sid->scrollto.x.animator = NULL;
3816 psd->api->pos_get(sid->pan_obj, &px, NULL);
3818 sid->down.x = sid->down.history[0].x;
3821 if ((sid->scrollto.y.animator) && (!sid->hold) && (!sid->freeze) &&
3822 !(sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL))
3825 ecore_animator_del(sid->scrollto.y.animator);
3826 sid->scrollto.y.animator = NULL;
3827 psd->api->pos_get(sid->pan_obj, NULL, &py);
3829 sid->down.y = sid->down.history[0].y;
3833 DBG("::: %i %i\n", ev->cur.canvas.x, ev->cur.canvas.y);
3835 memmove(&(sid->down.history[1]), &(sid->down.history[0]),
3836 sizeof(sid->down.history[0]) * (ELM_SCROLL_HISTORY_SIZE - 1));
3838 sid->down.history[0].timestamp = ev->timestamp / 1000.0;
3839 sid->down.history[0].localtimestamp = ecore_loop_time_get();
3841 sid->down.history[0].timestamp = ecore_loop_time_get();
3843 sid->down.history[0].x = ev->cur.canvas.x;
3844 sid->down.history[0].y = ev->cur.canvas.y;
3846 if (!sid->down.dragged_began)
3848 x = ev->cur.canvas.x - sid->down.x;
3849 y = ev->cur.canvas.y - sid->down.y;
3851 if (sid->one_direction_at_a_time == ELM_SCROLLER_SINGLE_DIRECTION_HARD)
3853 if (abs(x) <_elm_scroll_gradient_check_pixel && abs(y) <_elm_scroll_gradient_check_pixel)
3859 sid->down.hdir = -1;
3860 sid->down.vdir = -1;
3862 if (x > 0) sid->down.hdir = LEFT;
3864 sid->down.hdir = RIGHT;
3865 if (y > 0) sid->down.vdir = UP;
3867 sid->down.vdir = DOWN;
3872 if (sid->one_direction_at_a_time)
3874 if (((x * x) + (y * y)) >
3875 (_elm_config->thumbscroll_threshold *
3876 _elm_config->thumbscroll_threshold))
3878 if (sid->one_direction_at_a_time ==
3879 ELM_SCROLLER_SINGLE_DIRECTION_SOFT)
3885 ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
3887 sid->down.dir_x = EINA_TRUE;
3889 sid->down.dir_y = EINA_FALSE;
3894 sid->down.dir_x = EINA_FALSE;
3896 ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL))
3898 sid->down.dir_y = EINA_TRUE;
3905 ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
3907 sid->down.dir_x = EINA_TRUE;
3910 ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL))
3912 sid->down.dir_y = EINA_TRUE;
3916 else if (sid->one_direction_at_a_time ==
3917 ELM_SCROLLER_SINGLE_DIRECTION_HARD)
3922 ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
3924 sid->down.dir_x = EINA_TRUE;
3926 sid->down.dir_y = EINA_FALSE;
3931 sid->down.dir_x = EINA_FALSE;
3933 ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL))
3935 sid->down.dir_y = EINA_TRUE;
3944 ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
3946 sid->down.dir_x = EINA_TRUE;
3949 ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL))
3951 sid->down.dir_y = EINA_TRUE;
3955 if ((!sid->hold) && (!sid->freeze))
3957 if ((sid->down.dragged) ||
3958 (((x * x) + (y * y)) >
3959 (_elm_config->thumbscroll_threshold *
3960 _elm_config->thumbscroll_threshold)))
3962 if (!sid->down.dragged_began &&
3963 _elm_config->scroll_smooth_start_enable)
3965 #if SMART_SMOOTH_START
3967 for (i = 0 ; i < 5 ; i++)
3968 if (!sid->down.history[i].timestamp)
3973 DBG("smooth-start(-%d): %d->%d->%d->%d->%d->%d\n",
3975 sid->down.history[0].x,
3976 sid->down.history[1].x,
3977 sid->down.history[2].x,
3978 sid->down.history[3].x,
3979 sid->down.history[4].x,
3981 sid->down.x = sid->down.history[i].x;
3982 sid->down.y = sid->down.history[i].y;
3983 sid->down.dragged_began_timestamp = sid->down.history[i].timestamp;
3987 sid->down.x = ev->cur.canvas.x;
3988 sid->down.y = ev->cur.canvas.y;
3990 sid->down.dragged_began_timestamp =
3991 ev->timestamp / 1000.0;
3993 sid->down.dragged_began_timestamp =
3994 ecore_loop_time_get();
3999 if (!sid->down.dragged)
4001 sid->down.want_dragged = EINA_TRUE;
4003 //***************** TIZEN Only
4004 if ((((_elm_scroll_can_scroll(sid, LEFT) || _elm_scroll_can_scroll(sid, RIGHT)) && sid->down.dir_x) ||
4005 ((_elm_scroll_can_scroll(sid, UP) || _elm_scroll_can_scroll(sid, DOWN)) && sid->down.dir_y)) &&
4006 !sid->down.dragged_began)
4008 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
4009 sid->down.dragged_began = EINA_TRUE;
4011 else if (sid->down.dragged_began)
4013 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
4015 //****************************
4016 if (sid->down.dir_x)
4017 x = sid->down.sx - (ev->cur.canvas.x - sid->down.x);
4020 if (sid->down.dir_y)
4021 y = sid->down.sy - (ev->cur.canvas.y - sid->down.y);
4024 if (sid->down.want_reset)
4026 sid->down.x = ev->cur.canvas.x;
4027 sid->down.y = ev->cur.canvas.y;
4028 sid->down.want_reset = EINA_FALSE;
4030 if ((sid->down.dir_x) || (sid->down.dir_y))
4032 if (!sid->down.locked)
4034 sid->down.locked_x = x;
4035 sid->down.locked_y = y;
4036 sid->down.locked = EINA_TRUE;
4038 if (!((sid->down.dir_x) && (sid->down.dir_y)))
4040 if (sid->down.dir_x) y = sid->down.locked_y;
4041 else x = sid->down.locked_x;
4045 Evas_Coord minx, miny, mx, my;
4047 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
4048 psd->api->pos_max_get(sid->pan_obj, &mx, &my);
4049 if (!sid->loop_v && y < miny)
4051 _elm_config->thumbscroll_border_friction;
4052 else if (!sid->loop_v && my <= 0)
4053 y += (sid->down.sy - y) *
4054 _elm_config->thumbscroll_border_friction;
4055 else if (!sid->loop_v && (my + miny) < y)
4056 y += (my + miny - y) *
4057 _elm_config->thumbscroll_border_friction;
4058 if (!sid->loop_h && x < minx)
4060 _elm_config->thumbscroll_border_friction;
4061 else if (!sid->loop_h && mx <= 0)
4062 x += (sid->down.sx - x) *
4063 _elm_config->thumbscroll_border_friction;
4064 else if (!sid->loop_h && (mx + minx) < x)
4065 x += (mx + minx - x) *
4066 _elm_config->thumbscroll_border_friction;
4069 sid->down.hold_x = x;
4070 sid->down.hold_y = y;
4071 if (!sid->down.hold_animator)
4073 sid->down.hold_animator =
4074 ecore_animator_add(_elm_scroll_hold_animator, sid);
4075 sid->down.anim_x_prev = 0;
4076 sid->down.anim_y_prev = 0;
4077 sid->down.anim_vx_prev = 0;
4078 sid->down.anim_vy_prev = 0;
4079 sid->down.anim_t_prev = 0;
4080 sid->down.anim_x_coord_prev = 0;
4081 sid->down.anim_y_coord_prev = 0;
4082 sid->down.anim_count = 0;
4083 sid->down.anim_skip = 0;
4084 sid->down.anim_t_dont_adjust = 0;
4085 sid->down.anim_t_delay = 0;
4086 sid->down.anim_t_adjusted = 0;
4087 sid->down.anim_pos_t_prev = 0;
4088 memset(&sid->down.predict, 0 , sizeof(sid->down.predict));
4093 if (sid->down.dragged_began)
4095 //***************** TIZEN Only
4096 if ((_elm_scroll_can_scroll(sid, sid->down.hdir) && sid->down.dir_x) ||
4097 (_elm_scroll_can_scroll(sid, sid->down.vdir) && sid->down.dir_y))
4099 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
4101 //****************************
4102 if (!sid->down.hold)
4104 sid->down.hold = EINA_TRUE;
4105 evas_event_feed_hold
4106 (e, 1, ev->timestamp, ev->data);
4111 else if (!sid->freeze)
4113 double vx = 0.0, vy = 0.0;
4115 x = ev->cur.canvas.x - sid->x;
4116 y = ev->cur.canvas.y - sid->y;
4117 if (x < _elm_config->thumbscroll_hold_threshold)
4119 if (_elm_config->thumbscroll_hold_threshold > 0.0)
4120 vx = -(double)(_elm_config->thumbscroll_hold_threshold - x)
4121 / _elm_config->thumbscroll_hold_threshold;
4125 else if (x > (sid->w - _elm_config->thumbscroll_hold_threshold))
4127 if (_elm_config->thumbscroll_hold_threshold > 0.0)
4128 vx = (double)(_elm_config->thumbscroll_hold_threshold -
4130 _elm_config->thumbscroll_hold_threshold;
4134 if (y < _elm_config->thumbscroll_hold_threshold)
4136 if (_elm_config->thumbscroll_hold_threshold > 0.0)
4137 vy = -(double)(_elm_config->thumbscroll_hold_threshold - y)
4138 / _elm_config->thumbscroll_hold_threshold;
4142 else if (y > (sid->h - _elm_config->thumbscroll_hold_threshold))
4144 if (_elm_config->thumbscroll_hold_threshold > 0.0)
4145 vy = (double)(_elm_config->thumbscroll_hold_threshold -
4147 _elm_config->thumbscroll_hold_threshold;
4151 if ((vx != 0.0) || (vy != 0.0))
4153 sid->down.onhold_vx = vx;
4154 sid->down.onhold_vy = vy;
4155 if (!sid->down.onhold_animator)
4157 sid->down.onhold_vxe = 0.0;
4158 sid->down.onhold_vye = 0.0;
4159 sid->down.onhold_tlast = 0.0;
4160 sid->down.onhold_animator = ecore_animator_add
4161 (_elm_scroll_on_hold_animator, sid);
4166 if (sid->down.onhold_animator)
4168 ecore_animator_del(sid->down.onhold_animator);
4169 sid->down.onhold_animator = NULL;
4170 if (sid->content_info.resized)
4171 _elm_scroll_wanted_region_set(sid->obj);
4180 _elm_scroll_reconfigure(Elm_Scrollable_Smart_Interface_Data *sid)
4182 _elm_scroll_scroll_bar_size_adjust(sid);
4186 _on_edje_move(void *data,
4188 Evas_Object *edje_obj,
4189 void *event_info __UNUSED__)
4191 Elm_Scrollable_Smart_Interface_Data *sid = data;
4194 evas_object_geometry_get(edje_obj, &x, &y, NULL, NULL);
4199 _elm_scroll_reconfigure(sid);
4203 _on_edje_resize(void *data,
4205 Evas_Object *edje_obj,
4206 void *event_info __UNUSED__)
4208 Elm_Scrollable_Smart_Interface_Data *sid = data;
4211 evas_object_geometry_get(edje_obj, NULL, NULL, &w, &h);
4216 _elm_scroll_reconfigure(sid);
4217 _elm_scroll_wanted_region_set(sid->obj);
4221 _scroll_edje_object_attach(Evas_Object *obj)
4223 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4225 evas_object_event_callback_add
4226 (sid->edje_obj, EVAS_CALLBACK_RESIZE, _on_edje_resize, sid);
4227 evas_object_event_callback_add
4228 (sid->edje_obj, EVAS_CALLBACK_MOVE, _on_edje_move, sid);
4230 edje_object_signal_callback_add
4231 (sid->edje_obj, "reload", "elm", _elm_scroll_reload_cb, sid);
4232 edje_object_signal_callback_add
4233 (sid->edje_obj, "drag", "elm.dragable.vbar", _elm_scroll_vbar_drag_cb,
4235 edje_object_signal_callback_add
4236 (sid->edje_obj, "drag,set", "elm.dragable.vbar",
4237 _elm_scroll_edje_drag_v_cb, sid);
4238 edje_object_signal_callback_add
4239 (sid->edje_obj, "drag,start", "elm.dragable.vbar",
4240 _elm_scroll_edje_drag_v_start_cb, sid);
4241 edje_object_signal_callback_add
4242 (sid->edje_obj, "drag,stop", "elm.dragable.vbar",
4243 _elm_scroll_edje_drag_v_stop_cb, sid);
4244 edje_object_signal_callback_add
4245 (sid->edje_obj, "drag,step", "elm.dragable.vbar",
4246 _elm_scroll_edje_drag_v_cb, sid);
4247 edje_object_signal_callback_add
4248 (sid->edje_obj, "drag,page", "elm.dragable.vbar",
4249 _elm_scroll_edje_drag_v_cb, sid);
4250 edje_object_signal_callback_add
4251 (sid->edje_obj, "elm,vbar,press", "elm",
4252 _elm_scroll_vbar_press_cb, sid);
4253 edje_object_signal_callback_add
4254 (sid->edje_obj, "elm,vbar,unpress", "elm",
4255 _elm_scroll_vbar_unpress_cb, sid);
4256 edje_object_signal_callback_add
4257 (sid->edje_obj, "drag", "elm.dragable.hbar", _elm_scroll_hbar_drag_cb,
4259 edje_object_signal_callback_add
4260 (sid->edje_obj, "drag,set", "elm.dragable.hbar",
4261 _elm_scroll_edje_drag_h_cb, sid);
4262 edje_object_signal_callback_add
4263 (sid->edje_obj, "drag,start", "elm.dragable.hbar",
4264 _elm_scroll_edje_drag_h_start_cb, sid);
4265 edje_object_signal_callback_add
4266 (sid->edje_obj, "drag,stop", "elm.dragable.hbar",
4267 _elm_scroll_edje_drag_h_stop_cb, sid);
4268 edje_object_signal_callback_add
4269 (sid->edje_obj, "drag,step", "elm.dragable.hbar",
4270 _elm_scroll_edje_drag_h_cb, sid);
4271 edje_object_signal_callback_add
4272 (sid->edje_obj, "drag,page", "elm.dragable.hbar",
4273 _elm_scroll_edje_drag_h_cb, sid);
4274 edje_object_signal_callback_add
4275 (sid->edje_obj, "elm,hbar,press", "elm",
4276 _elm_scroll_hbar_press_cb, sid);
4277 edje_object_signal_callback_add
4278 (sid->edje_obj, "elm,hbar,unpress", "elm",
4279 _elm_scroll_hbar_unpress_cb, sid);
4283 _scroll_event_object_attach(Evas_Object *obj)
4285 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4287 evas_object_event_callback_add
4288 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL, _elm_scroll_wheel_event_cb,
4290 evas_object_event_callback_add
4291 (sid->event_rect, EVAS_CALLBACK_MOUSE_DOWN,
4292 _elm_scroll_mouse_down_event_cb, sid);
4293 evas_object_event_callback_add
4294 (sid->event_rect, EVAS_CALLBACK_MOUSE_UP,
4295 _elm_scroll_mouse_up_event_cb, sid);
4296 evas_object_event_callback_add
4297 (sid->event_rect, EVAS_CALLBACK_MOUSE_MOVE,
4298 _elm_scroll_mouse_move_event_cb, sid);
4302 _scroll_edje_object_detach(Evas_Object *obj)
4304 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4306 evas_object_event_callback_del_full
4307 (sid->edje_obj, EVAS_CALLBACK_RESIZE, _on_edje_resize, sid);
4308 evas_object_event_callback_del_full
4309 (sid->edje_obj, EVAS_CALLBACK_MOVE, _on_edje_move, sid);
4311 edje_object_signal_callback_del_full
4312 (sid->edje_obj, "drag", "elm.dragable.vbar", _elm_scroll_vbar_drag_cb,
4314 edje_object_signal_callback_del_full
4315 (sid->edje_obj, "drag,set", "elm.dragable.vbar",
4316 _elm_scroll_edje_drag_v_cb, sid);
4317 edje_object_signal_callback_del_full
4318 (sid->edje_obj, "drag,start", "elm.dragable.vbar",
4319 _elm_scroll_edje_drag_v_start_cb, sid);
4320 edje_object_signal_callback_del_full
4321 (sid->edje_obj, "drag,stop", "elm.dragable.vbar",
4322 _elm_scroll_edje_drag_v_stop_cb, sid);
4323 edje_object_signal_callback_del_full
4324 (sid->edje_obj, "drag,step", "elm.dragable.vbar",
4325 _elm_scroll_edje_drag_v_cb, sid);
4326 edje_object_signal_callback_del_full
4327 (sid->edje_obj, "drag,page", "elm.dragable.vbar",
4328 _elm_scroll_edje_drag_v_cb, sid);
4329 edje_object_signal_callback_del_full
4330 (sid->edje_obj, "elm,vbar,press", "elm",
4331 _elm_scroll_vbar_press_cb, sid);
4332 edje_object_signal_callback_del_full
4333 (sid->edje_obj, "elm,vbar,unpress", "elm",
4334 _elm_scroll_vbar_unpress_cb, sid);
4335 edje_object_signal_callback_del_full
4336 (sid->edje_obj, "drag", "elm.dragable.hbar", _elm_scroll_hbar_drag_cb,
4338 edje_object_signal_callback_del_full
4339 (sid->edje_obj, "drag,set", "elm.dragable.hbar",
4340 _elm_scroll_edje_drag_h_cb, sid);
4341 edje_object_signal_callback_del_full
4342 (sid->edje_obj, "drag,start", "elm.dragable.hbar",
4343 _elm_scroll_edje_drag_h_start_cb, sid);
4344 edje_object_signal_callback_del_full
4345 (sid->edje_obj, "drag,stop", "elm.dragable.hbar",
4346 _elm_scroll_edje_drag_h_stop_cb, sid);
4347 edje_object_signal_callback_del_full
4348 (sid->edje_obj, "drag,step", "elm.dragable.hbar",
4349 _elm_scroll_edje_drag_h_cb, sid);
4350 edje_object_signal_callback_del_full
4351 (sid->edje_obj, "drag,page", "elm.dragable.hbar",
4352 _elm_scroll_edje_drag_h_cb, sid);
4353 edje_object_signal_callback_del_full
4354 (sid->edje_obj, "elm,hbar,press", "elm",
4355 _elm_scroll_hbar_press_cb, sid);
4356 edje_object_signal_callback_del_full
4357 (sid->edje_obj, "elm,hbar,unpress", "elm",
4358 _elm_scroll_hbar_unpress_cb, sid);
4362 _scroll_event_object_detach(Evas_Object *obj)
4364 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4366 evas_object_event_callback_del_full
4367 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL, _elm_scroll_wheel_event_cb,
4369 evas_object_event_callback_del_full
4370 (sid->event_rect, EVAS_CALLBACK_MOUSE_DOWN,
4371 _elm_scroll_mouse_down_event_cb, sid);
4372 evas_object_event_callback_del_full
4373 (sid->event_rect, EVAS_CALLBACK_MOUSE_UP,
4374 _elm_scroll_mouse_up_event_cb, sid);
4375 evas_object_event_callback_del_full
4376 (sid->event_rect, EVAS_CALLBACK_MOUSE_MOVE,
4377 _elm_scroll_mouse_move_event_cb, sid);
4381 _elm_scroll_objects_set(Evas_Object *obj,
4382 Evas_Object *edje_object,
4383 Evas_Object *hit_rectangle)
4387 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4389 if (!edje_object || !hit_rectangle) return;
4392 _scroll_edje_object_detach(obj);
4394 sid->edje_obj = edje_object;
4396 if (sid->event_rect)
4397 _scroll_event_object_detach(obj);
4399 sid->event_rect = hit_rectangle;
4400 evas_object_repeat_events_set(hit_rectangle, EINA_TRUE);
4402 _scroll_edje_object_attach(obj);
4403 _scroll_event_object_attach(obj);
4406 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
4407 if (edje_object_part_exists(sid->edje_obj, "elm.scrollbar.base"))
4411 base = edje_object_part_swallow_get
4412 (sid->edje_obj, "elm.scrollbar.base");
4415 base = evas_object_rectangle_add
4416 (evas_object_evas_get(sid->edje_obj));
4417 evas_object_color_set(base, 0, 0, 0, 0);
4418 edje_object_part_swallow
4419 (sid->edje_obj, "elm.scrollbar.base", base);
4421 if (!_elm_config->thumbscroll_enable)
4422 evas_object_size_hint_min_set(base, mw, mh);
4425 _elm_scroll_scroll_bar_visibility_adjust(sid);
4429 _elm_scroll_scroll_bar_reset(Elm_Scrollable_Smart_Interface_Data *sid)
4431 Evas_Coord px = 0, py = 0, minx = 0, miny = 0;
4433 if (!sid->edje_obj) return;
4435 edje_object_part_drag_value_set
4436 (sid->edje_obj, "elm.dragable.vbar", 0.0, 0.0);
4437 edje_object_part_drag_value_set
4438 (sid->edje_obj, "elm.dragable.hbar", 0.0, 0.0);
4439 if ((!sid->content) && (!sid->extern_pan))
4441 edje_object_part_drag_size_set
4442 (sid->edje_obj, "elm.dragable.vbar", 1.0, 1.0);
4443 edje_object_part_drag_size_set
4444 (sid->edje_obj, "elm.dragable.hbar", 1.0, 1.0);
4448 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
4450 psd->api->pos_min_get(sid->pan_obj, &minx, &miny);
4451 psd->api->pos_get(sid->pan_obj, &px, &py);
4452 psd->api->pos_set(sid->pan_obj, minx, miny);
4454 if ((px != minx) || (py != miny))
4455 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
4456 _elm_direction_arrows_eval(sid);
4459 /* even external pan objects get this */
4461 _elm_scroll_pan_changed_cb(void *data,
4462 Evas_Object *obj __UNUSED__,
4463 void *event_info __UNUSED__)
4465 Evas_Coord w, h, vw, vh;
4466 Elm_Scrollable_Smart_Interface_Data *sid = data;
4468 if (!sid->pan_obj) return;
4470 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
4472 psd->api->content_size_get(sid->pan_obj, &w, &h);
4473 _elm_scroll_content_viewport_size_get(sid->obj, &vw, &vh);
4474 if ((w != sid->content_info.w) || (h != sid->content_info.h))
4476 if (_paging_is_enabled(sid))
4478 if (w != sid->content_info.w)
4480 if (sid->pagerel_h > 0)
4481 sid->pagecount_h = w / (vw * sid->pagerel_h);
4483 if (h != sid->content_info.h)
4485 if (sid->pagerel_v > 0)
4486 sid->pagecount_v = h / (vh * sid->pagerel_v);
4489 sid->content_info.w = w;
4490 sid->content_info.h = h;
4491 _elm_scroll_scroll_bar_size_adjust(sid);
4493 evas_object_size_hint_min_set
4494 (sid->edje_obj, sid->content_info.w, sid->content_info.h);
4495 sid->content_info.resized = EINA_TRUE;
4496 _elm_scroll_reconfigure(sid);
4497 _elm_scroll_wanted_region_set(sid->obj);
4502 _elm_scroll_pan_resized_cb(void *data,
4504 Evas_Object *obj __UNUSED__,
4505 void *event_info __UNUSED__)
4508 Elm_Scrollable_Smart_Interface_Data *sid = data;
4510 if (sid->cb_func.content_viewport_resize)
4512 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
4513 sid->cb_func.content_viewport_resize(sid->obj, w, h);
4518 _elm_scroll_content_del_cb(void *data,
4520 Evas_Object *obj __UNUSED__,
4521 void *event_info __UNUSED__)
4523 Elm_Scrollable_Smart_Interface_Data *sid = data;
4525 sid->content = NULL;
4526 _elm_scroll_scroll_bar_size_adjust(sid);
4527 _elm_scroll_scroll_bar_reset(sid);
4531 _elm_scroll_content_set(Evas_Object *obj,
4532 Evas_Object *content)
4537 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4539 if (!sid->edje_obj) return;
4543 /* if we had content, for sure we had a pan object */
4544 _elm_pan_content_set(sid->pan_obj, NULL);
4545 evas_object_event_callback_del_full
4546 (sid->content, EVAS_CALLBACK_DEL, _elm_scroll_content_del_cb, sid);
4549 sid->content = content;
4550 sid->wx = sid->wy = 0;
4551 /* (-1) means want viewports size */
4552 sid->ww = sid->wh = -1;
4553 if (!content) return;
4557 o = _elm_pan_add(evas_object_evas_get(obj));
4559 evas_object_smart_callback_add
4560 (o, SIG_CHANGED, _elm_scroll_pan_changed_cb, sid);
4561 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE,
4562 _elm_scroll_pan_resized_cb, sid);
4563 edje_object_part_swallow(sid->edje_obj, "elm.swallow.content", o);
4566 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
4568 evas_object_event_callback_add
4569 (content, EVAS_CALLBACK_DEL, _elm_scroll_content_del_cb, sid);
4571 _elm_pan_content_set(sid->pan_obj, content);
4572 psd->api->content_size_get(sid->pan_obj, &w, &h);
4573 sid->content_info.w = w;
4574 sid->content_info.h = h;
4576 _elm_scroll_scroll_bar_size_adjust(sid);
4577 _elm_scroll_scroll_bar_reset(sid);
4581 _elm_scroll_extern_pan_set(Evas_Object *obj,
4584 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4586 if (!sid->edje_obj) return;
4588 _elm_scroll_content_set(obj, NULL);
4592 evas_object_smart_callback_del
4593 (sid->pan_obj, SIG_CHANGED, _elm_scroll_pan_changed_cb);
4594 evas_object_event_callback_del(sid->pan_obj, EVAS_CALLBACK_RESIZE,
4595 _elm_scroll_pan_resized_cb);
4598 if (sid->extern_pan)
4602 /* not owned by scroller, just leave (was external already) */
4603 edje_object_part_unswallow(sid->edje_obj, sid->pan_obj);
4604 sid->pan_obj = NULL;
4611 evas_object_del(sid->pan_obj);
4612 sid->pan_obj = NULL;
4617 sid->extern_pan = EINA_FALSE;
4623 sid->extern_pan = EINA_TRUE;
4624 evas_object_smart_callback_add
4625 (sid->pan_obj, SIG_CHANGED, _elm_scroll_pan_changed_cb, sid);
4626 evas_object_event_callback_add(sid->pan_obj, EVAS_CALLBACK_RESIZE,
4627 _elm_scroll_pan_resized_cb, sid);
4628 edje_object_part_swallow
4629 (sid->edje_obj, "elm.swallow.content", sid->pan_obj);
4633 _elm_scroll_drag_start_cb_set(Evas_Object *obj,
4634 void (*drag_start_cb)(Evas_Object *obj,
4637 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4639 sid->cb_func.drag_start = drag_start_cb;
4643 _elm_scroll_drag_stop_cb_set(Evas_Object *obj,
4644 void (*drag_stop_cb)(Evas_Object *obj,
4647 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4649 sid->cb_func.drag_stop = drag_stop_cb;
4653 _elm_scroll_animate_start_cb_set(Evas_Object *obj,
4654 void (*animate_start_cb)(Evas_Object *obj,
4657 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4659 sid->cb_func.animate_start = animate_start_cb;
4663 _elm_scroll_animate_stop_cb_set(Evas_Object *obj,
4664 void (*animate_stop_cb)(Evas_Object *obj,
4667 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4669 sid->cb_func.animate_stop = animate_stop_cb;
4673 _elm_scroll_scroll_cb_set(Evas_Object *obj,
4674 void (*scroll_cb)(Evas_Object *obj,
4677 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4679 sid->cb_func.scroll = scroll_cb;
4683 _elm_scroll_scroll_left_cb_set(Evas_Object *obj,
4684 void (*scroll_left_cb)(Evas_Object *obj,
4687 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4689 sid->cb_func.scroll_left = scroll_left_cb;
4693 _elm_scroll_scroll_right_cb_set(Evas_Object *obj,
4694 void (*scroll_right_cb)(Evas_Object *obj,
4697 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4699 sid->cb_func.scroll_right = scroll_right_cb;
4703 _elm_scroll_scroll_up_cb_set(Evas_Object *obj,
4704 void (*scroll_up_cb)(Evas_Object *obj,
4707 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4709 sid->cb_func.scroll_up = scroll_up_cb;
4713 _elm_scroll_scroll_down_cb_set(Evas_Object *obj,
4714 void (*scroll_down_cb)(Evas_Object *obj,
4717 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4719 sid->cb_func.scroll_down = scroll_down_cb;
4723 _elm_scroll_edge_left_cb_set(Evas_Object *obj,
4724 void (*edge_left_cb)(Evas_Object *obj,
4727 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4729 sid->cb_func.edge_left = edge_left_cb;
4733 _elm_scroll_edge_right_cb_set(Evas_Object *obj,
4734 void (*edge_right_cb)(Evas_Object *obj,
4737 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4739 sid->cb_func.edge_right = edge_right_cb;
4743 _elm_scroll_edge_top_cb_set(Evas_Object *obj,
4744 void (*edge_top_cb)(Evas_Object *obj,
4747 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4749 sid->cb_func.edge_top = edge_top_cb;
4753 _elm_scroll_edge_bottom_cb_set(Evas_Object *obj,
4754 void (*edge_bottom_cb)(Evas_Object *obj,
4757 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4759 sid->cb_func.edge_bottom = edge_bottom_cb;
4763 _elm_scroll_vbar_drag_cb_set(Evas_Object *obj,
4764 void (*vbar_drag_cb)(Evas_Object *obj,
4767 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4769 sid->cb_func.vbar_drag = vbar_drag_cb;
4773 _elm_scroll_vbar_press_cb_set(Evas_Object *obj,
4774 void (*vbar_press_cb)(Evas_Object *obj,
4777 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4779 sid->cb_func.vbar_press = vbar_press_cb;
4783 _elm_scroll_vbar_unpress_cb_set(Evas_Object *obj,
4784 void (*vbar_unpress_cb)(Evas_Object *obj,
4787 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4789 sid->cb_func.vbar_unpress = vbar_unpress_cb;
4793 _elm_scroll_hbar_drag_cb_set(Evas_Object *obj,
4794 void (*hbar_drag_cb)(Evas_Object *obj,
4797 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4799 sid->cb_func.hbar_drag = hbar_drag_cb;
4803 _elm_scroll_hbar_press_cb_set(Evas_Object *obj,
4804 void (*hbar_press_cb)(Evas_Object *obj,
4807 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4809 sid->cb_func.hbar_press = hbar_press_cb;
4813 _elm_scroll_hbar_unpress_cb_set(Evas_Object *obj,
4814 void (*hbar_unpress_cb)(Evas_Object *obj,
4817 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4819 sid->cb_func.hbar_unpress = hbar_unpress_cb;
4823 _elm_scroll_content_min_limit_cb_set(Evas_Object *obj,
4824 void (*c_min_limit_cb)(Evas_Object *obj,
4828 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4830 sid->cb_func.content_min_limit = c_min_limit_cb;
4834 _elm_scroll_content_viewport_resize_cb_set(Evas_Object *obj,
4835 void (*c_viewport_resize_cb)(Evas_Object *obj,
4839 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4841 sid->cb_func.content_viewport_resize = c_viewport_resize_cb;
4845 _elm_scroll_momentum_animator_disabled_get(const Evas_Object *obj)
4847 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
4849 return sid->momentum_animator_disabled;
4853 _elm_scroll_momentum_animator_disabled_set(Evas_Object *obj,
4856 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4858 sid->momentum_animator_disabled = disabled;
4859 if (sid->momentum_animator_disabled)
4861 if (sid->down.momentum_animator)
4863 ecore_animator_del(sid->down.momentum_animator);
4864 sid->down.momentum_animator = NULL;
4865 if (sid->content_info.resized)
4866 _elm_scroll_wanted_region_set(sid->obj);
4872 _elm_scroll_bounce_animator_disabled_get(const Evas_Object *obj)
4874 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
4876 return sid->bounce_animator_disabled;
4880 _elm_scroll_bounce_animator_disabled_set(Evas_Object *obj,
4883 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4885 sid->bounce_animator_disabled = disabled;
4886 if (sid->bounce_animator_disabled)
4888 if (sid->scrollto.x.animator)
4890 ecore_animator_del(sid->scrollto.x.animator);
4891 sid->scrollto.x.animator = NULL;
4894 if (sid->scrollto.y.animator)
4896 ecore_animator_del(sid->scrollto.y.animator);
4897 sid->scrollto.y.animator = NULL;
4903 _elm_scroll_wheel_disabled_get(const Evas_Object *obj)
4905 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
4907 return sid->wheel_disabled;
4911 _elm_scroll_wheel_disabled_set(Evas_Object *obj,
4914 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4916 if (!sid->event_rect) return;
4918 if ((!sid->wheel_disabled) && (disabled))
4919 evas_object_event_callback_del_full
4920 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL,
4921 _elm_scroll_wheel_event_cb, sid);
4922 else if ((sid->wheel_disabled) && (!disabled))
4923 evas_object_event_callback_add
4924 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL,
4925 _elm_scroll_wheel_event_cb, sid);
4926 sid->wheel_disabled = disabled;
4930 _elm_scroll_movement_block_set(Evas_Object *obj,
4931 Elm_Scroller_Movement_Block block)
4933 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4938 static Elm_Scroller_Movement_Block
4939 _elm_scroll_movement_block_get(const Evas_Object *obj)
4941 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, ELM_SCROLLER_MOVEMENT_NO_BLOCK);
4947 _elm_scroll_step_size_set(Evas_Object *obj,
4951 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4958 _elm_scroll_scroll_bar_size_adjust(sid);
4962 _elm_scroll_step_size_get(const Evas_Object *obj,
4966 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4968 if (x) *x = sid->step.x;
4969 if (y) *y = sid->step.y;
4973 _elm_scroll_page_size_set(Evas_Object *obj,
4977 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4982 _elm_scroll_scroll_bar_size_adjust(sid);
4986 _elm_scroll_page_size_get(const Evas_Object *obj,
4990 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4992 if (x) *x = sid->page.x;
4993 if (y) *y = sid->page.y;
4997 _elm_scroll_policy_set(Evas_Object *obj,
4998 Elm_Scroller_Policy hbar,
4999 Elm_Scroller_Policy vbar)
5001 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
5003 if (!sid->edje_obj) return;
5005 if ((sid->hbar_flags == hbar) && (sid->vbar_flags == vbar)) return;
5007 sid->hbar_flags = hbar;
5008 sid->vbar_flags = vbar;
5009 _elm_scroll_policy_signal_emit(sid);
5010 if (sid->cb_func.content_min_limit)
5011 sid->cb_func.content_min_limit(sid->obj, sid->min_w, sid->min_h);
5012 _elm_direction_arrows_eval(sid);
5016 _elm_scroll_policy_get(const Evas_Object *obj,
5017 Elm_Scroller_Policy *hbar,
5018 Elm_Scroller_Policy *vbar)
5020 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
5022 if (hbar) *hbar = sid->hbar_flags;
5023 if (vbar) *vbar = sid->vbar_flags;
5027 _elm_scroll_single_direction_set(Evas_Object *obj,
5028 Elm_Scroller_Single_Direction single_dir)
5030 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
5032 sid->one_direction_at_a_time = single_dir;
5035 static Elm_Scroller_Single_Direction
5036 _elm_scroll_single_direction_get(const Evas_Object *obj)
5038 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, ELM_SCROLLER_SINGLE_DIRECTION_SOFT);
5040 return sid->one_direction_at_a_time;
5044 _elm_scroll_repeat_events_set(Evas_Object *obj,
5045 Eina_Bool repeat_events)
5047 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
5049 evas_object_repeat_events_set(sid->event_rect, repeat_events);
5053 _elm_scroll_repeat_events_get(const Evas_Object *obj)
5055 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
5057 return evas_object_repeat_events_get(sid->event_rect);
5061 _elm_scroll_hold_set(Evas_Object *obj,
5064 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
5070 _elm_scroll_freeze_set(Evas_Object *obj,
5073 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
5075 sid->freeze = freeze;
5078 if (sid->down.onhold_animator)
5080 ecore_animator_del(sid->down.onhold_animator);
5081 sid->down.onhold_animator = NULL;
5082 if (sid->content_info.resized)
5083 _elm_scroll_wanted_region_set(sid->obj);
5087 _elm_scroll_bounce_eval(sid);
5091 _elm_scroll_bounce_allow_set(Evas_Object *obj,
5095 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
5097 sid->bounce_horiz = !!horiz;
5098 sid->bounce_vert = !!vert;
5102 _elm_scroll_bounce_allow_get(const Evas_Object *obj,
5106 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
5108 if (horiz) *horiz = sid->bounce_horiz;
5109 if (vert) *vert = sid->bounce_vert;
5113 _elm_scroll_paging_set(Evas_Object *obj,
5116 Evas_Coord pagesize_h,
5117 Evas_Coord pagesize_v)
5119 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
5121 sid->pagerel_h = pagerel_h;
5122 sid->pagerel_v = pagerel_v;
5123 sid->pagesize_h = pagesize_h;
5124 sid->pagesize_v = pagesize_v;
5128 _elm_scroll_paging_get(const Evas_Object *obj,
5131 Evas_Coord *pagesize_h,
5132 Evas_Coord *pagesize_v)
5134 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
5136 if (pagerel_h) *pagerel_h = sid->pagerel_h;
5137 if (pagerel_v) *pagerel_v = sid->pagerel_v;
5138 if (pagesize_h) *pagesize_h = sid->pagesize_h;
5139 if (pagesize_v) *pagesize_v = sid->pagesize_v;
5143 _elm_scroll_page_scroll_limit_set(const Evas_Object *obj,
5147 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
5149 sid->page_limit_h = page_limit_h;
5150 sid->page_limit_v = page_limit_v;
5154 _elm_scroll_page_scroll_limit_get(const Evas_Object *obj,
5158 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
5160 if (page_limit_h) *page_limit_h = sid->page_limit_h;
5161 if (page_limit_v) *page_limit_v = sid->page_limit_v;
5165 _elm_scroll_current_page_get(const Evas_Object *obj,
5171 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
5173 _elm_scroll_content_pos_get(sid->obj, &x, &y);
5176 if (sid->pagesize_h > 0)
5178 double result = (double)x / (double)sid->pagesize_h;
5179 double rest = result - (x / sid->pagesize_h);
5181 *pagenumber_h = result + 1;
5183 *pagenumber_h = result;
5190 if (sid->pagesize_v > 0)
5192 double result = (double)y / (double)sid->pagesize_v;
5193 double rest = result - (y / sid->pagesize_v);
5195 *pagenumber_v = result + 1;
5197 *pagenumber_v = result;
5205 _elm_scroll_last_page_get(const Evas_Object *obj,
5211 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
5213 if (!sid->pan_obj) return;
5215 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
5217 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
5220 if (sid->pagesize_h > 0)
5221 *pagenumber_h = cw / sid->pagesize_h - 1;
5227 if (sid->pagesize_v > 0)
5228 *pagenumber_v = ch / sid->pagesize_v - 1;
5235 _elm_scroll_page_show(Evas_Object *obj,
5239 Evas_Coord w, h, cw = 0, ch = 0;
5243 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
5246 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
5247 psd->api->content_size_get(sid->pan_obj, &cw, &ch);
5250 sid->current_page.x = _elm_scroll_page_x_get(sid, 0, EINA_FALSE);
5251 sid->current_page.y = _elm_scroll_page_y_get(sid, 0, EINA_FALSE);
5253 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
5254 if (pagenumber_h >= 0) x = sid->pagesize_h * pagenumber_h;
5255 if (pagenumber_v >= 0) y = sid->pagesize_v * pagenumber_v;
5257 if (sid->origin_x && cw > 0)
5260 if (sid->wx < 0) sid->wx = 0;
5265 if (sid->origin_y && ch > 0)
5268 if (sid->wy < 0) sid->wy = 0;
5275 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
5276 _elm_scroll_content_pos_set(obj, x, y, EINA_TRUE);
5280 _elm_scroll_page_bring_in(Evas_Object *obj,
5288 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
5290 sid->current_page.x = _elm_scroll_page_x_get(sid, 0, EINA_FALSE);
5291 sid->current_page.y = _elm_scroll_page_y_get(sid, 0, EINA_FALSE);
5293 _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
5294 if (pagenumber_h >= 0) x = sid->pagesize_h * pagenumber_h;
5295 if (pagenumber_v >= 0) y = sid->pagesize_v * pagenumber_v;
5296 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
5298 _elm_scroll_scroll_to_x(sid, _elm_config->bring_in_scroll_friction, x);
5299 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, y);
5304 _elm_scroll_region_bring_in(Evas_Object *obj,
5310 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
5312 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
5314 _elm_scroll_scroll_to_x(sid, _elm_config->bring_in_scroll_friction, x);
5315 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, y);
5320 _elm_scroll_gravity_set(Evas_Object *obj,
5324 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
5326 if (!sid->pan_obj) return;
5328 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
5330 psd->api->gravity_set(sid->pan_obj, x, y);
5334 _elm_scroll_gravity_get(const Evas_Object *obj,
5338 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
5340 if (!sid->pan_obj) return;
5342 ELM_PAN_DATA_GET_OR_RETURN(sid->pan_obj, psd);
5344 psd->api->gravity_get(sid->pan_obj, x, y);
5349 _elm_scroll_loop_set(Evas_Object *obj,
5353 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
5355 if (sid->loop_h == loop_h &&
5356 sid->loop_v == loop_v)
5359 sid->loop_h = loop_h;
5360 sid->loop_v = loop_v;
5364 _elm_scroll_loop_get(const Evas_Object *obj,
5368 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
5370 *loop_h = sid->loop_h;
5371 *loop_v = sid->loop_v;
5376 _elm_scroll_interface_add(Evas_Object *obj)
5378 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
5380 memset(sid, 0, sizeof(*sid));
5392 sid->page_limit_h = 9999;
5393 sid->page_limit_v = 9999;
5394 sid->hbar_flags = ELM_SCROLLER_POLICY_AUTO;
5395 sid->vbar_flags = ELM_SCROLLER_POLICY_AUTO;
5396 sid->hbar_visible = EINA_TRUE;
5397 sid->vbar_visible = EINA_TRUE;
5398 sid->loop_h = EINA_FALSE;
5399 sid->loop_v = EINA_FALSE;
5400 sid->origin_x = EINA_FALSE;
5401 sid->origin_y = EINA_FALSE;
5403 sid->bounce_horiz = EINA_TRUE;
5404 sid->bounce_vert = EINA_TRUE;
5406 sid->one_direction_at_a_time = ELM_SCROLLER_SINGLE_DIRECTION_SOFT;
5407 sid->momentum_animator_disabled = EINA_FALSE;
5408 sid->bounce_animator_disabled = EINA_FALSE;
5409 sid->block = ELM_SCROLLER_MOVEMENT_NO_BLOCK;
5411 _elm_scroll_scroll_bar_reset(sid);
5417 _elm_scroll_interface_del(Evas_Object *obj)
5419 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
5421 _elm_scroll_content_set(obj, NULL);
5422 if (!sid->extern_pan) evas_object_del(sid->pan_obj);
5424 if (sid->down.hold_animator)
5425 ecore_animator_del(sid->down.hold_animator);
5426 if (sid->down.onhold_animator)
5427 ecore_animator_del(sid->down.onhold_animator);
5428 if (sid->down.momentum_animator)
5429 ecore_animator_del(sid->down.momentum_animator);
5430 if (sid->down.bounce_x_animator)
5431 ecore_animator_del(sid->down.bounce_x_animator);
5432 if (sid->down.bounce_y_animator)
5433 ecore_animator_del(sid->down.bounce_y_animator);
5434 if (sid->scrollto.x.animator) ecore_animator_del(sid->scrollto.x.animator);
5435 if (sid->scrollto.y.animator) ecore_animator_del(sid->scrollto.y.animator);
5438 EAPI const char ELM_SCROLLABLE_IFACE_NAME[] = "elm_interface_scrollable";
5440 EAPI const Elm_Scrollable_Smart_Interface ELM_SCROLLABLE_IFACE =
5443 ELM_SCROLLABLE_IFACE_NAME,
5444 sizeof(Elm_Scrollable_Smart_Interface_Data),
5445 _elm_scroll_interface_add,
5446 _elm_scroll_interface_del
5449 _elm_scroll_objects_set,
5450 _elm_scroll_content_set,
5451 _elm_scroll_extern_pan_set,
5452 _elm_scroll_drag_start_cb_set,
5453 _elm_scroll_drag_stop_cb_set,
5454 _elm_scroll_animate_start_cb_set,
5455 _elm_scroll_animate_stop_cb_set,
5456 _elm_scroll_scroll_cb_set,
5457 _elm_scroll_scroll_left_cb_set,
5458 _elm_scroll_scroll_right_cb_set,
5459 _elm_scroll_scroll_up_cb_set,
5460 _elm_scroll_scroll_down_cb_set,
5461 _elm_scroll_edge_left_cb_set,
5462 _elm_scroll_edge_right_cb_set,
5463 _elm_scroll_edge_top_cb_set,
5464 _elm_scroll_edge_bottom_cb_set,
5465 _elm_scroll_vbar_drag_cb_set,
5466 _elm_scroll_vbar_press_cb_set,
5467 _elm_scroll_vbar_unpress_cb_set,
5468 _elm_scroll_hbar_drag_cb_set,
5469 _elm_scroll_hbar_press_cb_set,
5470 _elm_scroll_hbar_unpress_cb_set,
5471 _elm_scroll_content_min_limit_cb_set,
5472 _elm_scroll_content_viewport_resize_cb_set,
5473 _elm_scroll_content_pos_set,
5474 _elm_scroll_content_pos_get,
5475 _elm_scroll_content_region_show,
5476 _elm_scroll_content_region_set,
5477 _elm_scroll_content_size_get,
5478 _elm_scroll_content_viewport_size_get,
5479 _elm_scroll_content_viewport_pos_get,
5480 _elm_scroll_content_min_limit,
5481 _elm_scroll_step_size_set,
5482 _elm_scroll_step_size_get,
5483 _elm_scroll_page_size_set,
5484 _elm_scroll_page_size_get,
5485 _elm_scroll_policy_set,
5486 _elm_scroll_policy_get,
5487 _elm_scroll_single_direction_set,
5488 _elm_scroll_single_direction_get,
5489 _elm_scroll_repeat_events_set,
5490 _elm_scroll_repeat_events_get,
5491 _elm_scroll_mirrored_set,
5492 _elm_scroll_hold_set,
5493 _elm_scroll_freeze_set,
5494 _elm_scroll_bounce_allow_set,
5495 _elm_scroll_bounce_allow_get,
5496 _elm_scroll_origin_reverse_set,
5497 _elm_scroll_origin_reverse_get,
5498 _elm_scroll_paging_set,
5499 _elm_scroll_paging_get,
5500 _elm_scroll_page_scroll_limit_set,
5501 _elm_scroll_page_scroll_limit_get,
5502 _elm_scroll_current_page_get,
5503 _elm_scroll_last_page_get,
5504 _elm_scroll_page_show,
5505 _elm_scroll_page_bring_in,
5506 _elm_scroll_region_bring_in,
5507 _elm_scroll_gravity_set,
5508 _elm_scroll_gravity_get,
5509 _elm_scroll_loop_set,
5510 _elm_scroll_loop_get,
5511 _elm_scroll_momentum_animator_disabled_get,
5512 _elm_scroll_momentum_animator_disabled_set,
5513 _elm_scroll_bounce_animator_disabled_set,
5514 _elm_scroll_bounce_animator_disabled_get,
5515 _elm_scroll_wheel_disabled_get,
5516 _elm_scroll_wheel_disabled_set,
5517 _elm_scroll_movement_block_set,
5518 _elm_scroll_movement_block_get