2 # include "elementary_config.h"
5 #include <Elementary.h>
8 #include "elm_interface_scrollable.h"
10 #define MY_PAN_CLASS ELM_PAN_CLASS
12 #define MY_PAN_CLASS_NAME "Elm_Pan"
13 #define MY_PAN_CLASS_NAME_LEGACY "elm_pan"
15 #define ELM_PAN_DATA_GET_OR_RETURN(o, ptr) \
16 Elm_Pan_Smart_Data *ptr = eo_data_scope_get(o, MY_PAN_CLASS); \
19 CRI("No smart data for object %p (%s)", \
20 o, evas_object_type_get(o)); \
24 #define ELM_PAN_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
25 Elm_Pan_Smart_Data *ptr = eo_data_scope_get(o, MY_PAN_CLASS); \
28 CRI("No smart data for object %p (%s)", \
29 o, evas_object_type_get(o)); \
33 static const char SIG_CHANGED[] = "changed";
34 //TIZEN_ONLY(20170718): Add content,resize callback to keep backward compat
35 static const char SIG_CONTENT_RESIZE[] = "content,resize";
37 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
39 //TIZEN_ONLY(20170718): Add content,resize callback to keep backward compat
40 {SIG_CONTENT_RESIZE, ""},
45 static void _elm_pan_content_set(Evas_Object *, Evas_Object *);
47 _elm_scroll_scroll_to_x(Elm_Scrollable_Smart_Interface_Data *sid,
51 _elm_scroll_scroll_to_y(Elm_Scrollable_Smart_Interface_Data *sid,
55 _elm_scroll_wanted_coordinates_update(Elm_Scrollable_Smart_Interface_Data *sid,
59 _round(double value, int pos)
63 temp = value * pow( 10, pos );
64 temp = floor( temp + 0.5 );
65 temp *= pow( 10, -pos );
71 _elm_pan_update(Elm_Pan_Smart_Data *psd)
73 evas_object_move(psd->content, psd->x - psd->px, psd->y - psd->py);
77 _elm_pan_evas_object_smart_add(Eo *obj, Elm_Pan_Smart_Data *priv)
79 eo_do_super(obj, MY_PAN_CLASS, evas_obj_smart_add());
85 _elm_pan_evas_object_smart_del(Eo *obj, Elm_Pan_Smart_Data *_pd EINA_UNUSED)
87 _elm_pan_content_set(obj, NULL);
89 eo_do_super(obj, MY_PAN_CLASS, evas_obj_smart_del());
93 _elm_pan_evas_object_smart_move(Eo *obj EINA_UNUSED, Elm_Pan_Smart_Data *psd, Evas_Coord x, Evas_Coord y)
102 _elm_pan_evas_object_smart_resize(Eo *obj EINA_UNUSED, Elm_Pan_Smart_Data *psd, Evas_Coord w, Evas_Coord h)
107 _elm_pan_update(psd);
108 eo_do(psd->self, eo_event_callback_call(ELM_PAN_EVENT_CHANGED, NULL));
112 _elm_pan_evas_object_smart_show(Eo *obj, Elm_Pan_Smart_Data *psd)
114 eo_do_super(obj, MY_PAN_CLASS, evas_obj_smart_show());
117 evas_object_show(psd->content);
121 _elm_pan_evas_object_smart_hide(Eo *obj, Elm_Pan_Smart_Data *psd)
123 eo_do_super(obj, MY_PAN_CLASS, evas_obj_smart_hide());
126 evas_object_hide(psd->content);
130 _elm_pan_pos_set(Eo *obj EINA_UNUSED, Elm_Pan_Smart_Data *psd, Evas_Coord x, Evas_Coord y)
132 if ((x == psd->px) && (y == psd->py)) return;
136 _elm_pan_update(psd);
137 eo_do(psd->self, eo_event_callback_call(ELM_PAN_EVENT_CHANGED, NULL));
141 _elm_pan_pos_get(Eo *obj EINA_UNUSED, Elm_Pan_Smart_Data *psd, Evas_Coord *x, Evas_Coord *y)
148 _elm_pan_pos_max_get(Eo *obj EINA_UNUSED, Elm_Pan_Smart_Data *psd, Evas_Coord *x, Evas_Coord *y)
152 if (psd->w < psd->content_w) *x = psd->content_w - psd->w;
157 if (psd->h < psd->content_h) *y = psd->content_h - psd->h;
163 _elm_pan_pos_min_get(Eo *obj EINA_UNUSED, Elm_Pan_Smart_Data *_pd EINA_UNUSED, Evas_Coord *x, Evas_Coord *y)
171 // TIZEN_ONLY(20150705): Genlist item align feature
173 _elm_pan_pos_adjust(Eo *obj EINA_UNUSED, Elm_Pan_Smart_Data *psd EINA_UNUSED, Evas_Coord *x EINA_UNUSED, Evas_Coord *y EINA_UNUSED)
180 _elm_pan_content_size_get(Eo *obj EINA_UNUSED, Elm_Pan_Smart_Data *psd, Evas_Coord *w, Evas_Coord *h)
182 if (w) *w = psd->content_w;
183 if (h) *h = psd->content_h;
187 _elm_pan_add(Evas *evas)
189 Evas_Object *obj = eo_add(MY_PAN_CLASS, evas);
194 _elm_pan_eo_base_constructor(Eo *obj, Elm_Pan_Smart_Data *_pd EINA_UNUSED)
196 obj = eo_do_super_ret(obj, MY_PAN_CLASS, obj, eo_constructor());
198 evas_obj_type_set(MY_PAN_CLASS_NAME_LEGACY),
199 evas_obj_smart_callbacks_descriptions_set(_smart_callbacks));
205 _elm_pan_content_del_cb(void *data,
207 Evas_Object *obj EINA_UNUSED,
208 void *event_info EINA_UNUSED)
210 Elm_Pan_Smart_Data *psd;
214 psd->content_w = psd->content_h = psd->px = psd->py = 0;
215 eo_do(psd->self, eo_event_callback_call(ELM_PAN_EVENT_CHANGED, NULL));
219 _elm_pan_content_resize_cb(void *data,
221 Evas_Object *obj EINA_UNUSED,
222 void *event_info EINA_UNUSED)
224 Elm_Pan_Smart_Data *psd;
228 evas_object_geometry_get(psd->content, NULL, NULL, &w, &h);
229 if ((w != psd->content_w) || (h != psd->content_h))
233 _elm_pan_update(psd);
235 eo_do(psd->self, eo_event_callback_call(ELM_PAN_EVENT_CHANGED, NULL));
239 _elm_pan_content_set(Evas_Object *obj,
240 Evas_Object *content)
244 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
246 if (content == psd->content) return;
249 evas_object_smart_member_del(psd->content);
250 evas_object_event_callback_del_full
251 (psd->content, EVAS_CALLBACK_DEL, _elm_pan_content_del_cb, psd);
252 evas_object_event_callback_del_full
253 (psd->content, EVAS_CALLBACK_RESIZE, _elm_pan_content_resize_cb,
257 if (!content) goto end;
259 psd->content = content;
260 evas_object_smart_member_add(psd->content, psd->self);
261 evas_object_geometry_get(psd->content, NULL, NULL, &w, &h);
264 evas_object_event_callback_add
265 (content, EVAS_CALLBACK_DEL, _elm_pan_content_del_cb, psd);
266 evas_object_event_callback_add
267 (content, EVAS_CALLBACK_RESIZE, _elm_pan_content_resize_cb, psd);
269 if (evas_object_visible_get(psd->self))
270 evas_object_show(psd->content);
272 evas_object_hide(psd->content);
274 _elm_pan_update(psd);
277 eo_do(psd->self, eo_event_callback_call(ELM_PAN_EVENT_CHANGED, NULL));
281 _elm_pan_class_constructor(Eo_Class *klass)
283 evas_smart_legacy_type_register(MY_PAN_CLASS_NAME_LEGACY, klass);
286 /* pan smart object on top, scroller interface on bottom */
287 /* ============================================================ */
289 #define MY_SCROLLABLE_INTERFACE ELM_INTERFACE_SCROLLABLE_MIXIN
291 #define MY_SCROLLABLE_INTERFACE_NAME "Elm_Interface_Scrollable"
292 #define MY_SCROLLABLE_INTERFACE_NAME_LEGACY "elm_interface_scrollable"
294 #define ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(o, ptr) \
295 Elm_Scrollable_Smart_Interface_Data *ptr = \
296 (!eo_isa(o, MY_SCROLLABLE_INTERFACE) ? NULL : \
297 eo_data_scope_get(o, MY_SCROLLABLE_INTERFACE)); \
300 CRI("No interface data for object %p (%s)", \
301 o, evas_object_type_get(o)); \
305 #define ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
306 Elm_Scrollable_Smart_Interface_Data *ptr = \
307 (!eo_isa(o, MY_SCROLLABLE_INTERFACE) ? NULL : \
308 eo_data_scope_get(o, MY_SCROLLABLE_INTERFACE)); \
311 CRI("No interface data for object %p (%s)", \
312 o, evas_object_type_get(o)); \
316 static void _elm_scroll_scroll_bar_size_adjust(
317 Elm_Scrollable_Smart_Interface_Data *);
318 //TIZEN_ONLY(20151012): Separate logic which calculate for bar size and logic which calculate for bar position.
319 static void _elm_scroll_scroll_bar_pos_adjust(
320 Elm_Scrollable_Smart_Interface_Data *);
322 static Eina_Bool _paging_is_enabled(Elm_Scrollable_Smart_Interface_Data *sid);
323 static Evas_Coord _elm_scroll_page_x_get(
324 Elm_Scrollable_Smart_Interface_Data *sid, int offset, Eina_Bool limit);
325 static Evas_Coord _elm_scroll_page_y_get(
326 Elm_Scrollable_Smart_Interface_Data *sid, int offset, Eina_Bool limit);
333 //#define SCROLLDBG 1
334 /* smoothness debug calls - for debugging how much smooth your app is */
338 #define SMOOTH_DEBUG_COUNT 100
341 typedef struct _smooth_debug_info smooth_debug_info;
342 struct _smooth_debug_info
351 static smooth_debug_info smooth_x_history[SMOOTH_DEBUG_COUNT];
352 static smooth_debug_info smooth_y_history[SMOOTH_DEBUG_COUNT];
353 static int smooth_info_x_count = 0;
354 static int smooth_info_y_count = 0;
355 static double start_time = 0;
356 static int _elm_scroll_smooth_debug = 0;
359 _elm_scroll_smooth_debug_init(void)
361 start_time = ecore_time_get();
362 smooth_info_x_count = 0;
363 smooth_info_y_count = 0;
365 memset(&(smooth_x_history[0]), 0,
366 sizeof(smooth_x_history[0]) * SMOOTH_DEBUG_COUNT);
367 memset(&(smooth_y_history[0]), 0,
368 sizeof(smooth_y_history[0]) * SMOOTH_DEBUG_COUNT);
374 _elm_scroll_smooth_debug_shutdown(void)
377 int info_x_count = 0;
378 int info_y_count = 0;
379 double x_ave = 0, y_ave = 0;
380 double x_sum = 0, y_sum = 0;
381 double x_dev = 0, y_dev = 0;
382 double x_dev_sum = 0, y_dev_sum = 0;
384 if (smooth_info_x_count >= SMOOTH_DEBUG_COUNT)
385 info_x_count = SMOOTH_DEBUG_COUNT;
387 info_x_count = smooth_info_x_count;
389 if (smooth_info_y_count >= SMOOTH_DEBUG_COUNT)
390 info_y_count = SMOOTH_DEBUG_COUNT;
392 info_y_count = smooth_info_y_count;
394 DBG("\n\n<<< X-axis Smoothness >>>\n");
395 DBG("| Num | t(time) | dt | x | dx |vx(dx/1fps) |\n");
397 for (i = info_x_count - 1; i >= 0; i--)
399 DBG("| %4d | %1.6f | %1.6f | %4d | %4d | %9.3f |\n", info_x_count - i,
400 smooth_x_history[i].t,
401 smooth_x_history[i].dt,
402 smooth_x_history[i].pos,
403 smooth_x_history[i].dpos,
404 smooth_x_history[i].vpos);
405 if (i == info_x_count - 1) continue;
406 x_sum += smooth_x_history[i].vpos;
409 x_ave = x_sum / (info_x_count - 1);
410 for (i = 0; i < info_x_count - 1; i++)
412 x_dev_sum += (smooth_x_history[i].vpos - x_ave) *
413 (smooth_x_history[i].vpos - x_ave);
415 x_dev = x_dev_sum / (info_x_count - 1);
416 DBG(" Standard deviation of X-axis velocity: %9.3f\n", sqrt(x_dev));
418 DBG("\n\n<<< Y-axis Smoothness >>>\n");
419 DBG("| Num | t(time) | dt | y | dy |vy(dy/1fps) |\n");
420 for (i = info_y_count - 1; i >= 0; i--)
422 DBG("| %4d | %1.6f | %1.6f | %4d | %4d | %9.3f |\n", info_y_count - i,
423 smooth_y_history[i].t,
424 smooth_y_history[i].dt,
425 smooth_y_history[i].pos,
426 smooth_y_history[i].dpos,
427 smooth_y_history[i].vpos);
428 if (i == info_y_count - 1) continue;
429 y_sum += smooth_y_history[i].vpos;
431 y_ave = y_sum / (info_y_count - 1);
432 for (i = 0; i < info_y_count - 1; i++)
434 y_dev_sum += (smooth_y_history[i].vpos - y_ave) *
435 (smooth_y_history[i].vpos - y_ave);
437 y_dev = y_dev_sum / (info_y_count - 1);
439 DBG(" Standard deviation of Y-axis velocity: %9.3f\n", sqrt(y_dev));
443 _elm_direction_arrows_eval(Elm_Scrollable_Smart_Interface_Data *sid)
445 Eina_Bool go_left = EINA_TRUE, go_right = EINA_TRUE;
446 Eina_Bool go_up = EINA_TRUE, go_down = EINA_TRUE;
447 Evas_Coord x = 0, y = 0, mx = 0, my = 0, minx = 0, miny = 0;
449 if (!sid->edje_obj || !sid->pan_obj) return;
451 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
452 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
453 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&x, &y));
455 if (x == minx) go_left = EINA_FALSE;
456 if (x == (mx + minx)) go_right = EINA_FALSE;
457 if (y == miny) go_up = EINA_FALSE;
458 if (y == (my + miny)) go_down = EINA_FALSE;
459 if (go_left != sid->go_left)
462 edje_object_signal_emit(sid->edje_obj, "elm,action,show,left", "elm");
464 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,left", "elm");
465 sid->go_left = go_left;
467 if (go_right != sid->go_right)
470 edje_object_signal_emit(sid->edje_obj, "elm,action,show,right", "elm");
472 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,right", "elm");
473 sid->go_right= go_right;
475 if (go_up != sid->go_up)
478 edje_object_signal_emit(sid->edje_obj, "elm,action,show,up", "elm");
480 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,up", "elm");
483 if (go_down != sid->go_down)
486 edje_object_signal_emit(sid->edje_obj, "elm,action,show,down", "elm");
488 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,down", "elm");
489 sid->go_down= go_down;
494 _elm_scroll_smooth_debug_movetime_add(int x,
501 tim = ecore_time_get();
505 smooth_info_x_count++;
506 memmove(&(smooth_x_history[1]), &(smooth_x_history[0]),
507 sizeof(smooth_x_history[0]) * (SMOOTH_DEBUG_COUNT - 1));
508 smooth_x_history[0].t = tim - start_time;
509 smooth_x_history[0].dt = smooth_x_history[0].t - smooth_x_history[1].t;
510 smooth_x_history[0].pos = x;
511 smooth_x_history[0].dpos =
512 smooth_x_history[0].pos - smooth_x_history[1].pos;
514 if (smooth_x_history[0].dpos >= 0)
515 smooth_x_history[0].vpos = (double)(smooth_x_history[0].dpos) /
516 smooth_x_history[0].dt * FPS;
518 smooth_x_history[0].vpos = -((double)(smooth_x_history[0].dpos) /
519 smooth_x_history[0].dt * FPS);
524 smooth_info_y_count++;
525 memmove(&(smooth_y_history[1]), &(smooth_y_history[0]),
526 sizeof(smooth_y_history[0]) * (SMOOTH_DEBUG_COUNT - 1));
527 smooth_y_history[0].t = tim - start_time;
528 smooth_y_history[0].dt = smooth_y_history[0].t - smooth_y_history[1].t;
529 smooth_y_history[0].pos = y;
530 smooth_y_history[0].dpos = smooth_y_history[0].pos -
531 smooth_y_history[1].pos;
533 if (smooth_y_history[0].dpos >= 0)
534 smooth_y_history[0].vpos = (double)(smooth_y_history[0].dpos) /
535 smooth_y_history[0].dt * FPS;
537 smooth_y_history[0].vpos = -((double)(smooth_y_history[0].dpos) /
538 smooth_y_history[0].dt * FPS);
548 _elm_scroll_scroll_bar_h_visibility_apply(Elm_Scrollable_Smart_Interface_Data *sid)
550 if (sid->hbar_flags != ELM_SCROLLER_POLICY_OFF)
552 if (sid->hbar_visible)
553 edje_object_signal_emit
554 (sid->edje_obj, "elm,action,show,hbar", "elm");
556 edje_object_signal_emit
557 (sid->edje_obj, "elm,action,hide,hbar", "elm");
560 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,hbar", "elm");
561 edje_object_message_signal_process(sid->edje_obj);
562 _elm_scroll_scroll_bar_size_adjust(sid);
563 if (sid->cb_func.content_min_limit)
564 sid->cb_func.content_min_limit(sid->obj, sid->min_w, sid->min_h);
568 _elm_scroll_scroll_bar_v_visibility_apply(Elm_Scrollable_Smart_Interface_Data *sid)
570 if (sid->vbar_flags != ELM_SCROLLER_POLICY_OFF)
572 if (sid->vbar_visible)
573 edje_object_signal_emit
574 (sid->edje_obj, "elm,action,show,vbar", "elm");
576 edje_object_signal_emit
577 (sid->edje_obj, "elm,action,hide,vbar", "elm");
580 edje_object_signal_emit
581 (sid->edje_obj, "elm,action,hide,vbar", "elm");
582 edje_object_message_signal_process(sid->edje_obj);
583 _elm_scroll_scroll_bar_size_adjust(sid);
584 if (sid->cb_func.content_min_limit)
585 sid->cb_func.content_min_limit(sid->obj, sid->min_w, sid->min_h);
589 _elm_scroll_scroll_bar_h_visibility_adjust(
590 Elm_Scrollable_Smart_Interface_Data *sid)
592 int scroll_h_vis_change = 0;
593 Evas_Coord w, vw = 0, vh = 0;
595 if (!sid->edje_obj) return 0;
597 w = sid->content_info.w;
599 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &vw, &vh);
600 if (sid->hbar_visible)
604 scroll_h_vis_change = 1;
605 sid->hbar_visible = EINA_FALSE;
609 if (sid->hbar_flags == ELM_SCROLLER_POLICY_AUTO)
611 if ((sid->content) || (sid->extern_pan))
615 scroll_h_vis_change = 1;
616 sid->hbar_visible = EINA_FALSE;
621 scroll_h_vis_change = 1;
622 sid->hbar_visible = EINA_FALSE;
625 else if (sid->hbar_flags == ELM_SCROLLER_POLICY_OFF)
627 scroll_h_vis_change = 1;
628 sid->hbar_visible = EINA_FALSE;
636 if (sid->hbar_flags == ELM_SCROLLER_POLICY_AUTO)
638 if ((sid->content) || (sid->extern_pan))
642 scroll_h_vis_change = 1;
643 sid->hbar_visible = EINA_TRUE;
647 else if (sid->hbar_flags == ELM_SCROLLER_POLICY_ON)
649 scroll_h_vis_change = 1;
650 sid->hbar_visible = EINA_TRUE;
655 if (scroll_h_vis_change) _elm_scroll_scroll_bar_h_visibility_apply(sid);
657 _elm_direction_arrows_eval(sid);
658 return scroll_h_vis_change;
662 _elm_scroll_scroll_bar_v_visibility_adjust(
663 Elm_Scrollable_Smart_Interface_Data *sid)
665 int scroll_v_vis_change = 0;
666 Evas_Coord h, vw = 0, vh = 0;
668 if (!sid->edje_obj) return 0;
670 h = sid->content_info.h;
672 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &vw, &vh);
673 if (sid->vbar_visible)
677 scroll_v_vis_change = 1;
678 sid->vbar_visible = EINA_FALSE;
682 if (sid->vbar_flags == ELM_SCROLLER_POLICY_AUTO)
684 if ((sid->content) || (sid->extern_pan))
688 scroll_v_vis_change = 1;
689 sid->vbar_visible = EINA_FALSE;
694 scroll_v_vis_change = 1;
695 sid->vbar_visible = EINA_FALSE;
698 else if (sid->vbar_flags == ELM_SCROLLER_POLICY_OFF)
700 scroll_v_vis_change = 1;
701 sid->vbar_visible = EINA_FALSE;
709 if (sid->vbar_flags == ELM_SCROLLER_POLICY_AUTO)
711 if ((sid->content) || (sid->extern_pan))
715 scroll_v_vis_change = 1;
716 sid->vbar_visible = EINA_TRUE;
720 else if (sid->vbar_flags == ELM_SCROLLER_POLICY_ON)
722 scroll_v_vis_change = 1;
723 sid->vbar_visible = EINA_TRUE;
727 if (scroll_v_vis_change) _elm_scroll_scroll_bar_v_visibility_apply(sid);
729 _elm_direction_arrows_eval(sid);
730 return scroll_v_vis_change;
734 _elm_scroll_scroll_bar_visibility_adjust(
735 Elm_Scrollable_Smart_Interface_Data *sid)
739 changed |= _elm_scroll_scroll_bar_h_visibility_adjust(sid);
740 changed |= _elm_scroll_scroll_bar_v_visibility_adjust(sid);
744 _elm_scroll_scroll_bar_h_visibility_adjust(sid);
745 _elm_scroll_scroll_bar_v_visibility_adjust(sid);
749 //TIZEN_ONLY(20151012): Separate logic which calculate for bar size and logic which calculate for bar position.
752 _elm_scroll_scroll_bar_size_adjust(Elm_Scrollable_Smart_Interface_Data *sid)
754 if (!sid->pan_obj || !sid->edje_obj) return;
756 if (sid->size_adjust_recurse_abort) return;
757 if (sid->size_adjust_recurse > 20)
759 sid->size_adjust_recurse_abort = EINA_TRUE;
762 sid->size_adjust_recurse++;
763 if ((sid->content) || (sid->extern_pan))
765 Evas_Coord x, y, w, h, mx = 0, my = 0, vw = 0, vh = 0, px, py,
769 edje_object_calc_force(sid->edje_obj);
770 edje_object_part_geometry_get
771 (sid->edje_obj, "elm.swallow.content", NULL, NULL, &vw, &vh);
772 w = sid->content_info.w;
774 size = (double)vw / (double)w;
779 edje_object_part_drag_value_set
780 (sid->edje_obj, "elm.dragable.hbar", 0.0, 0.0);
782 edje_object_part_drag_size_set
783 (sid->edje_obj, "elm.dragable.hbar", size, 1.0);
785 h = sid->content_info.h;
787 size = (double)vh / (double)h;
791 edje_object_part_drag_value_set
792 (sid->edje_obj, "elm.dragable.vbar", 0.0, 0.0);
794 edje_object_part_drag_size_set
795 (sid->edje_obj, "elm.dragable.vbar", 1.0, size);
797 //TIZEN_ONLY(20150909) : Use the specific bar_chagnged_bar_pos_adjust func only for gengrid.
798 //edje_object_part_drag_value_get
799 // (sid->edje_obj, "elm.dragable.hbar", &vx, NULL);
800 //edje_object_part_drag_value_get
801 // (sid->edje_obj, "elm.dragable.vbar", NULL, &vy);
804 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
805 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
806 //TIZEN_ONLY(20150909) : Use the specific bar_chagnged_bar_pos_adjust func only for gengrid.
807 //x = vx * mx + minx;
808 //y = vy * my + miny;
811 edje_object_part_drag_step_set
812 (sid->edje_obj, "elm.dragable.hbar", (double)sid->step.x /
814 edje_object_part_drag_step_set
815 (sid->edje_obj, "elm.dragable.vbar", 0.0, (double)sid->step.y /
818 edje_object_part_drag_page_set
819 (sid->edje_obj, "elm.dragable.hbar", (double)sid->page.x /
822 edje_object_part_drag_page_set
823 (sid->edje_obj, "elm.dragable.hbar",
824 -((double)sid->page.x * ((double)vw / (double)w)) / 100.0, 0.0);
826 edje_object_part_drag_page_set
827 (sid->edje_obj, "elm.dragable.vbar", 0.0,
828 (double)sid->page.y / (double)h);
830 edje_object_part_drag_page_set
831 (sid->edje_obj, "elm.dragable.vbar", 0.0,
832 -((double)sid->page.y * ((double)vh / (double)h)) / 100.0);
834 //TIZEN_ONLY(20150909) : Use the specific bar_chagnged_bar_pos_adjust func only for gengrid.
835 //eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
837 //if (vx != mx) x = px;
838 //if (vy != my) y = py;
840 eo_do(sid->obj, elm_interface_scrollable_custom_pan_pos_adjust(&x, &y));
843 eo_do(sid->pan_obj, elm_obj_pan_pos_set(x, y));
845 if (mx > 0) vx = (double)(x - minx) / (double)mx;
848 if (vx < 0.0) vx = 0.0;
852 if (my > 0) vy = (double)(y - miny) / (double)my;
855 if (vy < 0.0) vy = 0.0;
859 edje_object_part_drag_value_set
860 (sid->edje_obj, "elm.dragable.vbar", 0.0, vy);
861 edje_object_part_drag_value_set
862 (sid->edje_obj, "elm.dragable.hbar", vx, 0.0);
866 Evas_Coord px = 0, py = 0, minx = 0, miny = 0;
868 edje_object_part_drag_size_set
869 (sid->edje_obj, "elm.dragable.vbar", 1.0, 1.0);
870 edje_object_part_drag_size_set
871 (sid->edje_obj, "elm.dragable.hbar", 1.0, 1.0);
872 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
873 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
874 eo_do(sid->pan_obj, elm_obj_pan_pos_set(minx, miny));
875 if ((px != minx) || (py != miny))
876 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
878 _elm_scroll_scroll_bar_visibility_adjust(sid);
879 sid->size_adjust_recurse--;
880 if (sid->size_adjust_recurse <= 0)
882 sid->size_adjust_recurse = 0;
883 sid->size_adjust_recurse_abort = EINA_FALSE;
887 //Calculate size of bar and position of bar must be separated two different functions.
888 //So we divided a function into the elm_scroll_scroll_bar_pos_adjust and elm_scroll_scroll_bar_size_adjust.
889 //A elm_scroll_scroll_bar_pos_adjust is called when size of content is changed.
890 //If size of pan is changed only, A elm_scroll_scroll_bar_pos_adjust isn`t called. Only a elm_scroll_scroll_bar_size_adjust is called.
892 //This function adjusts the size of the bar.
894 _elm_scroll_scroll_bar_size_adjust_internal(void *data)
896 Elm_Scrollable_Smart_Interface_Data *sid = (Elm_Scrollable_Smart_Interface_Data *)data;
898 if (!sid->pan_obj || !sid->edje_obj) return;
900 sid->adjust_job.bar_size_adjust = NULL;
902 if ((sid->content) || (sid->extern_pan))
904 Evas_Coord w, h, vw = 0, vh = 0;
907 edje_object_part_geometry_get
908 (sid->edje_obj, "elm.swallow.content", NULL, NULL, &vw, &vh);
909 w = sid->content_info.w;
911 size = (double)vw / (double)w;
912 if (size > 1.0) size = 1.0;
913 edje_object_part_drag_size_set
914 (sid->edje_obj, "elm.dragable.hbar", size, 1.0);
916 h = sid->content_info.h;
918 size = (double)vh / (double)h;
919 if (size > 1.0) size = 1.0;
920 edje_object_part_drag_size_set
921 (sid->edje_obj, "elm.dragable.vbar", 1.0, size);
923 edje_object_part_drag_step_set
924 (sid->edje_obj, "elm.dragable.hbar", (double)sid->step.x /
926 edje_object_part_drag_step_set
927 (sid->edje_obj, "elm.dragable.vbar", 0.0, (double)sid->step.y /
930 edje_object_part_drag_page_set
931 (sid->edje_obj, "elm.dragable.hbar", (double)sid->page.x /
934 edje_object_part_drag_page_set
935 (sid->edje_obj, "elm.dragable.hbar",
936 -((double)sid->page.x * ((double)vw / (double)w)) / 100.0, 0.0);
938 edje_object_part_drag_page_set
939 (sid->edje_obj, "elm.dragable.vbar", 0.0,
940 (double)sid->page.y / (double)h);
942 edje_object_part_drag_page_set
943 (sid->edje_obj, "elm.dragable.vbar", 0.0,
944 -((double)sid->page.y * ((double)vh / (double)h)) / 100.0);
948 edje_object_part_drag_size_set
949 (sid->edje_obj, "elm.dragable.vbar", 1.0, 1.0);
950 edje_object_part_drag_size_set
951 (sid->edje_obj, "elm.dragable.hbar", 1.0, 1.0);
953 _elm_scroll_scroll_bar_visibility_adjust(sid);
957 _elm_scroll_scroll_bar_size_adjust(Elm_Scrollable_Smart_Interface_Data *sid)
959 if (!sid->pan_obj || !sid->edje_obj) return;
961 if (!sid->adjust_job.bar_size_adjust)
962 sid->adjust_job.bar_size_adjust
963 = ecore_job_add(_elm_scroll_scroll_bar_size_adjust_internal, sid);
966 //This function adjusts the position of the bar.
968 _elm_scroll_scroll_bar_pos_adjust_internal(void *data)
970 Elm_Scrollable_Smart_Interface_Data *sid = (Elm_Scrollable_Smart_Interface_Data *)data;
972 if (!sid->pan_obj || !sid->edje_obj) return;
974 sid->adjust_job.bar_pos_adjust = NULL;
976 if ((sid->content) || (sid->extern_pan))
978 Evas_Coord x, y, w, h, mx = 0, my = 0, vw = 0, vh = 0,
982 edje_object_part_geometry_get
983 (sid->edje_obj, "elm.swallow.content", NULL, NULL, &vw, &vh);
984 w = sid->content_info.w;
986 size = (double)vw / (double)w;
990 edje_object_part_drag_value_set
991 (sid->edje_obj, "elm.dragable.hbar", 0.0, 0.0);
994 h = sid->content_info.h;
996 size = (double)vh / (double)h;
1000 edje_object_part_drag_value_set
1001 (sid->edje_obj, "elm.dragable.vbar", 0.0, 0.0);
1004 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
1005 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
1006 eo_do(sid->obj, elm_interface_scrollable_custom_pan_pos_adjust(&x, &y));
1007 eo_do(sid->pan_obj, elm_obj_pan_pos_set(x, y));
1009 if (mx > 0) vx = (double)(x - minx) / (double)mx;
1012 if (vx < 0.0) vx = 0.0;
1016 if (my > 0) vy = (double)(y - miny) / (double)my;
1019 if (vy < 0.0) vy = 0.0;
1023 edje_object_part_drag_value_set
1024 (sid->edje_obj, "elm.dragable.vbar", 0.0, vy);
1025 edje_object_part_drag_value_set
1026 (sid->edje_obj, "elm.dragable.hbar", vx, 0.0);
1030 Evas_Coord px = 0, py = 0, minx = 0, miny = 0;
1032 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
1033 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
1034 eo_do(sid->pan_obj, elm_obj_pan_pos_set(minx, miny));
1035 if ((px != minx) || (py != miny))
1036 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
1041 _elm_scroll_scroll_bar_pos_adjust(Elm_Scrollable_Smart_Interface_Data *sid)
1043 if (!sid->pan_obj || !sid->edje_obj) return;
1045 if (!sid->adjust_job.bar_pos_adjust)
1046 sid->adjust_job.bar_pos_adjust
1047 = ecore_job_add(_elm_scroll_scroll_bar_pos_adjust_internal, sid);
1053 //TIZEN_ONLY(20150909) : Use the specific bar_chagnged_bar_pos_adjust func only for gengrid.
1054 //When position of scrollbar is changed, you can adjust a position of custom pan by using this function.
1057 _elm_interface_scrollable_custom_pan_pos_adjust(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord *x, Evas_Coord *y)
1059 Evas_Coord mx, my, minx, miny, px, py;
1062 edje_object_part_drag_value_get
1063 (sid->edje_obj, "elm.dragable.hbar", &vx, NULL);
1064 edje_object_part_drag_value_get
1065 (sid->edje_obj, "elm.dragable.vbar", NULL, &vy);
1067 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
1068 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
1070 *x = _round(vx * (double)mx + minx, 1);
1071 *y = _round(vy * (double)my + miny, 1);
1073 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
1075 if (vx != mx) *x = px;
1076 if (vy != my) *y = py;
1081 _elm_scroll_scroll_bar_read_and_update(
1082 Elm_Scrollable_Smart_Interface_Data *sid)
1084 Evas_Coord x, y, mx = 0, my = 0, minx = 0, miny = 0;
1087 if (!sid->edje_obj || !sid->pan_obj) return;
1089 if ((sid->down.dragged) || (sid->down.bounce_x_animator)
1090 || (sid->down.bounce_y_animator) || (sid->down.momentum_animator)
1091 || (sid->scrollto.x.animator) || (sid->scrollto.y.animator))
1093 edje_object_part_drag_value_get
1094 (sid->edje_obj, "elm.dragable.vbar", NULL, &vy);
1095 edje_object_part_drag_value_get
1096 (sid->edje_obj, "elm.dragable.hbar", &vx, NULL);
1097 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
1098 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
1099 x = _round(vx * (double)mx + minx, 1);
1100 y = _round(vy * (double)my + miny, 1);
1101 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
1102 _elm_scroll_wanted_coordinates_update(sid, x, y);
1105 //TIZEN_ONLY(20190219): fix page snap behavior.
1107 _elm_scroll_scroll_start(Elm_Scrollable_Smart_Interface_Data *sid)
1109 sid->current_page.x = _elm_scroll_page_x_get(sid, 0, EINA_FALSE);
1110 sid->current_page.y = _elm_scroll_page_y_get(sid, 0, EINA_FALSE);
1112 sid->scrolling = EINA_TRUE;
1116 _elm_scroll_scroll_stop(Elm_Scrollable_Smart_Interface_Data *sid)
1119 sid->scrolling = EINA_FALSE;
1120 x = _elm_scroll_page_x_get(sid, 0, EINA_FALSE);
1121 y = _elm_scroll_page_y_get(sid, 0, EINA_FALSE);
1122 if ((sid->cb_func.page_change) &&
1123 ((x != sid->current_page.x) || (y != sid->current_page.y)))
1124 sid->cb_func.page_change(sid->obj, NULL);
1125 sid->current_page.x = x;
1126 sid->current_page.y = y;
1131 _elm_scroll_drag_start(Elm_Scrollable_Smart_Interface_Data *sid)
1133 sid->current_page.x = _elm_scroll_page_x_get(sid, 0, EINA_FALSE);
1134 sid->current_page.y = _elm_scroll_page_y_get(sid, 0, EINA_FALSE);
1136 //TIZEN_ONLY(20190219): fix page snap behavior.
1137 if (!sid->scrolling)
1138 _elm_scroll_scroll_start(sid);
1143 _elm_scroll_drag_stop(Elm_Scrollable_Smart_Interface_Data *sid)
1145 if (sid->cb_func.drag_stop)
1146 sid->cb_func.drag_stop(sid->obj, NULL);
1150 _elm_scroll_anim_start(Elm_Scrollable_Smart_Interface_Data *sid)
1152 if (sid->cb_func.animate_start)
1153 sid->cb_func.animate_start(sid->obj, NULL);
1155 //TIZEN_ONLY(20190219): fix page snap behavior.
1156 if (!sid->scrolling)
1157 _elm_scroll_scroll_start(sid);
1162 _elm_scroll_anim_stop(Elm_Scrollable_Smart_Interface_Data *sid)
1166 if (sid->cb_func.animate_stop)
1167 sid->cb_func.animate_stop(sid->obj, NULL);
1169 //TIZEN_ONLY(20190219): fix page snap behavior.
1171 _elm_scroll_scroll_stop(sid);
1176 _elm_scroll_policy_signal_emit(Elm_Scrollable_Smart_Interface_Data *sid)
1178 if (sid->hbar_flags == ELM_SCROLLER_POLICY_ON)
1179 edje_object_signal_emit
1180 (sid->edje_obj, "elm,action,show_always,hbar", "elm");
1181 else if (sid->hbar_flags == ELM_SCROLLER_POLICY_OFF)
1182 edje_object_signal_emit
1183 (sid->edje_obj, "elm,action,hide,hbar", "elm");
1185 edje_object_signal_emit
1186 (sid->edje_obj, "elm,action,show_notalways,hbar", "elm");
1187 if (sid->vbar_flags == ELM_SCROLLER_POLICY_ON)
1188 edje_object_signal_emit
1189 (sid->edje_obj, "elm,action,show_always,vbar", "elm");
1190 else if (sid->vbar_flags == ELM_SCROLLER_POLICY_OFF)
1191 edje_object_signal_emit
1192 (sid->edje_obj, "elm,action,hide,vbar", "elm");
1194 edje_object_signal_emit
1195 (sid->edje_obj, "elm,action,show_notalways,vbar", "elm");
1196 edje_object_message_signal_process(sid->edje_obj);
1197 _elm_scroll_scroll_bar_size_adjust(sid);
1201 _elm_scroll_reload_cb(void *data,
1202 Evas_Object *obj EINA_UNUSED,
1203 const char *emission EINA_UNUSED,
1204 const char *source EINA_UNUSED)
1206 Elm_Scrollable_Smart_Interface_Data *sid = data;
1207 _elm_scroll_policy_signal_emit(sid);
1208 _elm_scroll_scroll_bar_h_visibility_apply(sid);
1209 _elm_scroll_scroll_bar_v_visibility_apply(sid);
1213 _elm_scroll_vbar_drag_cb(void *data,
1214 Evas_Object *obj EINA_UNUSED,
1215 const char *emission EINA_UNUSED,
1216 const char *source EINA_UNUSED)
1218 Elm_Scrollable_Smart_Interface_Data *sid = data;
1220 if (sid->cb_func.vbar_drag)
1221 sid->cb_func.vbar_drag(sid->obj, NULL);
1223 _elm_scroll_scroll_bar_read_and_update(sid);
1227 _elm_scroll_vbar_press_cb(void *data,
1228 Evas_Object *obj EINA_UNUSED,
1229 const char *emission EINA_UNUSED,
1230 const char *source EINA_UNUSED)
1232 Elm_Scrollable_Smart_Interface_Data *sid = data;
1234 if (sid->cb_func.vbar_press)
1235 sid->cb_func.vbar_press(sid->obj, NULL);
1239 _elm_scroll_vbar_unpress_cb(void *data,
1240 Evas_Object *obj EINA_UNUSED,
1241 const char *emission EINA_UNUSED,
1242 const char *source EINA_UNUSED)
1244 Elm_Scrollable_Smart_Interface_Data *sid = data;
1246 if (sid->cb_func.vbar_unpress)
1247 sid->cb_func.vbar_unpress(sid->obj, NULL);
1251 _elm_scroll_edje_drag_v_start_cb(void *data,
1252 Evas_Object *obj EINA_UNUSED,
1253 const char *emission EINA_UNUSED,
1254 const char *source EINA_UNUSED)
1256 Elm_Scrollable_Smart_Interface_Data *sid = data;
1258 _elm_scroll_scroll_bar_read_and_update(sid);
1259 _elm_scroll_drag_start(sid);
1260 sid->freeze = EINA_TRUE;
1264 _elm_scroll_edje_drag_v_stop_cb(void *data,
1265 Evas_Object *obj EINA_UNUSED,
1266 const char *emission EINA_UNUSED,
1267 const char *source EINA_UNUSED)
1269 Elm_Scrollable_Smart_Interface_Data *sid = data;
1271 _elm_scroll_scroll_bar_read_and_update(sid);
1272 _elm_scroll_drag_stop(sid);
1273 sid->freeze = EINA_FALSE;
1277 _elm_scroll_edje_drag_v_cb(void *data,
1278 Evas_Object *obj EINA_UNUSED,
1279 const char *emission EINA_UNUSED,
1280 const char *source EINA_UNUSED)
1282 Elm_Scrollable_Smart_Interface_Data *sid = data;
1284 _elm_scroll_scroll_bar_read_and_update(sid);
1288 _elm_scroll_hbar_drag_cb(void *data,
1289 Evas_Object *obj EINA_UNUSED,
1290 const char *emission EINA_UNUSED,
1291 const char *source EINA_UNUSED)
1293 Elm_Scrollable_Smart_Interface_Data *sid = data;
1295 if (sid->cb_func.hbar_drag)
1296 sid->cb_func.hbar_drag(sid->obj, NULL);
1298 _elm_scroll_scroll_bar_read_and_update(sid);
1302 _elm_scroll_hbar_press_cb(void *data,
1303 Evas_Object *obj EINA_UNUSED,
1304 const char *emission EINA_UNUSED,
1305 const char *source EINA_UNUSED)
1307 Elm_Scrollable_Smart_Interface_Data *sid = data;
1309 if (sid->cb_func.hbar_press)
1310 sid->cb_func.hbar_press(sid->obj, NULL);
1314 _elm_scroll_hbar_unpress_cb(void *data,
1315 Evas_Object *obj EINA_UNUSED,
1316 const char *emission EINA_UNUSED,
1317 const char *source EINA_UNUSED)
1319 Elm_Scrollable_Smart_Interface_Data *sid = data;
1321 if (sid->cb_func.hbar_unpress)
1322 sid->cb_func.hbar_unpress(sid->obj, NULL);
1326 _elm_scroll_edje_drag_h_start_cb(void *data,
1327 Evas_Object *obj EINA_UNUSED,
1328 const char *emission EINA_UNUSED,
1329 const char *source EINA_UNUSED)
1331 Elm_Scrollable_Smart_Interface_Data *sid = data;
1333 _elm_scroll_scroll_bar_read_and_update(sid);
1334 _elm_scroll_drag_start(sid);
1335 sid->freeze = EINA_TRUE;
1339 _elm_scroll_edje_drag_h_stop_cb(void *data,
1340 Evas_Object *obj EINA_UNUSED,
1341 const char *emission EINA_UNUSED,
1342 const char *source EINA_UNUSED)
1344 Elm_Scrollable_Smart_Interface_Data *sid = data;
1346 _elm_scroll_scroll_bar_read_and_update(sid);
1347 _elm_scroll_drag_stop(sid);
1348 sid->freeze = EINA_FALSE;
1352 _elm_scroll_edje_drag_h_cb(void *data,
1353 Evas_Object *obj EINA_UNUSED,
1354 const char *emission EINA_UNUSED,
1355 const char *source EINA_UNUSED)
1357 Elm_Scrollable_Smart_Interface_Data *sid = data;
1359 _elm_scroll_scroll_bar_read_and_update(sid);
1363 _elm_interface_scrollable_content_size_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord *w, Evas_Coord *h)
1365 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(w, h));
1369 _elm_interface_scrollable_content_viewport_geometry_get(Eo *obj EINA_UNUSED,
1370 Elm_Scrollable_Smart_Interface_Data *sid,
1376 if (!sid->pan_obj || !sid->edje_obj) return;
1378 edje_object_calc_force(sid->edje_obj);
1379 evas_object_geometry_get(sid->pan_obj, x, y, w, h);
1383 _elm_interface_scrollable_content_min_limit(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool w, Eina_Bool h)
1385 if (!sid->edje_obj) return;
1387 if (!sid->cb_func.content_min_limit)
1389 ERR("Content minimim size limiting is unimplemented -- you "
1390 "must provide it yourself\n");
1396 sid->cb_func.content_min_limit(sid->obj, w, h);
1400 _elm_scroll_x_mirrored_get(const Evas_Object *obj,
1403 Evas_Coord cw = 0, w = 0, min = 0, ret;
1405 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, x);
1407 if (!sid->pan_obj) return 0;
1409 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&min, NULL));
1410 eo_do((Eo *)obj, elm_interface_scrollable_content_viewport_geometry_get
1411 (NULL, NULL, &w, NULL));
1412 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&cw, NULL));
1413 ret = cw - w - x + min + min;
1415 return (ret >= min) ? ret : min;
1418 /* Update the wanted coordinates according to the x, y passed
1419 * widget directionality, content size and etc. */
1421 _elm_scroll_wanted_coordinates_update(Elm_Scrollable_Smart_Interface_Data *sid,
1425 Evas_Coord mx = 0, my = 0, minx = 0, miny = 0;
1427 if (!sid->pan_obj) return;
1429 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
1430 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
1432 /* Update wx/y/w/h - and if the requested positions aren't legal
1434 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
1435 (NULL, NULL, &sid->ww, &sid->wh));
1437 if (x < minx && !sid->is_mirrored)
1439 if (!sid->loop_h) sid->wx = minx;
1442 else if (!sid->loop_h && (x > mx)) sid->wx = mx;
1443 else if (sid->loop_h && x >= (sid->ww + mx)) sid->wx = 0;
1448 if (!sid->loop_v) sid->wy = miny;
1451 else if (!sid->loop_v && (y > my)) sid->wy = my;
1452 else if (sid->loop_v && y >= (sid->wh + my)) sid->wy = 0;
1457 _elm_scroll_momentum_end(Elm_Scrollable_Smart_Interface_Data *sid)
1459 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator)) return;
1460 if (sid->down.momentum_animator)
1462 Evas_Coord px = 0, py = 0;
1463 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&px, &py));
1464 _elm_scroll_wanted_coordinates_update(sid, px, py);
1466 ELM_SAFE_FREE(sid->down.momentum_animator, ecore_animator_del);
1467 sid->down.bounce_x_hold = EINA_FALSE;
1468 sid->down.bounce_y_hold = EINA_FALSE;
1475 if (sid->content_info.resized)
1476 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
1477 //_elm_scroll_wanted_region_set(sid->obj);
1478 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
1484 _elm_scroll_bounce_x_animator(void *data)
1486 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(data, sid, EINA_FALSE);
1487 Evas_Coord x, y, dx, w, odx, ed, md;
1488 double t, p, dt, pd, r;
1490 t = ecore_loop_time_get();
1491 dt = t - sid->down.anim_start2;
1494 dt = dt / _elm_config->thumbscroll_bounce_friction;
1495 odx = sid->down.b2x - sid->down.bx;
1496 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
1497 (NULL, NULL, &w, NULL));
1498 if (!sid->down.momentum_animator && (w > abs(odx)))
1500 pd = (double)odx / (double)w;
1501 pd = (pd > 0) ? pd : -pd;
1502 pd = 1.0 - ((1.0 - pd) * (1.0 - pd));
1505 if (dt > 1.0) dt = 1.0;
1506 p = 1.0 - ((1.0 - dt) * (1.0 - dt));
1507 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
1510 if (sid->down.momentum_animator)
1512 ed = abs((int)(sid->down.dx * (_elm_config->thumbscroll_friction +
1513 sid->down.extra_time) - sid->down.b0x));
1514 md = abs((int)(_elm_config->thumbscroll_friction * 5 * w));
1515 if (ed > md) r = (double)(md) / (double)ed;
1517 x = sid->down.b2x + (int)((double)(dx - odx) * r);
1518 if (!sid->down.cancelled)
1519 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
1522 if (sid->down.momentum_animator)
1523 sid->down.bounce_x_hold = EINA_TRUE;
1524 if ((!sid->down.bounce_y_animator) &&
1525 (!sid->scrollto.y.animator))
1526 _elm_scroll_anim_stop(sid);
1527 sid->down.bounce_x_animator = NULL;
1529 sid->bouncemex = EINA_FALSE;
1530 _elm_scroll_momentum_end(sid);
1531 if (sid->content_info.resized)
1532 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
1533 //_elm_scroll_wanted_region_set(sid->obj);
1534 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
1536 return ECORE_CALLBACK_CANCEL;
1539 return ECORE_CALLBACK_RENEW;
1543 _elm_scroll_bounce_y_animator(void *data)
1545 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(data, sid, EINA_FALSE);
1546 Evas_Coord x, y, dy, h, ody, ed, md;
1547 double t, p, dt, pd, r;
1549 t = ecore_loop_time_get();
1550 dt = t - sid->down.anim_start3;
1553 dt = dt / _elm_config->thumbscroll_bounce_friction;
1554 ody = sid->down.b2y - sid->down.by;
1555 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
1556 (NULL, NULL, NULL, &h));
1557 if (!sid->down.momentum_animator && (h > abs(ody)))
1559 pd = (double)ody / (double)h;
1560 pd = (pd > 0) ? pd : -pd;
1561 pd = 1.0 - ((1.0 - pd) * (1.0 - pd));
1564 if (dt > 1.0) dt = 1.0;
1565 p = 1.0 - ((1.0 - dt) * (1.0 - dt));
1566 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
1569 if (sid->down.momentum_animator)
1571 ed = abs((int)(sid->down.dy * (_elm_config->thumbscroll_friction +
1572 sid->down.extra_time) - sid->down.b0y));
1573 md = abs((int)(_elm_config->thumbscroll_friction * 5 * h));
1574 if (ed > md) r = (double)(md) / (double)ed;
1576 y = sid->down.b2y + (int)((double)(dy - ody) * r);
1577 if (!sid->down.cancelled)
1578 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
1581 if (sid->down.momentum_animator)
1582 sid->down.bounce_y_hold = EINA_TRUE;
1583 if ((!sid->down.bounce_x_animator) &&
1584 (!sid->scrollto.y.animator))
1585 _elm_scroll_anim_stop(sid);
1586 sid->down.bounce_y_animator = NULL;
1588 sid->bouncemey = EINA_FALSE;
1589 _elm_scroll_momentum_end(sid);
1590 if (sid->content_info.resized)
1591 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
1592 //_elm_scroll_wanted_region_set(sid->obj);
1593 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
1595 return ECORE_CALLBACK_CANCEL;
1599 return ECORE_CALLBACK_RENEW;
1603 _elm_scroll_bounce_eval(Elm_Scrollable_Smart_Interface_Data *sid)
1605 Evas_Coord mx = 0, my = 0, px = 0, py = 0, bx, by, b2x, b2y, minx = 0, miny = 0;
1607 if (!sid->pan_obj) return;
1609 if (sid->freeze) return;
1610 if ((!sid->bouncemex) && (!sid->bouncemey)) return;
1611 if (sid->down.now) return; // down bounce while still held down
1612 if (sid->down.onhold_animator)
1614 ELM_SAFE_FREE(sid->down.onhold_animator, ecore_animator_del);
1615 if (sid->content_info.resized)
1616 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
1617 //_elm_scroll_wanted_region_set(sid->obj);
1618 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
1621 if (sid->down.hold_animator)
1623 ELM_SAFE_FREE(sid->down.hold_animator, ecore_animator_del);
1624 if (sid->content_info.resized)
1625 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
1626 //_elm_scroll_wanted_region_set(sid->obj);
1627 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
1631 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
1632 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
1633 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
1636 if (px < minx) px = minx;
1637 if ((px - minx) > mx) px = mx + minx;
1638 if (py < miny) py = miny;
1639 if ((py - miny) > my) py = my + miny;
1643 (!elm_widget_drag_child_locked_x_get(sid->obj)))
1645 if ((!sid->down.bounce_x_animator) && (!sid->bounce_animator_disabled))
1649 ELM_SAFE_FREE(sid->scrollto.x.animator, ecore_animator_del);
1650 sid->down.bounce_x_animator =
1651 ecore_animator_add(_elm_scroll_bounce_x_animator, sid->obj);
1652 sid->down.anim_start2 = ecore_loop_time_get();
1655 sid->down.b2x = b2x;
1656 if (sid->down.momentum_animator)
1657 sid->down.b0x = sid->down.ax;
1658 else sid->down.b0x = 0;
1663 (!elm_widget_drag_child_locked_y_get(sid->obj)))
1665 if ((!sid->down.bounce_y_animator) && (!sid->bounce_animator_disabled))
1669 ELM_SAFE_FREE(sid->scrollto.y.animator, ecore_animator_del);
1670 sid->down.bounce_y_animator =
1671 ecore_animator_add(_elm_scroll_bounce_y_animator, sid->obj);
1672 sid->down.anim_start3 = ecore_loop_time_get();
1675 sid->down.b2y = b2y;
1676 if (sid->down.momentum_animator)
1677 sid->down.b0y = sid->down.ay;
1678 else sid->down.b0y = 0;
1685 _elm_interface_scrollable_content_pos_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord *x, Evas_Coord *y)
1687 if (!sid->pan_obj) return;
1689 eo_do(sid->pan_obj, elm_obj_pan_pos_get(x, y));
1693 _elm_interface_scrollable_content_pos_set(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord x, Evas_Coord y, Eina_Bool sig)
1695 Evas_Coord mx = 0, my = 0, px = 0, py = 0, spx = 0, spy = 0, minx = 0, miny = 0;
1696 Evas_Coord cw = 0, ch = 0, pw = 0, ph = 0;
1697 // TIZEN_ONLY(20160624): Overscroll effect
1698 Evas_Coord ww = 0, wh = 0;
1703 if (!sid->edje_obj || !sid->pan_obj) return;
1705 // FIXME: allow for bounce outside of range
1706 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
1707 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
1708 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&cw, &ch));
1709 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
1710 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &pw, &ph);
1711 // TIZEN_ONLY(20160624): Overscroll effect
1712 eo_do(obj, elm_interface_scrollable_content_viewport_geometry_get
1713 (NULL, NULL, &ww, &wh));
1716 if (_paging_is_enabled(sid))
1718 if (sid->page_snap_horiz)
1720 //we passed one page to the right
1721 if (x > sid->current_page.x + sid->pagesize_h)
1722 x = sid->current_page.x + sid->pagesize_h;
1723 //we passed one page to the left
1724 if (x < sid->current_page.x - sid->pagesize_h)
1725 x = sid->current_page.x - sid->pagesize_h;
1727 if (sid->page_snap_vert)
1729 //we passed one page to the bottom
1730 if (y > sid->current_page.y + sid->pagesize_v)
1731 y = sid->current_page.y + sid->pagesize_v;
1732 //we passed one page to the top
1733 if (y < sid->current_page.y - sid->pagesize_v)
1734 y = sid->current_page.y - sid->pagesize_v;
1738 if (sid->loop_h && cw > 0)
1740 if (x < 0) x = cw + (x % cw);
1741 else if (x >= cw) x = (x % cw);
1743 if (sid->loop_v && ch > 0)
1745 if (y < 0) y = ch + (y % ch);
1746 else if (y >= ch) y = (y % ch);
1748 // TIZEN_ONLY(20160624): Overscroll effect
1754 edje_object_signal_emit(sid->edje_obj, "elm,edge,left", "elm");
1755 if (!sid->loop_h && (x - minx) > mx)
1756 edje_object_signal_emit(sid->edje_obj, "elm,edge,right", "elm");
1761 edje_object_signal_emit(sid->edje_obj, "elm,edge,top", "elm");
1762 if (!sid->loop_v && (y - miny) > my)
1763 edje_object_signal_emit(sid->edje_obj, "elm,edge,bottom", "elm");
1767 if (!_elm_config->thumbscroll_bounce_enable)
1770 if (x < minx) x = minx;
1771 if (!sid->loop_h && (x - minx) > mx) x = mx + minx;
1772 if (y < miny) y = miny;
1773 if (!sid->loop_v && (y - miny) > my) y = my + miny;
1776 if (!sid->bounce_horiz)
1778 if (x < minx) x = minx;
1779 if (!sid->loop_h && (x - minx) > mx) x = mx + minx;
1781 if (!sid->bounce_vert)
1783 if (y < miny) y = miny;
1784 if (!sid->loop_v && (y - miny) > my) y = my + miny;
1787 eo_do(sid->pan_obj, elm_obj_pan_pos_set(x, y));
1788 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&spx, &spy));
1790 if (mx > 0) vx = (double)(spx - minx) / (double)mx;
1793 if (vx < 0.0) vx = 0.0;
1797 if (my > 0) vy = (double)(spy - miny) / (double)my;
1800 if (vy < 0.0) vy = 0.0;
1804 edje_object_part_drag_value_set
1805 (sid->edje_obj, "elm.dragable.vbar", 0.0, vy);
1806 edje_object_part_drag_value_set
1807 (sid->edje_obj, "elm.dragable.hbar", vx, 0.0);
1809 if (!sid->loop_h && !sid->down.bounce_x_animator)
1811 if (((x < minx) && (0 <= sid->down.dx)) ||
1812 ((x > (mx + minx)) && (0 >= sid->down.dx)))
1814 sid->bouncemex = EINA_TRUE;
1815 _elm_scroll_bounce_eval(sid);
1818 sid->bouncemex = EINA_FALSE;
1820 if (!sid->loop_v && !sid->down.bounce_y_animator)
1822 if (((y < miny) && (0 <= sid->down.dy)) ||
1823 ((y > (my + miny)) && (0 >= sid->down.dy)))
1825 sid->bouncemey = EINA_TRUE;
1826 _elm_scroll_bounce_eval(sid);
1829 sid->bouncemey = EINA_FALSE;
1834 if ((x != px) || (y != py))
1836 if (sid->cb_func.scroll)
1837 sid->cb_func.scroll(obj, NULL);
1838 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
1841 if (sid->cb_func.scroll_left)
1842 sid->cb_func.scroll_left(obj, NULL);
1843 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,left", "elm");
1847 if (sid->cb_func.scroll_right)
1848 sid->cb_func.scroll_right(obj, NULL);
1849 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,right", "elm");
1853 if (sid->cb_func.scroll_up)
1854 sid->cb_func.scroll_up(obj, NULL);
1855 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,up", "elm");
1859 if (sid->cb_func.scroll_down)
1860 sid->cb_func.scroll_down(obj, NULL);
1861 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,down", "elm");
1868 if (sid->cb_func.edge_left)
1869 sid->cb_func.edge_left(obj, NULL);
1870 // TIZEN_ONLY(20160624): Overscroll effect
1871 // edje_object_signal_emit(sid->edje_obj, "elm,edge,left", "elm");
1873 if (x == (mx + minx))
1875 if (sid->cb_func.edge_right)
1876 sid->cb_func.edge_right(obj, NULL);
1877 // TIZEN_ONLY(20160624): Overscroll effect
1878 //edje_object_signal_emit(sid->edje_obj, "elm,edge,right", "elm");
1885 if (sid->cb_func.edge_top)
1886 sid->cb_func.edge_top(obj, NULL);
1887 // TIZEN_ONLY(20160624): Overscroll effect
1888 //edje_object_signal_emit(sid->edje_obj, "elm,edge,top", "elm");
1892 if (sid->cb_func.edge_bottom)
1893 sid->cb_func.edge_bottom(obj, NULL);
1894 // TIZEN_ONLY(20160624): Overscroll effect
1895 // edje_object_signal_emit(sid->edje_obj, "elm,edge,bottom", "elm");
1900 _elm_direction_arrows_eval(sid);
1904 _elm_interface_scrollable_mirrored_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool mirrored)
1908 if (!sid->edje_obj) return;
1910 mirrored = !!mirrored;
1912 if (sid->is_mirrored == mirrored)
1915 sid->is_mirrored = mirrored;
1916 edje_object_mirrored_set(sid->edje_obj, mirrored);
1917 wx = _elm_scroll_x_mirrored_get(sid->obj, sid->wx);
1918 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(wx, sid->wy, EINA_FALSE));
1921 /* returns TRUE when we need to move the scroller, FALSE otherwise.
1922 * Updates w and h either way, so save them if you need them. */
1924 _elm_scroll_content_region_show_internal(Evas_Object *obj,
1930 Evas_Coord cw = 0, ch = 0, px = 0, py = 0, nx, ny,
1931 minx = 0, miny = 0, pw = 0, ph = 0, x = *_x, y = *_y;
1933 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
1935 if (!sid->pan_obj) return EINA_FALSE;
1937 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
1938 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&cw, &ch));
1939 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
1940 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &pw, &ph);
1943 if ((x > px) && (w < pw))
1945 if ((px + pw) < (x + w)) nx = x - pw + w;
1949 if ((y > py) && (h < ph))
1951 if ((py + ph) < (y + h)) ny = y - ph + h;
1955 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
1956 (sid->scrollto.x.animator) || (sid->scrollto.y.animator))
1958 ELM_SAFE_FREE(sid->scrollto.x.animator, ecore_animator_del);
1959 ELM_SAFE_FREE(sid->scrollto.y.animator, ecore_animator_del);
1960 if (sid->down.bounce_x_animator)
1962 ELM_SAFE_FREE(sid->down.bounce_x_animator, ecore_animator_del);
1963 sid->bouncemex = EINA_FALSE;
1964 if (sid->content_info.resized)
1965 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
1966 //_elm_scroll_wanted_region_set(sid->obj);
1967 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
1970 if (sid->down.bounce_y_animator)
1972 ELM_SAFE_FREE(sid->down.bounce_y_animator, ecore_animator_del);
1973 sid->bouncemey = EINA_FALSE;
1974 if (sid->content_info.resized)
1975 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
1976 //_elm_scroll_wanted_region_set(sid->obj);
1977 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
1981 _elm_scroll_anim_stop(sid);
1983 if (sid->down.hold_animator)
1985 ELM_SAFE_FREE(sid->down.hold_animator, ecore_animator_del);
1986 _elm_scroll_drag_stop(sid);
1987 if (sid->content_info.resized)
1988 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
1989 //_elm_scroll_wanted_region_set(sid->obj);
1990 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
1993 if (sid->down.momentum_animator)
1995 ELM_SAFE_FREE(sid->down.momentum_animator, ecore_animator_del);
1996 sid->down.bounce_x_hold = EINA_FALSE;
1997 sid->down.bounce_y_hold = EINA_FALSE;
2002 if (sid->content_info.resized)
2003 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
2004 //_elm_scroll_wanted_region_set(sid->obj);
2005 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
2009 if (_paging_is_enabled(sid))
2011 x = _elm_scroll_page_x_get(sid, nx - px, EINA_FALSE);
2012 y = _elm_scroll_page_y_get(sid, ny - py, EINA_FALSE);
2021 if ((x + pw) > cw) x = cw - pw;
2022 if (x < minx) x = minx;
2026 if ((y + ph) > ch) y = ch - ph;
2027 if (y < miny) y = miny;
2030 if ((x == px) && (y == py)) return EINA_FALSE;
2037 _elm_interface_scrollable_content_region_get(Eo *obj, Elm_Scrollable_Smart_Interface_Data *_pd EINA_UNUSED, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
2039 eo_do(obj, elm_interface_scrollable_content_pos_get(x, y));
2040 eo_do(obj, elm_interface_scrollable_content_viewport_geometry_get
2041 (NULL, NULL, w, h));
2044 /* Set should be used for calculated positions, for example, when we move
2045 * because of an animation or because this is the correct position after
2048 _elm_interface_scrollable_content_region_set(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
2050 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
2052 eo_do(obj, elm_interface_scrollable_content_pos_set(x, y, EINA_FALSE));
2055 sid->down.x = sid->down.history[0].x;
2056 sid->down.y = sid->down.history[0].y;
2060 /* Set should be used for setting the wanted position, for example a
2061 * user scroll or moving the cursor in an entry. */
2063 _elm_interface_scrollable_content_region_show(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
2069 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
2071 eo_do(obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
2074 sid->down.x = sid->down.history[0].x;
2075 sid->down.y = sid->down.history[0].y;
2079 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
2081 //_elm_scroll_wanted_region_set(Evas_Object *obj)
2083 _elm_interface_scrollable_wanted_region_set(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord x EINA_UNUSED, Evas_Coord y EINA_UNUSED)
2086 Evas_Coord ww, wh, wx;
2087 Evas_Coord mx = 0, my = 0;
2089 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
2090 // ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
2095 if (sid->down.now || sid->down.momentum_animator ||
2096 sid->down.bounce_x_animator || sid->down.bounce_y_animator ||
2097 sid->down.hold_animator || sid->down.onhold_animator ||
2098 sid->scrollto.x.animator || sid->scrollto.y.animator)
2101 sid->content_info.resized = EINA_FALSE;
2105 eo_do(obj, elm_interface_scrollable_content_viewport_geometry_get
2106 (NULL, NULL, &ww, &wh));
2114 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
2116 wx += (mx - sid->prev_cw) * sid->gravity_x;
2117 sid->wy += (my - sid->prev_ch) * sid->gravity_y;
2122 eo_do(obj, elm_interface_scrollable_content_region_set(wx, sid->wy, ww, wh));
2127 _scroll_wheel_post_event_cb(void *data, Evas *e EINA_UNUSED)
2129 Elm_Scrollable_Smart_Interface_Data *sid = data;
2130 Evas_Event_Mouse_Wheel *ev = sid->event_info;
2132 Evas_Coord x = 0, y = 0, vw = 0, vh = 0, cw = 0, ch = 0;
2133 int pagenumber_h = 0, pagenumber_v = 0;
2134 int mx = 0, my = 0, minx = 0, miny = 0;
2135 Evas_Coord pwx, pwy;
2139 direction = ev->direction;
2144 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_TRUE;
2145 if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
2146 direction = !direction;
2148 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
2149 if (sid->scrollto.x.animator) x = sid->scrollto.x.end;
2150 if (sid->scrollto.y.animator) y = sid->scrollto.y.end;
2151 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
2152 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
2153 if (x < minx) x = minx;
2155 if (y < miny) y = miny;
2158 t = ecore_loop_time_get();
2160 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
2161 (sid->scrollto.x.animator) || (sid->scrollto.y.animator))
2163 _elm_scroll_anim_stop(sid);
2165 ELM_SAFE_FREE(sid->scrollto.x.animator, ecore_animator_del);
2166 ELM_SAFE_FREE(sid->scrollto.y.animator, ecore_animator_del);
2167 if (sid->down.bounce_x_animator)
2169 ELM_SAFE_FREE(sid->down.bounce_x_animator, ecore_animator_del);
2170 sid->bouncemex = EINA_FALSE;
2171 if (sid->content_info.resized)
2172 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
2173 //_elm_scroll_wanted_region_set(sid->obj);
2174 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
2177 if (sid->down.bounce_y_animator)
2179 ELM_SAFE_FREE(sid->down.bounce_y_animator, ecore_animator_del);
2180 sid->bouncemey = EINA_FALSE;
2181 if (sid->content_info.resized)
2182 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
2183 //_elm_scroll_wanted_region_set(sid->obj);
2184 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
2187 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
2188 (NULL, NULL, &vw, &vh));
2190 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&cw, &ch));
2191 if (!_paging_is_enabled(sid))
2194 double delta_t = (double)(ev->timestamp - sid->last_wheel) / 1000.0;
2197 mul = 1.0 + (7.0 * ((0.2 - delta_t) / 0.2));
2198 if (delta_t < 0.2) d *= mul;
2199 sid->last_wheel = ev->timestamp;
2202 if ((ch > vh) || (cw <= vw)) y += d * sid->step.y;
2203 else x += d * sid->step.x;
2205 else if (direction == 1)
2207 if ((cw > vw) || (ch <= vh)) x += d * sid->step.x;
2208 else y += d * sid->step.y;
2211 if ((!sid->hold) && (!sid->freeze))
2213 _elm_scroll_wanted_coordinates_update(sid, x, y);
2214 _elm_scroll_scroll_to_x(sid, _elm_config->bring_in_scroll_friction, x);
2215 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, y);
2220 eo_do(sid->obj, elm_interface_scrollable_current_page_get(&pagenumber_h, &pagenumber_v));
2223 if (ch > vh || cw <= vw)
2224 y = (pagenumber_v + (1 * ev->z)) * sid->pagesize_v;
2226 x = (pagenumber_h + (1 * ev->z)) * sid->pagesize_h;
2228 else if (direction == 1)
2230 if (cw > vw || ch <= vh)
2231 x = (pagenumber_h + (1 * ev->z)) * sid->pagesize_h;
2233 y = (pagenumber_v + (1 * ev->z)) * sid->pagesize_v;
2236 if ((!sid->hold) && (!sid->freeze))
2238 _elm_scroll_wanted_coordinates_update(sid, x, y);
2239 _elm_scroll_scroll_to_x(sid, _elm_config->bring_in_scroll_friction, x);
2240 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, y);
2246 if ((pwx != sid->wx) ||
2247 (((t - sid->down.last_time_x_wheel) < 0.5) &&
2248 (sid->down.last_hold_x_wheel)))
2250 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2251 sid->down.last_hold_x_wheel = EINA_TRUE;
2253 else sid->down.last_hold_x_wheel = EINA_FALSE;
2254 sid->down.last_time_x_wheel = t;
2258 if ((pwy != sid->wy) ||
2259 (((t - sid->down.last_time_y_wheel) < 0.5) &&
2260 (sid->down.last_hold_y_wheel)))
2262 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2263 sid->down.last_hold_y_wheel = EINA_TRUE;
2265 else sid->down.last_hold_y_wheel = EINA_FALSE;
2266 sid->down.last_time_y_wheel = t;
2273 _elm_scroll_wheel_event_cb(void *data,
2275 Evas_Object *obj EINA_UNUSED,
2278 Elm_Scrollable_Smart_Interface_Data *sid;
2279 Evas_Event_Mouse_Wheel *ev;
2284 sid->event_info = event_info;
2285 direction = ev->direction;
2287 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
2288 if ((evas_key_modifier_is_set(ev->modifiers, "Control")) ||
2289 (evas_key_modifier_is_set(ev->modifiers, "Alt")) ||
2290 (evas_key_modifier_is_set(ev->modifiers, "Meta")) ||
2291 (evas_key_modifier_is_set(ev->modifiers, "Hyper")) ||
2292 (evas_key_modifier_is_set(ev->modifiers, "Super")))
2296 if (sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL) return;
2300 if (sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL) return;
2303 evas_post_event_callback_push(e, _scroll_wheel_post_event_cb, sid);
2307 _elm_scroll_post_event_up(void *data,
2308 Evas *e EINA_UNUSED)
2310 Elm_Scrollable_Smart_Interface_Data *sid = data;
2314 if (sid->down.dragged)
2316 elm_widget_drag_lock_x_set(sid->obj, EINA_FALSE);
2317 elm_widget_drag_lock_y_set(sid->obj, EINA_FALSE);
2324 _paging_is_enabled(Elm_Scrollable_Smart_Interface_Data *sid)
2326 if ((sid->pagerel_h == 0.0) && (!sid->pagesize_h) &&
2327 (sid->pagerel_v == 0.0) && (!sid->pagesize_v))
2333 _elm_scroll_momentum_animator(void *data)
2335 double t, at, dt, p, r;
2336 Elm_Scrollable_Smart_Interface_Data *sid = data;
2337 Evas_Coord x, y, dx, dy, px, py, maxx, maxy, minx, miny;
2338 Eina_Bool no_bounce_x_end = EINA_FALSE, no_bounce_y_end = EINA_FALSE;
2342 sid->down.momentum_animator = NULL;
2343 return ECORE_CALLBACK_CANCEL;
2346 t = ecore_loop_time_get();
2347 dt = t - sid->down.anim_start;
2350 r = _elm_config->thumbscroll_min_friction / _elm_config->thumbscroll_friction;
2352 (sid->down.dx * sid->down.dx) + (sid->down.dy * sid->down.dy));
2353 at = at < ((1.0 - r) * _elm_config->thumbscroll_friction_standard) ?
2354 at : (1.0 - r) * _elm_config->thumbscroll_friction_standard;
2355 at = ((at / _elm_config->thumbscroll_friction_standard) + r) *
2356 (_elm_config->thumbscroll_friction + sid->down.extra_time);
2358 if (dt > 1.0) dt = 1.0;
2359 p = 1.0 - ((1.0 - dt) * (1.0 - dt));
2361 // TIZEN_ONLY(20150705): Genlist item align feature
2362 if (_elm_config->scroll_item_align_enable)
2364 dx = sid->down.dx * p;
2365 dy = sid->down.dy * p;
2370 dx = (sid->down.dx * (_elm_config->thumbscroll_friction +
2371 sid->down.extra_time) * p);
2372 dy = (sid->down.dy * (_elm_config->thumbscroll_friction +
2373 sid->down.extra_time) * p);
2374 // TIZEN_ONLY(20150705): Genlist item align feature
2379 x = sid->down.sx - dx;
2380 y = sid->down.sy - dy;
2381 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&px, &py));
2382 if ((sid->down.bounce_x_animator) ||
2383 (sid->down.bounce_x_hold))
2385 sid->down.bx = sid->down.bx0 - dx + sid->down.b0x;
2388 if ((sid->down.bounce_y_animator) ||
2389 (sid->down.bounce_y_hold))
2391 sid->down.by = sid->down.by0 - dy + sid->down.b0y;
2394 if (sid->loop_v && y < 0)
2395 y = sid->content_info.h + y;
2397 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
2398 _elm_scroll_wanted_coordinates_update(sid, x, y);
2399 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&maxx, &maxy));
2400 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
2402 if (!_elm_config->thumbscroll_bounce_enable || !sid->bounce_horiz)
2404 if (x <= minx) no_bounce_x_end = EINA_TRUE;
2405 if (!sid->loop_h && (x - minx) >= maxx) no_bounce_x_end = EINA_TRUE;
2407 if (!sid->loop_v && (!_elm_config->thumbscroll_bounce_enable || !sid->bounce_vert))
2409 if (y <= miny) no_bounce_y_end = EINA_TRUE;
2410 if ((y - miny) >= maxy) no_bounce_y_end = EINA_TRUE;
2413 ((sid->down.bounce_x_hold) && (sid->down.bounce_y_hold)) ||
2414 (no_bounce_x_end && no_bounce_y_end))
2416 _elm_scroll_anim_stop(sid);
2418 sid->down.momentum_animator = NULL;
2419 sid->down.bounce_x_hold = EINA_FALSE;
2420 sid->down.bounce_y_hold = EINA_FALSE;
2425 if (sid->content_info.resized)
2426 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
2427 //_elm_scroll_wanted_region_set(sid->obj);
2428 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
2431 return ECORE_CALLBACK_CANCEL;
2435 return ECORE_CALLBACK_RENEW;
2439 _elm_scroll_page_x_get(Elm_Scrollable_Smart_Interface_Data *sid,
2440 int offset, Eina_Bool limit)
2442 Evas_Coord x, y, w, h, dx, cw, ch, minx = 0;
2444 if (!sid->pan_obj) return 0;
2446 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
2447 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
2448 (NULL, NULL, &w, &h));
2449 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&cw, &ch));
2450 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, NULL));
2452 if (sid->pagerel_h > 0.0)
2453 sid->pagesize_h = w * sid->pagerel_h;
2459 dx = (sid->pagesize_h * ((double)sid->page_limit_h - 0.5));
2462 x += (abs(offset) < dx ? offset : dx);
2464 x += (abs(offset) < dx ? offset : -(dx + 1));
2467 if (sid->pagesize_h > 0)
2470 x = x + (sid->pagesize_h * 0.5);
2471 else if (x < 0 && sid->loop_h)
2472 x = x - (sid->pagesize_h * 0.5);
2473 x = x / (sid->pagesize_h);
2474 x = x * (sid->pagesize_h);
2478 if ((x + w) > cw) x = cw - w;
2479 if (x < minx) x = minx;
2486 _elm_scroll_page_y_get(Elm_Scrollable_Smart_Interface_Data *sid,
2487 int offset, Eina_Bool limit)
2489 Evas_Coord x, y, w = 0, h = 0, dy, cw = 0, ch = 0, miny = 0;
2491 if (!sid->pan_obj) return 0;
2493 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
2494 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
2495 (NULL, NULL, &w, &h));
2496 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&cw, &ch));
2497 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(NULL, &miny));
2499 if (sid->pagerel_v > 0.0)
2500 sid->pagesize_v = h * sid->pagerel_v;
2506 dy = (sid->pagesize_v * ((double)sid->page_limit_v - 0.5));
2509 y += (abs(offset) < dy ? offset : dy);
2511 y += (abs(offset) < dy ? offset : -(dy + 1));
2514 if (sid->pagesize_v > 0)
2517 y = y + (sid->pagesize_v * 0.5);
2518 else if (y < 0 && sid->loop_v)
2519 y = y - (sid->pagesize_v * 0.5);
2520 y = y / (sid->pagesize_v);
2521 y = y * (sid->pagesize_v);
2525 if ((y + h) > ch) y = ch - h;
2526 if (y < miny) y = miny;
2533 _elm_scroll_scroll_to_x_animator(void *data)
2535 Elm_Scrollable_Smart_Interface_Data *sid = data;
2541 sid->scrollto.x.animator = NULL;
2542 return ECORE_CALLBACK_CANCEL;
2545 t = ecore_loop_time_get();
2546 tt = (t - sid->scrollto.x.t_start) /
2547 (sid->scrollto.x.t_end - sid->scrollto.x.t_start);
2549 tt = 1.0 - (tt * tt);
2550 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
2551 px = (sid->scrollto.x.start * (1.0 - tt)) +
2552 (sid->scrollto.x.end * tt);
2553 if (t >= sid->scrollto.x.t_end)
2555 px = sid->scrollto.x.end;
2556 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(px, py, EINA_TRUE));
2558 sid->down.x = sid->down.history[0].x;
2560 _elm_scroll_wanted_coordinates_update(sid, px, py);
2561 sid->scrollto.x.animator = NULL;
2562 if ((!sid->scrollto.y.animator) && (!sid->down.bounce_y_animator))
2563 _elm_scroll_anim_stop(sid);
2564 return ECORE_CALLBACK_CANCEL;
2566 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(px, py, EINA_TRUE));
2567 _elm_scroll_wanted_coordinates_update(sid, px, py);
2568 return ECORE_CALLBACK_RENEW;
2572 _elm_scroll_scroll_to_y_animator(void *data)
2574 Elm_Scrollable_Smart_Interface_Data *sid = data;
2578 if (!sid->pan_obj) return EINA_FALSE;
2580 t = ecore_loop_time_get();
2581 tt = (t - sid->scrollto.y.t_start) /
2582 (sid->scrollto.y.t_end - sid->scrollto.y.t_start);
2584 tt = 1.0 - (tt * tt);
2585 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
2587 py = (sid->scrollto.y.start * (1.0 - tt)) +
2588 (sid->scrollto.y.end * tt);
2592 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(NULL, &ch));
2593 if (sid->y_forward_scroll)
2595 py = (sid->scrollto.y.start * (1.0 - tt)) +
2596 (ch + sid->scrollto.y.end)*tt;//works for neg value of y_end also becuase in looping case neg value starts from bottom
2597 if (py > ch) py %= ch; //needed when y_end is positive
2600 py = (sid->scrollto.y.start * (1.0 - tt)) +
2601 (sid->scrollto.y.end * tt);
2603 if (t >= sid->scrollto.y.t_end)
2605 py = sid->scrollto.y.end;
2606 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(px, py, EINA_TRUE));
2608 sid->down.y = sid->down.history[0].y;
2610 sid->y_forward_scroll = EINA_FALSE;
2611 _elm_scroll_wanted_coordinates_update(sid, px, py);
2612 sid->scrollto.y.animator = NULL;
2613 if ((!sid->scrollto.x.animator) && (!sid->down.bounce_x_animator))
2614 _elm_scroll_anim_stop(sid);
2615 return ECORE_CALLBACK_CANCEL;
2617 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(px, py, EINA_TRUE));
2618 _elm_scroll_wanted_coordinates_update(sid, px, py);
2620 return ECORE_CALLBACK_RENEW;
2624 _elm_scroll_scroll_to_y(Elm_Scrollable_Smart_Interface_Data *sid,
2628 Evas_Coord px = 0, py = 0, x, y, w, h;
2631 if (!sid->pan_obj) return;
2633 if (sid->freeze) return;
2636 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
2637 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
2638 (NULL, NULL, &w, &h));
2640 eo_do(sid->obj, elm_interface_scrollable_content_region_set(x, y, w, h));
2643 t = ecore_loop_time_get();
2644 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
2645 sid->scrollto.y.start = py;
2646 sid->scrollto.y.end = pos_y;
2647 sid->scrollto.y.t_start = t;
2648 sid->scrollto.y.t_end = t + t_in;
2649 //PRODUCT_ONLY(20181105): bring_in animation should happen
2652 Evas_Coord ch = 0, for_dist = 0, back_dist = 0;
2653 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(NULL, &ch));
2654 back_dist = abs(sid->scrollto.y.end - sid->scrollto.y.start);
2655 if (sid->scrollto.y.end < 0)
2656 for_dist = abs((ch + sid->scrollto.y.end) - sid->scrollto.y.start);
2658 for_dist = abs(ch - sid->scrollto.y.start) + sid->scrollto.y.end;
2659 if (for_dist <= back_dist)
2660 sid->y_forward_scroll = EINA_TRUE;
2662 sid->y_forward_scroll = EINA_FALSE;
2664 if (!sid->scrollto.y.animator)
2666 sid->scrollto.y.animator =
2667 ecore_animator_add(_elm_scroll_scroll_to_y_animator, sid);
2668 if (!sid->scrollto.x.animator)
2669 _elm_scroll_anim_start(sid);
2671 if (sid->down.bounce_y_animator)
2673 ELM_SAFE_FREE(sid->down.bounce_y_animator, ecore_animator_del);
2674 _elm_scroll_momentum_end(sid);
2675 if (sid->content_info.resized)
2676 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
2677 //_elm_scroll_wanted_region_set(sid->obj);
2678 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
2681 sid->bouncemey = EINA_FALSE;
2685 _elm_scroll_scroll_to_x(Elm_Scrollable_Smart_Interface_Data *sid,
2689 Evas_Coord px = 0, py = 0, x, y, w, h;
2692 if (!sid->pan_obj) return;
2694 if (sid->freeze) return;
2697 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
2698 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
2699 (NULL, NULL, &w, &h));
2701 eo_do(sid->obj, elm_interface_scrollable_content_region_set
2705 t = ecore_loop_time_get();
2706 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
2707 sid->scrollto.x.start = px;
2708 sid->scrollto.x.end = pos_x;
2709 sid->scrollto.x.t_start = t;
2710 sid->scrollto.x.t_end = t + t_in;
2711 if (!sid->scrollto.x.animator)
2713 sid->scrollto.x.animator =
2714 ecore_animator_add(_elm_scroll_scroll_to_x_animator, sid);
2715 if (!sid->scrollto.y.animator)
2716 _elm_scroll_anim_start(sid);
2718 if (sid->down.bounce_x_animator)
2720 ELM_SAFE_FREE(sid->down.bounce_x_animator, ecore_animator_del);
2721 _elm_scroll_momentum_end(sid);
2722 if (sid->content_info.resized)
2723 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
2724 //_elm_scroll_wanted_region_set(sid->obj);
2725 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
2728 sid->bouncemex = EINA_FALSE;
2732 _elm_scroll_mouse_up_event_cb(void *data,
2734 Evas_Object *obj EINA_UNUSED,
2737 Elm_Scrollable_Smart_Interface_Data *sid = data;
2738 Evas_Coord x = 0, y = 0, ox = 0, oy = 0;
2739 Evas_Event_Mouse_Up *ev;
2741 if (!sid->pan_obj) return;
2743 if ((sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL) &&
2744 (sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
2748 if (_elm_scroll_smooth_debug) _elm_scroll_smooth_debug_shutdown();
2752 sid->down.hold_parent = EINA_FALSE;
2755 evas_post_event_callback_push(e, _elm_scroll_post_event_up, sid);
2757 // FIXME: respect elm_widget_scroll_hold_get of parent container
2758 if (!_elm_config->thumbscroll_enable) return;
2760 if (ev->button == 1)
2762 // TIZEN_ONLY(20160624): Overscroll effect
2763 edje_object_signal_emit(sid->edje_obj, "elm,state,mouse,up", "elm");
2765 if (sid->down.onhold_animator)
2767 ELM_SAFE_FREE(sid->down.onhold_animator, ecore_animator_del);
2768 if (sid->content_info.resized)
2769 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
2770 //_elm_scroll_wanted_region_set(sid->obj);
2771 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
2774 x = ev->canvas.x - sid->down.x;
2775 y = ev->canvas.y - sid->down.y;
2776 if (sid->down.dragged)
2778 _elm_scroll_drag_stop(sid);
2779 if ((!sid->hold) && (!sid->freeze))
2783 Evas_Coord ax, ay, dx, dy, vel;
2786 t = ev->timestamp / 1000.0;
2788 t = ecore_loop_time_get();
2791 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2796 DBG("------ %i %i\n", ev->canvas.x, ev->canvas.y);
2798 for (i = 0; i < 60; i++)
2800 dt = t - sid->down.history[i].timestamp;
2801 if (dt > 0.2) break;
2803 DBG("H: %i %i @ %1.3f\n",
2804 sid->down.history[i].x,
2805 sid->down.history[i].y, dt);
2808 ax += sid->down.history[i].x;
2809 ay += sid->down.history[i].y;
2814 at /= _elm_config->thumbscroll_sensitivity_friction;
2815 dx = ev->canvas.x - ax;
2816 dy = ev->canvas.y - ay;
2819 vel = sqrt((dx * dx) + (dy * dy)) / at;
2820 if ((_elm_config->thumbscroll_friction > 0.0) &&
2821 (vel > _elm_config->thumbscroll_momentum_threshold))
2824 int minx, miny, mx, my, px, py;
2825 double tt = 0.0, dtt = 0.0;
2827 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get
2829 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get
2831 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
2832 max_d = _elm_config->thumbscroll_flick_distance_tolerance;
2835 if (dx > max_d) dx = max_d;
2836 sid->down.dx = (sin((M_PI * (double)dx / max_d)
2837 - (M_PI / 2)) + 1) * max_d / at;
2841 if (dx < -max_d) dx = -max_d;
2842 sid->down.dx = (sin((M_PI * (double)dx / max_d)
2843 + (M_PI / 2)) - 1) * max_d / at;
2847 if (dy > max_d) dy = max_d;
2848 sid->down.dy = (sin((M_PI * (double)dy / max_d)
2849 - (M_PI / 2)) + 1) * max_d / at;
2853 if (dy < -max_d) dy = -max_d;
2854 sid->down.dy = (sin((M_PI * (double)dy / max_d)
2855 + (M_PI / 2)) - 1) * max_d / at;
2857 if (((sid->down.dx > 0) && (sid->down.pdx > 0)) ||
2858 ((sid->down.dx < 0) && (sid->down.pdx < 0)) ||
2859 ((sid->down.dy > 0) && (sid->down.pdy > 0)) ||
2860 ((sid->down.dy < 0) && (sid->down.pdy < 0)))
2862 tt = ecore_loop_time_get();
2863 dtt = tt - sid->down.anim_start;
2865 if (dtt < 0.0) dtt = 0.0;
2867 _elm_config->thumbscroll_friction)
2868 dtt = _elm_config->thumbscroll_friction;
2869 sid->down.extra_time =
2870 _elm_config->thumbscroll_friction - dtt;
2873 sid->down.extra_time = 0.0;
2875 if (abs(sid->down.dx) > _elm_config->thumbscroll_acceleration_threshold &&
2876 (dtt < _elm_config->thumbscroll_acceleration_time_limit) &&
2877 (((sid->down.dx > 0) && (sid->down.pdx > 0)) ||
2878 ((sid->down.dx < 0) && (sid->down.pdx < 0))))
2879 if (px > minx && px < mx)
2880 sid->down.dx += (double)sid->down.pdx * _elm_config->thumbscroll_acceleration_weight;
2881 if (abs(sid->down.dy) > _elm_config->thumbscroll_acceleration_threshold &&
2882 (dtt < _elm_config->thumbscroll_acceleration_time_limit) &&
2883 (((sid->down.dy > 0) && (sid->down.pdy > 0)) ||
2884 ((sid->down.dy < 0) && (sid->down.pdy < 0))))
2885 if (py > miny && py < my)
2887 sid->down.dy += (double)sid->down.pdy * _elm_config->thumbscroll_acceleration_weight;
2890 // TIZEN_ONLY(20150705): Genlist item align feature
2891 if (_elm_config->scroll_item_align_enable)
2893 Evas_Coord pos_x, pos_y;
2895 pos_x = sid->down.dx;
2896 pos_y = sid->down.dy;
2898 pos_x = _round(pos_x * (_elm_config->thumbscroll_friction +
2899 sid->down.extra_time), 0);
2900 pos_y = _round(pos_y * (_elm_config->thumbscroll_friction +
2901 sid->down.extra_time), 0);
2904 if ((px - pos_x) > mx)
2909 if ((px - pos_x) < minx)
2916 if ((py - pos_y) > my)
2921 if ((py - pos_y) < miny)
2925 //PRODUCT_ONLY(20181115): scroll distance have to be less than content size
2926 else if (sid->loop_v && abs(pos_y) > sid->content_info.h)
2928 Evas_Coord final_pos_y = pos_y % sid->content_info.h;
2930 pos_y = final_pos_y;
2932 pos_y = -final_pos_y;
2936 eo_do(sid->pan_obj, elm_obj_pan_pos_adjust(&pos_x, &pos_y));
2938 //PRODUCT_ONLY(20181511): take the direction of flick always for scroll in loop case
2941 if (pos_y > 0 && dy < 0)
2942 pos_y = pos_y - sid->content_info.h;
2943 else if (pos_y < 0 && dy > 0)
2944 pos_y = sid->content_info.h + pos_y;
2947 // adjusted position using to _elm_scroll_momentum_animator()
2948 sid->down.dx = pos_x;
2949 sid->down.dy = pos_y;
2953 sid->down.pdx = sid->down.dx;
2954 sid->down.pdy = sid->down.dy;
2957 if (!_paging_is_enabled(sid))
2959 if ((!sid->down.momentum_animator) &&
2960 (!sid->momentum_animator_disabled) &&
2962 (!elm_widget_drag_child_locked_y_get
2965 sid->down.momentum_animator =
2967 (_elm_scroll_momentum_animator, sid);
2969 EVAS_EVENT_FLAG_ON_SCROLL;
2970 _elm_scroll_anim_start(sid);
2972 sid->down.anim_start = ecore_loop_time_get();
2974 elm_interface_scrollable_content_pos_get(&x, &y));
2981 // TIZEN_ONLY(20150705): Genlist item align feature
2984 if (_elm_config->scroll_item_align_enable)
2986 Evas_Coord pos_x = 0, pos_y = 0;
2987 Evas_Coord adjust_x, adjust_y;
2989 eo_do(sid->pan_obj, elm_obj_pan_pos_adjust(&pos_x, &pos_y));
2991 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&adjust_x, &adjust_y));
2995 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, adjust_y);
3001 if (_elm_config->scroll_item_align_enable)
3003 Evas_Coord pos_x = 0, pos_y = 0;
3004 Evas_Coord adjust_x, adjust_y;
3006 eo_do(sid->pan_obj, elm_obj_pan_pos_adjust(&pos_x, &pos_y));
3008 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&adjust_x, &adjust_y));
3012 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, adjust_y);
3022 evas_event_feed_hold(e, 0, ev->timestamp, ev->data);
3023 if (_paging_is_enabled(sid))
3025 Evas_Coord pgx, pgy;
3027 eo_do(sid->obj, elm_interface_scrollable_content_pos_get
3030 (!elm_widget_drag_child_locked_x_get
3033 pgx = _elm_scroll_page_x_get(sid, ox, EINA_TRUE);
3036 ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
3038 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
3039 _elm_scroll_scroll_to_x
3040 (sid, _elm_config->page_scroll_friction, pgx);
3044 (!elm_widget_drag_child_locked_y_get
3047 pgy = _elm_scroll_page_y_get(sid, oy, EINA_TRUE);
3050 ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL))
3052 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
3053 _elm_scroll_scroll_to_y
3054 (sid, _elm_config->page_scroll_friction, pgy);
3063 if (_paging_is_enabled(sid))
3065 Evas_Coord pgx, pgy;
3067 eo_do(sid->obj, elm_interface_scrollable_content_pos_get
3070 (!elm_widget_drag_child_locked_x_get
3073 pgx = _elm_scroll_page_x_get(sid, ox, EINA_TRUE);
3075 _elm_scroll_scroll_to_x
3076 (sid, _elm_config->page_scroll_friction, pgx);
3079 (!elm_widget_drag_child_locked_y_get
3082 pgy = _elm_scroll_page_y_get(sid, oy, EINA_TRUE);
3084 _elm_scroll_scroll_to_y
3085 (sid, _elm_config->page_scroll_friction, pgy);
3089 if (sid->down.hold_animator)
3091 ELM_SAFE_FREE(sid->down.hold_animator, ecore_animator_del);
3092 if (sid->content_info.resized)
3093 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
3094 //_elm_scroll_wanted_region_set(sid->obj);
3095 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
3098 if (sid->down.scroll)
3100 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
3101 sid->down.scroll = EINA_FALSE;
3105 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3106 sid->down.hold = EINA_FALSE;
3108 sid->down.dragged_began = EINA_FALSE;
3109 sid->down.dir_x = EINA_FALSE;
3110 sid->down.dir_y = EINA_FALSE;
3111 sid->down.want_dragged = EINA_FALSE;
3112 sid->down.dragged = EINA_FALSE;
3113 sid->down.now = EINA_FALSE;
3114 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
3115 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
3116 _elm_scroll_wanted_coordinates_update(sid, x, y);
3118 if (sid->content_info.resized)
3119 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
3120 //_elm_scroll_wanted_region_set(sid->obj);
3121 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
3124 if (!_paging_is_enabled(sid))
3125 _elm_scroll_bounce_eval(sid);
3127 //TIZEN_ONLY(20190219): fix page snap behavior.
3128 if (sid->scrolling && !sid->down.momentum_animator &&
3129 !sid->down.bounce_x_animator && !sid->down.bounce_y_animator &&
3130 !sid->scrollto.x.animator && !sid->scrollto.y.animator)
3131 _elm_scroll_scroll_stop(sid);
3138 _elm_scroll_mouse_down_event_cb(void *data,
3139 Evas *e EINA_UNUSED,
3140 Evas_Object *obj EINA_UNUSED,
3143 Elm_Scrollable_Smart_Interface_Data *sid;
3144 Evas_Event_Mouse_Down *ev;
3145 Evas_Coord x = 0, y = 0;
3150 if ((sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL) &&
3151 (sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
3155 if (getenv("ELS_SCROLLER_SMOOTH_DEBUG")) _elm_scroll_smooth_debug = 1;
3156 if (_elm_scroll_smooth_debug) _elm_scroll_smooth_debug_init();
3159 if (!_elm_config->thumbscroll_enable) return;
3162 sid->down.hold = EINA_FALSE;
3163 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
3164 (sid->down.momentum_animator) || (sid->scrollto.x.animator) ||
3165 (sid->scrollto.y.animator))
3167 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL |
3168 EVAS_EVENT_FLAG_ON_HOLD;
3169 sid->down.scroll = EINA_TRUE;
3170 sid->down.hold = EINA_TRUE;
3171 _elm_scroll_anim_stop(sid);
3173 ELM_SAFE_FREE(sid->scrollto.x.animator, ecore_animator_del);
3174 ELM_SAFE_FREE(sid->scrollto.y.animator, ecore_animator_del);
3175 if (sid->down.bounce_x_animator)
3177 ELM_SAFE_FREE(sid->down.bounce_x_animator, ecore_animator_del);
3178 sid->bouncemex = EINA_FALSE;
3179 if (sid->content_info.resized)
3180 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
3181 //_elm_scroll_wanted_region_set(sid->obj);
3182 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
3185 if (sid->down.bounce_y_animator)
3187 ELM_SAFE_FREE(sid->down.bounce_y_animator, ecore_animator_del);
3188 sid->bouncemey = EINA_FALSE;
3189 if (sid->content_info.resized)
3190 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
3191 //_elm_scroll_wanted_region_set(sid->obj);
3192 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
3195 if (sid->down.hold_animator)
3197 ELM_SAFE_FREE(sid->down.hold_animator, ecore_animator_del);
3198 _elm_scroll_drag_stop(sid);
3199 if (sid->content_info.resized)
3200 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
3201 //_elm_scroll_wanted_region_set(sid->obj);
3202 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
3205 if (sid->down.momentum_animator)
3207 ELM_SAFE_FREE(sid->down.momentum_animator, ecore_animator_del);
3208 sid->down.bounce_x_hold = EINA_FALSE;
3209 sid->down.bounce_y_hold = EINA_FALSE;
3212 if (sid->content_info.resized)
3213 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
3214 //_elm_scroll_wanted_region_set(sid->obj);
3215 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
3218 if (ev->button == 1)
3220 // TIZEN_ONLY(20160624): Overscroll effect
3221 edje_object_signal_emit(sid->edje_obj, "elm,state,mouse,down", "elm");
3223 sid->down.hist.est_timestamp_diff =
3224 ecore_loop_time_get() - ((double)ev->timestamp / 1000.0);
3225 sid->down.hist.tadd = 0.0;
3226 sid->down.hist.dxsum = 0.0;
3227 sid->down.hist.dysum = 0.0;
3228 sid->down.now = EINA_TRUE;
3229 sid->down.dragged = EINA_FALSE;
3230 sid->down.dir_x = EINA_FALSE;
3231 sid->down.dir_y = EINA_FALSE;
3232 sid->down.x = ev->canvas.x;
3233 sid->down.y = ev->canvas.y;
3234 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
3237 sid->down.locked = EINA_FALSE;
3238 memset(&(sid->down.history[0]), 0,
3239 sizeof(sid->down.history[0]) * 60);
3241 sid->down.history[0].timestamp = ev->timestamp / 1000.0;
3242 sid->down.history[0].localtimestamp = ecore_loop_time_get();
3244 sid->down.history[0].timestamp = ecore_loop_time_get();
3246 sid->down.dragged_began_timestamp = sid->down.history[0].timestamp;
3247 sid->down.history[0].x = ev->canvas.x;
3248 sid->down.history[0].y = ev->canvas.y;
3250 sid->down.dragged_began = EINA_FALSE;
3251 sid->down.hold_parent = EINA_FALSE;
3252 sid->down.cancelled = EINA_FALSE;
3253 if (sid->hold || sid->freeze)
3254 sid->down.want_reset = EINA_TRUE;
3256 sid->down.want_reset = EINA_FALSE;
3260 _elm_scroll_can_scroll(Elm_Scrollable_Smart_Interface_Data *sid,
3263 Evas_Coord mx = 0, my = 0, px = 0, py = 0, minx = 0, miny = 0;
3265 if (!sid->pan_obj) return EINA_FALSE;
3267 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
3268 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
3269 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
3273 if (px > minx) return EINA_TRUE;
3277 if ((px - minx) < mx) return EINA_TRUE;
3281 if (py > miny) return EINA_TRUE;
3285 if ((py - miny) < my) return EINA_TRUE;
3295 _elm_scroll_post_event_move(void *data,
3296 Evas *e EINA_UNUSED)
3298 Elm_Scrollable_Smart_Interface_Data *sid = data;
3299 Eina_Bool horiz, vert;
3302 if (!sid->down.want_dragged) return EINA_TRUE;
3304 elm_widget_parents_bounce_get(sid->obj, &horiz, &vert);
3305 if (sid->down.hold_parent)
3307 if ((sid->down.dir_x) && (horiz || !sid->bounce_horiz) &&
3308 !_elm_scroll_can_scroll(sid, sid->down.hdir))
3310 sid->down.dir_x = EINA_FALSE;
3312 if ((sid->down.dir_y) && (vert || !sid->bounce_vert) &&
3313 !_elm_scroll_can_scroll(sid, sid->down.vdir))
3315 sid->down.dir_y = EINA_FALSE;
3317 sid->down.dragged_began = EINA_TRUE;
3319 if (sid->down.dir_x)
3322 (!elm_widget_drag_child_locked_x_get(sid->obj)))
3324 if (sid->down.dragged_began)
3326 sid->down.want_dragged = EINA_FALSE;
3327 sid->down.dragged = EINA_TRUE;
3330 elm_widget_drag_lock_x_set(sid->obj, 1);
3337 sid->down.dragged_began = EINA_TRUE;
3338 sid->down.dir_x = EINA_FALSE;
3341 if (sid->down.dir_y)
3344 (!elm_widget_drag_child_locked_y_get(sid->obj)))
3346 if (sid->down.dragged_began)
3348 sid->down.want_dragged = EINA_FALSE;
3349 sid->down.dragged = EINA_TRUE;
3352 elm_widget_drag_lock_y_set
3353 (sid->obj, EINA_TRUE);
3360 sid->down.dragged_began = EINA_TRUE;
3361 sid->down.dir_y = EINA_FALSE;
3364 if ((!sid->down.dir_x) && (!sid->down.dir_y))
3366 sid->down.cancelled = EINA_TRUE;
3368 if (start) _elm_scroll_drag_start(sid);
3374 // TIZEN_ONLY(20161125): Limit coordination when there is just one page
3376 _elm_scroll_down_coord_limit(Elm_Scrollable_Smart_Interface_Data *sid,
3380 Evas_Coord w = 0, h = 0;
3382 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &w, &h);
3385 ((*x + sid->content_info.w) % sid->content_info.w - w < 0) &&
3386 ((*x + sid->content_info.w) % sid->content_info.w + w > sid->content_info.w))
3389 ((*y + sid->content_info.h) % sid->content_info.h - h < 0) &&
3390 ((*y + sid->content_info.h) % sid->content_info.h + h > sid->content_info.h))
3396 _elm_scroll_down_coord_eval(Elm_Scrollable_Smart_Interface_Data *sid,
3400 Evas_Coord minx, miny;
3402 if (!sid->pan_obj) return;
3404 if (sid->down.dir_x) *x = sid->down.sx - (*x - sid->down.x);
3405 else *x = sid->down.sx;
3406 if (sid->down.dir_y) *y = sid->down.sy - (*y - sid->down.y);
3407 else *y = sid->down.sy;
3409 if ((sid->down.dir_x) || (sid->down.dir_y))
3411 if (!((sid->down.dir_x) && (sid->down.dir_y)))
3413 if (sid->down.dir_x) *y = sid->down.locked_y;
3414 else *x = sid->down.locked_x;
3418 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
3420 if (!sid->loop_h && *x < minx)
3421 *x += (minx - *x) * _elm_config->thumbscroll_border_friction;
3422 else if (!sid->loop_h && sid->content_info.w <= sid->w)
3423 *x += (sid->down.sx - *x) * _elm_config->thumbscroll_border_friction;
3424 else if (!sid->loop_h && (sid->content_info.w - sid->w + minx) < *x)
3425 *x += (sid->content_info.w - sid->w + minx - *x) *
3426 _elm_config->thumbscroll_border_friction;
3428 if (!sid->loop_v && *y < miny)
3429 *y += (miny - *y) * _elm_config->thumbscroll_border_friction;
3430 else if (!sid->loop_v && sid->content_info.h <= sid->h)
3431 *y += (sid->down.sy - *y) * _elm_config->thumbscroll_border_friction;
3432 else if (!sid->loop_v && (sid->content_info.h - sid->h + miny) < *y)
3433 *y += (sid->content_info.h - sid->h + miny - *y) *
3434 _elm_config->thumbscroll_border_friction;
3436 // TIZEN_ONLY(20161125): Limit coordination when there is just one page
3437 _elm_scroll_down_coord_limit(sid, x, y);
3441 //TIZEN ONLY : for scroll smooth algorithm
3442 #define iround(x) ((x)>=0?(int)((x)+0.5):(int)((x)-0.5))
3444 //> Frequency of move events
3445 #define ELM_MOVE_PER_SECOND (90.75f)
3446 //>Time between two subsequent events
3447 static const float ELM_MOVE_TIMEOUT = (1.0f/ELM_MOVE_PER_SECOND);
3449 //>Quantity of move events in time interval
3450 #define ELM_MOVE_COUNT(t) iround((t)*ELM_MOVE_PER_SECOND)
3452 //>Getting coordinate (x is 0, y is 1) from struct Elm_Scroll_Pos or Elm_Scroll_History_Item.
3453 #define ELM_GET_COORD(p, coord) (*((int *)p + coord))
3455 //>Difference of coordinates of points with indexes ind and ind+inc.
3456 #define ELM_DIFF(p, coord, ind, inc) (ELM_GET_COORD((p + ind), coord) - ELM_GET_COORD((p + ind + inc), coord))
3458 //>Index in array for calculation of smoothed velocity.
3459 #define ELM_SMOOTH_SPEED_INDEX 9
3461 //>in seconds, includes driver to X time gap
3462 #define EXTRA_PREDIOCTION_TIME (-0.005)
3464 //>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).
3465 //>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
3466 //>The index ELM_SMOOTH_SPEED_INDEX is replaced by 1.
3467 double _elm_scroll_get_v(Elm_Scroll_Pos *pos, int num, int coord,
3468 double *dt, int *pdiff, double *padt, Elm_Scroll_Predict *predict)
3471 int nmeasure_idx = (num > ELM_SMOOTH_SPEED_INDEX) ? ELM_SMOOTH_SPEED_INDEX : (num -1);
3472 // a recent input takes higher priority
3473 #if USE_HISTORY_WEIGHT
3474 if (nmeasure_idx >= 2)
3475 *pdiff = (ELM_DIFF(pos, coord, 0, 1) * 2 + ELM_DIFF(pos, coord, 1, 1))/3;
3478 *pdiff = ELM_DIFF(pos, coord, 0, 1);
3481 #if ADJUST_EVENT_TIME
3482 *dt = -ELM_MOVE_TIMEOUT;
3484 if (nmeasure_idx >= 2)
3485 *dt = -(pos[2].t - pos[0].t)/2.;
3487 *dt = -(pos[1].t - pos[0].t);
3490 *dt = -ELM_MOVE_TIMEOUT;
3492 predict->k[coord] = 0;
3493 *padt = EXTRA_PREDIOCTION_TIME;
3499 _elm_scroll_get_pos(Elm_Scrollable_Smart_Interface_Data *sid,
3500 Elm_Scroll_Pos *pos, int num, int *fx, int *fy)
3502 double vx = 0, vy = 0, dt = 0, dtx = 0, dty = 0;
3510 *fx = iround((double)pos[0].x);
3511 *fy = iround((double)pos[0].y);
3516 if (sid->down.dir_y)
3517 vy = _elm_scroll_get_v(pos, num, 1, &dt, &diffy, &dty, &sid->down.predict);
3518 if (sid->down.dir_x)
3519 vx = _elm_scroll_get_v(pos, num, 0, &dt, &diffx, &dtx, &sid->down.predict);
3522 if (sid->down.dir_x)
3524 *fx = iround((double)pos[0].x - (pos[0].t + dtx) * vx);
3525 // don't go back even though over-run is detected.
3526 if (sid->down.anim_vx_prev && sid->down.anim_vx_prev * vx >= 0)
3527 if (vx == 0 || (vx > 0 && *fx > sid->down.anim_x_prev) ||
3528 (vx < 0 && *fx < sid->down.anim_x_prev))
3529 *fx = sid->down.anim_x_prev;
3532 if (sid->down.dir_y)
3534 *fy = iround((double)pos[0].y - (pos[0].t + dty) * vy);
3535 // don't go back even though over-run is detected.
3536 if (sid->down.anim_vy_prev && sid->down.anim_vy_prev * vy >= 0)
3537 if (vy == 0 || (vy > 0 && *fy > sid->down.anim_y_prev) ||
3538 (vy < 0 && *fy < sid->down.anim_y_prev))
3539 *fy = sid->down.anim_y_prev;
3542 sid->down.anim_x_prev = *fx;
3543 sid->down.anim_y_prev = *fy;
3544 sid->down.anim_vx_prev = vx;
3545 sid->down.anim_vy_prev = vy;
3550 #define COMPENSATE_FOR_INITIAL_RENDER_DELAY 0
3551 #define ADJUST_ANIMATOR_TIMING 0
3552 #define SMART_SMOOTH_START 1
3553 #define HOLD_ANIMATOR_DEBUG_LEVEL1 0
3554 #define HOLD_ANIMATOR_DEBUG_LEVEL2 0
3555 #define HOLD_ANIMATOR_DEBUG_X_AXIS 1
3556 #define ADJUST_EVENT_TIME 0
3557 #define USE_HISTORY_WEIGHT 0
3558 #define USE_LOOP_TIME 1
3559 #define PREDICT_WHEN_PAUSED 0
3562 _elm_scroll_hold_animator(void *data)
3564 Elm_Scrollable_Smart_Interface_Data *sid = data;
3565 Evas_Coord ox = 0, oy = 0, fx = 0, fy = 0, x = 0, y = 0, num = 0;
3566 Evas_Coord fx_coord = 0, fy_coord = 0;
3567 fx = sid->down.hold_x;
3568 fy = sid->down.hold_y;
3569 fx_coord = sid->down.anim_x_coord_prev;
3570 fy_coord = sid->down.anim_y_coord_prev;
3571 #define QUEUE_SIZE 3 /* for event queue size */
3572 Elm_Scroll_Pos pos[QUEUE_SIZE];
3574 double now, now_diff, prev;
3575 double animators_frametime = 0;
3577 sid->down.anim_count++;
3579 #if COMPENSATE_FOR_INITIAL_RENDER_DELAY
3580 Ecore_Animator_Source source = ecore_animator_source_get();
3583 // FIXME: assume server and client have the same "timezone"
3584 // (0 timepoint) for now. this needs to be figured out in advance
3587 now = ecore_loop_time_get();
3589 now = ecore_time_get();
3592 // init variables for the first animator run
3593 if (sid->down.anim_count == 1)
3595 sid->down.anim_t_prev = now;
3596 sid->down.anim_x_coord_prev = fx;
3597 sid->down.anim_y_coord_prev = fy;
3601 prev = sid->down.anim_t_prev;
3602 now_diff = now - prev;
3603 animators_frametime = ecore_animator_frametime_get();
3604 #if COMPENSATE_FOR_INITIAL_RENDER_DELAY
3605 if (sid->down.anim_count == 1)
3607 if (source != ECORE_ANIMATOR_SOURCE_CUSTOM)
3608 sid->down.anim_t_delay = fmod(now, animators_frametime);
3613 sid->down.anim_t_delay += now_diff - animators_frametime;
3616 // skip this turn if specified.
3617 if (sid->down.anim_skip > 0)
3619 sid->down.anim_skip--;
3620 #if HOLD_ANIMATOR_DEBUG_LEVEL1
3621 DBG("[%03d/%s] %.4f %.3f/%.3f dt:%.3f = %.3f%+.3f ev: %.4f skip(%d)\n",
3622 sid->down.anim_count, (source == ECORE_ANIMATOR_SOURCE_CUSTOM) ? "V" : "T",
3623 now, sid->down.anim_t_delay * 1000, sid->down.anim_t_adjusted * 1000,
3625 (now_diff - d)*1000,
3627 sid->down.history[0].timestamp,
3628 sid->down.anim_skip);
3630 if ((now_diff * 1000) > 18)
3632 #if ADJUST_ANIMATOR_TIMING
3633 sid->down.anim_t_dont_adjust = 1;
3635 goto update_time_and_quit;
3639 // We don't need to process old events again.
3640 if (sid->down.anim_count != 1 &&
3641 sid->down.anim_pos_t_prev == sid->down.history[0].timestamp)
3643 #if HOLD_ANIMATOR_DEBUG_LEVEL1
3644 DBG("[%03d/%s] %.4f %.3f/%.3f dt:%.3f = %.3f%+.3f ev:%.4f skip(%d) no events.\n",
3645 sid->down.anim_count, (source == ECORE_ANIMATOR_SOURCE_CUSTOM) ? "V" : "T",
3646 now, sid->down.anim_t_delay * 1000, sid->down.anim_t_adjusted * 1000,
3648 (now_diff - d)*1000,
3650 sid->down.history[0].timestamp,
3651 sid->down.anim_skip);
3654 goto update_time_and_quit;
3657 #if ADJUST_ANIMATOR_TIMING
3658 if (sid->down.anim_count != 1 && !sid->down.anim_t_dont_adjust)
3660 if (now_diff < animators_frametime*3/4)
3662 d += animators_frametime/4;
3664 else if (now_diff < animators_frametime)
3666 d = animators_frametime - now_diff;
3668 else if (now_diff < animators_frametime*5/4)
3670 d = -(now_diff - animators_frametime);
3674 d = -animators_frametime/4;
3679 sid->down.anim_t_adjusted += d;
3682 sid->down.anim_t_dont_adjust = 0;
3686 #if COMPENSATE_FOR_INITIAL_RENDER_DELAY
3687 // in case the first animator is called manually to make up for gpu's wake-up time,
3688 // then the second animator should be skipped.
3689 if ((sid->down.anim_count == 1) && (sid->down.anim_skip <= 0))
3690 sid->down.anim_skip++;
3693 if ((!sid->hold) && (!sid->freeze))
3696 int ncur_diff_x=0, ncur_diff_y=0;
3697 int nprev_diff_x=0, nprev_diff_y=0;
3699 for (i = 0; i < QUEUE_SIZE; i++)
3701 if (sid->down.history[i].timestamp >=
3702 sid->down.dragged_began_timestamp)
3704 x = sid->down.history[i].x;
3705 y = sid->down.history[i].y;
3707 //if there is no history value, we don't deal with it if
3708 //there is better wat to know existance of history value
3709 //, I will modify this code to it
3710 if ((x == 0) && (y == 0))
3717 pos[i].t = now - sid->down.history[i].timestamp;
3723 // get rid of histories with different move direction.
3724 if (sid->down.dir_x)
3725 ncur_diff_x = pos[i].x - pos[i-1].x;
3726 if (sid->down.dir_y)
3727 ncur_diff_y = pos[i].y - pos[i-1].y;
3729 if (ncur_diff_x * nprev_diff_x < 0 || ncur_diff_y * nprev_diff_y < 0)
3732 #if HOLD_ANIMATOR_DEBUG_LEVEL2
3733 DBG("[%03d] i=%d a dir change detected. stopped.\n",
3734 sid->down.anim_count, i);
3739 nprev_diff_x = ncur_diff_x;
3740 nprev_diff_y = ncur_diff_y;
3742 #if ADJUST_EVENT_TIME
3743 //> a event is delayed??
3744 if (ELM_MOVE_COUNT(pos[i].t - pos[i-1].t) <= 0)
3746 DBG("[%03d] i=%d a event is delayed (%f) ??????????????????\n",
3747 sid->down.anim_count,
3748 i, pos[i].t - pos[i-1].t);
3751 //> a pause in movement detected
3752 if (ELM_MOVE_COUNT(pos[i].t - pos[i-1].t) >= 2)
3754 #if HOLD_ANIMATOR_DEBUG_LEVEL2
3755 DBG("[%03d] i=%d a pause(%f) in movement detected. stopped.\n",
3756 sid->down.anim_count, i, pos[i].t - pos[i-1].t);
3758 #if PREDICT_WHEN_PAUSED
3759 pos[i].t = pos[i-1].t + ELM_MOVE_TIMEOUT;
3769 #if ADJUST_EVENT_TIME
3770 // X server fills in time in milisecond order and it rounds off.
3771 // let's makt it more precise and this is proven by machine moving at constant speed.
3772 //double pos_diff = 0;
3775 //double tmp = sid->down.history[0].timestamp;
3776 for (i = num - 1; i >= 1; i--)
3778 pos[i-1].t = pos[i].t - ELM_MOVE_TIMEOUT;
3779 sid->down.history[i-1].timestamp = now - pos[i-1].t;
3781 //pos_diff = sid->down.history[0].timestamp - tmp;
3785 sid->down.anim_pos_t_prev = sid->down.history[0].timestamp;
3787 //TIZEN ONLY : for scroll smooth algorithm
3788 _elm_scroll_get_pos(sid, pos, num, &fx, &fy);
3792 _elm_scroll_down_coord_eval(sid, &fx_coord, &fy_coord);
3796 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&ox, &oy));
3797 if (sid->down.dir_x)
3800 (!elm_widget_drag_child_locked_x_get(sid->obj)))
3805 if (sid->down.dir_y)
3808 (!elm_widget_drag_child_locked_y_get(sid->obj)))
3815 if (_elm_scroll_smooth_debug)
3816 _elm_scroll_smooth_debug_movetime_add(ox, oy);
3819 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(ox, oy, EINA_TRUE));
3820 ERR("[DDO] ox(%d), oy(%d)", ox, oy);
3822 #if HOLD_ANIMATOR_DEBUG_LEVEL1
3823 #if HOLD_ANIMATOR_DEBUG_X_AXIS
3824 DBG("[%03d/%s] %.4f %.3f/%.3f dt:%.3f = %.3f%+.3f ev:%02d %3.4f/%+.3f p:%d(%d) = %d%+d %d %d\n",
3825 sid->down.anim_count, (source == ECORE_ANIMATOR_SOURCE_CUSTOM) ? "V" : "T",
3826 now, sid->down.anim_t_delay * 1000, sid->down.anim_t_adjusted * 1000,
3828 (now_diff - d)*1000,
3830 num, sid->down.history[0].timestamp, pos_diff*1000,
3832 sid->down.hold_x, ox - sid->down.hold_x,
3833 ox - sid->down.anim_x_coord_prev,
3834 (int)sid->down.anim_vx_prev);
3836 DBG("[%03d/%s] %.4f %.3f/%.3f dt:%.3f = %.3f%+.3f ev:%02d %3.4f/%+.3f p:%d(%d) = %d%+d %d %d\n",
3837 sid->down.anim_count, (source == ECORE_ANIMATOR_SOURCE_CUSTOM) ? "V" : "T",
3838 now, sid->down.anim_t_delay * 1000, sid->down.anim_t_adjusted * 1000,
3840 (now_diff - d)*1000,
3842 num, sid->down.history[0].timestamp, pos_diff*1000,
3844 sid->down.hold_y, oy - sid->down.hold_y,
3845 oy - sid->down.anim_y_coord_prev,
3846 (int)sid->down.anim_vy_prev);
3850 sid->down.anim_x_coord_prev = ox;
3851 sid->down.anim_y_coord_prev = oy;
3853 update_time_and_quit:
3854 sid->down.anim_t_prev = now;
3856 return ECORE_CALLBACK_RENEW;
3860 _elm_scroll_on_hold_animator(void *data)
3864 Evas_Coord x, y, ox = 0, oy = 0;
3865 Elm_Scrollable_Smart_Interface_Data *sid;
3868 t = ecore_loop_time_get();
3869 if (sid->down.onhold_tlast > 0.0)
3871 td = t - sid->down.onhold_tlast;
3872 vx = sid->down.onhold_vx * td *
3873 (double)_elm_config->thumbscroll_hold_threshold * 2.0;
3874 vy = sid->down.onhold_vy * td *
3875 (double)_elm_config->thumbscroll_hold_threshold * 2.0;
3876 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&ox, &oy));
3880 if (sid->down.dir_x)
3883 (!elm_widget_drag_child_locked_x_get(sid->obj)))
3885 sid->down.onhold_vxe += vx;
3886 x = ox + (int)sid->down.onhold_vxe;
3887 sid->down.onhold_vxe -= (int)sid->down.onhold_vxe;
3891 if (sid->down.dir_y)
3894 (!elm_widget_drag_child_locked_y_get(sid->obj)))
3896 sid->down.onhold_vye += vy;
3897 y = oy + (int)sid->down.onhold_vye;
3898 sid->down.onhold_vye -= (int)sid->down.onhold_vye;
3902 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
3904 sid->down.onhold_tlast = t;
3906 return ECORE_CALLBACK_RENEW;
3910 _elm_scroll_mouse_move_event_cb(void *data,
3912 Evas_Object *obj EINA_UNUSED,
3915 Elm_Scrollable_Smart_Interface_Data *sid = data;
3916 Evas_Event_Mouse_Move *ev;
3917 Evas_Coord x = 0, y = 0;
3919 if (!sid->pan_obj) return;
3921 if ((sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL) &&
3922 (sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
3926 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
3927 sid->down.hold_parent = EINA_TRUE;
3928 evas_post_event_callback_push(e, _elm_scroll_post_event_move, sid);
3930 // FIXME: respect elm_widget_scroll_hold_get of parent container
3931 if (!_elm_config->thumbscroll_enable)
3934 if (!sid->down.now) return;
3936 // TIZEN_ONLY(20160624): Overscroll effect
3937 edje_object_signal_emit(sid->edje_obj, "elm,state,mouse,move", "elm");
3940 // TIZEN_ONLY(20180418): invoke stop callback
3941 Eina_Bool is_stopped = EINA_FALSE;
3943 if ((sid->scrollto.x.animator) && (!sid->hold) && (!sid->freeze) &&
3944 !(sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
3947 ELM_SAFE_FREE(sid->scrollto.x.animator, ecore_animator_del);
3948 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, NULL));
3950 sid->down.x = sid->down.history[0].x;
3951 // TIZEN_ONLY(20180418): invoke stop callback
3952 is_stopped = EINA_TRUE;
3956 if ((sid->scrollto.y.animator) && (!sid->hold) && (!sid->freeze) &&
3957 !(sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL))
3960 ELM_SAFE_FREE(sid->scrollto.y.animator, ecore_animator_del);
3961 eo_do(sid->pan_obj, elm_obj_pan_pos_get(NULL, &py));
3963 sid->down.y = sid->down.history[0].y;
3964 // TIZEN_ONLY(20180418): invoke stop callback
3965 is_stopped = EINA_TRUE;
3969 // TIZEN_ONLY(20180418): invoke stop callback
3972 _elm_scroll_anim_stop(sid);
3977 DBG("::: %i %i\n", ev->cur.canvas.x, ev->cur.canvas.y);
3979 memmove(&(sid->down.history[1]), &(sid->down.history[0]),
3980 sizeof(sid->down.history[0]) * (60 - 1));
3982 sid->down.history[0].timestamp = ev->timestamp / 1000.0;
3983 sid->down.history[0].localtimestamp = ecore_loop_time_get();
3985 sid->down.history[0].timestamp = ecore_loop_time_get();
3987 sid->down.history[0].x = ev->cur.canvas.x;
3988 sid->down.history[0].y = ev->cur.canvas.y;
3990 if (!sid->down.dragged_began)
3992 x = ev->cur.canvas.x - sid->down.x;
3993 y = ev->cur.canvas.y - sid->down.y;
3995 sid->down.hdir = -1;
3996 sid->down.vdir = -1;
3998 if (x > 0) sid->down.hdir = LEFT;
4000 sid->down.hdir = RIGHT;
4001 if (y > 0) sid->down.vdir = UP;
4003 sid->down.vdir = DOWN;
4008 if (sid->one_direction_at_a_time)
4010 if (((x * x) + (y * y)) >
4011 (_elm_config->thumbscroll_threshold *
4012 _elm_config->thumbscroll_threshold))
4014 if (sid->one_direction_at_a_time ==
4015 ELM_SCROLLER_SINGLE_DIRECTION_SOFT)
4021 ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
4023 sid->down.dir_x = EINA_TRUE;
4025 sid->down.dir_y = EINA_FALSE;
4030 sid->down.dir_x = EINA_FALSE;
4032 ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL))
4034 sid->down.dir_y = EINA_TRUE;
4041 ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
4043 sid->down.dir_x = EINA_TRUE;
4046 ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL))
4048 sid->down.dir_y = EINA_TRUE;
4052 else if (sid->one_direction_at_a_time ==
4053 ELM_SCROLLER_SINGLE_DIRECTION_HARD)
4058 ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
4060 sid->down.dir_x = EINA_TRUE;
4062 sid->down.dir_y = EINA_FALSE;
4066 sid->down.dir_x = EINA_FALSE;
4068 ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL))
4070 sid->down.dir_y = EINA_TRUE;
4079 ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
4081 sid->down.dir_x = EINA_TRUE;
4084 ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL))
4086 sid->down.dir_y = EINA_TRUE;
4090 if ((!sid->hold) && (!sid->freeze))
4092 if ((sid->down.dragged) ||
4093 (((x * x) + (y * y)) >
4094 (_elm_config->thumbscroll_threshold *
4095 _elm_config->thumbscroll_threshold)))
4097 if (!sid->down.dragged_began &&
4098 _elm_config->scroll_smooth_start_enable)
4100 #if SMART_SMOOTH_START
4102 for (i = 0 ; i < 5 ; i++)
4103 if (!sid->down.history[i].timestamp)
4108 DBG("smooth-start(-%d): %d->%d->%d->%d->%d->%d\n",
4110 sid->down.history[0].x,
4111 sid->down.history[1].x,
4112 sid->down.history[2].x,
4113 sid->down.history[3].x,
4114 sid->down.history[4].x,
4116 sid->down.x = sid->down.history[i].x;
4117 sid->down.y = sid->down.history[i].y;
4118 sid->down.dragged_began_timestamp = sid->down.history[i].timestamp;
4121 sid->down.x = ev->cur.canvas.x;
4122 sid->down.y = ev->cur.canvas.y;
4124 sid->down.dragged_began_timestamp =
4125 ev->timestamp / 1000.0;
4127 sid->down.dragged_began_timestamp =
4128 ecore_loop_time_get();
4133 if (!sid->down.dragged)
4135 sid->down.want_dragged = EINA_TRUE;
4137 if ((((_elm_scroll_can_scroll(sid, LEFT) || _elm_scroll_can_scroll(sid, RIGHT)) && sid->down.dir_x) ||
4138 ((_elm_scroll_can_scroll(sid, UP) || _elm_scroll_can_scroll(sid, DOWN)) && sid->down.dir_y)) &&
4139 !sid->down.dragged_began)
4141 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
4142 sid->down.dragged_began = EINA_TRUE;
4144 else if (sid->down.dragged_began)
4146 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
4148 if (sid->down.dir_x)
4149 x = sid->down.sx - (ev->cur.canvas.x - sid->down.x);
4152 if (sid->down.dir_y)
4153 y = sid->down.sy - (ev->cur.canvas.y - sid->down.y);
4156 if (sid->down.want_reset)
4158 sid->down.x = ev->cur.canvas.x;
4159 sid->down.y = ev->cur.canvas.y;
4160 sid->down.want_reset = EINA_FALSE;
4162 if ((sid->down.dir_x) || (sid->down.dir_y))
4164 if (!sid->down.locked)
4166 sid->down.locked_x = x;
4167 sid->down.locked_y = y;
4168 sid->down.locked = EINA_TRUE;
4170 if (!((sid->down.dir_x) && (sid->down.dir_y)))
4172 if (sid->down.dir_x) y = sid->down.locked_y;
4173 else x = sid->down.locked_x;
4177 Evas_Coord minx = 0, miny = 0, mx, my;
4179 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
4180 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
4181 if (!sid->loop_v && y < miny)
4183 _elm_config->thumbscroll_border_friction;
4184 else if (!sid->loop_v && my <= 0)
4185 y += (sid->down.sy - y) *
4186 _elm_config->thumbscroll_border_friction;
4187 else if (!sid->loop_v && (my + miny) < y)
4188 y += (my + miny - y) *
4189 _elm_config->thumbscroll_border_friction;
4190 if (!sid->loop_h && x < minx)
4192 _elm_config->thumbscroll_border_friction;
4193 else if (!sid->loop_h && mx <= 0)
4194 x += (sid->down.sx - x) *
4195 _elm_config->thumbscroll_border_friction;
4196 else if (!sid->loop_h && (mx + minx) < x)
4197 x += (mx + minx - x) *
4198 _elm_config->thumbscroll_border_friction;
4201 sid->down.hold_x = x;
4202 sid->down.hold_y = y;
4203 if (!sid->down.hold_animator)
4205 sid->down.hold_animator =
4206 ecore_animator_add(_elm_scroll_hold_animator, sid);
4207 sid->down.anim_x_prev = 0;
4208 sid->down.anim_y_prev = 0;
4209 sid->down.anim_vx_prev = 0;
4210 sid->down.anim_vy_prev = 0;
4211 sid->down.anim_t_prev = 0;
4212 sid->down.anim_x_coord_prev = 0;
4213 sid->down.anim_y_coord_prev = 0;
4214 sid->down.anim_count = 0;
4215 sid->down.anim_skip = 0;
4216 sid->down.anim_t_dont_adjust = 0;
4217 sid->down.anim_t_delay = 0;
4218 sid->down.anim_t_adjusted = 0;
4219 sid->down.anim_pos_t_prev = 0;
4220 memset(&sid->down.predict, 0 , sizeof(sid->down.predict));
4225 if (sid->down.dragged_began)
4227 if ((_elm_scroll_can_scroll(sid, sid->down.hdir) && sid->down.dir_x) ||
4228 (_elm_scroll_can_scroll(sid, sid->down.vdir) && sid->down.dir_y))
4230 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
4232 if (!sid->down.hold)
4234 sid->down.hold = EINA_TRUE;
4235 evas_event_feed_hold
4236 (e, 1, ev->timestamp, ev->data);
4241 else if (!sid->freeze)
4243 double vx = 0.0, vy = 0.0;
4245 x = ev->cur.canvas.x - sid->x;
4246 y = ev->cur.canvas.y - sid->y;
4247 if (x < _elm_config->thumbscroll_hold_threshold)
4249 if (_elm_config->thumbscroll_hold_threshold > 0.0)
4250 vx = -(double)(_elm_config->thumbscroll_hold_threshold - x)
4251 / _elm_config->thumbscroll_hold_threshold;
4255 else if (x > (sid->w - _elm_config->thumbscroll_hold_threshold))
4257 if (_elm_config->thumbscroll_hold_threshold > 0.0)
4258 vx = (double)(_elm_config->thumbscroll_hold_threshold -
4260 _elm_config->thumbscroll_hold_threshold;
4264 if (y < _elm_config->thumbscroll_hold_threshold)
4266 if (_elm_config->thumbscroll_hold_threshold > 0.0)
4267 vy = -(double)(_elm_config->thumbscroll_hold_threshold - y)
4268 / _elm_config->thumbscroll_hold_threshold;
4272 else if (y > (sid->h - _elm_config->thumbscroll_hold_threshold))
4274 if (_elm_config->thumbscroll_hold_threshold > 0.0)
4275 vy = (double)(_elm_config->thumbscroll_hold_threshold -
4277 _elm_config->thumbscroll_hold_threshold;
4281 if ((vx != 0.0) || (vy != 0.0))
4283 sid->down.onhold_vx = vx;
4284 sid->down.onhold_vy = vy;
4285 if (!sid->down.onhold_animator)
4287 sid->down.onhold_vxe = 0.0;
4288 sid->down.onhold_vye = 0.0;
4289 sid->down.onhold_tlast = 0.0;
4290 sid->down.onhold_animator = ecore_animator_add
4291 (_elm_scroll_on_hold_animator, sid);
4296 if (sid->down.onhold_animator)
4298 ELM_SAFE_FREE(sid->down.onhold_animator, ecore_animator_del);
4299 if (sid->content_info.resized)
4300 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
4301 //_elm_scroll_wanted_region_set(sid->obj);
4302 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
4310 _elm_scroll_page_adjust(Elm_Scrollable_Smart_Interface_Data *sid)
4312 Evas_Coord x, y, w, h;
4314 if (!_paging_is_enabled(sid)) return;
4316 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
4317 (NULL, NULL, &w, &h));
4319 x = _elm_scroll_page_x_get(sid, 0, EINA_TRUE);
4320 y = _elm_scroll_page_y_get(sid, 0, EINA_TRUE);
4322 eo_do(sid->obj, elm_interface_scrollable_content_region_set(x, y, w, h));
4326 _elm_scroll_reconfigure(Elm_Scrollable_Smart_Interface_Data *sid)
4328 _elm_scroll_scroll_bar_size_adjust(sid);
4329 _elm_scroll_page_adjust(sid);
4333 _on_edje_move(void *data,
4334 Evas *e EINA_UNUSED,
4335 Evas_Object *edje_obj,
4336 void *event_info EINA_UNUSED)
4338 Elm_Scrollable_Smart_Interface_Data *sid = data;
4341 evas_object_geometry_get(edje_obj, &x, &y, NULL, NULL);
4346 _elm_scroll_reconfigure(sid);
4350 _on_edje_resize(void *data,
4352 Evas_Object *edje_obj,
4353 void *event_info EINA_UNUSED)
4355 Elm_Scrollable_Smart_Interface_Data *sid = data;
4358 Eina_Bool reconf_ok = EINA_TRUE;
4360 evas_object_geometry_get(edje_obj, NULL, NULL, &w, &h);
4365 current_calc = evas_smart_objects_calculate_count_get(e);
4366 if (current_calc == sid->current_calc)
4369 //TIZEN_ONLY(20160524): support for ctxpopup 'more/default' style
4370 //if (sid->size_count > 3) reconf_ok = EINA_FALSE;
4371 if (sid->size_count > 4) reconf_ok = EINA_FALSE;
4376 sid->current_calc = current_calc;
4377 sid->size_count = 0;
4379 if (reconf_ok) _elm_scroll_reconfigure(sid);
4380 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
4381 //_elm_scroll_wanted_region_set(sid->obj);
4382 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
4387 _scroll_edje_object_attach(Evas_Object *obj)
4389 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4391 evas_object_event_callback_add
4392 (sid->edje_obj, EVAS_CALLBACK_RESIZE, _on_edje_resize, sid);
4393 evas_object_event_callback_add
4394 (sid->edje_obj, EVAS_CALLBACK_MOVE, _on_edje_move, sid);
4396 edje_object_signal_callback_add
4397 (sid->edje_obj, "reload", "elm", _elm_scroll_reload_cb, sid);
4398 edje_object_signal_callback_add
4399 (sid->edje_obj, "drag", "elm.dragable.vbar", _elm_scroll_vbar_drag_cb,
4401 edje_object_signal_callback_add
4402 (sid->edje_obj, "drag,set", "elm.dragable.vbar",
4403 _elm_scroll_edje_drag_v_cb, sid);
4404 edje_object_signal_callback_add
4405 (sid->edje_obj, "drag,start", "elm.dragable.vbar",
4406 _elm_scroll_edje_drag_v_start_cb, sid);
4407 edje_object_signal_callback_add
4408 (sid->edje_obj, "drag,stop", "elm.dragable.vbar",
4409 _elm_scroll_edje_drag_v_stop_cb, sid);
4410 edje_object_signal_callback_add
4411 (sid->edje_obj, "drag,step", "elm.dragable.vbar",
4412 _elm_scroll_edje_drag_v_cb, sid);
4413 edje_object_signal_callback_add
4414 (sid->edje_obj, "drag,page", "elm.dragable.vbar",
4415 _elm_scroll_edje_drag_v_cb, sid);
4416 edje_object_signal_callback_add
4417 (sid->edje_obj, "elm,vbar,press", "elm",
4418 _elm_scroll_vbar_press_cb, sid);
4419 edje_object_signal_callback_add
4420 (sid->edje_obj, "elm,vbar,unpress", "elm",
4421 _elm_scroll_vbar_unpress_cb, sid);
4422 edje_object_signal_callback_add
4423 (sid->edje_obj, "drag", "elm.dragable.hbar", _elm_scroll_hbar_drag_cb,
4425 edje_object_signal_callback_add
4426 (sid->edje_obj, "drag,set", "elm.dragable.hbar",
4427 _elm_scroll_edje_drag_h_cb, sid);
4428 edje_object_signal_callback_add
4429 (sid->edje_obj, "drag,start", "elm.dragable.hbar",
4430 _elm_scroll_edje_drag_h_start_cb, sid);
4431 edje_object_signal_callback_add
4432 (sid->edje_obj, "drag,stop", "elm.dragable.hbar",
4433 _elm_scroll_edje_drag_h_stop_cb, sid);
4434 edje_object_signal_callback_add
4435 (sid->edje_obj, "drag,step", "elm.dragable.hbar",
4436 _elm_scroll_edje_drag_h_cb, sid);
4437 edje_object_signal_callback_add
4438 (sid->edje_obj, "drag,page", "elm.dragable.hbar",
4439 _elm_scroll_edje_drag_h_cb, sid);
4440 edje_object_signal_callback_add
4441 (sid->edje_obj, "elm,hbar,press", "elm",
4442 _elm_scroll_hbar_press_cb, sid);
4443 edje_object_signal_callback_add
4444 (sid->edje_obj, "elm,hbar,unpress", "elm",
4445 _elm_scroll_hbar_unpress_cb, sid);
4449 _scroll_event_object_attach(Evas_Object *obj)
4451 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4453 evas_object_event_callback_add
4454 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL, _elm_scroll_wheel_event_cb,
4456 evas_object_event_callback_add
4457 (sid->event_rect, EVAS_CALLBACK_MOUSE_DOWN,
4458 _elm_scroll_mouse_down_event_cb, sid);
4459 evas_object_event_callback_add
4460 (sid->event_rect, EVAS_CALLBACK_MOUSE_UP,
4461 _elm_scroll_mouse_up_event_cb, sid);
4462 evas_object_event_callback_add
4463 (sid->event_rect, EVAS_CALLBACK_MOUSE_MOVE,
4464 _elm_scroll_mouse_move_event_cb, sid);
4468 _scroll_edje_object_detach(Evas_Object *obj)
4470 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4472 evas_object_event_callback_del_full
4473 (sid->edje_obj, EVAS_CALLBACK_RESIZE, _on_edje_resize, sid);
4474 evas_object_event_callback_del_full
4475 (sid->edje_obj, EVAS_CALLBACK_MOVE, _on_edje_move, sid);
4477 edje_object_signal_callback_del_full
4478 (sid->edje_obj, "drag", "elm.dragable.vbar", _elm_scroll_vbar_drag_cb,
4480 edje_object_signal_callback_del_full
4481 (sid->edje_obj, "drag,set", "elm.dragable.vbar",
4482 _elm_scroll_edje_drag_v_cb, sid);
4483 edje_object_signal_callback_del_full
4484 (sid->edje_obj, "drag,start", "elm.dragable.vbar",
4485 _elm_scroll_edje_drag_v_start_cb, sid);
4486 edje_object_signal_callback_del_full
4487 (sid->edje_obj, "drag,stop", "elm.dragable.vbar",
4488 _elm_scroll_edje_drag_v_stop_cb, sid);
4489 edje_object_signal_callback_del_full
4490 (sid->edje_obj, "drag,step", "elm.dragable.vbar",
4491 _elm_scroll_edje_drag_v_cb, sid);
4492 edje_object_signal_callback_del_full
4493 (sid->edje_obj, "drag,page", "elm.dragable.vbar",
4494 _elm_scroll_edje_drag_v_cb, sid);
4495 edje_object_signal_callback_del_full
4496 (sid->edje_obj, "elm,vbar,press", "elm",
4497 _elm_scroll_vbar_press_cb, sid);
4498 edje_object_signal_callback_del_full
4499 (sid->edje_obj, "elm,vbar,unpress", "elm",
4500 _elm_scroll_vbar_unpress_cb, sid);
4501 edje_object_signal_callback_del_full
4502 (sid->edje_obj, "drag", "elm.dragable.hbar", _elm_scroll_hbar_drag_cb,
4504 edje_object_signal_callback_del_full
4505 (sid->edje_obj, "drag,set", "elm.dragable.hbar",
4506 _elm_scroll_edje_drag_h_cb, sid);
4507 edje_object_signal_callback_del_full
4508 (sid->edje_obj, "drag,start", "elm.dragable.hbar",
4509 _elm_scroll_edje_drag_h_start_cb, sid);
4510 edje_object_signal_callback_del_full
4511 (sid->edje_obj, "drag,stop", "elm.dragable.hbar",
4512 _elm_scroll_edje_drag_h_stop_cb, sid);
4513 edje_object_signal_callback_del_full
4514 (sid->edje_obj, "drag,step", "elm.dragable.hbar",
4515 _elm_scroll_edje_drag_h_cb, sid);
4516 edje_object_signal_callback_del_full
4517 (sid->edje_obj, "drag,page", "elm.dragable.hbar",
4518 _elm_scroll_edje_drag_h_cb, sid);
4519 edje_object_signal_callback_del_full
4520 (sid->edje_obj, "elm,hbar,press", "elm",
4521 _elm_scroll_hbar_press_cb, sid);
4522 edje_object_signal_callback_del_full
4523 (sid->edje_obj, "elm,hbar,unpress", "elm",
4524 _elm_scroll_hbar_unpress_cb, sid);
4528 _scroll_event_object_detach(Evas_Object *obj)
4530 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
4532 evas_object_event_callback_del_full
4533 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL, _elm_scroll_wheel_event_cb,
4535 evas_object_event_callback_del_full
4536 (sid->event_rect, EVAS_CALLBACK_MOUSE_DOWN,
4537 _elm_scroll_mouse_down_event_cb, sid);
4538 evas_object_event_callback_del_full
4539 (sid->event_rect, EVAS_CALLBACK_MOUSE_UP,
4540 _elm_scroll_mouse_up_event_cb, sid);
4541 evas_object_event_callback_del_full
4542 (sid->event_rect, EVAS_CALLBACK_MOUSE_MOVE,
4543 _elm_scroll_mouse_move_event_cb, sid);
4547 _elm_interface_scrollable_objects_set(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Object *edje_object, Evas_Object *hit_rectangle)
4551 if (!edje_object || !hit_rectangle) return;
4554 _scroll_edje_object_detach(obj);
4556 sid->edje_obj = edje_object;
4558 if (sid->event_rect)
4559 _scroll_event_object_detach(obj);
4561 sid->event_rect = hit_rectangle;
4562 evas_object_repeat_events_set(hit_rectangle, EINA_TRUE);
4564 _scroll_edje_object_attach(obj);
4565 _scroll_event_object_attach(obj);
4568 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
4569 if (edje_object_part_exists(sid->edje_obj, "elm.scrollbar.base"))
4573 base = edje_object_part_swallow_get
4574 (sid->edje_obj, "elm.scrollbar.base");
4577 base = evas_object_rectangle_add
4578 (evas_object_evas_get(sid->edje_obj));
4579 evas_object_color_set(base, 0, 0, 0, 0);
4580 edje_object_part_swallow
4581 (sid->edje_obj, "elm.scrollbar.base", base);
4583 if (!_elm_config->thumbscroll_enable)
4584 evas_object_size_hint_min_set(base, mw, mh);
4587 _elm_scroll_scroll_bar_visibility_adjust(sid);
4591 _elm_scroll_scroll_bar_reset(Elm_Scrollable_Smart_Interface_Data *sid)
4593 Evas_Coord px = 0, py = 0, minx = 0, miny = 0;
4595 if (!sid->edje_obj) return;
4597 edje_object_part_drag_value_set
4598 (sid->edje_obj, "elm.dragable.vbar", 0.0, 0.0);
4599 edje_object_part_drag_value_set
4600 (sid->edje_obj, "elm.dragable.hbar", 0.0, 0.0);
4601 if ((!sid->content) && (!sid->extern_pan))
4603 edje_object_part_drag_size_set
4604 (sid->edje_obj, "elm.dragable.vbar", 1.0, 1.0);
4605 edje_object_part_drag_size_set
4606 (sid->edje_obj, "elm.dragable.hbar", 1.0, 1.0);
4610 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
4611 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
4612 eo_do(sid->pan_obj, elm_obj_pan_pos_set(minx, miny));
4614 if ((px != minx) || (py != miny))
4615 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
4616 _elm_direction_arrows_eval(sid);
4620 _elm_scroll_pan_resized_cb(void *data,
4621 Evas *e EINA_UNUSED,
4622 Evas_Object *obj EINA_UNUSED,
4623 void *event_info EINA_UNUSED)
4625 Evas_Coord w = 0, h = 0;
4626 Elm_Scrollable_Smart_Interface_Data *sid = data;
4628 if (sid->cb_func.content_viewport_resize)
4630 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
4631 (NULL, NULL, &w, &h));
4632 sid->cb_func.content_viewport_resize(sid->obj, w, h);
4636 /* even external pan objects get this */
4638 _elm_scroll_pan_changed_cb(void *data,
4639 Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED,
4640 void *event_info EINA_UNUSED)
4642 Evas_Coord w = 0, h = 0;
4643 Elm_Scrollable_Smart_Interface_Data *sid = data;
4645 if (!sid->pan_obj) return EINA_TRUE;
4647 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&w, &h));
4648 if ((w != sid->content_info.w) || (h != sid->content_info.h))
4650 sid->content_info.w = w;
4651 sid->content_info.h = h;
4652 //TIZEN_ONLY(20170210): update pan position once pan size is changed
4653 //_elm_scroll_scroll_bar_size_adjust(sid);
4655 evas_object_size_hint_min_set
4656 (sid->edje_obj, sid->content_info.w, sid->content_info.h);
4657 sid->content_info.resized = EINA_TRUE;
4659 //FIXME FIXME FIXME: Would you please fix me ?
4660 //TIZEN_ONLY(20170227): Compensate scroller when scroller is not stable.
4661 int current_calc = 0;
4662 Evas_Coord x = 0, y = 0;
4663 current_calc = evas_smart_objects_calculate_count_get(evas_object_evas_get(obj));
4664 if (sid->requested_page.loop_cnt == current_calc)
4666 ELM_SAFE_FREE(sid->scrollto.x.animator, ecore_animator_del);
4667 ELM_SAFE_FREE(sid->scrollto.y.animator, ecore_animator_del);
4669 x = sid->pagesize_h * sid->requested_page.h;
4670 x = (sid->is_mirrored ? _elm_scroll_x_mirrored_get(sid->obj, x) : x);
4671 y = sid->pagesize_v * sid->requested_page.v;
4673 _elm_scroll_wanted_coordinates_update(sid, x, y);
4674 eo_do(sid->pan_obj, elm_obj_pan_pos_set(x, y));
4678 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
4679 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
4683 //TIZEN_ONLY(20170718): Add content,resize callback to keep backward compat
4684 evas_object_smart_callback_call(sid->obj, SIG_CONTENT_RESIZE, NULL);
4687 //TIZEN_ONLY(20170210): update pan position once pan size is changed
4688 //Bar should be updated on not only content size changed moment, but also pan pos/size updated moment
4689 _elm_scroll_scroll_bar_size_adjust(sid);
4690 _elm_scroll_scroll_bar_pos_adjust(sid);
4696 _elm_scroll_content_del_cb(void *data,
4697 Evas *e EINA_UNUSED,
4698 Evas_Object *obj EINA_UNUSED,
4699 void *event_info EINA_UNUSED)
4701 Elm_Scrollable_Smart_Interface_Data *sid = data;
4703 sid->content = NULL;
4704 _elm_scroll_scroll_bar_size_adjust(sid);
4705 //TIZEN_ONLY(20151012): Separate logic which calculate for bar size and logic which calculate for bar position.
4706 //A elm_scroll_scroll_bar_pos_adjust is called when size of content is changed.
4707 //If size of pan is changed only, A elm_scroll_scroll_bar_pos_adjust isn`t called. Only a elm_scroll_scroll_bar_size_adjust is called.
4708 _elm_scroll_scroll_bar_pos_adjust(sid);
4710 _elm_scroll_scroll_bar_reset(sid);
4714 _elm_interface_scrollable_content_set(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Object *content)
4716 Evas_Coord w = 0, h = 0;
4719 if (!sid->edje_obj) return;
4723 /* if we had content, for sure we had a pan object */
4724 _elm_pan_content_set(sid->pan_obj, NULL);
4725 evas_object_event_callback_del_full
4726 (sid->content, EVAS_CALLBACK_DEL, _elm_scroll_content_del_cb, sid);
4729 sid->content = content;
4730 sid->wx = sid->wy = 0;
4731 /* (-1) means want viewports size */
4732 sid->ww = sid->wh = -1;
4733 if (!content) return;
4737 o = _elm_pan_add(evas_object_evas_get(obj));
4739 eo_do(o, eo_event_callback_add
4740 (ELM_PAN_EVENT_CHANGED, _elm_scroll_pan_changed_cb, sid));
4741 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE,
4742 _elm_scroll_pan_resized_cb, sid);
4743 edje_object_part_swallow(sid->edje_obj, "elm.swallow.content", o);
4746 evas_object_event_callback_add
4747 (content, EVAS_CALLBACK_DEL, _elm_scroll_content_del_cb, sid);
4749 _elm_pan_content_set(sid->pan_obj, content);
4750 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&w, &h));
4751 sid->content_info.w = w;
4752 sid->content_info.h = h;
4754 _elm_scroll_scroll_bar_size_adjust(sid);
4755 //TIZEN_ONLY(20151012): Separate logic which calculate for bar size and logic which calculate for bar position.
4756 //A elm_scroll_scroll_bar_pos_adjust is called when size of content is changed.
4757 //If size of pan is changed only, A elm_scroll_scroll_bar_pos_adjust isn`t called. Only a elm_scroll_scroll_bar_size_adjust is called.
4758 _elm_scroll_scroll_bar_pos_adjust(sid);
4760 _elm_scroll_scroll_bar_reset(sid);
4764 _elm_interface_scrollable_extern_pan_set(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Object *pan)
4766 if (!sid->edje_obj) return;
4768 eo_do(obj, elm_interface_scrollable_content_set(NULL));
4772 eo_do(sid->pan_obj, eo_event_callback_del(
4773 ELM_PAN_EVENT_CHANGED, _elm_scroll_pan_changed_cb, sid));
4774 evas_object_event_callback_del(sid->pan_obj, EVAS_CALLBACK_RESIZE,
4775 _elm_scroll_pan_resized_cb);
4778 if (sid->extern_pan)
4782 /* not owned by scroller, just leave (was external already) */
4783 edje_object_part_unswallow(sid->edje_obj, sid->pan_obj);
4784 sid->pan_obj = NULL;
4789 ELM_SAFE_FREE(sid->pan_obj, evas_object_del);
4793 sid->extern_pan = EINA_FALSE;
4799 sid->extern_pan = EINA_TRUE;
4800 eo_do(sid->pan_obj, eo_event_callback_add
4801 (ELM_PAN_EVENT_CHANGED, _elm_scroll_pan_changed_cb, sid));
4802 evas_object_event_callback_add(sid->pan_obj, EVAS_CALLBACK_RESIZE,
4803 _elm_scroll_pan_resized_cb, sid);
4804 edje_object_part_swallow
4805 (sid->edje_obj, "elm.swallow.content", sid->pan_obj);
4809 _elm_interface_scrollable_drag_start_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb drag_start_cb)
4811 sid->cb_func.drag_start = drag_start_cb;
4815 _elm_interface_scrollable_drag_stop_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb drag_stop_cb)
4817 sid->cb_func.drag_stop = drag_stop_cb;
4821 _elm_interface_scrollable_animate_start_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb animate_start_cb)
4823 sid->cb_func.animate_start = animate_start_cb;
4827 _elm_interface_scrollable_animate_stop_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb animate_stop_cb)
4829 sid->cb_func.animate_stop = animate_stop_cb;
4833 _elm_interface_scrollable_page_change_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb page_change_cb EINA_UNUSED)
4835 sid->cb_func.page_change = page_change_cb;
4839 _elm_interface_scrollable_scroll_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb scroll_cb)
4841 sid->cb_func.scroll = scroll_cb;
4845 _elm_interface_scrollable_scroll_left_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb scroll_left_cb)
4847 sid->cb_func.scroll_left = scroll_left_cb;
4851 _elm_interface_scrollable_scroll_right_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb scroll_right_cb)
4853 sid->cb_func.scroll_right = scroll_right_cb;
4857 _elm_interface_scrollable_scroll_up_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb scroll_up_cb)
4859 sid->cb_func.scroll_up = scroll_up_cb;
4863 _elm_interface_scrollable_scroll_down_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb scroll_down_cb)
4865 sid->cb_func.scroll_down = scroll_down_cb;
4869 _elm_interface_scrollable_edge_left_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb edje_left_cb)
4871 sid->cb_func.edge_left = edje_left_cb;
4875 _elm_interface_scrollable_edge_right_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb edje_right_cb)
4877 sid->cb_func.edge_right = edje_right_cb;
4881 _elm_interface_scrollable_edge_top_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb edje_top_cb)
4883 sid->cb_func.edge_top = edje_top_cb;
4887 _elm_interface_scrollable_edge_bottom_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb edje_bottom_cb)
4889 sid->cb_func.edge_bottom = edje_bottom_cb;
4893 _elm_interface_scrollable_vbar_drag_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb vbar_drag_cb)
4895 sid->cb_func.vbar_drag = vbar_drag_cb;
4899 _elm_interface_scrollable_vbar_press_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb vbar_press_cb)
4901 sid->cb_func.vbar_press = vbar_press_cb;
4905 _elm_interface_scrollable_vbar_unpress_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb vbar_unpress_cb)
4907 sid->cb_func.vbar_unpress = vbar_unpress_cb;
4911 _elm_interface_scrollable_hbar_drag_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb hbar_drag_cb)
4913 sid->cb_func.hbar_drag = hbar_drag_cb;
4917 _elm_interface_scrollable_hbar_press_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb hbar_press_cb)
4919 sid->cb_func.hbar_press = hbar_press_cb;
4923 _elm_interface_scrollable_hbar_unpress_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb hbar_unpress_cb)
4925 sid->cb_func.hbar_unpress = hbar_unpress_cb;
4929 _elm_interface_scrollable_content_min_limit_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Min_Limit_Cb min_limit_cb)
4931 sid->cb_func.content_min_limit = min_limit_cb;
4935 _elm_interface_scrollable_content_viewport_resize_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Resize_Cb viewport_resize_cb)
4937 sid->cb_func.content_viewport_resize = viewport_resize_cb;
4940 EOLIAN static Eina_Bool
4941 _elm_interface_scrollable_momentum_animator_disabled_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid)
4943 return sid->momentum_animator_disabled;
4947 _elm_interface_scrollable_momentum_animator_disabled_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool disabled)
4949 sid->momentum_animator_disabled = disabled;
4950 if (sid->momentum_animator_disabled)
4952 if (sid->down.momentum_animator)
4954 ELM_SAFE_FREE(sid->down.momentum_animator, ecore_animator_del);
4955 if (sid->content_info.resized)
4956 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
4957 //_elm_scroll_wanted_region_set(sid->obj);
4958 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
4964 EOLIAN static Eina_Bool
4965 _elm_interface_scrollable_bounce_animator_disabled_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid)
4967 return sid->bounce_animator_disabled;
4971 _elm_interface_scrollable_bounce_animator_disabled_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool disabled)
4973 sid->bounce_animator_disabled = disabled;
4974 if (sid->bounce_animator_disabled)
4976 ELM_SAFE_FREE(sid->scrollto.x.animator, ecore_animator_del);
4977 ELM_SAFE_FREE(sid->scrollto.y.animator, ecore_animator_del);
4981 EOLIAN static Eina_Bool
4982 _elm_interface_scrollable_wheel_disabled_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid)
4984 return sid->wheel_disabled;
4988 _elm_interface_scrollable_wheel_disabled_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool disabled)
4990 if (!sid->event_rect) return;
4992 if ((!sid->wheel_disabled) && (disabled))
4993 evas_object_event_callback_del_full
4994 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL,
4995 _elm_scroll_wheel_event_cb, sid);
4996 else if ((sid->wheel_disabled) && (!disabled))
4997 evas_object_event_callback_add
4998 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL,
4999 _elm_scroll_wheel_event_cb, sid);
5000 sid->wheel_disabled = disabled;
5004 _elm_interface_scrollable_step_size_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord x, Evas_Coord y)
5011 _elm_scroll_scroll_bar_size_adjust(sid);
5015 _elm_interface_scrollable_step_size_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord *x, Evas_Coord *y)
5017 if (x) *x = sid->step.x;
5018 if (y) *y = sid->step.y;
5022 _elm_interface_scrollable_page_size_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord x, Evas_Coord y)
5027 _elm_scroll_scroll_bar_size_adjust(sid);
5031 _elm_interface_scrollable_page_size_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord *x, Evas_Coord *y)
5033 if (x) *x = sid->page.x;
5034 if (y) *y = sid->page.y;
5038 _elm_interface_scrollable_policy_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Scroller_Policy hbar, Elm_Scroller_Policy vbar)
5040 if (!sid->edje_obj) return;
5042 if ((sid->hbar_flags == hbar) && (sid->vbar_flags == vbar)) return;
5044 sid->hbar_flags = hbar;
5045 sid->vbar_flags = vbar;
5046 _elm_scroll_policy_signal_emit(sid);
5047 if (sid->cb_func.content_min_limit)
5048 sid->cb_func.content_min_limit(sid->obj, sid->min_w, sid->min_h);
5049 _elm_direction_arrows_eval(sid);
5053 _elm_interface_scrollable_policy_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Scroller_Policy *hbar, Elm_Scroller_Policy *vbar)
5055 if (hbar) *hbar = sid->hbar_flags;
5056 if (vbar) *vbar = sid->vbar_flags;
5060 _elm_interface_scrollable_single_direction_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Scroller_Single_Direction single_dir)
5062 sid->one_direction_at_a_time = single_dir;
5065 EOLIAN static Elm_Scroller_Single_Direction
5066 _elm_interface_scrollable_single_direction_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid)
5068 return sid->one_direction_at_a_time;
5072 _elm_interface_scrollable_repeat_events_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool repeat_events)
5074 if (sid->event_rect)
5075 evas_object_repeat_events_set(sid->event_rect, repeat_events);
5078 EOLIAN static Eina_Bool
5079 _elm_interface_scrollable_repeat_events_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid)
5081 if (sid->event_rect)
5082 return evas_object_repeat_events_get(sid->event_rect);
5088 _elm_interface_scrollable_hold_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool hold)
5094 _elm_interface_scrollable_freeze_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool freeze)
5096 sid->freeze = freeze;
5099 if (sid->down.onhold_animator)
5101 ELM_SAFE_FREE(sid->down.onhold_animator, ecore_animator_del);
5102 if (sid->content_info.resized)
5103 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
5104 //_elm_scroll_wanted_region_set(sid->obj);
5105 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
5110 _elm_scroll_bounce_eval(sid);
5114 _elm_interface_scrollable_page_snap_allow_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool horiz, Eina_Bool vert)
5116 sid->page_snap_horiz = !!horiz;
5117 sid->page_snap_vert = !!vert;
5121 _elm_interface_scrollable_page_snap_allow_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool *horiz, Eina_Bool *vert)
5123 if (horiz) *horiz = sid->page_snap_horiz;
5124 if (vert) *vert = sid->page_snap_vert;
5128 _elm_interface_scrollable_bounce_allow_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool horiz, Eina_Bool vert)
5130 sid->bounce_horiz = !!horiz;
5131 sid->bounce_vert = !!vert;
5135 _elm_interface_scrollable_bounce_allow_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool *horiz, Eina_Bool *vert)
5137 if (horiz) *horiz = sid->bounce_horiz;
5138 if (vert) *vert = sid->bounce_vert;
5142 _elm_interface_scrollable_paging_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, double pagerel_h, double pagerel_v, Evas_Coord pagesize_h, Evas_Coord pagesize_v)
5144 sid->pagerel_h = pagerel_h;
5145 sid->pagerel_v = pagerel_v;
5146 sid->pagesize_h = pagesize_h;
5147 sid->pagesize_v = pagesize_v;
5149 _elm_scroll_page_adjust(sid);
5153 _elm_interface_scrollable_paging_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, double *pagerel_h, double *pagerel_v, Evas_Coord *pagesize_h, Evas_Coord *pagesize_v)
5155 if (pagerel_h) *pagerel_h = sid->pagerel_h;
5156 if (pagerel_v) *pagerel_v = sid->pagerel_v;
5157 if (pagesize_h) *pagesize_h = sid->pagesize_h;
5158 if (pagesize_v) *pagesize_v = sid->pagesize_v;
5162 _elm_interface_scrollable_page_relative_set(Eo *obj, Elm_Scrollable_Smart_Interface_Data *_pd EINA_UNUSED, double h_pagerel, double v_pagerel)
5164 Evas_Coord pagesize_h, pagesize_v;
5166 eo_do(obj, elm_interface_scrollable_paging_get(NULL, NULL, &pagesize_h, &pagesize_v));
5168 eo_do(obj, elm_interface_scrollable_paging_set(h_pagerel, v_pagerel, pagesize_h, pagesize_v));
5172 _elm_interface_scrollable_page_scroll_limit_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, int page_limit_h, int page_limit_v)
5174 sid->page_limit_h = page_limit_h;
5175 sid->page_limit_v = page_limit_v;
5179 _elm_interface_scrollable_page_scroll_limit_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, int *page_limit_h, int *page_limit_v)
5181 if (page_limit_h) *page_limit_h = sid->page_limit_h;
5182 if (page_limit_v) *page_limit_v = sid->page_limit_v;
5186 _elm_interface_scrollable_current_page_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, int *pagenumber_h, int *pagenumber_v)
5190 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
5192 // TIZEN_ONLY(20170110): Unify basis of calculation of current_page_get logic on both rtl & ltr
5193 if (sid->is_mirrored)
5194 x = _elm_scroll_x_mirrored_get(sid->obj, x);
5199 if (sid->pagesize_h > 0)
5201 double result = (double)x / (double)sid->pagesize_h;
5202 double rest = result - (int)(x / sid->pagesize_h);
5204 *pagenumber_h = result + 1;
5206 *pagenumber_h = result;
5213 if (sid->pagesize_v > 0)
5215 double result = (double)y / (double)sid->pagesize_v;
5216 double rest = result - (int)(y / sid->pagesize_v);
5218 *pagenumber_v = result + 1;
5220 *pagenumber_v = result;
5228 _elm_interface_scrollable_last_page_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, int *pagenumber_h, int *pagenumber_v)
5232 if (!sid->pan_obj) return;
5234 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&cw, &ch));
5237 if ((sid->pagesize_h > 0) && (cw > sid->pagesize_h))
5238 *pagenumber_h = ceil((double)cw / (double)sid->pagesize_h) - 1;
5244 if ((sid->pagesize_v > 0) && (ch > sid->pagesize_v))
5245 *pagenumber_v = ceil((double)ch / (double)sid->pagesize_v) - 1;
5252 _elm_interface_scrollable_page_show(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid, int pagenumber_h, int pagenumber_v)
5254 Evas_Coord w = 0, h = 0;
5258 sid->current_page.x = _elm_scroll_page_x_get(sid, 0, EINA_FALSE);
5259 sid->current_page.y = _elm_scroll_page_y_get(sid, 0, EINA_FALSE);
5261 //FIXME FIXME FIXME: Would you please fix me ?
5262 //TIZEN_ONLY(20170227): Compensate scroller when scroller is not stable.
5263 sid->requested_page.h = pagenumber_h;
5264 sid->requested_page.v = pagenumber_v;
5265 sid->requested_page.loop_cnt = evas_smart_objects_calculate_count_get(evas_object_evas_get(obj));
5268 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
5269 (NULL, NULL, &w, &h));
5270 x = sid->pagesize_h * pagenumber_h;
5271 x = (sid->is_mirrored ? _elm_scroll_x_mirrored_get(sid->obj, x) : x);
5272 y = sid->pagesize_v * pagenumber_v;
5279 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
5280 eo_do(obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
5282 if ((sid->current_page.x != x) || (sid->current_page.y != y))
5284 if (sid->cb_func.page_change)
5285 sid->cb_func.page_change(sid->obj, NULL);
5290 _elm_interface_scrollable_page_bring_in(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid, int pagenumber_h, int pagenumber_v)
5292 Evas_Coord w = 0, h = 0;
5296 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
5297 (NULL, NULL, &w, &h));
5298 x = sid->pagesize_h * pagenumber_h;
5299 x = (sid->is_mirrored ? _elm_scroll_x_mirrored_get(sid->obj, x) : x);
5300 y = sid->pagesize_v * pagenumber_v;
5302 //FIXME FIXME FIXME: Would you please fix me ?
5303 //TIZEN_ONLY(20170227): Compensate scroller when scroller is not stable.
5304 sid->requested_page.h = pagenumber_h;
5305 sid->requested_page.v = pagenumber_v;
5306 sid->requested_page.loop_cnt = evas_smart_objects_calculate_count_get(evas_object_evas_get(obj));
5309 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
5311 _elm_scroll_scroll_to_x(sid, _elm_config->bring_in_scroll_friction, x);
5312 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, y);
5317 _elm_interface_scrollable_region_bring_in(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
5319 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
5321 _elm_scroll_scroll_to_x(sid, _elm_config->bring_in_scroll_friction, x);
5322 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, y);
5327 _elm_interface_scrollable_gravity_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, double x, double y)
5331 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&sid->prev_cw, &sid->prev_ch));
5335 _elm_interface_scrollable_gravity_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, double *x, double *y)
5337 if (x) *x = sid->gravity_x;
5338 if (y) *y = sid->gravity_y;
5342 _elm_interface_scrollable_movement_block_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Scroller_Movement_Block block)
5347 EOLIAN static Elm_Scroller_Movement_Block
5348 _elm_interface_scrollable_movement_block_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid)
5354 _elm_interface_scrollable_loop_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool loop_h, Eina_Bool loop_v)
5356 if (sid->loop_h == loop_h && sid->loop_v == loop_v) return;
5358 sid->loop_h = loop_h;
5359 sid->loop_v = loop_v;
5362 edje_object_signal_emit(sid->edje_obj, "elm,loop_x,set", "elm");
5364 edje_object_signal_emit(sid->edje_obj, "elm,loop_x,unset", "elm");
5367 edje_object_signal_emit(sid->edje_obj, "elm,loop_y,set", "elm");
5369 edje_object_signal_emit(sid->edje_obj, "elm,loop_y,unset", "elm");
5373 _elm_interface_scrollable_loop_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool *loop_h, Eina_Bool *loop_v)
5375 if (loop_h) *loop_h = sid->loop_h;
5376 if (loop_v) *loop_v = sid->loop_v;
5380 _elm_interface_scrollable_evas_object_smart_add(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid)
5382 memset(sid, 0, sizeof(*sid));
5394 sid->page_limit_h = 9999;
5395 sid->page_limit_v = 9999;
5396 sid->hbar_flags = ELM_SCROLLER_POLICY_AUTO;
5397 sid->vbar_flags = ELM_SCROLLER_POLICY_AUTO;
5398 sid->hbar_visible = EINA_TRUE;
5399 sid->vbar_visible = EINA_TRUE;
5400 sid->loop_h = EINA_FALSE;
5401 sid->loop_v = EINA_FALSE;
5402 //FIXME FIXME FIXME: Would you please fix me ?
5403 //TIZEN_ONLY(20170227): Initialize member variables which are used for unstable situation
5404 sid->requested_page.h = 0;
5405 sid->requested_page.v = 0;
5406 sid->requested_page.loop_cnt = evas_smart_objects_calculate_count_get(evas_object_evas_get(obj));
5409 sid->bounce_horiz = EINA_TRUE;
5410 sid->bounce_vert = EINA_TRUE;
5412 sid->one_direction_at_a_time = ELM_SCROLLER_SINGLE_DIRECTION_SOFT;
5413 sid->momentum_animator_disabled = EINA_FALSE;
5414 sid->bounce_animator_disabled = EINA_FALSE;
5415 sid->block = ELM_SCROLLER_MOVEMENT_NO_BLOCK;
5416 //TIZEN_ONLY(20190219): fix page snap behavior.
5417 sid->scrolling = EINA_FALSE;
5420 _elm_scroll_scroll_bar_reset(sid);
5422 eo_do_super(obj, MY_SCROLLABLE_INTERFACE, evas_obj_smart_add());
5426 _elm_interface_scrollable_evas_object_smart_del(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid)
5429 eo_do_super(obj, MY_SCROLLABLE_INTERFACE, evas_obj_smart_del());
5431 eo_do(obj, elm_interface_scrollable_content_set(NULL));
5432 if (!sid->extern_pan) evas_object_del(sid->pan_obj);
5434 ecore_animator_del(sid->down.hold_animator);
5435 ecore_animator_del(sid->down.onhold_animator);
5436 ecore_animator_del(sid->down.momentum_animator);
5437 ecore_animator_del(sid->down.bounce_x_animator);
5438 ecore_animator_del(sid->down.bounce_y_animator);
5439 ecore_animator_del(sid->scrollto.x.animator);
5440 ecore_animator_del(sid->scrollto.y.animator);
5442 ELM_SAFE_FREE(sid->adjust_job.bar_size_adjust, ecore_job_del);
5443 ELM_SAFE_FREE(sid->adjust_job.bar_pos_adjust, ecore_job_del);
5444 ELM_SAFE_FREE(sid->adjust_job.page_adjust, ecore_job_del);
5448 _elm_interface_scrollable_class_constructor(Eo_Class *klass)
5450 evas_smart_legacy_type_register(MY_SCROLLABLE_INTERFACE_NAME_LEGACY, klass);
5453 #include "elm_interface_scrollable.eo.c"
5454 #include "elm_pan.eo.c"