Looping Support for genlist 74/196074/7
authorGodly T.Alias <godlytalias@yahoo.co.in>
Fri, 21 Dec 2018 07:50:14 +0000 (13:20 +0530)
committerWoochanlee <wc0917.lee@samsung.com>
Mon, 11 Feb 2019 06:53:32 +0000 (15:53 +0900)
Change-Id: I2c458e78b54573f9d0ad12776347212483deab74
Signed-off-by: Godly T.Alias <godlytalias@yahoo.co.in>
src/lib/elm_genlist.c
src/lib/elm_interface_scrollable.c
src/lib/elm_interface_scrollable.h
src/mobile_lib/elm_genlist.c

index 7ca093c50a2c56fc3729af50ee91a0c75f64c0af..5e3156e97a6189a93c33e4bb63eec8b4f582c311 100644 (file)
@@ -244,11 +244,22 @@ EOLIAN static void
 _elm_genlist_pan_elm_pan_pos_max_get(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord *x, Evas_Coord *y)
 {
    Evas_Coord ow, oh;
+   //TIZEN_ONLY(20181127):For loop enabled case max pan position should be equal to height
+   Eina_Bool loop_v = EINA_FALSE;
+   eo_do(psd->wsd->obj, elm_interface_scrollable_loop_get(NULL, &loop_v));
+   //
 
    evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
    ow = psd->wsd->minw - ow;
    if (ow < 0) ow = 0;
-   oh = psd->wsd->minh - oh;
+   //PTIZEN_ONLY(20181127):For loop enabled case max pan position should be equal to height
+   //oh = psd->wsd->minh - oh;
+   if (loop_v)
+     oh = psd->wsd->minh;
+   else
+     oh = psd->wsd->minh - oh;
+   //
+
    if (oh < 0) oh = 0;
    if (x) *x = ow;
    if (y) *y = oh;
@@ -2435,7 +2446,7 @@ _item_block_position(Item_Block *itb,
 {
    Elm_Gen_Item *it;
    const Eina_List *l;
-   Eina_Bool vis = EINA_FALSE;
+   Eina_Bool vis = EINA_FALSE, loop_v = EINA_FALSE;
    Evas_Coord y = 0, ox, oy, ow, oh, cvx, cvy, cvw, cvh;
    Elm_Genlist_Data *sd = NULL;
 
@@ -2462,6 +2473,10 @@ _item_block_position(Item_Block *itb,
         it->item->scrl_x = itb->x + it->x - sd->pan_x + ox;
         it->item->scrl_y = itb->y + it->y - sd->pan_y + oy;
 
+        eo_do(sd->obj, elm_interface_scrollable_loop_get(NULL, &loop_v));
+        if (loop_v && GL_IT(it)->scrl_y < 0 && (sd->pan_y > (sd->minh - cvh)))
+          GL_IT(it)->scrl_y = it->y + itb->y - (sd->pan_y - sd->minh) + oy;
+
         vis = (ELM_RECTS_INTERSECT
                  (it->item->scrl_x, it->item->scrl_y, it->item->w, it->item->h,
                  cvx, cvy, cvw, cvh));
@@ -2550,6 +2565,7 @@ _elm_genlist_pan_evas_object_smart_calculate(Eo *obj, Elm_Genlist_Pan_Data *psd)
 {
    Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
    Evas_Coord vx = 0, vy = 0, vw = 0, vh = 0;
+   Eina_Bool loop_v = EINA_FALSE;
    Elm_Gen_Item *git;
    Item_Block *itb;
    Eina_List *l;
@@ -2558,6 +2574,7 @@ _elm_genlist_pan_evas_object_smart_calculate(Eo *obj, Elm_Genlist_Pan_Data *psd)
    Elm_Genlist_Data *sd = psd->wsd;
 
    evas_event_freeze(evas_object_evas_get(obj));
+   eo_do(sd->obj, elm_interface_scrollable_loop_get(NULL, &loop_v));
 
    if (sd->pan_changed)
      {
@@ -2597,10 +2614,24 @@ _elm_genlist_pan_evas_object_smart_calculate(Eo *obj, Elm_Genlist_Pan_Data *psd)
                _item_block_realize(itb);
              _item_block_position(itb, in);
           }
-        else
+        else if (loop_v && sd->pan_y > (sd->minh - cvh))
           {
-             if (itb->realized) _item_block_unrealize(itb);
+             if (ELM_RECTS_INTERSECT(itb->x - sd->pan_x + ox,
+                                     itb->y - (sd->pan_y - sd->minh) + oy,
+                                     itb->w, itb->h,
+                                     cvx, cvy, cvw, cvh))
+               {
+                  if ((!itb->realized) || (itb->changed))
+                    _item_block_realize(itb);
+                  _item_block_position(itb, in);
+               }
+             else
+               {
+                  if (itb->realized) _item_block_unrealize(itb);
+               }
           }
+        else
+          if (itb->realized) _item_block_unrealize(itb);
         in += itb->count;
      }
    if ((!sd->reorder_it) || (sd->reorder_pan_move))
index 75ca2c3e222ff3c7ebf05392fab293bfeebe2ab7..612895fd8cf1c0347c6ee992ac5a67a1383ca6fe 100644 (file)
@@ -2381,6 +2381,9 @@ _elm_scroll_momentum_animator(void *data)
              sid->down.by = sid->down.by0 - dy + sid->down.b0y;
              y = py;
           }
+        if (sid->loop_v && y < 0)
+          y = sid->content_info.h + y;
+
         eo_do(sid->obj, elm_interface_scrollable_content_pos_set(x, y, EINA_TRUE));
         _elm_scroll_wanted_coordinates_update(sid, x, y);
         eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&maxx, &maxy));
@@ -2391,10 +2394,10 @@ _elm_scroll_momentum_animator(void *data)
              if (x <= minx) no_bounce_x_end = EINA_TRUE;
              if (!sid->loop_h && (x - minx) >= maxx) no_bounce_x_end = EINA_TRUE;
           }
-        if (!_elm_config->thumbscroll_bounce_enable || !sid->bounce_vert)
+        if (!sid->loop_v && (!_elm_config->thumbscroll_bounce_enable || !sid->bounce_vert))
           {
              if (y <= miny) no_bounce_y_end = EINA_TRUE;
-             if (!sid->loop_v && (y - miny) >= maxy) no_bounce_y_end = EINA_TRUE;
+             if ((y - miny) >= maxy) no_bounce_y_end = EINA_TRUE;
           }
         if ((dt >= 1.0) ||
             ((sid->down.bounce_x_hold) && (sid->down.bounce_y_hold)) ||
@@ -2570,8 +2573,23 @@ _elm_scroll_scroll_to_y_animator(void *data)
    tt = 1.0 - tt;
    tt = 1.0 - (tt * tt);
    eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
-   py = (sid->scrollto.y.start * (1.0 - tt)) +
-     (sid->scrollto.y.end * tt);
+   if (!sid->loop_v)
+     py = (sid->scrollto.y.start * (1.0 - tt)) +
+              (sid->scrollto.y.end * tt);
+   else
+     {
+        Evas_Coord ch = 0;
+        eo_do(sid->pan_obj, elm_obj_pan_content_size_get(NULL, &ch));
+        if (sid->y_forward_scroll)
+          {
+             py = (sid->scrollto.y.start * (1.0 - tt)) +
+                (ch + sid->scrollto.y.end)*tt;//works for neg value of y_end also becuase in looping case neg value starts from bottom
+             if (py > ch) py %= ch; //needed when y_end is positive
+          }
+        else
+           py = (sid->scrollto.y.start * (1.0 - tt)) +
+                    (sid->scrollto.y.end * tt);
+     }
    if (t >= sid->scrollto.y.t_end)
      {
         py = sid->scrollto.y.end;
@@ -2579,6 +2597,7 @@ _elm_scroll_scroll_to_y_animator(void *data)
         sid->down.sy = py;
         sid->down.y = sid->down.history[0].y;
         sid->down.pdy = 0;
+        sid->y_forward_scroll = EINA_FALSE;
         _elm_scroll_wanted_coordinates_update(sid, px, py);
         sid->scrollto.y.animator = NULL;
         if ((!sid->scrollto.x.animator) && (!sid->down.bounce_x_animator))
@@ -2617,6 +2636,21 @@ _elm_scroll_scroll_to_y(Elm_Scrollable_Smart_Interface_Data *sid,
    sid->scrollto.y.end = pos_y;
    sid->scrollto.y.t_start = t;
    sid->scrollto.y.t_end = t + t_in;
+   //PRODUCT_ONLY(20181105): bring_in animation should happen
+   if (sid->loop_v)
+     {
+        Evas_Coord ch = 0, for_dist = 0, back_dist = 0;
+        eo_do(sid->pan_obj, elm_obj_pan_content_size_get(NULL, &ch));
+        back_dist = abs(sid->scrollto.y.end - sid->scrollto.y.start);
+        if (sid->scrollto.y.end < 0)
+           for_dist = abs((ch + sid->scrollto.y.end) - sid->scrollto.y.start);
+        else
+           for_dist = abs(ch - sid->scrollto.y.start) + sid->scrollto.y.end;
+        if (for_dist <= back_dist)
+           sid->y_forward_scroll = EINA_TRUE;
+        else
+           sid->y_forward_scroll = EINA_FALSE;
+     }
    if (!sid->scrollto.y.animator)
      {
         sid->scrollto.y.animator =
@@ -2855,9 +2889,51 @@ _elm_scroll_mouse_up_event_cb(void *data,
                                                          sid->down.extra_time), 0);
                                  pos_y = _round(pos_y * (_elm_config->thumbscroll_friction +
                                                          sid->down.extra_time), 0);
+                                 if (pos_x < 0)
+                                   {
+                                      if ((px - pos_x) > mx)
+                                      pos_x = px - mx;
+                                   }
+                                 else
+                                   {
+                                      if ((px - pos_x) < minx)
+                                      pos_x = px - minx;
+                                   }
+                                 if (!sid->loop_v)
+                                   {
+                                      if (pos_y < 0)
+                                        {
+                                           if ((py - pos_y) > my)
+                                             pos_y = py - my;
+                                        }
+                                      else
+                                        {
+                                           if ((py - pos_y) < miny)
+                                             pos_y = py - miny;
+                                        }
+                                   }
+                                 //PRODUCT_ONLY(20181115): scroll distance have to be less than content size
+                                 else if (sid->loop_v && abs(pos_y) > sid->content_info.h)
+                                   {
+                                      Evas_Coord final_pos_y = pos_y % sid->content_info.h;
+                                      if (pos_y > 0)
+                                        pos_y = final_pos_y;
+                                      else
+                                        pos_y = -final_pos_y;
+                                   }
+                                 //
 
                                  eo_do(sid->pan_obj, elm_obj_pan_pos_adjust(&pos_x, &pos_y));
 
+                                 //PRODUCT_ONLY(20181511): take the direction of flick always for scroll in loop case
+                                 if (sid->loop_v)
+                                   {
+                                      if (pos_y > 0 && dy < 0)
+                                        pos_y = pos_y - sid->content_info.h;
+                                      else if (pos_y < 0 && dy > 0)
+                                        pos_y = sid->content_info.h + pos_y;
+                                   }
+                                 //
                                  // adjusted position using to _elm_scroll_momentum_animator()
                                  sid->down.dx = pos_x;
                                  sid->down.dy = pos_y;
@@ -5278,8 +5354,8 @@ _elm_interface_scrollable_loop_set(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Int
 EOLIAN static void
 _elm_interface_scrollable_loop_get(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Eina_Bool *loop_h, Eina_Bool *loop_v)
 {
-   *loop_h = sid->loop_h;
-   *loop_v = sid->loop_v;
+   if (loop_h) *loop_h = sid->loop_h;
+   if (loop_v) *loop_v = sid->loop_v;
 }
 
 EOLIAN static void
index b4ce897bc00cd10fa41a242ff61eba6c0b51a651..c032a719b65ce341cb1bbba9a942f38c90904a4a 100644 (file)
@@ -257,6 +257,7 @@ struct _Elm_Scrollable_Smart_Interface_Data
    Eina_Bool  loop_h : 1;
    Eina_Bool  loop_v : 1;
 
+   Eina_Bool  y_forward_scroll : 1;
    struct
    {
       Ecore_Job *bar_size_adjust;
index 94e75f690b46666141dd5978f7c8ade3ddb8d759..e8555c6dc964de1e29958877ce5c62f445577560 100644 (file)
@@ -510,13 +510,35 @@ _elm_genlist_pos_adjust_xy_item_get(const Evas_Object *obj,
 
    ELM_GENLIST_CHECK(obj) NULL;
    ELM_GENLIST_DATA_GET(obj, sd);
+   Evas_Coord oh, itb_y, yy;
+   Eina_Bool loop_v = EINA_FALSE;
 
+   yy = y;
+   eo_do(sd->obj, elm_interface_scrollable_loop_get(NULL, &loop_v));
+   evas_object_geometry_get(obj, NULL, NULL, NULL, &oh);
    EINA_INLIST_FOREACH(sd->blocks, itb)
      {
         Eina_List *l = NULL;
         Elm_Gen_Item *it;
+        //PRODUCT_ONLY(20181511): Pan pos calculation for looping cases
+        itb_y = itb->y - sd->pan_y;
+        y = yy;
+
+        //get item at (x,y) position if looping is enabled
+        if (loop_v && (sd->pan_y + y) > sd->minh)
+          {
+             y = y - (sd->minh - sd->pan_y);
+             itb_y = itb->y;
+          }
+        else if (loop_v && (sd->pan_y + y) < 0)
+          {
+             y = sd->minh + y + sd->pan_y;
+             itb_y = itb->y;
+          }
+        //
+
         if (!ELM_RECTS_INTERSECT(itb->x - sd->pan_x,
-                                 itb->y - sd->pan_y,
+                                 itb_y,
                                  sd->minw, itb->minh, x, y, 1, 1))
           continue;
         EINA_LIST_FOREACH(itb->items, l, it)
@@ -524,7 +546,7 @@ _elm_genlist_pos_adjust_xy_item_get(const Evas_Object *obj,
              Evas_Coord itx, ity, itw, ith;
 
              itx = itb->x + it->x - sd->pan_x;
-             ity = itb->y + it->y - sd->pan_y;
+             ity = itb_y + it->y;
 
              itw = (GL_IT(it)->w ? GL_IT(it)->w : sd->minw);
              ith = GL_IT(it)->minh;
@@ -623,7 +645,8 @@ _elm_genlist_pan_elm_pan_pos_adjust(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *p
    if (!y) return;
 
    Elm_Object_Item *eo_it;
-   Evas_Coord vw, vh;
+   Eina_Bool loop_v = EINA_FALSE;
+   Evas_Coord vy, vw, vh;
    Evas_Coord cx = 0, cy = 0;
    Evas_Coord it_y, it_h;
    Evas_Coord yy = *y;
@@ -652,6 +675,7 @@ _elm_genlist_pan_elm_pan_pos_adjust(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *p
    sd->adjusted_item = _adjust_item_align(sd->adjusted_item);
    if (!sd->adjusted_item) return;
 
+   eo_do(sd->obj, elm_interface_scrollable_loop_get(NULL, &loop_v));
    cy += psd->wsd->pan_y;
    it_y = sd->adjusted_item->y + GL_IT(sd->adjusted_item)->block->y;
    it_h = GL_IT(sd->adjusted_item)->h;
@@ -686,11 +710,26 @@ EOLIAN static void
 _elm_genlist_pan_elm_pan_pos_max_get(Eo *obj, Elm_Genlist_Pan_Data *psd, Evas_Coord *x, Evas_Coord *y)
 {
    Evas_Coord ow, oh;
+   //PRODUCT_ONLY(20181127):For loop enabled case max pan position should be equal to height
+   Eina_Bool loop_v = EINA_FALSE;
+   eo_do(psd->wsd->obj, elm_interface_scrollable_loop_get(NULL, &loop_v));
+   //
 
    evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
    ow = psd->wsd->minw - ow;
    if (ow < 0) ow = 0;
-   oh = psd->wsd->minh - oh;
+   //PRODUCT_ONLY(20181127):For loop enabled case max pan position should be equal to height
+   //oh = psd->wsd->minh - oh;
+   if (loop_v)
+     oh = psd->wsd->minh;
+   else
+     oh = psd->wsd->minh - oh;
+   //
+
+#ifdef TIZEN_PROFILE_WEARABLE_C1
+   oh += psd->wsd->bottom_margin;
+#endif // #ifdef TIZEN_PROFILE_WEARABLE_C1
+
    if (oh < 0) oh = 0;
    if (x) *x = ow;
    if (y) *y = oh;
@@ -2280,7 +2319,7 @@ _item_block_realize(Item_Block *itb, Eina_Bool force)
    Elm_Gen_Item *top_drawn_item = NULL;
    const Eina_List *l, *ll;
    Evas_Object *content;
-   Eina_Bool unrealize = EINA_TRUE;
+   Eina_Bool unrealize = EINA_TRUE, loop_v = EINA_FALSE;
    Evas_Coord ox = 0, oy = 0, ow = 0, oh = 0, cvx = 0, cvy = 0, cvw = 0, cvh = 0;
    ELM_WIDGET_DATA_GET_OR_RETURN(sd->obj, wsd);
 
@@ -2330,6 +2369,10 @@ _item_block_realize(Item_Block *itb, Eina_Bool force)
           }
         GL_IT(it)->scrl_x = it->x + itb->x - sd->pan_x + ox;
         GL_IT(it)->scrl_y = it->y + itb->y - sd->pan_y + oy;
+
+        eo_do(sd->obj, elm_interface_scrollable_loop_get(NULL, &loop_v));
+        if (loop_v && GL_IT(it)->scrl_y < 0 && (sd->pan_y > (sd->minh - cvh)))
+          GL_IT(it)->scrl_y = it->y + itb->y - (sd->pan_y - sd->minh) + oy;
         GL_IT(it)->w = sd->minw;
         GL_IT(it)->h = GL_IT(it)->minh;
 
@@ -2424,9 +2467,11 @@ _elm_genlist_pan_evas_object_smart_calculate(Eo *obj, Elm_Genlist_Pan_Data *psd)
    Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
    Item_Block *itb;
    ELM_WIDGET_DATA_GET_OR_RETURN(psd->wsd->obj, wd);
+   Eina_Bool loop_v = EINA_FALSE;
 
    evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
    evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
+   eo_do(psd->wsd->obj, elm_interface_scrollable_loop_get(NULL, &loop_v));
 
    //FIXME: This is for optimizing genlist calculation after
    //       genlist sizing eval properly.
@@ -2471,7 +2516,8 @@ _elm_genlist_pan_evas_object_smart_calculate(Eo *obj, Elm_Genlist_Pan_Data *psd)
    Eina_Inlist *start = NULL;
    Eina_List *realized_new = NULL;
    Eina_Bool flag = EINA_FALSE;
-   if ((psd->wsd->blocks_realized) && (psd->wsd->dir == -1) &&
+
+   if (!loop_v && (psd->wsd->blocks_realized) && (psd->wsd->dir == -1) &&
        (!_elm_config->access_mode) && (!_elm_atspi_enabled()))
      {
         start = EINA_INLIST_GET((Item_Block *)eina_list_data_get
@@ -2498,7 +2544,7 @@ _elm_genlist_pan_evas_object_smart_calculate(Eo *obj, Elm_Genlist_Pan_Data *psd)
                }
           }
      }
-   else if ((psd->wsd->blocks_realized) && (psd->wsd->dir == 1) &&
+   else if (!loop_v && (psd->wsd->blocks_realized) && (psd->wsd->dir == 1) &&
             (!_elm_config->access_mode) && (!_elm_atspi_enabled()))
      {
         start = EINA_INLIST_GET((Item_Block *)eina_list_data_get
@@ -2543,6 +2589,19 @@ _elm_genlist_pan_evas_object_smart_calculate(Eo *obj, Elm_Genlist_Pan_Data *psd)
                         realized_new = eina_list_append(realized_new, itb);
                         _item_block_realize(itb, EINA_FALSE);
                      }
+                   else if (loop_v && psd->wsd->pan_y > (psd->wsd->minh - cvh))
+                     {
+                        itb_y = itb->y - (psd->wsd->pan_y - psd->wsd->minh) + oy;
+                        if (ELM_RECTS_INTERSECT(itb_x, itb_y, itb_w, itb_h,
+                                                 cvx, cvy, cvw, cvh))
+                        {
+                           flag = EINA_TRUE;
+                           realized_new = eina_list_append(realized_new, itb);
+                           _item_block_realize(itb, EINA_FALSE);
+                        }
+                        else
+                           _item_block_unrealize(itb);
+                     }
                    else
                      {
                         _item_block_unrealize(itb);
@@ -2686,7 +2745,9 @@ _elm_genlist_pan_evas_object_smart_calculate(Eo *obj, Elm_Genlist_Pan_Data *psd)
        !psd->wsd->show_item->item->queued &&
        psd->wsd->show_item->item->calc_done &&
        psd->wsd->show_item->item->block->calc_done &&
-       psd->wsd->calc_done)
+       psd->wsd->calc_done &&
+       (oh > 0) &&
+       (!loop_v || (loop_v && !psd->wsd->queue)))
      {
         Evas_Coord x, y, w, h;
         Elm_Gen_Item *it = psd->wsd->show_item;