X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Flib%2Fels_scroller.c;h=484efdb13bf0e5628302e11d249ced317ba1862c;hb=02416fdf5874983611580cfaa34f18d045e92c8d;hp=95b2dea38375dc3806aa8b5b37a2a64aa36e6f86;hpb=13610f117cd428dcb7e83dd9fbbffd5922e21334;p=framework%2Fuifw%2Felementary.git diff --git a/src/lib/els_scroller.c b/src/lib/els_scroller.c index 95b2dea..484efdb 100644 --- a/src/lib/els_scroller.c +++ b/src/lib/els_scroller.c @@ -21,23 +21,27 @@ struct _Smart_Data Evas_Object *event_obj; Evas_Object *widget; - + Elm_Smart_Scroller_Policy hbar_flags, vbar_flags; struct { - Evas_Coord x, y; - Evas_Coord sx, sy; - Evas_Coord dx, dy; - Evas_Coord pdx, pdy; - Evas_Coord bx, by; - Evas_Coord ax, ay; - Evas_Coord bx0, by0; - Evas_Coord b0x, b0y; - Evas_Coord b2x, b2y; - struct { - Evas_Coord x, y; - double timestamp; - } history[20]; + Evas_Coord x, y; + Evas_Coord sx, sy; + Evas_Coord dx, dy; + Evas_Coord pdx, pdy; + Evas_Coord bx, by; + Evas_Coord ax, ay; + Evas_Coord bx0, by0; + Evas_Coord b0x, b0y; + Evas_Coord b2x, b2y; + struct { + Evas_Coord x, y; + double timestamp, localtimestamp; + } history[60]; + struct { + double tadd, dxsum, dysum; + double est_timestamp_diff; + } hist; double anim_start; double anim_start2; double anim_start3; @@ -103,9 +107,11 @@ struct _Smart_Data unsigned char bouncemey : 1; unsigned char bounce_horiz : 1; unsigned char bounce_vert : 1; - unsigned char momentum_animator_disabled :1; - unsigned char bounce_animator_disabled :1; unsigned char event_propagation :1; + Eina_Bool momentum_animator_disabled :1; + Eina_Bool bounce_animator_disabled :1; + Eina_Bool is_mirrored : 1; + Eina_Bool wheel_disabled : 1; }; /* local subsystem functions */ @@ -154,6 +160,37 @@ elm_smart_scroller_add(Evas *evas) return evas_object_smart_add(evas, _smart); } +static Evas_Coord +_elm_smart_scroller_x_mirrored_get(Evas_Object *obj, Evas_Coord x) +{ + API_ENTRY return x; + + Evas_Coord cw, ch, w, ret; + elm_smart_scroller_child_viewport_size_get(obj, &w, NULL); + sd->pan_func.child_size_get(sd->pan_obj, &cw, &ch); + ret = (cw - (x + w)); + return (ret >= 0) ? ret : 0; +} + +void +elm_smart_scroller_mirrored_set(Evas_Object *obj, Eina_Bool mirrored) +{ + API_ENTRY return; + Evas_Coord wx; + if (sd->is_mirrored == mirrored) + return; + + sd->is_mirrored = mirrored; + edje_object_mirrored_set(sd->edje_obj, mirrored); + + if (sd->is_mirrored) + wx = _elm_smart_scroller_x_mirrored_get(sd->smart_obj, sd->wx); + else + wx = sd->wx; + + elm_smart_scroller_child_pos_set(sd->smart_obj, wx, sd->wy); +} + void elm_smart_scroller_child_set(Evas_Object *obj, Evas_Object *child) { @@ -163,22 +200,23 @@ elm_smart_scroller_child_set(Evas_Object *obj, Evas_Object *child) API_ENTRY return; if (sd->child_obj) { - _elm_smart_pan_child_set(sd->pan_obj, NULL); - evas_object_event_callback_del_full(sd->child_obj, EVAS_CALLBACK_DEL, _smart_child_del_hook, sd); + _elm_smart_pan_child_set(sd->pan_obj, NULL); + evas_object_event_callback_del_full(sd->child_obj, EVAS_CALLBACK_DEL, _smart_child_del_hook, sd); } sd->child_obj = child; - sd->wx = sd->wy = sd->ww = sd->wh = 0; + sd->wx = sd->wy = 0; + /* (-1) means want viewports size */ + sd->ww = sd->wh = -1; if (!child) return; if (!sd->pan_obj) { - o = _elm_smart_pan_add(evas_object_evas_get(obj)); - sd->pan_obj = o; - evas_object_smart_callback_add(o, "changed", _smart_pan_changed_hook, sd); - evas_object_smart_callback_add(o, "pan_changed", _smart_pan_pan_changed_hook, sd); - evas_object_show(o); - edje_object_part_swallow(sd->edje_obj, "elm.swallow.content", o); + o = _elm_smart_pan_add(evas_object_evas_get(obj)); + sd->pan_obj = o; + evas_object_smart_callback_add(o, "changed", _smart_pan_changed_hook, sd); + evas_object_smart_callback_add(o, "pan_changed", _smart_pan_pan_changed_hook, sd); + edje_object_part_swallow(sd->edje_obj, "elm.swallow.content", o); } sd->pan_func.set = _elm_smart_pan_set; @@ -188,7 +226,7 @@ elm_smart_scroller_child_set(Evas_Object *obj, Evas_Object *child) sd->pan_func.child_size_get = _elm_smart_pan_child_size_get; evas_object_event_callback_add(child, EVAS_CALLBACK_DEL, _smart_child_del_hook, sd); - _elm_smart_pan_child_set(sd->pan_obj, sd->child_obj); + _elm_smart_pan_child_set(sd->pan_obj, child); sd->pan_func.child_size_get(sd->pan_obj, &w, &h); sd->child.w = w; sd->child.h = h; @@ -216,24 +254,24 @@ elm_smart_scroller_extern_pan_set(Evas_Object *obj, Evas_Object *pan, if (sd->extern_pan) { - if (sd->pan_obj) - { - edje_object_part_unswallow(sd->edje_obj, sd->pan_obj); - sd->pan_obj = NULL; - } + if (sd->pan_obj) + { + edje_object_part_unswallow(sd->edje_obj, sd->pan_obj); + sd->pan_obj = NULL; + } } else { - if (sd->pan_obj) - { - evas_object_del(sd->pan_obj); - sd->pan_obj = NULL; - } + if (sd->pan_obj) + { + evas_object_del(sd->pan_obj); + sd->pan_obj = NULL; + } } if (!pan) { - sd->extern_pan = 0; - return; + sd->extern_pan = 0; + return; } sd->pan_obj = pan; @@ -314,7 +352,7 @@ elm_smart_scroller_bounce_animator_disabled_set(Evas_Object *obj, Eina_Bool disa { ecore_animator_del(sd->scrollto.x.animator); sd->scrollto.x.animator = NULL; - } + } if (sd->scrollto.y.animator) { @@ -324,6 +362,49 @@ elm_smart_scroller_bounce_animator_disabled_set(Evas_Object *obj, Eina_Bool disa } } +Eina_Bool +elm_smart_scroller_wheel_disabled_get(Evas_Object *obj) +{ + API_ENTRY return EINA_FALSE; + return sd->wheel_disabled; +} + +void +elm_smart_scroller_wheel_disabled_set(Evas_Object *obj, Eina_Bool disabled) +{ + API_ENTRY return; + if ((!sd->wheel_disabled) && (disabled)) + evas_object_event_callback_del_full(sd->event_obj, EVAS_CALLBACK_MOUSE_WHEEL, _smart_event_wheel, sd); + else if ((sd->wheel_disabled) && (!disabled)) + evas_object_event_callback_add(sd->event_obj, EVAS_CALLBACK_MOUSE_WHEEL, _smart_event_wheel, sd); + sd->wheel_disabled = disabled; +} + +/* Update the wanted coordinates according to the x, y passed + * widget directionality, child size and etc. */ +static void +_update_wanted_coordinates(Smart_Data *sd, Evas_Coord x, Evas_Coord y) +{ + Evas_Coord cw, ch; + + sd->pan_func.child_size_get(sd->pan_obj, &cw, &ch); + + /* Update wx/y/w/h - and if the requested positions aren't legal + * adjust a bit. */ + elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &sd->ww, &sd->wh); + if (x < 0) + sd->wx = 0; + else if ((x + sd->ww) > cw) + sd->wx = cw - sd->ww; + else if (sd->is_mirrored) + sd->wx = _elm_smart_scroller_x_mirrored_get(sd->smart_obj, x); + else + sd->wx = x; + if (y < 0) sd->wy = 0; + else if ((y + sd->wh) > ch) sd->wy = ch - sd->wh; + else sd->wy = y; +} + static void _smart_anim_start(Evas_Object *obj) { @@ -381,12 +462,18 @@ _smart_momentum_end(Smart_Data *sd) if ((sd->down.bounce_x_animator) || (sd->down.bounce_y_animator)) return; if (sd->down.momentum_animator) { + Evas_Coord px, py; + elm_smart_scroller_child_pos_get(sd->smart_obj, &px, &py); + _update_wanted_coordinates(sd, px, py); + ecore_animator_del(sd->down.momentum_animator); sd->down.momentum_animator = NULL; sd->down.bounce_x_hold = 0; sd->down.bounce_y_hold = 0; sd->down.ax = 0; sd->down.ay = 0; + sd->down.dx = 0; + sd->down.dy = 0; sd->down.pdx = 0; sd->down.pdy = 0; } @@ -404,7 +491,7 @@ _smart_scrollto_x(Smart_Data *sd, double t_in, Evas_Coord pos_x) elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y); elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &w, &h); x = pos_x; - //elm_smart_scroller_child_region_set(sd->smart_obj, x, y, w, h); + elm_smart_scroller_child_region_set(sd->smart_obj, x, y, w, h); return; } t = ecore_loop_time_get(); @@ -413,14 +500,11 @@ _smart_scrollto_x(Smart_Data *sd, double t_in, Evas_Coord pos_x) sd->scrollto.x.end = pos_x; sd->scrollto.x.t_start = t; sd->scrollto.x.t_end = t + t_in; - elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y); - elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &w, &h); - //elm_smart_scroller_child_region_set(sd->smart_obj, x, y, w, h); if (!sd->scrollto.x.animator) { + sd->scrollto.x.animator = ecore_animator_add(_smart_scrollto_x_animator, sd); if (!sd->scrollto.y.animator) _smart_anim_start(sd->smart_obj); - sd->scrollto.x.animator = ecore_animator_add(_smart_scrollto_x_animator, sd); } if (sd->down.bounce_x_animator) { @@ -471,7 +555,7 @@ _smart_scrollto_y(Smart_Data *sd, double t_in, Evas_Coord pos_y) elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y); elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &w, &h); y = pos_y; - //elm_smart_scroller_child_region_set(sd->smart_obj, x, y, w, h); + elm_smart_scroller_child_region_set(sd->smart_obj, x, y, w, h); return; } t = ecore_loop_time_get(); @@ -480,14 +564,11 @@ _smart_scrollto_y(Smart_Data *sd, double t_in, Evas_Coord pos_y) sd->scrollto.y.end = pos_y; sd->scrollto.y.t_start = t; sd->scrollto.y.t_end = t + t_in; - elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y); - elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &w, &h); - //elm_smart_scroller_child_region_set(sd->smart_obj, x, y, w, h); if (!sd->scrollto.y.animator) { + sd->scrollto.y.animator = ecore_animator_add(_smart_scrollto_y_animator, sd); if (!sd->scrollto.x.animator) _smart_anim_start(sd->smart_obj); - sd->scrollto.y.animator = ecore_animator_add(_smart_scrollto_y_animator, sd); } if (sd->down.bounce_y_animator) { @@ -531,8 +612,8 @@ _smart_page_x_get(Smart_Data *sd, int offset) x = x / (sd->pagesize_h); x = x * (sd->pagesize_h); } + if ((x + w) > cw) x = cw - w; if (x < minx) x = minx; - else if ((x + w) > cw) x = cw - w; return x; } @@ -560,8 +641,8 @@ _smart_page_y_get(Smart_Data *sd, int offset) y = y / (sd->pagesize_v); y = y * (sd->pagesize_v); } + if ((y + h) > ch) y = ch - h; if (y < miny) y = miny; - else if ((y + h) > ch) y = ch - h; return y; } @@ -584,38 +665,45 @@ static Eina_Bool _smart_bounce_x_animator(void *data) { Smart_Data *sd; - Evas_Coord x, y, dx, px, w; - double t, p, dt, pd; + Evas_Coord x, y, dx, px, w, odx, ed, md; + double t, p, dt, pd, r; sd = data; t = ecore_loop_time_get(); dt = t - sd->down.anim_start2; if (dt >= 0.0) { - dt = dt / _elm_config->thumbscroll_bounce_friction; - dx = sd->down.b2x - sd->down.bx; - sd->pan_func.get(sd->pan_obj, &px, NULL); + dt = dt / _elm_config->thumbscroll_bounce_friction; + odx = sd->down.b2x - sd->down.bx; + sd->pan_func.get(sd->pan_obj, &px, NULL); elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &w, NULL); - if(!sd->down.momentum_animator && ((w - px) > 0) && ((-px) < w)) + if (!sd->down.momentum_animator && ((w - px) > 0) && ((-px) < w)) { - pd = (double)dx / (double)w; + pd = (double)odx / (double)w; pd = (pd > 0) ? pd : -pd; pd = 1.0 - ((1.0 - pd) * (1.0 - pd)); dt = dt / pd; } - if (dt > 1.0) dt = 1.0; - p = 1.0 - ((1.0 - dt) * (1.0 - dt)); + if (dt > 1.0) dt = 1.0; + p = 1.0 - ((1.0 - dt) * (1.0 - dt)); elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y); - dx = (dx * p); - x = sd->down.bx + dx; + dx = (odx * p); + r = 1.0; + if (sd->down.momentum_animator) + { + ed = abs(sd->down.dx * (_elm_config->thumbscroll_friction + sd->down.extra_time) - sd->down.b0x); + md = abs(_elm_config->thumbscroll_friction*5*w); + if (ed > md) r = (double)(md)/(double)ed; + } + x = sd->down.b2x + (int)((double)(dx - odx)*r); if (!sd->down.cancelled) elm_smart_scroller_child_pos_set(sd->smart_obj, x, y); if (dt >= 1.0) { if (sd->down.momentum_animator) sd->down.bounce_x_hold = 1; - else if ((!sd->down.bounce_y_animator) && - (!sd->scrollto.y.animator)) + else if ((!sd->down.bounce_y_animator) && + (!sd->scrollto.y.animator)) _smart_anim_stop(sd->smart_obj); sd->down.bounce_x_animator = NULL; sd->down.pdx = 0; @@ -631,37 +719,44 @@ static Eina_Bool _smart_bounce_y_animator(void *data) { Smart_Data *sd; - Evas_Coord x, y, dy, py, h; - double t, p, dt, pd; + Evas_Coord x, y, dy, py, h, ody, ed, md; + double t, p, dt, pd, r; sd = data; t = ecore_loop_time_get(); dt = t - sd->down.anim_start3; if (dt >= 0.0) { - dt = dt / _elm_config->thumbscroll_bounce_friction; - dy = sd->down.b2y - sd->down.by; - sd->pan_func.get(sd->pan_obj, NULL, &py); + dt = dt / _elm_config->thumbscroll_bounce_friction; + ody = sd->down.b2y - sd->down.by; + sd->pan_func.get(sd->pan_obj, NULL, &py); elm_smart_scroller_child_viewport_size_get(sd->smart_obj, NULL, &h); - if(!sd->down.momentum_animator && ((h - py) > 0) && ((-py) < h)) + if (!sd->down.momentum_animator && ((h - py) > 0) && ((-py) < h)) { - pd = (double)dy / (double)h; + pd = (double)ody / (double)h; pd = (pd > 0) ? pd : -pd; pd = 1.0 - ((1.0 - pd) * (1.0 - pd)); dt = dt / pd; } - if (dt > 1.0) dt = 1.0; - p = 1.0 - ((1.0 - dt) * (1.0 - dt)); + if (dt > 1.0) dt = 1.0; + p = 1.0 - ((1.0 - dt) * (1.0 - dt)); elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y); - dy = (dy * p); - y = sd->down.by + dy; + dy = (ody * p); + r = 1.0; + if (sd->down.momentum_animator) + { + ed = abs(sd->down.dy * (_elm_config->thumbscroll_friction + sd->down.extra_time) - sd->down.b0y); + md = abs(_elm_config->thumbscroll_friction*5*h); + if (ed > md) r = (double)(md)/(double)ed; + } + y = sd->down.b2y + (int)((double)(dy - ody)*r); if (!sd->down.cancelled) elm_smart_scroller_child_pos_set(sd->smart_obj, x, y); if (dt >= 1.0) { if (sd->down.momentum_animator) sd->down.bounce_y_hold = 1; - else if ((!sd->down.bounce_x_animator) && + else if ((!sd->down.bounce_x_animator) && (!sd->scrollto.y.animator)) _smart_anim_stop(sd->smart_obj); sd->down.bounce_y_animator = NULL; @@ -729,22 +824,22 @@ _smart_momentum_animator(void *data) if ((sd->down.dir_y) && !can_scroll(sd, sd->down.vdir)) { sd->down.dir_y = 0; - } - } - if ((!sd->down.dir_x) && (!sd->down.dir_y)) - { - sd->down.cancelled = 1; - } + } + } + if ((!sd->down.dir_x) && (!sd->down.dir_y)) + { + sd->down.cancelled = 1; + } */ - dt = dt / (_elm_config->thumbscroll_friction + sd->down.extra_time); - if (dt > 1.0) dt = 1.0; - p = 1.0 - ((1.0 - dt) * (1.0 - dt)); - dx = (sd->down.dx * (_elm_config->thumbscroll_friction + sd->down.extra_time) * p); - dy = (sd->down.dy * (_elm_config->thumbscroll_friction + sd->down.extra_time) * p); + dt = dt / (_elm_config->thumbscroll_friction + sd->down.extra_time); + if (dt > 1.0) dt = 1.0; + p = 1.0 - ((1.0 - dt) * (1.0 - dt)); + dx = (sd->down.dx * (_elm_config->thumbscroll_friction + sd->down.extra_time) * p); + dy = (sd->down.dy * (_elm_config->thumbscroll_friction + sd->down.extra_time) * p); sd->down.ax = dx; sd->down.ay = dy; - x = sd->down.sx - dx; - y = sd->down.sy - dy; + x = sd->down.sx - dx; + y = sd->down.sy - dy; elm_smart_scroller_child_pos_get(sd->smart_obj, &px, &py); if ((sd->down.bounce_x_animator) || (sd->down.bounce_x_hold)) @@ -758,10 +853,11 @@ _smart_momentum_animator(void *data) sd->down.by = sd->down.by0 - dy + sd->down.b0y; y = py; } - elm_smart_scroller_child_pos_set(sd->smart_obj, x, y); + elm_smart_scroller_child_pos_set(sd->smart_obj, x, y); + _update_wanted_coordinates(sd, x, y); sd->pan_func.max_get(sd->pan_obj, &maxx, &maxy); sd->pan_func.min_get(sd->pan_obj, &minx, &miny); - if (!sd->bounce_horiz) + if (!sd->bounce_horiz) { if (x <= minx) no_bounce_x_end = EINA_TRUE; if ((x - minx) >= maxx) no_bounce_x_end = EINA_TRUE; @@ -771,20 +867,21 @@ _smart_momentum_animator(void *data) if (y <= miny) no_bounce_y_end = EINA_TRUE; if ((y - miny) >= maxy) no_bounce_y_end = EINA_TRUE; } - if ((dt >= 1.0) || + if ((dt >= 1.0) || ((sd->down.bounce_x_hold) && (sd->down.bounce_y_hold)) || (no_bounce_x_end && no_bounce_y_end)) - { + { _smart_anim_stop(sd->smart_obj); - sd->down.momentum_animator = NULL; + + sd->down.momentum_animator = NULL; sd->down.bounce_x_hold = 0; sd->down.bounce_y_hold = 0; sd->down.ax = 0; sd->down.ay = 0; sd->down.pdx = 0; sd->down.pdy = 0; - return ECORE_CALLBACK_CANCEL; - } + return ECORE_CALLBACK_CANCEL; + } } return ECORE_CALLBACK_RENEW; } @@ -818,10 +915,10 @@ bounce_eval(Smart_Data *sd) if ((py - miny) > my) py = my + miny; b2x = px; b2y = py; - if ((!sd->widget) || + if ((!sd->widget) || (!elm_widget_drag_child_locked_x_get(sd->widget))) { - if (!sd->down.bounce_x_animator && !sd->bounce_animator_disabled) + if ((!sd->down.bounce_x_animator) && (!sd->bounce_animator_disabled)) { if (sd->bouncemex) { @@ -840,10 +937,10 @@ bounce_eval(Smart_Data *sd) } } } - if ((!sd->widget) || + if ((!sd->widget) || (!elm_widget_drag_child_locked_y_get(sd->widget))) { - if (!sd->down.bounce_y_animator && !sd->bounce_animator_disabled) + if ((!sd->down.bounce_y_animator) && (!sd->bounce_animator_disabled)) { if (sd->bouncemey) { @@ -867,7 +964,7 @@ bounce_eval(Smart_Data *sd) void elm_smart_scroller_child_pos_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y) { - Evas_Coord mx = 0, my = 0, px, py, minx = 0, miny = 0; + Evas_Coord mx = 0, my = 0, px = 0, py = 0, minx = 0, miny = 0; double vx, vy; API_ENTRY return; @@ -909,19 +1006,25 @@ elm_smart_scroller_child_pos_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y) edje_object_signal_emit(sd->edje_obj, "elm,action,scroll", "elm"); if (!sd->down.bounce_x_animator) { - if ((x < minx) || (x > (mx + minx))) + if (((x < minx) && (0 <= sd->down.dx)) || + ((x > (mx + minx)) && (0 >= sd->down.dx))) { sd->bouncemex = 1; bounce_eval(sd); } + else + sd->bouncemex = 0; } if (!sd->down.bounce_y_animator) { - if ((y < miny) || (y > my + miny)) + if (((y < miny) && (0 <= sd->down.dy)) || + ((y > (my + miny)) && (0 >= sd->down.dy))) { sd->bouncemey = 1; bounce_eval(sd); } + else + sd->bouncemey = 0; } if ((x != px) || (y != py)) { @@ -950,18 +1053,19 @@ elm_smart_scroller_child_pos_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y) sd->pan_func.get(sd->pan_obj, x, y); } -/* "internal_call" actually toggles whether we should save the coords and do - * extra "speedup" checks, or not. */ -static void -_elm_smart_scroller_child_region_show_internal(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, Eina_Bool internal_call) +/* returns TRUE when we need to move the scroller, FALSE otherwise. + * Updates w and h either way, so save them if you need them. */ +static Eina_Bool +_elm_smart_scroller_child_region_show_internal(Evas_Object *obj, Evas_Coord *_x, Evas_Coord *_y, Evas_Coord w, Evas_Coord h) { - Evas_Coord mx = 0, my = 0, cw = 0, ch = 0, px = 0, py = 0, nx, ny, minx = 0, miny = 0; + Evas_Coord mx = 0, my = 0, cw = 0, ch = 0, px = 0, py = 0, nx, ny, minx = 0, miny = 0, pw = 0, ph = 0, x = *_x, y = *_y; - API_ENTRY return; + API_ENTRY return EINA_FALSE; sd->pan_func.max_get(sd->pan_obj, &mx, &my); sd->pan_func.min_get(sd->pan_obj, &minx, &miny); sd->pan_func.child_size_get(sd->pan_obj, &cw, &ch); sd->pan_func.get(sd->pan_obj, &px, &py); + evas_object_geometry_get(sd->pan_obj, NULL, NULL, &pw, &ph); nx = px; if ((x < px) && ((x + w) < (px + (cw - mx)))) nx = x; @@ -969,15 +1073,7 @@ _elm_smart_scroller_child_region_show_internal(Evas_Object *obj, Evas_Coord x, E ny = py; if ((y < py) && ((y + h) < (py + (ch - my)))) ny = y; else if ((y > py) && ((y + h) > (py + (ch - my)))) ny = y + h - (ch - my); -// if ((nx == px) && (ny == py)) return; - if (!internal_call) - { - sd->wx = x; - sd->wy = y; - sd->ww = w; - sd->wh = h; - if ((nx == px) && (ny == py)) return; - } + if ((sd->down.bounce_x_animator) || (sd->down.bounce_y_animator) || (sd->scrollto.x.animator) || (sd->scrollto.y.animator)) { @@ -1022,13 +1118,18 @@ _elm_smart_scroller_child_region_show_internal(Evas_Object *obj, Evas_Coord x, E sd->down.pdx = 0; sd->down.pdy = 0; } + x = nx; + if ((x + pw) > cw) x = cw - pw; if (x < minx) x = minx; - else if ((x + w) > cw) x = cw - w; y = ny; + if ((y + ph) > ch) y = ch - ph; if (y < miny) y = miny; - else if ((y + h) > ch) y = ch - h; - elm_smart_scroller_child_pos_set(obj, x, y); + + if ((x == px) && (y == py)) return EINA_FALSE; + *_x = x; + *_y = y; + return EINA_TRUE; } /* Set should be used for calculated positions, for example, when we move @@ -1037,7 +1138,8 @@ _elm_smart_scroller_child_region_show_internal(Evas_Object *obj, Evas_Coord x, E void elm_smart_scroller_child_region_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) { - _elm_smart_scroller_child_region_show_internal(obj, x, y, w, h, EINA_TRUE); + if (_elm_smart_scroller_child_region_show_internal(obj, &x, &y, w, h)) + elm_smart_scroller_child_pos_set(obj, x, y); } /* Set should be used for setting the wanted position, for example a user scroll @@ -1045,13 +1147,20 @@ elm_smart_scroller_child_region_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y void elm_smart_scroller_child_region_show(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) { - _elm_smart_scroller_child_region_show_internal(obj, x, y, w, h, EINA_FALSE); + API_ENTRY return; + sd->wx = x; + sd->wy = y; + sd->ww = w; + sd->wh = h; + if (_elm_smart_scroller_child_region_show_internal(obj, &x, &y, w, h)) + elm_smart_scroller_child_pos_set(obj, x, y); } void elm_smart_scroller_child_viewport_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h) { API_ENTRY return; + if (!sd->pan_obj) return; edje_object_calc_force(sd->edje_obj); evas_object_geometry_get(sd->pan_obj, NULL, NULL, w, h); } @@ -1164,8 +1273,10 @@ elm_smart_scroller_object_theme_set(Evas_Object *parent, Evas_Object *obj, const { API_ENTRY return; Evas_Coord mw, mh; + //Does this API require parent object absolutely? if then remove this exception. + double parent_scale = parent ? elm_widget_scale_get(parent) : 1; _elm_theme_object_set(parent, sd->edje_obj, clas, group, style); - edje_object_scale_set(sd->edje_obj, elm_widget_scale_get(parent) * _elm_config->scale); + edje_object_scale_set(sd->edje_obj, parent_scale * _elm_config->scale); if (sd->pan_obj) edje_object_part_swallow(sd->edje_obj, "elm.swallow.content", sd->pan_obj); mw = mh = -1; @@ -1208,6 +1319,8 @@ elm_smart_scroller_freeze_set(Evas_Object *obj, Eina_Bool freeze) sd->down.onhold_animator = NULL; } } + else + bounce_eval(sd); } void @@ -1222,8 +1335,8 @@ void elm_smart_scroller_bounce_allow_get(const Evas_Object *obj, Eina_Bool *horiz, Eina_Bool *vert) { API_ENTRY return; - *horiz = sd->bounce_horiz; - *vert = sd->bounce_vert; + if (horiz) *horiz = sd->bounce_horiz; + if (vert) *vert = sd->bounce_vert; } void @@ -1234,7 +1347,7 @@ elm_smart_scroller_paging_set(Evas_Object *obj, double pagerel_h, double pagerel sd->pagerel_v = pagerel_v; sd->pagesize_h = pagesize_h; sd->pagesize_v = pagesize_v; - if (sd->child_obj) _smart_page_adjust(sd); + _smart_page_adjust(sd); } void @@ -1250,73 +1363,12 @@ elm_smart_scroller_paging_get(Evas_Object *obj, double *pagerel_h, double *pager void elm_smart_scroller_region_bring_in(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) { - Evas_Coord mx = 0, my = 0, cw = 0, ch = 0, px = 0, py = 0, nx, ny, minx = 0, miny = 0; - API_ENTRY return; - sd->pan_func.max_get(sd->pan_obj, &mx, &my); - sd->pan_func.min_get(sd->pan_obj, &minx, &miny); - sd->pan_func.child_size_get(sd->pan_obj, &cw, &ch); - sd->pan_func.get(sd->pan_obj, &px, &py); - - nx = px; - if ((x < px) && ((x + w) < (px + (cw - mx)))) nx = x; - else if ((x > px) && ((x + w) > (px + (cw - mx)))) nx = x + w - (cw - mx); - ny = py; - if ((y < py) && ((y + h) < (py + (ch - my)))) ny = y; - else if ((y > py) && ((y + h) > (py + (ch - my)))) ny = y + h - (ch - my); -// if ((nx == px) && (ny == py)) return; - if ((sd->down.bounce_x_animator) || (sd->down.bounce_y_animator) || - (sd->scrollto.x.animator) || (sd->scrollto.y.animator)) - { - _smart_anim_stop(sd->smart_obj); - } - if (sd->scrollto.x.animator) + if (_elm_smart_scroller_child_region_show_internal(obj, &x, &y, w, h)) { - ecore_animator_del(sd->scrollto.x.animator); - sd->scrollto.x.animator = NULL; + _smart_scrollto_x(sd, _elm_config->bring_in_scroll_friction, x); + _smart_scrollto_y(sd, _elm_config->bring_in_scroll_friction, y); } - if (sd->scrollto.y.animator) - { - ecore_animator_del(sd->scrollto.y.animator); - sd->scrollto.y.animator = NULL; - } - if (sd->down.bounce_x_animator) - { - ecore_animator_del(sd->down.bounce_x_animator); - sd->down.bounce_x_animator = NULL; - sd->bouncemex = 0; - } - if (sd->down.bounce_y_animator) - { - ecore_animator_del(sd->down.bounce_y_animator); - sd->down.bounce_y_animator = NULL; - sd->bouncemey = 0; - } - if (sd->down.hold_animator) - { - ecore_animator_del(sd->down.hold_animator); - sd->down.hold_animator = NULL; - _smart_drag_stop(sd->smart_obj); - } - if (sd->down.momentum_animator) - { - ecore_animator_del(sd->down.momentum_animator); - sd->down.momentum_animator = NULL; - sd->down.bounce_x_hold = 0; - sd->down.bounce_y_hold = 0; - sd->down.ax = 0; - sd->down.ay = 0; - sd->down.pdx = 0; - sd->down.pdy = 0; - } - x = nx; - if (x < minx) x = minx; - else if ((x + w) > cw) x = cw - w; - y = ny; - if (y < miny) y = miny; - else if ((y + h) > ch) y = ch - h; - _smart_scrollto_x(sd, _elm_config->bring_in_scroll_friction, nx); - _smart_scrollto_y(sd, _elm_config->bring_in_scroll_friction, ny); } void @@ -1326,6 +1378,33 @@ elm_smart_scroller_widget_set(Evas_Object *obj, Evas_Object *wid) sd->widget = wid; } +static void +_elm_smart_scroller_wanted_region_set(Evas_Object *obj) +{ + INTERNAL_ENTRY; + Evas_Coord ww, wh, wx = sd->wx; + + if (sd->down.now || sd->down.momentum_animator || + sd->down.bounce_x_animator || sd->down.bounce_y_animator || + sd->down.hold_animator || sd->down.onhold_animator) return; + + /* Flip to RTL cords only if init in RTL mode */ + if(sd->is_mirrored) + wx = _elm_smart_scroller_x_mirrored_get(obj, sd->wx); + + if (sd->ww == -1) + { + elm_smart_scroller_child_viewport_size_get(obj, &ww, &wh); + } + else + { + ww = sd->ww; + wh = sd->wh; + } + + elm_smart_scroller_child_region_set(obj, wx, sd->wy, ww, wh); +} + /* local subsystem functions */ static void _smart_edje_drag_v_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) @@ -1403,31 +1482,27 @@ _smart_child_del_hook(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED_ static void _smart_pan_changed_hook(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - Evas_Coord x, y; Evas_Coord w, h; Smart_Data *sd; sd = data; - sd->pan_func.get(sd->pan_obj, &x, &y); sd->pan_func.child_size_get(sd->pan_obj, &w, &h); if ((w != sd->child.w) || (h != sd->child.h)) { - sd->child.w = w; - sd->child.h = h; - _smart_scrollbar_size_adjust(sd); + sd->child.w = w; + sd->child.h = h; + _smart_scrollbar_size_adjust(sd); evas_object_size_hint_min_set(sd->smart_obj, sd->child.w, sd->child.h); - elm_smart_scroller_child_pos_set(sd->smart_obj, x, y); + _elm_smart_scroller_wanted_region_set(sd->smart_obj); } } static void _smart_pan_pan_changed_hook(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - Evas_Coord x, y; Smart_Data *sd; sd = data; - sd->pan_func.get(sd->pan_obj, &x, &y); if ((sd->down.bounce_x_animator) || (sd->down.bounce_y_animator) || (sd->scrollto.x.animator) || (sd->scrollto.y.animator)) { @@ -1455,7 +1530,7 @@ _smart_pan_pan_changed_hook(void *data, Evas_Object *obj __UNUSED__, void *event sd->down.bounce_y_animator = NULL; sd->bouncemey = 0; } - elm_smart_scroller_child_pos_set(sd->smart_obj, x, y); + _elm_smart_scroller_wanted_region_set(sd->smart_obj); } static void @@ -1510,8 +1585,7 @@ _smart_event_wheel(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, if ((!sd->hold) && (!sd->freeze)) { - sd->wx = x; - sd->wy = y; + _update_wanted_coordinates(sd, x, y); elm_smart_scroller_child_pos_set(sd->smart_obj, x, y); } } @@ -1525,7 +1599,7 @@ _smart_event_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSE sd = data; ev = event_info; -// if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return ; + // if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return ; if (_elm_config->thumbscroll_enable) { sd->down.hold = 0; @@ -1560,42 +1634,48 @@ _smart_event_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSE sd->down.bounce_y_animator = NULL; sd->bouncemey = 0; } - if (sd->down.hold_animator) - { - ecore_animator_del(sd->down.hold_animator); - sd->down.hold_animator = NULL; + if (sd->down.hold_animator) + { + ecore_animator_del(sd->down.hold_animator); + sd->down.hold_animator = NULL; _smart_drag_stop(sd->smart_obj); - } - if (sd->down.momentum_animator) - { - ecore_animator_del(sd->down.momentum_animator); - sd->down.momentum_animator = NULL; + } + if (sd->down.momentum_animator) + { + ecore_animator_del(sd->down.momentum_animator); + sd->down.momentum_animator = NULL; sd->down.bounce_x_hold = 0; sd->down.bounce_y_hold = 0; sd->down.ax = 0; sd->down.ay = 0; - } - if (ev->button == 1) - { - sd->down.now = 1; - sd->down.dragged = 0; - sd->down.dir_x = 0; - sd->down.dir_y = 0; - sd->down.x = ev->canvas.x; - sd->down.y = ev->canvas.y; - elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y); - sd->down.sx = x; - sd->down.sy = y; - sd->down.locked = 0; - memset(&(sd->down.history[0]), 0, sizeof(sd->down.history[0]) * 20); + } + if (ev->button == 1) + { + sd->down.hist.est_timestamp_diff = + ecore_loop_time_get() - ((double)ev->timestamp / 1000.0); + sd->down.hist.tadd = 0.0; + sd->down.hist.dxsum = 0.0; + sd->down.hist.dysum = 0.0; + sd->down.now = 1; + sd->down.dragged = 0; + sd->down.dir_x = 0; + sd->down.dir_y = 0; + sd->down.x = ev->canvas.x; + sd->down.y = ev->canvas.y; + elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y); + sd->down.sx = x; + sd->down.sy = y; + sd->down.locked = 0; + memset(&(sd->down.history[0]), 0, sizeof(sd->down.history[0]) * 60); #ifdef EVTIME - sd->down.history[0].timestamp = ev->timestamp / 1000.0; + sd->down.history[0].timestamp = ev->timestamp / 1000.0; + sd->down.history[0].localtimestamp = ecore_loop_time_get(); #else - sd->down.history[0].timestamp = ecore_loop_time_get(); + sd->down.history[0].timestamp = ecore_loop_time_get(); #endif - sd->down.history[0].x = ev->canvas.x; - sd->down.history[0].y = ev->canvas.y; - } + sd->down.history[0].x = ev->canvas.x; + sd->down.history[0].y = ev->canvas.y; + } sd->down.dragged_began = 0; sd->down.hold_parent = 0; sd->down.cancelled = 0; @@ -1606,32 +1686,138 @@ _smart_event_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSE } } +static void +_down_coord_eval(Smart_Data *sd, Evas_Coord *x, Evas_Coord *y) +{ + Evas_Coord minx, miny; + + if (sd->down.dir_x) *x = sd->down.sx - (*x - sd->down.x); + else *x = sd->down.sx; + if (sd->down.dir_y) *y = sd->down.sy - (*y - sd->down.y); + else *y = sd->down.sy; + + if ((sd->down.dir_x) || (sd->down.dir_y)) + { + if (!((sd->down.dir_x) && (sd->down.dir_y))) + { + if (sd->down.dir_x) *y = sd->down.locked_y; + else *x = sd->down.locked_x; + } + } + + sd->pan_func.min_get(sd->pan_obj, &minx, &miny); + + if (*x < minx) + *x += (minx - *x) * _elm_config->thumbscroll_border_friction; + else if (sd->child.w <= sd->w) + *x += (sd->down.sx - *x) * _elm_config->thumbscroll_border_friction; + else if ((sd->child.w - sd->w + minx) < *x) + *x += (sd->child.w - sd->w + minx - *x) * + _elm_config->thumbscroll_border_friction; + + if (*y < miny) + *y += (miny - *y) * _elm_config->thumbscroll_border_friction; + else if (sd->child.h <= sd->h) + *y += (sd->down.sy - *y) * _elm_config->thumbscroll_border_friction; + else if ((sd->child.h - sd->h + miny) < *y) + *y += (sd->child.h - sd->h + miny - *y) * + _elm_config->thumbscroll_border_friction; +} + static Eina_Bool _smart_hold_animator(void *data) { Smart_Data *sd = data; - Evas_Coord ox, oy; - + Evas_Coord ox = 0, oy = 0, fx = 0, fy= 0; + + fx = sd->down.hold_x; + fy = sd->down.hold_y; + + if ((!sd->hold) && (!sd->freeze) && (_elm_config->scroll_smooth_time_interval > 0.0)) + { + int i, count = 0; //count for the real event number we have to deal with + int queue_size = 10; //for event queue size + int src_index = 0, dst_index = 0; + int xsum = 0, ysum=0; + Evas_Coord x=0, y=0; + + struct { + Evas_Coord x, y; + double t; + } pos[queue_size]; + + double tdiff, tnow; + double time_interval=_elm_config->scroll_smooth_time_interval; + // FIXME: assume server and client have the same "timezone" + // (0 timepoint) for now. this needs to be figured out in advance + // though. + tdiff = sd->down.hist.est_timestamp_diff; + tnow = ecore_time_get() - tdiff; + + for(i = 0; i < queue_size; i++) + { + x = sd->down.history[i].x; + y = sd->down.history[i].y; + + //if there is no history value , we don't deal with it + //if there is better wat to know existance of history value , I will modify this code to it + if ( (x == 0) && (y == 0) ) + { + break; + } + _down_coord_eval(sd, &x, &y); + + pos[i].x = x; + pos[i].y = y; + pos[i].t = tnow - sd->down.history[i].timestamp; + } + count = --i; + + // we only deal with smooth scroll there is enough history + for(i = 0; i < queue_size; i++) + { + if (src_index > count) break; + if (i == 0) + { + xsum = pos[i].x; + ysum = pos[i].y; + dst_index++; + continue; + } + while ((pos[src_index].t < time_interval *i) && + (src_index <= count)) + { + src_index++; + } + if (src_index <= count) + { + xsum += pos[src_index].x; + ysum += pos[src_index].y; + dst_index++; + } + } + fx = xsum / dst_index; + fy = ysum / dst_index; + } + elm_smart_scroller_child_pos_get(sd->smart_obj, &ox, &oy); if (sd->down.dir_x) { - if ((!sd->widget) || + if ((!sd->widget) || (!elm_widget_drag_child_locked_x_get(sd->widget))) { - ox = sd->down.hold_x; + ox = fx; } } if (sd->down.dir_y) { - if ((!sd->widget) || + if ((!sd->widget) || (!elm_widget_drag_child_locked_y_get(sd->widget))) { - oy = sd->down.hold_y; + oy = fy; } } elm_smart_scroller_child_pos_set(sd->smart_obj, ox, oy); - sd->wx = ox; - sd->wy = oy; return ECORE_CALLBACK_RENEW; } @@ -1656,24 +1842,27 @@ _smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *ev Evas_Event_Mouse_Down *ev; Smart_Data *sd; Evas_Coord x = 0, y = 0, ox = 0, oy = 0; + Evas_Coord vw, vh, aw, ah; sd = data; ev = event_info; sd->down.hold_parent = 0; -// if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return ; + sd->down.dx = 0; + sd->down.dy = 0; + // if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return ; evas_post_event_callback_push(e, _smart_event_post_up, sd); // FIXME: respect elm_widget_scroll_hold_get of parent container if (_elm_config->thumbscroll_enable) { - if (ev->button == 1) - { + if (ev->button == 1) + { if (sd->down.onhold_animator) { ecore_animator_del(sd->down.onhold_animator); sd->down.onhold_animator = NULL; } - x = ev->canvas.x - sd->down.x; - y = ev->canvas.y - sd->down.y; + x = ev->canvas.x - sd->down.x; + y = ev->canvas.y - sd->down.y; if (sd->down.dragged) { _smart_drag_stop(sd->smart_obj); @@ -1695,7 +1884,7 @@ _smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *ev #ifdef SCROLLDBG printf("------ %i %i\n", ev->canvas.x, ev->canvas.y); #endif - for (i = 0; i < 20; i++) + for (i = 0; i < 60; i++) { dt = t - sd->down.history[i].timestamp; if (dt > 0.2) break; @@ -1711,63 +1900,64 @@ _smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *ev ax /= (i + 1); ay /= (i + 1); at /= (i + 1); - at *= 4.0; + at /= _elm_config->thumbscroll_sensitivity_friction; dx = ev->canvas.x - ax; dy = ev->canvas.y - ay; if (at > 0) { vel = sqrt((dx * dx) + (dy * dy)) / at; if ((_elm_config->thumbscroll_friction > 0.0) && - (vel > _elm_config->thumbscroll_momentum_threshold) && - (!sd->freeze)) + (vel > _elm_config->thumbscroll_momentum_threshold)) { - Evas_Coord cw = 0, ch = 0, px = 0, py = 0; + int minx, miny, mx, my, px, py; + sd->pan_func.min_get(sd->pan_obj, &minx, &miny); + sd->pan_func.max_get(sd->pan_obj, &mx, &my); + sd->pan_func.get(sd->pan_obj, &px, &py); sd->down.dx = ((double)dx / at); sd->down.dy = ((double)dy / at); if (((sd->down.dx > 0) && (sd->down.pdx > 0)) || + ((sd->down.dx < 0) && (sd->down.pdx < 0))) + if (px > minx && px < mx) + sd->down.dx += (double)sd->down.pdx * 1.5; // FIXME: * 1.5 - probably should be config + if (((sd->down.dy > 0) && (sd->down.pdy > 0)) || + ((sd->down.dy < 0) && (sd->down.pdy < 0))) + if (py > miny && py < my) + sd->down.dy += (double)sd->down.pdy * 1.5; // FIXME: * 1.5 - probably should be config + if (((sd->down.dx > 0) && (sd->down.pdx > 0)) || ((sd->down.dx < 0) && (sd->down.pdx < 0)) || ((sd->down.dy > 0) && (sd->down.pdy > 0)) || ((sd->down.dy < 0) && (sd->down.pdy < 0))) - { - double t = ecore_loop_time_get(); - double dt = t - sd->down.anim_start; - - if (dt < 0.0) dt = 0.0; - else if (dt > _elm_config->thumbscroll_friction) - dt = _elm_config->thumbscroll_friction; - sd->down.extra_time = _elm_config->thumbscroll_friction - dt; - } - if (((sd->down.dx > 0) && (sd->down.pdx > 0)) || - ((sd->down.dx < 0) && (sd->down.pdx < 0))) { - int buf = (int)((double)sd->down.dx * (_elm_config->thumbscroll_friction + sd->down.extra_time) * 2); - sd->down.dx += (double)sd->down.pdx * 1.5; // FIXME: * 1.5 - probably should be config - int dest = (int)((double)sd->down.dx * (_elm_config->thumbscroll_friction + sd->down.extra_time)); - if (dest < ((px - cw) + buf)) - sd->down.dx = (int)((double)((px - cw) + buf) / (_elm_config->thumbscroll_friction + sd->down.extra_time)); - else if (dest > (px + buf)) - sd->down.dx = (int)((double)(px + buf) / (_elm_config->thumbscroll_friction + sd->down.extra_time)); + double t = ecore_loop_time_get(); + double dt = t - sd->down.anim_start; + + if (dt < 0.0) dt = 0.0; + else if (dt > _elm_config->thumbscroll_friction) + dt = _elm_config->thumbscroll_friction; + sd->down.extra_time = _elm_config->thumbscroll_friction - dt; } - if (((sd->down.dy > 0) && (sd->down.pdy > 0)) || - ((sd->down.dy < 0) && (sd->down.pdy < 0))) + else + sd->down.extra_time = 0.0; + elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &vw, &vh); + aw = abs(sd->down.dx); + if (aw > vw*3) { - int buf = (int)((double)sd->down.dy * (_elm_config->thumbscroll_friction + sd->down.extra_time) * 2); - sd->down.dy += (double)sd->down.pdy * 1.5; // FIXME: * 1.5 - probably should be config - int dest = (int)((double)sd->down.dy * (_elm_config->thumbscroll_friction + sd->down.extra_time)); - if (dest < ((py - ch) + buf)) - sd->down.dy = (int)((double)((py - ch) + buf) / (_elm_config->thumbscroll_friction + sd->down.extra_time)); - else if (dest > (py + buf)) - sd->down.dy = (int)((double)(py + buf) / (_elm_config->thumbscroll_friction + sd->down.extra_time)); + if (sd->down.dx > 0) sd->down.dx = vw*3; + else sd->down.dx = -(vw*3); + } + ah = abs(sd->down.dy); + if (ah > vh*3) + { + if (sd->down.dy > 0) sd->down.dy = vh*3; + else sd->down.dy = -(vh*3); } - else - sd->down.extra_time = 0.0; sd->down.pdx = sd->down.dx; sd->down.pdy = sd->down.dy; ox = -sd->down.dx; oy = -sd->down.dy; if (!_smart_do_page(sd)) { - if (!sd->down.momentum_animator && !sd->momentum_animator_disabled) + if ((!sd->down.momentum_animator) && (!sd->momentum_animator_disabled)) { sd->down.momentum_animator = ecore_animator_add(_smart_momentum_animator, sd); ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL; @@ -1782,11 +1972,6 @@ _smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *ev } } } - if (sd->down.hold_animator) - { - ecore_animator_del(sd->down.hold_animator); - sd->down.hold_animator = NULL; - } } else { @@ -1799,28 +1984,28 @@ _smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *ev Evas_Coord pgx, pgy; elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y); - if ((!sd->widget) || + if ((!sd->widget) || (!elm_widget_drag_child_locked_x_get(sd->widget))) { pgx = _smart_page_x_get(sd, ox); - if (pgx != x) + if (pgx != x) { ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL; _smart_scrollto_x(sd, _elm_config->page_scroll_friction, pgx); } } - if ((!sd->widget) || + if ((!sd->widget) || (!elm_widget_drag_child_locked_y_get(sd->widget))) { pgy = _smart_page_y_get(sd, oy); - if (pgy != y) + if (pgy != y) { ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL; _smart_scrollto_y(sd, _elm_config->page_scroll_friction, pgy); } } } - } + } else { sd->down.pdx = 0; @@ -1830,24 +2015,24 @@ _smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *ev Evas_Coord pgx, pgy; elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y); - if ((!sd->widget) || + if ((!sd->widget) || (!elm_widget_drag_child_locked_x_get(sd->widget))) { pgx = _smart_page_x_get(sd, ox); if (pgx != x) _smart_scrollto_x(sd, _elm_config->page_scroll_friction, pgx); } - if ((!sd->widget) || + if ((!sd->widget) || (!elm_widget_drag_child_locked_y_get(sd->widget))) { pgy = _smart_page_y_get(sd, oy); if (pgy != y) _smart_scrollto_y(sd, _elm_config->page_scroll_friction, pgy); } } - if (sd->down.hold_animator) - { - ecore_animator_del(sd->down.hold_animator); - sd->down.hold_animator = NULL; - } + } + if (sd->down.hold_animator) + { + ecore_animator_del(sd->down.hold_animator); + sd->down.hold_animator = NULL; } if (sd->down.scroll) { @@ -1863,15 +2048,15 @@ _smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *ev sd->down.dir_x = 0; sd->down.dir_y = 0; sd->down.want_dragged = 0; - sd->down.dragged = 0; - sd->down.now = 0; + sd->down.dragged = 0; + sd->down.now = 0; elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y); elm_smart_scroller_child_pos_set(sd->smart_obj, x, y); - sd->wx = x; - sd->wy = y; + _update_wanted_coordinates(sd, x, y); + if (!_smart_do_page(sd)) bounce_eval(sd); - } + } } } @@ -1893,10 +2078,10 @@ _smart_onhold_animator(void *data) elm_smart_scroller_child_pos_get(sd->smart_obj, &ox, &oy); x = ox; y = oy; - + if (sd->down.dir_x) { - if ((!sd->widget) || + if ((!sd->widget) || (!elm_widget_drag_child_locked_x_get(sd->widget))) { sd->down.onhold_vxe += vx; @@ -1904,10 +2089,10 @@ _smart_onhold_animator(void *data) sd->down.onhold_vxe -= (int)sd->down.onhold_vxe; } } - + if (sd->down.dir_y) { - if ((!sd->widget) || + if ((!sd->widget) || (!elm_widget_drag_child_locked_y_get(sd->widget))) { sd->down.onhold_vye += vy; @@ -1915,11 +2100,8 @@ _smart_onhold_animator(void *data) sd->down.onhold_vye -= (int)sd->down.onhold_vye; } } - + elm_smart_scroller_child_pos_set(sd->smart_obj, x, y); - sd->wx = x; - sd->wy = y; -// printf("scroll %i %i\n", sd->down.hold_x, sd->down.hold_y); } sd->down.onhold_tlast = t; return ECORE_CALLBACK_RENEW; @@ -1947,7 +2129,7 @@ _smart_event_post_move(void *data, Evas *e __UNUSED__) } if (sd->down.dir_x) { - if ((!sd->widget) || + if ((!sd->widget) || (!elm_widget_drag_child_locked_x_get(sd->widget))) { sd->down.want_dragged = 0; @@ -1963,7 +2145,7 @@ _smart_event_post_move(void *data, Evas *e __UNUSED__) } if (sd->down.dir_y) { - if ((!sd->widget) || + if ((!sd->widget) || (!elm_widget_drag_child_locked_y_get(sd->widget))) { sd->down.want_dragged = 0; @@ -1995,47 +2177,46 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj __UNUSED__, void * sd = data; ev = event_info; -// if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return ; + // if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return ; if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) sd->down.hold_parent = 1; evas_post_event_callback_push(e, _smart_event_post_move, sd); // FIXME: respect elm_widget_scroll_hold_get of parent container if (_elm_config->thumbscroll_enable) { - if (sd->down.now) - { + if (sd->down.now) + { int dodir = 0; #ifdef SCROLLDBG printf("::: %i %i\n", ev->cur.canvas.x, ev->cur.canvas.y); #endif - sd->wx = ev->cur.canvas.x; - sd->wy = ev->cur.canvas.y; - memmove(&(sd->down.history[1]), &(sd->down.history[0]), - sizeof(sd->down.history[0]) * 19); + memmove(&(sd->down.history[1]), &(sd->down.history[0]), + sizeof(sd->down.history[0]) * (60 - 1)); #ifdef EVTIME - sd->down.history[0].timestamp = ev->timestamp / 1000.0; + sd->down.history[0].timestamp = ev->timestamp / 1000.0; + sd->down.history[0].localtimestamp = ecore_loop_time_get(); #else - sd->down.history[0].timestamp = ecore_loop_time_get(); + sd->down.history[0].timestamp = ecore_loop_time_get(); #endif - sd->down.history[0].x = ev->cur.canvas.x; - sd->down.history[0].y = ev->cur.canvas.y; + sd->down.history[0].x = ev->cur.canvas.x; + sd->down.history[0].y = ev->cur.canvas.y; if (!sd->down.dragged_began) { x = ev->cur.canvas.x - sd->down.x; y = ev->cur.canvas.y - sd->down.y; - + sd->down.hdir = -1; sd->down.vdir = -1; - + if (x > 0) sd->down.hdir = LEFT; else if (x < 0) sd->down.hdir = RIGHT; if (y > 0) sd->down.vdir = UP; else if (y < 0) sd->down.vdir = DOWN; - + if (x < 0) x = -x; if (y < 0) y = -y; - + if ((sd->one_dir_at_a_time) && (!((sd->down.dir_x) || (sd->down.dir_y)))) { @@ -2065,10 +2246,10 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj __UNUSED__, void * } else { -// can_scroll(sd, LEFT); -// can_scroll(sd, RIGHT); -// can_scroll(sd, UP); -// can_scroll(sd, DOWN); + // can_scroll(sd, LEFT); + // can_scroll(sd, RIGHT); + // can_scroll(sd, UP); + // can_scroll(sd, DOWN); sd->down.dir_x = 1; sd->down.dir_y = 1; } @@ -2085,15 +2266,15 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj __UNUSED__, void * { sd->down.want_dragged = 1; ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; -// evas_event_feed_hold(e, 1, ev->timestamp, ev->data); -// _smart_drag_start(sd->smart_obj); + // evas_event_feed_hold(e, 1, ev->timestamp, ev->data); + // _smart_drag_start(sd->smart_obj); } if (sd->down.dragged) { ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; } -// ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; -// sd->down.dragged = 1; + // ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + // sd->down.dragged = 1; if (sd->down.dir_x) x = sd->down.sx - (ev->cur.canvas.x - sd->down.x); else @@ -2122,38 +2303,37 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj __UNUSED__, void * else x = sd->down.locked_x; } } - if (_elm_config->thumbscroll_border_friction > 0.0) { Evas_Coord minx, miny; sd->pan_func.min_get(sd->pan_obj, &minx, &miny); if (y < miny) - y += (miny - y) * - _elm_config->thumbscroll_border_friction; + y += (miny - y) * + _elm_config->thumbscroll_border_friction; else if (sd->child.h <= sd->h) - y += (sd->down.sy - y) * - _elm_config->thumbscroll_border_friction; + y += (sd->down.sy - y) * + _elm_config->thumbscroll_border_friction; else if ((sd->child.h - sd->h + miny) < y) - y += (sd->child.h - sd->h + miny - y) * - _elm_config->thumbscroll_border_friction; + y += (sd->child.h - sd->h + miny - y) * + _elm_config->thumbscroll_border_friction; if (x < minx) - x += (minx - x) * - _elm_config->thumbscroll_border_friction; + x += (minx - x) * + _elm_config->thumbscroll_border_friction; else if (sd->child.w <= sd->w) - x += (sd->down.sx - x) * - _elm_config->thumbscroll_border_friction; + x += (sd->down.sx - x) * + _elm_config->thumbscroll_border_friction; else if ((sd->child.w - sd->w + minx) < x) - x += (sd->child.w - sd->w + minx - x) * - _elm_config->thumbscroll_border_friction; + x += (sd->child.w - sd->w + minx - x) * + _elm_config->thumbscroll_border_friction; } sd->down.hold_x = x; sd->down.hold_y = y; if (!sd->down.hold_animator) - sd->down.hold_animator = - ecore_animator_add(_smart_hold_animator, sd); -// printf("a %i %i\n", sd->down.hold_x, sd->down.hold_y); -// _smart_onhold_animator(sd); -// elm_smart_scroller_child_pos_set(sd->smart_obj, x, y); + sd->down.hold_animator = + ecore_animator_add(_smart_hold_animator, sd); + // printf("a %i %i\n", sd->down.hold_x, sd->down.hold_y); + // _smart_onhold_animator(sd); + // elm_smart_scroller_child_pos_set(sd->smart_obj, x, y); } else { @@ -2167,7 +2347,7 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj __UNUSED__, void * } } } - } + } else if (!sd->freeze) { Evas_Coord ex, ey, ew, eh; @@ -2180,7 +2360,7 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj __UNUSED__, void * { if (_elm_config->thumbscroll_threshold > 0.0) vx = -(double)(_elm_config->thumbscroll_threshold - x) / - _elm_config->thumbscroll_threshold; + _elm_config->thumbscroll_threshold; else vx = -1.0; } @@ -2188,7 +2368,7 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj __UNUSED__, void * { if (_elm_config->thumbscroll_threshold > 0.0) vx = (double)(_elm_config->thumbscroll_threshold - (ew - x)) / - _elm_config->thumbscroll_threshold; + _elm_config->thumbscroll_threshold; else vx = 1.0; } @@ -2196,7 +2376,7 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj __UNUSED__, void * { if (_elm_config->thumbscroll_threshold > 0.0) vy = -(double)(_elm_config->thumbscroll_threshold - y) / - _elm_config->thumbscroll_threshold; + _elm_config->thumbscroll_threshold; else vy = -1.0; } @@ -2204,7 +2384,7 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj __UNUSED__, void * { if (_elm_config->thumbscroll_threshold > 0.0) vy = (double)(_elm_config->thumbscroll_threshold - (eh - y)) / - _elm_config->thumbscroll_threshold; + _elm_config->thumbscroll_threshold; else vy = 1.0; } @@ -2219,7 +2399,7 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj __UNUSED__, void * sd->down.onhold_tlast = 0.0; sd->down.onhold_animator = ecore_animator_add(_smart_onhold_animator, sd); } -// printf("b %i %i\n", sd->down.hold_x, sd->down.hold_y); + // printf("b %i %i\n", sd->down.hold_x, sd->down.hold_y); } else { @@ -2230,7 +2410,7 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj __UNUSED__, void * } } } - } + } } } @@ -2261,12 +2441,15 @@ _smart_scrollbar_reset(Smart_Data *sd) edje_object_part_drag_value_set(sd->edje_obj, "elm.dragable.hbar", 0.0, 0.0); if ((!sd->child_obj) && (!sd->extern_pan)) { - edje_object_part_drag_size_set(sd->edje_obj, "elm.dragable.vbar", 1.0, 1.0); - edje_object_part_drag_size_set(sd->edje_obj, "elm.dragable.hbar", 1.0, 1.0); + edje_object_part_drag_size_set(sd->edje_obj, "elm.dragable.vbar", 1.0, 1.0); + edje_object_part_drag_size_set(sd->edje_obj, "elm.dragable.hbar", 1.0, 1.0); + } + if (sd->pan_obj) + { + sd->pan_func.min_get(sd->pan_obj, &minx, &miny); + sd->pan_func.get(sd->pan_obj, &px, &py); + sd->pan_func.set(sd->pan_obj, minx, miny); } - sd->pan_func.min_get(sd->pan_obj, &minx, &miny); - sd->pan_func.get(sd->pan_obj, &px, &py); - sd->pan_func.set(sd->pan_obj, minx, miny); if ((px != minx) || (py != miny)) edje_object_signal_emit(sd->edje_obj, "elm,action,scroll", "elm"); } @@ -2275,52 +2458,53 @@ static int _smart_scrollbar_bar_v_visibility_adjust(Smart_Data *sd) { int scroll_v_vis_change = 0; - Evas_Coord h, vw, vh; + Evas_Coord h, vw = 0, vh = 0; h = sd->child.h; - evas_object_geometry_get(sd->pan_obj, NULL, NULL, &vw, &vh); + if (sd->pan_obj) + evas_object_geometry_get(sd->pan_obj, NULL, NULL, &vw, &vh); if (sd->vbar_visible) { - if (sd->vbar_flags == ELM_SMART_SCROLLER_POLICY_AUTO) - { - if ((sd->child_obj) || (sd->extern_pan)) - { - if (h <= vh) - { - scroll_v_vis_change = 1; - sd->vbar_visible = 0; - } - } - else - { - scroll_v_vis_change = 1; - sd->vbar_visible = 0; - } - } - else if (sd->vbar_flags == ELM_SMART_SCROLLER_POLICY_OFF) - { - scroll_v_vis_change = 1; - sd->vbar_visible = 0; - } + if (sd->vbar_flags == ELM_SMART_SCROLLER_POLICY_AUTO) + { + if ((sd->child_obj) || (sd->extern_pan)) + { + if (h <= vh) + { + scroll_v_vis_change = 1; + sd->vbar_visible = 0; + } + } + else + { + scroll_v_vis_change = 1; + sd->vbar_visible = 0; + } + } + else if (sd->vbar_flags == ELM_SMART_SCROLLER_POLICY_OFF) + { + scroll_v_vis_change = 1; + sd->vbar_visible = 0; + } } else { - if (sd->vbar_flags == ELM_SMART_SCROLLER_POLICY_AUTO) - { - if ((sd->child_obj) || (sd->extern_pan)) - { - if (h > vh) - { - scroll_v_vis_change = 1; - sd->vbar_visible = 1; - } - } - } - else if (sd->vbar_flags == ELM_SMART_SCROLLER_POLICY_ON) - { - scroll_v_vis_change = 1; - sd->vbar_visible = 1; - } + if (sd->vbar_flags == ELM_SMART_SCROLLER_POLICY_AUTO) + { + if ((sd->child_obj) || (sd->extern_pan)) + { + if (h > vh) + { + scroll_v_vis_change = 1; + sd->vbar_visible = 1; + } + } + } + else if (sd->vbar_flags == ELM_SMART_SCROLLER_POLICY_ON) + { + scroll_v_vis_change = 1; + sd->vbar_visible = 1; + } } if (scroll_v_vis_change) { @@ -2343,52 +2527,53 @@ static int _smart_scrollbar_bar_h_visibility_adjust(Smart_Data *sd) { int scroll_h_vis_change = 0; - Evas_Coord w, vw, vh; + Evas_Coord w, vw = 0, vh = 0; w = sd->child.w; - evas_object_geometry_get(sd->pan_obj, NULL, NULL, &vw, &vh); + if (sd->pan_obj) + evas_object_geometry_get(sd->pan_obj, NULL, NULL, &vw, &vh); if (sd->hbar_visible) { - if (sd->hbar_flags == ELM_SMART_SCROLLER_POLICY_AUTO) - { - if ((sd->child_obj) || (sd->extern_pan)) - { - if (w <= vw) - { - scroll_h_vis_change = 1; - sd->hbar_visible = 0; - } - } - else - { - scroll_h_vis_change = 1; - sd->hbar_visible = 0; - } - } - else if (sd->hbar_flags == ELM_SMART_SCROLLER_POLICY_OFF) - { - scroll_h_vis_change = 1; - sd->hbar_visible = 0; - } + if (sd->hbar_flags == ELM_SMART_SCROLLER_POLICY_AUTO) + { + if ((sd->child_obj) || (sd->extern_pan)) + { + if (w <= vw) + { + scroll_h_vis_change = 1; + sd->hbar_visible = 0; + } + } + else + { + scroll_h_vis_change = 1; + sd->hbar_visible = 0; + } + } + else if (sd->hbar_flags == ELM_SMART_SCROLLER_POLICY_OFF) + { + scroll_h_vis_change = 1; + sd->hbar_visible = 0; + } } else { - if (sd->hbar_flags == ELM_SMART_SCROLLER_POLICY_AUTO) - { - if ((sd->child_obj) || (sd->extern_pan)) - { - if (w > vw) - { - scroll_h_vis_change = 1; - sd->hbar_visible = 1; - } - } - } - else if (sd->hbar_flags == ELM_SMART_SCROLLER_POLICY_ON) - { - scroll_h_vis_change = 1; - sd->hbar_visible = 1; - } + if (sd->hbar_flags == ELM_SMART_SCROLLER_POLICY_AUTO) + { + if ((sd->child_obj) || (sd->extern_pan)) + { + if (w > vw) + { + scroll_h_vis_change = 1; + sd->hbar_visible = 1; + } + } + } + else if (sd->hbar_flags == ELM_SMART_SCROLLER_POLICY_ON) + { + scroll_h_vis_change = 1; + sd->hbar_visible = 1; + } } if (scroll_h_vis_change) { @@ -2403,7 +2588,7 @@ _smart_scrollbar_bar_h_visibility_adjust(Smart_Data *sd) } else edje_object_signal_emit(sd->edje_obj, "elm,action,hide,hbar", "elm"); - _smart_scrollbar_size_adjust(sd); + _smart_scrollbar_size_adjust(sd); } return scroll_h_vis_change; } @@ -2417,8 +2602,8 @@ _smart_scrollbar_bar_visibility_adjust(Smart_Data *sd) changed |= _smart_scrollbar_bar_v_visibility_adjust(sd); if (changed) { - _smart_scrollbar_bar_h_visibility_adjust(sd); - _smart_scrollbar_bar_v_visibility_adjust(sd); + _smart_scrollbar_bar_h_visibility_adjust(sd); + _smart_scrollbar_bar_v_visibility_adjust(sd); } } @@ -2427,67 +2612,67 @@ _smart_scrollbar_size_adjust(Smart_Data *sd) { if ((sd->child_obj) || (sd->extern_pan)) { - Evas_Coord x, y, w, h, mx = 0, my = 0, vw = 0, vh = 0, px, py, minx = 0, miny = 0; - double vx, vy, size; - - edje_object_part_geometry_get(sd->edje_obj, "elm.swallow.content", - NULL, NULL, &vw, &vh); - w = sd->child.w; - if (w < 1) w = 1; - size = (double)vw / (double)w; - if (size > 1.0) - { - size = 1.0; - edje_object_part_drag_value_set(sd->edje_obj, "elm.dragable.hbar", 0.0, 0.0); - } - edje_object_part_drag_size_set(sd->edje_obj, "elm.dragable.hbar", size, 1.0); - - h = sd->child.h; - if (h < 1) h = 1; - size = (double)vh / (double)h; - if (size > 1.0) - { - size = 1.0; - edje_object_part_drag_value_set(sd->edje_obj, "elm.dragable.vbar", 0.0, 0.0); - } - edje_object_part_drag_size_set(sd->edje_obj, "elm.dragable.vbar", 1.0, size); - - edje_object_part_drag_value_get(sd->edje_obj, "elm.dragable.hbar", &vx, NULL); - edje_object_part_drag_value_get(sd->edje_obj, "elm.dragable.vbar", NULL, &vy); - sd->pan_func.max_get(sd->pan_obj, &mx, &my); - sd->pan_func.min_get(sd->pan_obj, &minx, &miny); - x = vx * mx + minx; - y = vy * my + miny; - - edje_object_part_drag_step_set(sd->edje_obj, "elm.dragable.hbar", (double)sd->step.x / (double)w, 0.0); - edje_object_part_drag_step_set(sd->edje_obj, "elm.dragable.vbar", 0.0, (double)sd->step.y / (double)h); - if (sd->page.x > 0) - edje_object_part_drag_page_set(sd->edje_obj, "elm.dragable.hbar", (double)sd->page.x / (double)w, 0.0); - else - edje_object_part_drag_page_set(sd->edje_obj, "elm.dragable.hbar", -((double)sd->page.x * ((double)vw / (double)w)) / 100.0, 0.0); - if (sd->page.y > 0) - edje_object_part_drag_page_set(sd->edje_obj, "elm.dragable.vbar", 0.0, (double)sd->page.y / (double)h); - else - edje_object_part_drag_page_set(sd->edje_obj, "elm.dragable.vbar", 0.0, -((double)sd->page.y * ((double)vh / (double)h)) / 100.0); - - sd->pan_func.get(sd->pan_obj, &px, &py); + Evas_Coord x, y, w, h, mx = 0, my = 0, vw = 0, vh = 0, px, py, minx = 0, miny = 0; + double vx, vy, size; + + edje_object_part_geometry_get(sd->edje_obj, "elm.swallow.content", + NULL, NULL, &vw, &vh); + w = sd->child.w; + if (w < 1) w = 1; + size = (double)vw / (double)w; + if (size > 1.0) + { + size = 1.0; + edje_object_part_drag_value_set(sd->edje_obj, "elm.dragable.hbar", 0.0, 0.0); + } + edje_object_part_drag_size_set(sd->edje_obj, "elm.dragable.hbar", size, 1.0); + + h = sd->child.h; + if (h < 1) h = 1; + size = (double)vh / (double)h; + if (size > 1.0) + { + size = 1.0; + edje_object_part_drag_value_set(sd->edje_obj, "elm.dragable.vbar", 0.0, 0.0); + } + edje_object_part_drag_size_set(sd->edje_obj, "elm.dragable.vbar", 1.0, size); + + edje_object_part_drag_value_get(sd->edje_obj, "elm.dragable.hbar", &vx, NULL); + edje_object_part_drag_value_get(sd->edje_obj, "elm.dragable.vbar", NULL, &vy); + sd->pan_func.max_get(sd->pan_obj, &mx, &my); + sd->pan_func.min_get(sd->pan_obj, &minx, &miny); + x = vx * mx + minx; + y = vy * my + miny; + + edje_object_part_drag_step_set(sd->edje_obj, "elm.dragable.hbar", (double)sd->step.x / (double)w, 0.0); + edje_object_part_drag_step_set(sd->edje_obj, "elm.dragable.vbar", 0.0, (double)sd->step.y / (double)h); + if (sd->page.x > 0) + edje_object_part_drag_page_set(sd->edje_obj, "elm.dragable.hbar", (double)sd->page.x / (double)w, 0.0); + else + edje_object_part_drag_page_set(sd->edje_obj, "elm.dragable.hbar", -((double)sd->page.x * ((double)vw / (double)w)) / 100.0, 0.0); + if (sd->page.y > 0) + edje_object_part_drag_page_set(sd->edje_obj, "elm.dragable.vbar", 0.0, (double)sd->page.y / (double)h); + else + edje_object_part_drag_page_set(sd->edje_obj, "elm.dragable.vbar", 0.0, -((double)sd->page.y * ((double)vh / (double)h)) / 100.0); + + sd->pan_func.get(sd->pan_obj, &px, &py); if (vx != mx) x = px; if (vy != my) y = py; - sd->pan_func.set(sd->pan_obj, x, y); -// if ((px != 0) || (py != 0)) -// edje_object_signal_emit(sd->edje_obj, "elm,action,scroll", "elm"); + sd->pan_func.set(sd->pan_obj, x, y); + // if ((px != 0) || (py != 0)) + // edje_object_signal_emit(sd->edje_obj, "elm,action,scroll", "elm"); } else { - Evas_Coord px = 0, py = 0, minx = 0, miny = 0; + Evas_Coord px = 0, py = 0, minx = 0, miny = 0; - edje_object_part_drag_size_set(sd->edje_obj, "elm.dragable.vbar", 1.0, 1.0); - edje_object_part_drag_size_set(sd->edje_obj, "elm.dragable.hbar", 1.0, 1.0); + edje_object_part_drag_size_set(sd->edje_obj, "elm.dragable.vbar", 1.0, 1.0); + edje_object_part_drag_size_set(sd->edje_obj, "elm.dragable.hbar", 1.0, 1.0); sd->pan_func.min_get(sd->pan_obj, &minx, &miny); - sd->pan_func.get(sd->pan_obj, &px, &py); - sd->pan_func.set(sd->pan_obj, minx, miny); + sd->pan_func.get(sd->pan_obj, &px, &py); + sd->pan_func.set(sd->pan_obj, minx, miny); if ((px != minx) || (py != miny)) - edje_object_signal_emit(sd->edje_obj, "elm,action,scroll", "elm"); + edje_object_signal_emit(sd->edje_obj, "elm,action,scroll", "elm"); } _smart_scrollbar_bar_visibility_adjust(sd); } @@ -2530,13 +2715,12 @@ _smart_add(Evas_Object *obj) sd->bounce_vert = 1; sd->one_dir_at_a_time = 1; - sd->momentum_animator_disabled = 0; - sd->bounce_animator_disabled = 0; - + sd->momentum_animator_disabled = EINA_FALSE; + sd->bounce_animator_disabled = EINA_FALSE; + o = edje_object_add(evas_object_evas_get(obj)); evas_object_propagate_events_set(o, 0); sd->edje_obj = o; - // FIXME: null parent obj ... :( elm_smart_scroller_object_theme_set(NULL, obj, "scroller", "base", "default"); edje_object_signal_callback_add(o, "drag", "elm.dragable.vbar", _smart_edje_drag_v, sd); edje_object_signal_callback_add(o, "drag,start", "elm.dragable.vbar", _smart_edje_drag_v_start, sd); @@ -2604,7 +2788,7 @@ _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) sd->w = w; sd->h = h; _smart_reconfigure(sd); - elm_smart_scroller_child_region_set(obj, sd->wx, sd->wy, sd->ww, sd->wh); + _elm_smart_scroller_wanted_region_set(obj); } static void @@ -2653,28 +2837,27 @@ _smart_init(void) { if (_smart) return; { - static const Evas_Smart_Class sc = - { - SMART_NAME, - EVAS_SMART_CLASS_VERSION, - _smart_add, - _smart_del, - _smart_move, - _smart_resize, - _smart_show, - _smart_hide, - _smart_color_set, - _smart_clip_set, - _smart_clip_unset, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL - }; - _smart = evas_smart_class_new(&sc); + static const Evas_Smart_Class sc = + { + SMART_NAME, + EVAS_SMART_CLASS_VERSION, + _smart_add, + _smart_del, + _smart_move, + _smart_resize, + _smart_show, + _smart_hide, + _smart_color_set, + _smart_clip_set, + _smart_clip_unset, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL + }; + _smart = evas_smart_class_new(&sc); } } -