genlist: Add item loop feature
authorHosang Kim <hosang.kim@samsung.com>
Thu, 24 Apr 2014 05:12:52 +0000 (14:12 +0900)
committerChunEon Park <hermet@hermet.pe.kr>
Thu, 24 Apr 2014 05:17:35 +0000 (14:17 +0900)
Summary:
If item loop feature is enabled, item is moved infinitely.

    1. Refactor direction key event handling routine
      - added internal function _elm_genlist_elm_widget_event_direction.
    2. Add looping feature for genlist
      - added Eolian function _elm_genlist_elm_widget_item_loop_enabled_set/get.
    3. Add demo - test_genlist.c / genlist focus

Reviewers: seoz, woohyun, jaehwan, Hermet, raster

Reviewed By: Hermet

Differential Revision: https://phab.enlightenment.org/D778

Conflicts:

src/lib/elm_widget_genlist.h

src/bin/test_genlist.c
src/lib/elm_genlist.c
src/lib/elm_genlist.eo
src/lib/elm_widget_genlist.h

index 14186a7..4557804 100644 (file)
@@ -3615,7 +3615,7 @@ test_genlist_del(void *data EINA_UNUSED,
 }
 
 /*************/
-static unsigned _gl_focus_objects = 5;
+static unsigned _gl_focus_objects = 3;
 static const char *_gl_focus_object_names[] = {"None", "Square", "Button", "Check", "Box"};
 
 static char *
@@ -3675,6 +3675,14 @@ gl_focus_content_get(void *data, Evas_Object *obj, const char *part)
 }
 
 static void
+test_genlist_focus_item_loop_enable_check_changed(void *data, Evas_Object *obj,
+                                               void *event_info  EINA_UNUSED)
+{
+   Evas_Object *gl = data;
+   elm_object_scroll_item_loop_enabled_set(gl, elm_check_state_get(obj));
+}
+
+static void
 test_genlist_focus_focus_on_selection_set(Evas_Object *gl,
                                           Evas_Object *chk, Eina_Bool focus)
 {
@@ -3947,6 +3955,14 @@ test_genlist_focus(void *data EINA_UNUSED,
    elm_box_pack_end(bx_opt, chk);
    evas_object_show(chk);
 
+   chk = elm_check_add(bx_opt);
+   elm_object_text_set(chk, "Item Looping Enalbe");
+   evas_object_size_hint_weight_set(chk, EVAS_HINT_EXPAND, 0.0);
+   evas_object_smart_callback_add(chk, "changed",
+                                  test_genlist_focus_item_loop_enable_check_changed, gl);
+   elm_box_pack_end(bx_opt, chk);
+   evas_object_show(chk);
+
    // Focus Movement Policy
    fr = elm_frame_add(bx);
    elm_object_text_set(fr, "Focus Movement Policy");
index db317d4..28cd2f1 100644 (file)
@@ -2577,6 +2577,64 @@ _elm_genlist_item_content_focus_set(Elm_Gen_Item *it, Elm_Focus_Direction dir)
 }
 
 static Eina_Bool
+_elm_genlist_elm_widget_event_direction(Evas_Object *obj, Elm_Focus_Direction dir, Eina_Bool multi)
+{
+   ELM_GENLIST_DATA_GET(obj, sd);
+   Elm_Object_Item *it = NULL;
+   Eina_Bool ret = EINA_FALSE;
+   Evas_Coord v = 0;
+   Evas_Coord min = 0;
+
+   // get content size and viewport size
+   eo_do(obj,
+         elm_interface_scrollable_content_viewport_geometry_get
+         (NULL, NULL, NULL, &v),
+         elm_interface_scrollable_content_size_get(NULL, &min));
+
+   if (multi)
+     {
+        if (dir == ELM_FOCUS_UP)
+          ret = _item_multi_select_up(sd);
+        else if (dir == ELM_FOCUS_DOWN)
+          ret = _item_multi_select_down(sd);
+     }
+   else
+     {
+        if (dir == ELM_FOCUS_UP)
+          ret = _item_single_select_up(sd);
+        else if (dir == ELM_FOCUS_DOWN)
+          ret = _item_single_select_down(sd);
+     }
+   if (ret)
+     return EINA_TRUE;
+
+   // handle item loop feature
+   if (sd->item_loop_enable)
+     {
+        if (min > v)
+          {
+             if (dir == ELM_FOCUS_UP)
+               elm_layout_signal_emit(obj, "elm,action,looping,up", "elm");
+             else if (dir == ELM_FOCUS_DOWN)
+               elm_layout_signal_emit(obj, "elm,action,looping,down", "elm");
+          }
+        else
+          {
+             if (dir == ELM_FOCUS_UP)
+               it = elm_genlist_last_item_get(obj);
+            else if(dir == ELM_FOCUS_DOWN)
+               it = elm_genlist_first_item_get(obj);
+
+             if (it)
+               elm_genlist_item_selected_set(it, EINA_TRUE);
+          }
+        return EINA_TRUE;
+     }
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
 _key_action_move(Evas_Object *obj, const char *params)
 {
    ELM_GENLIST_DATA_GET(obj, sd);
@@ -2620,24 +2678,24 @@ _key_action_move(Evas_Object *obj, const char *params)
      }
    else if (!strcmp(dir, "up"))
      {
-        if (_item_single_select_up(sd)) return EINA_TRUE;
+        if (_elm_genlist_elm_widget_event_direction(obj, ELM_FOCUS_UP, EINA_FALSE)) return EINA_TRUE;
         else return EINA_FALSE;
      }
    else if (!strcmp(dir, "up_multi"))
      {
-        if (_item_multi_select_up(sd)) return EINA_TRUE;
-        else if (_item_single_select_up(sd)) return EINA_TRUE;
+        if (_elm_genlist_elm_widget_event_direction(obj, ELM_FOCUS_UP, EINA_TRUE)) return EINA_TRUE;
+        else if (_elm_genlist_elm_widget_event_direction(obj, ELM_FOCUS_UP, EINA_FALSE)) return EINA_TRUE;
         else return EINA_FALSE;
      }
    else if (!strcmp(dir, "down"))
      {
-        if (_item_single_select_down(sd)) return EINA_TRUE;
+        if (_elm_genlist_elm_widget_event_direction(obj, ELM_FOCUS_DOWN, EINA_FALSE)) return EINA_TRUE;
         else return EINA_FALSE;
      }
    else if (!strcmp(dir, "down_multi"))
      {
-        if (_item_multi_select_down(sd)) return EINA_TRUE;
-        else if (_item_single_select_down(sd)) return EINA_TRUE;
+        if (_elm_genlist_elm_widget_event_direction(obj, ELM_FOCUS_DOWN, EINA_TRUE)) return EINA_TRUE;
+        else if (_elm_genlist_elm_widget_event_direction(obj, ELM_FOCUS_DOWN, EINA_FALSE)) return EINA_TRUE;
         else return EINA_FALSE;
      }
    else if (!strcmp(dir, "first"))
@@ -5092,6 +5150,31 @@ _decorate_item_unset(Elm_Genlist_Data *sd)
    sd->mode_item = NULL;
 }
 
+static void
+_elm_genlist_looping_up_cb(void *data,
+                          Evas_Object *obj EINA_UNUSED,
+                          const char *emission EINA_UNUSED,
+                          const char *source EINA_UNUSED)
+{
+   Evas_Object *genlist = data;
+   Elm_Object_Item *it = elm_genlist_last_item_get(genlist);
+   elm_genlist_item_selected_set(it, EINA_TRUE);
+   elm_layout_signal_emit(genlist, "elm,action,looping,up,end", "elm");
+}
+
+static void
+_elm_genlist_looping_down_cb(void *data,
+                          Evas_Object *obj EINA_UNUSED,
+                          const char *emission EINA_UNUSED,
+                          const char *source EINA_UNUSED)
+{
+   Evas_Object *genlist = data;
+   Elm_Object_Item *it = elm_genlist_first_item_get(genlist);
+   elm_genlist_item_selected_set(it, EINA_TRUE);
+   elm_layout_signal_emit(genlist, "elm,action,looping,down,end", "elm");
+}
+
+
 EOLIAN static void
 _elm_genlist_evas_smart_add(Eo *obj, Elm_Genlist_Data *priv)
 {
@@ -5169,6 +5252,9 @@ _elm_genlist_evas_smart_add(Eo *obj, Elm_Genlist_Data *priv)
    _mirrored_set(obj, elm_widget_mirrored_get(obj));
 
    elm_layout_sizing_eval(obj);
+
+   edje_object_signal_callback_add(wd->resize_obj, "elm,looping,up,done", "elm", _elm_genlist_looping_up_cb, obj);
+   edje_object_signal_callback_add(wd->resize_obj, "elm,looping,down,done", "elm", _elm_genlist_looping_down_cb, obj);
 }
 
 EOLIAN static void
@@ -7374,6 +7460,19 @@ _elm_genlist_elm_widget_focused_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *
 }
 
 EOLIAN static void
+_elm_genlist_elm_widget_item_loop_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool enable)
+{
+   if (sd->item_loop_enable == enable) return;
+   sd->item_loop_enable = !!enable;
+}
+
+EOLIAN static Eina_Bool
+_elm_genlist_elm_widget_item_loop_enabled_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
+{
+   return sd->item_loop_enable;
+}
+
+EOLIAN static void
 _elm_genlist_class_constructor(Eo_Class *klass)
 {
    if (_elm_config->access_mode)
index 0e9fc8d..0a2d74a 100644 (file)
@@ -701,6 +701,8 @@ class Elm_Genlist (Elm_Layout, Elm_Interface_Scrollable, Evas_Clickable_Interfac
       Elm_Widget::sub_object_del;
       Elm_Widget::event;
       Elm_Widget::focused_item::get;
+      Elm_Widget::item_loop_enabled::set;
+      Elm_Widget::item_loop_enabled::get;
       Elm_Layout::sub_object_add_enable;
       Elm_Layout::sizing_eval;
       Elm_Interface_Scrollable::bounce_allow;
index 19991c4..af187b2 100644 (file)
@@ -184,6 +184,8 @@ struct _Elm_Genlist_Data
                                                      * selection */
 
    Eina_Bool                             swipe : 1;
+   /**< value whether item loop feature is enabled or not. */
+   Eina_Bool                             item_loop_enable : 1;
 };
 
 typedef struct _Item_Block Item_Block;