genlist: add on focus handling when item's child has focus.
authorHosang Kim <hosang12.kim@samsung.com>
Fri, 25 Nov 2016 06:15:34 +0000 (15:15 +0900)
committerWonki Kim <wonki_.kim@samsung.com>
Mon, 2 Jan 2017 05:37:03 +0000 (14:37 +0900)
Signed-off-by: Hosang Kim <hosang12.kim@samsung.com>
Change-Id: I6c6735d55ad9cc9dbeec8784b0dacadfacbc29db

src/mobile_lib/elm_genlist.c

index 725df1c..b1055cc 100644 (file)
@@ -198,6 +198,7 @@ static void _evas_viewport_resize_cb(void *d, Evas *e EINA_UNUSED, void *ei EINA
 static Eina_Bool _item_process(Elm_Genlist_Data *sd, Elm_Gen_Item *it);
 static int _is_item_in_viewport(int viewport_y, int viewport_h, int obj_y, int obj_h);
 static Eina_Bool _item_filtered_get(Elm_Gen_Item *it);
+static Eina_Bool _item_focusable_search(Elm_Gen_Item **it, int dir);
 
 typedef struct _Size_Cache {
      Evas_Coord minw;
@@ -2852,14 +2853,7 @@ static void _item_unfocused(Elm_Gen_Item *it)
    if (!it) return;
    Elm_Genlist_Data *sd = GL_IT(it)->wsd;
    if (!sd->focused_item || it != sd->focused_item) return;
-   Evas_Object *content = sd->focused_content;
 
-   if (content)
-     {
-        elm_object_focus_set(sd->obj, EINA_FALSE);
-        elm_object_focus_set(sd->obj, EINA_TRUE);
-        sd->focused_content = NULL;
-     }
    edje_object_signal_emit
       (VIEW(sd->focused_item), SIGNAL_UNFOCUSED, "elm");
    if (sd->focused_item->deco_all_view)
@@ -3100,6 +3094,13 @@ _item_select(Elm_Gen_Item *it)
      }
    sd->last_selected_item = EO_OBJ(it);
    _item_highlight(it);
+
+   if (sd->focused_content)
+     {
+        elm_object_focus_set(sd->focused_content, EINA_FALSE);
+        sd->focused_content = NULL;
+     }
+
    sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
    elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
 
@@ -3168,15 +3169,21 @@ static Evas_Object
         next = eina_list_data_get(l);
         if (next && (elm_widget_can_focus_get(next) &&
                    (evas_object_visible_get(next))))
-           break;
+          break;
         else if (next && (elm_widget_child_can_focus_get(next)))
           {
-             if ((dir == 1) && (elm_widget_focus_next_get
-                               (next, ELM_FOCUS_RIGHT, &next, &next_item)))
-                break;
-             else if ((dir == -1) && (elm_widget_focus_next_get
-                                     (next, ELM_FOCUS_LEFT, &next, &next_item)))
-                break;
+             if (elm_widget_focused_object_get(next))
+               break;
+             else
+               {
+                  Evas_Object *child = next;
+                  if ((dir == 1) &&
+                      (elm_widget_focus_next_get(next, ELM_FOCUS_RIGHT, &child, &next_item)))
+                    break;
+                  else if ((dir == -1) &&
+                           (elm_widget_focus_next_get(next, ELM_FOCUS_LEFT, &child, &next_item)))
+                    break;
+               }
           }
 
         next = NULL;
@@ -3204,11 +3211,18 @@ static Eina_Bool _item_focusable_search(Elm_Gen_Item **it, int dir)
              if ((tmp->select_mode == ELM_OBJECT_SELECT_MODE_DEFAULT) ||
                  (tmp->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS))
                {
+
+                  if (GL_IT(tmp)->wsd->focused_content)
+                    {
+                       elm_object_focus_set(GL_IT(tmp)->wsd->focused_content, EINA_FALSE);
+                       GL_IT(tmp)->wsd->focused_content = NULL;
+                    }
                   *it = tmp;
                   return EINA_TRUE;
                }
 
              if ((tmp->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
+                 (tmp->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
                  (tmp->flipped))
                {
                   Evas_Object *obj = NULL;
@@ -3238,11 +3252,12 @@ static Eina_Bool _item_focusable_search(Elm_Gen_Item **it, int dir)
 
                   if (obj)
                     {
-                       GL_IT(tmp)->wsd->focused_item = tmp;
+                       if (GL_IT(tmp)->wsd->focused_content)
+                         elm_object_focus_set(GL_IT(tmp)->wsd->focused_content, EINA_FALSE);
                        GL_IT(tmp)->wsd->focused_content = obj;
                        elm_object_focus_set(obj, EINA_TRUE);
                        *it = tmp;
-                       return EINA_FALSE;
+                       return EINA_TRUE;
                     }
                }
           }
@@ -3354,8 +3369,7 @@ static Eina_Bool _item_focus_next(Elm_Genlist_Data *sd, Focus_Dir dir)
                   //search focused content is child of content
                   if (sd->focused_content)
                     l = eina_list_data_find_list(contents,
-                                                 elm_widget_parent_get
-                                                 (sd->focused_content));
+                                                 sd->focused_content);
                   if (!l) l = eina_list_last(contents);
                   obj = _item_focusable_content_search(obj, l, -1);
                }
@@ -3374,8 +3388,7 @@ static Eina_Bool _item_focus_next(Elm_Genlist_Data *sd, Focus_Dir dir)
                   //search focused content is child of content
                   if (sd->focused_content)
                     l = eina_list_data_find_list(contents,
-                                                 elm_widget_parent_get
-                                                 (sd->focused_content));
+                                                 sd->focused_content);
                   if (!l) l = contents;
                   obj = _item_focusable_content_search(obj, l, 1);
                }
@@ -3432,6 +3445,27 @@ _elm_genlist_elm_widget_event(Eo *obj, Elm_Genlist_Data *sd, Evas_Object *src EI
          (NULL, NULL, &v_w, &v_h));
 
    if ((!strcmp(ev->keyname, "Left")) ||
+       ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)) ||
+       (!strcmp(ev->keyname, "Right")) ||
+       ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)) ||
+       (!strcmp(ev->keyname, "Up")) ||
+       ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)) ||
+       (!strcmp(ev->keyname, "Down")) ||
+       ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)) ||
+       (!strcmp(ev->keyname, "Home")) ||
+       ((!strcmp(ev->keyname, "KP_Home")) && (!ev->string)) ||
+       (!strcmp(ev->keyname, "End")) ||
+       ((!strcmp(ev->keyname, "KP_End")) && (!ev->string)) ||
+       (!strcmp(ev->keyname, "Prior")) ||
+       ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)) ||
+       (!strcmp(ev->keyname, "Next")) ||
+       ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
+     {
+        if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
+        _elm_widget_focus_auto_show(obj);
+     }
+
+   if ((!strcmp(ev->keyname, "Left")) ||
        ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
      {
         if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
@@ -3849,6 +3883,37 @@ _elm_genlist_elm_widget_on_focus(Eo *obj, Elm_Genlist_Data *sd, Elm_Object_Item
                        elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
                     }
                }
+             else
+               elm_object_focus_set(sd->focused_content, EINA_TRUE);
+          }
+        else if (elm_widget_focused_object_get(obj) &&
+                 (obj != elm_widget_focused_object_get(obj)))
+          {
+             Item_Block *itb, *nib;
+             Eina_List *l, *ll;
+             Evas_Object *content = NULL;
+             Elm_Gen_Item *it;
+             EINA_INLIST_FOREACH(sd->blocks, itb)
+               {
+                  if (itb->realized)
+                    {
+                       EINA_LIST_FOREACH(itb->items, l, it)
+                         {
+                            EINA_LIST_FOREACH(it->content_objs, ll, content)
+                              {
+                                 if (elm_widget_focused_object_get(content))
+                                   {
+                                      sd->focused_item = it;
+                                      sd->focused_content = content;
+                                      goto success;
+                                   }
+                              }
+                         }
+
+                       nib = EINA_INLIST_CONTAINER_GET(EINA_INLIST_GET(itb)->next, Item_Block);
+                       if (!nib || !nib->realized) goto fail;
+                    }
+               }
           }
         else
           {
@@ -3869,7 +3934,7 @@ _elm_genlist_elm_widget_on_focus(Eo *obj, Elm_Genlist_Data *sd, Elm_Object_Item
                                  if (ELM_RECTS_INCLUDE(sx, sy, sw, sh, x, y, w, h))
                                    {
                                       elm_object_item_focus_set(EO_OBJ(tmp), EINA_TRUE);
-                                      goto done;
+                                      goto success;
                                    }
                               }
 
@@ -3878,10 +3943,9 @@ _elm_genlist_elm_widget_on_focus(Eo *obj, Elm_Genlist_Data *sd, Elm_Object_Item
                          }
 
                        nib = EINA_INLIST_CONTAINER_GET(EINA_INLIST_GET(itb)->next, Item_Block);
-                       if (!nib || !nib->realized) goto done;
+                       if (!nib || !nib->realized) break;
                     }
                }
-done:
              if (!sd->focused_item) _item_focus_next(sd, FOCUS_DIR_DOWN);
           }
      }
@@ -3910,10 +3974,13 @@ done:
                 edje_object_signal_emit
                    (sd->focused_item->deco_all_view, SIGNAL_UNFOCUSED, "elm");
           }
-        return EINA_FALSE;
      }
 
+success:
    return EINA_TRUE;
+
+fail:
+   return EINA_FALSE;
 }
 
 EOLIAN static void
@@ -4431,7 +4498,9 @@ _long_press_cb(void *data)
 
    if (eo_do_ret(EO_OBJ(it), ret, elm_wdg_item_disabled_get()) ||
        (it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
-       (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY))
+       (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE) ||
+       (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
+       (sd->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
      goto end;
 
    if ((sd->reorder_mode) &&
@@ -5196,6 +5265,20 @@ _item_mouse_up_cb(void *data,
                  ((!wd->scroll_item_align_enable) || (it == sd->aligned_item)))
                GL_IT(it)->highlight_timer =
                   ecore_timer_add(ITEM_SELECT_TIMER, _select_timer, it);
+             else if ((it->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
+                      (it->select_mode == ELM_OBJECT_SELECT_MODE_NONE))
+               {
+                  if (sd->focused_item != it)
+                    {
+                       Eina_Bool found = EINA_FALSE;
+                       found = _item_focusable_search(&it, 1);
+                       if (found)
+                         {
+                            sd->focus_scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN;
+                            elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
+                         }
+                    }
+               }
           }
      }
    else if (sd->reorder.it == it)