elm_widget: Introduce elm_focus_legacy
authorMarcel Hollerbach <marcel@osg.samsung.com>
Thu, 12 Apr 2018 19:28:49 +0000 (21:28 +0200)
committerWonki Kim <wonki_.kim@samsung.com>
Thu, 31 May 2018 05:51:40 +0000 (14:51 +0900)
Code located here is meant for a legacy tree and legacy widgets.
This is checked on the entry of the function

src/Makefile_Elementary.am
src/lib/elementary/efl_ui_win.c
src/lib/elementary/elm_focus_legacy.c [new file with mode: 0644]
src/lib/elementary/elm_main.c
src/lib/elementary/elm_priv.h
src/lib/elementary/elm_widget.h

index dafb604..1afb405 100644 (file)
@@ -846,6 +846,7 @@ lib_elementary_libelementary_la_SOURCES = \
        lib/elementary/efl_selection.c \
        lib/elementary/efl_datetime_manager.c \
        lib/elementary/efl_ui_dnd.c \
+       lib/elementary/elm_focus_legacy.c \
   static_libs/buildsystem/buildsystem.h \
   static_libs/buildsystem/buildsystem_autotools.c \
        lib/elementary/efl_ui_pager.c \
index ed0ca42..92ff8d4 100644 (file)
@@ -2097,18 +2097,27 @@ _key_action_move(Evas_Object *obj, const char *params)
      focus_dir = EFL_UI_FOCUS_DIRECTION_DOWN;
    else return EINA_FALSE;
 
-   o = efl_ui_focus_manager_move(obj, focus_dir);
 
-   if (!o)
-     {
-        if (focus_dir == EFL_UI_FOCUS_DIRECTION_NEXT || focus_dir == EFL_UI_FOCUS_DIRECTION_PREVIOUS)
-          {
-             Efl_Ui_Focus_Object *root;
+  // The handling for legacy is different due to elm_object_next set
+  if (elm_widget_is_legacy(obj))
+    elm_object_focus_next(obj, focus_dir);
+  else
+    {
+       Efl_Ui_Widget *o;
+
+       o = efl_ui_focus_manager_move(obj, focus_dir);
+       if (!o)
+         {
+            if (focus_dir == EFL_UI_FOCUS_DIRECTION_NEXT || focus_dir == EFL_UI_FOCUS_DIRECTION_PREVIOUS)
+              {
+                 Efl_Ui_Focus_Object *root;
+
+                 root = efl_ui_focus_manager_root_get(obj);
+                 efl_ui_focus_manager_setup_on_first_touch(obj, focus_dir, root);
+              }
+         }
+    }
 
-             root = efl_ui_focus_manager_root_get(obj);
-             efl_ui_focus_manager_setup_on_first_touch(obj, focus_dir, root);
-          }
-     }
    return EINA_TRUE;
 }
 
diff --git a/src/lib/elementary/elm_focus_legacy.c b/src/lib/elementary/elm_focus_legacy.c
new file mode 100644 (file)
index 0000000..f39a777
--- /dev/null
@@ -0,0 +1,291 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#include <Elementary.h>
+#include "elm_priv.h"
+
+//we need those for legacy compatible code
+#include "elm_genlist.eo.h"
+#include "elm_gengrid.eo.h"
+
+#define API_ENTRY()\
+   EINA_SAFETY_ON_NULL_RETURN(obj); \
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, pd); \
+   EINA_SAFETY_ON_FALSE_RETURN(elm_widget_is_legacy(obj));
+
+#define API_ENTRY_VAL(val)\
+   EINA_SAFETY_ON_NULL_RETURN_VAL(obj, val); \
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, pd, val); \
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(elm_widget_is_legacy(obj), val);
+
+#define MAPPING() \
+        MAP(PREVIOUS, prev) \
+        MAP(NEXT, next) \
+        MAP(UP, up) \
+        MAP(DOWN, down) \
+        MAP(LEFT, left) \
+        MAP(RIGHT, right)
+
+
+
+static Eina_List*
+_custom_chain_get(const Efl_Ui_Widget *node)
+{
+   ELM_WIDGET_DATA_GET_OR_RETURN(node, pd, NULL);
+
+   return pd->legacy_focus.custom_chain;
+}
+
+static void
+_custom_chain_set(Efl_Ui_Widget *node, Eina_List *lst)
+{
+   ELM_WIDGET_DATA_GET_OR_RETURN(node, pd);
+
+   pd->legacy_focus.custom_chain = eina_list_free(pd->legacy_focus.custom_chain);
+   pd->legacy_focus.custom_chain = lst;
+}
+
+Evas_Object*
+legacy_elm_widget_next_targer(Efl_Ui_Widget *obj, Elm_Focus_Direction dir)
+{
+   API_ENTRY_VAL(NULL)
+   Efl_Ui_Widget *target = NULL;
+
+   #define MAP(direction, field)  if (dir == EFL_UI_FOCUS_DIRECTION_ ##direction && pd->legacy_focus.field) target = pd->legacy_focus.field;
+
+   if (!target)
+     {
+        MAPPING()
+     }
+   #undef MAP
+
+   return target;
+}
+
+EAPI void
+elm_object_focus_next_object_set(Evas_Object        *obj,
+                                 Evas_Object        *next EINA_UNUSED,
+                                 Elm_Focus_Direction dir EINA_UNUSED)
+{
+   API_ENTRY()
+
+
+   #define MAP(direction, field)  if (dir == EFL_UI_FOCUS_DIRECTION_ ##direction) pd->legacy_focus.field = next;
+   MAPPING()
+   #undef MAP
+   ELM_WIDGET_DATA_GET_OR_RETURN(next, next_pd);
+   dir = efl_ui_focus_util_direction_complement(EFL_UI_FOCUS_UTIL_CLASS, dir);
+   #define MAP(direction, field)  if (dir == EFL_UI_FOCUS_DIRECTION_ ##direction) next_pd->legacy_focus.field = obj;
+   MAPPING()
+   #undef MAP
+}
+
+EAPI void
+elm_object_focus_custom_chain_set(Evas_Object *obj,
+                                  Eina_List   *objs EINA_UNUSED)
+{
+   API_ENTRY()
+   _custom_chain_set(obj, objs);
+}
+
+EAPI void
+elm_object_focus_custom_chain_unset(Evas_Object *obj)
+{
+   API_ENTRY()
+
+   _custom_chain_set(obj, NULL);
+}
+
+EAPI const Eina_List *
+elm_object_focus_custom_chain_get(const Evas_Object *obj)
+{
+   API_ENTRY_VAL(NULL)
+
+   return _custom_chain_get(obj);
+}
+
+EAPI void
+elm_object_focus_custom_chain_append(Evas_Object *obj,
+                                     Evas_Object *child EINA_UNUSED,
+                                     Evas_Object *relative_child EINA_UNUSED)
+{
+   API_ENTRY()
+
+   pd->legacy_focus.custom_chain = eina_list_append_relative(pd->legacy_focus.custom_chain, child, relative_child);
+}
+
+EAPI void
+elm_object_focus_custom_chain_prepend(Evas_Object *obj,
+                                      Evas_Object *child EINA_UNUSED,
+                                      Evas_Object *relative_child EINA_UNUSED)
+{
+   API_ENTRY()
+
+   pd->legacy_focus.custom_chain = eina_list_prepend_relative(pd->legacy_focus.custom_chain, child, relative_child);
+}
+
+EINA_DEPRECATED EAPI void
+elm_object_focus_cycle(Evas_Object        *obj,
+                       Elm_Focus_Direction dir)
+{
+   elm_object_focus_next(obj, dir);
+}
+
+EAPI void
+elm_object_focus_next(Evas_Object        *obj,
+                      Elm_Focus_Direction dir)
+{
+   Eina_Bool legacy_focus_move = EINA_FALSE;
+   Efl_Ui_Widget *o = NULL, *top;
+   Efl_Ui_Focus_Object *regular, *logical;
+   Efl_Ui_Focus_Manager *manager_top;
+   API_ENTRY()
+
+   top = elm_object_top_widget_get(obj);
+   manager_top = efl_ui_focus_util_active_manager(EFL_UI_FOCUS_UTIL_CLASS, obj);
+   regular = efl_ui_focus_manager_request_move(manager_top, dir, NULL, EINA_FALSE);
+   logical = efl_ui_focus_manager_focus_get(manager_top);
+
+   Efl_Ui_Focus_Object *legacy_target = legacy_elm_widget_next_targer(logical, dir);
+   if (legacy_target)
+     {
+        o = legacy_target;
+        efl_ui_focus_util_focus(EFL_UI_FOCUS_UTIL_CLASS, legacy_target);
+        if (elm_object_focused_object_get(top) == legacy_target)
+          {
+             legacy_focus_move = EINA_TRUE;
+          }
+     }
+
+   if (!legacy_focus_move)
+     o = efl_ui_focus_manager_move(top, dir);
+   if (!o)
+     {
+        if (dir == EFL_UI_FOCUS_DIRECTION_NEXT || dir == EFL_UI_FOCUS_DIRECTION_PREVIOUS)
+          {
+             Efl_Ui_Focus_Object *root;
+
+             root = efl_ui_focus_manager_root_get(obj);
+             efl_ui_focus_manager_setup_on_first_touch(obj, dir, root);
+          }
+     }
+}
+
+EAPI Evas_Object *
+elm_object_focus_next_object_get(const Evas_Object  *obj,
+                                 Elm_Focus_Direction dir)
+{
+   Efl_Ui_Widget *top = elm_object_top_widget_get(obj);
+   API_ENTRY_VAL(NULL)
+
+   #define MAP(direction, field)  if (dir == EFL_UI_FOCUS_DIRECTION_ ##direction && pd->legacy_focus.field) return pd->legacy_focus.field;
+   MAPPING()
+   #undef MAP
+
+   return efl_ui_focus_manager_request_move(efl_ui_focus_util_active_manager(EFL_UI_FOCUS_UTIL_CLASS, top), dir, NULL, EINA_FALSE);
+}
+
+EAPI Elm_Object_Item *
+elm_object_focus_next_item_get(const Evas_Object  *obj,
+                               Elm_Focus_Direction dir EINA_UNUSED)
+{
+   API_ENTRY_VAL(NULL)
+   /* FOCUS-FIXME */
+   return NULL;
+}
+
+EAPI void
+elm_object_focus_next_item_set(Evas_Object     *obj,
+                               Elm_Object_Item *next_item EINA_UNUSED,
+                               Elm_Focus_Direction dir EINA_UNUSED)
+{
+   API_ENTRY()
+   /* FOCUS-FIXME */
+}
+
+EAPI Evas_Object *
+elm_object_focused_object_get(const Evas_Object *obj)
+{
+   API_ENTRY_VAL(NULL)
+   Efl_Ui_Focus_Manager *man = elm_object_top_widget_get(obj);
+
+   while(efl_ui_focus_manager_redirect_get(man))
+     {
+        man = efl_ui_focus_manager_redirect_get(man);
+
+        // legacy compatible code, earlier those containers have not exposed theire items
+        if (efl_isa(man, ELM_GENGRID_CLASS) ||
+            efl_isa(man, ELM_TOOLBAR_CLASS) ||
+            efl_isa(man, ELM_GENLIST_CLASS)) return man;
+     }
+
+   return efl_ui_focus_manager_focus_get(man);
+}
+
+EAPI Eina_Bool
+elm_object_focus_get(const Evas_Object *obj)
+{
+   Efl_Ui_Focus_Manager *m;
+   Efl_Ui_Focus_Object *focused_child;
+   API_ENTRY_VAL(EINA_FALSE)
+
+   if (!elm_widget_is(obj))
+     return evas_object_focus_get(obj);
+
+   m = efl_ui_focus_object_focus_manager_get(obj);
+
+   //no manager means not registered
+   if (!m) return EINA_FALSE;
+
+   //assertion: our redirect manager m is in the redirect chain
+   m = efl_ui_focus_object_focus_manager_get(obj);
+
+   //if obj is the redriect manager its kind of focused
+   if (efl_ui_focus_manager_redirect_get(m) == obj) return EINA_TRUE;
+
+   //if there is a redirect manager
+   if (!!efl_ui_focus_manager_redirect_get(m)) return EINA_FALSE;
+
+   //now take the focused object and walk down the parents, if this is
+   focused_child = efl_ui_focus_manager_focus_get(m);
+
+   while(focused_child)
+     {
+        if (focused_child == obj) return EINA_TRUE;
+
+        focused_child = efl_ui_focus_object_focus_parent_get(focused_child);
+     }
+
+   return efl_ui_focus_object_focus_get(obj);
+}
+
+EAPI void
+elm_object_focus_set(Evas_Object *obj,
+                     Eina_Bool    focus)
+{
+   // ugly, but, special case for inlined windows
+   if (efl_isa(obj, EFL_UI_WIN_CLASS))
+     {
+        Evas_Object *inlined = elm_win_inlined_image_object_get(obj);
+        if (inlined)
+          {
+             evas_object_focus_set(inlined, focus);
+             return;
+          }
+     }
+   else if (elm_widget_is(obj))
+     {
+        if (focus)
+          efl_ui_focus_util_focus(EFL_UI_FOCUS_UTIL_CLASS, obj);
+        else
+          {
+             if (efl_ui_focus_manager_focus_get(efl_ui_focus_object_focus_manager_get(obj)) == obj)
+               efl_ui_focus_manager_pop_history_stack(efl_ui_focus_object_focus_manager_get(obj));
+          }
+     }
+   else
+     {
+        evas_object_focus_set(obj, focus);
+     }
+}
index 02c0ca6..dfd895b 100644 (file)
@@ -1581,75 +1581,6 @@ elm_cache_all_flush(void)
      }
 }
 
-EAPI Eina_Bool
-elm_object_focus_get(const Evas_Object *obj)
-{
-   Efl_Ui_Focus_Manager *m;
-   Efl_Ui_Focus_Object *focused_child;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
-
-   if (!elm_widget_is(obj))
-     return evas_object_focus_get(obj);
-
-   m = efl_ui_focus_object_focus_manager_get(obj);
-
-   //no manager means not registered
-   if (!m) return EINA_FALSE;
-
-   //assertion: our redirect manager m is in the redirect chain
-   m = efl_ui_focus_object_focus_manager_get(obj);
-
-   //if obj is the redriect manager its kind of focused
-   if (efl_ui_focus_manager_redirect_get(m) == obj) return EINA_TRUE;
-
-   //if there is a redirect manager
-   if (!!efl_ui_focus_manager_redirect_get(m)) return EINA_FALSE;
-
-   //now take the focused object and walk down the parents, if this is
-   focused_child = efl_ui_focus_manager_focus_get(m);
-
-   while(focused_child)
-     {
-        if (focused_child == obj) return EINA_TRUE;
-
-        focused_child = efl_ui_focus_object_focus_parent_get(focused_child);
-     }
-
-   return efl_ui_focus_object_focus_get(obj);
-}
-
-EAPI void
-elm_object_focus_set(Evas_Object *obj,
-                     Eina_Bool    focus)
-{
-   EINA_SAFETY_ON_NULL_RETURN(obj);
-
-   // ugly, but, special case for inlined windows
-   if (efl_isa(obj, EFL_UI_WIN_CLASS))
-     {
-        Evas_Object *inlined = elm_win_inlined_image_object_get(obj);
-        if (inlined)
-          {
-             evas_object_focus_set(inlined, focus);
-             return;
-          }
-     }
-   else if (elm_widget_is(obj))
-     {
-        if (focus)
-          efl_ui_focus_util_focus(EFL_UI_FOCUS_UTIL_CLASS, obj);
-        else
-          {
-             if (efl_ui_focus_manager_focus_get(efl_ui_focus_object_focus_manager_get(obj)) == obj)
-               efl_ui_focus_manager_pop_history_stack(efl_ui_focus_object_focus_manager_get(obj));
-          }
-     }
-   else
-     {
-        evas_object_focus_set(obj, focus);
-     }
-}
-
 EAPI void
 elm_object_focus_allow_set(Evas_Object *obj,
                            Eina_Bool    enable)
@@ -1665,119 +1596,6 @@ elm_object_focus_allow_get(const Evas_Object *obj)
    return (elm_widget_can_focus_get(obj)) || (elm_widget_child_can_focus_get(obj));
 }
 
-EAPI void
-elm_object_focus_custom_chain_set(Evas_Object *obj,
-                                  Eina_List   *objs EINA_UNUSED)
-{
-   EINA_SAFETY_ON_NULL_RETURN(obj);
-   ERR("Focus-chain not supported");
-}
-
-EAPI void
-elm_object_focus_custom_chain_unset(Evas_Object *obj)
-{
-   EINA_SAFETY_ON_NULL_RETURN(obj);
-   ERR("Focus-chain not supported");
-}
-
-EAPI const Eina_List *
-elm_object_focus_custom_chain_get(const Evas_Object *obj)
-{
-   EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
-   ERR("Focus-chain not supported");
-   return NULL;
-}
-
-EAPI void
-elm_object_focus_custom_chain_append(Evas_Object *obj,
-                                     Evas_Object *child EINA_UNUSED,
-                                     Evas_Object *relative_child EINA_UNUSED)
-{
-   EINA_SAFETY_ON_NULL_RETURN(obj);
-   ERR("Focus-chain not supported");
-}
-
-EAPI void
-elm_object_focus_custom_chain_prepend(Evas_Object *obj,
-                                      Evas_Object *child EINA_UNUSED,
-                                      Evas_Object *relative_child EINA_UNUSED)
-{
-   EINA_SAFETY_ON_NULL_RETURN(obj);
-   ERR("Focus-chain not supported");
-}
-
-EINA_DEPRECATED EAPI void
-elm_object_focus_cycle(Evas_Object        *obj,
-                       Elm_Focus_Direction dir)
-{
-   elm_object_focus_next(obj, dir);
-}
-
-EAPI void
-elm_object_focus_next(Evas_Object        *obj,
-                      Elm_Focus_Direction dir)
-{
-   Efl_Ui_Widget *top = elm_object_top_widget_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN(obj);
-
-   efl_ui_focus_manager_move(top, dir);
-}
-
-EAPI Evas_Object *
-elm_object_focus_next_object_get(const Evas_Object  *obj,
-                                 Elm_Focus_Direction dir)
-{
-   Efl_Ui_Widget *top = elm_object_top_widget_get(obj);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
-
-   return efl_ui_focus_manager_request_move(efl_ui_focus_util_active_manager(EFL_UI_FOCUS_UTIL_CLASS, top), dir, NULL, EINA_FALSE);
-}
-
-EAPI void
-elm_object_focus_next_object_set(Evas_Object        *obj,
-                                 Evas_Object        *next EINA_UNUSED,
-                                 Elm_Focus_Direction dir EINA_UNUSED)
-{
-   EINA_SAFETY_ON_NULL_RETURN(obj);
-   ERR("setting explicit objects not allowed not supported");
-}
-
-EAPI Elm_Object_Item *
-elm_object_focus_next_item_get(const Evas_Object  *obj,
-                               Elm_Focus_Direction dir EINA_UNUSED)
-{
-   EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
-   /* FOCUS-FIXME */
-   return NULL;
-}
-
-EAPI void
-elm_object_focus_next_item_set(Evas_Object     *obj,
-                               Elm_Object_Item *next_item EINA_UNUSED,
-                               Elm_Focus_Direction dir EINA_UNUSED)
-{
-   EINA_SAFETY_ON_NULL_RETURN(obj);
-   /* FOCUS-FIXME */
-}
-
-EAPI Evas_Object *
-elm_object_focused_object_get(const Evas_Object *obj)
-{
-   EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
-   Efl_Ui_Focus_Manager *man = elm_object_top_widget_get(obj);
-
-   while(efl_ui_focus_manager_redirect_get(man))
-     {
-        man = efl_ui_focus_manager_redirect_get(man);
-
-        // legacy compatible code, earlier those containers have not exposed theire items
-        if (efl_isa(man, ELM_GENGRID_CLASS) ||
-            efl_isa(man, ELM_TOOLBAR_CLASS) ||
-            efl_isa(man, ELM_GENLIST_CLASS)) return man;
-     }
-
-   return efl_ui_focus_manager_focus_get(man);
-}
 
 EAPI void
 elm_object_tree_focus_allow_set(Evas_Object *obj,
index e823c33..98cdecf 100644 (file)
@@ -731,7 +731,7 @@ void                 _elm_win_wl_cursor_set(Evas_Object *obj, const char *cursor
 
 void _efl_ui_focus_manager_redirect_events_del(Efl_Ui_Focus_Manager *manager, Eo *obj);
 void _efl_ui_focus_manager_redirect_events_add(Efl_Ui_Focus_Manager *manager, Eo *obj);
-
+Evas_Object* legacy_elm_widget_next_targer(Efl_Ui_Widget *obj, Elm_Focus_Direction dir);
 void _efl_access_shutdown(void);
 
 /* Combobox: no proper support for Efl.Part API yet. */
index 1bf2fa4..f73e412 100644 (file)
@@ -389,10 +389,6 @@ typedef struct _Elm_Widget_Smart_Data
    Evas_Object                  *hover_obj;
    Evas_Object                  *bg;
    Eina_List                    *tooltips, *cursors;
-   Evas_Object                  *focus_previous, *focus_next;
-   Evas_Object                  *focus_up, *focus_down, *focus_right, *focus_left;
-   Elm_Object_Item              *item_focus_previous, *item_focus_next;
-   Elm_Object_Item              *item_focus_up, *item_focus_down, *item_focus_right, *item_focus_left;
 
    /* "show region" coordinates. all widgets got those because this
     * info may be set and queried recursively through the widget
@@ -459,16 +455,11 @@ typedef struct _Elm_Widget_Smart_Data
       Efl_Ui_Focus_Manager *manager;
       Efl_Ui_Focus_Object *provider;
    } manager;
-
-   /***********************************************************
-    * TIZEN_ONLY(20180117): Override Paragraph Direction APIs *
-    ***********************************************************/
-   Evas_BiDi_Direction           paragraph_direction : 3;
-   Eina_Bool                     inherit_paragraph_direction : 1;
-   /*******
-    * END *
-    *******/
-
+   struct {
+     Eina_List *custom_chain;
+     Evas_Object *prev, *next, *up, *down, *right, *left;
+     Elm_Object_Item *item_prev, *item_next, *item_up, *item_down, *item_right, *item_left;
+   } legacy_focus;
    Eina_Bool                     scroll_x_locked : 1;
    Eina_Bool                     scroll_y_locked : 1;
 
@@ -492,6 +483,15 @@ typedef struct _Elm_Widget_Smart_Data
    Eina_Bool                     on_destroy: 1; /**< This is true when the widget is on destruction(general widget destructor). */
    Eina_Bool                     provider_lookup : 1; /**< This is true when efl_provider_find is currently walking the tree */
    Eina_Bool                     has_shadow : 1;
+
+   /***********************************************************
+    * TIZEN_ONLY(20180117): Override Paragraph Direction APIs *
+    ***********************************************************/
+   Evas_BiDi_Direction           paragraph_direction : 3;
+   Eina_Bool                     inherit_paragraph_direction : 1;
+   /*******
+    * END *
+    *******/
    ///TIZEN_ONLY(20170717) : expose highlight information on atspi
    Eina_Bool                     can_highlight : 1; /**< true if widget have at-spi HIGHLIGHTABLE state */
    ///