[Scroller] Fix the region_show/region_bring_in don't have a limit at a paging movement.
[framework/uifw/elementary.git] / src / lib / elm_interface_scrollable.c
index e764a90..acf5ffa 100644 (file)
@@ -382,6 +382,11 @@ static const char SCROLL_SMART_NAME[] = "elm_scroll";
 static void _elm_scroll_scroll_bar_size_adjust(
   Elm_Scrollable_Smart_Interface_Data *);
 static void _elm_scroll_wanted_region_set(Evas_Object *);
+static Eina_Bool _paging_is_enabled(Elm_Scrollable_Smart_Interface_Data *sid);
+static Evas_Coord _elm_scroll_page_x_get(
+   Elm_Scrollable_Smart_Interface_Data *sid, int offset, Eina_Bool limit);
+static Evas_Coord _elm_scroll_page_y_get(
+   Elm_Scrollable_Smart_Interface_Data *sid, int offset, Eina_Bool limit);
 static void _elm_scroll_content_pos_get(const Evas_Object *,
                                         Evas_Coord *,
                                         Evas_Coord *);
@@ -1342,6 +1347,40 @@ _elm_scroll_content_pos_set(Evas_Object *obj,
         if (y - miny > my) y = my + miny;
      }
 
+   if (((!_elm_config->thumbscroll_bounce_enable) ||
+        (!sid->bounce_horiz)) && (sid->scrollto.x.animator) &&
+       ((px != x) && ((x == minx) || (x == (mx + minx)))))
+     {
+        ecore_animator_del(sid->scrollto.x.animator);
+        sid->scrollto.x.animator = NULL;
+     }
+
+   if (((!_elm_config->thumbscroll_bounce_enable) ||
+        (!sid->bounce_vert)) && (sid->scrollto.y.animator) &&
+       ((py != y) && ((y == miny) || (y == (my + miny)))))
+     {
+        ecore_animator_del(sid->scrollto.y.animator);
+        sid->scrollto.y.animator = NULL;
+     }
+
+   if (((!_elm_config->thumbscroll_bounce_enable) ||
+        ((!sid->bounce_horiz) && (!sid->bounce_vert))) &&
+       (sid->down.momentum_animator) &&
+       ((((px != x) && ((x == minx) || (x == (mx + minx)))) && (py == y)) ||
+       (((py != y) && ((y == miny) || (y == (my + miny)))) && (px == x))))
+     {
+        ecore_animator_del(sid->down.momentum_animator);
+        sid->down.momentum_animator = NULL;
+        sid->down.bounce_x_hold = EINA_FALSE;
+        sid->down.bounce_y_hold = EINA_FALSE;
+        sid->down.ax = 0;
+        sid->down.ay = 0;
+        sid->down.pdx = 0;
+        sid->down.pdy = 0;
+        if (sid->content_info.resized)
+          _elm_scroll_wanted_region_set(sid->obj);
+     }
+
    psd->api->pos_set(sid->pan_obj, x, y);
    psd->api->pos_get(sid->pan_obj, &spx, &spy);
 
@@ -1566,10 +1605,18 @@ _elm_scroll_content_region_show_internal(Evas_Object *obj,
           _elm_scroll_wanted_region_set(sid->obj);
      }
 
-   x = nx;
+   if (_paging_is_enabled(sid))
+     {
+        x = _elm_scroll_page_x_get(sid, nx - px, EINA_FALSE);
+        y = _elm_scroll_page_y_get(sid, ny - py, EINA_FALSE);
+     }
+   else
+     {
+        x = nx;
+        y = ny;
+     }
    if ((x + pw) > cw) x = cw - pw;
    if (x < minx) x = minx;
-   y = ny;
    if ((y + ph) > ch) y = ch - ph;
    if (y < miny) y = miny;
 
@@ -1845,9 +1892,9 @@ _elm_scroll_momentum_animator(void *data)
 
 static Evas_Coord
 _elm_scroll_page_x_get(Elm_Scrollable_Smart_Interface_Data *sid,
-                       int offset)
+                       int offset, Eina_Bool limit)
 {
-   Evas_Coord x, y, w, h, cw, ch, minx = 0;
+   Evas_Coord x, y, w, h, dx, cw, ch, minx = 0;
 
    if (!sid->pan_obj) return 0;
 
@@ -1858,10 +1905,21 @@ _elm_scroll_page_x_get(Elm_Scrollable_Smart_Interface_Data *sid,
    psd->api->content_size_get(sid->pan_obj, &cw, &ch);
    psd->api->pos_min_get(sid->pan_obj, &minx, NULL);
 
-   x += offset;
-
    if (sid->pagerel_h > 0.0)
      sid->pagesize_h = w * sid->pagerel_h;
+
+   if (!limit)
+     x += offset;
+   else
+     {
+        dx = (sid->pagesize_h * ((double)sid->page_limit_h - 0.5));
+
+        if (offset > 0)
+          x += (abs(offset) < dx ? offset : dx);
+        else
+          x += (abs(offset) < dx ? offset : -dx);
+     }
+
    if (sid->pagesize_h > 0)
      {
         x = x + (sid->pagesize_h * 0.5);
@@ -1876,9 +1934,9 @@ _elm_scroll_page_x_get(Elm_Scrollable_Smart_Interface_Data *sid,
 
 static Evas_Coord
 _elm_scroll_page_y_get(Elm_Scrollable_Smart_Interface_Data *sid,
-                       int offset)
+                       int offset, Eina_Bool limit)
 {
-   Evas_Coord x, y, w, h, cw, ch, miny = 0;
+   Evas_Coord x, y, w, h, dy, cw, ch, miny = 0;
 
    if (!sid->pan_obj) return 0;
 
@@ -1889,10 +1947,21 @@ _elm_scroll_page_y_get(Elm_Scrollable_Smart_Interface_Data *sid,
    psd->api->content_size_get(sid->pan_obj, &cw, &ch);
    psd->api->pos_min_get(sid->pan_obj, NULL, &miny);
 
-   y += offset;
-
    if (sid->pagerel_v > 0.0)
      sid->pagesize_v = h * sid->pagerel_v;
+
+   if (!limit)
+     y += offset;
+   else
+     {
+        dy = (sid->pagesize_v * ((double)sid->page_limit_v - 0.5));
+
+        if (offset > 0)
+          y += (abs(offset) < dy ? offset : dy);
+        else
+          y += (abs(offset) < dy ? offset : -dy);
+     }
+
    if (sid->pagesize_v > 0)
      {
         y = y + (sid->pagesize_v * 0.5);
@@ -2196,7 +2265,7 @@ _elm_scroll_mouse_up_event_cb(void *data,
                       (!elm_widget_drag_child_locked_x_get
                          (sid->obj)))
                     {
-                       pgx = _elm_scroll_page_x_get(sid, ox);
+                       pgx = _elm_scroll_page_x_get(sid, ox, EINA_TRUE);
                        if (pgx != x)
                          {
                             ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
@@ -2208,7 +2277,7 @@ _elm_scroll_mouse_up_event_cb(void *data,
                       (!elm_widget_drag_child_locked_y_get
                          (sid->obj)))
                     {
-                       pgy = _elm_scroll_page_y_get(sid, oy);
+                       pgy = _elm_scroll_page_y_get(sid, oy, EINA_TRUE);
                        if (pgy != y)
                          {
                             ev->event_flags |= EVAS_EVENT_FLAG_ON_SCROLL;
@@ -2231,7 +2300,7 @@ _elm_scroll_mouse_up_event_cb(void *data,
                       (!elm_widget_drag_child_locked_x_get
                          (sid->obj)))
                     {
-                       pgx = _elm_scroll_page_x_get(sid, ox);
+                       pgx = _elm_scroll_page_x_get(sid, ox, EINA_TRUE);
                        if (pgx != x)
                          _elm_scroll_scroll_to_x
                            (sid, _elm_config->page_scroll_friction, pgx);
@@ -2240,7 +2309,7 @@ _elm_scroll_mouse_up_event_cb(void *data,
                       (!elm_widget_drag_child_locked_y_get
                          (sid->obj)))
                     {
-                       pgy = _elm_scroll_page_y_get(sid, oy);
+                       pgy = _elm_scroll_page_y_get(sid, oy, EINA_TRUE);
                        if (pgy != y)
                          _elm_scroll_scroll_to_y
                            (sid, _elm_config->page_scroll_friction, pgy);
@@ -2894,8 +2963,8 @@ _elm_scroll_page_adjust(Elm_Scrollable_Smart_Interface_Data *sid)
 
    _elm_scroll_content_viewport_size_get(sid->obj, &w, &h);
 
-   x = _elm_scroll_page_x_get(sid, 0);
-   y = _elm_scroll_page_y_get(sid, 0);
+   x = _elm_scroll_page_x_get(sid, 0, EINA_TRUE);
+   y = _elm_scroll_page_y_get(sid, 0, EINA_TRUE);
 
    _elm_scroll_content_region_set(sid->obj, x, y, w, h);
 }
@@ -3729,7 +3798,7 @@ _elm_scroll_repeat_events_set(Evas_Object *obj,
 static Eina_Bool
 _elm_scroll_repeat_events_get(Evas_Object *obj)
 {
-   ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
+   ELM_SCROLL_IFACE_DATA_GET_OR_RETURN_VAL(obj, sid, EINA_FALSE);
 
    return evas_object_repeat_events_get(sid->event_rect);
 }
@@ -3819,6 +3888,28 @@ _elm_scroll_paging_get(const Evas_Object *obj,
 }
 
 static void
+_elm_scroll_page_scroll_limit_set(const Evas_Object *obj,
+                                  int page_limit_h,
+                                  int page_limit_v)
+{
+   ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
+
+   sid->page_limit_h = page_limit_h;
+   sid->page_limit_v = page_limit_v;
+}
+
+static void
+_elm_scroll_page_scroll_limit_get(const Evas_Object *obj,
+                                  int *page_limit_h,
+                                  int *page_limit_v)
+{
+   ELM_SCROLL_IFACE_DATA_GET_OR_RETURN(obj, sid);
+
+   if (page_limit_h) *page_limit_h = sid->page_limit_h;
+   if (page_limit_v) *page_limit_v = sid->page_limit_v;
+}
+
+static void
 _elm_scroll_current_page_get(const Evas_Object *obj,
                              int *pagenumber_h,
                              int *pagenumber_v)
@@ -3974,6 +4065,8 @@ _elm_scroll_interface_add(Evas_Object *obj)
    sid->step.y = 32;
    sid->page.x = -50;
    sid->page.y = -50;
+   sid->page_limit_h = 9999;
+   sid->page_limit_v = 9999;
    sid->hbar_flags = ELM_SCROLLER_POLICY_AUTO;
    sid->vbar_flags = ELM_SCROLLER_POLICY_AUTO;
    sid->hbar_visible = EINA_TRUE;
@@ -4071,6 +4164,8 @@ EAPI const Elm_Scrollable_Smart_Interface ELM_SCROLLABLE_IFACE =
    _elm_scroll_bounce_allow_get,
    _elm_scroll_paging_set,
    _elm_scroll_paging_get,
+   _elm_scroll_page_scroll_limit_set,
+   _elm_scroll_page_scroll_limit_get,
    _elm_scroll_current_page_get,
    _elm_scroll_last_page_get,
    _elm_scroll_page_show,