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 eo_do(psd->self, eo_event_callback_call(ELM_PAN_EVENT_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 eo_do(psd->self, eo_event_callback_call(ELM_PAN_EVENT_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)
184 _elm_pan_content_size_get(Eo *obj EINA_UNUSED, Elm_Pan_Smart_Data *psd, Evas_Coord *w, Evas_Coord *h)
186 if (w) *w = psd->content_w;
187 if (h) *h = psd->content_h;
191 _elm_pan_gravity_set(Eo *obj EINA_UNUSED, Elm_Pan_Smart_Data *psd, double x, double y)
195 psd->prev_cw = psd->content_w;
196 psd->prev_ch = psd->content_h;
202 _elm_pan_gravity_get(Eo *obj EINA_UNUSED, Elm_Pan_Smart_Data *psd, double *x, double *y)
204 if (x) *x = psd->gravity_x;
205 if (y) *y = psd->gravity_y;
209 _elm_pan_add(Evas *evas)
211 Evas_Object *obj = eo_add(MY_PAN_CLASS, evas);
216 _elm_pan_eo_base_constructor(Eo *obj, Elm_Pan_Smart_Data *_pd EINA_UNUSED)
218 obj = eo_do_super_ret(obj, MY_PAN_CLASS, obj, eo_constructor());
220 evas_obj_type_set(MY_PAN_CLASS_NAME_LEGACY),
221 evas_obj_smart_callbacks_descriptions_set(_smart_callbacks));
227 _elm_pan_content_del_cb(void *data,
229 Evas_Object *obj EINA_UNUSED,
230 void *event_info EINA_UNUSED)
232 Elm_Pan_Smart_Data *psd;
236 psd->content_w = psd->content_h = psd->px = psd->py =
237 psd->prev_cw = psd->prev_ch = psd->delta_posx = psd->delta_posy = 0;
238 eo_do(psd->self, eo_event_callback_call(ELM_PAN_EVENT_CHANGED, NULL));
242 _elm_pan_content_resize_cb(void *data,
244 Evas_Object *obj EINA_UNUSED,
245 void *event_info EINA_UNUSED)
247 Elm_Pan_Smart_Data *psd;
251 evas_object_geometry_get(psd->content, NULL, NULL, &w, &h);
252 if ((w != psd->content_w) || (h != psd->content_h))
256 _elm_pan_update(psd);
258 eo_do(psd->self, eo_event_callback_call(ELM_PAN_EVENT_CHANGED, NULL));
262 _elm_pan_content_set(Evas_Object *obj,
263 Evas_Object *content)
267 ELM_PAN_DATA_GET_OR_RETURN(obj, psd);
269 if (content == psd->content) return;
272 evas_object_smart_member_del(psd->content);
273 evas_object_event_callback_del_full
274 (psd->content, EVAS_CALLBACK_DEL, _elm_pan_content_del_cb, psd);
275 evas_object_event_callback_del_full
276 (psd->content, EVAS_CALLBACK_RESIZE, _elm_pan_content_resize_cb,
280 if (!content) goto end;
282 psd->content = content;
283 evas_object_smart_member_add(psd->content, psd->self);
284 evas_object_geometry_get(psd->content, NULL, NULL, &w, &h);
287 evas_object_event_callback_add
288 (content, EVAS_CALLBACK_DEL, _elm_pan_content_del_cb, psd);
289 evas_object_event_callback_add
290 (content, EVAS_CALLBACK_RESIZE, _elm_pan_content_resize_cb, psd);
292 if (evas_object_visible_get(psd->self))
293 evas_object_show(psd->content);
295 evas_object_hide(psd->content);
297 _elm_pan_update(psd);
300 eo_do(psd->self, eo_event_callback_call(ELM_PAN_EVENT_CHANGED, NULL));
304 _elm_pan_class_constructor(Eo_Class *klass)
306 evas_smart_legacy_type_register(MY_PAN_CLASS_NAME_LEGACY, klass);
309 /* pan smart object on top, scroller interface on bottom */
310 /* ============================================================ */
312 #define MY_SCROLLABLE_INTERFACE ELM_INTERFACE_SCROLLABLE_MIXIN
314 #define MY_SCROLLABLE_INTERFACE_NAME "Elm_Interface_Scrollable"
315 #define MY_SCROLLABLE_INTERFACE_NAME_LEGACY "elm_interface_scrollable"
317 #define ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(o, ptr) \
318 Elm_Scrollable_Smart_Interface_Data *ptr = \
319 (!eo_isa(o, MY_SCROLLABLE_INTERFACE) ? NULL : \
320 eo_data_scope_get(o, MY_SCROLLABLE_INTERFACE)); \
323 CRI("No interface data for object %p (%s)", \
324 o, evas_object_type_get(o)); \
328 #define ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
329 Elm_Scrollable_Smart_Interface_Data *ptr = \
330 (!eo_isa(o, MY_SCROLLABLE_INTERFACE) ? NULL : \
331 eo_data_scope_get(o, MY_SCROLLABLE_INTERFACE)); \
334 CRI("No interface data for object %p (%s)", \
335 o, evas_object_type_get(o)); \
339 static void _elm_scroll_scroll_bar_size_adjust(
340 Elm_Scrollable_Smart_Interface_Data *);
341 static void _elm_scroll_wanted_region_set(Evas_Object *);
342 static Eina_Bool _paging_is_enabled(Elm_Scrollable_Smart_Interface_Data *sid);
343 static Evas_Coord _elm_scroll_page_x_get(
344 Elm_Scrollable_Smart_Interface_Data *sid, int offset, Eina_Bool limit);
345 static Evas_Coord _elm_scroll_page_y_get(
346 Elm_Scrollable_Smart_Interface_Data *sid, int offset, Eina_Bool limit);
353 //#define SCROLLDBG 1
354 /* smoothness debug calls - for debugging how much smooth your app is */
358 #define SMOOTH_DEBUG_COUNT 100
361 typedef struct _smooth_debug_info smooth_debug_info;
362 struct _smooth_debug_info
371 static smooth_debug_info smooth_x_history[SMOOTH_DEBUG_COUNT];
372 static smooth_debug_info smooth_y_history[SMOOTH_DEBUG_COUNT];
373 static int smooth_info_x_count = 0;
374 static int smooth_info_y_count = 0;
375 static double start_time = 0;
376 static int _elm_scroll_smooth_debug = 0;
379 _elm_scroll_smooth_debug_init(void)
381 start_time = ecore_time_get();
382 smooth_info_x_count = 0;
383 smooth_info_y_count = 0;
385 memset(&(smooth_x_history[0]), 0,
386 sizeof(smooth_x_history[0]) * SMOOTH_DEBUG_COUNT);
387 memset(&(smooth_y_history[0]), 0,
388 sizeof(smooth_y_history[0]) * SMOOTH_DEBUG_COUNT);
394 _elm_scroll_smooth_debug_shutdown(void)
397 int info_x_count = 0;
398 int info_y_count = 0;
399 double x_ave = 0, y_ave = 0;
400 double x_sum = 0, y_sum = 0;
401 double x_dev = 0, y_dev = 0;
402 double x_dev_sum = 0, y_dev_sum = 0;
404 if (smooth_info_x_count >= SMOOTH_DEBUG_COUNT)
405 info_x_count = SMOOTH_DEBUG_COUNT;
407 info_x_count = smooth_info_x_count;
409 if (smooth_info_y_count >= SMOOTH_DEBUG_COUNT)
410 info_y_count = SMOOTH_DEBUG_COUNT;
412 info_y_count = smooth_info_y_count;
414 DBG("\n\n<<< X-axis Smoothness >>>\n");
415 DBG("| Num | t(time) | dt | x | dx |vx(dx/1fps) |\n");
417 for (i = info_x_count - 1; i >= 0; i--)
419 DBG("| %4d | %1.6f | %1.6f | %4d | %4d | %9.3f |\n", info_x_count - i,
420 smooth_x_history[i].t,
421 smooth_x_history[i].dt,
422 smooth_x_history[i].pos,
423 smooth_x_history[i].dpos,
424 smooth_x_history[i].vpos);
425 if (i == info_x_count - 1) continue;
426 x_sum += smooth_x_history[i].vpos;
429 x_ave = x_sum / (info_x_count - 1);
430 for (i = 0; i < info_x_count - 1; i++)
432 x_dev_sum += (smooth_x_history[i].vpos - x_ave) *
433 (smooth_x_history[i].vpos - x_ave);
435 x_dev = x_dev_sum / (info_x_count - 1);
436 DBG(" Standard deviation of X-axis velocity: %9.3f\n", sqrt(x_dev));
438 DBG("\n\n<<< Y-axis Smoothness >>>\n");
439 DBG("| Num | t(time) | dt | y | dy |vy(dy/1fps) |\n");
440 for (i = info_y_count - 1; i >= 0; i--)
442 DBG("| %4d | %1.6f | %1.6f | %4d | %4d | %9.3f |\n", info_y_count - i,
443 smooth_y_history[i].t,
444 smooth_y_history[i].dt,
445 smooth_y_history[i].pos,
446 smooth_y_history[i].dpos,
447 smooth_y_history[i].vpos);
448 if (i == info_y_count - 1) continue;
449 y_sum += smooth_y_history[i].vpos;
451 y_ave = y_sum / (info_y_count - 1);
452 for (i = 0; i < info_y_count - 1; i++)
454 y_dev_sum += (smooth_y_history[i].vpos - y_ave) *
455 (smooth_y_history[i].vpos - y_ave);
457 y_dev = y_dev_sum / (info_y_count - 1);
459 DBG(" Standard deviation of Y-axis velocity: %9.3f\n", sqrt(y_dev));
463 _elm_direction_arrows_eval(Elm_Scrollable_Smart_Interface_Data *sid)
465 Eina_Bool go_left = EINA_TRUE, go_right = EINA_TRUE;
466 Eina_Bool go_up = EINA_TRUE, go_down = EINA_TRUE;
467 Evas_Coord x = 0, y = 0, mx = 0, my = 0, minx = 0, miny = 0;
469 if (!sid->edje_obj || !sid->pan_obj) return;
471 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
472 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
473 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&x, &y));
475 if (x == minx) go_left = EINA_FALSE;
476 if (x == (mx + minx)) go_right = EINA_FALSE;
477 if (y == miny) go_up = EINA_FALSE;
478 if (y == (my + miny)) go_down = EINA_FALSE;
479 if (go_left != sid->go_left)
482 edje_object_signal_emit(sid->edje_obj, "elm,action,show,left", "elm");
484 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,left", "elm");
485 sid->go_left = go_left;
487 if (go_right != sid->go_right)
490 edje_object_signal_emit(sid->edje_obj, "elm,action,show,right", "elm");
492 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,right", "elm");
493 sid->go_right= go_right;
495 if (go_up != sid->go_up)
498 edje_object_signal_emit(sid->edje_obj, "elm,action,show,up", "elm");
500 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,up", "elm");
503 if (go_down != sid->go_down)
506 edje_object_signal_emit(sid->edje_obj, "elm,action,show,down", "elm");
508 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,down", "elm");
509 sid->go_down= go_down;
514 _elm_scroll_smooth_debug_movetime_add(int x,
521 tim = ecore_time_get();
525 smooth_info_x_count++;
526 memmove(&(smooth_x_history[1]), &(smooth_x_history[0]),
527 sizeof(smooth_x_history[0]) * (SMOOTH_DEBUG_COUNT - 1));
528 smooth_x_history[0].t = tim - start_time;
529 smooth_x_history[0].dt = smooth_x_history[0].t - smooth_x_history[1].t;
530 smooth_x_history[0].pos = x;
531 smooth_x_history[0].dpos =
532 smooth_x_history[0].pos - smooth_x_history[1].pos;
534 if (smooth_x_history[0].dpos >= 0)
535 smooth_x_history[0].vpos = (double)(smooth_x_history[0].dpos) /
536 smooth_x_history[0].dt * FPS;
538 smooth_x_history[0].vpos = -((double)(smooth_x_history[0].dpos) /
539 smooth_x_history[0].dt * FPS);
544 smooth_info_y_count++;
545 memmove(&(smooth_y_history[1]), &(smooth_y_history[0]),
546 sizeof(smooth_y_history[0]) * (SMOOTH_DEBUG_COUNT - 1));
547 smooth_y_history[0].t = tim - start_time;
548 smooth_y_history[0].dt = smooth_y_history[0].t - smooth_y_history[1].t;
549 smooth_y_history[0].pos = y;
550 smooth_y_history[0].dpos = smooth_y_history[0].pos -
551 smooth_y_history[1].pos;
553 if (smooth_y_history[0].dpos >= 0)
554 smooth_y_history[0].vpos = (double)(smooth_y_history[0].dpos) /
555 smooth_y_history[0].dt * FPS;
557 smooth_y_history[0].vpos = -((double)(smooth_y_history[0].dpos) /
558 smooth_y_history[0].dt * FPS);
568 _elm_scroll_scroll_bar_h_visibility_apply(Elm_Scrollable_Smart_Interface_Data *sid)
570 if (sid->hbar_flags != ELM_SCROLLER_POLICY_OFF)
572 if (sid->hbar_visible)
573 edje_object_signal_emit
574 (sid->edje_obj, "elm,action,show,hbar", "elm");
576 edje_object_signal_emit
577 (sid->edje_obj, "elm,action,hide,hbar", "elm");
580 edje_object_signal_emit(sid->edje_obj, "elm,action,hide,hbar", "elm");
581 edje_object_message_signal_process(sid->edje_obj);
582 _elm_scroll_scroll_bar_size_adjust(sid);
583 if (sid->cb_func.content_min_limit)
584 sid->cb_func.content_min_limit(sid->obj, sid->min_w, sid->min_h);
588 _elm_scroll_scroll_bar_v_visibility_apply(Elm_Scrollable_Smart_Interface_Data *sid)
590 if (sid->vbar_flags != ELM_SCROLLER_POLICY_OFF)
592 if (sid->vbar_visible)
593 edje_object_signal_emit
594 (sid->edje_obj, "elm,action,show,vbar", "elm");
596 edje_object_signal_emit
597 (sid->edje_obj, "elm,action,hide,vbar", "elm");
600 edje_object_signal_emit
601 (sid->edje_obj, "elm,action,hide,vbar", "elm");
602 edje_object_message_signal_process(sid->edje_obj);
603 _elm_scroll_scroll_bar_size_adjust(sid);
604 if (sid->cb_func.content_min_limit)
605 sid->cb_func.content_min_limit(sid->obj, sid->min_w, sid->min_h);
609 _elm_scroll_scroll_bar_h_visibility_adjust(
610 Elm_Scrollable_Smart_Interface_Data *sid)
612 int scroll_h_vis_change = 0;
613 Evas_Coord w, vw = 0, vh = 0;
615 if (!sid->edje_obj) return 0;
617 w = sid->content_info.w;
619 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &vw, &vh);
620 if (sid->hbar_visible)
624 scroll_h_vis_change = 1;
625 sid->hbar_visible = EINA_FALSE;
629 if (sid->hbar_flags == ELM_SCROLLER_POLICY_AUTO)
631 if ((sid->content) || (sid->extern_pan))
635 scroll_h_vis_change = 1;
636 sid->hbar_visible = EINA_FALSE;
641 scroll_h_vis_change = 1;
642 sid->hbar_visible = EINA_FALSE;
645 else if (sid->hbar_flags == ELM_SCROLLER_POLICY_OFF)
647 scroll_h_vis_change = 1;
648 sid->hbar_visible = EINA_FALSE;
656 if (sid->hbar_flags == ELM_SCROLLER_POLICY_AUTO)
658 if ((sid->content) || (sid->extern_pan))
662 scroll_h_vis_change = 1;
663 sid->hbar_visible = EINA_TRUE;
667 else if (sid->hbar_flags == ELM_SCROLLER_POLICY_ON)
669 scroll_h_vis_change = 1;
670 sid->hbar_visible = EINA_TRUE;
675 if (scroll_h_vis_change) _elm_scroll_scroll_bar_h_visibility_apply(sid);
677 _elm_direction_arrows_eval(sid);
678 return scroll_h_vis_change;
682 _elm_scroll_scroll_bar_v_visibility_adjust(
683 Elm_Scrollable_Smart_Interface_Data *sid)
685 int scroll_v_vis_change = 0;
686 Evas_Coord h, vw = 0, vh = 0;
688 if (!sid->edje_obj) return 0;
690 h = sid->content_info.h;
692 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &vw, &vh);
693 if (sid->vbar_visible)
697 scroll_v_vis_change = 1;
698 sid->vbar_visible = EINA_FALSE;
702 if (sid->vbar_flags == ELM_SCROLLER_POLICY_AUTO)
704 if ((sid->content) || (sid->extern_pan))
708 scroll_v_vis_change = 1;
709 sid->vbar_visible = EINA_FALSE;
714 scroll_v_vis_change = 1;
715 sid->vbar_visible = EINA_FALSE;
718 else if (sid->vbar_flags == ELM_SCROLLER_POLICY_OFF)
720 scroll_v_vis_change = 1;
721 sid->vbar_visible = EINA_FALSE;
729 if (sid->vbar_flags == ELM_SCROLLER_POLICY_AUTO)
731 if ((sid->content) || (sid->extern_pan))
735 scroll_v_vis_change = 1;
736 sid->vbar_visible = EINA_TRUE;
740 else if (sid->vbar_flags == ELM_SCROLLER_POLICY_ON)
742 scroll_v_vis_change = 1;
743 sid->vbar_visible = EINA_TRUE;
747 if (scroll_v_vis_change) _elm_scroll_scroll_bar_v_visibility_apply(sid);
749 _elm_direction_arrows_eval(sid);
750 return scroll_v_vis_change;
754 _elm_scroll_scroll_bar_visibility_adjust(
755 Elm_Scrollable_Smart_Interface_Data *sid)
759 changed |= _elm_scroll_scroll_bar_h_visibility_adjust(sid);
760 changed |= _elm_scroll_scroll_bar_v_visibility_adjust(sid);
764 _elm_scroll_scroll_bar_h_visibility_adjust(sid);
765 _elm_scroll_scroll_bar_v_visibility_adjust(sid);
770 _elm_scroll_scroll_bar_size_adjust(Elm_Scrollable_Smart_Interface_Data *sid)
772 if (!sid->pan_obj || !sid->edje_obj) return;
774 if (sid->size_adjust_recurse_abort) return;
775 if (sid->size_adjust_recurse > 20)
777 sid->size_adjust_recurse_abort = EINA_TRUE;
780 sid->size_adjust_recurse++;
781 if ((sid->content) || (sid->extern_pan))
783 Evas_Coord x, y, w, h, mx = 0, my = 0, vw = 0, vh = 0, px, py,
787 edje_object_part_geometry_get
788 (sid->edje_obj, "elm.swallow.content", NULL, NULL, &vw, &vh);
789 w = sid->content_info.w;
791 size = (double)vw / (double)w;
796 edje_object_part_drag_value_set
797 (sid->edje_obj, "elm.dragable.hbar", 0.0, 0.0);
799 edje_object_part_drag_size_set
800 (sid->edje_obj, "elm.dragable.hbar", size, 1.0);
802 h = sid->content_info.h;
804 size = (double)vh / (double)h;
808 edje_object_part_drag_value_set
809 (sid->edje_obj, "elm.dragable.vbar", 0.0, 0.0);
811 edje_object_part_drag_size_set
812 (sid->edje_obj, "elm.dragable.vbar", 1.0, size);
814 edje_object_part_drag_value_get
815 (sid->edje_obj, "elm.dragable.hbar", &vx, NULL);
816 edje_object_part_drag_value_get
817 (sid->edje_obj, "elm.dragable.vbar", NULL, &vy);
819 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
820 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
824 edje_object_part_drag_step_set
825 (sid->edje_obj, "elm.dragable.hbar", (double)sid->step.x /
827 edje_object_part_drag_step_set
828 (sid->edje_obj, "elm.dragable.vbar", 0.0, (double)sid->step.y /
831 edje_object_part_drag_page_set
832 (sid->edje_obj, "elm.dragable.hbar", (double)sid->page.x /
835 edje_object_part_drag_page_set
836 (sid->edje_obj, "elm.dragable.hbar",
837 -((double)sid->page.x * ((double)vw / (double)w)) / 100.0, 0.0);
839 edje_object_part_drag_page_set
840 (sid->edje_obj, "elm.dragable.vbar", 0.0,
841 (double)sid->page.y / (double)h);
843 edje_object_part_drag_page_set
844 (sid->edje_obj, "elm.dragable.vbar", 0.0,
845 -((double)sid->page.y * ((double)vh / (double)h)) / 100.0);
847 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
848 if (vx != mx) x = px;
849 if (vy != my) y = py;
850 eo_do(sid->pan_obj, elm_obj_pan_pos_set(x, y));
852 if (mx > 0) vx = (double)(x - minx) / (double)mx;
855 if (vx < 0.0) vx = 0.0;
859 if (my > 0) vy = (double)(y - miny) / (double)my;
862 if (vy < 0.0) vy = 0.0;
866 edje_object_part_drag_value_set
867 (sid->edje_obj, "elm.dragable.vbar", 0.0, vy);
868 edje_object_part_drag_value_set
869 (sid->edje_obj, "elm.dragable.hbar", vx, 0.0);
873 Evas_Coord px = 0, py = 0, minx = 0, miny = 0;
875 edje_object_part_drag_size_set
876 (sid->edje_obj, "elm.dragable.vbar", 1.0, 1.0);
877 edje_object_part_drag_size_set
878 (sid->edje_obj, "elm.dragable.hbar", 1.0, 1.0);
879 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
880 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
881 eo_do(sid->pan_obj, elm_obj_pan_pos_set(minx, miny));
882 if ((px != minx) || (py != miny))
883 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
885 _elm_scroll_scroll_bar_visibility_adjust(sid);
886 sid->size_adjust_recurse--;
887 if (sid->size_adjust_recurse <= 0)
889 sid->size_adjust_recurse = 0;
890 sid->size_adjust_recurse_abort = EINA_FALSE;
895 _elm_scroll_scroll_bar_read_and_update(
896 Elm_Scrollable_Smart_Interface_Data *sid)
898 Evas_Coord x, y, mx = 0, my = 0, minx = 0, miny = 0;
901 if (!sid->edje_obj || !sid->pan_obj) return;
903 if ((sid->down.dragged) || (sid->down.bounce_x_animator)
904 || (sid->down.bounce_y_animator) || (sid->down.momentum_animator)
905 || (sid->scrollto.x.animator) || (sid->scrollto.y.animator))
907 edje_object_part_drag_value_get
908 (sid->edje_obj, "elm.dragable.vbar", NULL, &vy);
909 edje_object_part_drag_value_get
910 (sid->edje_obj, "elm.dragable.hbar", &vx, NULL);
911 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
912 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
913 x = _round(vx * (double)mx + minx, 1);
914 y = _round(vy * (double)my + miny, 1);
915 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
916 _elm_scroll_wanted_coordinates_update(sid, x, y);
920 _elm_scroll_drag_start(Elm_Scrollable_Smart_Interface_Data *sid)
922 sid->current_page.x = _elm_scroll_page_x_get(sid, 0, EINA_FALSE);
923 sid->current_page.y = _elm_scroll_page_y_get(sid, 0, EINA_FALSE);
925 if (sid->cb_func.drag_start)
926 sid->cb_func.drag_start(sid->obj, NULL);
930 _elm_scroll_drag_stop(Elm_Scrollable_Smart_Interface_Data *sid)
934 if (!(sid->down.bounce_x_animator) && !(sid->down.bounce_y_animator) &&
935 !(sid->scrollto.x.animator) && !(sid->scrollto.y.animator))
937 x = _elm_scroll_page_x_get(sid, 0, EINA_FALSE);
938 y = _elm_scroll_page_y_get(sid, 0, EINA_FALSE);
939 if (sid->cb_func.page_change &&
940 ((x != sid->current_page.x) || (y != sid->current_page.y)))
941 sid->cb_func.page_change(sid->obj, NULL);
942 sid->current_page.x = x;
943 sid->current_page.y = y;
946 if (sid->cb_func.drag_stop)
947 sid->cb_func.drag_stop(sid->obj, NULL);
951 _elm_scroll_anim_start(Elm_Scrollable_Smart_Interface_Data *sid)
953 sid->current_page.x = _elm_scroll_page_x_get(sid, 0, EINA_FALSE);
954 sid->current_page.y = _elm_scroll_page_y_get(sid, 0, EINA_FALSE);
956 if (sid->cb_func.animate_start)
957 sid->cb_func.animate_start(sid->obj, NULL);
961 _elm_scroll_anim_stop(Elm_Scrollable_Smart_Interface_Data *sid)
965 if (sid->cb_func.page_change)
967 x = _elm_scroll_page_x_get(sid, 0, EINA_FALSE);
968 y = _elm_scroll_page_y_get(sid, 0, EINA_FALSE);
969 if ((x != sid->current_page.x) || (y != sid->current_page.y))
970 sid->cb_func.page_change(sid->obj, NULL);
971 sid->current_page.x = x;
972 sid->current_page.y = y;
975 if (sid->cb_func.animate_stop)
976 sid->cb_func.animate_stop(sid->obj, NULL);
980 _elm_scroll_policy_signal_emit(Elm_Scrollable_Smart_Interface_Data *sid)
982 if (sid->hbar_flags == ELM_SCROLLER_POLICY_ON)
983 edje_object_signal_emit
984 (sid->edje_obj, "elm,action,show_always,hbar", "elm");
985 else if (sid->hbar_flags == ELM_SCROLLER_POLICY_OFF)
986 edje_object_signal_emit
987 (sid->edje_obj, "elm,action,hide,hbar", "elm");
989 edje_object_signal_emit
990 (sid->edje_obj, "elm,action,show_notalways,hbar", "elm");
991 if (sid->vbar_flags == ELM_SCROLLER_POLICY_ON)
992 edje_object_signal_emit
993 (sid->edje_obj, "elm,action,show_always,vbar", "elm");
994 else if (sid->vbar_flags == ELM_SCROLLER_POLICY_OFF)
995 edje_object_signal_emit
996 (sid->edje_obj, "elm,action,hide,vbar", "elm");
998 edje_object_signal_emit
999 (sid->edje_obj, "elm,action,show_notalways,vbar", "elm");
1000 edje_object_message_signal_process(sid->edje_obj);
1001 _elm_scroll_scroll_bar_size_adjust(sid);
1005 _elm_scroll_reload_cb(void *data,
1006 Evas_Object *obj EINA_UNUSED,
1007 const char *emission EINA_UNUSED,
1008 const char *source EINA_UNUSED)
1010 Elm_Scrollable_Smart_Interface_Data *sid = data;
1011 _elm_scroll_policy_signal_emit(sid);
1012 _elm_scroll_scroll_bar_h_visibility_apply(sid);
1013 _elm_scroll_scroll_bar_v_visibility_apply(sid);
1017 _elm_scroll_vbar_drag_cb(void *data,
1018 Evas_Object *obj EINA_UNUSED,
1019 const char *emission EINA_UNUSED,
1020 const char *source EINA_UNUSED)
1022 Elm_Scrollable_Smart_Interface_Data *sid = data;
1024 if (sid->cb_func.vbar_drag)
1025 sid->cb_func.vbar_drag(sid->obj, NULL);
1027 _elm_scroll_scroll_bar_read_and_update(sid);
1031 _elm_scroll_vbar_press_cb(void *data,
1032 Evas_Object *obj EINA_UNUSED,
1033 const char *emission EINA_UNUSED,
1034 const char *source EINA_UNUSED)
1036 Elm_Scrollable_Smart_Interface_Data *sid = data;
1038 if (sid->cb_func.vbar_press)
1039 sid->cb_func.vbar_press(sid->obj, NULL);
1043 _elm_scroll_vbar_unpress_cb(void *data,
1044 Evas_Object *obj EINA_UNUSED,
1045 const char *emission EINA_UNUSED,
1046 const char *source EINA_UNUSED)
1048 Elm_Scrollable_Smart_Interface_Data *sid = data;
1050 if (sid->cb_func.vbar_unpress)
1051 sid->cb_func.vbar_unpress(sid->obj, NULL);
1055 _elm_scroll_edje_drag_v_start_cb(void *data,
1056 Evas_Object *obj EINA_UNUSED,
1057 const char *emission EINA_UNUSED,
1058 const char *source EINA_UNUSED)
1060 Elm_Scrollable_Smart_Interface_Data *sid = data;
1062 _elm_scroll_scroll_bar_read_and_update(sid);
1063 _elm_scroll_drag_start(sid);
1064 sid->freeze = EINA_TRUE;
1068 _elm_scroll_edje_drag_v_stop_cb(void *data,
1069 Evas_Object *obj EINA_UNUSED,
1070 const char *emission EINA_UNUSED,
1071 const char *source EINA_UNUSED)
1073 Elm_Scrollable_Smart_Interface_Data *sid = data;
1075 _elm_scroll_scroll_bar_read_and_update(sid);
1076 _elm_scroll_drag_stop(sid);
1077 sid->freeze = EINA_FALSE;
1081 _elm_scroll_edje_drag_v_cb(void *data,
1082 Evas_Object *obj EINA_UNUSED,
1083 const char *emission EINA_UNUSED,
1084 const char *source EINA_UNUSED)
1086 Elm_Scrollable_Smart_Interface_Data *sid = data;
1088 _elm_scroll_scroll_bar_read_and_update(sid);
1092 _elm_scroll_hbar_drag_cb(void *data,
1093 Evas_Object *obj EINA_UNUSED,
1094 const char *emission EINA_UNUSED,
1095 const char *source EINA_UNUSED)
1097 Elm_Scrollable_Smart_Interface_Data *sid = data;
1099 if (sid->cb_func.hbar_drag)
1100 sid->cb_func.hbar_drag(sid->obj, NULL);
1102 _elm_scroll_scroll_bar_read_and_update(sid);
1106 _elm_scroll_hbar_press_cb(void *data,
1107 Evas_Object *obj EINA_UNUSED,
1108 const char *emission EINA_UNUSED,
1109 const char *source EINA_UNUSED)
1111 Elm_Scrollable_Smart_Interface_Data *sid = data;
1113 if (sid->cb_func.hbar_press)
1114 sid->cb_func.hbar_press(sid->obj, NULL);
1118 _elm_scroll_hbar_unpress_cb(void *data,
1119 Evas_Object *obj EINA_UNUSED,
1120 const char *emission EINA_UNUSED,
1121 const char *source EINA_UNUSED)
1123 Elm_Scrollable_Smart_Interface_Data *sid = data;
1125 if (sid->cb_func.hbar_unpress)
1126 sid->cb_func.hbar_unpress(sid->obj, NULL);
1130 _elm_scroll_edje_drag_h_start_cb(void *data,
1131 Evas_Object *obj EINA_UNUSED,
1132 const char *emission EINA_UNUSED,
1133 const char *source EINA_UNUSED)
1135 Elm_Scrollable_Smart_Interface_Data *sid = data;
1137 _elm_scroll_scroll_bar_read_and_update(sid);
1138 _elm_scroll_drag_start(sid);
1139 sid->freeze = EINA_TRUE;
1143 _elm_scroll_edje_drag_h_stop_cb(void *data,
1144 Evas_Object *obj EINA_UNUSED,
1145 const char *emission EINA_UNUSED,
1146 const char *source EINA_UNUSED)
1148 Elm_Scrollable_Smart_Interface_Data *sid = data;
1150 _elm_scroll_scroll_bar_read_and_update(sid);
1151 _elm_scroll_drag_stop(sid);
1152 sid->freeze = EINA_FALSE;
1156 _elm_scroll_edje_drag_h_cb(void *data,
1157 Evas_Object *obj EINA_UNUSED,
1158 const char *emission EINA_UNUSED,
1159 const char *source EINA_UNUSED)
1161 Elm_Scrollable_Smart_Interface_Data *sid = data;
1163 _elm_scroll_scroll_bar_read_and_update(sid);
1167 _elm_interface_scrollable_content_size_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord *w, Evas_Coord *h)
1169 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(w, h));
1173 _elm_interface_scrollable_content_viewport_geometry_get(Eo *obj EINA_UNUSED,
1174 Elm_Scrollable_Smart_Interface_Data *sid,
1180 if (!sid->pan_obj || !sid->edje_obj) return;
1182 edje_object_calc_force(sid->edje_obj);
1183 evas_object_geometry_get(sid->pan_obj, x, y, w, h);
1187 _elm_interface_scrollable_content_min_limit(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool w, Eina_Bool h)
1189 if (!sid->edje_obj) return;
1191 if (!sid->cb_func.content_min_limit)
1193 ERR("Content minimim size limiting is unimplemented -- you "
1194 "must provide it yourself\n");
1200 sid->cb_func.content_min_limit(sid->obj, w, h);
1204 _elm_scroll_x_mirrored_get(const Evas_Object *obj,
1207 Evas_Coord cw = 0, w = 0, min = 0, ret;
1209 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, x);
1211 if (!sid->pan_obj) return 0;
1213 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&min, NULL));
1214 eo_do((Eo *)obj, elm_interface_scrollable_content_viewport_geometry_get
1215 (NULL, NULL, &w, NULL));
1216 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&cw, NULL));
1217 ret = cw - w - x + min + min;
1219 return (ret >= min) ? ret : min;
1222 /* Update the wanted coordinates according to the x, y passed
1223 * widget directionality, content size and etc. */
1225 _elm_scroll_wanted_coordinates_update(Elm_Scrollable_Smart_Interface_Data *sid,
1229 Evas_Coord mx = 0, my = 0, minx = 0, miny = 0;
1231 if (!sid->pan_obj) return;
1233 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
1234 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
1236 /* Update wx/y/w/h - and if the requested positions aren't legal
1238 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
1239 (NULL, NULL, &sid->ww, &sid->wh));
1241 if (x < minx && !sid->is_mirrored)
1243 if (!sid->loop_h) sid->wx = minx;
1246 else if (sid->is_mirrored)
1247 sid->wx = _elm_scroll_x_mirrored_get(sid->obj, x);
1248 else if (!sid->loop_h && (x > mx)) sid->wx = mx;
1249 else if (sid->loop_h && x >= (sid->ww + mx)) sid->wx = 0;
1254 if (!sid->loop_v) sid->wy = miny;
1257 else if (!sid->loop_v && (y > my)) sid->wy = my;
1258 else if (sid->loop_v && y >= (sid->wh + my)) sid->wy = 0;
1263 _elm_scroll_momentum_end(Elm_Scrollable_Smart_Interface_Data *sid)
1265 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator)) return;
1266 if (sid->down.momentum_animator)
1268 Evas_Coord px = 0, py = 0;
1269 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&px, &py));
1270 _elm_scroll_wanted_coordinates_update(sid, px, py);
1272 ELM_SAFE_FREE(sid->down.momentum_animator, ecore_animator_del);
1273 sid->down.bounce_x_hold = EINA_FALSE;
1274 sid->down.bounce_y_hold = EINA_FALSE;
1281 if (sid->content_info.resized)
1282 _elm_scroll_wanted_region_set(sid->obj);
1287 _elm_scroll_bounce_x_animator(void *data)
1289 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(data, sid, EINA_FALSE);
1290 Evas_Coord x, y, dx, w, odx, ed, md;
1291 double t, p, dt, pd, r;
1293 t = ecore_loop_time_get();
1294 dt = t - sid->down.anim_start2;
1297 dt = dt / _elm_config->thumbscroll_bounce_friction;
1298 odx = sid->down.b2x - sid->down.bx;
1299 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
1300 (NULL, NULL, &w, NULL));
1301 if (!sid->down.momentum_animator && (w > abs(odx)))
1303 pd = (double)odx / (double)w;
1304 pd = (pd > 0) ? pd : -pd;
1305 pd = 1.0 - ((1.0 - pd) * (1.0 - pd));
1308 if (dt > 1.0) dt = 1.0;
1309 p = 1.0 - ((1.0 - dt) * (1.0 - dt));
1310 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
1313 if (sid->down.momentum_animator)
1315 ed = abs((int)(sid->down.dx * (_elm_config->thumbscroll_friction +
1316 sid->down.extra_time) - sid->down.b0x));
1317 md = abs((int)(_elm_config->thumbscroll_friction * 5 * w));
1318 if (ed > md) r = (double)(md) / (double)ed;
1320 x = sid->down.b2x + (int)((double)(dx - odx) * r);
1321 if (!sid->down.cancelled)
1322 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
1325 if (sid->down.momentum_animator)
1326 sid->down.bounce_x_hold = EINA_TRUE;
1327 if ((!sid->down.bounce_y_animator) &&
1328 (!sid->scrollto.y.animator))
1329 _elm_scroll_anim_stop(sid);
1330 sid->down.bounce_x_animator = NULL;
1332 sid->bouncemex = EINA_FALSE;
1333 _elm_scroll_momentum_end(sid);
1334 if (sid->content_info.resized)
1335 _elm_scroll_wanted_region_set(sid->obj);
1336 return ECORE_CALLBACK_CANCEL;
1339 return ECORE_CALLBACK_RENEW;
1343 _elm_scroll_bounce_y_animator(void *data)
1345 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(data, sid, EINA_FALSE);
1346 Evas_Coord x, y, dy, h, ody, ed, md;
1347 double t, p, dt, pd, r;
1349 t = ecore_loop_time_get();
1350 dt = t - sid->down.anim_start3;
1353 dt = dt / _elm_config->thumbscroll_bounce_friction;
1354 ody = sid->down.b2y - sid->down.by;
1355 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
1356 (NULL, NULL, NULL, &h));
1357 if (!sid->down.momentum_animator && (h > abs(ody)))
1359 pd = (double)ody / (double)h;
1360 pd = (pd > 0) ? pd : -pd;
1361 pd = 1.0 - ((1.0 - pd) * (1.0 - pd));
1364 if (dt > 1.0) dt = 1.0;
1365 p = 1.0 - ((1.0 - dt) * (1.0 - dt));
1366 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
1369 if (sid->down.momentum_animator)
1371 ed = abs((int)(sid->down.dy * (_elm_config->thumbscroll_friction +
1372 sid->down.extra_time) - sid->down.b0y));
1373 md = abs((int)(_elm_config->thumbscroll_friction * 5 * h));
1374 if (ed > md) r = (double)(md) / (double)ed;
1376 y = sid->down.b2y + (int)((double)(dy - ody) * r);
1377 if (!sid->down.cancelled)
1378 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
1381 if (sid->down.momentum_animator)
1382 sid->down.bounce_y_hold = EINA_TRUE;
1383 if ((!sid->down.bounce_x_animator) &&
1384 (!sid->scrollto.y.animator))
1385 _elm_scroll_anim_stop(sid);
1386 sid->down.bounce_y_animator = NULL;
1388 sid->bouncemey = EINA_FALSE;
1389 _elm_scroll_momentum_end(sid);
1390 if (sid->content_info.resized)
1391 _elm_scroll_wanted_region_set(sid->obj);
1392 return ECORE_CALLBACK_CANCEL;
1396 return ECORE_CALLBACK_RENEW;
1400 _elm_scroll_bounce_eval(Elm_Scrollable_Smart_Interface_Data *sid)
1402 Evas_Coord mx = 0, my = 0, px = 0, py = 0, bx, by, b2x, b2y, minx = 0, miny = 0;
1404 if (!sid->pan_obj) return;
1406 if (sid->freeze) return;
1407 if ((!sid->bouncemex) && (!sid->bouncemey)) return;
1408 if (sid->down.now) return; // down bounce while still held down
1409 if (sid->down.onhold_animator)
1411 ELM_SAFE_FREE(sid->down.onhold_animator, ecore_animator_del);
1412 if (sid->content_info.resized)
1413 _elm_scroll_wanted_region_set(sid->obj);
1415 if (sid->down.hold_animator)
1417 ELM_SAFE_FREE(sid->down.hold_animator, ecore_animator_del);
1418 if (sid->content_info.resized)
1419 _elm_scroll_wanted_region_set(sid->obj);
1421 ELM_SAFE_FREE(sid->down.hold_enterer, ecore_idle_enterer_del);
1423 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
1424 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
1425 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
1428 if (px < minx) px = minx;
1429 if ((px - minx) > mx) px = mx + minx;
1430 if (py < miny) py = miny;
1431 if ((py - miny) > my) py = my + miny;
1435 (!elm_widget_drag_child_locked_x_get(sid->obj)))
1437 if ((!sid->down.bounce_x_animator) && (!sid->bounce_animator_disabled))
1441 ELM_SAFE_FREE(sid->scrollto.x.animator, ecore_animator_del);
1442 sid->down.bounce_x_animator =
1443 ecore_animator_add(_elm_scroll_bounce_x_animator, sid->obj);
1444 sid->down.anim_start2 = ecore_loop_time_get();
1447 sid->down.b2x = b2x;
1448 if (sid->down.momentum_animator)
1449 sid->down.b0x = sid->down.ax;
1450 else sid->down.b0x = 0;
1455 (!elm_widget_drag_child_locked_y_get(sid->obj)))
1457 if ((!sid->down.bounce_y_animator) && (!sid->bounce_animator_disabled))
1461 ELM_SAFE_FREE(sid->scrollto.y.animator, ecore_animator_del);
1462 sid->down.bounce_y_animator =
1463 ecore_animator_add(_elm_scroll_bounce_y_animator, sid->obj);
1464 sid->down.anim_start3 = ecore_loop_time_get();
1467 sid->down.b2y = b2y;
1468 if (sid->down.momentum_animator)
1469 sid->down.b0y = sid->down.ay;
1470 else sid->down.b0y = 0;
1477 _elm_interface_scrollable_content_pos_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord *x, Evas_Coord *y)
1479 if (!sid->pan_obj) return;
1481 eo_do(sid->pan_obj, elm_obj_pan_pos_get(x, y));
1485 _elm_interface_scrollable_content_pos_set(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord x, Evas_Coord y, Eina_Bool sig)
1487 Evas_Coord mx = 0, my = 0, px = 0, py = 0, spx = 0, spy = 0, minx = 0, miny = 0;
1488 Evas_Coord cw = 0, ch = 0, pw = 0, ph = 0;
1489 // TIZEN_ONLY(20160624): Overscroll effect
1490 Evas_Coord ww = 0, wh = 0;
1495 if (!sid->edje_obj || !sid->pan_obj) return;
1497 // FIXME: allow for bounce outside of range
1498 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
1499 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
1500 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&cw, &ch));
1501 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
1502 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &pw, &ph);
1503 // TIZEN_ONLY(20160624): Overscroll effect
1504 eo_do(obj, elm_interface_scrollable_content_viewport_geometry_get
1505 (NULL, NULL, &ww, &wh));
1508 if (_paging_is_enabled(sid))
1510 if (sid->page_snap_horiz)
1512 //we passed one page to the right
1513 if (x > sid->current_page.x + sid->pagesize_h)
1514 x = sid->current_page.x + sid->pagesize_h;
1515 //we passed one page to the left
1516 if (x < sid->current_page.x - sid->pagesize_h)
1517 x = sid->current_page.x - sid->pagesize_h;
1519 if (sid->page_snap_vert)
1521 //we passed one page to the bottom
1522 if (y > sid->current_page.y + sid->pagesize_v)
1523 y = sid->current_page.y + sid->pagesize_v;
1524 //we passed one page to the top
1525 if (y < sid->current_page.y - sid->pagesize_v)
1526 y = sid->current_page.y - sid->pagesize_v;
1530 if (sid->loop_h && cw > 0)
1532 if (x < 0) x = cw + (x % cw);
1533 else if (x >= cw) x = (x % cw);
1535 if (sid->loop_v && ch > 0)
1537 if (y < 0) y = ch + (y % ch);
1538 else if (y >= ch) y = (y % ch);
1540 // TIZEN_ONLY(20160624): Overscroll effect
1546 edje_object_signal_emit(sid->edje_obj, "elm,edge,left", "elm");
1547 if (!sid->loop_h && (x - minx) > mx)
1548 edje_object_signal_emit(sid->edje_obj, "elm,edge,right", "elm");
1553 edje_object_signal_emit(sid->edje_obj, "elm,edge,top", "elm");
1554 if (!sid->loop_v && (y - miny) > my)
1555 edje_object_signal_emit(sid->edje_obj, "elm,edge,bottom", "elm");
1559 if (!_elm_config->thumbscroll_bounce_enable)
1562 if (x < minx) x = minx;
1563 if (!sid->loop_h && (x - minx) > mx) x = mx + minx;
1564 if (y < miny) y = miny;
1565 if (!sid->loop_v && (y - miny) > my) y = my + miny;
1568 if (!sid->bounce_horiz)
1570 if (x < minx) x = minx;
1571 if (!sid->loop_h && (x - minx) > mx) x = mx + minx;
1573 if (!sid->bounce_vert)
1575 if (y < miny) y = miny;
1576 if (!sid->loop_v && (y - miny) > my) y = my + miny;
1579 eo_do(sid->pan_obj, elm_obj_pan_pos_set(x, y));
1580 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&spx, &spy));
1582 if (mx > 0) vx = (double)(spx - minx) / (double)mx;
1585 if (vx < 0.0) vx = 0.0;
1589 if (my > 0) vy = (double)(spy - miny) / (double)my;
1592 if (vy < 0.0) vy = 0.0;
1596 edje_object_part_drag_value_set
1597 (sid->edje_obj, "elm.dragable.vbar", 0.0, vy);
1598 edje_object_part_drag_value_set
1599 (sid->edje_obj, "elm.dragable.hbar", vx, 0.0);
1601 if (!sid->loop_h && !sid->down.bounce_x_animator)
1603 if (((x < minx) && (0 <= sid->down.dx)) ||
1604 ((x > (mx + minx)) && (0 >= sid->down.dx)))
1606 sid->bouncemex = EINA_TRUE;
1607 _elm_scroll_bounce_eval(sid);
1610 sid->bouncemex = EINA_FALSE;
1612 if (!sid->loop_v && !sid->down.bounce_y_animator)
1614 if (((y < miny) && (0 <= sid->down.dy)) ||
1615 ((y > (my + miny)) && (0 >= sid->down.dy)))
1617 sid->bouncemey = EINA_TRUE;
1618 _elm_scroll_bounce_eval(sid);
1621 sid->bouncemey = EINA_FALSE;
1626 if ((x != px) || (y != py))
1628 if (sid->cb_func.scroll)
1629 sid->cb_func.scroll(obj, NULL);
1630 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
1633 if (sid->cb_func.scroll_left)
1634 sid->cb_func.scroll_left(obj, NULL);
1635 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,left", "elm");
1639 if (sid->cb_func.scroll_right)
1640 sid->cb_func.scroll_right(obj, NULL);
1641 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,right", "elm");
1645 if (sid->cb_func.scroll_up)
1646 sid->cb_func.scroll_up(obj, NULL);
1647 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,up", "elm");
1651 if (sid->cb_func.scroll_down)
1652 sid->cb_func.scroll_down(obj, NULL);
1653 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll,down", "elm");
1660 if (sid->cb_func.edge_left)
1661 sid->cb_func.edge_left(obj, NULL);
1662 // TIZEN_ONLY(20160624): Overscroll effect
1663 // edje_object_signal_emit(sid->edje_obj, "elm,edge,left", "elm");
1665 if (x == (mx + minx))
1667 if (sid->cb_func.edge_right)
1668 sid->cb_func.edge_right(obj, NULL);
1669 // TIZEN_ONLY(20160624): Overscroll effect
1670 //edje_object_signal_emit(sid->edje_obj, "elm,edge,right", "elm");
1677 if (sid->cb_func.edge_top)
1678 sid->cb_func.edge_top(obj, NULL);
1679 // TIZEN_ONLY(20160624): Overscroll effect
1680 //edje_object_signal_emit(sid->edje_obj, "elm,edge,top", "elm");
1684 if (sid->cb_func.edge_bottom)
1685 sid->cb_func.edge_bottom(obj, NULL);
1686 // TIZEN_ONLY(20160624): Overscroll effect
1687 // edje_object_signal_emit(sid->edje_obj, "elm,edge,bottom", "elm");
1692 _elm_direction_arrows_eval(sid);
1696 _elm_interface_scrollable_mirrored_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool mirrored)
1700 if (!sid->edje_obj) return;
1702 mirrored = !!mirrored;
1704 if (sid->is_mirrored == mirrored)
1707 sid->is_mirrored = mirrored;
1708 edje_object_mirrored_set(sid->edje_obj, mirrored);
1710 if (sid->is_mirrored)
1711 wx = _elm_scroll_x_mirrored_get(sid->obj, sid->wx);
1715 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(wx, sid->wy, EINA_FALSE));
1718 /* returns TRUE when we need to move the scroller, FALSE otherwise.
1719 * Updates w and h either way, so save them if you need them. */
1721 _elm_scroll_content_region_show_internal(Evas_Object *obj,
1727 Evas_Coord mx = 0, my = 0, cw = 0, ch = 0, px = 0, py = 0, nx, ny,
1728 minx = 0, miny = 0, pw = 0, ph = 0, x = *_x, y = *_y;
1730 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
1732 if (!sid->pan_obj) return EINA_FALSE;
1734 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
1735 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
1736 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&cw, &ch));
1737 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
1738 evas_object_geometry_get(sid->pan_obj, NULL, NULL, &pw, &ph);
1741 if ((x < px) && ((x + w) < (px + (cw - mx)))) nx = x;
1742 else if ((x > px) && ((x + w) > (px + (cw - mx))))
1743 nx = x + w - (cw - mx);
1745 if ((y < py) && ((y + h) < (py + (ch - my)))) ny = y;
1746 else if ((y > py) && ((y + h) > (py + (ch - my))))
1747 ny = y + h - (ch - my);
1749 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
1750 (sid->scrollto.x.animator) || (sid->scrollto.y.animator))
1752 ELM_SAFE_FREE(sid->scrollto.x.animator, ecore_animator_del);
1753 ELM_SAFE_FREE(sid->scrollto.y.animator, ecore_animator_del);
1754 if (sid->down.bounce_x_animator)
1756 ELM_SAFE_FREE(sid->down.bounce_x_animator, ecore_animator_del);
1757 sid->bouncemex = EINA_FALSE;
1758 if (sid->content_info.resized)
1759 _elm_scroll_wanted_region_set(sid->obj);
1761 if (sid->down.bounce_y_animator)
1763 ELM_SAFE_FREE(sid->down.bounce_y_animator, ecore_animator_del);
1764 sid->bouncemey = EINA_FALSE;
1765 if (sid->content_info.resized)
1766 _elm_scroll_wanted_region_set(sid->obj);
1769 _elm_scroll_anim_stop(sid);
1771 if (sid->down.hold_animator)
1773 ELM_SAFE_FREE(sid->down.hold_animator, ecore_animator_del);
1774 _elm_scroll_drag_stop(sid);
1775 if (sid->content_info.resized)
1776 _elm_scroll_wanted_region_set(sid->obj);
1778 ELM_SAFE_FREE(sid->down.hold_enterer, ecore_idle_enterer_del);
1779 if (sid->down.momentum_animator)
1781 ELM_SAFE_FREE(sid->down.momentum_animator, ecore_animator_del);
1782 sid->down.bounce_x_hold = EINA_FALSE;
1783 sid->down.bounce_y_hold = EINA_FALSE;
1788 if (sid->content_info.resized)
1789 _elm_scroll_wanted_region_set(sid->obj);
1792 if (_paging_is_enabled(sid))
1794 x = _elm_scroll_page_x_get(sid, nx - px, EINA_FALSE);
1795 y = _elm_scroll_page_y_get(sid, ny - py, EINA_FALSE);
1804 if ((x + pw) > cw) x = cw - pw;
1805 if (x < minx) x = minx;
1809 if ((y + ph) > ch) y = ch - ph;
1810 if (y < miny) y = miny;
1813 if ((x == px) && (y == py)) return EINA_FALSE;
1820 _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)
1822 eo_do(obj, elm_interface_scrollable_content_pos_get(x, y));
1823 eo_do(obj, elm_interface_scrollable_content_viewport_geometry_get
1824 (NULL, NULL, w, h));
1827 /* Set should be used for calculated positions, for example, when we move
1828 * because of an animation or because this is the correct position after
1831 _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)
1833 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
1835 eo_do(obj, elm_interface_scrollable_content_pos_set(x, y, EINA_FALSE));
1838 sid->down.x = sid->down.history[0].x;
1839 sid->down.y = sid->down.history[0].y;
1843 /* Set should be used for setting the wanted position, for example a
1844 * user scroll or moving the cursor in an entry. */
1846 _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)
1848 sid->wx = (sid->is_mirrored ? _elm_scroll_x_mirrored_get(sid->obj, x) : x);
1852 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
1854 // TIZEN_ONLY(20160624): Overscroll effect
1855 eo_do(obj, elm_interface_scrollable_content_pos_set(x, y, EINA_FALSE));
1859 sid->down.x = sid->down.history[0].x;
1860 sid->down.y = sid->down.history[0].y;
1865 _elm_scroll_wanted_region_set(Evas_Object *obj)
1867 Evas_Coord ww, wh, wx;
1869 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
1873 if (sid->down.now || sid->down.momentum_animator ||
1874 sid->down.bounce_x_animator || sid->down.bounce_y_animator ||
1875 sid->down.hold_animator || sid->down.onhold_animator ||
1876 sid->scrollto.x.animator || sid->scrollto.y.animator)
1879 sid->content_info.resized = EINA_FALSE;
1881 /* Flip to RTL cords only if init in RTL mode */
1882 if (sid->is_mirrored)
1883 wx = _elm_scroll_x_mirrored_get(obj, sid->wx);
1887 eo_do(obj, elm_interface_scrollable_content_viewport_geometry_get
1888 (NULL, NULL, &ww, &wh));
1896 eo_do(obj, elm_interface_scrollable_content_region_set(wx, sid->wy, ww, wh));
1901 _scroll_wheel_post_event_cb(void *data, Evas *e EINA_UNUSED)
1903 Elm_Scrollable_Smart_Interface_Data *sid = data;
1904 Evas_Event_Mouse_Wheel *ev = sid->event_info;
1906 Evas_Coord x = 0, y = 0, vw = 0, vh = 0, cw = 0, ch = 0;
1907 int pagenumber_h = 0, pagenumber_v = 0;
1908 int mx = 0, my = 0, minx = 0, miny = 0;
1909 Evas_Coord pwx, pwy;
1913 direction = ev->direction;
1918 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
1919 if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
1920 direction = !direction;
1922 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
1923 if (sid->scrollto.x.animator) x = sid->scrollto.x.end;
1924 if (sid->scrollto.y.animator) y = sid->scrollto.y.end;
1925 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
1926 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
1927 if (x < minx) x = minx;
1929 if (y < miny) y = miny;
1932 t = ecore_loop_time_get();
1934 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
1935 (sid->scrollto.x.animator) || (sid->scrollto.y.animator))
1937 _elm_scroll_anim_stop(sid);
1939 ELM_SAFE_FREE(sid->scrollto.x.animator, ecore_animator_del);
1940 ELM_SAFE_FREE(sid->scrollto.y.animator, ecore_animator_del);
1941 if (sid->down.bounce_x_animator)
1943 ELM_SAFE_FREE(sid->down.bounce_x_animator, ecore_animator_del);
1944 sid->bouncemex = EINA_FALSE;
1945 if (sid->content_info.resized)
1946 _elm_scroll_wanted_region_set(sid->obj);
1948 if (sid->down.bounce_y_animator)
1950 ELM_SAFE_FREE(sid->down.bounce_y_animator, ecore_animator_del);
1951 sid->bouncemey = EINA_FALSE;
1952 if (sid->content_info.resized)
1953 _elm_scroll_wanted_region_set(sid->obj);
1955 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
1956 (NULL, NULL, &vw, &vh));
1958 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&cw, &ch));
1959 if (!_paging_is_enabled(sid))
1962 double delta_t = (double)(ev->timestamp - sid->last_wheel) / 1000.0;
1965 mul = 1.0 + (7.0 * ((0.2 - delta_t) / 0.2));
1966 if (delta_t < 0.2) d *= mul;
1967 sid->last_wheel = ev->timestamp;
1970 if ((ch > vh) || (cw <= vw)) y += d * sid->step.y;
1971 else x += d * sid->step.x;
1973 else if (direction == 1)
1975 if ((cw > vw) || (ch <= vh)) x += d * sid->step.x;
1976 else y += d * sid->step.y;
1979 if ((!sid->hold) && (!sid->freeze))
1981 _elm_scroll_wanted_coordinates_update(sid, x, y);
1982 _elm_scroll_scroll_to_x(sid, _elm_config->bring_in_scroll_friction, x);
1983 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, y);
1988 eo_do(sid->obj, elm_interface_scrollable_current_page_get(&pagenumber_h, &pagenumber_v));
1991 if (ch > vh || cw <= vw)
1992 y = (pagenumber_v + (1 * ev->z)) * sid->pagesize_v;
1994 x = (pagenumber_h + (1 * ev->z)) * sid->pagesize_h;
1996 else if (direction == 1)
1998 if (cw > vw || ch <= vh)
1999 x = (pagenumber_h + (1 * ev->z)) * sid->pagesize_h;
2001 y = (pagenumber_v + (1 * ev->z)) * sid->pagesize_v;
2004 if ((!sid->hold) && (!sid->freeze))
2006 _elm_scroll_wanted_coordinates_update(sid, x, y);
2007 _elm_scroll_scroll_to_x(sid, _elm_config->bring_in_scroll_friction, x);
2008 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, y);
2014 if ((pwx != sid->wx) ||
2015 (((t - sid->down.last_time_x_wheel) < 0.5) &&
2016 (sid->down.last_hold_x_wheel)))
2018 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2019 sid->down.last_hold_x_wheel = EINA_TRUE;
2021 else sid->down.last_hold_x_wheel = EINA_FALSE;
2022 sid->down.last_time_x_wheel = t;
2026 if ((pwy != sid->wy) ||
2027 (((t - sid->down.last_time_y_wheel) < 0.5) &&
2028 (sid->down.last_hold_y_wheel)))
2030 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2031 sid->down.last_hold_y_wheel = EINA_TRUE;
2033 else sid->down.last_hold_y_wheel = EINA_FALSE;
2034 sid->down.last_time_y_wheel = t;
2041 _elm_scroll_wheel_event_cb(void *data,
2043 Evas_Object *obj EINA_UNUSED,
2046 Elm_Scrollable_Smart_Interface_Data *sid;
2047 Evas_Event_Mouse_Wheel *ev;
2052 sid->event_info = event_info;
2053 direction = ev->direction;
2055 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
2056 if ((evas_key_modifier_is_set(ev->modifiers, "Control")) ||
2057 (evas_key_modifier_is_set(ev->modifiers, "Alt")) ||
2058 (evas_key_modifier_is_set(ev->modifiers, "Meta")) ||
2059 (evas_key_modifier_is_set(ev->modifiers, "Hyper")) ||
2060 (evas_key_modifier_is_set(ev->modifiers, "Super")))
2064 if (sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL) return;
2068 if (sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL) return;
2071 evas_post_event_callback_push(e, _scroll_wheel_post_event_cb, sid);
2075 _elm_scroll_post_event_up(void *data,
2076 Evas *e EINA_UNUSED)
2078 Elm_Scrollable_Smart_Interface_Data *sid = data;
2082 if (sid->down.dragged)
2084 elm_widget_drag_lock_x_set(sid->obj, EINA_FALSE);
2085 elm_widget_drag_lock_y_set(sid->obj, EINA_FALSE);
2092 _paging_is_enabled(Elm_Scrollable_Smart_Interface_Data *sid)
2094 if ((sid->pagerel_h == 0.0) && (!sid->pagesize_h) &&
2095 (sid->pagerel_v == 0.0) && (!sid->pagesize_v))
2101 _elm_scroll_momentum_animator(void *data)
2103 double t, at, dt, p, r;
2104 Elm_Scrollable_Smart_Interface_Data *sid = data;
2105 Evas_Coord x, y, dx, dy, px, py, maxx, maxy, minx, miny;
2106 Eina_Bool no_bounce_x_end = EINA_FALSE, no_bounce_y_end = EINA_FALSE;
2110 sid->down.momentum_animator = NULL;
2111 return ECORE_CALLBACK_CANCEL;
2114 t = ecore_loop_time_get();
2115 dt = t - sid->down.anim_start;
2118 r = _elm_config->thumbscroll_min_friction / _elm_config->thumbscroll_friction;
2120 (sid->down.dx * sid->down.dx) + (sid->down.dy * sid->down.dy));
2121 at = at < ((1.0 - r) * _elm_config->thumbscroll_friction_standard) ?
2122 at : (1.0 - r) * _elm_config->thumbscroll_friction_standard;
2123 at = ((at / _elm_config->thumbscroll_friction_standard) + r) *
2124 (_elm_config->thumbscroll_friction + sid->down.extra_time);
2126 if (dt > 1.0) dt = 1.0;
2127 p = 1.0 - ((1.0 - dt) * (1.0 - dt));
2128 dx = (sid->down.dx * (_elm_config->thumbscroll_friction +
2129 sid->down.extra_time) * p);
2130 dy = (sid->down.dy * (_elm_config->thumbscroll_friction +
2131 sid->down.extra_time) * p);
2134 x = sid->down.sx - dx;
2135 y = sid->down.sy - dy;
2136 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&px, &py));
2137 if ((sid->down.bounce_x_animator) ||
2138 (sid->down.bounce_x_hold))
2140 sid->down.bx = sid->down.bx0 - dx + sid->down.b0x;
2143 if ((sid->down.bounce_y_animator) ||
2144 (sid->down.bounce_y_hold))
2146 sid->down.by = sid->down.by0 - dy + sid->down.b0y;
2149 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
2150 _elm_scroll_wanted_coordinates_update(sid, x, y);
2151 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&maxx, &maxy));
2152 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
2154 if (!_elm_config->thumbscroll_bounce_enable || !sid->bounce_horiz)
2156 if (x <= minx) no_bounce_x_end = EINA_TRUE;
2157 if (!sid->loop_h && (x - minx) >= maxx) no_bounce_x_end = EINA_TRUE;
2159 if (!_elm_config->thumbscroll_bounce_enable || !sid->bounce_vert)
2161 if (y <= miny) no_bounce_y_end = EINA_TRUE;
2162 if (!sid->loop_v && (y - miny) >= maxy) no_bounce_y_end = EINA_TRUE;
2165 ((sid->down.bounce_x_hold) && (sid->down.bounce_y_hold)) ||
2166 (no_bounce_x_end && no_bounce_y_end))
2168 _elm_scroll_anim_stop(sid);
2170 sid->down.momentum_animator = NULL;
2171 sid->down.bounce_x_hold = EINA_FALSE;
2172 sid->down.bounce_y_hold = EINA_FALSE;
2177 if (sid->content_info.resized)
2178 _elm_scroll_wanted_region_set(sid->obj);
2180 return ECORE_CALLBACK_CANCEL;
2184 return ECORE_CALLBACK_RENEW;
2188 _elm_scroll_page_x_get(Elm_Scrollable_Smart_Interface_Data *sid,
2189 int offset, Eina_Bool limit)
2191 Evas_Coord x, y, w, h, dx, cw, ch, minx = 0;
2193 if (!sid->pan_obj) return 0;
2195 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
2196 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
2197 (NULL, NULL, &w, &h));
2198 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&cw, &ch));
2199 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, NULL));
2201 if (sid->pagerel_h > 0.0)
2202 sid->pagesize_h = w * sid->pagerel_h;
2208 dx = (sid->pagesize_h * ((double)sid->page_limit_h - 0.5));
2211 x += (abs(offset) < dx ? offset : dx);
2213 x += (abs(offset) < dx ? offset : -(dx + 1));
2216 if (sid->pagesize_h > 0)
2219 x = x + (sid->pagesize_h * 0.5);
2220 else if (x < 0 && sid->loop_h)
2221 x = x - (sid->pagesize_h * 0.5);
2222 x = x / (sid->pagesize_h);
2223 x = x * (sid->pagesize_h);
2227 if ((x + w) > cw) x = cw - w;
2228 if (x < minx) x = minx;
2235 _elm_scroll_page_y_get(Elm_Scrollable_Smart_Interface_Data *sid,
2236 int offset, Eina_Bool limit)
2238 Evas_Coord x, y, w = 0, h = 0, dy, cw = 0, ch = 0, miny = 0;
2240 if (!sid->pan_obj) return 0;
2242 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
2243 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
2244 (NULL, NULL, &w, &h));
2245 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&cw, &ch));
2246 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(NULL, &miny));
2248 if (sid->pagerel_v > 0.0)
2249 sid->pagesize_v = h * sid->pagerel_v;
2255 dy = (sid->pagesize_v * ((double)sid->page_limit_v - 0.5));
2258 y += (abs(offset) < dy ? offset : dy);
2260 y += (abs(offset) < dy ? offset : -(dy + 1));
2263 if (sid->pagesize_v > 0)
2266 y = y + (sid->pagesize_v * 0.5);
2267 else if (y < 0 && sid->loop_v)
2268 y = y - (sid->pagesize_v * 0.5);
2269 y = y / (sid->pagesize_v);
2270 y = y * (sid->pagesize_v);
2274 if ((y + h) > ch) y = ch - h;
2275 if (y < miny) y = miny;
2282 _elm_scroll_scroll_to_x_animator(void *data)
2284 Elm_Scrollable_Smart_Interface_Data *sid = data;
2290 sid->scrollto.x.animator = NULL;
2291 return ECORE_CALLBACK_CANCEL;
2294 t = ecore_loop_time_get();
2295 tt = (t - sid->scrollto.x.t_start) /
2296 (sid->scrollto.x.t_end - sid->scrollto.x.t_start);
2298 tt = 1.0 - (tt * tt);
2299 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
2300 px = (sid->scrollto.x.start * (1.0 - tt)) +
2301 (sid->scrollto.x.end * tt);
2302 if (t >= sid->scrollto.x.t_end)
2304 px = sid->scrollto.x.end;
2305 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(px, py, EINA_TRUE));
2307 sid->down.x = sid->down.history[0].x;
2309 _elm_scroll_wanted_coordinates_update(sid, px, py);
2310 sid->scrollto.x.animator = NULL;
2311 if ((!sid->scrollto.y.animator) && (!sid->down.bounce_y_animator))
2312 _elm_scroll_anim_stop(sid);
2313 return ECORE_CALLBACK_CANCEL;
2315 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(px, py, EINA_TRUE));
2316 _elm_scroll_wanted_coordinates_update(sid, px, py);
2317 return ECORE_CALLBACK_RENEW;
2321 _elm_scroll_scroll_to_y_animator(void *data)
2323 Elm_Scrollable_Smart_Interface_Data *sid = data;
2327 if (!sid->pan_obj) return EINA_FALSE;
2329 t = ecore_loop_time_get();
2330 tt = (t - sid->scrollto.y.t_start) /
2331 (sid->scrollto.y.t_end - sid->scrollto.y.t_start);
2333 tt = 1.0 - (tt * tt);
2334 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
2335 py = (sid->scrollto.y.start * (1.0 - tt)) +
2336 (sid->scrollto.y.end * tt);
2337 if (t >= sid->scrollto.y.t_end)
2339 py = sid->scrollto.y.end;
2340 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(px, py, EINA_TRUE));
2342 sid->down.y = sid->down.history[0].y;
2344 _elm_scroll_wanted_coordinates_update(sid, px, py);
2345 sid->scrollto.y.animator = NULL;
2346 if ((!sid->scrollto.x.animator) && (!sid->down.bounce_x_animator))
2347 _elm_scroll_anim_stop(sid);
2348 return ECORE_CALLBACK_CANCEL;
2350 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(px, py, EINA_TRUE));
2351 _elm_scroll_wanted_coordinates_update(sid, px, py);
2353 return ECORE_CALLBACK_RENEW;
2357 _elm_scroll_scroll_to_y(Elm_Scrollable_Smart_Interface_Data *sid,
2361 Evas_Coord px = 0, py = 0, x, y, w, h;
2364 if (!sid->pan_obj) return;
2366 if (sid->freeze) return;
2369 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
2370 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
2371 (NULL, NULL, &w, &h));
2373 eo_do(sid->obj, elm_interface_scrollable_content_region_set(x, y, w, h));
2376 t = ecore_loop_time_get();
2377 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
2378 sid->scrollto.y.start = py;
2379 sid->scrollto.y.end = pos_y;
2380 sid->scrollto.y.t_start = t;
2381 sid->scrollto.y.t_end = t + t_in;
2382 if (!sid->scrollto.y.animator)
2384 sid->scrollto.y.animator =
2385 ecore_animator_add(_elm_scroll_scroll_to_y_animator, sid);
2386 if (!sid->scrollto.x.animator)
2387 _elm_scroll_anim_start(sid);
2389 if (sid->down.bounce_y_animator)
2391 ELM_SAFE_FREE(sid->down.bounce_y_animator, ecore_animator_del);
2392 _elm_scroll_momentum_end(sid);
2393 if (sid->content_info.resized)
2394 _elm_scroll_wanted_region_set(sid->obj);
2396 sid->bouncemey = EINA_FALSE;
2400 _elm_scroll_scroll_to_x(Elm_Scrollable_Smart_Interface_Data *sid,
2404 Evas_Coord px = 0, py = 0, x, y, w, h;
2407 if (!sid->pan_obj) return;
2409 if (sid->freeze) return;
2412 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
2413 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
2414 (NULL, NULL, &w, &h));
2416 eo_do(sid->obj, elm_interface_scrollable_content_region_set
2420 t = ecore_loop_time_get();
2421 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
2422 sid->scrollto.x.start = px;
2423 sid->scrollto.x.end = pos_x;
2424 sid->scrollto.x.t_start = t;
2425 sid->scrollto.x.t_end = t + t_in;
2426 if (!sid->scrollto.x.animator)
2428 sid->scrollto.x.animator =
2429 ecore_animator_add(_elm_scroll_scroll_to_x_animator, sid);
2430 if (!sid->scrollto.y.animator)
2431 _elm_scroll_anim_start(sid);
2433 if (sid->down.bounce_x_animator)
2435 ELM_SAFE_FREE(sid->down.bounce_x_animator, ecore_animator_del);
2436 _elm_scroll_momentum_end(sid);
2437 if (sid->content_info.resized)
2438 _elm_scroll_wanted_region_set(sid->obj);
2440 sid->bouncemex = EINA_FALSE;
2444 _elm_scroll_mouse_up_event_cb(void *data,
2446 Evas_Object *obj EINA_UNUSED,
2449 Elm_Scrollable_Smart_Interface_Data *sid = data;
2450 Evas_Coord x = 0, y = 0, ox = 0, oy = 0;
2451 Evas_Event_Mouse_Up *ev;
2453 if (!sid->pan_obj) return;
2455 if ((sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL) &&
2456 (sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
2460 if (_elm_scroll_smooth_debug) _elm_scroll_smooth_debug_shutdown();
2464 sid->down.hold_parent = EINA_FALSE;
2467 evas_post_event_callback_push(e, _elm_scroll_post_event_up, sid);
2469 // FIXME: respect elm_widget_scroll_hold_get of parent container
2470 if (!_elm_config->thumbscroll_enable) return;
2472 if (ev->button == 1)
2474 // TIZEN_ONLY(20160624): Overscroll effect
2475 edje_object_signal_emit(sid->edje_obj, "elm,state,mouse,up", "elm");
2477 if (sid->down.onhold_animator)
2479 ELM_SAFE_FREE(sid->down.onhold_animator, ecore_animator_del);
2480 if (sid->content_info.resized)
2481 _elm_scroll_wanted_region_set(sid->obj);
2483 x = ev->canvas.x - sid->down.x;
2484 y = ev->canvas.y - sid->down.y;
2485 if (sid->down.dragged)
2487 _elm_scroll_drag_stop(sid);
2488 if ((!sid->hold) && (!sid->freeze))
2492 Evas_Coord ax, ay, dx, dy, vel;
2495 t = ev->timestamp / 1000.0;
2497 t = ecore_loop_time_get();
2500 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2505 DBG("------ %i %i\n", ev->canvas.x, ev->canvas.y);
2507 for (i = 0; i < 60; i++)
2509 dt = t - sid->down.history[i].timestamp;
2510 if (dt > 0.2) break;
2512 DBG("H: %i %i @ %1.3f\n",
2513 sid->down.history[i].x,
2514 sid->down.history[i].y, dt);
2517 ax += sid->down.history[i].x;
2518 ay += sid->down.history[i].y;
2523 at /= _elm_config->thumbscroll_sensitivity_friction;
2524 dx = ev->canvas.x - ax;
2525 dy = ev->canvas.y - ay;
2528 vel = sqrt((dx * dx) + (dy * dy)) / at;
2529 if ((_elm_config->thumbscroll_friction > 0.0) &&
2530 (vel > _elm_config->thumbscroll_momentum_threshold))
2533 int minx, miny, mx, my, px, py;
2534 double tt = 0.0, dtt = 0.0;
2536 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get
2538 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get
2540 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
2541 max_d = _elm_config->thumbscroll_flick_distance_tolerance;
2544 if (dx > max_d) dx = max_d;
2545 sid->down.dx = (sin((M_PI * (double)dx / max_d)
2546 - (M_PI / 2)) + 1) * max_d / at;
2550 if (dx < -max_d) dx = -max_d;
2551 sid->down.dx = (sin((M_PI * (double)dx / max_d)
2552 + (M_PI / 2)) - 1) * max_d / at;
2556 if (dy > max_d) dy = max_d;
2557 sid->down.dy = (sin((M_PI * (double)dy / max_d)
2558 - (M_PI / 2)) + 1) * max_d / at;
2562 if (dy < -max_d) dy = -max_d;
2563 sid->down.dy = (sin((M_PI * (double)dy / max_d)
2564 + (M_PI / 2)) - 1) * max_d / at;
2566 if (((sid->down.dx > 0) && (sid->down.pdx > 0)) ||
2567 ((sid->down.dx < 0) && (sid->down.pdx < 0)) ||
2568 ((sid->down.dy > 0) && (sid->down.pdy > 0)) ||
2569 ((sid->down.dy < 0) && (sid->down.pdy < 0)))
2571 tt = ecore_loop_time_get();
2572 dtt = tt - sid->down.anim_start;
2574 if (dtt < 0.0) dtt = 0.0;
2576 _elm_config->thumbscroll_friction)
2577 dtt = _elm_config->thumbscroll_friction;
2578 sid->down.extra_time =
2579 _elm_config->thumbscroll_friction - dtt;
2582 sid->down.extra_time = 0.0;
2584 if (abs(sid->down.dx) > _elm_config->thumbscroll_acceleration_threshold &&
2585 (dtt < _elm_config->thumbscroll_acceleration_time_limit) &&
2586 (((sid->down.dx > 0) && (sid->down.pdx > 0)) ||
2587 ((sid->down.dx < 0) && (sid->down.pdx < 0))))
2588 if (px > minx && px < mx)
2589 sid->down.dx += (double)sid->down.pdx * _elm_config->thumbscroll_acceleration_weight;
2590 if (abs(sid->down.dy) > _elm_config->thumbscroll_acceleration_threshold &&
2591 (dtt < _elm_config->thumbscroll_acceleration_time_limit) &&
2592 (((sid->down.dy > 0) && (sid->down.pdy > 0)) ||
2593 ((sid->down.dy < 0) && (sid->down.pdy < 0))))
2594 if (py > miny && py < my)
2596 sid->down.dy += (double)sid->down.pdy * _elm_config->thumbscroll_acceleration_weight;
2598 sid->down.pdx = sid->down.dx;
2599 sid->down.pdy = sid->down.dy;
2602 if (!_paging_is_enabled(sid))
2604 if ((!sid->down.momentum_animator) &&
2605 (!sid->momentum_animator_disabled) &&
2607 (!elm_widget_drag_child_locked_y_get
2610 sid->down.momentum_animator =
2612 (_elm_scroll_momentum_animator, sid);
2614 EVAS_EVENT_FLAG_ON_SCROLL;
2615 _elm_scroll_anim_start(sid);
2617 sid->down.anim_start = ecore_loop_time_get();
2619 elm_interface_scrollable_content_pos_get(&x, &y));
2633 evas_event_feed_hold(e, 0, ev->timestamp, ev->data);
2634 if (_paging_is_enabled(sid))
2636 Evas_Coord pgx, pgy;
2638 eo_do(sid->obj, elm_interface_scrollable_content_pos_get
2641 (!elm_widget_drag_child_locked_x_get
2644 pgx = _elm_scroll_page_x_get(sid, ox, EINA_TRUE);
2647 ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
2649 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2650 _elm_scroll_scroll_to_x
2651 (sid, _elm_config->page_scroll_friction, pgx);
2655 (!elm_widget_drag_child_locked_y_get
2658 pgy = _elm_scroll_page_y_get(sid, oy, EINA_TRUE);
2661 ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL))
2663 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2664 _elm_scroll_scroll_to_y
2665 (sid, _elm_config->page_scroll_friction, pgy);
2674 if (_paging_is_enabled(sid))
2676 Evas_Coord pgx, pgy;
2678 eo_do(sid->obj, elm_interface_scrollable_content_pos_get
2681 (!elm_widget_drag_child_locked_x_get
2684 pgx = _elm_scroll_page_x_get(sid, ox, EINA_TRUE);
2686 _elm_scroll_scroll_to_x
2687 (sid, _elm_config->page_scroll_friction, pgx);
2690 (!elm_widget_drag_child_locked_y_get
2693 pgy = _elm_scroll_page_y_get(sid, oy, EINA_TRUE);
2695 _elm_scroll_scroll_to_y
2696 (sid, _elm_config->page_scroll_friction, pgy);
2700 if (sid->down.hold_animator)
2702 ELM_SAFE_FREE(sid->down.hold_animator, ecore_animator_del);
2703 if (sid->content_info.resized)
2704 _elm_scroll_wanted_region_set(sid->obj);
2706 ELM_SAFE_FREE(sid->down.hold_enterer, ecore_idle_enterer_del);
2707 if (sid->down.scroll)
2709 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
2710 sid->down.scroll = EINA_FALSE;
2714 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
2715 sid->down.hold = EINA_FALSE;
2717 sid->down.dragged_began = EINA_FALSE;
2718 sid->down.dir_x = EINA_FALSE;
2719 sid->down.dir_y = EINA_FALSE;
2720 sid->down.want_dragged = EINA_FALSE;
2721 sid->down.dragged = EINA_FALSE;
2722 sid->down.now = EINA_FALSE;
2723 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
2724 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
2725 _elm_scroll_wanted_coordinates_update(sid, x, y);
2727 if (sid->content_info.resized)
2728 _elm_scroll_wanted_region_set(sid->obj);
2730 if (!_paging_is_enabled(sid))
2731 _elm_scroll_bounce_eval(sid);
2736 _elm_scroll_mouse_down_event_cb(void *data,
2737 Evas *e EINA_UNUSED,
2738 Evas_Object *obj EINA_UNUSED,
2741 Elm_Scrollable_Smart_Interface_Data *sid;
2742 Evas_Event_Mouse_Down *ev;
2743 Evas_Coord x = 0, y = 0;
2748 if ((sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL) &&
2749 (sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
2753 if (getenv("ELS_SCROLLER_SMOOTH_DEBUG")) _elm_scroll_smooth_debug = 1;
2754 if (_elm_scroll_smooth_debug) _elm_scroll_smooth_debug_init();
2757 if (!_elm_config->thumbscroll_enable) return;
2760 sid->down.hold = EINA_FALSE;
2761 if ((sid->down.bounce_x_animator) || (sid->down.bounce_y_animator) ||
2762 (sid->down.momentum_animator) || (sid->scrollto.x.animator) ||
2763 (sid->scrollto.y.animator))
2765 ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL |
2766 EVAS_EVENT_FLAG_ON_HOLD;
2767 sid->down.scroll = EINA_TRUE;
2768 sid->down.hold = EINA_TRUE;
2769 _elm_scroll_anim_stop(sid);
2771 ELM_SAFE_FREE(sid->scrollto.x.animator, ecore_animator_del);
2772 ELM_SAFE_FREE(sid->scrollto.y.animator, ecore_animator_del);
2773 if (sid->down.bounce_x_animator)
2775 ELM_SAFE_FREE(sid->down.bounce_x_animator, ecore_animator_del);
2776 sid->bouncemex = EINA_FALSE;
2777 if (sid->content_info.resized)
2778 _elm_scroll_wanted_region_set(sid->obj);
2780 if (sid->down.bounce_y_animator)
2782 ELM_SAFE_FREE(sid->down.bounce_y_animator, ecore_animator_del);
2783 sid->bouncemey = EINA_FALSE;
2784 if (sid->content_info.resized)
2785 _elm_scroll_wanted_region_set(sid->obj);
2787 if (sid->down.hold_animator)
2789 ELM_SAFE_FREE(sid->down.hold_animator, ecore_animator_del);
2790 _elm_scroll_drag_stop(sid);
2791 if (sid->content_info.resized)
2792 _elm_scroll_wanted_region_set(sid->obj);
2794 ELM_SAFE_FREE(sid->down.hold_enterer, ecore_idle_enterer_del);
2795 if (sid->down.momentum_animator)
2797 ELM_SAFE_FREE(sid->down.momentum_animator, ecore_animator_del);
2798 sid->down.bounce_x_hold = EINA_FALSE;
2799 sid->down.bounce_y_hold = EINA_FALSE;
2802 if (sid->content_info.resized)
2803 _elm_scroll_wanted_region_set(sid->obj);
2805 if (ev->button == 1)
2807 // TIZEN_ONLY(20160624): Overscroll effect
2808 edje_object_signal_emit(sid->edje_obj, "elm,state,mouse,down", "elm");
2810 sid->down.hist.est_timestamp_diff =
2811 ecore_loop_time_get() - ((double)ev->timestamp / 1000.0);
2812 sid->down.hist.tadd = 0.0;
2813 sid->down.hist.dxsum = 0.0;
2814 sid->down.hist.dysum = 0.0;
2815 sid->down.now = EINA_TRUE;
2816 sid->down.dragged = EINA_FALSE;
2817 sid->down.dir_x = EINA_FALSE;
2818 sid->down.dir_y = EINA_FALSE;
2819 sid->down.x = ev->canvas.x;
2820 sid->down.y = ev->canvas.y;
2821 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
2824 sid->down.locked = EINA_FALSE;
2825 memset(&(sid->down.history[0]), 0,
2826 sizeof(sid->down.history[0]) * 60);
2828 sid->down.history[0].timestamp = ev->timestamp / 1000.0;
2829 sid->down.history[0].localtimestamp = ecore_loop_time_get();
2831 sid->down.history[0].timestamp = ecore_loop_time_get();
2833 sid->down.dragged_began_timestamp = sid->down.history[0].timestamp;
2834 sid->down.history[0].x = ev->canvas.x;
2835 sid->down.history[0].y = ev->canvas.y;
2837 sid->down.dragged_began = EINA_FALSE;
2838 sid->down.hold_parent = EINA_FALSE;
2839 sid->down.cancelled = EINA_FALSE;
2840 if (sid->hold || sid->freeze)
2841 sid->down.want_reset = EINA_TRUE;
2843 sid->down.want_reset = EINA_FALSE;
2847 _elm_scroll_can_scroll(Elm_Scrollable_Smart_Interface_Data *sid,
2850 Evas_Coord mx = 0, my = 0, px = 0, py = 0, minx = 0, miny = 0;
2852 if (!sid->pan_obj) return EINA_FALSE;
2854 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
2855 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
2856 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
2860 if (px > minx) return EINA_TRUE;
2864 if ((px - minx) < mx) return EINA_TRUE;
2868 if (py > miny) return EINA_TRUE;
2872 if ((py - miny) < my) return EINA_TRUE;
2882 _elm_scroll_post_event_move(void *data,
2883 Evas *e EINA_UNUSED)
2885 Elm_Scrollable_Smart_Interface_Data *sid = data;
2886 Eina_Bool horiz, vert;
2889 if (!sid->down.want_dragged) return EINA_TRUE;
2891 elm_widget_parents_bounce_get(sid->obj, &horiz, &vert);
2892 if (sid->down.hold_parent)
2894 if ((sid->down.dir_x) && (horiz || !sid->bounce_horiz) &&
2895 !_elm_scroll_can_scroll(sid, sid->down.hdir))
2897 sid->down.dir_x = EINA_FALSE;
2899 if ((sid->down.dir_y) && (vert || !sid->bounce_vert) &&
2900 !_elm_scroll_can_scroll(sid, sid->down.vdir))
2902 sid->down.dir_y = EINA_FALSE;
2904 sid->down.dragged_began = EINA_TRUE;
2906 if (sid->down.dir_x)
2909 (!elm_widget_drag_child_locked_x_get(sid->obj)))
2911 if (sid->down.dragged_began)
2913 sid->down.want_dragged = EINA_FALSE;
2914 sid->down.dragged = EINA_TRUE;
2917 elm_widget_drag_lock_x_set(sid->obj, 1);
2924 sid->down.dragged_began = EINA_TRUE;
2925 sid->down.dir_x = EINA_FALSE;
2928 if (sid->down.dir_y)
2931 (!elm_widget_drag_child_locked_y_get(sid->obj)))
2933 if (sid->down.dragged_began)
2935 sid->down.want_dragged = EINA_FALSE;
2936 sid->down.dragged = EINA_TRUE;
2939 elm_widget_drag_lock_y_set
2940 (sid->obj, EINA_TRUE);
2947 sid->down.dragged_began = EINA_TRUE;
2948 sid->down.dir_y = EINA_FALSE;
2951 if ((!sid->down.dir_x) && (!sid->down.dir_y))
2953 sid->down.cancelled = EINA_TRUE;
2955 if (start) _elm_scroll_drag_start(sid);
2961 _elm_scroll_down_coord_eval(Elm_Scrollable_Smart_Interface_Data *sid,
2965 Evas_Coord minx, miny;
2967 if (!sid->pan_obj) return;
2969 if (sid->down.dir_x) *x = sid->down.sx - (*x - sid->down.x);
2970 else *x = sid->down.sx;
2971 if (sid->down.dir_y) *y = sid->down.sy - (*y - sid->down.y);
2972 else *y = sid->down.sy;
2974 if ((sid->down.dir_x) || (sid->down.dir_y))
2976 if (!((sid->down.dir_x) && (sid->down.dir_y)))
2978 if (sid->down.dir_x) *y = sid->down.locked_y;
2979 else *x = sid->down.locked_x;
2983 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
2985 if (!sid->loop_h && *x < minx)
2986 *x += (minx - *x) * _elm_config->thumbscroll_border_friction;
2987 else if (!sid->loop_h && sid->content_info.w <= sid->w)
2988 *x += (sid->down.sx - *x) * _elm_config->thumbscroll_border_friction;
2989 else if (!sid->loop_h && (sid->content_info.w - sid->w + minx) < *x)
2990 *x += (sid->content_info.w - sid->w + minx - *x) *
2991 _elm_config->thumbscroll_border_friction;
2993 if (!sid->loop_v && *y < miny)
2994 *y += (miny - *y) * _elm_config->thumbscroll_border_friction;
2995 else if (!sid->loop_v && sid->content_info.h <= sid->h)
2996 *y += (sid->down.sy - *y) * _elm_config->thumbscroll_border_friction;
2997 else if (!sid->loop_v && (sid->content_info.h - sid->h + miny) < *y)
2998 *y += (sid->content_info.h - sid->h + miny - *y) *
2999 _elm_config->thumbscroll_border_friction;
3003 _elm_scroll_hold_enterer(void *data)
3005 Elm_Scrollable_Smart_Interface_Data *sid = data;
3006 Evas_Coord ox = 0, oy = 0, fx = 0, fy = 0;
3009 sid->down.hold_enterer = NULL;
3011 fx = sid->down.hold_x;
3012 fy = sid->down.hold_y;
3014 if ((_elm_config->scroll_smooth_amount > 0.0) &&
3015 (_elm_config->scroll_smooth_time_window > 0.0))
3018 Evas_Coord basex = 0, basey = 0, x, y;
3019 double dt, tdiff, tnow, twin, ttot;
3027 tdiff = sid->down.hist.est_timestamp_diff;
3028 tnow = ecore_loop_time_get();
3029 twin = _elm_config->scroll_smooth_time_window;
3030 for (i = 0; i < 60; i++)
3032 if ((sid->down.history[i].timestamp - tdiff) > tnow)
3034 if ((sid->down.history[i].timestamp >
3035 sid->down.dragged_began_timestamp) || (count == 0))
3037 x = sid->down.history[i].x;
3038 y = sid->down.history[i].y;
3039 _elm_scroll_down_coord_eval(sid, &x, &y);
3045 dt = (tnow + tdiff) - sid->down.history[i].timestamp;
3046 if ((dt > twin) && (count > 0)) break;
3047 if ((dt > 0.0) && (count == 0))
3049 pos[count].x = x - basex;
3050 pos[count].y = y - basey;
3054 pos[count].x = x - basex;
3055 pos[count].y = y - basey;
3065 ttot = pos[count - 1].t;
3066 for (i = 0; i < count; i++)
3072 if (i < (count - 1))
3073 wt = (ttot - pos[i].t) * (pos[i + 1].t - pos[i].t);
3079 xx += ((double)(pos[i].x)) * wt;
3080 yy += ((double)(pos[i].y)) * wt;
3085 xx = basex + (xx / tot);
3086 yy = basey + (yy / tot);
3088 (_elm_config->scroll_smooth_amount * xx) +
3089 ((1.0 - _elm_config->scroll_smooth_amount) * fx);
3091 (_elm_config->scroll_smooth_amount * yy) +
3092 ((1.0 - _elm_config->scroll_smooth_amount) * fy);
3096 // printf("%1.5f %i %i\n",
3097 // ecore_loop_time_get() - sid->down.dragged_began_timestamp,
3100 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&ox, &oy));
3101 if (sid->down.dir_x)
3104 (!elm_widget_drag_child_locked_x_get(sid->obj)))
3107 if (sid->down.dir_y)
3110 (!elm_widget_drag_child_locked_y_get(sid->obj)))
3115 if (_elm_scroll_smooth_debug)
3116 _elm_scroll_smooth_debug_movetime_add(ox, oy);
3119 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(ox, oy, EINA_TRUE));
3125 _elm_scroll_hold_animator(void *data)
3127 Elm_Scrollable_Smart_Interface_Data *sid = data;
3129 ecore_idle_enterer_del(sid->down.hold_enterer);
3130 sid->down.hold_enterer =
3131 ecore_idle_enterer_before_add(_elm_scroll_hold_enterer, sid);
3132 return ECORE_CALLBACK_RENEW;
3136 _elm_scroll_on_hold_animator(void *data)
3140 Evas_Coord x, y, ox = 0, oy = 0;
3141 Elm_Scrollable_Smart_Interface_Data *sid;
3144 t = ecore_loop_time_get();
3145 if (sid->down.onhold_tlast > 0.0)
3147 td = t - sid->down.onhold_tlast;
3148 vx = sid->down.onhold_vx * td *
3149 (double)_elm_config->thumbscroll_hold_threshold * 2.0;
3150 vy = sid->down.onhold_vy * td *
3151 (double)_elm_config->thumbscroll_hold_threshold * 2.0;
3152 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&ox, &oy));
3156 if (sid->down.dir_x)
3159 (!elm_widget_drag_child_locked_x_get(sid->obj)))
3161 sid->down.onhold_vxe += vx;
3162 x = ox + (int)sid->down.onhold_vxe;
3163 sid->down.onhold_vxe -= (int)sid->down.onhold_vxe;
3167 if (sid->down.dir_y)
3170 (!elm_widget_drag_child_locked_y_get(sid->obj)))
3172 sid->down.onhold_vye += vy;
3173 y = oy + (int)sid->down.onhold_vye;
3174 sid->down.onhold_vye -= (int)sid->down.onhold_vye;
3178 eo_do(sid->obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
3180 sid->down.onhold_tlast = t;
3182 return ECORE_CALLBACK_RENEW;
3186 _elm_scroll_mouse_move_event_cb(void *data,
3188 Evas_Object *obj EINA_UNUSED,
3191 Elm_Scrollable_Smart_Interface_Data *sid = data;
3192 Evas_Event_Mouse_Move *ev;
3193 Evas_Coord x = 0, y = 0;
3195 if (!sid->pan_obj) return;
3197 if ((sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL) &&
3198 (sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
3202 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
3203 sid->down.hold_parent = EINA_TRUE;
3204 evas_post_event_callback_push(e, _elm_scroll_post_event_move, sid);
3206 // FIXME: respect elm_widget_scroll_hold_get of parent container
3207 if (!_elm_config->thumbscroll_enable)
3210 if (!sid->down.now) return;
3212 // TIZEN_ONLY(20160624): Overscroll effect
3213 edje_object_signal_emit(sid->edje_obj, "elm,state,mouse,move", "elm");
3215 if ((sid->scrollto.x.animator) && (!sid->hold) && (!sid->freeze) &&
3216 !(sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
3219 ELM_SAFE_FREE(sid->scrollto.x.animator, ecore_animator_del);
3220 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, NULL));
3222 sid->down.x = sid->down.history[0].x;
3225 if ((sid->scrollto.y.animator) && (!sid->hold) && (!sid->freeze) &&
3226 !(sid->block & ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL))
3229 ELM_SAFE_FREE(sid->scrollto.y.animator, ecore_animator_del);
3230 eo_do(sid->pan_obj, elm_obj_pan_pos_get(NULL, &py));
3232 sid->down.y = sid->down.history[0].y;
3236 DBG("::: %i %i\n", ev->cur.canvas.x, ev->cur.canvas.y);
3238 memmove(&(sid->down.history[1]), &(sid->down.history[0]),
3239 sizeof(sid->down.history[0]) * (60 - 1));
3241 sid->down.history[0].timestamp = ev->timestamp / 1000.0;
3242 sid->down.history[0].localtimestamp = ecore_loop_time_get();
3244 sid->down.history[0].timestamp = ecore_loop_time_get();
3246 sid->down.history[0].x = ev->cur.canvas.x;
3247 sid->down.history[0].y = ev->cur.canvas.y;
3249 if (!sid->down.dragged_began)
3251 x = ev->cur.canvas.x - sid->down.x;
3252 y = ev->cur.canvas.y - sid->down.y;
3254 sid->down.hdir = -1;
3255 sid->down.vdir = -1;
3257 if (x > 0) sid->down.hdir = LEFT;
3259 sid->down.hdir = RIGHT;
3260 if (y > 0) sid->down.vdir = UP;
3262 sid->down.vdir = DOWN;
3267 if (sid->one_direction_at_a_time)
3269 if (((x * x) + (y * y)) >
3270 (_elm_config->thumbscroll_threshold *
3271 _elm_config->thumbscroll_threshold))
3273 if (sid->one_direction_at_a_time ==
3274 ELM_SCROLLER_SINGLE_DIRECTION_SOFT)
3280 ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
3282 sid->down.dir_x = EINA_TRUE;
3284 sid->down.dir_y = EINA_FALSE;
3289 sid->down.dir_x = EINA_FALSE;
3291 ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL))
3293 sid->down.dir_y = EINA_TRUE;
3300 ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
3302 sid->down.dir_x = EINA_TRUE;
3305 ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL))
3307 sid->down.dir_y = EINA_TRUE;
3311 else if (sid->one_direction_at_a_time ==
3312 ELM_SCROLLER_SINGLE_DIRECTION_HARD)
3317 ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
3319 sid->down.dir_x = EINA_TRUE;
3321 sid->down.dir_y = EINA_FALSE;
3325 sid->down.dir_x = EINA_FALSE;
3327 ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL))
3329 sid->down.dir_y = EINA_TRUE;
3338 ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL))
3340 sid->down.dir_x = EINA_TRUE;
3343 ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL))
3345 sid->down.dir_y = EINA_TRUE;
3349 if ((!sid->hold) && (!sid->freeze))
3351 if ((sid->down.dragged) ||
3352 (((x * x) + (y * y)) >
3353 (_elm_config->thumbscroll_threshold *
3354 _elm_config->thumbscroll_threshold)))
3356 if (!sid->down.dragged_began &&
3357 _elm_config->scroll_smooth_start_enable)
3359 sid->down.x = ev->cur.canvas.x;
3360 sid->down.y = ev->cur.canvas.y;
3362 sid->down.dragged_began_timestamp = ev->timestamp / 1000.0;
3364 sid->down.dragged_began_timestamp = ecore_loop_time_get();
3368 if (!sid->down.dragged)
3370 sid->down.want_dragged = EINA_TRUE;
3372 if ((((_elm_scroll_can_scroll(sid, LEFT) || _elm_scroll_can_scroll(sid, RIGHT)) && sid->down.dir_x) ||
3373 ((_elm_scroll_can_scroll(sid, UP) || _elm_scroll_can_scroll(sid, DOWN)) && sid->down.dir_y)) &&
3374 !sid->down.dragged_began)
3376 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3377 sid->down.dragged_began = EINA_TRUE;
3379 else if (sid->down.dragged_began)
3381 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3383 if (sid->down.dir_x)
3384 x = sid->down.sx - (ev->cur.canvas.x - sid->down.x);
3387 if (sid->down.dir_y)
3388 y = sid->down.sy - (ev->cur.canvas.y - sid->down.y);
3391 if (sid->down.want_reset)
3393 sid->down.x = ev->cur.canvas.x;
3394 sid->down.y = ev->cur.canvas.y;
3395 sid->down.want_reset = EINA_FALSE;
3397 if ((sid->down.dir_x) || (sid->down.dir_y))
3399 if (!sid->down.locked)
3401 sid->down.locked_x = x;
3402 sid->down.locked_y = y;
3403 sid->down.locked = EINA_TRUE;
3405 if (!((sid->down.dir_x) && (sid->down.dir_y)))
3407 if (sid->down.dir_x) y = sid->down.locked_y;
3408 else x = sid->down.locked_x;
3412 Evas_Coord minx = 0, miny = 0, mx, my;
3414 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
3415 eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
3416 if (!sid->loop_v && y < miny)
3418 _elm_config->thumbscroll_border_friction;
3419 else if (!sid->loop_v && my <= 0)
3420 y += (sid->down.sy - y) *
3421 _elm_config->thumbscroll_border_friction;
3422 else if (!sid->loop_v && (my + miny) < y)
3423 y += (my + miny - y) *
3424 _elm_config->thumbscroll_border_friction;
3425 if (!sid->loop_h && x < minx)
3427 _elm_config->thumbscroll_border_friction;
3428 else if (!sid->loop_h && mx <= 0)
3429 x += (sid->down.sx - x) *
3430 _elm_config->thumbscroll_border_friction;
3431 else if (!sid->loop_h && (mx + minx) < x)
3432 x += (mx + minx - x) *
3433 _elm_config->thumbscroll_border_friction;
3436 sid->down.hold_x = x;
3437 sid->down.hold_y = y;
3438 if (!sid->down.hold_animator)
3439 sid->down.hold_animator =
3440 ecore_animator_add(_elm_scroll_hold_animator, sid);
3444 if (sid->down.dragged_began)
3446 if ((_elm_scroll_can_scroll(sid, sid->down.hdir) && sid->down.dir_x) ||
3447 (_elm_scroll_can_scroll(sid, sid->down.vdir) && sid->down.dir_y))
3449 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
3451 if (!sid->down.hold)
3453 sid->down.hold = EINA_TRUE;
3454 evas_event_feed_hold
3455 (e, 1, ev->timestamp, ev->data);
3460 else if (!sid->freeze)
3462 double vx = 0.0, vy = 0.0;
3464 x = ev->cur.canvas.x - sid->x;
3465 y = ev->cur.canvas.y - sid->y;
3466 if (x < _elm_config->thumbscroll_hold_threshold)
3468 if (_elm_config->thumbscroll_hold_threshold > 0.0)
3469 vx = -(double)(_elm_config->thumbscroll_hold_threshold - x)
3470 / _elm_config->thumbscroll_hold_threshold;
3474 else if (x > (sid->w - _elm_config->thumbscroll_hold_threshold))
3476 if (_elm_config->thumbscroll_hold_threshold > 0.0)
3477 vx = (double)(_elm_config->thumbscroll_hold_threshold -
3479 _elm_config->thumbscroll_hold_threshold;
3483 if (y < _elm_config->thumbscroll_hold_threshold)
3485 if (_elm_config->thumbscroll_hold_threshold > 0.0)
3486 vy = -(double)(_elm_config->thumbscroll_hold_threshold - y)
3487 / _elm_config->thumbscroll_hold_threshold;
3491 else if (y > (sid->h - _elm_config->thumbscroll_hold_threshold))
3493 if (_elm_config->thumbscroll_hold_threshold > 0.0)
3494 vy = (double)(_elm_config->thumbscroll_hold_threshold -
3496 _elm_config->thumbscroll_hold_threshold;
3500 if ((vx != 0.0) || (vy != 0.0))
3502 sid->down.onhold_vx = vx;
3503 sid->down.onhold_vy = vy;
3504 if (!sid->down.onhold_animator)
3506 sid->down.onhold_vxe = 0.0;
3507 sid->down.onhold_vye = 0.0;
3508 sid->down.onhold_tlast = 0.0;
3509 sid->down.onhold_animator = ecore_animator_add
3510 (_elm_scroll_on_hold_animator, sid);
3515 if (sid->down.onhold_animator)
3517 ELM_SAFE_FREE(sid->down.onhold_animator, ecore_animator_del);
3518 if (sid->content_info.resized)
3519 _elm_scroll_wanted_region_set(sid->obj);
3526 _elm_scroll_page_adjust(Elm_Scrollable_Smart_Interface_Data *sid)
3528 Evas_Coord x, y, w, h;
3530 if (!_paging_is_enabled(sid)) return;
3532 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
3533 (NULL, NULL, &w, &h));
3535 x = _elm_scroll_page_x_get(sid, 0, EINA_TRUE);
3536 y = _elm_scroll_page_y_get(sid, 0, EINA_TRUE);
3538 eo_do(sid->obj, elm_interface_scrollable_content_region_set(x, y, w, h));
3542 _elm_scroll_reconfigure(Elm_Scrollable_Smart_Interface_Data *sid)
3544 _elm_scroll_scroll_bar_size_adjust(sid);
3545 _elm_scroll_page_adjust(sid);
3549 _on_edje_move(void *data,
3550 Evas *e EINA_UNUSED,
3551 Evas_Object *edje_obj,
3552 void *event_info EINA_UNUSED)
3554 Elm_Scrollable_Smart_Interface_Data *sid = data;
3557 evas_object_geometry_get(edje_obj, &x, &y, NULL, NULL);
3562 _elm_scroll_reconfigure(sid);
3566 _on_edje_resize(void *data,
3568 Evas_Object *edje_obj,
3569 void *event_info EINA_UNUSED)
3571 Elm_Scrollable_Smart_Interface_Data *sid = data;
3574 Eina_Bool reconf_ok = EINA_TRUE;
3576 evas_object_geometry_get(edje_obj, NULL, NULL, &w, &h);
3581 current_calc = evas_smart_objects_calculate_count_get(e);
3582 if (current_calc == sid->current_calc)
3585 //TIZEN_ONLY(20160524): support for ctxpopup 'more/default' style
3586 //if (sid->size_count > 3) reconf_ok = EINA_FALSE;
3587 if (sid->size_count > 4) reconf_ok = EINA_FALSE;
3592 sid->current_calc = current_calc;
3593 sid->size_count = 0;
3595 if (reconf_ok) _elm_scroll_reconfigure(sid);
3596 _elm_scroll_wanted_region_set(sid->obj);
3600 _scroll_edje_object_attach(Evas_Object *obj)
3602 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3604 evas_object_event_callback_add
3605 (sid->edje_obj, EVAS_CALLBACK_RESIZE, _on_edje_resize, sid);
3606 evas_object_event_callback_add
3607 (sid->edje_obj, EVAS_CALLBACK_MOVE, _on_edje_move, sid);
3609 edje_object_signal_callback_add
3610 (sid->edje_obj, "reload", "elm", _elm_scroll_reload_cb, sid);
3611 edje_object_signal_callback_add
3612 (sid->edje_obj, "drag", "elm.dragable.vbar", _elm_scroll_vbar_drag_cb,
3614 edje_object_signal_callback_add
3615 (sid->edje_obj, "drag,set", "elm.dragable.vbar",
3616 _elm_scroll_edje_drag_v_cb, sid);
3617 edje_object_signal_callback_add
3618 (sid->edje_obj, "drag,start", "elm.dragable.vbar",
3619 _elm_scroll_edje_drag_v_start_cb, sid);
3620 edje_object_signal_callback_add
3621 (sid->edje_obj, "drag,stop", "elm.dragable.vbar",
3622 _elm_scroll_edje_drag_v_stop_cb, sid);
3623 edje_object_signal_callback_add
3624 (sid->edje_obj, "drag,step", "elm.dragable.vbar",
3625 _elm_scroll_edje_drag_v_cb, sid);
3626 edje_object_signal_callback_add
3627 (sid->edje_obj, "drag,page", "elm.dragable.vbar",
3628 _elm_scroll_edje_drag_v_cb, sid);
3629 edje_object_signal_callback_add
3630 (sid->edje_obj, "elm,vbar,press", "elm",
3631 _elm_scroll_vbar_press_cb, sid);
3632 edje_object_signal_callback_add
3633 (sid->edje_obj, "elm,vbar,unpress", "elm",
3634 _elm_scroll_vbar_unpress_cb, sid);
3635 edje_object_signal_callback_add
3636 (sid->edje_obj, "drag", "elm.dragable.hbar", _elm_scroll_hbar_drag_cb,
3638 edje_object_signal_callback_add
3639 (sid->edje_obj, "drag,set", "elm.dragable.hbar",
3640 _elm_scroll_edje_drag_h_cb, sid);
3641 edje_object_signal_callback_add
3642 (sid->edje_obj, "drag,start", "elm.dragable.hbar",
3643 _elm_scroll_edje_drag_h_start_cb, sid);
3644 edje_object_signal_callback_add
3645 (sid->edje_obj, "drag,stop", "elm.dragable.hbar",
3646 _elm_scroll_edje_drag_h_stop_cb, sid);
3647 edje_object_signal_callback_add
3648 (sid->edje_obj, "drag,step", "elm.dragable.hbar",
3649 _elm_scroll_edje_drag_h_cb, sid);
3650 edje_object_signal_callback_add
3651 (sid->edje_obj, "drag,page", "elm.dragable.hbar",
3652 _elm_scroll_edje_drag_h_cb, sid);
3653 edje_object_signal_callback_add
3654 (sid->edje_obj, "elm,hbar,press", "elm",
3655 _elm_scroll_hbar_press_cb, sid);
3656 edje_object_signal_callback_add
3657 (sid->edje_obj, "elm,hbar,unpress", "elm",
3658 _elm_scroll_hbar_unpress_cb, sid);
3662 _scroll_event_object_attach(Evas_Object *obj)
3664 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3666 evas_object_event_callback_add
3667 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL, _elm_scroll_wheel_event_cb,
3669 evas_object_event_callback_add
3670 (sid->event_rect, EVAS_CALLBACK_MOUSE_DOWN,
3671 _elm_scroll_mouse_down_event_cb, sid);
3672 evas_object_event_callback_add
3673 (sid->event_rect, EVAS_CALLBACK_MOUSE_UP,
3674 _elm_scroll_mouse_up_event_cb, sid);
3675 evas_object_event_callback_add
3676 (sid->event_rect, EVAS_CALLBACK_MOUSE_MOVE,
3677 _elm_scroll_mouse_move_event_cb, sid);
3681 _scroll_edje_object_detach(Evas_Object *obj)
3683 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3685 evas_object_event_callback_del_full
3686 (sid->edje_obj, EVAS_CALLBACK_RESIZE, _on_edje_resize, sid);
3687 evas_object_event_callback_del_full
3688 (sid->edje_obj, EVAS_CALLBACK_MOVE, _on_edje_move, sid);
3690 edje_object_signal_callback_del_full
3691 (sid->edje_obj, "drag", "elm.dragable.vbar", _elm_scroll_vbar_drag_cb,
3693 edje_object_signal_callback_del_full
3694 (sid->edje_obj, "drag,set", "elm.dragable.vbar",
3695 _elm_scroll_edje_drag_v_cb, sid);
3696 edje_object_signal_callback_del_full
3697 (sid->edje_obj, "drag,start", "elm.dragable.vbar",
3698 _elm_scroll_edje_drag_v_start_cb, sid);
3699 edje_object_signal_callback_del_full
3700 (sid->edje_obj, "drag,stop", "elm.dragable.vbar",
3701 _elm_scroll_edje_drag_v_stop_cb, sid);
3702 edje_object_signal_callback_del_full
3703 (sid->edje_obj, "drag,step", "elm.dragable.vbar",
3704 _elm_scroll_edje_drag_v_cb, sid);
3705 edje_object_signal_callback_del_full
3706 (sid->edje_obj, "drag,page", "elm.dragable.vbar",
3707 _elm_scroll_edje_drag_v_cb, sid);
3708 edje_object_signal_callback_del_full
3709 (sid->edje_obj, "elm,vbar,press", "elm",
3710 _elm_scroll_vbar_press_cb, sid);
3711 edje_object_signal_callback_del_full
3712 (sid->edje_obj, "elm,vbar,unpress", "elm",
3713 _elm_scroll_vbar_unpress_cb, sid);
3714 edje_object_signal_callback_del_full
3715 (sid->edje_obj, "drag", "elm.dragable.hbar", _elm_scroll_hbar_drag_cb,
3717 edje_object_signal_callback_del_full
3718 (sid->edje_obj, "drag,set", "elm.dragable.hbar",
3719 _elm_scroll_edje_drag_h_cb, sid);
3720 edje_object_signal_callback_del_full
3721 (sid->edje_obj, "drag,start", "elm.dragable.hbar",
3722 _elm_scroll_edje_drag_h_start_cb, sid);
3723 edje_object_signal_callback_del_full
3724 (sid->edje_obj, "drag,stop", "elm.dragable.hbar",
3725 _elm_scroll_edje_drag_h_stop_cb, sid);
3726 edje_object_signal_callback_del_full
3727 (sid->edje_obj, "drag,step", "elm.dragable.hbar",
3728 _elm_scroll_edje_drag_h_cb, sid);
3729 edje_object_signal_callback_del_full
3730 (sid->edje_obj, "drag,page", "elm.dragable.hbar",
3731 _elm_scroll_edje_drag_h_cb, sid);
3732 edje_object_signal_callback_del_full
3733 (sid->edje_obj, "elm,hbar,press", "elm",
3734 _elm_scroll_hbar_press_cb, sid);
3735 edje_object_signal_callback_del_full
3736 (sid->edje_obj, "elm,hbar,unpress", "elm",
3737 _elm_scroll_hbar_unpress_cb, sid);
3741 _scroll_event_object_detach(Evas_Object *obj)
3743 ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
3745 evas_object_event_callback_del_full
3746 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL, _elm_scroll_wheel_event_cb,
3748 evas_object_event_callback_del_full
3749 (sid->event_rect, EVAS_CALLBACK_MOUSE_DOWN,
3750 _elm_scroll_mouse_down_event_cb, sid);
3751 evas_object_event_callback_del_full
3752 (sid->event_rect, EVAS_CALLBACK_MOUSE_UP,
3753 _elm_scroll_mouse_up_event_cb, sid);
3754 evas_object_event_callback_del_full
3755 (sid->event_rect, EVAS_CALLBACK_MOUSE_MOVE,
3756 _elm_scroll_mouse_move_event_cb, sid);
3760 _elm_interface_scrollable_objects_set(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Object *edje_object, Evas_Object *hit_rectangle)
3764 if (!edje_object || !hit_rectangle) return;
3767 _scroll_edje_object_detach(obj);
3769 sid->edje_obj = edje_object;
3771 if (sid->event_rect)
3772 _scroll_event_object_detach(obj);
3774 sid->event_rect = hit_rectangle;
3775 evas_object_repeat_events_set(hit_rectangle, EINA_TRUE);
3777 _scroll_edje_object_attach(obj);
3778 _scroll_event_object_attach(obj);
3781 elm_coords_finger_size_adjust(1, &mw, 1, &mh);
3782 if (edje_object_part_exists(sid->edje_obj, "elm.scrollbar.base"))
3786 base = edje_object_part_swallow_get
3787 (sid->edje_obj, "elm.scrollbar.base");
3790 base = evas_object_rectangle_add
3791 (evas_object_evas_get(sid->edje_obj));
3792 evas_object_color_set(base, 0, 0, 0, 0);
3793 edje_object_part_swallow
3794 (sid->edje_obj, "elm.scrollbar.base", base);
3796 if (!_elm_config->thumbscroll_enable)
3797 evas_object_size_hint_min_set(base, mw, mh);
3800 _elm_scroll_scroll_bar_visibility_adjust(sid);
3804 _elm_scroll_scroll_bar_reset(Elm_Scrollable_Smart_Interface_Data *sid)
3806 Evas_Coord px = 0, py = 0, minx = 0, miny = 0;
3808 if (!sid->edje_obj) return;
3810 edje_object_part_drag_value_set
3811 (sid->edje_obj, "elm.dragable.vbar", 0.0, 0.0);
3812 edje_object_part_drag_value_set
3813 (sid->edje_obj, "elm.dragable.hbar", 0.0, 0.0);
3814 if ((!sid->content) && (!sid->extern_pan))
3816 edje_object_part_drag_size_set
3817 (sid->edje_obj, "elm.dragable.vbar", 1.0, 1.0);
3818 edje_object_part_drag_size_set
3819 (sid->edje_obj, "elm.dragable.hbar", 1.0, 1.0);
3823 eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
3824 eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
3825 eo_do(sid->pan_obj, elm_obj_pan_pos_set(minx, miny));
3827 if ((px != minx) || (py != miny))
3828 edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
3829 _elm_direction_arrows_eval(sid);
3833 _elm_scroll_pan_resized_cb(void *data,
3834 Evas *e EINA_UNUSED,
3835 Evas_Object *obj EINA_UNUSED,
3836 void *event_info EINA_UNUSED)
3838 Evas_Coord w = 0, h = 0;
3839 Elm_Scrollable_Smart_Interface_Data *sid = data;
3841 if (sid->cb_func.content_viewport_resize)
3843 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
3844 (NULL, NULL, &w, &h));
3845 sid->cb_func.content_viewport_resize(sid->obj, w, h);
3849 /* even external pan objects get this */
3851 _elm_scroll_pan_changed_cb(void *data,
3852 Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED,
3853 void *event_info EINA_UNUSED)
3855 Evas_Coord w = 0, h = 0;
3856 Elm_Scrollable_Smart_Interface_Data *sid = data;
3858 if (!sid->pan_obj) return EINA_TRUE;
3860 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&w, &h));
3861 if ((w != sid->content_info.w) || (h != sid->content_info.h))
3863 sid->content_info.w = w;
3864 sid->content_info.h = h;
3865 _elm_scroll_scroll_bar_size_adjust(sid);
3867 evas_object_size_hint_min_set
3868 (sid->edje_obj, sid->content_info.w, sid->content_info.h);
3869 sid->content_info.resized = EINA_TRUE;
3870 _elm_scroll_wanted_region_set(sid->obj);
3877 _elm_scroll_content_del_cb(void *data,
3878 Evas *e EINA_UNUSED,
3879 Evas_Object *obj EINA_UNUSED,
3880 void *event_info EINA_UNUSED)
3882 Elm_Scrollable_Smart_Interface_Data *sid = data;
3884 sid->content = NULL;
3885 _elm_scroll_scroll_bar_size_adjust(sid);
3886 _elm_scroll_scroll_bar_reset(sid);
3890 _elm_interface_scrollable_content_set(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Object *content)
3892 Evas_Coord w = 0, h = 0;
3895 if (!sid->edje_obj) return;
3899 /* if we had content, for sure we had a pan object */
3900 _elm_pan_content_set(sid->pan_obj, NULL);
3901 evas_object_event_callback_del_full
3902 (sid->content, EVAS_CALLBACK_DEL, _elm_scroll_content_del_cb, sid);
3905 sid->content = content;
3906 sid->wx = sid->wy = 0;
3907 /* (-1) means want viewports size */
3908 sid->ww = sid->wh = -1;
3909 if (!content) return;
3913 o = _elm_pan_add(evas_object_evas_get(obj));
3915 eo_do(o, eo_event_callback_add
3916 (ELM_PAN_EVENT_CHANGED, _elm_scroll_pan_changed_cb, sid));
3917 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE,
3918 _elm_scroll_pan_resized_cb, sid);
3919 edje_object_part_swallow(sid->edje_obj, "elm.swallow.content", o);
3922 evas_object_event_callback_add
3923 (content, EVAS_CALLBACK_DEL, _elm_scroll_content_del_cb, sid);
3925 _elm_pan_content_set(sid->pan_obj, content);
3926 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&w, &h));
3927 sid->content_info.w = w;
3928 sid->content_info.h = h;
3930 _elm_scroll_scroll_bar_size_adjust(sid);
3931 _elm_scroll_scroll_bar_reset(sid);
3935 _elm_interface_scrollable_extern_pan_set(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Object *pan)
3937 if (!sid->edje_obj) return;
3939 eo_do(obj, elm_interface_scrollable_content_set(NULL));
3943 eo_do(sid->pan_obj, eo_event_callback_del(
3944 ELM_PAN_EVENT_CHANGED, _elm_scroll_pan_changed_cb, sid));
3945 evas_object_event_callback_del(sid->pan_obj, EVAS_CALLBACK_RESIZE,
3946 _elm_scroll_pan_resized_cb);
3949 if (sid->extern_pan)
3953 /* not owned by scroller, just leave (was external already) */
3954 edje_object_part_unswallow(sid->edje_obj, sid->pan_obj);
3955 sid->pan_obj = NULL;
3960 ELM_SAFE_FREE(sid->pan_obj, evas_object_del);
3964 sid->extern_pan = EINA_FALSE;
3970 sid->extern_pan = EINA_TRUE;
3971 eo_do(sid->pan_obj, eo_event_callback_add
3972 (ELM_PAN_EVENT_CHANGED, _elm_scroll_pan_changed_cb, sid));
3973 evas_object_event_callback_add(sid->pan_obj, EVAS_CALLBACK_RESIZE,
3974 _elm_scroll_pan_resized_cb, sid);
3975 edje_object_part_swallow
3976 (sid->edje_obj, "elm.swallow.content", sid->pan_obj);
3980 _elm_interface_scrollable_drag_start_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb drag_start_cb)
3982 sid->cb_func.drag_start = drag_start_cb;
3986 _elm_interface_scrollable_drag_stop_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb drag_stop_cb)
3988 sid->cb_func.drag_stop = drag_stop_cb;
3992 _elm_interface_scrollable_animate_start_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb animate_start_cb)
3994 sid->cb_func.animate_start = animate_start_cb;
3998 _elm_interface_scrollable_animate_stop_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb animate_stop_cb)
4000 sid->cb_func.animate_stop = animate_stop_cb;
4004 _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)
4006 sid->cb_func.page_change = page_change_cb;
4010 _elm_interface_scrollable_scroll_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb scroll_cb)
4012 sid->cb_func.scroll = scroll_cb;
4016 _elm_interface_scrollable_scroll_left_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb scroll_left_cb)
4018 sid->cb_func.scroll_left = scroll_left_cb;
4022 _elm_interface_scrollable_scroll_right_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb scroll_right_cb)
4024 sid->cb_func.scroll_right = scroll_right_cb;
4028 _elm_interface_scrollable_scroll_up_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb scroll_up_cb)
4030 sid->cb_func.scroll_up = scroll_up_cb;
4034 _elm_interface_scrollable_scroll_down_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb scroll_down_cb)
4036 sid->cb_func.scroll_down = scroll_down_cb;
4040 _elm_interface_scrollable_edge_left_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb edje_left_cb)
4042 sid->cb_func.edge_left = edje_left_cb;
4046 _elm_interface_scrollable_edge_right_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb edje_right_cb)
4048 sid->cb_func.edge_right = edje_right_cb;
4052 _elm_interface_scrollable_edge_top_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb edje_top_cb)
4054 sid->cb_func.edge_top = edje_top_cb;
4058 _elm_interface_scrollable_edge_bottom_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb edje_bottom_cb)
4060 sid->cb_func.edge_bottom = edje_bottom_cb;
4064 _elm_interface_scrollable_vbar_drag_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb vbar_drag_cb)
4066 sid->cb_func.vbar_drag = vbar_drag_cb;
4070 _elm_interface_scrollable_vbar_press_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb vbar_press_cb)
4072 sid->cb_func.vbar_press = vbar_press_cb;
4076 _elm_interface_scrollable_vbar_unpress_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb vbar_unpress_cb)
4078 sid->cb_func.vbar_unpress = vbar_unpress_cb;
4082 _elm_interface_scrollable_hbar_drag_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb hbar_drag_cb)
4084 sid->cb_func.hbar_drag = hbar_drag_cb;
4088 _elm_interface_scrollable_hbar_press_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb hbar_press_cb)
4090 sid->cb_func.hbar_press = hbar_press_cb;
4094 _elm_interface_scrollable_hbar_unpress_cb_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Interface_Scrollable_Cb hbar_unpress_cb)
4096 sid->cb_func.hbar_unpress = hbar_unpress_cb;
4100 _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)
4102 sid->cb_func.content_min_limit = min_limit_cb;
4106 _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)
4108 sid->cb_func.content_viewport_resize = viewport_resize_cb;
4111 EOLIAN static Eina_Bool
4112 _elm_interface_scrollable_momentum_animator_disabled_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid)
4114 return sid->momentum_animator_disabled;
4118 _elm_interface_scrollable_momentum_animator_disabled_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool disabled)
4120 sid->momentum_animator_disabled = disabled;
4121 if (sid->momentum_animator_disabled)
4123 if (sid->down.momentum_animator)
4125 ELM_SAFE_FREE(sid->down.momentum_animator, ecore_animator_del);
4126 if (sid->content_info.resized)
4127 _elm_scroll_wanted_region_set(sid->obj);
4132 EOLIAN static Eina_Bool
4133 _elm_interface_scrollable_bounce_animator_disabled_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid)
4135 return sid->bounce_animator_disabled;
4139 _elm_interface_scrollable_bounce_animator_disabled_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool disabled)
4141 sid->bounce_animator_disabled = disabled;
4142 if (sid->bounce_animator_disabled)
4144 ELM_SAFE_FREE(sid->scrollto.x.animator, ecore_animator_del);
4145 ELM_SAFE_FREE(sid->scrollto.y.animator, ecore_animator_del);
4149 EOLIAN static Eina_Bool
4150 _elm_interface_scrollable_wheel_disabled_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid)
4152 return sid->wheel_disabled;
4156 _elm_interface_scrollable_wheel_disabled_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool disabled)
4158 if (!sid->event_rect) return;
4160 if ((!sid->wheel_disabled) && (disabled))
4161 evas_object_event_callback_del_full
4162 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL,
4163 _elm_scroll_wheel_event_cb, sid);
4164 else if ((sid->wheel_disabled) && (!disabled))
4165 evas_object_event_callback_add
4166 (sid->event_rect, EVAS_CALLBACK_MOUSE_WHEEL,
4167 _elm_scroll_wheel_event_cb, sid);
4168 sid->wheel_disabled = disabled;
4172 _elm_interface_scrollable_step_size_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord x, Evas_Coord y)
4179 _elm_scroll_scroll_bar_size_adjust(sid);
4183 _elm_interface_scrollable_step_size_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord *x, Evas_Coord *y)
4185 if (x) *x = sid->step.x;
4186 if (y) *y = sid->step.y;
4190 _elm_interface_scrollable_page_size_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord x, Evas_Coord y)
4195 _elm_scroll_scroll_bar_size_adjust(sid);
4199 _elm_interface_scrollable_page_size_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord *x, Evas_Coord *y)
4201 if (x) *x = sid->page.x;
4202 if (y) *y = sid->page.y;
4206 _elm_interface_scrollable_policy_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Scroller_Policy hbar, Elm_Scroller_Policy vbar)
4208 if (!sid->edje_obj) return;
4210 if ((sid->hbar_flags == hbar) && (sid->vbar_flags == vbar)) return;
4212 sid->hbar_flags = hbar;
4213 sid->vbar_flags = vbar;
4214 _elm_scroll_policy_signal_emit(sid);
4215 if (sid->cb_func.content_min_limit)
4216 sid->cb_func.content_min_limit(sid->obj, sid->min_w, sid->min_h);
4217 _elm_direction_arrows_eval(sid);
4221 _elm_interface_scrollable_policy_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Scroller_Policy *hbar, Elm_Scroller_Policy *vbar)
4223 if (hbar) *hbar = sid->hbar_flags;
4224 if (vbar) *vbar = sid->vbar_flags;
4228 _elm_interface_scrollable_single_direction_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Scroller_Single_Direction single_dir)
4230 sid->one_direction_at_a_time = single_dir;
4233 EOLIAN static Elm_Scroller_Single_Direction
4234 _elm_interface_scrollable_single_direction_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid)
4236 return sid->one_direction_at_a_time;
4240 _elm_interface_scrollable_repeat_events_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool repeat_events)
4242 if (sid->event_rect)
4243 evas_object_repeat_events_set(sid->event_rect, repeat_events);
4246 EOLIAN static Eina_Bool
4247 _elm_interface_scrollable_repeat_events_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid)
4249 if (sid->event_rect)
4250 return evas_object_repeat_events_get(sid->event_rect);
4256 _elm_interface_scrollable_hold_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool hold)
4262 _elm_interface_scrollable_freeze_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool freeze)
4264 sid->freeze = freeze;
4267 if (sid->down.onhold_animator)
4269 ELM_SAFE_FREE(sid->down.onhold_animator, ecore_animator_del);
4270 if (sid->content_info.resized)
4271 _elm_scroll_wanted_region_set(sid->obj);
4275 _elm_scroll_bounce_eval(sid);
4279 _elm_interface_scrollable_page_snap_allow_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool horiz, Eina_Bool vert)
4281 sid->page_snap_horiz = !!horiz;
4282 sid->page_snap_vert = !!vert;
4286 _elm_interface_scrollable_page_snap_allow_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool *horiz, Eina_Bool *vert)
4288 if (horiz) *horiz = sid->page_snap_horiz;
4289 if (vert) *vert = sid->page_snap_vert;
4293 _elm_interface_scrollable_bounce_allow_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool horiz, Eina_Bool vert)
4295 sid->bounce_horiz = !!horiz;
4296 sid->bounce_vert = !!vert;
4300 _elm_interface_scrollable_bounce_allow_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool *horiz, Eina_Bool *vert)
4302 if (horiz) *horiz = sid->bounce_horiz;
4303 if (vert) *vert = sid->bounce_vert;
4307 _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)
4309 sid->pagerel_h = pagerel_h;
4310 sid->pagerel_v = pagerel_v;
4311 sid->pagesize_h = pagesize_h;
4312 sid->pagesize_v = pagesize_v;
4314 _elm_scroll_page_adjust(sid);
4318 _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)
4320 if (pagerel_h) *pagerel_h = sid->pagerel_h;
4321 if (pagerel_v) *pagerel_v = sid->pagerel_v;
4322 if (pagesize_h) *pagesize_h = sid->pagesize_h;
4323 if (pagesize_v) *pagesize_v = sid->pagesize_v;
4327 _elm_interface_scrollable_page_relative_set(Eo *obj, Elm_Scrollable_Smart_Interface_Data *_pd EINA_UNUSED, double h_pagerel, double v_pagerel)
4329 Evas_Coord pagesize_h, pagesize_v;
4331 eo_do(obj, elm_interface_scrollable_paging_get(NULL, NULL, &pagesize_h, &pagesize_v));
4333 eo_do(obj, elm_interface_scrollable_paging_set(h_pagerel, v_pagerel, pagesize_h, pagesize_v));
4337 _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)
4339 sid->page_limit_h = page_limit_h;
4340 sid->page_limit_v = page_limit_v;
4344 _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)
4346 if (page_limit_h) *page_limit_h = sid->page_limit_h;
4347 if (page_limit_v) *page_limit_v = sid->page_limit_v;
4351 _elm_interface_scrollable_current_page_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, int *pagenumber_h, int *pagenumber_v)
4355 eo_do(sid->obj, elm_interface_scrollable_content_pos_get(&x, &y));
4358 if (sid->pagesize_h > 0)
4360 double result = (double)x / (double)sid->pagesize_h;
4361 double rest = result - (x / sid->pagesize_h);
4363 *pagenumber_h = result + 1;
4365 *pagenumber_h = result;
4372 if (sid->pagesize_v > 0)
4374 double result = (double)y / (double)sid->pagesize_v;
4375 double rest = result - (y / sid->pagesize_v);
4377 *pagenumber_v = result + 1;
4379 *pagenumber_v = result;
4387 _elm_interface_scrollable_last_page_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, int *pagenumber_h, int *pagenumber_v)
4391 if (!sid->pan_obj) return;
4393 eo_do(sid->pan_obj, elm_obj_pan_content_size_get(&cw, &ch));
4396 if ((sid->pagesize_h > 0) && (cw > sid->pagesize_h))
4397 *pagenumber_h = cw / sid->pagesize_h - 1;
4403 if ((sid->pagesize_v > 0) && (ch > sid->pagesize_v))
4404 *pagenumber_v = ch / sid->pagesize_v - 1;
4411 _elm_interface_scrollable_page_show(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid, int pagenumber_h, int pagenumber_v)
4413 Evas_Coord w = 0, h = 0;
4417 sid->current_page.x = _elm_scroll_page_x_get(sid, 0, EINA_FALSE);
4418 sid->current_page.y = _elm_scroll_page_y_get(sid, 0, EINA_FALSE);
4420 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
4421 (NULL, NULL, &w, &h));
4422 x = sid->pagesize_h * pagenumber_h;
4423 y = sid->pagesize_v * pagenumber_v;
4425 sid->wx = (sid->is_mirrored ? _elm_scroll_x_mirrored_get(sid->obj, x) : x);
4430 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
4431 eo_do(obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
4433 if ((sid->current_page.x != x) || (sid->current_page.y != y))
4435 if (sid->cb_func.page_change)
4436 sid->cb_func.page_change(sid->obj, NULL);
4441 _elm_interface_scrollable_page_bring_in(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid, int pagenumber_h, int pagenumber_v)
4443 Evas_Coord w = 0, h = 0;
4447 eo_do(sid->obj, elm_interface_scrollable_content_viewport_geometry_get
4448 (NULL, NULL, &w, &h));
4449 x = sid->pagesize_h * pagenumber_h;
4450 y = sid->pagesize_v * pagenumber_v;
4451 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
4453 _elm_scroll_scroll_to_x(sid, _elm_config->bring_in_scroll_friction, x);
4454 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, y);
4459 _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)
4461 if (_elm_scroll_content_region_show_internal(obj, &x, &y, w, h))
4463 _elm_scroll_scroll_to_x(sid, _elm_config->bring_in_scroll_friction, x);
4464 _elm_scroll_scroll_to_y(sid, _elm_config->bring_in_scroll_friction, y);
4469 _elm_interface_scrollable_gravity_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, double x, double y)
4471 if (!sid->pan_obj) return;
4473 eo_do(sid->pan_obj, elm_obj_pan_gravity_set(x, y));
4477 _elm_interface_scrollable_gravity_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, double *x, double *y)
4479 if (!sid->pan_obj) return;
4481 eo_do(sid->pan_obj, elm_obj_pan_gravity_get(x, y));
4485 _elm_interface_scrollable_movement_block_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Elm_Scroller_Movement_Block block)
4490 EOLIAN static Elm_Scroller_Movement_Block
4491 _elm_interface_scrollable_movement_block_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid)
4497 _elm_interface_scrollable_loop_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool loop_h, Eina_Bool loop_v)
4499 if (sid->loop_h == loop_h && sid->loop_v == loop_v) return;
4501 sid->loop_h = loop_h;
4502 sid->loop_v = loop_v;
4505 edje_object_signal_emit(sid->edje_obj, "elm,loop_x,set", "elm");
4507 edje_object_signal_emit(sid->edje_obj, "elm,loop_x,unset", "elm");
4510 edje_object_signal_emit(sid->edje_obj, "elm,loop_y,set", "elm");
4512 edje_object_signal_emit(sid->edje_obj, "elm,loop_y,unset", "elm");
4516 _elm_interface_scrollable_loop_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool *loop_h, Eina_Bool *loop_v)
4518 *loop_h = sid->loop_h;
4519 *loop_v = sid->loop_v;
4523 _elm_interface_scrollable_evas_object_smart_add(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid)
4525 memset(sid, 0, sizeof(*sid));
4537 sid->page_limit_h = 9999;
4538 sid->page_limit_v = 9999;
4539 sid->hbar_flags = ELM_SCROLLER_POLICY_AUTO;
4540 sid->vbar_flags = ELM_SCROLLER_POLICY_AUTO;
4541 sid->hbar_visible = EINA_TRUE;
4542 sid->vbar_visible = EINA_TRUE;
4543 sid->loop_h = EINA_FALSE;
4544 sid->loop_v = EINA_FALSE;
4546 sid->bounce_horiz = EINA_TRUE;
4547 sid->bounce_vert = EINA_TRUE;
4549 sid->one_direction_at_a_time = ELM_SCROLLER_SINGLE_DIRECTION_SOFT;
4550 sid->momentum_animator_disabled = EINA_FALSE;
4551 sid->bounce_animator_disabled = EINA_FALSE;
4552 sid->block = ELM_SCROLLER_MOVEMENT_NO_BLOCK;
4554 _elm_scroll_scroll_bar_reset(sid);
4556 eo_do_super(obj, MY_SCROLLABLE_INTERFACE, evas_obj_smart_add());
4560 _elm_interface_scrollable_evas_object_smart_del(Eo *obj, Elm_Scrollable_Smart_Interface_Data *sid)
4563 eo_do_super(obj, MY_SCROLLABLE_INTERFACE, evas_obj_smart_del());
4565 eo_do(obj, elm_interface_scrollable_content_set(NULL));
4566 if (!sid->extern_pan) evas_object_del(sid->pan_obj);
4568 ecore_idle_enterer_del(sid->down.hold_enterer);
4569 ecore_animator_del(sid->down.hold_animator);
4570 ecore_animator_del(sid->down.onhold_animator);
4571 ecore_animator_del(sid->down.momentum_animator);
4572 ecore_animator_del(sid->down.bounce_x_animator);
4573 ecore_animator_del(sid->down.bounce_y_animator);
4574 ecore_animator_del(sid->scrollto.x.animator);
4575 ecore_animator_del(sid->scrollto.y.animator);
4579 _elm_interface_scrollable_class_constructor(Eo_Class *klass)
4581 evas_smart_legacy_type_register(MY_SCROLLABLE_INTERFACE_NAME_LEGACY, klass);
4584 #include "elm_interface_scrollable.eo.c"
4585 #include "elm_pan.eo.c"