[Genlist/list] Add focused UI implementation
authorTae-Hwan Kim <the81.kim@samsung.com>
Sun, 14 Apr 2013 13:07:32 +0000 (22:07 +0900)
committerSungho Kwak <sungho1.kwak@samsung.com>
Wed, 12 Jun 2013 02:26:07 +0000 (11:26 +0900)
For key down/up/home/end

Change-Id: I5f4b78a13f60128f8b608cff967efd5cf075456f

src/lib/elm_genlist.c
src/lib/elm_list.c
src/lib/elm_widget_genlist.h
src/lib/elm_widget_list.h

index 7306458..1688d85 100644 (file)
@@ -78,6 +78,8 @@ static const char SIG_UNHIGHLIGHTED[] = "unhighlighted";
 static const char SIG_LANG_CHANGED[] = "language,changed";
 static const char SIG_PRESSED[] = "pressed";
 static const char SIG_RELEASED[] = "released";
+static const char SIG_FOCUSED[] = "item,focused";
+static const char SIG_UNFOCUSED[] = "item,unfocused";
 
 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
    {SIG_CLICKED_DOUBLE, ""},
@@ -2363,7 +2365,7 @@ _item_single_select_down(Elm_Genlist_Smart_Data *sd)
      }
    else
      next = (Elm_Gen_Item *)elm_genlist_item_next_get
-         (sd->last_selected_item);
+        (sd->last_selected_item);
 
    if (!next) return EINA_FALSE;
 
@@ -2376,6 +2378,214 @@ _item_single_select_down(Elm_Genlist_Smart_Data *sd)
    return EINA_TRUE;
 }
 
+static void
+_item_highlight(Elm_Gen_Item *it)
+{
+   const char *selectraise;
+   Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
+
+   if (elm_widget_item_disabled_get(it)) return;
+   if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
+       (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ) ||
+       (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
+       (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
+     return;
+
+   if (!sd->highlight || it->highlighted) return;
+#if GENLIST_PINCH_ZOOM_SUPPORT
+   if (sd->pinch_zoom_mode) return;
+#endif
+
+   selectraise = edje_object_data_get(VIEW(it), "selectraise");
+   if ((selectraise) && (!strcmp(selectraise, "on")))
+     {
+        if (it->deco_all_view) evas_object_raise(it->deco_all_view);
+        else evas_object_raise(VIEW(it));
+        if ((it->item->group_item) && (it->item->group_item->realized))
+          evas_object_raise(it->item->VIEW(group_item));
+     }
+   it->highlighted = EINA_TRUE;
+
+   if (it->deco_all_view)
+     edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
+   edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
+   evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, it);
+}
+
+static void
+_item_unhighlight(Elm_Gen_Item *it)
+{
+   if (!it->highlighted) return;
+
+   if (!it->item->nostacking)
+     {
+        if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
+          {
+             if (it->deco_all_view) evas_object_lower(it->deco_all_view);
+             else evas_object_lower(VIEW(it));
+          }
+        else
+          {
+             if (it->deco_all_view) evas_object_raise(it->deco_all_view);
+             else evas_object_raise(VIEW(it));
+          }
+     }
+   it->highlighted = EINA_FALSE;
+
+   if (it->deco_all_view)
+     edje_object_signal_emit(it->deco_all_view, "elm,state,unselected", "elm");
+   edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
+   evas_object_smart_callback_call(WIDGET(it), SIG_UNHIGHLIGHTED, it);
+}
+
+static void
+_item_unselect(Elm_Gen_Item *it)
+{
+   Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
+   _item_unhighlight(it);
+   if (!it->selected) return;
+
+   it->selected = EINA_FALSE;
+   sd->selected = eina_list_remove(sd->selected, it);
+   evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
+}
+
+static void
+_item_select(Elm_Gen_Item *it)
+{
+   Evas_Object *obj = WIDGET(it);
+   Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
+   if (elm_widget_item_disabled_get(it)) return;
+   if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
+       (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
+       (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
+       (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
+     return;
+
+#if GENLIST_PINCH_ZOOM_SUPPORT
+   if (IS_ROOT_PARENT_IT(it) && (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT))
+     {
+        elm_genlist_pinch_zoom_mode_set(obj, ELM_GEN_PINCH_ZOOM_EXPAND);
+        elm_genlist_item_show((Elm_Object_Item *)it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
+        return;
+     }
+#endif
+
+#if 0
+   // FIXME: difference from upstream
+   if ((GL_IT(it)->wsd->last_selected_item) &&
+       (it != (Elm_Gen_Item *) GL_IT(it)->wsd->last_selected_item))
+     _item_unfocusable_set
+       ((Elm_Gen_Item *)GL_IT(it)->wsd->last_selected_item, EINA_TRUE);
+#endif
+
+   // Do not check selected because always select mode can be used
+   _item_highlight(it);
+   it->selected = EINA_TRUE;
+   sd->selected = eina_list_append(sd->selected, it);
+   sd->last_selected_item = (Elm_Object_Item *)it;
+
+   if (it->func.func) it->func.func((void *)it->func.data, obj, it);
+   if (!EINA_MAGIC_CHECK((Elm_Widget_Item *)it, ELM_WIDGET_ITEM_MAGIC))
+     return;
+   evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
+}
+
+static void
+_item_select_unselect(Elm_Gen_Item *it, Eina_Bool selected)
+{
+   Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
+   Evas_Object *obj = ELM_WIDGET_DATA(sd)->obj;
+   if (elm_widget_item_disabled_get(it)) return;
+
+   evas_object_ref(obj);
+   if (!sd->multi)
+     {
+        const Eina_List *l, *ll;
+        Elm_Gen_Item *it2;
+        EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it2)
+           if (it2 != it) _item_unselect(it2);
+     }
+   if (selected) _item_select(it);
+   else _item_unselect(it);
+   evas_object_unref(obj);
+}
+
+static void _item_focused(Elm_Gen_Item *it)
+{
+   if (!it) return;
+   Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
+   Evas_Coord x, y, w, h, sx, sy, sw, sh;
+
+   evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
+   evas_object_geometry_get(ELM_WIDGET_DATA(sd)->obj, &sx, &sy, &sw, &sh);
+   if ((x < sx) || (y < sy) || ((x + w) > (sx + sw)) || ((y + h) > (sy + sh)))
+     {
+        elm_genlist_item_bring_in((Elm_Object_Item *)it,
+                                  ELM_GENLIST_ITEM_SCROLLTO_IN);
+     }
+
+   edje_object_signal_emit
+      (VIEW(it), "elm,state,focused", "elm");
+   if (it->deco_all_view)
+      edje_object_signal_emit
+         (it->deco_all_view, "elm,state,focused", "elm");
+
+   sd->focused = it;
+}
+
+static void _item_unfocused(Elm_Gen_Item *it)
+{
+   if (!it) return;
+   Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
+   edje_object_signal_emit
+      (VIEW(sd->focused), "elm,state,unfocused", "elm");
+   if (sd->focused->deco_all_view)
+      edje_object_signal_emit
+         (sd->focused->deco_all_view, "elm,state,unfocused", "elm");
+   if (it == sd->focused)
+      sd->focused = NULL;
+}
+
+static Elm_Gen_Item *_item_focused_search(Elm_Gen_Item *it, int dir)
+{
+   if (!it) return NULL;
+   Elm_Gen_Item *tmp = it;
+   if (dir == 1)
+     {
+        tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->next);
+     }
+   else
+     {
+        tmp = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(tmp)->prev);
+     }
+   if (!tmp) tmp = it;
+   return tmp;
+}
+
+static void _item_focused_next(Elm_Genlist_Smart_Data *sd, int dir)
+{
+   Elm_Gen_Item *it;
+   if (elm_widget_focus_get(ELM_WIDGET_DATA(sd)->obj))
+      edje_object_signal_emit
+         (ELM_WIDGET_DATA(sd)->resize_obj, "elm,state,unfocused", "elm");
+
+   if (!sd->focused)
+     {
+        if (dir == 1)
+           it = ELM_GEN_ITEM_FROM_INLIST(sd->items);
+        else
+           it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
+     }
+   else
+     {
+        it = sd->focused;
+        _item_unfocused(sd->focused);
+        it = _item_focused_search(it, dir);
+     }
+   _item_focused(it);
+}
+
 static Eina_Bool
 _elm_genlist_smart_event(Evas_Object *obj,
                          Evas_Object *src __UNUSED__,
@@ -2390,7 +2600,6 @@ _elm_genlist_smart_event(Evas_Object *obj,
    Evas_Coord step_y = 0;
    Evas_Coord page_x = 0;
    Evas_Coord page_y = 0;
-   Elm_Object_Item *it;
    Evas_Event_Key_Down *ev = event_info;
    Evas_Coord pan_max_x = 0, pan_max_y = 0;
 
@@ -2420,43 +2629,48 @@ _elm_genlist_smart_event(Evas_Object *obj,
             ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)))
      {
         if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
-             (_item_multi_select_up(sd)))
-            || (_item_single_select_up(sd)))
+             (_item_multi_select_up(sd))))
           {
              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
              return EINA_TRUE;
           }
         else
-          y -= step_y;
+          {
+             _item_focused_next(sd, -1);
+             ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+             return EINA_TRUE;
+          }
      }
    else if ((!strcmp(ev->keyname, "Down")) ||
             ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)))
      {
         if (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
-             (_item_multi_select_down(sd)))
-            || (_item_single_select_down(sd)))
+             (_item_multi_select_down(sd))))
           {
              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
              return EINA_TRUE;
           }
         else
-          y += step_y;
+          {
+             _item_focused_next(sd, 1);
+             ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+             return EINA_TRUE;
+          }
      }
    else if ((!strcmp(ev->keyname, "Home")) ||
             ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)))
      {
-        it = elm_genlist_first_item_get(obj);
-        elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
-        elm_genlist_item_selected_set(it, EINA_TRUE);
+        _item_unfocused(sd->focused);
+        _item_focused_next(sd, 1);
         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
         return EINA_TRUE;
      }
    else if ((!strcmp(ev->keyname, "End")) ||
             ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)))
      {
-        it = elm_genlist_last_item_get(obj);
-        elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
-        elm_genlist_item_selected_set(it, EINA_TRUE);
+        _item_unfocused(sd->focused);
+        sd->focused = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
+        _item_focused_next(sd, -1);
         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
         return EINA_TRUE;
      }
@@ -2482,14 +2696,16 @@ _elm_genlist_smart_event(Evas_Object *obj,
         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
         return EINA_TRUE;
      }
-   else if (((!strcmp(ev->keyname, "Return")) ||
-             (!strcmp(ev->keyname, "KP_Enter")) ||
-             (!strcmp(ev->keyname, "space")))
-            && (!sd->multi) && (sd->selected))
+   else if (!strcmp(ev->keyname, "Return") ||
+            !strcmp(ev->keyname, "KP_Enter") ||
+            !strcmp(ev->keyname, "space"))
      {
-        it = elm_genlist_selected_item_get(obj);
-        elm_genlist_item_expanded_set(it, !elm_genlist_item_expanded_get(it));
-        evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
+        if (sd->focused)
+          {
+             Elm_Gen_Item *it = sd->focused;
+             _item_select_unselect(it, EINA_TRUE);
+             evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
+          }
      }
    else return EINA_FALSE;
 
@@ -2551,6 +2767,7 @@ _elm_genlist_smart_on_focus(Evas_Object *obj)
 {
    ELM_GENLIST_DATA_GET(obj, sd);
 
+   // Why does parent do first?
    if (!ELM_WIDGET_CLASS(_elm_genlist_parent_sc)->on_focus(obj))
      return EINA_FALSE;
 
@@ -2558,6 +2775,32 @@ _elm_genlist_smart_on_focus(Evas_Object *obj)
        (!sd->last_selected_item))
      sd->last_selected_item = eina_list_data_get(sd->selected);
 
+   if (elm_widget_focus_get(obj))
+     {
+        if (sd->focused)
+          {
+             edje_object_signal_emit
+                (VIEW(sd->focused), "elm,state,focused", "elm");
+             if (sd->focused->deco_all_view)
+                edje_object_signal_emit
+                   (sd->focused->deco_all_view, "elm,state,focused", "elm");
+          }
+        else
+           edje_object_signal_emit(ELM_WIDGET_DATA(sd)->resize_obj, "elm,state,focused", "elm");
+     }
+   else
+     {
+        if (sd->focused)
+          {
+             edje_object_signal_emit
+                (VIEW(sd->focused), "elm,state,unfocused", "elm");
+             if (sd->focused->deco_all_view)
+                edje_object_signal_emit
+                   (sd->focused->deco_all_view, "elm,state,unfocused", "elm");
+          }
+        else
+           edje_object_signal_emit(ELM_WIDGET_DATA(sd)->resize_obj, "elm,state,unfocused", "elm");
+     }
    return EINA_TRUE;
 }
 
@@ -2692,139 +2935,6 @@ _elm_genlist_smart_translate(Evas_Object *obj)
 }
 
 static void
-_item_highlight(Elm_Gen_Item *it)
-{
-   const char *selectraise;
-   Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
-
-   if (elm_widget_item_disabled_get(it)) return;
-   if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
-       (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ) ||
-       (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
-       (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY ))
-     return;
-
-   if (!sd->highlight || it->highlighted) return;
-#if GENLIST_PINCH_ZOOM_SUPPORT
-   if (sd->pinch_zoom_mode) return;
-#endif
-
-   selectraise = edje_object_data_get(VIEW(it), "selectraise");
-   if ((selectraise) && (!strcmp(selectraise, "on")))
-     {
-        if (it->deco_all_view) evas_object_raise(it->deco_all_view);
-        else evas_object_raise(VIEW(it));
-        if ((it->item->group_item) && (it->item->group_item->realized))
-          evas_object_raise(it->item->VIEW(group_item));
-     }
-   it->highlighted = EINA_TRUE;
-
-   if (it->deco_all_view)
-     edje_object_signal_emit(it->deco_all_view, "elm,state,selected", "elm");
-   edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
-   evas_object_smart_callback_call(WIDGET(it), SIG_HIGHLIGHTED, it);
-}
-
-static void
-_item_unhighlight(Elm_Gen_Item *it)
-{
-   if (!it->highlighted) return;
-
-   if (!it->item->nostacking)
-     {
-        if ((it->item->order_num_in & 0x1) ^ it->item->stacking_even)
-          {
-             if (it->deco_all_view) evas_object_lower(it->deco_all_view);
-             else evas_object_lower(VIEW(it));
-          }
-        else
-          {
-             if (it->deco_all_view) evas_object_raise(it->deco_all_view);
-             else evas_object_raise(VIEW(it));
-          }
-     }
-   it->highlighted = EINA_FALSE;
-
-   if (it->deco_all_view)
-     edje_object_signal_emit(it->deco_all_view, "elm,state,unselected", "elm");
-   edje_object_signal_emit(VIEW(it), "elm,state,unselected", "elm");
-   evas_object_smart_callback_call(WIDGET(it), SIG_UNHIGHLIGHTED, it);
-}
-
-static void
-_item_unselect(Elm_Gen_Item *it)
-{
-   Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
-   _item_unhighlight(it);
-   if (!it->selected) return;
-
-   it->selected = EINA_FALSE;
-   sd->selected = eina_list_remove(sd->selected, it);
-   evas_object_smart_callback_call(WIDGET(it), SIG_UNSELECTED, it);
-}
-
-static void
-_item_select(Elm_Gen_Item *it)
-{
-   Evas_Object *obj = WIDGET(it);
-   Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
-   if (elm_widget_item_disabled_get(it)) return;
-   if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
-       (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
-       (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
-       (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
-     return;
-
-#if GENLIST_PINCH_ZOOM_SUPPORT
-   if (IS_ROOT_PARENT_IT(it) && (sd->pinch_zoom_mode == ELM_GEN_PINCH_ZOOM_CONTRACT))
-     {
-        elm_genlist_pinch_zoom_mode_set(obj, ELM_GEN_PINCH_ZOOM_EXPAND);
-        elm_genlist_item_show((Elm_Object_Item *)it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
-        return;
-     }
-#endif
-
-#if 0
-   // FIXME: difference from upstream
-   if ((GL_IT(it)->wsd->last_selected_item) &&
-       (it != (Elm_Gen_Item *) GL_IT(it)->wsd->last_selected_item))
-     _item_unfocusable_set
-       ((Elm_Gen_Item *)GL_IT(it)->wsd->last_selected_item, EINA_TRUE);
-#endif
-
-   // Do not check selected because always select mode can be used
-   _item_highlight(it);
-   it->selected = EINA_TRUE;
-   sd->selected = eina_list_append(sd->selected, it);
-   sd->last_selected_item = (Elm_Object_Item *)it;
-
-   if (it->func.func) it->func.func((void *)it->func.data, obj, it);
-   if (!EINA_MAGIC_CHECK((Elm_Widget_Item *)it, ELM_WIDGET_ITEM_MAGIC))
-     return;
-   evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, it);
-}
-
-static void
-_item_select_unselect(Elm_Gen_Item *it, Eina_Bool selected)
-{
-   Elm_Genlist_Smart_Data *sd = GL_IT(it)->wsd;
-   Evas_Object *obj = ELM_WIDGET_DATA(sd)->obj;
-   if (elm_widget_item_disabled_get(it)) return;
-
-   evas_object_ref(obj);
-   if (!sd->multi)
-     {
-        const Eina_List *l, *ll;
-        Elm_Gen_Item *it2;
-        EINA_LIST_FOREACH_SAFE(sd->selected, l, ll, it2)
-           if (it2 != it) _item_unselect(it2);
-     }
-   if (selected) _item_select(it);
-   else _item_unselect(it);
-   evas_object_unref(obj);
-}
-
-static void
 _item_block_position_update(Eina_Inlist *list,
                             int idx)
 {
@@ -4898,7 +5008,7 @@ _elm_genlist_smart_set_user(Elm_Genlist_Smart_Class *sc)
    ELM_WIDGET_CLASS(sc)->translate = _elm_genlist_smart_translate;
 
    /* not a 'focus chain manager' */
-   ELM_WIDGET_CLASS(sc)->focus_next = NULL;
+   ELM_WIDGET_CLASS(sc)->focus_next = NULL; //_elm_genlist_smart_focus_next;
    ELM_WIDGET_CLASS(sc)->focus_direction = NULL;
 
    ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_genlist_smart_sizing_eval;
index 0f2fc58..1f7e131 100644 (file)
@@ -44,6 +44,10 @@ static void _mouse_up_cb(void *, Evas *, Evas_Object *, void *);
 static void _mouse_down_cb(void *, Evas *, Evas_Object *, void *);
 static void _mouse_move_cb(void *, Evas *, Evas_Object *, void *);
 static void _items_fix(Evas_Object *);
+static void _item_select(Elm_List_Item *it);
+static void _item_unselect(Elm_List_Item *it);
+
+
 
 EVAS_SMART_SUBCLASS_IFACE_NEW
   (ELM_LIST_SMART_NAME, _elm_list, Elm_List_Smart_Class,
@@ -192,6 +196,71 @@ _item_single_select_down(Elm_List_Smart_Data *sd)
    return EINA_TRUE;
 }
 
+static void _item_focused(Elm_List_Item *it)
+{
+   if (!it) return;
+   Elm_List_Smart_Data *sd = it->sd;
+   Evas_Coord x, y, w, h, sx, sy, sw, sh;
+
+   evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
+   evas_object_geometry_get(ELM_WIDGET_DATA(sd)->obj, &sx, &sy, &sw, &sh);
+   if ((x < sx) || (y < sy) || ((x + w) > (sx + sw)) || ((y + h) > (sy + sh)))
+     {
+        elm_list_item_bring_in((Elm_Object_Item *)it);
+     }
+
+   edje_object_signal_emit
+      (VIEW(it), "elm,state,focused", "elm");
+
+   sd->focused = (Elm_Object_Item *)it;
+}
+
+static void _item_unfocused(Elm_List_Item *it)
+{
+   if (!it) return;
+   Elm_List_Smart_Data *sd = it->sd;
+   edje_object_signal_emit
+      (VIEW(sd->focused), "elm,state,unfocused", "elm");
+   if (it == (Elm_List_Item *)sd->focused)
+      sd->focused = NULL;
+}
+
+static Elm_List_Item *_item_focused_search(Elm_List_Item *it, int dir)
+{
+   if (!it) return NULL;
+   Eina_List *l = eina_list_data_find_list(it->sd->items, it);
+   Eina_List *tmp = l;
+   if (dir == 1) tmp = eina_list_next(tmp);
+   else tmp = eina_list_prev(tmp);
+   if (!tmp) tmp = l;
+   return (Elm_List_Item *)eina_list_data_get(tmp);
+}
+
+static void _item_focused_next(Elm_List_Smart_Data *sd, int dir)
+{
+   Elm_List_Item *it = NULL;
+
+   if (elm_widget_focus_get(ELM_WIDGET_DATA(sd)->obj))
+      edje_object_signal_emit
+         (ELM_WIDGET_DATA(sd)->resize_obj, "elm,state,unfocused", "elm");
+
+   if (!sd->focused)
+     {
+        if (dir == 1)
+           it = (Elm_List_Item *)eina_list_data_get(sd->items);
+        else
+           it = (Elm_List_Item *)eina_list_data_get(eina_list_last(sd->items));
+     }
+   else
+     {
+        it = (Elm_List_Item *)sd->focused;
+        _item_unfocused((Elm_List_Item *)sd->focused);
+        it = _item_focused_search(it, dir);
+     }
+   _item_focused(it);
+}
+
+
 static Eina_Bool
 _elm_list_smart_event(Evas_Object *obj,
                       Evas_Object *src __UNUSED__,
@@ -254,43 +323,49 @@ _elm_list_smart_event(Evas_Object *obj,
             ((!strcmp(ev->keyname, "KP_Up")) && !ev->string))
      {
         if ((!sd->h_mode) &&
-            (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
-              (_item_multi_select_up(sd)))
-             || (_item_single_select_up(sd))))
+            (evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
+            (_item_multi_select_up(sd)))
           {
              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
              return EINA_TRUE;
           }
         else
-          y -= step_y;
+          {
+             _item_focused_next(sd, -1);
+             ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+             return EINA_TRUE;
+          }
      }
    else if ((!strcmp(ev->keyname, "Down")) ||
             ((!strcmp(ev->keyname, "KP_Down")) && !ev->string))
      {
         if ((!sd->h_mode) &&
-            (((evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
-              (_item_multi_select_down(sd)))
-             || (_item_single_select_down(sd))))
+            (evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
+            (_item_multi_select_down(sd)))
           {
              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
              return EINA_TRUE;
           }
         else
-          y += step_y;
+          {
+             _item_focused_next(sd, 1);
+             ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+             return EINA_TRUE;
+          }
      }
    else if ((!strcmp(ev->keyname, "Home")) ||
             ((!strcmp(ev->keyname, "KP_Home")) && !ev->string))
      {
-        it = eina_list_data_get(sd->items);
-        elm_list_item_bring_in((Elm_Object_Item *)it);
+        _item_unfocused((Elm_List_Item *)sd->focused);
+        _item_focused_next(sd, 1);
         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
         return EINA_TRUE;
      }
    else if ((!strcmp(ev->keyname, "End")) ||
             ((!strcmp(ev->keyname, "KP_End")) && !ev->string))
      {
-        it = eina_list_data_get(eina_list_last(sd->items));
-        elm_list_item_bring_in((Elm_Object_Item *)it);
+        _item_unfocused((Elm_List_Item *)sd->focused);
+        _item_focused_next(sd, -1);
         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
         return EINA_TRUE;
      }
@@ -332,11 +407,17 @@ _elm_list_smart_event(Evas_Object *obj,
      }
    else if (((!strcmp(ev->keyname, "Return")) ||
              (!strcmp(ev->keyname, "KP_Enter")) ||
-             (!strcmp(ev->keyname, "space")))
-            && (!sd->multi) && (sd->selected))
+             (!strcmp(ev->keyname, "space"))) &&
+            (!sd->multi))
      {
-        it = (Elm_List_Item *)elm_list_selected_item_get(obj);
-        if (it) evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
+        if (sd->focused)
+          {
+             it = (Elm_List_Item *)sd->focused;
+             _item_select(it);
+             evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
+             it->selected = EINA_FALSE;
+             sd->selected = eina_list_remove(sd->selected, it);
+          }
      }
    else if (!strcmp(ev->keyname, "Escape"))
      {
@@ -792,6 +873,26 @@ _elm_list_smart_on_focus(Evas_Object *obj)
    if (elm_widget_focus_get(obj) && sd->selected && !sd->last_selected_item)
      sd->last_selected_item = eina_list_data_get(sd->selected);
 
+   if (elm_widget_focus_get(obj))
+     {
+        if (sd->focused)
+          {
+             edje_object_signal_emit
+                (VIEW(sd->focused), "elm,state,focused", "elm");
+                 }
+        else
+           edje_object_signal_emit(ELM_WIDGET_DATA(sd)->resize_obj, "elm,state,focused", "elm");
+     }
+   else
+     {
+        if (sd->focused)
+          {
+             edje_object_signal_emit
+                (VIEW(sd->focused), "elm,state,unfocused", "elm");
+          }
+        else
+           edje_object_signal_emit(ELM_WIDGET_DATA(sd)->resize_obj, "elm,state,unfocused", "elm");
+     }
    return EINA_TRUE;
 }
 
index 4895434..07967d8 100644 (file)
@@ -139,6 +139,7 @@ struct _Elm_Genlist_Smart_Data
    Evas_Object                          *hit_rect;
    Evas_Object                          *pan_obj;
 
+   Elm_Gen_Item                         *focused;
    Eina_List                            *selected; /* a list of
                                                     * selected
                                                     * items */
index 8bd51c5..6b9fe38 100644 (file)
@@ -131,6 +131,7 @@ struct _Elm_List_Smart_Data
    Evas_Object                          *box, *hit_rect;
    const Elm_Scrollable_Smart_Interface *s_iface;
 
+   Elm_Object_Item                      *focused;
    Eina_List                            *items, *selected, *to_delete;
    Elm_Object_Item                      *last_selected_item;
    Evas_Coord                            minw[2], minh[2];