interface_scrollable: fix calculation logic of gengrid/scroller. 65/124365/1
authorj_yong.hwang <j_yong.hwang@samsung.com>
Tue, 8 Sep 2015 11:22:03 +0000 (20:22 +0900)
committerWonki Kim <wonki_.kim@samsung.com>
Tue, 11 Apr 2017 07:31:36 +0000 (16:31 +0900)
this commit is ported code about gengrid/interface_scrollable from tizen_2.4.

ported commits list = (
      72c55bbadc310e39b2b929811316ef6eabaf9b6a2c2fc2d0bbbe91ad640d73a7a85fb19bd0c5b086
      8c76cca65fa841c9646ac21eec9ccd627cb962a3cdf2b41436c0bb0f17c34439e5e0f73e111d802b
      2ba6eedfd54ad9b3bbcee5dce45d35528696a69ed22885ea8ee67b8da5a7d77b8aebd9db6ce0f91d
      357cf9b9b084e96acd71db89a19bf2a85a6e792 )

when gengrid is rotating, gengrid shows wrong position because size of gengrid
content is changed. Above commits override function of interface_scrollable to set
proper position of gengrid.

@tizen_only

Change-Id: I20136971730063c6a6730e23e9acb66f6fc416dd

src/lib/elm_gengrid.c
src/lib/elm_gengrid.eo
src/lib/elm_interface_scrollable.c
src/lib/elm_interface_scrollable.eo

index c95ee34..126cdbf 100644 (file)
@@ -6156,6 +6156,60 @@ _elm_gengrid_elm_interface_scrollable_wanted_region_set(Eo *obj EINA_UNUSED, Elm
 }
 //
 
+//TIZEN_ONLY(20150909) : Use the specific bar_chagnged_bar_pos_adjust func only for gengrid.
+static double
+_round(double value, int pos)
+{
+   double temp;
+
+   temp = value * pow( 10, pos );
+   temp = floor( temp + 0.5 );
+   temp *= pow( 10, -pos );
+
+   return temp;
+}
+
+EOLIAN static void
+_elm_gengrid_elm_interface_scrollable_custom_pan_pos_adjust(Eo *obj, Elm_Gengrid_Data *sd, Evas_Coord *x, Evas_Coord *y)
+{
+   Evas_Coord mx, my, minx, miny;
+   double vx, vy;
+
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+   eo_do(sd->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
+   eo_do(sd->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
+   eo_do(sd->pan_obj, elm_obj_pan_pos_get(x, y));
+
+   if (edje_object_part_exists(wd->resize_obj, "elm.dragable.hbar"))
+     {
+        edje_object_part_drag_value_get
+           (wd->resize_obj, "elm.dragable.hbar", &vx, NULL);
+        *x = _round(vx * (double)mx + minx, 1);
+     }
+   else
+     {
+        if (*x > mx) *x = mx;
+        else if (*x < minx) *x = minx;
+     }
+   if (edje_object_part_exists(wd->resize_obj, "elm.dragable.vbar"))
+     {
+        edje_object_part_drag_value_get
+           (wd->resize_obj, "elm.dragable.vbar", NULL, &vy);
+        *y = _round(vy * (double)my + miny, 1);
+     }
+   else
+     {
+        if (*y > my) *y = my;
+        else if (*y < miny) *y = miny;
+     }
+}
+//
+
+//////////////////////////////////////////////////////
+// TIZEN_ONLY(20150623): Region show on item elements fixed
+// Grab and clear highlight on gengrid items
+//////////////////////////////////////////////////////
 EOLIAN static Eina_Bool
 _elm_gengrid_item_elm_interface_atspi_component_highlight_grab(Eo *eo_it, Elm_Gen_Item *it)
 {
index 6b43993..dac1467 100644 (file)
@@ -744,6 +744,8 @@ class Elm.Gengrid (Elm.Layout, Elm_Interface_Scrollable,
       // TIZEN_ONLY(20150825) : Use the specific wanted_region_set func only for gengrid. */
       Elm_Interface_Scrollable.wanted_region_set;
       //
+      /* TIZEN_ONLY(20150909) : Use the specific bar_chagnged_bar_pos_adjust func only for gengrid. */
+      Elm_Interface_Scrollable.custom_pan_pos_adjust;
    }
    events {
       language,changed;
index 0c9f40b..30acdab 100644 (file)
@@ -308,8 +308,11 @@ _elm_pan_class_constructor(Eo_Class *klass)
     }
 
 static void _elm_scroll_scroll_bar_size_adjust(
-  Elm_Scrollable_Smart_Interface_Data *);
-static void _elm_scroll_wanted_region_set(Evas_Object *);
+   Elm_Scrollable_Smart_Interface_Data *);
+//TIZEN_ONLY(20151012): Separate logic which calculate for bar size and logic which calculate for bar position.
+static void _elm_scroll_scroll_bar_pos_adjust(
+   Elm_Scrollable_Smart_Interface_Data *);
+//
 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);
@@ -737,6 +740,8 @@ _elm_scroll_scroll_bar_visibility_adjust(
      }
 }
 
+//TIZEN_ONLY(20151012): Separate logic which calculate for bar size and logic which calculate for bar position.
+#if 0
 static void
 _elm_scroll_scroll_bar_size_adjust(Elm_Scrollable_Smart_Interface_Data *sid)
 {
@@ -783,15 +788,19 @@ _elm_scroll_scroll_bar_size_adjust(Elm_Scrollable_Smart_Interface_Data *sid)
         edje_object_part_drag_size_set
           (sid->edje_obj, "elm.dragable.vbar", 1.0, size);
 
-        edje_object_part_drag_value_get
-          (sid->edje_obj, "elm.dragable.hbar", &vx, NULL);
-        edje_object_part_drag_value_get
-          (sid->edje_obj, "elm.dragable.vbar", NULL, &vy);
+        //TIZEN_ONLY(20150909) : Use the specific bar_chagnged_bar_pos_adjust func only for gengrid.
+        //edje_object_part_drag_value_get
+        //  (sid->edje_obj, "elm.dragable.hbar", &vx, NULL);
+        //edje_object_part_drag_value_get
+        //  (sid->edje_obj, "elm.dragable.vbar", NULL, &vy);
+        //
 
         eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
         eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
-        x = vx * mx + minx;
-        y = vy * my + miny;
+        //TIZEN_ONLY(20150909) : Use the specific bar_chagnged_bar_pos_adjust func only for gengrid.
+        //x = vx * mx + minx;
+        //y = vy * my + miny;
+        //
 
         edje_object_part_drag_step_set
           (sid->edje_obj, "elm.dragable.hbar", (double)sid->step.x /
@@ -816,9 +825,15 @@ _elm_scroll_scroll_bar_size_adjust(Elm_Scrollable_Smart_Interface_Data *sid)
             (sid->edje_obj, "elm.dragable.vbar", 0.0,
             -((double)sid->page.y * ((double)vh / (double)h)) / 100.0);
 
-        eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
-        if (vx != mx) x = px;
-        if (vy != my) y = py;
+        //TIZEN_ONLY(20150909) : Use the specific bar_chagnged_bar_pos_adjust func only for gengrid.
+        //eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
+        //
+        //if (vx != mx) x = px;
+        //if (vy != my) y = py;
+        //
+        eo_do(sid->obj, elm_interface_scrollable_custom_pan_pos_adjust(&x, &y));
+        //
+
         eo_do(sid->pan_obj, elm_obj_pan_pos_set(x, y));
 
         if (mx > 0) vx = (double)(x - minx) / (double)mx;
@@ -862,6 +877,181 @@ _elm_scroll_scroll_bar_size_adjust(Elm_Scrollable_Smart_Interface_Data *sid)
         sid->size_adjust_recurse_abort = EINA_FALSE;
      }
 }
+#endif
+//Calculate size of bar and position of bar must be separated two different functions.
+//So we divided a function into the elm_scroll_scroll_bar_pos_adjust and elm_scroll_scroll_bar_size_adjust.
+//A elm_scroll_scroll_bar_pos_adjust is called when size of content is changed.
+//If size of pan is changed only, A elm_scroll_scroll_bar_pos_adjust isn`t called. Only a elm_scroll_scroll_bar_size_adjust is called.
+//
+//This function adjusts the size of the bar.
+static void
+_elm_scroll_scroll_bar_size_adjust(Elm_Scrollable_Smart_Interface_Data *sid)
+{
+   if (!sid->pan_obj || !sid->edje_obj) return;
+
+   if (sid->size_adjust_recurse_abort) return;
+   if (sid->size_adjust_recurse > 20)
+     {
+        sid->size_adjust_recurse_abort = EINA_TRUE;
+        return;
+     }
+   sid->size_adjust_recurse++;
+   if ((sid->content) || (sid->extern_pan))
+     {
+        Evas_Coord w, h, vw = 0, vh = 0;
+        double size;
+
+        edje_object_part_geometry_get
+          (sid->edje_obj, "elm.swallow.content", NULL, NULL, &vw, &vh);
+        w = sid->content_info.w;
+        if (w < 1) w = 1;
+        size = (double)vw / (double)w;
+        if (size > 1.0) size = 1.0;
+        edje_object_part_drag_size_set
+          (sid->edje_obj, "elm.dragable.hbar", size, 1.0);
+
+        h = sid->content_info.h;
+        if (h < 1) h = 1;
+        size = (double)vh / (double)h;
+        if (size > 1.0) size = 1.0;
+        edje_object_part_drag_size_set
+          (sid->edje_obj, "elm.dragable.vbar", 1.0, size);
+
+        edje_object_part_drag_step_set
+          (sid->edje_obj, "elm.dragable.hbar", (double)sid->step.x /
+          (double)w, 0.0);
+        edje_object_part_drag_step_set
+          (sid->edje_obj, "elm.dragable.vbar", 0.0, (double)sid->step.y /
+          (double)h);
+        if (sid->page.x > 0)
+          edje_object_part_drag_page_set
+            (sid->edje_obj, "elm.dragable.hbar", (double)sid->page.x /
+            (double)w, 0.0);
+        else
+          edje_object_part_drag_page_set
+            (sid->edje_obj, "elm.dragable.hbar",
+            -((double)sid->page.x * ((double)vw / (double)w)) / 100.0, 0.0);
+        if (sid->page.y > 0)
+          edje_object_part_drag_page_set
+            (sid->edje_obj, "elm.dragable.vbar", 0.0,
+            (double)sid->page.y / (double)h);
+        else
+          edje_object_part_drag_page_set
+            (sid->edje_obj, "elm.dragable.vbar", 0.0,
+            -((double)sid->page.y * ((double)vh / (double)h)) / 100.0);
+     }
+   else
+     {
+        edje_object_part_drag_size_set
+          (sid->edje_obj, "elm.dragable.vbar", 1.0, 1.0);
+        edje_object_part_drag_size_set
+          (sid->edje_obj, "elm.dragable.hbar", 1.0, 1.0);
+     }
+   _elm_scroll_scroll_bar_visibility_adjust(sid);
+   sid->size_adjust_recurse--;
+   if (sid->size_adjust_recurse <= 0)
+     {
+        sid->size_adjust_recurse = 0;
+        sid->size_adjust_recurse_abort = EINA_FALSE;
+     }
+}
+//This function adjusts the position of the bar.
+static void
+_elm_scroll_scroll_bar_pos_adjust(Elm_Scrollable_Smart_Interface_Data *sid)
+{
+   if (!sid->pan_obj || !sid->edje_obj) return;
+
+   if ((sid->content) || (sid->extern_pan))
+     {
+        Evas_Coord x, y, w, h, mx = 0, my = 0, vw = 0, vh = 0,
+                   minx = 0, miny = 0;
+        double vx, vy, size;
+
+        edje_object_part_geometry_get
+          (sid->edje_obj, "elm.swallow.content", NULL, NULL, &vw, &vh);
+        w = sid->content_info.w;
+        if (w < 1) w = 1;
+        size = (double)vw / (double)w;
+        if (size > 1.0)
+          {
+             size = 1.0;
+             edje_object_part_drag_value_set
+               (sid->edje_obj, "elm.dragable.hbar", 0.0, 0.0);
+          }
+
+        h = sid->content_info.h;
+        if (h < 1) h = 1;
+        size = (double)vh / (double)h;
+        if (size > 1.0)
+          {
+             size = 1.0;
+             edje_object_part_drag_value_set
+               (sid->edje_obj, "elm.dragable.vbar", 0.0, 0.0);
+          }
+
+        eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
+        eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
+        eo_do(sid->obj, elm_interface_scrollable_custom_pan_pos_adjust(&x, &y));
+        eo_do(sid->pan_obj, elm_obj_pan_pos_set(x, y));
+
+        if (mx > 0) vx = (double)(x - minx) / (double)mx;
+        else vx = 0.0;
+
+        if (vx < 0.0) vx = 0.0;
+        else if (vx > 1.0)
+          vx = 1.0;
+
+        if (my > 0) vy = (double)(y - miny) / (double)my;
+        else vy = 0.0;
+
+        if (vy < 0.0) vy = 0.0;
+        else if (vy > 1.0)
+          vy = 1.0;
+
+        edje_object_part_drag_value_set
+           (sid->edje_obj, "elm.dragable.vbar", 0.0, vy);
+        edje_object_part_drag_value_set
+           (sid->edje_obj, "elm.dragable.hbar", vx, 0.0);
+     }
+   else
+     {
+        Evas_Coord px = 0, py = 0, minx = 0, miny = 0;
+
+        eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
+        eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
+        eo_do(sid->pan_obj, elm_obj_pan_pos_set(minx, miny));
+        if ((px != minx) || (py != miny))
+          edje_object_signal_emit(sid->edje_obj, "elm,action,scroll", "elm");
+     }
+}
+//
+
+//TIZEN_ONLY(20150909) : Use the specific bar_chagnged_bar_pos_adjust func only for gengrid.
+//When position of scrollbar is changed, you can adjust a position of custom pan by using this function.
+//
+EOLIAN static void
+_elm_interface_scrollable_custom_pan_pos_adjust(Eo *obj EINA_UNUSED, Elm_Scrollable_Smart_Interface_Data *sid, Evas_Coord *x, Evas_Coord *y)
+{
+   Evas_Coord mx, my, minx, miny, px, py;
+   double vx, vy;
+
+   edje_object_part_drag_value_get
+      (sid->edje_obj, "elm.dragable.hbar", &vx, NULL);
+   edje_object_part_drag_value_get
+      (sid->edje_obj, "elm.dragable.vbar", NULL, &vy);
+
+   eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
+   eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
+
+   *x = _round(vx * (double)mx + minx, 1);
+   *y = _round(vy * (double)my + miny, 1);
+
+   eo_do(sid->pan_obj, elm_obj_pan_pos_get(&px, &py));
+
+   if (vx != mx) *x = px;
+   if (vy != my) *y = py;
+}
+//
 
 static void
 _elm_scroll_scroll_bar_read_and_update(
@@ -4313,6 +4503,20 @@ _elm_scroll_pan_resized_cb(void *data,
 {
    Evas_Coord w = 0, h = 0;
    Elm_Scrollable_Smart_Interface_Data *sid = data;
+   //TIZEN_ONLY(20151013): Check the validity of pan value
+   Evas_Coord pan_x = 0, pan_y = 0, minx = 0, miny = 0, mx = 0, my = 0;
+
+   eo_do(sid->pan_obj, elm_obj_pan_pos_get(&pan_x, &pan_y));
+   eo_do(sid->pan_obj, elm_obj_pan_pos_min_get(&minx, &miny));
+   eo_do(sid->pan_obj, elm_obj_pan_pos_max_get(&mx, &my));
+   if (pan_x < minx) pan_x = minx;
+   else if (pan_x > mx + minx) pan_x = mx + minx;
+
+   if (pan_y < miny) pan_y = miny;
+   else if (pan_y > my + miny) pan_y = my + miny;
+
+   eo_do(sid->pan_obj, elm_obj_pan_pos_set(pan_x, pan_y));
+   //
 
    if (sid->cb_func.content_viewport_resize)
      {
@@ -4339,6 +4543,11 @@ _elm_scroll_pan_changed_cb(void *data,
         sid->content_info.w = w;
         sid->content_info.h = h;
         _elm_scroll_scroll_bar_size_adjust(sid);
+        //TIZEN_ONLY(20151012): Separate logic which calculate for bar size and logic which calculate for bar position.
+        //A elm_scroll_scroll_bar_pos_adjust is called when size of content is changed.
+        //If size of pan is changed only, A elm_scroll_scroll_bar_pos_adjust isn`t called. Only a elm_scroll_scroll_bar_size_adjust is called.
+        _elm_scroll_scroll_bar_pos_adjust(sid);
+        //
 
         evas_object_size_hint_min_set
           (sid->edje_obj, sid->content_info.w, sid->content_info.h);
@@ -4362,6 +4571,11 @@ _elm_scroll_content_del_cb(void *data,
 
    sid->content = NULL;
    _elm_scroll_scroll_bar_size_adjust(sid);
+   //TIZEN_ONLY(20151012): Separate logic which calculate for bar size and logic which calculate for bar position.
+   //A elm_scroll_scroll_bar_pos_adjust is called when size of content is changed.
+   //If size of pan is changed only, A elm_scroll_scroll_bar_pos_adjust isn`t called. Only a elm_scroll_scroll_bar_size_adjust is called.
+   _elm_scroll_scroll_bar_pos_adjust(sid);
+   //
    _elm_scroll_scroll_bar_reset(sid);
 }
 
@@ -4407,6 +4621,11 @@ _elm_interface_scrollable_content_set(Eo *obj, Elm_Scrollable_Smart_Interface_Da
    sid->content_info.h = h;
 
    _elm_scroll_scroll_bar_size_adjust(sid);
+   //TIZEN_ONLY(20151012): Separate logic which calculate for bar size and logic which calculate for bar position.
+   //A elm_scroll_scroll_bar_pos_adjust is called when size of content is changed.
+   //If size of pan is changed only, A elm_scroll_scroll_bar_pos_adjust isn`t called. Only a elm_scroll_scroll_bar_size_adjust is called.
+   _elm_scroll_scroll_bar_pos_adjust(sid);
+   //
    _elm_scroll_scroll_bar_reset(sid);
 }
 
index 165da2d..2b24837 100644 (file)
@@ -623,6 +623,13 @@ mixin Elm_Interface_Scrollable(Evas.Scrollable_Interface, Evas.Object_Smart)
             @in y: Evas_Coord;
          }
       }
+      /* TIZEN_ONLY(20150909) : Use the specific bar_chagnged_bar_pos_adjust func only for gengrid. */
+      custom_pan_pos_adjust {
+         params {
+            @in x: Evas_Coord*;
+            @in y: Evas_Coord*;
+         }
+      }
    }
    implements {
       class.constructor;