genlist : apply item circular zooming feature in align mode 05/85505/7
authorSangHyeon Lee <sh10233.lee@samsung.com>
Thu, 25 Aug 2016 11:39:46 +0000 (20:39 +0900)
committerTaehyub Kim <taehyub.kim@samsung.com>
Tue, 29 Nov 2016 12:32:36 +0000 (21:32 +0900)
Change-Id: Idd8c8a6f537dd0d44052ac949eba0b3a6c84a6e7
Signed-off-by: SangHyeon Lee <sh10233.lee@samsung.com>
src/mobile_lib/elm_genlist.c
src/mobile_lib/elm_widget_genlist.h

index 7710eb2eb672ae62253a6e0bb4f3462c8efeeeca..f29764f67fdb35496197b7b25db1fe51ba370cba 100644 (file)
 #define HIGHLIGHT_ALPHA_MAX 0.74
 #define ELM_ITEM_HIGHLIGHT_TIMER 0.1
 #define ITEM_QUEUE_MAX 128
+#define DIMED_ITEM_COLOR 50
+#define ALIGNED_ITEM_SCALE_FACTOR 1.5
+#define CENTER_CHECK_GAP 50
+#define FLICK_GAP 30
 
 #define ERR_ABORT(_msg)                         \
    do {                                         \
@@ -171,12 +175,14 @@ static Eina_Bool _long_press_cb(void *data);
 static void _item_edje_callbacks_add(Elm_Gen_Item *it);
 static void _item_edje_callbacks_del(Elm_Gen_Item *it);
 
-static void _item_block_calc(Item_Block *);
+static void _item_block_calc(Item_Block *itb, Evas_Coord vw, Evas_Coord vh);
 static void _item_min_calc(Elm_Gen_Item *it);
 static void _item_calc(Elm_Gen_Item *it);
 static void _item_mouse_callbacks_add(Elm_Gen_Item *, Evas_Object *);
 static void _item_mouse_callbacks_del(Elm_Gen_Item *, Evas_Object *);
 static void _item_select(Elm_Gen_Item *it);
+static void _item_realize(Elm_Gen_Item *it, Eina_Bool calc);
+static void _item_unrealize(Elm_Gen_Item *it, Eina_Bool calc);
 
 static void _expand_toggle_signal_cb(void *data, Evas_Object *obj EINA_UNUSED, const char *emission EINA_UNUSED, const char *source EINA_UNUSED);
 static void _expand_signal_cb(void *data, Evas_Object *obj EINA_UNUSED, const char *emission EINA_UNUSED, const char *source EINA_UNUSED);
@@ -499,7 +505,7 @@ _elm_genlist_pos_adjust_xy_item_get(const Evas_Object *obj,
 
    EINA_INLIST_FOREACH(sd->blocks, itb)
      {
-        Eina_List *l;
+        Eina_List *l = NULL;
         Elm_Gen_Item *it;
         if (!ELM_RECTS_INTERSECT(itb->x - sd->pan_x,
                                  itb->y - sd->pan_y,
@@ -523,6 +529,81 @@ _elm_genlist_pos_adjust_xy_item_get(const Evas_Object *obj,
    return NULL;
 }
 
+static Elm_Gen_Item *
+_adjust_item_align(Elm_Gen_Item *it)
+{
+   if (!it) return NULL;
+   int loop_count = 0;
+   int direction;
+   Elm_Gen_Item *adjust_item = it;
+   Elm_Object_Item *eo_item = NULL;
+   Elm_Genlist_Data *sd = GL_IT(it)->wsd;
+
+   ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(adjust_item), wd, NULL);
+
+   if (!wd || !(wd->scroll_item_align_enable)) return it;
+   if (!sd || !sd->aligned_item || (it == sd->aligned_item)) return it;
+
+   direction = GL_IT(adjust_item)->scrl_y - GL_IT(sd->aligned_item)->scrl_y;
+   while (adjust_item && loop_count < 10)
+     {
+        const char *align = NULL;
+        if (!VIEW(adjust_item))
+          {
+             _item_realize(adjust_item, EINA_TRUE);
+             align = edje_object_data_get(VIEW(adjust_item), "align");
+             _item_unrealize(adjust_item, EINA_TRUE);
+          }
+        else
+          align = edje_object_data_get(VIEW(adjust_item), "align");
+
+        if (align && !strcmp(align, "off"))
+          {
+             if (direction < 0)
+               eo_item = elm_genlist_item_prev_get(EO_OBJ(adjust_item));
+             else
+               eo_item = elm_genlist_item_next_get(EO_OBJ(adjust_item));
+             adjust_item = eo_data_scope_get(eo_item, ELM_GENLIST_ITEM_CLASS);
+          }
+        else
+             break;
+        ++loop_count;
+     }
+
+   if (adjust_item) return adjust_item;
+
+   adjust_item = it;
+   while (adjust_item && loop_count < 10)
+     {
+        char *align = NULL;
+        if (!VIEW(adjust_item))
+          {
+             _item_realize(adjust_item, EINA_TRUE);
+             align = edje_object_data_get(VIEW(adjust_item), "align");
+             _item_unrealize(adjust_item, EINA_TRUE);
+          }
+        else
+          align = edje_object_data_get(VIEW(adjust_item), "align");
+
+        if (align && !strcmp(align, "off"))
+          {
+             if (direction > 0)
+               eo_item = elm_genlist_item_prev_get(EO_OBJ(adjust_item));
+             else
+               eo_item = elm_genlist_item_next_get(EO_OBJ(adjust_item));
+             adjust_item = eo_data_scope_get(eo_item, ELM_GENLIST_ITEM_CLASS);
+          }
+        else
+             break;
+        ++loop_count;
+     }
+
+   if (!adjust_item)
+     adjust_item = it;
+
+   return adjust_item;
+}
+
 EOLIAN static void
 _elm_genlist_pan_elm_pan_pos_adjust(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *psd, Evas_Coord *x EINA_UNUSED, Evas_Coord *y)
 {
@@ -533,8 +614,10 @@ _elm_genlist_pan_elm_pan_pos_adjust(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *p
 
    if (!y) return;
 
-   Elm_Gen_Item *it;
+   Elm_Gen_Item *adjust_item = NULL;
+   Elm_Object_Item *eo_it;
    Evas_Coord vw, vh;
+   Evas_Coord cx = 0, cy = 0;
    Evas_Coord it_y, it_h;
    Evas_Coord yy = *y;
 
@@ -542,20 +625,53 @@ _elm_genlist_pan_elm_pan_pos_adjust(Eo *obj EINA_UNUSED, Elm_Genlist_Pan_Data *p
          (NULL, NULL, &vw, &vh));
    if (!strcmp(wd->scroll_item_valign, "center"))
      {
-        vw = (vw / 2);
-        vh = (vh / 2) - yy;
+        cx = (vw / 2);
+        cy = (vh / 2) - yy;
      }
 
-   it = _elm_genlist_pos_adjust_xy_item_get(sd->obj, vw, vh);
+   sd->adjusted_item = _elm_genlist_pos_adjust_xy_item_get(sd->obj, cx, cy);
 
-   vh += psd->wsd->pan_y;
+   if ((abs(*y) > FLICK_GAP) && (sd->adjusted_item == sd->aligned_item))
+     {
+        Elm_Gen_Item *adjusted_item = NULL;
+        if (*y < 0)
+          eo_it = elm_genlist_item_next_get(EO_OBJ(sd->adjusted_item));
+        else
+          eo_it = elm_genlist_item_prev_get(EO_OBJ(sd->adjusted_item));
+        adjust_item = eo_data_scope_get(eo_it, ELM_GENLIST_ITEM_CLASS);
+        if (adjust_item)
+          sd->adjusted_item = adjusted_item;
+     }
+   sd->adjusted_item = _adjust_item_align(sd->adjusted_item);
+   if (!sd->adjusted_item) return;
 
-   if (!it) return;
+   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;
 
-   it_y = it->y + GL_IT(it)->block->y;
-   it_h = GL_IT(it)->h;
-   it_h = it_y + (it_h / 2);
-   *y += (vh - it_h);
+   if (GL_IT(sd->adjusted_item)->h <= vh)
+     {
+        it_h = it_y + (it_h / 2);
+        *y += (cy - it_h);
+     }
+   else
+     {
+        int it_b_y = it_y + it_h;
+        int half_vh = vh/2;
+        if (it_y <= cy && it_y >= cy - half_vh)
+          {
+             *y -= half_vh - (cy - it_y);
+          }
+       else if (it_b_y >= cy && it_b_y <= cy  + half_vh)
+          {
+             *y += half_vh - (it_b_y - cy);
+          }
+     }
+
+   if (!*y && !sd->unhighlighted)
+     sd->adjusted_item = NULL;
+   else
+     evas_object_smart_changed(sd->pan_obj);
 }
 //
 
@@ -1139,6 +1255,16 @@ _item_unrealize(Elm_Gen_Item *it,
    _item_edje_callbacks_del(it);
 
    _item_mouse_callbacks_del(it, VIEW(it));
+   if (!calc && it->item->proxy)
+     {
+        //FIXME: proxy source cannot recieve mouse move events due to the clipper
+        evas_object_event_callback_del_full
+           (it->item->proxy, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
+        evas_object_image_source_visible_set(it->item->proxy, EINA_TRUE);
+        evas_object_smart_member_del(it->item->proxy);
+        evas_object_del(it->item->proxy);
+        it->item->proxy = NULL;
+     }
 
    EINA_LIST_FREE(GL_IT(it)->flip_content_objs, content)
     evas_object_del(content);
@@ -1240,7 +1366,7 @@ _calc(void *data)
 {
    Elm_Genlist_Data *sd = data;
    Item_Block *itb;
-   Evas_Coord minw = 99999999, minh = 0, vw, vh;
+   Evas_Coord minw = 99999999, minh = 0, vw = 0, vh = 0, current_minh = 0;
    Evas_Coord processed_size = sd->minh;
    int cnt = 0;
 
@@ -1259,18 +1385,17 @@ _calc(void *data)
         cnt++;
      }
 //
-
+   eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
+         (NULL, NULL, &vw, &vh));
    EINA_INLIST_FOREACH(sd->blocks, itb)
      {
-        _item_block_calc(itb);
         itb->x = 0;
         itb->y = minh;
+        _item_block_calc(itb, vw, vh);
         if (minw > itb->minw) minw = itb->minw;
         minh += itb->minh;
      }
 
-   eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
-         (NULL, NULL, &vw, &vh));
    if ((sd->mode == ELM_LIST_COMPRESS) && (minw > vw))
       minw = vw;
    else if (minw < vw) minw = vw;
@@ -1278,10 +1403,11 @@ _calc(void *data)
    if ((minw != sd->minw) || (minh != sd->minh))
      {
         Eina_Bool load_done = EINA_FALSE;
-        if (!sd->queue && (minh != sd->minh)) load_done = EINA_TRUE;
 
+        current_minh = sd->minh;
         sd->minw = minw;
         sd->minh = minh;
+        if (!sd->queue && (minh != current_minh)) load_done = EINA_TRUE;
         elm_layout_sizing_eval(sd->obj);
         evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
         if (load_done)
@@ -1340,55 +1466,38 @@ _elm_genlist_content_min_limit_cb(Evas_Object *obj,
 }
 
 static void
-_elm_genlist_scroll_item_align_highlight_cb(Evas_Object *obj)
+_focus_bg_show(Elm_Gen_Item *it)
 {
-   ELM_GENLIST_DATA_GET(obj, sd);
-   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
-   Evas_Coord vw, vh;
+   Evas_Coord w;
+   Evas_Coord h = 0, rectangle_h = GL_IT(it)->h;
+   ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wd);
+   const Evas_Object *top, *bottom;
+   Evas_Object *rectangle;
+   const char *focus_bg;
 
-   if (!(wd->scroll_item_align_enable)) return;
+   if (!VIEW(it)) return;
+   focus_bg = edje_object_data_get(VIEW(it), "focus_bg");
+   if (focus_bg && !strcmp(focus_bg, "off")) return;
 
-   eo_do(obj, elm_interface_scrollable_content_viewport_geometry_get
-         (NULL, NULL, &vw, &vh));
+   evas_object_geometry_get(wd->resize_obj, NULL, NULL, &w, NULL);
+   top = edje_object_part_object_get(VIEW(it), "elm.padding.focus_bg.top");
+   bottom = edje_object_part_object_get(VIEW(it), "elm.padding.focus_bg.bottom");
 
-   if (!strcmp(wd->scroll_item_valign, "center"))
+   if (top && bottom)
      {
-        vw = (vw / 2);
-        vh = (vh / 2);
+        evas_object_geometry_get(top, NULL, NULL, NULL, &h);
+        rectangle_h -= h;
+        evas_object_geometry_get(bottom, NULL, NULL, NULL, &h);
+        rectangle_h -= h;
      }
 
-   sd->aligned_item = _elm_genlist_pos_adjust_xy_item_get(obj, vw, vh);
+   rectangle = evas_object_rectangle_add(evas_object_evas_get(wd->obj));
+   evas_object_size_hint_min_set(rectangle, w, rectangle_h);
+   evas_object_size_hint_max_set(rectangle, w, rectangle_h);
+   evas_object_color_set(rectangle, 0, 0, 0, 0);
+   elm_object_part_content_set(wd->obj, "focus_bg_size", rectangle);
 
-   if (sd->aligned_item && sd->aligned_item->realized)
-     {
-        //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
-        if (_elm_atspi_enabled())
-          {
-             if(sd->aligned_item != sd->currently_highlighted_item)
-               {
-                  eo_do(EO_OBJ(sd->aligned_item), elm_interface_atspi_component_highlight_grab());
-               }
-          }
-        //
-        edje_object_signal_emit(VIEW(sd->aligned_item), SIGNAL_ITEM_HIGHLIGHTED, "elm");
-     }
-}
-
-static void
-_elm_genlist_scroll_item_align_unhighlight_cb(Evas_Object *obj)
-{
-   ELM_GENLIST_DATA_GET(obj, sd);
-   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
-
-   if (!(wd->scroll_item_align_enable)) return;
-
-   if (sd->aligned_item)
-     {
-        if (sd->aligned_item->realized)
-          edje_object_signal_emit(VIEW(sd->aligned_item),
-                                  SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
-        sd->aligned_item = NULL;
-     }
+   edje_object_signal_emit(wd->resize_obj, SIGNAL_FOCUS_BG_SHOW, "elm");
 }
 
 static void
@@ -1400,9 +1509,120 @@ _item_position(Elm_Gen_Item *it,
    if (!it) return;
    if (!view) return;
 
-   evas_object_resize(view, GL_IT(it)->w, GL_IT(it)->h);
-   evas_object_move(view, it_x, it_y);
+   Evas_Coord ox = 0, oy = 0, ow = 0, oh = 0;
+   Evas_Coord ix = 0, iy = 0, iw = 0, ih = 0;
+   Elm_Gen_Item *target = it;
+   Elm_Genlist_Data *sd = GL_IT(target)->wsd;
+   ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(target), wsd);
+
+   ix = it_x;
+   iy = it_y;
+   iw = GL_IT(target)->w;
+   ih = GL_IT(target)->h;
+
+   evas_object_resize(view, iw, ih);
+   evas_object_move(view, ix, iy);
    evas_object_show(view);
+
+   if (wsd->scroll_item_align_enable)
+     {
+        int color = 0;
+        int pre_multiplied_color = 0;
+        int resize_width = 0;
+        int resize_hight = 0;
+        float ratio = 0.0;
+        double scale = 0.0;
+        char *vi_effect = NULL;
+        char *dim = NULL;
+        double move_v[4] = {0.49, 0.99, 0.45, 1.0};
+        double scale_v[4] = {0.49, 0.14, 1, 0.63};
+
+        evas_object_geometry_get(wsd->obj, &ox, &oy, &ow, &oh);
+        int g_center = oy + oh / 2;
+        int i_center = GL_IT(target)->scrl_y + GL_IT(target)->h / 2;
+
+        if (it->item->proxy && !ELM_RECTS_INTERSECT(ix, iy, iw, ih, ox, oy, ow, oh))
+          evas_object_hide(it->item->proxy);
+        else
+          {
+             vi_effect = edje_object_data_get(VIEW(target), "vi_effect");
+             if (vi_effect && !strcmp(vi_effect, "on"))
+               {
+                  ratio = (float)abs(g_center - i_center) / (float)((oh / 2) + ih / 2);
+                  color = DIMED_ITEM_COLOR + ((255 - DIMED_ITEM_COLOR) * (1.0 - ratio));
+                  double scale_p = ecore_animator_pos_map_n(ratio, ECORE_POS_MAP_CUBIC_BEZIER, 4, scale_v);
+                  scale = elm_config_scale_get() - (scale_p * ALIGNED_ITEM_SCALE_FACTOR);
+
+                  resize_width = GL_IT(target)->w * (scale / elm_config_scale_get());
+                  if (!((iw - resize_width) % 2))
+                    iw = resize_width;
+                  else
+                    iw = resize_width + 1;
+                  ix = GL_IT(target)->scrl_x + (GL_IT(target)->w - iw) / 2;
+                  resize_hight = GL_IT(target)->h * (scale / elm_config_scale_get());
+
+                  if (!((ih - resize_hight) % 2))
+                    ih = resize_hight;
+                  else
+                    ih = resize_hight + 1;
+
+                  if (i_center < g_center)
+                    {
+                       double move_p = ecore_animator_pos_map_n(ratio, ECORE_POS_MAP_CUBIC_BEZIER, 4, move_v);
+                       iy = GL_IT(target)->scrl_y + move_p * (GL_IT(target)->h - ih);
+                    }
+                  else
+                    iy = GL_IT(target)->scrl_y;
+
+                  dim = edje_object_data_get(view, "dim");
+                  if (!dim || (dim && !strcmp(dim, "on")))
+                    {
+                       pre_multiplied_color = 255 * color >> 8;
+                       if (!elm_object_item_disabled_get(EO_OBJ(target)))
+                         evas_object_color_set(target->item->proxy, pre_multiplied_color, pre_multiplied_color, pre_multiplied_color, color);
+                       else
+                         evas_object_color_set(target->item->proxy, 255, 255, 255, 255);
+                    }
+
+                  evas_object_move(target->item->proxy, ix, iy);
+                  evas_object_resize(target->item->proxy, iw, ih);
+                  evas_object_show(target->item->proxy);
+               }
+             else
+               {
+                  evas_object_move(target->item->proxy, ix, iy);
+                  evas_object_resize(target->item->proxy, iw, ih);
+                  evas_object_show(target->item->proxy);
+               }
+
+             if (!sd->on_hold &&
+                 ELM_RECTS_INTERSECT(GL_IT(target)->scrl_x, GL_IT(target)->scrl_y,
+                                     GL_IT(target)->w, GL_IT(target)->h,
+                                     ox, g_center - CENTER_CHECK_GAP,
+                                     ow, CENTER_CHECK_GAP * 2))
+               {
+                  if ((sd->adjusted_item == target) &&
+                      ((sd->adjusted_item != sd->aligned_item) || (sd->unhighlighted)))
+                    {
+                       edje_object_signal_emit(VIEW(sd->adjusted_item), SIGNAL_ITEM_HIGHLIGHTED, "elm");
+
+                       if (sd->aligned_item && sd->adjusted_item != sd->aligned_item)
+                         edje_object_signal_emit(VIEW(sd->aligned_item), SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
+                       sd->aligned_item = sd->adjusted_item;
+                       sd->unhighlighted = EINA_FALSE;
+                    }
+
+                  if (sd->adjusted_item == target &&
+                      sd->aligned_item == sd->adjusted_item &&
+                      ((i_center >= g_center && i_center < g_center + 10) ||
+                       (i_center <= g_center && i_center > g_center - 10)))
+                    {
+                       sd->adjusted_item = NULL;
+                       _focus_bg_show(sd->aligned_item);
+                    }
+               }
+          }
+     }
 }
 
 static void
@@ -1527,8 +1747,10 @@ _item_mouse_callbacks_add(Elm_Gen_Item *it,
 
    /*Registering Multi down/up events to ignore mouse down/up events untill all
      multi down/up events are released.*/
-   evas_object_event_callback_add
-     (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
+   //FIXME: proxy source cannot recieve mouse move events due to the clipper
+   if (!it->item->proxy)
+     evas_object_event_callback_add
+        (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
 }
 
 static void
@@ -1539,8 +1761,10 @@ _item_mouse_callbacks_del(Elm_Gen_Item *it,
      (view, EVAS_CALLBACK_MOUSE_DOWN, _item_mouse_down_cb, it);
    evas_object_event_callback_del_full
      (view, EVAS_CALLBACK_MOUSE_UP, _item_mouse_up_cb, it);
-   evas_object_event_callback_del_full
-     (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
+   //FIXME: proxy source cannot recieve mouse move events due to the clipper
+   if (!it->item->proxy)
+     evas_object_event_callback_del_full
+        (view, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
 
 }
 
@@ -1572,12 +1796,10 @@ _item_realize(Elm_Gen_Item *it,
               Eina_Bool calc)
 {
    const char *treesize;
-   Evas_Coord vw, vh;
    Eina_Bool ret;
 
    if (it->realized) return;
    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
-
    ELM_WIDGET_DATA_GET_OR_RETURN(sd->obj, wd);
 
    it->realized = EINA_TRUE;
@@ -1608,6 +1830,38 @@ _item_realize(Elm_Gen_Item *it,
           }
      }
    _view_inflate(VIEW(it), it, &it->content_objs);
+   if (wd->scroll_item_align_enable && !calc)
+     {
+        char *vi_effect = edje_object_data_get(VIEW(it), "vi_effect");
+        if (vi_effect && !strcmp(vi_effect, "on"))
+          {
+             Evas_Object *clip = evas_object_clip_get(VIEW(it));
+             const Eina_List *clipees = evas_object_clipees_get(clip);
+             // FIXME: This clipee rect is prevent white rect generation by all clip unset.
+             if ((eina_list_count(clipees) <= 2) && !sd->clipee)
+               {
+                  sd->clipee = evas_object_rectangle_add(evas_object_evas_get(WIDGET(it)));
+                  evas_object_color_set(sd->clipee, 0, 0, 0, 0);
+                  evas_object_clip_set(clip, sd->clipee);
+               }
+             if (!it->item->proxy)
+               {
+                  it->item->proxy = evas_object_image_filled_add(evas_object_evas_get(wd->obj));
+                  evas_object_smart_member_add(it->item->proxy, sd->pan_obj);
+               }
+             evas_object_clip_set(it->item->proxy, evas_object_clip_get(sd->pan_obj));
+             evas_object_clip_unset(VIEW(it));
+             evas_object_image_source_set(it->item->proxy, VIEW(it));
+             evas_object_image_source_visible_set(it->item->proxy, EINA_FALSE);
+             evas_object_image_source_events_set(it->item->proxy, EINA_TRUE);
+             evas_object_image_source_clip_set(it->item->proxy, EINA_FALSE);
+             evas_object_size_hint_min_set(it->item->proxy, GL_IT(it)->w, GL_IT(it)->h);
+             evas_object_repeat_events_set(it->item->proxy, EINA_TRUE);
+             //FIXME: proxy source cannot recieve mouse move events due to the clipper
+             evas_object_event_callback_add
+                (it->item->proxy, EVAS_CALLBACK_MOUSE_MOVE, _item_mouse_move_cb, it);
+          }
+     }
 
    _item_mouse_callbacks_add(it, VIEW(it));
    // Expand can be supported by only VIEW(it)
@@ -1650,28 +1904,6 @@ _item_realize(Elm_Gen_Item *it,
      {
         _decorate_item_realize(it);
      }
-   if (!sd->aligned_item)
-     {
-       //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
-        if (!_elm_atspi_enabled())
-        //
-          {
-             eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
-                   (NULL, NULL, &vw, &vh));
-             vw = (vw / 2);
-             vh = (vh / 2);
-
-             if (ELM_RECTS_INTERSECT(it->x - sd->pan_x, it->y - sd->pan_y, GL_IT(it)->w,
-                                     GL_IT(it)->minh, vw, vh, 1, 1))
-               {
-                  sd->aligned_item = it;
-                  edje_object_signal_emit(VIEW(sd->aligned_item), SIGNAL_ITEM_HIGHLIGHTED, "elm");
-               }
-          }
-     }
-   else if (sd->aligned_item == it)
-     edje_object_signal_emit(VIEW(it), SIGNAL_ITEM_HIGHLIGHTED, "elm");
-
    it->realized = EINA_TRUE;
    if (!calc)
      {
@@ -1986,13 +2218,15 @@ _item_block_realize(Item_Block *itb, Eina_Bool force)
 {
    Elm_Genlist_Data *sd = itb->sd;
    Elm_Gen_Item *it;
+   Elm_Gen_Item *aligned_item = NULL;
 #ifndef TIZEN_PROFILE_WEARABLE
    Elm_Gen_Item *top_drawn_item = NULL;
 #endif
    const Eina_List *l, *ll;
    Evas_Object *content;
    Eina_Bool unrealize = EINA_TRUE;
-   Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh;
+   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);
 
    // Do not check itb->realized
    // because it->item->block can be changed
@@ -2055,6 +2289,16 @@ _item_block_realize(Item_Block *itb, Eina_Bool force)
                }
           }
 #endif
+        if (wsd->scroll_item_align_enable)
+          {
+             if (!sd->aligned_item)
+               {
+                  if (ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y,
+                                          GL_IT(it)->w, GL_IT(it)->h,
+                                          ox + ow / 2, oy + oh / 2, 1, 1))
+                    aligned_item = sd->aligned_item = it;
+               }
+          }
         if (force || sd->realization_mode ||
             it->flipped ||
            (ELM_RECTS_INTERSECT(GL_IT(it)->scrl_x, GL_IT(it)->scrl_y,
@@ -2100,6 +2344,14 @@ _item_block_realize(Item_Block *itb, Eina_Bool force)
    if (sd->banded_bg_on)
      _banded_item_bg_index_color_set(sd->top_drawn_item, ox, oy, ow, oh);
 #endif
+
+   if (aligned_item)
+     {
+        edje_object_signal_emit(VIEW(aligned_item), SIGNAL_ITEM_HIGHLIGHTED, "elm");
+        _focus_bg_show(aligned_item);
+
+        edje_object_message_signal_process(VIEW(sd->aligned_item));
+     }
 }
 
 // FIXME: Remove below macro after opensource is patched
@@ -2337,9 +2589,11 @@ _elm_genlist_pan_evas_object_smart_calculate(Eo *obj, Elm_Genlist_Pan_Data *psd)
 
    if (psd->wsd->comp_y)
      {
+        psd->wsd->unhighlight_skip = EINA_TRUE;
         eo_do((psd->wsd)->obj, elm_interface_scrollable_content_region_show(psd->wsd->pan_x,
                                                                             psd->wsd->pan_y + psd->wsd->comp_y, ow, oh));
         psd->wsd->comp_y = 0;
+        psd->wsd->unhighlight_skip = EINA_FALSE;
      }
    else if (psd->wsd->expanded_item &&
             GL_IT(psd->wsd->expanded_item)->calc_done)
@@ -2402,9 +2656,16 @@ _elm_genlist_pan_evas_object_smart_calculate(Eo *obj, Elm_Genlist_Pan_Data *psd)
               break;
           }
         if (psd->wsd->bring_in)
-                  eo_do(WIDGET(it), elm_interface_scrollable_region_bring_in(x, y, ow, oh));
+          eo_do(WIDGET(it), elm_interface_scrollable_region_bring_in(x, y, ow, oh));
         else
-           eo_do(WIDGET(it), elm_interface_scrollable_content_region_show(x, y, ow, oh));
+          {
+             if (psd->wsd->aligned_item && (psd->wsd->aligned_item != psd->wsd->adjusted_item))
+               edje_object_signal_emit(VIEW(psd->wsd->aligned_item), SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
+             psd->wsd->aligned_item = NULL;
+             psd->wsd->unhighlight_skip = EINA_TRUE;
+             eo_do(WIDGET(it), elm_interface_scrollable_content_region_show(x, y, ow, oh));
+             psd->wsd->unhighlight_skip = EINA_FALSE;
+          }
 
         _changed(psd->wsd->pan_obj);
      }
@@ -2670,6 +2931,7 @@ static void
 _item_highlight(Elm_Gen_Item *it)
 {
    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
+   ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wsd);
    Eina_Bool ret;
 
    if (!sd->highlight) return;
@@ -2680,6 +2942,13 @@ _item_highlight(Elm_Gen_Item *it)
        (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
      return;
    if (it->highlighted) return;
+   if (wsd->scroll_item_align_enable)
+     {
+        if (sd->aligned_item == it)
+          edje_object_signal_emit(wsd->resize_obj, SIGNAL_HIGHLIGHTED, "elm");
+        else
+          return;
+     }
 
    it->highlighted = EINA_TRUE;
    sd->highlighted_item = it;
@@ -2730,6 +2999,7 @@ _item_highlight(Elm_Gen_Item *it)
 static void
 _item_unhighlight(Elm_Gen_Item *it, Eina_Bool effect)
 {
+   ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wsd);
    if (!it->highlighted) return;
 
    it->highlighted = EINA_FALSE;
@@ -2750,6 +3020,10 @@ _item_unhighlight(Elm_Gen_Item *it, Eina_Bool effect)
    if (it->deco_all_view)
      edje_object_signal_emit(it->deco_all_view, SIGNAL_UNHIGHLIGHTED, "elm");
    edje_object_signal_emit(VIEW(it), SIGNAL_UNHIGHLIGHTED, "elm");
+   if (wsd->scroll_item_align_enable)
+     edje_object_signal_emit(wsd->resize_obj, SIGNAL_UNHIGHLIGHTED, "elm");
+   else
+     edje_object_signal_emit(VIEW(it), SIGNAL_UNHIGHLIGHTED, "elm");
 //******************** TIZEN Only
 // If check is used on genlist item, unhighlight it also.
    Eina_List *l;
@@ -3556,36 +3830,6 @@ _elm_genlist_elm_widget_on_focus(Eo *obj, Elm_Genlist_Data *sd, Elm_Object_Item
 
    if ((sd->items) && (sd->selected) && (!sd->last_selected_item))
      sd->last_selected_item = eina_list_data_get(sd->selected);
-   if (wd->scroll_item_align_enable)
-     {
-        Evas_Coord vw, vh;
-
-        eo_do(sd->obj, elm_interface_scrollable_content_viewport_geometry_get
-              (NULL, NULL, &vw, &vh));
-
-        if (vw != 0 || vh != 0)
-          {
-             if (!strcmp(wd->scroll_item_valign, "center"))
-               {
-                  vw = (vw / 2);
-                  vh = (vh / 2);
-               }
-
-             sd->aligned_item = _elm_genlist_pos_adjust_xy_item_get(obj, vw, vh);
-             if (sd->aligned_item)
-               {
-                  if (sd->aligned_item->realized)
-                    {
-                        //TIZEN_ONLY(20161104) : Accessibility : synchronized highlight of atspi and item align feature for wearable profile
-                        if (!_elm_atspi_enabled())
-                        //
-                          {
-                             edje_object_signal_emit(VIEW(sd->aligned_item), SIGNAL_ITEM_HIGHLIGHTED, "elm");
-                          }
-                     }
-               }
-          }
-     }
 
    if (sd->select_on_focus_enabled) return EINA_TRUE;
    if (elm_widget_focus_get(obj))
@@ -3816,6 +4060,7 @@ _elm_genlist_elm_widget_theme_apply(Eo *obj, Elm_Genlist_Data *sd)
 {
    Item_Block *itb;
    Elm_Theme_Apply int_ret = ELM_THEME_APPLY_FAILED;
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wsd, ELM_THEME_APPLY_FAILED);
 
    eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_theme_apply());
    if (!int_ret) return ELM_THEME_APPLY_FAILED;
@@ -3844,6 +4089,9 @@ _elm_genlist_elm_widget_theme_apply(Eo *obj, Elm_Genlist_Data *sd)
    elm_layout_sizing_eval(obj);
    _changed(sd->pan_obj);
 
+   if (wsd->scroll_item_align_enable && sd->aligned_item)
+     elm_genlist_item_show(EO_OBJ(sd->aligned_item), ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
+
    return int_ret;
 }
 
@@ -4928,9 +5176,21 @@ _item_mouse_up_cb(void *data,
      {
         // FIXME: if highlight mode is not used, mouse move cannot disable
         // _item_select
-        if ((sd->highlight && it->highlighted) || !sd->highlight)
+        if ((sd->was_selected == it->selected) && (!sd->on_hold))
           {
-             if (sd->was_selected == it->selected && !sd->on_hold)
+             if (wd->scroll_item_align_enable)
+               {
+                  char *align = edje_object_data_get(VIEW(it), "align");
+                  if (!align || strcmp(align, "off"))
+                    {
+                       if (it != sd->aligned_item)
+                         {
+                            elm_genlist_item_bring_in(EO_OBJ(it), ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
+                         }
+                    }
+               }
+             if (((sd->highlight && it->highlighted) || !sd->highlight) &&
+                 ((!wd->scroll_item_align_enable) || (it == sd->aligned_item)))
                GL_IT(it)->highlight_timer =
                   ecore_timer_add(ITEM_SELECT_TIMER, _select_timer, it);
           }
@@ -5120,11 +5380,13 @@ _item_update(Elm_Gen_Item *it)
 }
 
 static void
-_item_block_calc(Item_Block *itb)
+_item_block_calc(Item_Block *itb, Evas_Coord vw EINA_UNUSED, Evas_Coord vh)
 {
    const Eina_List *l;
    Elm_Gen_Item *it;
    Evas_Coord minw = 9999999, minh = 0;
+   int sum_item_height = 0;
+   ELM_WIDGET_DATA_GET_OR_RETURN(itb->sd->obj, wsd);
 
    if (itb->calc_done) return;
 
@@ -5142,6 +5404,36 @@ _item_block_calc(Item_Block *itb)
           }
         if (!GL_IT(it)->queued) _item_calc(it);
 
+        if (wsd->scroll_item_align_enable)
+          {
+             int vcenter = vh / 2;
+             int icenter = GL_IT(it)->h / 2;
+             if ((itb->y + sum_item_height < vcenter && itb->y + sum_item_height + GL_IT(it)->h > vcenter) &&
+                 (sum_item_height + icenter < vcenter - 1 || sum_item_height + icenter > vcenter + 1))
+               {
+                  int first_item_height = sum_item_height = vcenter - icenter;
+
+                  Elm_Object_Item *eo_prev = elm_genlist_item_prev_get(EO_OBJ(it));
+                  Elm_Gen_Item *prev = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
+
+                  if (prev)
+                    minh = sum_item_height;
+                  while (prev)
+                    {
+                       if (eo_prev == elm_genlist_first_item_get(wsd->obj))
+                         {
+                            GL_IT(prev)->h = GL_IT(prev)->minh = first_item_height;
+                            break;
+                         }
+                       first_item_height -= GL_IT(prev)->h;
+                       prev->y = first_item_height;
+                       eo_prev = elm_genlist_item_prev_get(eo_prev);
+                       prev = eo_data_scope_get(eo_prev, ELM_GENLIST_ITEM_CLASS);
+                    }
+               }
+             sum_item_height += GL_IT(it)->h;
+          }
+
         it->x = 0;
         it->y = minh;
         if (minw > GL_IT(it)->minw) minw = GL_IT(it)->minw;
@@ -5163,10 +5455,6 @@ _scroll_animate_start_cb(Evas_Object *obj,
                          void *data EINA_UNUSED)
 {
    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
-
-   if (wd->scroll_item_align_enable)
-     _elm_genlist_scroll_item_align_unhighlight_cb(obj);
-
    evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_START, NULL);
 }
 
@@ -5175,10 +5463,6 @@ _scroll_animate_stop_cb(Evas_Object *obj,
                         void *data EINA_UNUSED)
 {
    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
-
-   if (wd->scroll_item_align_enable)
-     _elm_genlist_scroll_item_align_highlight_cb(obj);
-
    evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_STOP, NULL);
 
    //TIZEN_ONLY: Let the screen-reader know when scroll animation ends
@@ -5194,10 +5478,6 @@ _scroll_drag_start_cb(Evas_Object *obj,
                       void *data EINA_UNUSED)
 {
    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
-
-   if (wd->scroll_item_align_enable)
-     _elm_genlist_scroll_item_align_unhighlight_cb(obj);
-
    evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_START, NULL);
 }
 
@@ -5533,6 +5813,7 @@ _elm_genlist_evas_object_smart_del(Eo *obj, Elm_Genlist_Data *sd)
                                 _evas_viewport_resize_cb, sd);
    if (sd->size_caches) eina_hash_free(sd->size_caches);
    if (sd->decorate_it_type) eina_stringshare_del(sd->decorate_it_type);
+   if (sd->clipee) evas_object_del(sd->clipee);
 
    evas_object_del(sd->pan_obj);
    eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
@@ -6004,10 +6285,18 @@ end:
    if (it == sd->top_drawn_item) sd->top_drawn_item = NULL;
 #endif
 
+   _item_unrealize(it, EINA_FALSE);
+
+   if (sd->aligned_item == it) sd->aligned_item = NULL;
+
    sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
    sd->item_count--;
 
-   _item_unrealize(it, EINA_FALSE);
+   if (it->item->proxy)
+     {
+        evas_object_smart_member_del(it->item->proxy);
+        evas_object_del(it->item->proxy);
+     }
 
    if (it->itc->func.del)
      it->itc->func.del((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it));
@@ -6392,6 +6681,9 @@ elm_genlist_item_insert_after(Evas_Object *obj,
    after_it->item->rel_revs = eina_list_append(after_it->item->rel_revs, it);
    GL_IT(it)->before = EINA_FALSE;
    _item_queue_direct(it, NULL);
+
+   if (elm_genlist_item_next_get(eo_after_it) == EO_OBJ(sd->aligned_item))
+     sd->aligned_item = NULL;
    return EO_OBJ(it);
 }
 
@@ -6448,6 +6740,10 @@ elm_genlist_item_insert_before(Evas_Object *obj,
    before_it->item->rel_revs = eina_list_append(before_it->item->rel_revs, it);
    GL_IT(it)->before = EINA_TRUE;
    _item_queue_direct(it, NULL);
+
+   if (before_it == sd->aligned_item)
+     sd->aligned_item = NULL;
+
    return EO_OBJ(it);
 }
 
@@ -7017,9 +7313,21 @@ _elm_genlist_item_bring_in(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it, Elm_Genlis
      }
 
    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
-   sd->show_item = it;
+   ELM_WIDGET_DATA_GET_OR_RETURN(WIDGET(it), wd);
    sd->bring_in = EINA_TRUE;
    sd->scroll_to_type = type;
+
+   if (wd->scroll_item_align_enable)
+     {
+        it = _adjust_item_align(it);
+        sd->adjusted_item = sd->show_item = it;
+
+        if (sd->aligned_item && sd->show_item != sd->aligned_item)
+          edje_object_signal_emit(VIEW(sd->aligned_item), SIGNAL_ITEM_UNHIGHLIGHTED, "elm");
+     }
+   else
+     sd->show_item = it;
+
    _changed(sd->pan_obj);
 }
 
index c238db87ce7a08089575bf80732ba21eb60cca67..f75b7491ed3e4af15b41f5c19c3ef146c1b22f81 100644 (file)
@@ -221,6 +221,13 @@ struct _Elm_Genlist_Data
    Ecore_Idle_Enterer                   *queue_filter_enterer;
    Eina_Bool                             filter;
    Elm_Genlist_Item_Scrollto_Type        focus_scrollto_type;
+
+   Eina_Bool                             unhighlight_skip: 1;
+   Elm_Gen_Item                          *adjusted_item;
+   Eina_Bool                             bottom_margin_enabled : 1;
+   Eina_Bool                             unhighlighted : 1;
+   Evas_Object                           *focus_bg;
+   Evas_Object                           *clipee;
 };
 
 typedef struct _Item_Block Item_Block;
@@ -282,6 +289,7 @@ struct Elm_Gen_Item_Type
    Ecore_Timer             *highlight_timer;
    Eina_Bool               multiline : 1;
    Eina_Bool               resized : 1;
+   Evas_Object             *proxy;
 };