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 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
39 static void _elm_pan_content_set(Evas_Object *, Evas_Object *);
41 _elm_scroll_scroll_to_x(Elm_Scrollable_Smart_Interface_Data *sid,
45 _elm_scroll_scroll_to_y(Elm_Scrollable_Smart_Interface_Data *sid,
49 _elm_scroll_wanted_coordinates_update(Elm_Scrollable_Smart_Interface_Data *sid,
53 _round(double value, int pos)
57 temp = value * pow( 10, pos );
58 temp = floor( temp + 0.5 );
59 temp *= pow( 10, -pos );
65 _elm_pan_update(Elm_Pan_Smart_Data *psd)
67 if (!psd->gravity_x && !psd->gravity_y)
69 evas_object_move(psd->content, psd->x - psd->px, psd->y - psd->py);
73 if ((!psd->px) && (!psd->py))
75 psd->px = psd->delta_posx * psd->gravity_x;
76 psd->py = psd->delta_posy * psd->gravity_y;
78 psd->delta_posx += psd->content_w - psd->prev_cw;
79 psd->prev_cw = psd->content_w;
80 psd->delta_posy += psd->content_h - psd->prev_ch;
81 psd->prev_ch = psd->content_h;
83 evas_object_move(psd->content, psd->x - psd->px, psd->y - psd->py);
84 psd->px = psd->delta_posx * psd->gravity_x;
85 psd->py = psd->delta_posy * psd->gravity_y;
89 _elm_pan_evas_object_smart_add(Eo *obj, Elm_Pan_Smart_Data *priv)
91 eo_do_super(obj, MY_PAN_CLASS, evas_obj_smart_add());
97 _elm_pan_evas_object_smart_del(Eo *obj, Elm_Pan_Smart_Data *_pd EINA_UNUSED)
99 _elm_pan_content_set(obj, NULL);
101 eo_do_super(obj, MY_PAN_CLASS, evas_obj_smart_del());
105 _elm_pan_evas_object_smart_move(Eo *obj EINA_UNUSED, Elm_Pan_Smart_Data *psd, Evas_Coord x, Evas_Coord y)
110 _elm_pan_update(psd);
114 _elm_pan_evas_object_smart_resize(Eo *obj EINA_UNUSED, Elm_Pan_Smart_Data *psd, Evas_Coord w, Evas_Coord h)
119 _elm_pan_update(psd);
120 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
124 _elm_pan_evas_object_smart_show(Eo *obj, Elm_Pan_Smart_Data *psd)
126 eo_do_super(obj, MY_PAN_CLASS, evas_obj_smart_show());
129 evas_object_show(psd->content);
133 _elm_pan_evas_object_smart_hide(Eo *obj, Elm_Pan_Smart_Data *psd)
135 eo_do_super(obj, MY_PAN_CLASS, evas_obj_smart_hide());
138 evas_object_hide(psd->content);
142 _elm_pan_pos_set(Eo *obj EINA_UNUSED, Elm_Pan_Smart_Data *psd, Evas_Coord x, Evas_Coord y)
144 if ((x == psd->px) && (y == psd->py)) return;
148 _elm_pan_update(psd);
149 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
153 _elm_pan_pos_get(Eo *obj EINA_UNUSED, Elm_Pan_Smart_Data *psd, Evas_Coord *x, Evas_Coord *y)
160 _elm_pan_pos_max_get(Eo *obj EINA_UNUSED, Elm_Pan_Smart_Data *psd, Evas_Coord *x, Evas_Coord *y)
164 if (psd->w < psd->content_w) *x = psd->content_w - psd->w;
169 if (psd->h < psd->content_h) *y = psd->content_h - psd->h;
175 _elm_pan_pos_min_get(Eo *obj EINA_UNUSED, Elm_Pan_Smart_Data *_pd EINA_UNUSED, Evas_Coord *x, Evas_Coord *y)
183 // TIZEN_ONLY(20150705): Genlist item align feature
185 _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)
192 _elm_pan_content_size_get(Eo *obj EINA_UNUSED, Elm_Pan_Smart_Data *psd, Evas_Coord *w, Evas_Coord *h)
194 if (w) *w = psd->content_w;
195 if (h) *h = psd->content_h;
199 _elm_pan_gravity_set(Eo *obj EINA_UNUSED, Elm_Pan_Smart_Data *psd, double x, double y)
203 psd->prev_cw = psd->content_w;
204 psd->prev_ch = psd->content_h;
210 _elm_pan_gravity_get(Eo *obj EINA_UNUSED, Elm_Pan_Smart_Data *psd, double *x, double *y)
212 if (x) *x = psd->gravity_x;
213 if (y) *y = psd->gravity_y;
217 _elm_pan_add(Evas *evas)
219 Evas_Object *obj = eo_add(MY_PAN_CLASS, evas);
224 _elm_pan_eo_base_constructor(Eo *obj, Elm_Pan_Smart_Data *_pd EINA_UNUSED)
226 eo_do_super(obj, MY_PAN_CLASS, eo_constructor());
228 evas_obj_type_set(MY_PAN_CLASS_NAME_LEGACY),
229 evas_obj_smart_callbacks_descriptions_set(_smart_callbacks));
233 _elm_pan_content_del_cb(void *data,
235 Evas_Object *obj EINA_UNUSED,
236 void *event_info EINA_UNUSED)
238 Elm_Pan_Smart_Data *psd;
242 psd->content_w = psd->content_h = psd->px = psd->py =
243 psd->prev_cw = psd->prev_ch = psd->delta_posx = psd->delta_posy = 0;
244 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
248 _elm_pan_content_resize_cb(void *data,
250 Evas_Object *obj EINA_UNUSED,
251 void *event_info EINA_UNUSED)
253 Elm_Pan_Smart_Data *psd;
257 evas_object_geometry_get(psd->content, NULL, NULL, &w, &h);
258 if ((w != psd->content_w) || (h != psd->content_h))
262 _elm_pan_update(psd);
264 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
268 _elm_pan_content_set(Evas_Object *obj,
269 Evas_Object *content)
273 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
275 if (content == psd->content) return;
278 evas_object_smart_member_del(psd->content);
279 evas_object_event_callback_del_full
280 (psd->content, EVAS_CALLBACK_DEL, _elm_pan_content_del_cb, psd);
281 evas_object_event_callback_del_full
282 (psd->content, EVAS_CALLBACK_RESIZE, _elm_pan_content_resize_cb,
286 if (!content) goto end;
288 psd->content = content;
289 evas_object_smart_member_add(psd->content, psd->self);
290 evas_object_geometry_get(psd->content, NULL, NULL, &w, &h);
293 evas_object_event_callback_add
294 (content, EVAS_CALLBACK_DEL, _elm_pan_content_del_cb, psd);
295 evas_object_event_callback_add
296 (content, EVAS_CALLBACK_RESIZE, _elm_pan_content_resize_cb, psd);
298 if (evas_object_visible_get(psd->self))
299 evas_object_show(psd->content);
301 evas_object_hide(psd->content);
303 _elm_pan_update(psd);
306 evas_object_smart_callback_call(psd->self, SIG_CHANGED, NULL);
310 _elm_pan_class_constructor(Eo_Class *klass)
312 evas_smart_legacy_type_register(MY_PAN_CLASS_NAME_LEGACY, klass);
315 /* pan smart object on top, scroller interface on bottom */
316 /* ============================================================ */
318 #define MY_SCROLLABLE_INTERFACE ELM_INTERFACE_SCROLLABLE_MIXIN
320 #define MY_SCROLLABLE_INTERFACE_NAME "Elm_Interface_Scrollable"
321 #define MY_SCROLLABLE_INTERFACE_NAME_LEGACY "elm_interface_scrollable"
323 #define ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(o, ptr) \
324 Elm_Scrollable_Smart_Interface_Data *ptr = \
325 (!eo_isa(o, MY_SCROLLABLE_INTERFACE) ? NULL : \
326 eo_data_scope_get(o, MY_SCROLLABLE_INTERFACE)); \
329 CRI("No interface data for object %p (%s)", \
330 o, evas_object_type_get(o)); \
334 #define ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
335 Elm_Scrollable_Smart_Interface_Data *ptr = \
336 (!eo_isa(o, MY_SCROLLABLE_INTERFACE) ? NULL : \
337 eo_data_scope_get(o, MY_SCROLLABLE_INTERFACE)); \
340 CRI("No interface data for object %p (%s)", \
341 o, evas_object_type_get(o)); \
345 static void _elm_scroll_scroll_bar_size_adjust(
346 Elm_Scrollable_Smart_Interface_Data *);
347 static Eina_Bool _paging_is_enabled(Elm_Scrollable_Smart_Interface_Data *sid);
348 static Evas_Coord _elm_scroll_page_x_get(
349 Elm_Scrollable_Smart_Interface_Data *sid, int offset, Eina_Bool limit);
350 static Evas_Coord _elm_scroll_page_y_get(
351 Elm_Scrollable_Smart_Interface_Data *sid, int offset, Eina_Bool limit);
358 //#define SCROLLDBG 1
359 /* smoothness debug calls - for debugging how much smooth your app is */
363 #define SMOOTH_DEBUG_COUNT 100
366 typedef struct _smooth_debug_info smooth_debug_info;
367 struct _smooth_debug_info
376 static smooth_debug_info smooth_x_history[SMOOTH_DEBUG_COUNT];
377 static smooth_debug_info smooth_y_history[SMOOTH_DEBUG_COUNT];
378 static int smooth_info_x_count = 0;
379 static int smooth_info_y_count = 0;
380 static double start_time = 0;
381 static int _elm_scroll_smooth_debug = 0;
384 _elm_scroll_smooth_debug_init(void)
386 start_time = ecore_time_get();
387 smooth_info_x_count = 0;
388 smooth_info_y_count = 0;
390 memset(&(smooth_x_history[0]), 0,
391 sizeof(smooth_x_history[0]) * SMOOTH_DEBUG_COUNT);
392 memset(&(smooth_y_history[0]), 0,
393 sizeof(smooth_y_history[0]) * SMOOTH_DEBUG_COUNT);
399 _elm_scroll_smooth_debug_shutdown(void)
402 int info_x_count = 0;
403 int info_y_count = 0;
404 double x_ave = 0, y_ave = 0;
405 double x_sum = 0, y_sum = 0;
406 double x_dev = 0, y_dev = 0;
407 double x_dev_sum = 0, y_dev_sum = 0;
409 if (smooth_info_x_count >= SMOOTH_DEBUG_COUNT)
410 info_x_count = SMOOTH_DEBUG_COUNT;
412 info_x_count = smooth_info_x_count;
414 if (smooth_info_y_count >= SMOOTH_DEBUG_COUNT)
415 info_y_count = SMOOTH_DEBUG_COUNT;
417 info_y_count = smooth_info_y_count;
419 DBG("\n\n<<< X-axis Smoothness >>>\n");
420 DBG("| Num | t(time) | dt | x | dx |vx(dx/1fps) |\n");
422 for (i = info_x_count - 1; i >= 0; i--)
424 DBG("| %4d | %1.6f | %1.6f | %4d | %4d | %9.3f |\n", info_x_count - i,
425 smooth_x_history[i].t,
426 smooth_x_history[i].dt,
427 smooth_x_history[i].pos,
428 smooth_x_history[i].dpos,
429 smooth_x_history[i].vpos);
430 if (i == info_x_count - 1) continue;
431 x_sum += smooth_x_history[i].vpos;
434 x_ave = x_sum / (info_x_count - 1);
435 for (i = 0; i < info_x_count - 1; i++)
437 x_dev_sum += (smooth_x_history[i].vpos - x_ave) *
438 (smooth_x_history[i].vpos - x_ave);
440 x_dev = x_dev_sum / (info_x_count - 1);
441 DBG(" Standard deviation of X-axis velocity: %9.3f\n", sqrt(x_dev));
443 DBG("\n\n<<< Y-axis Smoothness >>>\n");
444 DBG("| Num | t(time) | dt | y | dy |vy(dy/1fps) |\n");
445 for (i = info_y_count - 1; i >= 0; i--)
447 DBG("| %4d | %1.6f | %1.6f | %4d | %4d | %9.3f |\n", info_y_count - i,
448 smooth_y_history[i].t,
449 smooth_y_history[i].dt,
450 smooth_y_history[i].pos,
451 smooth_y_history[i].dpos,
452 smooth_y_history[i].vpos);
453 if (i == info_y_count - 1) continue;
454 y_sum += smooth_y_history[i].vpos;
456 y_ave = y_sum / (info_y_count - 1);
457 for (i = 0; i < info_y_count - 1; i++)
459 y_dev_sum += (smooth_y_history[i].vpos - y_ave) *
460 (smooth_y_history[i].vpos - y_ave);
462 y_dev = y_dev_sum / (info_y_count - 1);
464 DBG(" Standard deviation of Y-axis velocity: %9.3f\n", sqrt(y_dev));
468 _elm_direction_arrows_eval(Elm_Scrollable_Smart_Interface_Data *sid)
470 Eina_Bool go_left = EINA_TRUE, go_right = EINA_TRUE;
471 Eina_Bool go_up = EINA_TRUE, go_down = EINA_TRUE;
472 Evas_Coord x = 0, y = 0, mx = 0, my = 0, minx = 0, miny = 0;
474 if (!sid->edje_obj || !sid->pan_obj) return;
476 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
477 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
478 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&x, &y));
480 if (x == minx) go_left = EINA_FALSE;
481 if (x == (mx + minx)) go_right = EINA_FALSE;
482 if (y == miny) go_up = EINA_FALSE;
483 if (y == (my + miny)) go_down = EINA_FALSE;
484 if (go_left != sid->go_left)
487 edje_object_signal_emit(sid->edje_obj, "elm,action,show,left", "elm");
489 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,left", "elm");
490 sid->go_left = go_left;
492 if (go_right != sid->go_right)
495 edje_object_signal_emit(sid->edje_obj, "elm,action,show,right", "elm");
497 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,right", "elm");
498 sid->go_right= go_right;
500 if (go_up != sid->go_up)
503 edje_object_signal_emit(sid->edje_obj, "elm,action,show,up", "elm");
505 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,up", "elm");
508 if (go_down != sid->go_down)
511 edje_object_signal_emit(sid->edje_obj, "elm,action,show,down", "elm");
513 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,down", "elm");
514 sid->go_down= go_down;
519 _elm_scroll_smooth_debug_movetime_add(int x,
526 tim = ecore_time_get();
530 smooth_info_x_count++;
531 memmove(&(smooth_x_history[1]), &(smooth_x_history[0]),
532 sizeof(smooth_x_history[0]) * (SMOOTH_DEBUG_COUNT - 1));
533 smooth_x_history[0].t = tim - start_time;
534 smooth_x_history[0].dt = smooth_x_history[0].t - smooth_x_history[1].t;
535 smooth_x_history[0].pos = x;
536 smooth_x_history[0].dpos =
537 smooth_x_history[0].pos - smooth_x_history[1].pos;
539 if (smooth_x_history[0].dpos >= 0)
540 smooth_x_history[0].vpos = (double)(smooth_x_history[0].dpos) /
541 smooth_x_history[0].dt * FPS;
543 smooth_x_history[0].vpos = -((double)(smooth_x_history[0].dpos) /
544 smooth_x_history[0].dt * FPS);
549 smooth_info_y_count++;
550 memmove(&(smooth_y_history[1]), &(smooth_y_history[0]),
551 sizeof(smooth_y_history[0]) * (SMOOTH_DEBUG_COUNT - 1));
552 smooth_y_history[0].t = tim - start_time;
553 smooth_y_history[0].dt = smooth_y_history[0].t - smooth_y_history[1].t;
554 smooth_y_history[0].pos = y;
555 smooth_y_history[0].dpos = smooth_y_history[0].pos -
556 smooth_y_history[1].pos;
558 if (smooth_y_history[0].dpos >= 0)
559 smooth_y_history[0].vpos = (double)(smooth_y_history[0].dpos) /
560 smooth_y_history[0].dt * FPS;
562 smooth_y_history[0].vpos = -((double)(smooth_y_history[0].dpos) /
563 smooth_y_history[0].dt * FPS);
573 _elm_scroll_scroll_bar_h_visibility_apply(Elm_Scrollable_Smart_Interface_Data *sid)
575 if (sid->hbar_flags != ELM_SCROLLER_POLICY_OFF)
577 if (sid->hbar_visible)
578 edje_object_signal_emit
579 (sid->edje_obj, "elm,action,show,hbar", "elm");
581 edje_object_signal_emit
582 (sid->edje_obj, "elm,action,hide,hbar", "elm");
585 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,hbar", "elm");
586 edje_object_message_signal_process(sid->edje_obj);
587 _elm_scroll_scroll_bar_size_adjust(sid);
588 if (sid->cb_func.content_min_limit)
589 sid->cb_func.content_min_limit(sid->obj, sid->min_w, sid->min_h);
593 _elm_scroll_scroll_bar_v_visibility_apply(Elm_Scrollable_Smart_Interface_Data *sid)
595 if (sid->vbar_flags != ELM_SCROLLER_POLICY_OFF)
597 if (sid->vbar_visible)
598 edje_object_signal_emit
599 (sid->edje_obj, "elm,action,show,vbar", "elm");
601 edje_object_signal_emit
602 (sid->edje_obj, "elm,action,hide,vbar", "elm");
605 edje_object_signal_emit
606 (sid->edje_obj, "elm,action,hide,vbar", "elm");
607 edje_object_message_signal_process(sid->edje_obj);
608 _elm_scroll_scroll_bar_size_adjust(sid);
609 if (sid->cb_func.content_min_limit)
610 sid->cb_func.content_min_limit(sid->obj, sid->min_w, sid->min_h);
614 _elm_scroll_scroll_bar_h_visibility_adjust(
615 Elm_Scrollable_Smart_Interface_Data *sid)
617 int scroll_h_vis_change = 0;
618 Evas_Coord w, vw = 0, vh = 0;
620 if (!sid->edje_obj) return 0;
622 w = sid->content_info.w;
624 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &vw, &vh);
625 if (sid->hbar_visible)
629 scroll_h_vis_change = 1;
630 sid->hbar_visible = EINA_FALSE;
634 if (sid->hbar_flags == ELM_SCROLLER_POLICY_AUTO)
636 if ((sid->content) || (sid->extern_pan))
640 scroll_h_vis_change = 1;
641 sid->hbar_visible = EINA_FALSE;
646 scroll_h_vis_change = 1;
647 sid->hbar_visible = EINA_FALSE;
650 else if (sid->hbar_flags == ELM_SCROLLER_POLICY_OFF)
652 scroll_h_vis_change = 1;
653 sid->hbar_visible = EINA_FALSE;
661 if (sid->hbar_flags == ELM_SCROLLER_POLICY_AUTO)
663 if ((sid->content) || (sid->extern_pan))
667 scroll_h_vis_change = 1;
668 sid->hbar_visible = EINA_TRUE;
672 else if (sid->hbar_flags == ELM_SCROLLER_POLICY_ON)
674 scroll_h_vis_change = 1;
675 sid->hbar_visible = EINA_TRUE;
680 if (scroll_h_vis_change) _elm_scroll_scroll_bar_h_visibility_apply(sid);
682 _elm_direction_arrows_eval(sid);
683 return scroll_h_vis_change;
687 _elm_scroll_scroll_bar_v_visibility_adjust(
688 Elm_Scrollable_Smart_Interface_Data *sid)
690 int scroll_v_vis_change = 0;
691 Evas_Coord h, vw = 0, vh = 0;
693 if (!sid->edje_obj) return 0;
695 h = sid->content_info.h;
697 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &vw, &vh);
698 if (sid->vbar_visible)
702 scroll_v_vis_change = 1;
703 sid->vbar_visible = EINA_FALSE;
707 if (sid->vbar_flags == ELM_SCROLLER_POLICY_AUTO)
709 if ((sid->content) || (sid->extern_pan))
713 scroll_v_vis_change = 1;
714 sid->vbar_visible = EINA_FALSE;
719 scroll_v_vis_change = 1;
720 sid->vbar_visible = EINA_FALSE;
723 else if (sid->vbar_flags == ELM_SCROLLER_POLICY_OFF)
725 scroll_v_vis_change = 1;
726 sid->vbar_visible = EINA_FALSE;
734 if (sid->vbar_flags == ELM_SCROLLER_POLICY_AUTO)
736 if ((sid->content) || (sid->extern_pan))
740 scroll_v_vis_change = 1;
741 sid->vbar_visible = EINA_TRUE;
745 else if (sid->vbar_flags == ELM_SCROLLER_POLICY_ON)
747 scroll_v_vis_change = 1;
748 sid->vbar_visible = EINA_TRUE;
752 if (scroll_v_vis_change) _elm_scroll_scroll_bar_v_visibility_apply(sid);
754 _elm_direction_arrows_eval(sid);
755 return scroll_v_vis_change;
759 _elm_scroll_scroll_bar_visibility_adjust(
760 Elm_Scrollable_Smart_Interface_Data *sid)
764 changed |= _elm_scroll_scroll_bar_h_visibility_adjust(sid);
765 changed |= _elm_scroll_scroll_bar_v_visibility_adjust(sid);
769 _elm_scroll_scroll_bar_h_visibility_adjust(sid);
770 _elm_scroll_scroll_bar_v_visibility_adjust(sid);
775 _elm_scroll_scroll_bar_size_adjust(Elm_Scrollable_Smart_Interface_Data *sid)
777 if (!sid->pan_obj || !sid->edje_obj) return;
779 if (sid->size_adjust_recurse_abort) return;
780 if (sid->size_adjust_recurse > 20)
782 sid->size_adjust_recurse_abort = EINA_TRUE;
785 sid->size_adjust_recurse++;
786 if ((sid->content) || (sid->extern_pan))
788 Evas_Coord x, y, w, h, mx = 0, my = 0, vw = 0, vh = 0,
792 edje_object_part_geometry_get
793 (sid->edje_obj, "elm.swallow.content", NULL, NULL, &vw, &vh);
794 w = sid->content_info.w;
796 size = (double)vw / (double)w;
801 edje_object_part_drag_value_set
802 (sid->edje_obj, "elm.dragable.hbar", 0.0, 0.0);
804 edje_object_part_drag_size_set
805 (sid->edje_obj, "elm.dragable.hbar", size, 1.0);
807 h = sid->content_info.h;
809 size = (double)vh / (double)h;
813 edje_object_part_drag_value_set
814 (sid->edje_obj, "elm.dragable.vbar", 0.0, 0.0);
816 edje_object_part_drag_size_set
817 (sid->edje_obj, "elm.dragable.vbar", 1.0, size);
819 //TIZEN_ONLY(20150909) : Use the specific bar_chagnged_bar_pos_adjust func only for gengrid.
820 //edje_object_part_drag_value_get
821 // (sid->edje_obj, "elm.dragable.hbar", &vx, NULL);
822 //edje_object_part_drag_value_get
823 // (sid->edje_obj, "elm.dragable.vbar", NULL, &vy);
826 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
827 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
828 //TIZEN_ONLY(20150909) : Use the specific bar_chagnged_bar_pos_adjust func only for gengrid.
829 //x = vx * mx + minx;
830 //y = vy * my + miny;
833 edje_object_part_drag_step_set
834 (sid->edje_obj, "elm.dragable.hbar", (double)sid->step.x /
836 edje_object_part_drag_step_set
837 (sid->edje_obj, "elm.dragable.vbar", 0.0, (double)sid->step.y /
840 edje_object_part_drag_page_set
841 (sid->edje_obj, "elm.dragable.hbar", (double)sid->page.x /
844 edje_object_part_drag_page_set
845 (sid->edje_obj, "elm.dragable.hbar",
846 -((double)sid->page.x * ((double)vw / (double)w)) / 100.0, 0.0);
848 edje_object_part_drag_page_set
849 (sid->edje_obj, "elm.dragable.vbar", 0.0,
850 (double)sid->page.y / (double)h);
852 edje_object_part_drag_page_set
853 (sid->edje_obj, "elm.dragable.vbar", 0.0,
854 -((double)sid->page.y * ((double)vh / (double)h)) / 100.0);
856 //TIZEN_ONLY(20150909) : Use the specific bar_chagnged_bar_pos_adjust func only for gengrid.
857 //eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
859 //if (vx != mx) x = px;
860 //if (vy != my) y = py;
862 eo_do(sid->obj, elm_interface_scrollable_bar_changed_bar_pos_adjust(&x, &y));
865 eo_do(sid->pan_obj, elm_obj_pan_pos_set(x, y));
867 if (mx > 0) vx = (double)(x - minx) / (double)mx;
870 if (vx < 0.0) vx = 0.0;
874 if (my > 0) vy = (double)(y - miny) / (double)my;
877 if (vy < 0.0) vy = 0.0;
881 edje_object_part_drag_value_set
882 (sid->edje_obj, "elm.dragable.vbar", 0.0, vy);
883 edje_object_part_drag_value_set
884 (sid->edje_obj, "elm.dragable.hbar", vx, 0.0);
888 Evas_Coord px = 0, py = 0, minx = 0, miny = 0;
890 edje_object_part_drag_size_set
891 (sid->edje_obj, "elm.dragable.vbar", 1.0, 1.0);
892 edje_object_part_drag_size_set
893 (sid->edje_obj, "elm.dragable.hbar", 1.0, 1.0);
894 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
895 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
896 eo_do(sid->pan_obj, elm_obj_pan_pos_set(minx, miny));
897 if ((px != minx) || (py != miny))
898 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
900 _elm_scroll_scroll_bar_visibility_adjust(sid);
901 sid->size_adjust_recurse--;
902 if (sid->size_adjust_recurse <= 0)
904 sid->size_adjust_recurse = 0;
905 sid->size_adjust_recurse_abort = EINA_FALSE;
909 //TIZEN_ONLY(20150909) : Use the specific bar_chagnged_bar_pos_adjust func only for gengrid.
911 _elm_interface_scrollable_bar_changed_bar_pos_adjust(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord *x, Evas_Coord *y)
913 Evas_Coord mx, my, minx, miny, px, py;
916 edje_object_part_drag_value_get
917 (sid->edje_obj, "elm.dragable.hbar", &vx, NULL);
918 edje_object_part_drag_value_get
919 (sid->edje_obj, "elm.dragable.vbar", NULL, &vy);
921 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
922 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
924 *x = _round(vx * (double)mx + minx, 1);
925 *y = _round(vy * (double)my + miny, 1);
927 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
929 if (vx != mx) *x = px;
930 if (vy != my) *y = py;
935 _elm_scroll_scroll_bar_read_and_update(
936 Elm_Scrollable_Smart_Interface_Data *sid)
938 Evas_Coord x, y, mx = 0, my = 0, minx = 0, miny = 0;
941 if (!sid->edje_obj || !sid->pan_obj) return;
943 if ((sid->down.dragged) || (sid->down.bounce_x_animator)
944 || (sid->down.bounce_y_animator) || (sid->down.momentum_animator)
945 || (sid->scrollto.x.animator) || (sid->scrollto.y.animator))
947 edje_object_part_drag_value_get
948 (sid->edje_obj, "elm.dragable.vbar", NULL, &vy);
949 edje_object_part_drag_value_get
950 (sid->edje_obj, "elm.dragable.hbar", &vx, NULL);
951 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
952 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
953 x = _round(vx * (double)mx + minx, 1);
954 y = _round(vy * (double)my + miny, 1);
955 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
956 _elm_scroll_wanted_coordinates_update(sid, x, y);
960 _elm_scroll_drag_start(Elm_Scrollable_Smart_Interface_Data *sid)
962 sid->current_page.x = _elm_scroll_page_x_get(sid, 0, EINA_FALSE);
963 sid->current_page.y = _elm_scroll_page_y_get(sid, 0, EINA_FALSE);
965 if (sid->cb_func.drag_start)
966 sid->cb_func.drag_start(sid->obj, NULL);
970 _elm_scroll_drag_stop(Elm_Scrollable_Smart_Interface_Data *sid)
974 if (!(sid->down.bounce_x_animator) && !(sid->down.bounce_y_animator) &&
975 !(sid->scrollto.x.animator) && !(sid->scrollto.y.animator))
977 x = _elm_scroll_page_x_get(sid, 0, EINA_FALSE);
978 y = _elm_scroll_page_y_get(sid, 0, EINA_FALSE);
979 if (sid->cb_func.page_change &&
980 ((x != sid->current_page.x) || (y != sid->current_page.y)))
981 sid->cb_func.page_change(sid->obj, NULL);
984 if (sid->cb_func.drag_stop)
985 sid->cb_func.drag_stop(sid->obj, NULL);
989 _elm_scroll_anim_start(Elm_Scrollable_Smart_Interface_Data *sid)
991 if (sid->cb_func.animate_start)
992 sid->cb_func.animate_start(sid->obj, NULL);
996 _elm_scroll_anim_stop(Elm_Scrollable_Smart_Interface_Data *sid)
1000 if (sid->cb_func.page_change)
1002 x = _elm_scroll_page_x_get(sid, 0, EINA_FALSE);
1003 y = _elm_scroll_page_y_get(sid, 0, EINA_FALSE);
1004 if ((x != sid->current_page.x) || (y != sid->current_page.y))
1005 sid->cb_func.page_change(sid->obj, NULL);
1008 if (sid->cb_func.animate_stop)
1009 sid->cb_func.animate_stop(sid->obj, NULL);
1013 _elm_scroll_policy_signal_emit(Elm_Scrollable_Smart_Interface_Data *sid)
1015 if (sid->hbar_flags == ELM_SCROLLER_POLICY_ON)
1016 edje_object_signal_emit
1017 (sid->edje_obj, "elm,action,show_always,hbar", "elm");
1018 else if (sid->hbar_flags == ELM_SCROLLER_POLICY_OFF)
1019 edje_object_signal_emit
1020 (sid->edje_obj, "elm,action,hide,hbar", "elm");
1022 edje_object_signal_emit
1023 (sid->edje_obj, "elm,action,show_notalways,hbar", "elm");
1024 if (sid->vbar_flags == ELM_SCROLLER_POLICY_ON)
1025 edje_object_signal_emit
1026 (sid->edje_obj, "elm,action,show_always,vbar", "elm");
1027 else if (sid->vbar_flags == ELM_SCROLLER_POLICY_OFF)
1028 edje_object_signal_emit
1029 (sid->edje_obj, "elm,action,hide,vbar", "elm");
1031 edje_object_signal_emit
1032 (sid->edje_obj, "elm,action,show_notalways,vbar", "elm");
1033 edje_object_message_signal_process(sid->edje_obj);
1034 _elm_scroll_scroll_bar_size_adjust(sid);
1038 _elm_scroll_reload_cb(void *data,
1039 Evas_Object *obj EINA_UNUSED,
1040 const char *emission EINA_UNUSED,
1041 const char *source EINA_UNUSED)
1043 Elm_Scrollable_Smart_Interface_Data *sid = data;
1044 _elm_scroll_policy_signal_emit(sid);
1045 _elm_scroll_scroll_bar_h_visibility_apply(sid);
1046 _elm_scroll_scroll_bar_v_visibility_apply(sid);
1050 _elm_scroll_vbar_drag_cb(void *data,
1051 Evas_Object *obj EINA_UNUSED,
1052 const char *emission EINA_UNUSED,
1053 const char *source EINA_UNUSED)
1055 Elm_Scrollable_Smart_Interface_Data *sid = data;
1057 if (sid->cb_func.vbar_drag)
1058 sid->cb_func.vbar_drag(sid->obj, NULL);
1060 _elm_scroll_scroll_bar_read_and_update(sid);
1064 _elm_scroll_vbar_press_cb(void *data,
1065 Evas_Object *obj EINA_UNUSED,
1066 const char *emission EINA_UNUSED,
1067 const char *source EINA_UNUSED)
1069 Elm_Scrollable_Smart_Interface_Data *sid = data;
1071 if (sid->cb_func.vbar_press)
1072 sid->cb_func.vbar_press(sid->obj, NULL);
1076 _elm_scroll_vbar_unpress_cb(void *data,
1077 Evas_Object *obj EINA_UNUSED,
1078 const char *emission EINA_UNUSED,
1079 const char *source EINA_UNUSED)
1081 Elm_Scrollable_Smart_Interface_Data *sid = data;
1083 if (sid->cb_func.vbar_unpress)
1084 sid->cb_func.vbar_unpress(sid->obj, NULL);
1088 _elm_scroll_edje_drag_v_start_cb(void *data,
1089 Evas_Object *obj EINA_UNUSED,
1090 const char *emission EINA_UNUSED,
1091 const char *source EINA_UNUSED)
1093 Elm_Scrollable_Smart_Interface_Data *sid = data;
1095 _elm_scroll_scroll_bar_read_and_update(sid);
1096 _elm_scroll_drag_start(sid);
1097 sid->freeze = EINA_TRUE;
1101 _elm_scroll_edje_drag_v_stop_cb(void *data,
1102 Evas_Object *obj EINA_UNUSED,
1103 const char *emission EINA_UNUSED,
1104 const char *source EINA_UNUSED)
1106 Elm_Scrollable_Smart_Interface_Data *sid = data;
1108 _elm_scroll_scroll_bar_read_and_update(sid);
1109 _elm_scroll_drag_stop(sid);
1110 sid->freeze = EINA_FALSE;
1114 _elm_scroll_edje_drag_v_cb(void *data,
1115 Evas_Object *obj EINA_UNUSED,
1116 const char *emission EINA_UNUSED,
1117 const char *source EINA_UNUSED)
1119 Elm_Scrollable_Smart_Interface_Data *sid = data;
1121 _elm_scroll_scroll_bar_read_and_update(sid);
1125 _elm_scroll_hbar_drag_cb(void *data,
1126 Evas_Object *obj EINA_UNUSED,
1127 const char *emission EINA_UNUSED,
1128 const char *source EINA_UNUSED)
1130 Elm_Scrollable_Smart_Interface_Data *sid = data;
1132 if (sid->cb_func.hbar_drag)
1133 sid->cb_func.hbar_drag(sid->obj, NULL);
1135 _elm_scroll_scroll_bar_read_and_update(sid);
1139 _elm_scroll_hbar_press_cb(void *data,
1140 Evas_Object *obj EINA_UNUSED,
1141 const char *emission EINA_UNUSED,
1142 const char *source EINA_UNUSED)
1144 Elm_Scrollable_Smart_Interface_Data *sid = data;
1146 if (sid->cb_func.hbar_press)
1147 sid->cb_func.hbar_press(sid->obj, NULL);
1151 _elm_scroll_hbar_unpress_cb(void *data,
1152 Evas_Object *obj EINA_UNUSED,
1153 const char *emission EINA_UNUSED,
1154 const char *source EINA_UNUSED)
1156 Elm_Scrollable_Smart_Interface_Data *sid = data;
1158 if (sid->cb_func.hbar_unpress)
1159 sid->cb_func.hbar_unpress(sid->obj, NULL);
1163 _elm_scroll_edje_drag_h_start_cb(void *data,
1164 Evas_Object *obj EINA_UNUSED,
1165 const char *emission EINA_UNUSED,
1166 const char *source EINA_UNUSED)
1168 Elm_Scrollable_Smart_Interface_Data *sid = data;
1170 _elm_scroll_scroll_bar_read_and_update(sid);
1171 _elm_scroll_drag_start(sid);
1172 sid->freeze = EINA_TRUE;
1176 _elm_scroll_edje_drag_h_stop_cb(void *data,
1177 Evas_Object *obj EINA_UNUSED,
1178 const char *emission EINA_UNUSED,
1179 const char *source EINA_UNUSED)
1181 Elm_Scrollable_Smart_Interface_Data *sid = data;
1183 _elm_scroll_scroll_bar_read_and_update(sid);
1184 _elm_scroll_drag_stop(sid);
1185 sid->freeze = EINA_FALSE;
1189 _elm_scroll_edje_drag_h_cb(void *data,
1190 Evas_Object *obj EINA_UNUSED,
1191 const char *emission EINA_UNUSED,
1192 const char *source EINA_UNUSED)
1194 Elm_Scrollable_Smart_Interface_Data *sid = data;
1196 _elm_scroll_scroll_bar_read_and_update(sid);
1200 _elm_interface_scrollable_content_size_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord *w, Evas_Coord *h)
1202 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(w, h));
1206 _elm_interface_scrollable_content_viewport_geometry_get(Eo *obj EINA_UNUSED,
1207 Elm_Scrollable_Smart_Interface_Data *sid,
1213 if (!sid->pan_obj || !sid->edje_obj) return;
1215 edje_object_calc_force(sid->edje_obj);
1216 evas_object_geometry_get(sid->pan_obj, x, y, w, h);
1220 _elm_interface_scrollable_content_min_limit(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool w, Eina_Bool h)
1222 if (!sid->edje_obj) return;
1224 if (!sid->cb_func.content_min_limit)
1226 ERR("Content minimim size limiting is unimplemented -- you "
1227 "must provide it yourself\n");
1233 sid->cb_func.content_min_limit(sid->obj, w, h);
1237 _elm_scroll_x_mirrored_get(const Evas_Object *obj,
1240 Evas_Coord cw = 0, w = 0, min = 0, ret;
1242 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, x);
1244 if (!sid->pan_obj) return 0;
1246 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&min, NULL));
1247 eo_do((Eo *)obj, elm_interface_scrollable_content_viewport_geometry_get
1248 (NULL, NULL, &w, NULL));
1249 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&cw, NULL));
1250 ret = cw - w - x + min + min;
1252 return (ret >= min) ? ret : min;
1255 /* Update the wanted coordinates according to the x, y passed
1256 * widget directionality, content size and etc. */
1258 _elm_scroll_wanted_coordinates_update(Elm_Scrollable_Smart_Interface_Data *sid,
1262 Evas_Coord mx = 0, my = 0, minx = 0, miny = 0;
1264 if (!sid->pan_obj) return;
1266 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
1267 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
1269 /* Update wx/y/w/h - and if the requested positions aren't legal
1271 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
1272 (NULL, NULL, &sid->ww, &sid->wh));
1274 if (x < minx && !sid->is_mirrored)
1276 if (!sid->loop_h) sid->wx = minx;
1279 else if (sid->is_mirrored)
1280 sid->wx = _elm_scroll_x_mirrored_get(sid->obj, x);
1281 else if (!sid->loop_h && (x > mx)) sid->wx = mx;
1282 else if (sid->loop_h && x >= (sid->ww + mx)) sid->wx = 0;
1287 if (!sid->loop_v) sid->wy = miny;
1290 else if (!sid->loop_v && (y > my)) sid->wy = my;
1291 else if (sid->loop_v && y >= (sid->wh + my)) sid->wy = 0;
1296 _elm_scroll_momentum_end(Elm_Scrollable_Smart_Interface_Data *sid)
1298 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator)) return;
1299 if (sid->down.momentum_animator)
1301 Evas_Coord px = 0, py = 0;
1302 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&px, &py));
1303 _elm_scroll_wanted_coordinates_update(sid, px, py);
1305 ELM_SAFE_FREE(sid->down.momentum_animator, ecore_animator_del);
1306 sid->down.bounce_x_hold = EINA_FALSE;
1307 sid->down.bounce_y_hold = EINA_FALSE;
1314 if (sid->content_info.resized)
1315 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
1316 //_elm_scroll_wanted_region_set(sid->obj);
1317 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
1323 _elm_scroll_bounce_x_animator(void *data)
1325 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(data, sid, EINA_FALSE);
1326 Evas_Coord x, y, dx, w, odx, ed, md;
1327 double t, p, dt, pd, r;
1329 t = ecore_loop_time_get();
1330 dt = t - sid->down.anim_start2;
1333 dt = dt / _elm_config->thumbscroll_bounce_friction;
1334 odx = sid->down.b2x - sid->down.bx;
1335 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
1336 (NULL, NULL, &w, NULL));
1337 if (!sid->down.momentum_animator && (w > abs(odx)))
1339 pd = (double)odx / (double)w;
1340 pd = (pd > 0) ? pd : -pd;
1341 pd = 1.0 - ((1.0 - pd) * (1.0 - pd));
1344 if (dt > 1.0) dt = 1.0;
1345 p = 1.0 - ((1.0 - dt) * (1.0 - dt));
1346 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
1349 if (sid->down.momentum_animator)
1351 ed = abs(sid->down.dx * (_elm_config->thumbscroll_friction +
1352 sid->down.extra_time) - sid->down.b0x);
1353 md = abs(_elm_config->thumbscroll_friction * 5 * w);
1354 if (ed > md) r = (double)(md) / (double)ed;
1356 x = sid->down.b2x + (int)((double)(dx - odx) * r);
1357 if (!sid->down.cancelled)
1358 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
1361 if (sid->down.momentum_animator)
1362 sid->down.bounce_x_hold = EINA_TRUE;
1363 if ((!sid->down.bounce_y_animator) &&
1364 (!sid->scrollto.y.animator))
1365 _elm_scroll_anim_stop(sid);
1366 sid->down.bounce_x_animator = NULL;
1368 sid->bouncemex = EINA_FALSE;
1369 _elm_scroll_momentum_end(sid);
1370 if (sid->content_info.resized)
1371 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
1372 //_elm_scroll_wanted_region_set(sid->obj);
1373 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
1375 return ECORE_CALLBACK_CANCEL;
1378 return ECORE_CALLBACK_RENEW;
1382 _elm_scroll_bounce_y_animator(void *data)
1384 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(data, sid, EINA_FALSE);
1385 Evas_Coord x, y, dy, h, ody, ed, md;
1386 double t, p, dt, pd, r;
1388 t = ecore_loop_time_get();
1389 dt = t - sid->down.anim_start3;
1392 dt = dt / _elm_config->thumbscroll_bounce_friction;
1393 ody = sid->down.b2y - sid->down.by;
1394 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
1395 (NULL, NULL, NULL, &h));
1396 if (!sid->down.momentum_animator && (h > abs(ody)))
1398 pd = (double)ody / (double)h;
1399 pd = (pd > 0) ? pd : -pd;
1400 pd = 1.0 - ((1.0 - pd) * (1.0 - pd));
1403 if (dt > 1.0) dt = 1.0;
1404 p = 1.0 - ((1.0 - dt) * (1.0 - dt));
1405 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
1408 if (sid->down.momentum_animator)
1410 ed = abs(sid->down.dy * (_elm_config->thumbscroll_friction +
1411 sid->down.extra_time) - sid->down.b0y);
1412 md = abs(_elm_config->thumbscroll_friction * 5 * h);
1413 if (ed > md) r = (double)(md) / (double)ed;
1415 y = sid->down.b2y + (int)((double)(dy - ody) * r);
1416 if (!sid->down.cancelled)
1417 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
1420 if (sid->down.momentum_animator)
1421 sid->down.bounce_y_hold = EINA_TRUE;
1422 if ((!sid->down.bounce_x_animator) &&
1423 (!sid->scrollto.y.animator))
1424 _elm_scroll_anim_stop(sid);
1425 sid->down.bounce_y_animator = NULL;
1427 sid->bouncemey = EINA_FALSE;
1428 _elm_scroll_momentum_end(sid);
1429 if (sid->content_info.resized)
1430 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
1431 //_elm_scroll_wanted_region_set(sid->obj);
1432 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
1434 return ECORE_CALLBACK_CANCEL;
1438 return ECORE_CALLBACK_RENEW;
1442 _elm_scroll_bounce_eval(Elm_Scrollable_Smart_Interface_Data *sid)
1444 Evas_Coord mx = 0, my = 0, px = 0, py = 0, bx, by, b2x, b2y, minx = 0, miny = 0;
1446 if (!sid->pan_obj) return;
1448 if (sid->freeze) return;
1449 if ((!sid->bouncemex) && (!sid->bouncemey)) return;
1450 if (sid->down.now) return; // down bounce while still held down
1451 if (sid->down.onhold_animator)
1453 ELM_SAFE_FREE(sid->down.onhold_animator, ecore_animator_del);
1454 if (sid->content_info.resized)
1455 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
1456 //_elm_scroll_wanted_region_set(sid->obj);
1457 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
1460 if (sid->down.hold_animator)
1462 ELM_SAFE_FREE(sid->down.hold_animator, ecore_animator_del);
1463 if (sid->content_info.resized)
1464 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
1465 //_elm_scroll_wanted_region_set(sid->obj);
1466 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
1469 ELM_SAFE_FREE(sid->down.hold_enterer, ecore_idle_enterer_del);
1471 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
1472 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
1473 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
1476 if (px < minx) px = minx;
1477 if ((px - minx) > mx) px = mx + minx;
1478 if (py < miny) py = miny;
1479 if ((py - miny) > my) py = my + miny;
1483 (!elm_widget_drag_child_locked_x_get(sid->obj)))
1485 if ((!sid->down.bounce_x_animator) && (!sid->bounce_animator_disabled))
1489 ELM_SAFE_FREE(sid->scrollto.x.animator, ecore_animator_del);
1490 sid->down.bounce_x_animator =
1491 ecore_animator_add(_elm_scroll_bounce_x_animator, sid->obj);
1492 sid->down.anim_start2 = ecore_loop_time_get();
1495 sid->down.b2x = b2x;
1496 if (sid->down.momentum_animator)
1497 sid->down.b0x = sid->down.ax;
1498 else sid->down.b0x = 0;
1503 (!elm_widget_drag_child_locked_y_get(sid->obj)))
1505 if ((!sid->down.bounce_y_animator) && (!sid->bounce_animator_disabled))
1509 ELM_SAFE_FREE(sid->scrollto.y.animator, ecore_animator_del);
1510 sid->down.bounce_y_animator =
1511 ecore_animator_add(_elm_scroll_bounce_y_animator, sid->obj);
1512 sid->down.anim_start3 = ecore_loop_time_get();
1515 sid->down.b2y = b2y;
1516 if (sid->down.momentum_animator)
1517 sid->down.b0y = sid->down.ay;
1518 else sid->down.b0y = 0;
1525 _elm_interface_scrollable_content_pos_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord *x, Evas_Coord *y)
1527 if (!sid->pan_obj) return;
1529 eo_do(sid->pan_obj, elm_obj_pan_pos_get(x, y));
1533 _elm_interface_scrollable_content_pos_set(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord x, Evas_Coord y, Eina_Bool sig)
1535 Evas_Coord mx = 0, my = 0, px = 0, py = 0, spx = 0, spy = 0, minx = 0, miny = 0;
1536 Evas_Coord cw = 0, ch = 0, pw = 0, ph = 0;
1537 // TIZEN_ONLY(20150820): Overscroll effect
1538 Evas_Coord ww = 0, wh = 0;
1543 if (!sid->edje_obj || !sid->pan_obj) return;
1545 // FIXME: allow for bounce outside of range
1546 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
1547 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
1548 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&cw, &ch));
1549 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
1550 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &pw, &ph);
1551 // TIZEN_ONLY(20150820): Overscroll effect
1552 eo_do(obj, elm_interface_scrollable_content_viewport_geometry_get
1553 (NULL, NULL, &ww, &wh));
1556 if (_paging_is_enabled(sid))
1558 if (sid->page_snap_horiz)
1560 //we passed one page to the right
1561 if (x > sid->current_page.x + sid->pagesize_h)
1562 x = sid->current_page.x + sid->pagesize_h;
1563 //we passed one page to the left
1564 if (x < sid->current_page.x - sid->pagesize_h)
1565 x = sid->current_page.x - sid->pagesize_h;
1567 if (sid->page_snap_vert)
1569 //we passed one page to the bottom
1570 if (y > sid->current_page.y + sid->pagesize_v)
1571 y = sid->current_page.y + sid->pagesize_v;
1572 //we passed one page to the top
1573 if (y < sid->current_page.y - sid->pagesize_v)
1574 y = sid->current_page.y - sid->pagesize_v;
1578 if (sid->loop_h && cw > 0)
1580 if (x < 0) x = cw + (x % cw);
1581 else if (x >= cw) x = (x % cw);
1583 if (sid->loop_v && ch > 0)
1585 if (y < 0) y = ch + (y % ch);
1586 else if (y >= ch) y = (y % ch);
1589 // TIZEN_ONLY(20150820): Overscroll effect
1593 edje_object_signal_emit(sid->edje_obj, "elm,edge,left", "elm");
1594 if (!sid->loop_h && (x - minx) > mx)
1595 edje_object_signal_emit(sid->edje_obj, "elm,edge,right", "elm");
1600 edje_object_signal_emit(sid->edje_obj, "elm,edge,top", "elm");
1601 if (!sid->loop_v && (y - miny) > my)
1602 edje_object_signal_emit(sid->edje_obj, "elm,edge,bottom", "elm");
1606 if (!_elm_config->thumbscroll_bounce_enable)
1609 if (x < minx) x = minx;
1610 if (!sid->loop_h && (x - minx) > mx) x = mx + minx;
1611 if (y < miny) y = miny;
1612 if (!sid->loop_v && (y - miny) > my) y = my + miny;
1615 if (!sid->bounce_horiz)
1617 if (x < minx) x = minx;
1618 if (!sid->loop_h && (x - minx) > mx) x = mx + minx;
1620 if (!sid->bounce_vert)
1622 if (y < miny) y = miny;
1623 if (!sid->loop_v && (y - miny) > my) y = my + miny;
1626 eo_do(sid->pan_obj, elm_obj_pan_pos_set(x, y));
1627 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&spx, &spy));
1629 if (mx > 0) vx = (double)(spx - minx) / (double)mx;
1632 if (vx < 0.0) vx = 0.0;
1636 if (my > 0) vy = (double)(spy - miny) / (double)my;
1639 if (vy < 0.0) vy = 0.0;
1643 edje_object_part_drag_value_set
1644 (sid->edje_obj, "elm.dragable.vbar", 0.0, vy);
1645 edje_object_part_drag_value_set
1646 (sid->edje_obj, "elm.dragable.hbar", vx, 0.0);
1648 if (!sid->loop_h && !sid->down.bounce_x_animator)
1650 if (((x < minx) && (0 <= sid->down.dx)) ||
1651 ((x > (mx + minx)) && (0 >= sid->down.dx)))
1653 sid->bouncemex = EINA_TRUE;
1654 _elm_scroll_bounce_eval(sid);
1657 sid->bouncemex = EINA_FALSE;
1659 if (!sid->loop_v && !sid->down.bounce_y_animator)
1661 if (((y < miny) && (0 <= sid->down.dy)) ||
1662 ((y > (my + miny)) && (0 >= sid->down.dy)))
1664 sid->bouncemey = EINA_TRUE;
1665 _elm_scroll_bounce_eval(sid);
1668 sid->bouncemey = EINA_FALSE;
1673 if ((x != px) || (y != py))
1675 if (sid->cb_func.scroll)
1676 sid->cb_func.scroll(obj, NULL);
1677 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
1680 if (sid->cb_func.scroll_left)
1681 sid->cb_func.scroll_left(obj, NULL);
1682 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,left", "elm");
1686 if (sid->cb_func.scroll_right)
1687 sid->cb_func.scroll_right(obj, NULL);
1688 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,right", "elm");
1692 if (sid->cb_func.scroll_up)
1693 sid->cb_func.scroll_up(obj, NULL);
1694 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,up", "elm");
1698 if (sid->cb_func.scroll_down)
1699 sid->cb_func.scroll_down(obj, NULL);
1700 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,down", "elm");
1707 if (sid->cb_func.edge_left)
1708 sid->cb_func.edge_left(obj, NULL);
1709 //TIZEN_ONLY(20150822): The effect removal it moves to the edge the using item show.
1710 // edje_object_signal_emit(sid->edje_obj, "elm,edge,left", "elm");
1713 if (x == (mx + minx))
1715 if (sid->cb_func.edge_right)
1716 sid->cb_func.edge_right(obj, NULL);
1717 //TIZEN_ONLY(20150822): The effect removal it moves to the edge the using item show.
1718 // edje_object_signal_emit(sid->edje_obj, "elm,edge,right", "elm");
1726 if (sid->cb_func.edge_top)
1727 sid->cb_func.edge_top(obj, NULL);
1728 //TIZEN_ONLY(20150822): The effect removal it moves to the edge the using item show.
1729 // edje_object_signal_emit(sid->edje_obj, "elm,edge,top", "elm");
1734 if (sid->cb_func.edge_bottom)
1735 sid->cb_func.edge_bottom(obj, NULL);
1736 //TIZEN_ONLY(20150822): The effect removal it moves to the edge the using item show.
1737 // edje_object_signal_emit(sid->edje_obj, "elm,edge,bottom", "elm");
1743 _elm_direction_arrows_eval(sid);
1747 _elm_interface_scrollable_mirrored_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool mirrored)
1751 if (!sid->edje_obj) return;
1753 mirrored = !!mirrored;
1755 if (sid->is_mirrored == mirrored)
1758 sid->is_mirrored = mirrored;
1759 edje_object_mirrored_set(sid->edje_obj, mirrored);
1761 if (sid->is_mirrored)
1762 wx = _elm_scroll_x_mirrored_get(sid->obj, sid->wx);
1766 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(wx, sid->wy, EINA_FALSE));
1769 /* returns TRUE when we need to move the scroller, FALSE otherwise.
1770 * Updates w and h either way, so save them if you need them. */
1772 _elm_scroll_content_region_show_internal(Evas_Object *obj,
1778 Evas_Coord mx = 0, my = 0, cw = 0, ch = 0, px = 0, py = 0, nx, ny,
1779 minx = 0, miny = 0, pw = 0, ph = 0, x = *_x, y = *_y;
1781 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
1783 if (!sid->pan_obj) return EINA_FALSE;
1785 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
1786 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
1787 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&cw, &ch));
1788 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
1789 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &pw, &ph);
1792 if ((x < px) && ((x + w) < (px + (cw - mx)))) nx = x;
1793 else if ((x > px) && ((x + w) > (px + (cw - mx))))
1794 nx = x + w - (cw - mx);
1796 if ((y < py) && ((y + h) < (py + (ch - my)))) ny = y;
1797 else if ((y > py) && ((y + h) > (py + (ch - my))))
1798 ny = y + h - (ch - my);
1800 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
1801 (sid->scrollto.x.animator) || (sid->scrollto.y.animator))
1803 ELM_SAFE_FREE(sid->scrollto.x.animator, ecore_animator_del);
1804 ELM_SAFE_FREE(sid->scrollto.y.animator, ecore_animator_del);
1805 if (sid->down.bounce_x_animator)
1807 ELM_SAFE_FREE(sid->down.bounce_x_animator, ecore_animator_del);
1808 sid->bouncemex = EINA_FALSE;
1809 if (sid->content_info.resized)
1810 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
1811 //_elm_scroll_wanted_region_set(sid->obj);
1812 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
1815 if (sid->down.bounce_y_animator)
1817 ELM_SAFE_FREE(sid->down.bounce_y_animator, ecore_animator_del);
1818 sid->bouncemey = EINA_FALSE;
1819 if (sid->content_info.resized)
1820 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
1821 //_elm_scroll_wanted_region_set(sid->obj);
1822 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
1826 _elm_scroll_anim_stop(sid);
1828 if (sid->down.hold_animator)
1830 ELM_SAFE_FREE(sid->down.hold_animator, ecore_animator_del);
1831 _elm_scroll_drag_stop(sid);
1832 if (sid->content_info.resized)
1833 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
1834 //_elm_scroll_wanted_region_set(sid->obj);
1835 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
1838 ELM_SAFE_FREE(sid->down.hold_enterer, ecore_idle_enterer_del);
1839 if (sid->down.momentum_animator)
1841 ELM_SAFE_FREE(sid->down.momentum_animator, ecore_animator_del);
1842 sid->down.bounce_x_hold = EINA_FALSE;
1843 sid->down.bounce_y_hold = EINA_FALSE;
1848 if (sid->content_info.resized)
1849 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
1850 //_elm_scroll_wanted_region_set(sid->obj);
1851 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
1855 if (_paging_is_enabled(sid))
1857 x = _elm_scroll_page_x_get(sid, nx - px, EINA_FALSE);
1858 y = _elm_scroll_page_y_get(sid, ny - py, EINA_FALSE);
1867 if ((x + pw) > cw) x = cw - pw;
1868 if (x < minx) x = minx;
1872 if ((y + ph) > ch) y = ch - ph;
1873 if (y < miny) y = miny;
1876 if ((x == px) && (y == py)) return EINA_FALSE;
1883 _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)
1885 eo_do(obj, elm_interface_scrollable_content_pos_get(x, y));
1886 eo_do(obj, elm_interface_scrollable_content_viewport_geometry_get
1887 (NULL, NULL, w, h));
1890 /* Set should be used for calculated positions, for example, when we move
1891 * because of an animation or because this is the correct position after
1894 _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)
1896 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
1898 eo_do(obj, elm_interface_scrollable_content_pos_set(x, y, EINA_FALSE));
1901 sid->down.x = sid->down.history[0].x;
1902 sid->down.y = sid->down.history[0].y;
1906 /* Set should be used for setting the wanted position, for example a
1907 * user scroll or moving the cursor in an entry. */
1909 _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)
1911 sid->wx = (sid->is_mirrored ? _elm_scroll_x_mirrored_get(sid->obj, x) : x);
1915 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
1917 eo_do(obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
1920 sid->down.x = sid->down.history[0].x;
1921 sid->down.y = sid->down.history[0].y;
1925 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
1927 //_elm_scroll_wanted_region_set(Evas_Object *obj)
1929 // Evas_Coord ww, wh, wx;
1931 // ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1934 // if (sid->down.now || sid->down.momentum_animator ||
1935 // sid->down.bounce_x_animator || sid->down.bounce_y_animator ||
1936 // sid->down.hold_animator || sid->down.onhold_animator ||
1937 // sid->scrollto.x.animator || sid->scrollto.y.animator)
1940 // sid->content_info.resized = EINA_FALSE;
1942 // /* Flip to RTL cords only if init in RTL mode */
1943 // if (sid->is_mirrored)
1944 // wx = _elm_scroll_x_mirrored_get(obj, sid->wx);
1946 // if (sid->ww == -1)
1948 // eo_do(obj, elm_interface_scrollable_content_viewport_geometry_get
1949 // (NULL, NULL, &ww, &wh));
1957 // eo_do(obj, elm_interface_scrollable_content_region_set(wx, sid->wy, ww, wh));
1961 _elm_interface_scrollable_wanted_region_set(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord x EINA_UNUSED, Evas_Coord y EINA_UNUSED)
1963 Evas_Coord ww, wh, wx;
1967 if (sid->down.now || sid->down.momentum_animator ||
1968 sid->down.bounce_x_animator || sid->down.bounce_y_animator ||
1969 sid->down.hold_animator || sid->down.onhold_animator ||
1970 sid->scrollto.x.animator || sid->scrollto.y.animator)
1973 sid->content_info.resized = EINA_FALSE;
1975 /* Flip to RTL cords only if init in RTL mode */
1976 if (sid->is_mirrored)
1977 wx = _elm_scroll_x_mirrored_get(obj, sid->wx);
1981 eo_do(obj, elm_interface_scrollable_content_viewport_geometry_get
1982 (NULL, NULL, &ww, &wh));
1990 eo_do(obj, elm_interface_scrollable_content_region_set(wx, sid->wy, ww, wh));
1995 _elm_scroll_wheel_event_cb(void *data,
1996 Evas *e EINA_UNUSED,
1997 Evas_Object *obj EINA_UNUSED,
2000 Elm_Scrollable_Smart_Interface_Data *sid;
2001 Evas_Event_Mouse_Wheel *ev;
2002 Evas_Coord x = 0, y = 0, vw = 0, vh = 0, cw = 0, ch = 0;
2004 int pagenumber_h = 0, pagenumber_v = 0;
2008 direction = ev->direction;
2010 if (sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL)
2013 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
2014 if ((evas_key_modifier_is_set(ev->modifiers, "Control")) ||
2015 (evas_key_modifier_is_set(ev->modifiers, "Alt")) ||
2016 (evas_key_modifier_is_set(ev->modifiers, "Meta")) ||
2017 (evas_key_modifier_is_set(ev->modifiers, "Hyper")) ||
2018 (evas_key_modifier_is_set(ev->modifiers, "Super")))
2020 else if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
2021 direction = !direction;
2022 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
2023 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
2024 (sid->scrollto.x.animator) || (sid->scrollto.y.animator))
2026 _elm_scroll_anim_stop(sid);
2028 ELM_SAFE_FREE(sid->scrollto.x.animator, ecore_animator_del);
2029 ELM_SAFE_FREE(sid->scrollto.y.animator, ecore_animator_del);
2030 if (sid->down.bounce_x_animator)
2032 ELM_SAFE_FREE(sid->down.bounce_x_animator, ecore_animator_del);
2033 sid->bouncemex = EINA_FALSE;
2034 if (sid->content_info.resized)
2035 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
2036 //_elm_scroll_wanted_region_set(sid->obj);
2037 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
2040 if (sid->down.bounce_y_animator)
2042 ELM_SAFE_FREE(sid->down.bounce_y_animator, ecore_animator_del);
2043 sid->bouncemey = EINA_FALSE;
2044 if (sid->content_info.resized)
2045 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
2046 //_elm_scroll_wanted_region_set(sid->obj);
2047 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
2050 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
2051 (NULL, NULL, &vw, &vh));
2053 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&cw, &ch));
2054 if (!_paging_is_enabled(sid))
2058 if (ch > vh || cw <= vw)
2059 y += ev->z * sid->step.y;
2061 x += ev->z * sid->step.x;
2063 else if (direction == 1)
2065 if (cw > vw || ch <= vh)
2066 x += ev->z * sid->step.x;
2068 y += ev->z * sid->step.y;
2071 if ((!sid->hold) && (!sid->freeze))
2073 _elm_scroll_wanted_coordinates_update(sid, x, y);
2074 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
2079 eo_do(sid->obj, elm_interface_scrollable_current_page_get(&pagenumber_h, &pagenumber_v));
2082 if (ch > vh || cw <= vw)
2083 y = (pagenumber_v + (1 * ev->z)) * sid->pagesize_v;
2085 x = (pagenumber_h + (1 * ev->z)) * sid->pagesize_h;
2087 else if (direction == 1)
2089 if (cw > vw || ch <= vh)
2090 x = (pagenumber_h + (1 * ev->z)) * sid->pagesize_h;
2092 y = (pagenumber_v + (1 * ev->z)) * sid->pagesize_v;
2095 if ((!sid->hold) && (!sid->freeze))
2097 _elm_scroll_scroll_to_x(sid, _elm_config->bring_in_scroll_friction, x);
2098 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, y);
2104 _elm_scroll_post_event_up(void *data,
2105 Evas *e EINA_UNUSED)
2107 Elm_Scrollable_Smart_Interface_Data *sid = data;
2111 if (sid->down.dragged)
2113 elm_widget_drag_lock_x_set(sid->obj, EINA_FALSE);
2114 elm_widget_drag_lock_y_set(sid->obj, EINA_FALSE);
2121 _paging_is_enabled(Elm_Scrollable_Smart_Interface_Data *sid)
2123 if ((sid->pagerel_h == 0.0) && (!sid->pagesize_h) &&
2124 (sid->pagerel_v == 0.0) && (!sid->pagesize_v))
2130 _elm_scroll_momentum_animator(void *data)
2132 double t, at, dt, p, r;
2133 Elm_Scrollable_Smart_Interface_Data *sid = data;
2134 Evas_Coord x, y, dx, dy, px, py, maxx, maxy, minx, miny;
2135 Eina_Bool no_bounce_x_end = EINA_FALSE, no_bounce_y_end = EINA_FALSE;
2139 sid->down.momentum_animator = NULL;
2140 return ECORE_CALLBACK_CANCEL;
2143 t = ecore_loop_time_get();
2144 dt = t - sid->down.anim_start;
2147 r = _elm_config->thumbscroll_min_friction / _elm_config->thumbscroll_friction;
2149 (sid->down.dx * sid->down.dx) + (sid->down.dy * sid->down.dy));
2150 at = at < ((1.0 - r) * _elm_config->thumbscroll_friction_standard) ?
2151 at : (1.0 - r) * _elm_config->thumbscroll_friction_standard;
2152 at = ((at / _elm_config->thumbscroll_friction_standard) + r) *
2153 (_elm_config->thumbscroll_friction + sid->down.extra_time);
2155 if (dt > 1.0) dt = 1.0;
2156 // TIZEN_ONLY(20150705): Genlist item align feature
2157 p = 1 - powf((1.0) - dt, 3);
2159 dx = sid->down.dx * p;
2160 dy = sid->down.dy * p;
2164 x = sid->down.sx - dx;
2165 y = sid->down.sy - dy;
2166 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&px, &py));
2167 if ((sid->down.bounce_x_animator) ||
2168 (sid->down.bounce_x_hold))
2170 sid->down.bx = sid->down.bx0 - dx + sid->down.b0x;
2173 if ((sid->down.bounce_y_animator) ||
2174 (sid->down.bounce_y_hold))
2176 sid->down.by = sid->down.by0 - dy + sid->down.b0y;
2179 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
2180 _elm_scroll_wanted_coordinates_update(sid, x, y);
2181 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&maxx, &maxy));
2182 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
2184 if (!_elm_config->thumbscroll_bounce_enable || !sid->bounce_horiz)
2186 if (x <= minx) no_bounce_x_end = EINA_TRUE;
2187 if (!sid->loop_h && (x - minx) >= maxx) no_bounce_x_end = EINA_TRUE;
2189 if (!_elm_config->thumbscroll_bounce_enable || !sid->bounce_vert)
2191 if (y <= miny) no_bounce_y_end = EINA_TRUE;
2192 if (!sid->loop_v && (y - miny) >= maxy) no_bounce_y_end = EINA_TRUE;
2195 ((sid->down.bounce_x_hold) && (sid->down.bounce_y_hold)) ||
2196 (no_bounce_x_end && no_bounce_y_end))
2198 _elm_scroll_anim_stop(sid);
2200 sid->down.momentum_animator = NULL;
2201 sid->down.bounce_x_hold = EINA_FALSE;
2202 sid->down.bounce_y_hold = EINA_FALSE;
2207 if (sid->content_info.resized)
2208 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
2209 //_elm_scroll_wanted_region_set(sid->obj);
2210 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
2213 return ECORE_CALLBACK_CANCEL;
2217 return ECORE_CALLBACK_RENEW;
2221 _elm_scroll_page_x_get(Elm_Scrollable_Smart_Interface_Data *sid,
2222 int offset, Eina_Bool limit)
2224 Evas_Coord x, y, w, h, dx, cw, ch, minx = 0;
2226 if (!sid->pan_obj) return 0;
2228 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
2229 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
2230 (NULL, NULL, &w, &h));
2231 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&cw, &ch));
2232 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, NULL));
2234 if (sid->pagerel_h > 0.0)
2235 sid->pagesize_h = w * sid->pagerel_h;
2241 dx = (sid->pagesize_h * ((double)sid->page_limit_h - 0.5));
2244 x += (abs(offset) < dx ? offset : dx);
2246 x += (abs(offset) < dx ? offset : -(dx + 1));
2249 if (sid->pagesize_h > 0)
2252 x = x + (sid->pagesize_h * 0.5);
2253 else if (x < 0 && sid->loop_h)
2254 x = x - (sid->pagesize_h * 0.5);
2255 x = x / (sid->pagesize_h);
2256 x = x * (sid->pagesize_h);
2260 if ((x + w) > cw) x = cw - w;
2261 if (x < minx) x = minx;
2268 _elm_scroll_page_y_get(Elm_Scrollable_Smart_Interface_Data *sid,
2269 int offset, Eina_Bool limit)
2271 Evas_Coord x, y, w = 0, h = 0, dy, cw = 0, ch = 0, miny = 0;
2273 if (!sid->pan_obj) return 0;
2275 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
2276 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
2277 (NULL, NULL, &w, &h));
2278 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&cw, &ch));
2279 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(NULL, &miny));
2281 if (sid->pagerel_v > 0.0)
2282 sid->pagesize_v = h * sid->pagerel_v;
2288 dy = (sid->pagesize_v * ((double)sid->page_limit_v - 0.5));
2291 y += (abs(offset) < dy ? offset : dy);
2293 y += (abs(offset) < dy ? offset : -(dy + 1));
2296 if (sid->pagesize_v > 0)
2299 y = y + (sid->pagesize_v * 0.5);
2300 else if (y < 0 && sid->loop_v)
2301 y = y - (sid->pagesize_v * 0.5);
2302 y = y / (sid->pagesize_v);
2303 y = y * (sid->pagesize_v);
2307 if ((y + h) > ch) y = ch - h;
2308 if (y < miny) y = miny;
2315 _elm_scroll_scroll_to_x_animator(void *data)
2317 Elm_Scrollable_Smart_Interface_Data *sid = data;
2323 sid->scrollto.x.animator = NULL;
2324 return ECORE_CALLBACK_CANCEL;
2327 t = ecore_loop_time_get();
2328 tt = (t - sid->scrollto.x.t_start) /
2329 (sid->scrollto.x.t_end - sid->scrollto.x.t_start);
2331 tt = 1.0 - (tt * tt);
2332 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
2333 px = (sid->scrollto.x.start * (1.0 - tt)) +
2334 (sid->scrollto.x.end * tt);
2335 if (t >= sid->scrollto.x.t_end)
2337 px = sid->scrollto.x.end;
2338 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(px, py, EINA_TRUE));
2340 sid->down.x = sid->down.history[0].x;
2342 _elm_scroll_wanted_coordinates_update(sid, px, py);
2343 sid->scrollto.x.animator = NULL;
2344 if ((!sid->scrollto.y.animator) && (!sid->down.bounce_y_animator))
2345 _elm_scroll_anim_stop(sid);
2346 return ECORE_CALLBACK_CANCEL;
2348 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(px, py, EINA_TRUE));
2349 _elm_scroll_wanted_coordinates_update(sid, px, py);
2350 return ECORE_CALLBACK_RENEW;
2354 _elm_scroll_scroll_to_y_animator(void *data)
2356 Elm_Scrollable_Smart_Interface_Data *sid = data;
2360 if (!sid->pan_obj) return EINA_FALSE;
2362 t = ecore_loop_time_get();
2363 tt = (t - sid->scrollto.y.t_start) /
2364 (sid->scrollto.y.t_end - sid->scrollto.y.t_start);
2366 tt = 1.0 - (tt * tt);
2367 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
2368 py = (sid->scrollto.y.start * (1.0 - tt)) +
2369 (sid->scrollto.y.end * tt);
2370 if (t >= sid->scrollto.y.t_end)
2372 py = sid->scrollto.y.end;
2373 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(px, py, EINA_TRUE));
2375 sid->down.y = sid->down.history[0].y;
2377 _elm_scroll_wanted_coordinates_update(sid, px, py);
2378 sid->scrollto.y.animator = NULL;
2379 if ((!sid->scrollto.x.animator) && (!sid->down.bounce_x_animator))
2380 _elm_scroll_anim_stop(sid);
2381 return ECORE_CALLBACK_CANCEL;
2383 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(px, py, EINA_TRUE));
2384 _elm_scroll_wanted_coordinates_update(sid, px, py);
2386 return ECORE_CALLBACK_RENEW;
2390 _elm_scroll_scroll_to_y(Elm_Scrollable_Smart_Interface_Data *sid,
2394 Evas_Coord px = 0, py = 0, x, y, w, h;
2397 if (!sid->pan_obj) return;
2399 if (sid->freeze) return;
2402 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
2403 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
2404 (NULL, NULL, &w, &h));
2406 eo_do(sid->obj, elm_interface_scrollable_content_region_set(x, y, w, h));
2409 t = ecore_loop_time_get();
2410 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
2411 sid->scrollto.y.start = py;
2412 sid->scrollto.y.end = pos_y;
2413 sid->scrollto.y.t_start = t;
2414 sid->scrollto.y.t_end = t + t_in;
2415 if (!sid->scrollto.y.animator)
2417 sid->scrollto.y.animator =
2418 ecore_animator_add(_elm_scroll_scroll_to_y_animator, sid);
2419 if (!sid->scrollto.x.animator)
2420 _elm_scroll_anim_start(sid);
2422 if (sid->down.bounce_y_animator)
2424 ELM_SAFE_FREE(sid->down.bounce_y_animator, ecore_animator_del);
2425 _elm_scroll_momentum_end(sid);
2426 if (sid->content_info.resized)
2427 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
2428 //_elm_scroll_wanted_region_set(sid->obj);
2429 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
2432 sid->bouncemey = EINA_FALSE;
2436 _elm_scroll_scroll_to_x(Elm_Scrollable_Smart_Interface_Data *sid,
2440 Evas_Coord px = 0, py = 0, x, y, w, h;
2443 if (!sid->pan_obj) return;
2445 if (sid->freeze) return;
2448 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
2449 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
2450 (NULL, NULL, &w, &h));
2452 eo_do(sid->obj, elm_interface_scrollable_content_region_set
2456 t = ecore_loop_time_get();
2457 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
2458 sid->scrollto.x.start = px;
2459 sid->scrollto.x.end = pos_x;
2460 sid->scrollto.x.t_start = t;
2461 sid->scrollto.x.t_end = t + t_in;
2462 if (!sid->scrollto.x.animator)
2464 sid->scrollto.x.animator =
2465 ecore_animator_add(_elm_scroll_scroll_to_x_animator, sid);
2466 if (!sid->scrollto.y.animator)
2467 _elm_scroll_anim_start(sid);
2469 if (sid->down.bounce_x_animator)
2471 ELM_SAFE_FREE(sid->down.bounce_x_animator, ecore_animator_del);
2472 _elm_scroll_momentum_end(sid);
2473 if (sid->content_info.resized)
2474 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
2475 //_elm_scroll_wanted_region_set(sid->obj);
2476 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
2479 sid->bouncemex = EINA_FALSE;
2483 _elm_scroll_mouse_up_event_cb(void *data,
2485 Evas_Object *obj EINA_UNUSED,
2488 Elm_Scrollable_Smart_Interface_Data *sid = data;
2489 Evas_Coord x = 0, y = 0, ox = 0, oy = 0;
2490 Evas_Event_Mouse_Up *ev;
2492 if (!sid->pan_obj) return;
2494 if ((sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL) &&
2495 (sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
2499 if (_elm_scroll_smooth_debug) _elm_scroll_smooth_debug_shutdown();
2503 sid->down.hold_parent = EINA_FALSE;
2506 evas_post_event_callback_push(e, _elm_scroll_post_event_up, sid);
2508 // TIZEN_ONLY(20150820): Overscroll effect
2509 edje_object_signal_emit(sid->edje_obj, "elm,state,mouse,up", "elm");
2512 // FIXME: respect elm_widget_scroll_hold_get of parent container
2513 if (!_elm_config->thumbscroll_enable) return;
2515 if (ev->button == 1)
2517 if (sid->down.onhold_animator)
2519 ELM_SAFE_FREE(sid->down.onhold_animator, ecore_animator_del);
2520 if (sid->content_info.resized)
2521 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
2522 //_elm_scroll_wanted_region_set(sid->obj);
2523 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
2526 x = ev->canvas.x - sid->down.x;
2527 y = ev->canvas.y - sid->down.y;
2528 if (sid->down.dragged)
2530 _elm_scroll_drag_stop(sid);
2531 if ((!sid->hold) && (!sid->freeze))
2535 Evas_Coord ax, ay, dx, dy, vel;
2538 t = ev->timestamp / 1000.0;
2540 t = ecore_loop_time_get();
2543 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2548 DBG("------ %i %i\n", ev->canvas.x, ev->canvas.y);
2550 for (i = 0; i < 60; i++)
2552 dt = t - sid->down.history[i].timestamp;
2553 if (dt > 0.2) break;
2555 DBG("H: %i %i @ %1.3f\n",
2556 sid->down.history[i].x,
2557 sid->down.history[i].y, dt);
2560 ax += sid->down.history[i].x;
2561 ay += sid->down.history[i].y;
2566 at /= _elm_config->thumbscroll_sensitivity_friction;
2567 dx = ev->canvas.x - ax;
2568 dy = ev->canvas.y - ay;
2571 vel = sqrt((dx * dx) + (dy * dy)) / at;
2572 if ((_elm_config->thumbscroll_friction > 0.0) &&
2573 (vel > _elm_config->thumbscroll_momentum_threshold))
2576 int minx, miny, mx, my, px, py;
2577 double tt = 0.0, dtt = 0.0;
2579 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get
2581 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get
2583 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
2584 max_d = _elm_config->thumbscroll_flick_distance_tolerance;
2587 if (dx > max_d) dx = max_d;
2588 sid->down.dx = (sin((M_PI * (double)dx / max_d)
2589 - (M_PI / 2)) + 1) * max_d / at;
2593 if (dx < -max_d) dx = -max_d;
2594 sid->down.dx = (sin((M_PI * (double)dx / max_d)
2595 + (M_PI / 2)) - 1) * max_d / at;
2599 if (dy > max_d) dy = max_d;
2600 sid->down.dy = (sin((M_PI * (double)dy / max_d)
2601 - (M_PI / 2)) + 1) * max_d / at;
2605 if (dy < -max_d) dy = -max_d;
2606 sid->down.dy = (sin((M_PI * (double)dy / max_d)
2607 + (M_PI / 2)) - 1) * max_d / at;
2609 if (((sid->down.dx > 0) && (sid->down.pdx > 0)) ||
2610 ((sid->down.dx < 0) && (sid->down.pdx < 0)) ||
2611 ((sid->down.dy > 0) && (sid->down.pdy > 0)) ||
2612 ((sid->down.dy < 0) && (sid->down.pdy < 0)))
2614 tt = ecore_loop_time_get();
2615 dtt = tt - sid->down.anim_start;
2617 if (dtt < 0.0) dtt = 0.0;
2619 _elm_config->thumbscroll_friction)
2620 dtt = _elm_config->thumbscroll_friction;
2621 sid->down.extra_time =
2622 _elm_config->thumbscroll_friction - dtt;
2625 sid->down.extra_time = 0.0;
2627 if (abs(sid->down.dx) > _elm_config->thumbscroll_acceleration_threshold &&
2628 (dtt < _elm_config->thumbscroll_acceleration_time_limit) &&
2629 (((sid->down.dx > 0) && (sid->down.pdx > 0)) ||
2630 ((sid->down.dx < 0) && (sid->down.pdx < 0))))
2631 if (px > minx && px < mx)
2632 sid->down.dx += (double)sid->down.pdx * _elm_config->thumbscroll_acceleration_weight;
2633 if (abs(sid->down.dy) > _elm_config->thumbscroll_acceleration_threshold &&
2634 (dtt < _elm_config->thumbscroll_acceleration_time_limit) &&
2635 (((sid->down.dy > 0) && (sid->down.pdy > 0)) ||
2636 ((sid->down.dy < 0) && (sid->down.pdy < 0))))
2637 if (py > miny && py < my)
2639 sid->down.dy += (double)sid->down.pdy * _elm_config->thumbscroll_acceleration_weight;
2642 // TIZEN_ONLY(20150705): Genlist item align feature
2643 Evas_Coord pos_x, pos_y;
2645 pos_x = sid->down.dx;
2646 pos_y = sid->down.dy;
2648 pos_x = _round(pos_x * (_elm_config->thumbscroll_friction +
2649 sid->down.extra_time), 0);
2650 pos_y = _round(pos_y * (_elm_config->thumbscroll_friction +
2651 sid->down.extra_time), 0);
2653 eo_do(sid->pan_obj, elm_obj_pan_pos_adjust(&pos_x, &pos_y));
2655 // adjusted position using to _elm_scroll_momentum_animator()
2656 sid->down.dx = pos_x;
2657 sid->down.dy = pos_y;
2659 sid->down.pdx = sid->down.dx;
2660 sid->down.pdy = sid->down.dy;
2663 if (!_paging_is_enabled(sid))
2665 if ((!sid->down.momentum_animator) &&
2666 (!sid->momentum_animator_disabled) &&
2668 (!elm_widget_drag_child_locked_y_get
2671 sid->down.momentum_animator =
2673 (_elm_scroll_momentum_animator, sid);
2675 EVAS_EVENT_FLAG_ON_SCROLL;
2676 _elm_scroll_anim_start(sid);
2678 sid->down.anim_start = ecore_loop_time_get();
2680 elm_interface_scrollable_content_pos_get(&x, &y));
2687 // TIZEN_ONLY(20150705): Genlist item align feature
2690 Evas_Coord pos_x = 0, pos_y = 0;
2691 Evas_Coord adjust_x, adjust_y;
2693 eo_do(sid->pan_obj, elm_obj_pan_pos_adjust(&pos_x, &pos_y));
2695 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&adjust_x, &adjust_y));
2699 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, adjust_y);
2704 Evas_Coord pos_x = 0, pos_y = 0;
2705 Evas_Coord adjust_x, adjust_y;
2707 eo_do(sid->pan_obj, elm_obj_pan_pos_adjust(&pos_x, &pos_y));
2709 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&adjust_x, &adjust_y));
2713 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, adjust_y);
2722 evas_event_feed_hold(e, 0, ev->timestamp, ev->data);
2723 if (_paging_is_enabled(sid))
2725 Evas_Coord pgx, pgy;
2727 eo_do(sid->obj, elm_interface_scrollable_content_pos_get
2730 (!elm_widget_drag_child_locked_x_get
2733 pgx = _elm_scroll_page_x_get(sid, ox, EINA_TRUE);
2736 ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
2738 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2739 _elm_scroll_scroll_to_x
2740 (sid, _elm_config->page_scroll_friction, pgx);
2744 (!elm_widget_drag_child_locked_y_get
2747 pgy = _elm_scroll_page_y_get(sid, oy, EINA_TRUE);
2750 ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL))
2752 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2753 _elm_scroll_scroll_to_y
2754 (sid, _elm_config->page_scroll_friction, pgy);
2763 if (_paging_is_enabled(sid))
2765 Evas_Coord pgx, pgy;
2767 eo_do(sid->obj, elm_interface_scrollable_content_pos_get
2770 (!elm_widget_drag_child_locked_x_get
2773 pgx = _elm_scroll_page_x_get(sid, ox, EINA_TRUE);
2775 _elm_scroll_scroll_to_x
2776 (sid, _elm_config->page_scroll_friction, pgx);
2779 (!elm_widget_drag_child_locked_y_get
2782 pgy = _elm_scroll_page_y_get(sid, oy, EINA_TRUE);
2784 _elm_scroll_scroll_to_y
2785 (sid, _elm_config->page_scroll_friction, pgy);
2789 if (sid->down.hold_animator)
2791 ELM_SAFE_FREE(sid->down.hold_animator, ecore_animator_del);
2792 if (sid->content_info.resized)
2793 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
2794 //_elm_scroll_wanted_region_set(sid->obj);
2795 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
2798 ELM_SAFE_FREE(sid->down.hold_enterer, ecore_idle_enterer_del);
2799 if (sid->down.scroll)
2801 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2802 sid->down.scroll = EINA_FALSE;
2806 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2807 sid->down.hold = EINA_FALSE;
2809 sid->down.dragged_began = EINA_FALSE;
2810 sid->down.dir_x = EINA_FALSE;
2811 sid->down.dir_y = EINA_FALSE;
2812 sid->down.want_dragged = EINA_FALSE;
2813 sid->down.dragged = EINA_FALSE;
2814 sid->down.now = EINA_FALSE;
2815 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
2816 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
2817 _elm_scroll_wanted_coordinates_update(sid, x, y);
2819 if (sid->content_info.resized)
2820 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
2821 //_elm_scroll_wanted_region_set(sid->obj);
2822 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
2825 if (!_paging_is_enabled(sid))
2826 _elm_scroll_bounce_eval(sid);
2831 _elm_scroll_mouse_down_event_cb(void *data,
2832 Evas *e EINA_UNUSED,
2833 Evas_Object *obj EINA_UNUSED,
2836 Elm_Scrollable_Smart_Interface_Data *sid;
2837 Evas_Event_Mouse_Down *ev;
2838 Evas_Coord x = 0, y = 0;
2843 if ((sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL) &&
2844 (sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
2847 // TIZEN_ONLY(20150820): Overscroll effect
2848 edje_object_signal_emit(sid->edje_obj, "elm,state,mouse,down", "elm");
2852 if (getenv("ELS_SCROLLER_SMOOTH_DEBUG")) _elm_scroll_smooth_debug = 1;
2853 if (_elm_scroll_smooth_debug) _elm_scroll_smooth_debug_init();
2856 if (!_elm_config->thumbscroll_enable) return;
2858 sid->down.hold = EINA_FALSE;
2859 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
2860 (sid->down.momentum_animator) || (sid->scrollto.x.animator) ||
2861 (sid->scrollto.y.animator))
2863 //TIZEN_ONLY: (20150819) Do not hold the flag causes click skip
2864 //and not required as we are deleting all animators here.
2865 //ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL |
2866 // EVAS_EVENT_FLAG_ON_HOLD;
2867 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2869 sid->down.scroll = EINA_TRUE;
2870 //TIZEN_ONLY: (20150819) Do not hold the flag causes click skip
2871 //sid->down.hold = EINA_TRUE;
2873 _elm_scroll_anim_stop(sid);
2875 ELM_SAFE_FREE(sid->scrollto.x.animator, ecore_animator_del);
2876 ELM_SAFE_FREE(sid->scrollto.y.animator, ecore_animator_del);
2877 if (sid->down.bounce_x_animator)
2879 ELM_SAFE_FREE(sid->down.bounce_x_animator, ecore_animator_del);
2880 sid->bouncemex = EINA_FALSE;
2881 if (sid->content_info.resized)
2882 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
2883 //_elm_scroll_wanted_region_set(sid->obj);
2884 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
2887 if (sid->down.bounce_y_animator)
2889 ELM_SAFE_FREE(sid->down.bounce_y_animator, ecore_animator_del);
2890 sid->bouncemey = EINA_FALSE;
2891 if (sid->content_info.resized)
2892 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
2893 //_elm_scroll_wanted_region_set(sid->obj);
2894 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
2897 if (sid->down.hold_animator)
2899 ELM_SAFE_FREE(sid->down.hold_animator, ecore_animator_del);
2900 _elm_scroll_drag_stop(sid);
2901 if (sid->content_info.resized)
2902 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
2903 //_elm_scroll_wanted_region_set(sid->obj);
2904 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
2907 ELM_SAFE_FREE(sid->down.hold_enterer, ecore_idle_enterer_del);
2908 if (sid->down.momentum_animator)
2910 ELM_SAFE_FREE(sid->down.momentum_animator, ecore_animator_del);
2911 sid->down.bounce_x_hold = EINA_FALSE;
2912 sid->down.bounce_y_hold = EINA_FALSE;
2915 if (sid->content_info.resized)
2916 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
2917 //_elm_scroll_wanted_region_set(sid->obj);
2918 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
2921 if (ev->button == 1)
2923 sid->down.hist.est_timestamp_diff =
2924 ecore_loop_time_get() - ((double)ev->timestamp / 1000.0);
2925 sid->down.hist.tadd = 0.0;
2926 sid->down.hist.dxsum = 0.0;
2927 sid->down.hist.dysum = 0.0;
2928 sid->down.now = EINA_TRUE;
2929 sid->down.dragged = EINA_FALSE;
2930 sid->down.dir_x = EINA_FALSE;
2931 sid->down.dir_y = EINA_FALSE;
2932 sid->down.x = ev->canvas.x;
2933 sid->down.y = ev->canvas.y;
2934 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
2937 sid->down.locked = EINA_FALSE;
2938 memset(&(sid->down.history[0]), 0,
2939 sizeof(sid->down.history[0]) * 60);
2941 sid->down.history[0].timestamp = ev->timestamp / 1000.0;
2942 sid->down.history[0].localtimestamp = ecore_loop_time_get();
2944 sid->down.history[0].timestamp = ecore_loop_time_get();
2946 sid->down.dragged_began_timestamp = sid->down.history[0].timestamp;
2947 sid->down.history[0].x = ev->canvas.x;
2948 sid->down.history[0].y = ev->canvas.y;
2950 sid->down.dragged_began = EINA_FALSE;
2951 sid->down.hold_parent = EINA_FALSE;
2952 sid->down.cancelled = EINA_FALSE;
2953 if (sid->hold || sid->freeze)
2954 sid->down.want_reset = EINA_TRUE;
2956 sid->down.want_reset = EINA_FALSE;
2960 _elm_scroll_can_scroll(Elm_Scrollable_Smart_Interface_Data *sid,
2963 Evas_Coord mx = 0, my = 0, px = 0, py = 0, minx = 0, miny = 0;
2965 if (!sid->pan_obj) return EINA_FALSE;
2967 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
2968 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
2969 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
2973 if (px > minx) return EINA_TRUE;
2977 if ((px - minx) < mx) return EINA_TRUE;
2981 if (py > miny) return EINA_TRUE;
2985 if ((py - miny) < my) return EINA_TRUE;
2995 _elm_scroll_post_event_move(void *data,
2996 Evas *e EINA_UNUSED)
2998 Elm_Scrollable_Smart_Interface_Data *sid = data;
2999 Eina_Bool horiz, vert;
3002 if (!sid->down.want_dragged) return EINA_TRUE;
3004 elm_widget_parents_bounce_get(sid->obj, &horiz, &vert);
3005 if (sid->down.hold_parent)
3007 if ((sid->down.dir_x) && (horiz || !sid->bounce_horiz) &&
3008 !_elm_scroll_can_scroll(sid, sid->down.hdir))
3010 sid->down.dir_x = EINA_FALSE;
3012 if ((sid->down.dir_y) && (vert || !sid->bounce_vert) &&
3013 !_elm_scroll_can_scroll(sid, sid->down.vdir))
3015 sid->down.dir_y = EINA_FALSE;
3017 sid->down.dragged_began = EINA_TRUE;
3019 if (sid->down.dir_x)
3022 (!elm_widget_drag_child_locked_x_get(sid->obj)))
3024 if (sid->down.dragged_began)
3026 sid->down.want_dragged = EINA_FALSE;
3027 sid->down.dragged = EINA_TRUE;
3030 elm_widget_drag_lock_x_set(sid->obj, 1);
3037 sid->down.dragged_began = EINA_TRUE;
3038 sid->down.dir_x = EINA_FALSE;
3041 if (sid->down.dir_y)
3044 (!elm_widget_drag_child_locked_y_get(sid->obj)))
3046 if (sid->down.dragged_began)
3048 sid->down.want_dragged = EINA_FALSE;
3049 sid->down.dragged = EINA_TRUE;
3052 elm_widget_drag_lock_y_set
3053 (sid->obj, EINA_TRUE);
3060 sid->down.dragged_began = EINA_TRUE;
3061 sid->down.dir_y = EINA_FALSE;
3064 if ((!sid->down.dir_x) && (!sid->down.dir_y))
3066 sid->down.cancelled = EINA_TRUE;
3068 if (start) _elm_scroll_drag_start(sid);
3074 _elm_scroll_down_coord_eval(Elm_Scrollable_Smart_Interface_Data *sid,
3078 Evas_Coord minx, miny;
3080 if (!sid->pan_obj) return;
3082 if (sid->down.dir_x) *x = sid->down.sx - (*x - sid->down.x);
3083 else *x = sid->down.sx;
3084 if (sid->down.dir_y) *y = sid->down.sy - (*y - sid->down.y);
3085 else *y = sid->down.sy;
3087 if ((sid->down.dir_x) || (sid->down.dir_y))
3089 if (!((sid->down.dir_x) && (sid->down.dir_y)))
3091 if (sid->down.dir_x) *y = sid->down.locked_y;
3092 else *x = sid->down.locked_x;
3096 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
3098 if (!sid->loop_h && *x < minx)
3099 *x += (minx - *x) * _elm_config->thumbscroll_border_friction;
3100 else if (!sid->loop_h && sid->content_info.w <= sid->w)
3101 *x += (sid->down.sx - *x) * _elm_config->thumbscroll_border_friction;
3102 else if (!sid->loop_h && (sid->content_info.w - sid->w + minx) < *x)
3103 *x += (sid->content_info.w - sid->w + minx - *x) *
3104 _elm_config->thumbscroll_border_friction;
3106 if (!sid->loop_v && *y < miny)
3107 *y += (miny - *y) * _elm_config->thumbscroll_border_friction;
3108 else if (!sid->loop_v && sid->content_info.h <= sid->h)
3109 *y += (sid->down.sy - *y) * _elm_config->thumbscroll_border_friction;
3110 else if (!sid->loop_v && (sid->content_info.h - sid->h + miny) < *y)
3111 *y += (sid->content_info.h - sid->h + miny - *y) *
3112 _elm_config->thumbscroll_border_friction;
3116 _elm_scroll_hold_enterer(void *data)
3118 Elm_Scrollable_Smart_Interface_Data *sid = data;
3119 Evas_Coord ox = 0, oy = 0, fx = 0, fy = 0;
3121 sid->down.hold_enterer = NULL;
3123 fx = sid->down.hold_x;
3124 fy = sid->down.hold_y;
3126 if (_elm_config->scroll_smooth_amount > 0.0)
3129 Evas_Coord basex = 0, basey = 0, x, y;
3130 double dt, t, tdiff, tnow, twin;
3133 Evas_Coord x, y, dx, dy;
3137 tdiff = sid->down.hist.est_timestamp_diff;
3138 tnow = ecore_time_get() - tdiff;
3140 twin = _elm_config->scroll_smooth_time_window;
3141 for (i = 0; i < 60; i++)
3143 if (sid->down.history[i].timestamp >
3144 sid->down.dragged_began_timestamp)
3146 // oldest point is sd->down.history[i]
3147 // newset is sd->down.history[0]
3148 dt = t - sid->down.history[i].timestamp;
3155 x = sid->down.history[i].x;
3156 y = sid->down.history[i].y;
3157 _elm_scroll_down_coord_eval(sid, &x, &y);
3163 pos[i].x = x - basex;
3164 pos[i].y = y - basey;
3165 pos[i].t = sid->down.history[i].timestamp - sid->down.history[0].timestamp;
3171 double dtsum = 0.0, tadd, maxdt;
3172 double dxsum = 0.0, dysum = 0.0, xsum = 0.0, ysum = 0.0;
3173 for (i = 0; i < (count - 1); i++)
3175 pos[i].dx = pos[i].x - pos[i + 1].x;
3176 pos[i].dy = pos[i].y - pos[i + 1].y;
3177 pos[i].dt = pos[i].t - pos[i + 1].t;
3192 tadd = tnow - sid->down.history[0].timestamp + _elm_config->scroll_smooth_future_time;
3193 tadd = tadd - (maxdt / 2);
3194 #define WEIGHT(n, o, v) n = (((double)o * (1.0 - v)) + ((double)n * v))
3195 WEIGHT(tadd, sid->down.hist.tadd, _elm_config->scroll_smooth_history_weight);
3196 WEIGHT(dxsum, sid->down.hist.dxsum, _elm_config->scroll_smooth_history_weight);
3197 WEIGHT(dysum, sid->down.hist.dysum, _elm_config->scroll_smooth_history_weight);
3198 fx = basex + xsum + ((dxsum * tadd) / dtsum);
3199 fy = basey + ysum + ((dysum * tadd) / dtsum);
3200 sid->down.hist.tadd = tadd;
3201 sid->down.hist.dxsum = dxsum;
3202 sid->down.hist.dysum = dysum;
3203 WEIGHT(fx, sid->down.hold_x, _elm_config->scroll_smooth_amount);
3204 WEIGHT(fy, sid->down.hold_y, _elm_config->scroll_smooth_amount);
3209 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&ox, &oy));
3210 if (sid->down.dir_x)
3213 (!elm_widget_drag_child_locked_x_get(sid->obj)))
3216 if (sid->down.dir_y)
3219 (!elm_widget_drag_child_locked_y_get(sid->obj)))
3224 if (_elm_scroll_smooth_debug)
3225 _elm_scroll_smooth_debug_movetime_add(ox, oy);
3228 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(ox, oy, EINA_TRUE));
3234 _elm_scroll_hold_animator(void *data)
3236 Elm_Scrollable_Smart_Interface_Data *sid = data;
3238 ecore_idle_enterer_del(sid->down.hold_enterer);
3239 sid->down.hold_enterer =
3240 ecore_idle_enterer_before_add(_elm_scroll_hold_enterer, sid);
3241 return ECORE_CALLBACK_RENEW;
3245 _elm_scroll_on_hold_animator(void *data)
3249 Evas_Coord x, y, ox = 0, oy = 0;
3250 Elm_Scrollable_Smart_Interface_Data *sid;
3253 t = ecore_loop_time_get();
3254 if (sid->down.onhold_tlast > 0.0)
3256 td = t - sid->down.onhold_tlast;
3257 vx = sid->down.onhold_vx * td *
3258 (double)_elm_config->thumbscroll_hold_threshold * 2.0;
3259 vy = sid->down.onhold_vy * td *
3260 (double)_elm_config->thumbscroll_hold_threshold * 2.0;
3261 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&ox, &oy));
3265 if (sid->down.dir_x)
3268 (!elm_widget_drag_child_locked_x_get(sid->obj)))
3270 sid->down.onhold_vxe += vx;
3271 x = ox + (int)sid->down.onhold_vxe;
3272 sid->down.onhold_vxe -= (int)sid->down.onhold_vxe;
3276 if (sid->down.dir_y)
3279 (!elm_widget_drag_child_locked_y_get(sid->obj)))
3281 sid->down.onhold_vye += vy;
3282 y = oy + (int)sid->down.onhold_vye;
3283 sid->down.onhold_vye -= (int)sid->down.onhold_vye;
3287 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
3289 sid->down.onhold_tlast = t;
3291 return ECORE_CALLBACK_RENEW;
3295 _elm_scroll_mouse_move_event_cb(void *data,
3297 Evas_Object *obj EINA_UNUSED,
3300 Elm_Scrollable_Smart_Interface_Data *sid = data;
3301 Evas_Event_Mouse_Move *ev;
3302 Evas_Coord x = 0, y = 0;
3304 if (!sid->pan_obj) return;
3306 if ((sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL) &&
3307 (sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
3311 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
3312 sid->down.hold_parent = EINA_TRUE;
3313 evas_post_event_callback_push(e, _elm_scroll_post_event_move, sid);
3315 // FIXME: respect elm_widget_scroll_hold_get of parent container
3316 if (!_elm_config->thumbscroll_enable)
3319 if (!sid->down.now) return;
3321 // TIZEN_ONLY(20150820): Overscroll effect
3322 edje_object_signal_emit(sid->edje_obj, "elm,state,mouse,move", "elm");
3325 if ((sid->scrollto.x.animator) && (!sid->hold) && (!sid->freeze) &&
3326 !(sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
3329 ELM_SAFE_FREE(sid->scrollto.x.animator, ecore_animator_del);
3330 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, NULL));
3332 sid->down.x = sid->down.history[0].x;
3335 if ((sid->scrollto.y.animator) && (!sid->hold) && (!sid->freeze) &&
3336 !(sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL))
3339 ELM_SAFE_FREE(sid->scrollto.y.animator, ecore_animator_del);
3340 eo_do(sid->pan_obj, elm_obj_pan_pos_get(NULL, &py));
3342 sid->down.y = sid->down.history[0].y;
3346 DBG("::: %i %i\n", ev->cur.canvas.x, ev->cur.canvas.y);
3348 memmove(&(sid->down.history[1]), &(sid->down.history[0]),
3349 sizeof(sid->down.history[0]) * (60 - 1));
3351 sid->down.history[0].timestamp = ev->timestamp / 1000.0;
3352 sid->down.history[0].localtimestamp = ecore_loop_time_get();
3354 sid->down.history[0].timestamp = ecore_loop_time_get();
3356 sid->down.history[0].x = ev->cur.canvas.x;
3357 sid->down.history[0].y = ev->cur.canvas.y;
3359 if (!sid->down.dragged_began)
3361 x = ev->cur.canvas.x - sid->down.x;
3362 y = ev->cur.canvas.y - sid->down.y;
3364 sid->down.hdir = -1;
3365 sid->down.vdir = -1;
3367 if (x > 0) sid->down.hdir = LEFT;
3369 sid->down.hdir = RIGHT;
3370 if (y > 0) sid->down.vdir = UP;
3372 sid->down.vdir = DOWN;
3377 if (sid->one_direction_at_a_time)
3379 if (((x * x) + (y * y)) >
3380 (_elm_config->thumbscroll_threshold *
3381 _elm_config->thumbscroll_threshold))
3383 if (sid->one_direction_at_a_time ==
3384 ELM_SCROLLER_SINGLE_DIRECTION_SOFT)
3390 ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
3392 sid->down.dir_x = EINA_TRUE;
3394 sid->down.dir_y = EINA_FALSE;
3399 sid->down.dir_x = EINA_FALSE;
3401 ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL))
3403 sid->down.dir_y = EINA_TRUE;
3410 ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
3412 sid->down.dir_x = EINA_TRUE;
3415 ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL))
3417 sid->down.dir_y = EINA_TRUE;
3421 else if (sid->one_direction_at_a_time ==
3422 ELM_SCROLLER_SINGLE_DIRECTION_HARD)
3427 ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
3429 sid->down.dir_x = EINA_TRUE;
3431 sid->down.dir_y = EINA_FALSE;
3435 sid->down.dir_x = EINA_FALSE;
3437 ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL))
3439 sid->down.dir_y = EINA_TRUE;
3448 ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
3450 sid->down.dir_x = EINA_TRUE;
3453 ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL))
3455 sid->down.dir_y = EINA_TRUE;
3459 if ((!sid->hold) && (!sid->freeze))
3461 if ((sid->down.dragged) ||
3462 (((x * x) + (y * y)) >
3463 (_elm_config->thumbscroll_threshold *
3464 _elm_config->thumbscroll_threshold)))
3466 if (!sid->down.dragged_began &&
3467 _elm_config->scroll_smooth_start_enable)
3469 sid->down.x = ev->cur.canvas.x;
3470 sid->down.y = ev->cur.canvas.y;
3472 sid->down.dragged_began_timestamp = ev->timestamp / 1000.0;
3474 sid->down.dragged_began_timestamp = ecore_loop_time_get();
3478 if (!sid->down.dragged)
3480 sid->down.want_dragged = EINA_TRUE;
3482 if ((((_elm_scroll_can_scroll(sid, LEFT) || _elm_scroll_can_scroll(sid, RIGHT)) && sid->down.dir_x) ||
3483 ((_elm_scroll_can_scroll(sid, UP) || _elm_scroll_can_scroll(sid, DOWN)) && sid->down.dir_y)) &&
3484 !sid->down.dragged_began)
3486 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3487 sid->down.dragged_began = EINA_TRUE;
3489 else if (sid->down.dragged_began)
3491 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3493 if (sid->down.dir_x)
3494 x = sid->down.sx - (ev->cur.canvas.x - sid->down.x);
3497 if (sid->down.dir_y)
3498 y = sid->down.sy - (ev->cur.canvas.y - sid->down.y);
3501 if (sid->down.want_reset)
3503 sid->down.x = ev->cur.canvas.x;
3504 sid->down.y = ev->cur.canvas.y;
3505 sid->down.want_reset = EINA_FALSE;
3507 if ((sid->down.dir_x) || (sid->down.dir_y))
3509 if (!sid->down.locked)
3511 sid->down.locked_x = x;
3512 sid->down.locked_y = y;
3513 sid->down.locked = EINA_TRUE;
3515 if (!((sid->down.dir_x) && (sid->down.dir_y)))
3517 if (sid->down.dir_x) y = sid->down.locked_y;
3518 else x = sid->down.locked_x;
3522 Evas_Coord minx = 0, miny = 0, mx, my;
3524 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
3525 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
3526 if (!sid->loop_v && y < miny)
3528 _elm_config->thumbscroll_border_friction;
3529 else if (!sid->loop_v && my <= 0)
3530 y += (sid->down.sy - y) *
3531 _elm_config->thumbscroll_border_friction;
3532 else if (!sid->loop_v && (my + miny) < y)
3533 y += (my + miny - y) *
3534 _elm_config->thumbscroll_border_friction;
3535 if (!sid->loop_h && x < minx)
3537 _elm_config->thumbscroll_border_friction;
3538 else if (!sid->loop_h && mx <= 0)
3539 x += (sid->down.sx - x) *
3540 _elm_config->thumbscroll_border_friction;
3541 else if (!sid->loop_h && (mx + minx) < x)
3542 x += (mx + minx - x) *
3543 _elm_config->thumbscroll_border_friction;
3546 sid->down.hold_x = x;
3547 sid->down.hold_y = y;
3548 if (!sid->down.hold_animator)
3549 sid->down.hold_animator =
3550 ecore_animator_add(_elm_scroll_hold_animator, sid);
3554 if (sid->down.dragged_began)
3556 if ((_elm_scroll_can_scroll(sid, sid->down.hdir) && sid->down.dir_x) ||
3557 (_elm_scroll_can_scroll(sid, sid->down.vdir) && sid->down.dir_y))
3559 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3561 if (!sid->down.hold)
3563 sid->down.hold = EINA_TRUE;
3564 evas_event_feed_hold
3565 (e, 1, ev->timestamp, ev->data);
3570 else if (!sid->freeze)
3572 double vx = 0.0, vy = 0.0;
3574 x = ev->cur.canvas.x - sid->x;
3575 y = ev->cur.canvas.y - sid->y;
3576 if (x < _elm_config->thumbscroll_hold_threshold)
3578 if (_elm_config->thumbscroll_hold_threshold > 0.0)
3579 vx = -(double)(_elm_config->thumbscroll_hold_threshold - x)
3580 / _elm_config->thumbscroll_hold_threshold;
3584 else if (x > (sid->w - _elm_config->thumbscroll_hold_threshold))
3586 if (_elm_config->thumbscroll_hold_threshold > 0.0)
3587 vx = (double)(_elm_config->thumbscroll_hold_threshold -
3589 _elm_config->thumbscroll_hold_threshold;
3593 if (y < _elm_config->thumbscroll_hold_threshold)
3595 if (_elm_config->thumbscroll_hold_threshold > 0.0)
3596 vy = -(double)(_elm_config->thumbscroll_hold_threshold - y)
3597 / _elm_config->thumbscroll_hold_threshold;
3601 else if (y > (sid->h - _elm_config->thumbscroll_hold_threshold))
3603 if (_elm_config->thumbscroll_hold_threshold > 0.0)
3604 vy = (double)(_elm_config->thumbscroll_hold_threshold -
3606 _elm_config->thumbscroll_hold_threshold;
3610 if ((vx != 0.0) || (vy != 0.0))
3612 sid->down.onhold_vx = vx;
3613 sid->down.onhold_vy = vy;
3614 if (!sid->down.onhold_animator)
3616 sid->down.onhold_vxe = 0.0;
3617 sid->down.onhold_vye = 0.0;
3618 sid->down.onhold_tlast = 0.0;
3619 sid->down.onhold_animator = ecore_animator_add
3620 (_elm_scroll_on_hold_animator, sid);
3625 if (sid->down.onhold_animator)
3627 ELM_SAFE_FREE(sid->down.onhold_animator, ecore_animator_del);
3628 if (sid->content_info.resized)
3629 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
3630 //_elm_scroll_wanted_region_set(sid->obj);
3631 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
3639 _elm_scroll_page_adjust(Elm_Scrollable_Smart_Interface_Data *sid)
3641 Evas_Coord x, y, w, h;
3643 if (!_paging_is_enabled(sid)) return;
3645 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
3646 (NULL, NULL, &w, &h));
3648 x = _elm_scroll_page_x_get(sid, 0, EINA_TRUE);
3649 y = _elm_scroll_page_y_get(sid, 0, EINA_TRUE);
3651 eo_do(sid->obj, elm_interface_scrollable_content_region_set(x, y, w, h));
3655 _elm_scroll_reconfigure(Elm_Scrollable_Smart_Interface_Data *sid)
3657 _elm_scroll_scroll_bar_size_adjust(sid);
3658 // TIZEN_ONLY(20150716): Remove dulplicated function calls for applying scroll bars visibility.
3659 //_elm_scroll_scroll_bar_h_visibility_apply(sid);
3660 //_elm_scroll_scroll_bar_v_visibility_apply(sid);
3662 _elm_scroll_page_adjust(sid);
3666 _on_edje_move(void *data,
3667 Evas *e EINA_UNUSED,
3668 Evas_Object *edje_obj,
3669 void *event_info EINA_UNUSED)
3671 Elm_Scrollable_Smart_Interface_Data *sid = data;
3674 evas_object_geometry_get(edje_obj, &x, &y, NULL, NULL);
3679 _elm_scroll_reconfigure(sid);
3683 _on_edje_resize(void *data,
3685 Evas_Object *edje_obj,
3686 void *event_info EINA_UNUSED)
3688 Elm_Scrollable_Smart_Interface_Data *sid = data;
3691 Eina_Bool reconf_ok = EINA_TRUE;
3693 evas_object_geometry_get(edje_obj, NULL, NULL, &w, &h);
3698 current_calc = evas_smart_objects_calculate_count_get(e);
3699 if (current_calc == sid->current_calc)
3702 if (sid->size_count > 3) reconf_ok = EINA_FALSE;
3706 sid->current_calc = current_calc;
3707 sid->size_count = 0;
3709 if (reconf_ok) _elm_scroll_reconfigure(sid);
3710 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
3711 //_elm_scroll_wanted_region_set(sid->obj);
3712 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
3717 _scroll_edje_object_attach(Evas_Object *obj)
3719 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3721 evas_object_event_callback_add
3722 (sid->edje_obj, EVAS_CALLBACK_RESIZE, _on_edje_resize, sid);
3723 evas_object_event_callback_add
3724 (sid->edje_obj, EVAS_CALLBACK_MOVE, _on_edje_move, sid);
3726 edje_object_signal_callback_add
3727 (sid->edje_obj, "reload", "elm", _elm_scroll_reload_cb, sid);
3728 edje_object_signal_callback_add
3729 (sid->edje_obj, "drag", "elm.dragable.vbar", _elm_scroll_vbar_drag_cb,
3731 edje_object_signal_callback_add
3732 (sid->edje_obj, "drag,set", "elm.dragable.vbar",
3733 _elm_scroll_edje_drag_v_cb, sid);
3734 edje_object_signal_callback_add
3735 (sid->edje_obj, "drag,start", "elm.dragable.vbar",
3736 _elm_scroll_edje_drag_v_start_cb, sid);
3737 edje_object_signal_callback_add
3738 (sid->edje_obj, "drag,stop", "elm.dragable.vbar",
3739 _elm_scroll_edje_drag_v_stop_cb, sid);
3740 edje_object_signal_callback_add
3741 (sid->edje_obj, "drag,step", "elm.dragable.vbar",
3742 _elm_scroll_edje_drag_v_cb, sid);
3743 edje_object_signal_callback_add
3744 (sid->edje_obj, "drag,page", "elm.dragable.vbar",
3745 _elm_scroll_edje_drag_v_cb, sid);
3746 edje_object_signal_callback_add
3747 (sid->edje_obj, "elm,vbar,press", "elm",
3748 _elm_scroll_vbar_press_cb, sid);
3749 edje_object_signal_callback_add
3750 (sid->edje_obj, "elm,vbar,unpress", "elm",
3751 _elm_scroll_vbar_unpress_cb, sid);
3752 edje_object_signal_callback_add
3753 (sid->edje_obj, "drag", "elm.dragable.hbar", _elm_scroll_hbar_drag_cb,
3755 edje_object_signal_callback_add
3756 (sid->edje_obj, "drag,set", "elm.dragable.hbar",
3757 _elm_scroll_edje_drag_h_cb, sid);
3758 edje_object_signal_callback_add
3759 (sid->edje_obj, "drag,start", "elm.dragable.hbar",
3760 _elm_scroll_edje_drag_h_start_cb, sid);
3761 edje_object_signal_callback_add
3762 (sid->edje_obj, "drag,stop", "elm.dragable.hbar",
3763 _elm_scroll_edje_drag_h_stop_cb, sid);
3764 edje_object_signal_callback_add
3765 (sid->edje_obj, "drag,step", "elm.dragable.hbar",
3766 _elm_scroll_edje_drag_h_cb, sid);
3767 edje_object_signal_callback_add
3768 (sid->edje_obj, "drag,page", "elm.dragable.hbar",
3769 _elm_scroll_edje_drag_h_cb, sid);
3770 edje_object_signal_callback_add
3771 (sid->edje_obj, "elm,hbar,press", "elm",
3772 _elm_scroll_hbar_press_cb, sid);
3773 edje_object_signal_callback_add
3774 (sid->edje_obj, "elm,hbar,unpress", "elm",
3775 _elm_scroll_hbar_unpress_cb, sid);
3779 _scroll_event_object_attach(Evas_Object *obj)
3781 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3783 evas_object_event_callback_add
3784 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL, _elm_scroll_wheel_event_cb,
3786 evas_object_event_callback_add
3787 (sid->event_rect, EVAS_CALLBACK_MOUSE_DOWN,
3788 _elm_scroll_mouse_down_event_cb, sid);
3789 evas_object_event_callback_add
3790 (sid->event_rect, EVAS_CALLBACK_MOUSE_UP,
3791 _elm_scroll_mouse_up_event_cb, sid);
3792 evas_object_event_callback_add
3793 (sid->event_rect, EVAS_CALLBACK_MOUSE_MOVE,
3794 _elm_scroll_mouse_move_event_cb, sid);
3798 _scroll_edje_object_detach(Evas_Object *obj)
3800 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3802 evas_object_event_callback_del_full
3803 (sid->edje_obj, EVAS_CALLBACK_RESIZE, _on_edje_resize, sid);
3804 evas_object_event_callback_del_full
3805 (sid->edje_obj, EVAS_CALLBACK_MOVE, _on_edje_move, sid);
3807 edje_object_signal_callback_del_full
3808 (sid->edje_obj, "drag", "elm.dragable.vbar", _elm_scroll_vbar_drag_cb,
3810 edje_object_signal_callback_del_full
3811 (sid->edje_obj, "drag,set", "elm.dragable.vbar",
3812 _elm_scroll_edje_drag_v_cb, sid);
3813 edje_object_signal_callback_del_full
3814 (sid->edje_obj, "drag,start", "elm.dragable.vbar",
3815 _elm_scroll_edje_drag_v_start_cb, sid);
3816 edje_object_signal_callback_del_full
3817 (sid->edje_obj, "drag,stop", "elm.dragable.vbar",
3818 _elm_scroll_edje_drag_v_stop_cb, sid);
3819 edje_object_signal_callback_del_full
3820 (sid->edje_obj, "drag,step", "elm.dragable.vbar",
3821 _elm_scroll_edje_drag_v_cb, sid);
3822 edje_object_signal_callback_del_full
3823 (sid->edje_obj, "drag,page", "elm.dragable.vbar",
3824 _elm_scroll_edje_drag_v_cb, sid);
3825 edje_object_signal_callback_del_full
3826 (sid->edje_obj, "elm,vbar,press", "elm",
3827 _elm_scroll_vbar_press_cb, sid);
3828 edje_object_signal_callback_del_full
3829 (sid->edje_obj, "elm,vbar,unpress", "elm",
3830 _elm_scroll_vbar_unpress_cb, sid);
3831 edje_object_signal_callback_del_full
3832 (sid->edje_obj, "drag", "elm.dragable.hbar", _elm_scroll_hbar_drag_cb,
3834 edje_object_signal_callback_del_full
3835 (sid->edje_obj, "drag,set", "elm.dragable.hbar",
3836 _elm_scroll_edje_drag_h_cb, sid);
3837 edje_object_signal_callback_del_full
3838 (sid->edje_obj, "drag,start", "elm.dragable.hbar",
3839 _elm_scroll_edje_drag_h_start_cb, sid);
3840 edje_object_signal_callback_del_full
3841 (sid->edje_obj, "drag,stop", "elm.dragable.hbar",
3842 _elm_scroll_edje_drag_h_stop_cb, sid);
3843 edje_object_signal_callback_del_full
3844 (sid->edje_obj, "drag,step", "elm.dragable.hbar",
3845 _elm_scroll_edje_drag_h_cb, sid);
3846 edje_object_signal_callback_del_full
3847 (sid->edje_obj, "drag,page", "elm.dragable.hbar",
3848 _elm_scroll_edje_drag_h_cb, sid);
3849 edje_object_signal_callback_del_full
3850 (sid->edje_obj, "elm,hbar,press", "elm",
3851 _elm_scroll_hbar_press_cb, sid);
3852 edje_object_signal_callback_del_full
3853 (sid->edje_obj, "elm,hbar,unpress", "elm",
3854 _elm_scroll_hbar_unpress_cb, sid);
3858 _scroll_event_object_detach(Evas_Object *obj)
3860 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3862 evas_object_event_callback_del_full
3863 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL, _elm_scroll_wheel_event_cb,
3865 evas_object_event_callback_del_full
3866 (sid->event_rect, EVAS_CALLBACK_MOUSE_DOWN,
3867 _elm_scroll_mouse_down_event_cb, sid);
3868 evas_object_event_callback_del_full
3869 (sid->event_rect, EVAS_CALLBACK_MOUSE_UP,
3870 _elm_scroll_mouse_up_event_cb, sid);
3871 evas_object_event_callback_del_full
3872 (sid->event_rect, EVAS_CALLBACK_MOUSE_MOVE,
3873 _elm_scroll_mouse_move_event_cb, sid);
3877 _elm_interface_scrollable_objects_set(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Object *edje_object, Evas_Object *hit_rectangle)
3881 if (!edje_object || !hit_rectangle) return;
3884 _scroll_edje_object_detach(obj);
3886 sid->edje_obj = edje_object;
3888 if (sid->event_rect)
3889 _scroll_event_object_detach(obj);
3891 sid->event_rect = hit_rectangle;
3892 evas_object_repeat_events_set(hit_rectangle, EINA_TRUE);
3894 _scroll_edje_object_attach(obj);
3895 _scroll_event_object_attach(obj);
3898 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
3899 if (edje_object_part_exists(sid->edje_obj, "elm.scrollbar.base"))
3903 base = edje_object_part_swallow_get
3904 (sid->edje_obj, "elm.scrollbar.base");
3907 base = evas_object_rectangle_add
3908 (evas_object_evas_get(sid->edje_obj));
3909 evas_object_color_set(base, 0, 0, 0, 0);
3910 edje_object_part_swallow
3911 (sid->edje_obj, "elm.scrollbar.base", base);
3913 if (!_elm_config->thumbscroll_enable)
3914 evas_object_size_hint_min_set(base, mw, mh);
3917 _elm_scroll_scroll_bar_visibility_adjust(sid);
3921 _elm_scroll_scroll_bar_reset(Elm_Scrollable_Smart_Interface_Data *sid)
3923 Evas_Coord px = 0, py = 0, minx = 0, miny = 0;
3925 if (!sid->edje_obj) return;
3927 edje_object_part_drag_value_set
3928 (sid->edje_obj, "elm.dragable.vbar", 0.0, 0.0);
3929 edje_object_part_drag_value_set
3930 (sid->edje_obj, "elm.dragable.hbar", 0.0, 0.0);
3931 if ((!sid->content) && (!sid->extern_pan))
3933 edje_object_part_drag_size_set
3934 (sid->edje_obj, "elm.dragable.vbar", 1.0, 1.0);
3935 edje_object_part_drag_size_set
3936 (sid->edje_obj, "elm.dragable.hbar", 1.0, 1.0);
3940 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
3941 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
3942 eo_do(sid->pan_obj, elm_obj_pan_pos_set(minx, miny));
3944 if ((px != minx) || (py != miny))
3945 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
3946 _elm_direction_arrows_eval(sid);
3950 _elm_scroll_pan_resized_cb(void *data,
3951 Evas *e EINA_UNUSED,
3952 Evas_Object *obj EINA_UNUSED,
3953 void *event_info EINA_UNUSED)
3955 Evas_Coord w = 0, h = 0;
3956 Elm_Scrollable_Smart_Interface_Data *sid = data;
3958 if (sid->cb_func.content_viewport_resize)
3960 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
3961 (NULL, NULL, &w, &h));
3962 sid->cb_func.content_viewport_resize(sid->obj, w, h);
3966 /* even external pan objects get this */
3968 _elm_scroll_pan_changed_cb(void *data,
3969 Evas_Object *obj EINA_UNUSED,
3970 void *event_info EINA_UNUSED)
3972 Evas_Coord w = 0, h = 0;
3973 Elm_Scrollable_Smart_Interface_Data *sid = data;
3975 if (!sid->pan_obj) return;
3977 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&w, &h));
3978 if ((w != sid->content_info.w) || (h != sid->content_info.h))
3980 sid->content_info.w = w;
3981 sid->content_info.h = h;
3982 _elm_scroll_scroll_bar_size_adjust(sid);
3984 evas_object_size_hint_min_set
3985 (sid->edje_obj, sid->content_info.w, sid->content_info.h);
3986 sid->content_info.resized = EINA_TRUE;
3987 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
3988 //_elm_scroll_wanted_region_set(sid->obj);
3989 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
3995 _elm_scroll_content_del_cb(void *data,
3996 Evas *e EINA_UNUSED,
3997 Evas_Object *obj EINA_UNUSED,
3998 void *event_info EINA_UNUSED)
4000 Elm_Scrollable_Smart_Interface_Data *sid = data;
4002 sid->content = NULL;
4003 _elm_scroll_scroll_bar_size_adjust(sid);
4004 _elm_scroll_scroll_bar_reset(sid);
4008 _elm_interface_scrollable_content_set(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Object *content)
4010 Evas_Coord w = 0, h = 0;
4013 if (!sid->edje_obj) return;
4017 /* if we had content, for sure we had a pan object */
4018 _elm_pan_content_set(sid->pan_obj, NULL);
4019 evas_object_event_callback_del_full
4020 (sid->content, EVAS_CALLBACK_DEL, _elm_scroll_content_del_cb, sid);
4023 sid->content = content;
4024 sid->wx = sid->wy = 0;
4025 /* (-1) means want viewports size */
4026 sid->ww = sid->wh = -1;
4027 if (!content) return;
4031 o = _elm_pan_add(evas_object_evas_get(obj));
4033 evas_object_smart_callback_add
4034 (o, SIG_CHANGED, _elm_scroll_pan_changed_cb, sid);
4035 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE,
4036 _elm_scroll_pan_resized_cb, sid);
4037 edje_object_part_swallow(sid->edje_obj, "elm.swallow.content", o);
4040 evas_object_event_callback_add
4041 (content, EVAS_CALLBACK_DEL, _elm_scroll_content_del_cb, sid);
4043 _elm_pan_content_set(sid->pan_obj, content);
4044 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&w, &h));
4045 sid->content_info.w = w;
4046 sid->content_info.h = h;
4048 _elm_scroll_scroll_bar_size_adjust(sid);
4049 _elm_scroll_scroll_bar_reset(sid);
4053 _elm_interface_scrollable_extern_pan_set(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Object *pan)
4055 if (!sid->edje_obj) return;
4057 eo_do(obj, elm_interface_scrollable_content_set(NULL));
4061 evas_object_smart_callback_del
4062 (sid->pan_obj, SIG_CHANGED, _elm_scroll_pan_changed_cb);
4063 evas_object_event_callback_del(sid->pan_obj, EVAS_CALLBACK_RESIZE,
4064 _elm_scroll_pan_resized_cb);
4067 if (sid->extern_pan)
4071 /* not owned by scroller, just leave (was external already) */
4072 edje_object_part_unswallow(sid->edje_obj, sid->pan_obj);
4073 sid->pan_obj = NULL;
4078 ELM_SAFE_FREE(sid->pan_obj, evas_object_del);
4082 sid->extern_pan = EINA_FALSE;
4088 sid->extern_pan = EINA_TRUE;
4089 evas_object_smart_callback_add
4090 (sid->pan_obj, SIG_CHANGED, _elm_scroll_pan_changed_cb, sid);
4091 evas_object_event_callback_add(sid->pan_obj, EVAS_CALLBACK_RESIZE,
4092 _elm_scroll_pan_resized_cb, sid);
4093 edje_object_part_swallow
4094 (sid->edje_obj, "elm.swallow.content", sid->pan_obj);
4098 _elm_interface_scrollable_drag_start_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb drag_start_cb)
4100 sid->cb_func.drag_start = drag_start_cb;
4104 _elm_interface_scrollable_drag_stop_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb drag_stop_cb)
4106 sid->cb_func.drag_stop = drag_stop_cb;
4110 _elm_interface_scrollable_animate_start_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb animate_start_cb)
4112 sid->cb_func.animate_start = animate_start_cb;
4116 _elm_interface_scrollable_animate_stop_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb animate_stop_cb)
4118 sid->cb_func.animate_stop = animate_stop_cb;
4122 _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)
4124 sid->cb_func.page_change = page_change_cb;
4128 _elm_interface_scrollable_scroll_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb scroll_cb)
4130 sid->cb_func.scroll = scroll_cb;
4134 _elm_interface_scrollable_scroll_left_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb scroll_left_cb)
4136 sid->cb_func.scroll_left = scroll_left_cb;
4140 _elm_interface_scrollable_scroll_right_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb scroll_right_cb)
4142 sid->cb_func.scroll_right = scroll_right_cb;
4146 _elm_interface_scrollable_scroll_up_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb scroll_up_cb)
4148 sid->cb_func.scroll_up = scroll_up_cb;
4152 _elm_interface_scrollable_scroll_down_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb scroll_down_cb)
4154 sid->cb_func.scroll_down = scroll_down_cb;
4158 _elm_interface_scrollable_edge_left_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb edje_left_cb)
4160 sid->cb_func.edge_left = edje_left_cb;
4164 _elm_interface_scrollable_edge_right_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb edje_right_cb)
4166 sid->cb_func.edge_right = edje_right_cb;
4170 _elm_interface_scrollable_edge_top_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb edje_top_cb)
4172 sid->cb_func.edge_top = edje_top_cb;
4176 _elm_interface_scrollable_edge_bottom_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb edje_bottom_cb)
4178 sid->cb_func.edge_bottom = edje_bottom_cb;
4182 _elm_interface_scrollable_vbar_drag_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb vbar_drag_cb)
4184 sid->cb_func.vbar_drag = vbar_drag_cb;
4188 _elm_interface_scrollable_vbar_press_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb vbar_press_cb)
4190 sid->cb_func.vbar_press = vbar_press_cb;
4194 _elm_interface_scrollable_vbar_unpress_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb vbar_unpress_cb)
4196 sid->cb_func.vbar_unpress = vbar_unpress_cb;
4200 _elm_interface_scrollable_hbar_drag_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb hbar_drag_cb)
4202 sid->cb_func.hbar_drag = hbar_drag_cb;
4206 _elm_interface_scrollable_hbar_press_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb hbar_press_cb)
4208 sid->cb_func.hbar_press = hbar_press_cb;
4212 _elm_interface_scrollable_hbar_unpress_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb hbar_unpress_cb)
4214 sid->cb_func.hbar_unpress = hbar_unpress_cb;
4218 _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)
4220 sid->cb_func.content_min_limit = min_limit_cb;
4224 _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)
4226 sid->cb_func.content_viewport_resize = viewport_resize_cb;
4229 EOLIAN static Eina_Bool
4230 _elm_interface_scrollable_momentum_animator_disabled_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid)
4232 return sid->momentum_animator_disabled;
4236 _elm_interface_scrollable_momentum_animator_disabled_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool disabled)
4238 sid->momentum_animator_disabled = disabled;
4239 if (sid->momentum_animator_disabled)
4241 if (sid->down.momentum_animator)
4243 ELM_SAFE_FREE(sid->down.momentum_animator, ecore_animator_del);
4244 if (sid->content_info.resized)
4245 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
4246 //_elm_scroll_wanted_region_set(sid->obj);
4247 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
4253 EOLIAN static Eina_Bool
4254 _elm_interface_scrollable_bounce_animator_disabled_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid)
4256 return sid->bounce_animator_disabled;
4260 _elm_interface_scrollable_bounce_animator_disabled_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool disabled)
4262 sid->bounce_animator_disabled = disabled;
4263 if (sid->bounce_animator_disabled)
4265 ELM_SAFE_FREE(sid->scrollto.x.animator, ecore_animator_del);
4266 ELM_SAFE_FREE(sid->scrollto.y.animator, ecore_animator_del);
4270 EOLIAN static Eina_Bool
4271 _elm_interface_scrollable_wheel_disabled_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid)
4273 return sid->wheel_disabled;
4277 _elm_interface_scrollable_wheel_disabled_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool disabled)
4279 if (!sid->event_rect) return;
4281 if ((!sid->wheel_disabled) && (disabled))
4282 evas_object_event_callback_del_full
4283 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL,
4284 _elm_scroll_wheel_event_cb, sid);
4285 else if ((sid->wheel_disabled) && (!disabled))
4286 evas_object_event_callback_add
4287 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL,
4288 _elm_scroll_wheel_event_cb, sid);
4289 sid->wheel_disabled = disabled;
4293 _elm_interface_scrollable_step_size_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord x, Evas_Coord y)
4300 _elm_scroll_scroll_bar_size_adjust(sid);
4304 _elm_interface_scrollable_step_size_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord *x, Evas_Coord *y)
4306 if (x) *x = sid->step.x;
4307 if (y) *y = sid->step.y;
4311 _elm_interface_scrollable_page_size_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord x, Evas_Coord y)
4316 _elm_scroll_scroll_bar_size_adjust(sid);
4320 _elm_interface_scrollable_page_size_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord *x, Evas_Coord *y)
4322 if (x) *x = sid->page.x;
4323 if (y) *y = sid->page.y;
4327 _elm_interface_scrollable_policy_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Scroller_Policy hbar, Elm_Scroller_Policy vbar)
4329 if (!sid->edje_obj) return;
4331 if ((sid->hbar_flags == hbar) && (sid->vbar_flags == vbar)) return;
4333 sid->hbar_flags = hbar;
4334 sid->vbar_flags = vbar;
4335 _elm_scroll_policy_signal_emit(sid);
4336 if (sid->cb_func.content_min_limit)
4337 sid->cb_func.content_min_limit(sid->obj, sid->min_w, sid->min_h);
4338 _elm_direction_arrows_eval(sid);
4342 _elm_interface_scrollable_policy_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Scroller_Policy *hbar, Elm_Scroller_Policy *vbar)
4344 if (hbar) *hbar = sid->hbar_flags;
4345 if (vbar) *vbar = sid->vbar_flags;
4349 _elm_interface_scrollable_single_direction_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Scroller_Single_Direction single_dir)
4351 sid->one_direction_at_a_time = single_dir;
4354 EOLIAN static Elm_Scroller_Single_Direction
4355 _elm_interface_scrollable_single_direction_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid)
4357 return sid->one_direction_at_a_time;
4361 _elm_interface_scrollable_repeat_events_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool repeat_events)
4363 if (sid->event_rect)
4364 evas_object_repeat_events_set(sid->event_rect, repeat_events);
4367 EOLIAN static Eina_Bool
4368 _elm_interface_scrollable_repeat_events_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid)
4370 if (sid->event_rect)
4371 return evas_object_repeat_events_get(sid->event_rect);
4377 _elm_interface_scrollable_hold_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool hold)
4383 _elm_interface_scrollable_freeze_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool freeze)
4385 sid->freeze = freeze;
4388 if (sid->down.onhold_animator)
4390 ELM_SAFE_FREE(sid->down.onhold_animator, ecore_animator_del);
4391 if (sid->content_info.resized)
4392 //TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid.
4393 //_elm_scroll_wanted_region_set(sid->obj);
4394 eo_do(sid->obj, elm_interface_scrollable_wanted_region_set(sid->wx, sid->wy));
4399 _elm_scroll_bounce_eval(sid);
4403 _elm_interface_scrollable_page_snap_allow_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool horiz, Eina_Bool vert)
4405 sid->page_snap_horiz = !!horiz;
4406 sid->page_snap_vert = !!vert;
4410 _elm_interface_scrollable_page_snap_allow_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool *horiz, Eina_Bool *vert)
4412 if (horiz) *horiz = sid->page_snap_horiz;
4413 if (vert) *vert = sid->page_snap_vert;
4417 _elm_interface_scrollable_bounce_allow_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool horiz, Eina_Bool vert)
4419 sid->bounce_horiz = !!horiz;
4420 sid->bounce_vert = !!vert;
4424 _elm_interface_scrollable_bounce_allow_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool *horiz, Eina_Bool *vert)
4426 if (horiz) *horiz = sid->bounce_horiz;
4427 if (vert) *vert = sid->bounce_vert;
4431 _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)
4433 sid->pagerel_h = pagerel_h;
4434 sid->pagerel_v = pagerel_v;
4435 sid->pagesize_h = pagesize_h;
4436 sid->pagesize_v = pagesize_v;
4438 _elm_scroll_page_adjust(sid);
4442 _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)
4444 if (pagerel_h) *pagerel_h = sid->pagerel_h;
4445 if (pagerel_v) *pagerel_v = sid->pagerel_v;
4446 if (pagesize_h) *pagesize_h = sid->pagesize_h;
4447 if (pagesize_v) *pagesize_v = sid->pagesize_v;
4451 _elm_interface_scrollable_page_relative_set(Eo *obj, Elm_Scrollable_Smart_Interface_Data *_pd EINA_UNUSED, double h_pagerel, double v_pagerel)
4453 Evas_Coord pagesize_h, pagesize_v;
4455 eo_do(obj, elm_interface_scrollable_paging_get(NULL, NULL, &pagesize_h, &pagesize_v));
4457 eo_do(obj, elm_interface_scrollable_paging_set(h_pagerel, v_pagerel, pagesize_h, pagesize_v));
4461 _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)
4463 sid->page_limit_h = page_limit_h;
4464 sid->page_limit_v = page_limit_v;
4468 _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)
4470 if (page_limit_h) *page_limit_h = sid->page_limit_h;
4471 if (page_limit_v) *page_limit_v = sid->page_limit_v;
4475 _elm_interface_scrollable_current_page_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, int *pagenumber_h, int *pagenumber_v)
4479 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
4482 if (sid->pagesize_h > 0)
4484 double result = (double)x / (double)sid->pagesize_h;
4485 double rest = result - (x / sid->pagesize_h);
4487 *pagenumber_h = result + 1;
4489 *pagenumber_h = result;
4496 if (sid->pagesize_v > 0)
4498 double result = (double)y / (double)sid->pagesize_v;
4499 double rest = result - (y / sid->pagesize_v);
4501 *pagenumber_v = result + 1;
4503 *pagenumber_v = result;
4511 _elm_interface_scrollable_last_page_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, int *pagenumber_h, int *pagenumber_v)
4515 if (!sid->pan_obj) return;
4517 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&cw, &ch));
4520 if ((sid->pagesize_h > 0) && (cw > sid->pagesize_h))
4521 *pagenumber_h = cw / sid->pagesize_h - 1;
4527 if ((sid->pagesize_v > 0) && (ch > sid->pagesize_v))
4528 *pagenumber_v = ch / sid->pagesize_v - 1;
4535 _elm_interface_scrollable_page_show(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid, int pagenumber_h, int pagenumber_v)
4537 Evas_Coord w = 0, h = 0;
4541 sid->current_page.x = _elm_scroll_page_x_get(sid, 0, EINA_FALSE);
4542 sid->current_page.y = _elm_scroll_page_y_get(sid, 0, EINA_FALSE);
4544 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
4545 (NULL, NULL, &w, &h));
4546 x = sid->pagesize_h * pagenumber_h;
4547 y = sid->pagesize_v * pagenumber_v;
4549 sid->wx = (sid->is_mirrored ? _elm_scroll_x_mirrored_get(sid->obj, x) : x);
4554 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
4555 eo_do(obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
4557 if ((sid->current_page.x != x) || (sid->current_page.y != y))
4559 if (sid->cb_func.page_change)
4560 sid->cb_func.page_change(sid->obj, NULL);
4565 _elm_interface_scrollable_page_bring_in(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid, int pagenumber_h, int pagenumber_v)
4567 Evas_Coord w = 0, h = 0;
4571 sid->current_page.x = _elm_scroll_page_x_get(sid, 0, EINA_FALSE);
4572 sid->current_page.y = _elm_scroll_page_y_get(sid, 0, EINA_FALSE);
4574 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
4575 (NULL, NULL, &w, &h));
4576 x = sid->pagesize_h * pagenumber_h;
4577 y = sid->pagesize_v * pagenumber_v;
4578 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
4580 _elm_scroll_scroll_to_x(sid, _elm_config->bring_in_scroll_friction, x);
4581 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, y);
4584 if ((sid->current_page.x != x) || (sid->current_page.y != y))
4586 if (sid->cb_func.page_change)
4587 sid->cb_func.page_change(sid->obj, NULL);
4592 _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)
4594 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
4596 _elm_scroll_scroll_to_x(sid, _elm_config->bring_in_scroll_friction, x);
4597 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, y);
4602 _elm_interface_scrollable_gravity_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, double x, double y)
4604 if (!sid->pan_obj) return;
4606 eo_do(sid->pan_obj, elm_obj_pan_gravity_set(x, y));
4610 _elm_interface_scrollable_gravity_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, double *x, double *y)
4612 if (!sid->pan_obj) return;
4614 eo_do(sid->pan_obj, elm_obj_pan_gravity_get(x, y));
4618 _elm_interface_scrollable_movement_block_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Scroller_Movement_Block block)
4623 EOLIAN static Elm_Scroller_Movement_Block
4624 _elm_interface_scrollable_movement_block_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid)
4630 _elm_interface_scrollable_loop_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool loop_h, Eina_Bool loop_v)
4632 if (sid->loop_h == loop_h && sid->loop_v == loop_v) return;
4634 sid->loop_h = loop_h;
4635 sid->loop_v = loop_v;
4639 _elm_interface_scrollable_loop_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool *loop_h, Eina_Bool *loop_v)
4641 *loop_h = sid->loop_h;
4642 *loop_v = sid->loop_v;
4646 _elm_interface_scrollable_evas_object_smart_add(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid)
4648 memset(sid, 0, sizeof(*sid));
4660 sid->page_limit_h = 9999;
4661 sid->page_limit_v = 9999;
4662 sid->hbar_flags = ELM_SCROLLER_POLICY_AUTO;
4663 sid->vbar_flags = ELM_SCROLLER_POLICY_AUTO;
4664 sid->hbar_visible = EINA_TRUE;
4665 sid->vbar_visible = EINA_TRUE;
4666 sid->loop_h = EINA_FALSE;
4667 sid->loop_v = EINA_FALSE;
4669 sid->bounce_horiz = EINA_TRUE;
4670 sid->bounce_vert = EINA_TRUE;
4672 sid->one_direction_at_a_time = ELM_SCROLLER_SINGLE_DIRECTION_SOFT;
4673 sid->momentum_animator_disabled = EINA_FALSE;
4674 sid->bounce_animator_disabled = EINA_FALSE;
4675 sid->block = ELM_SCROLLER_MOVEMENT_NO_BLOCK;
4677 _elm_scroll_scroll_bar_reset(sid);
4679 eo_do_super(obj, MY_SCROLLABLE_INTERFACE, evas_obj_smart_add());
4683 _elm_interface_scrollable_evas_object_smart_del(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid)
4686 eo_do_super(obj, MY_SCROLLABLE_INTERFACE, evas_obj_smart_del());
4688 eo_do(obj, elm_interface_scrollable_content_set(NULL));
4689 if (!sid->extern_pan) evas_object_del(sid->pan_obj);
4691 ecore_idle_enterer_del(sid->down.hold_enterer);
4692 ecore_animator_del(sid->down.hold_animator);
4693 ecore_animator_del(sid->down.onhold_animator);
4694 ecore_animator_del(sid->down.momentum_animator);
4695 ecore_animator_del(sid->down.bounce_x_animator);
4696 ecore_animator_del(sid->down.bounce_y_animator);
4697 ecore_animator_del(sid->scrollto.x.animator);
4698 ecore_animator_del(sid->scrollto.y.animator);
4702 _elm_interface_scrollable_eo_base_constructor(Eo *obj, Elm_Scrollable_Smart_Interface_Data *class_data EINA_UNUSED)
4704 eo_do_super(obj, MY_SCROLLABLE_INTERFACE, eo_constructor());
4708 _elm_interface_scrollable_class_constructor(Eo_Class *klass)
4710 evas_smart_legacy_type_register(MY_SCROLLABLE_INTERFACE_NAME_LEGACY, klass);
4713 #include "elm_interface_scrollable.eo.c"
4714 #include "elm_pan.eo.c"