[*][Scroller] merge from upstream revision 64051, but didn't accept data/theme/widget...
[framework/uifw/elementary.git] / src / lib / els_scroller.c
index d96881f..484efdb 100644 (file)
@@ -472,6 +472,8 @@ _smart_momentum_end(Smart_Data *sd)
         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;
      }
@@ -1004,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))
      {
@@ -1327,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
@@ -1725,7 +1733,7 @@ _smart_hold_animator(void *data)
    fx = sd->down.hold_x;
    fy = sd->down.hold_y;
 
-   if (_elm_config->scroll_smooth_time_interval > 0.0)
+   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
@@ -1834,10 +1842,13 @@ _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;
+   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
@@ -1889,7 +1900,7 @@ _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; // magic number! just trial and error shows this makes it behave "nicer" and not run off at high speed all the time
+                       at /= _elm_config->thumbscroll_sensitivity_friction;
                        dx = ev->canvas.x - ax;
                        dy = ev->canvas.y - ay;
                        if (at > 0)
@@ -1898,14 +1909,20 @@ _smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *ev
                             if ((_elm_config->thumbscroll_friction > 0.0) &&
                                 (vel > _elm_config->thumbscroll_momentum_threshold))
                               {
+                                 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)))
-                                   sd->down.dx += (double)sd->down.pdx * 1.5; // FIXME: * 1.5 - probably should be config
+                                   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)))
-                                   sd->down.dy += (double)sd->down.pdy * 1.5; // FIXME: * 1.5 - probably should be config
+                                   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)) ||
@@ -1921,6 +1938,19 @@ _smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *ev
                                    }
                                  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)
+                                   {
+                                      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);
+                                   }
                                  sd->down.pdx = sd->down.dx;
                                  sd->down.pdy = sd->down.dy;
                                  ox = -sd->down.dx;
@@ -1942,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
                     {
@@ -2003,11 +2028,11 @@ _smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *ev
                             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)
                {