efl_ui_widget: make treeunfocusable state easier 00/212400/1
authorMarcel Hollerbach <mail@marcel-hollerbach.de>
Tue, 20 Aug 2019 07:20:44 +0000 (09:20 +0200)
committerYeongjong Lee <yj34.lee@samsung.com>
Wed, 21 Aug 2019 07:02:39 +0000 (16:02 +0900)
Before this patch tree unfocusable set just set a simple flag, getting
this state however forced you to traverse the whole parent chain to get
the real result.
With this patch the setting of the unfocusable flag is heavier as it
walks all the children of the widget, however, the getting of the flag
is way easier now. The next revision will refactor the focus related
APIs for that.

Reviewed-by: Cedric BAIL <cedric.bail@free.fr>
Differential Revision: https://phab.enlightenment.org/D9644

Change-Id: I135a01a484bc111856e1e26f4b082fad24694911

src/lib/elementary/efl_ui_widget.c
src/lib/elementary/elm_widget.h

index 1d10f44..6d369ae 100644 (file)
@@ -264,7 +264,6 @@ _elm_scrollable_is(const Evas_Object *obj)
 static void
 _on_sub_obj_del(void *data, const Efl_Event *event);
 static void _propagate_event(void *data, const Efl_Event *eo_event);
-static void _elm_widget_focus_tree_unfocusable_handle(Eo *obj);
 static void _elm_widget_shadow_update(Efl_Ui_Widget *obj);
 
 EFL_CALLBACKS_ARRAY_DEFINE(elm_widget_subitems_callbacks,
@@ -1963,6 +1962,15 @@ elm_widget_child_can_focus_get(const Eo *obj)
 //
 }
 
+
+static int
+_tree_unfocusable_counter_get(Eo *widget)
+{
+   ELM_WIDGET_DATA_GET_OR_RETURN(widget, pd, -1);
+
+   return pd->tree_unfocusable;
+}
+
 /**
  * @internal
  *
@@ -1981,18 +1989,33 @@ elm_widget_child_can_focus_get(const Eo *obj)
 EAPI void
 elm_widget_tree_unfocusable_set(Eo *obj, Eina_Bool tree_unfocusable)
 {
-   Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
-   if (!sd) return;
+   Efl_Ui_Widget *subs;
+   Eina_List *n;
+   Elm_Widget_Smart_Data *pd = efl_data_scope_safe_get(obj, MY_CLASS);
+   if (!pd) return;
+   int distance, parent_counter = (pd->parent_obj ? _tree_unfocusable_counter_get(pd->parent_obj) : 0);
+
+   if (tree_unfocusable)
+     pd->tree_unfocusable ++;
+   else
+     pd->tree_unfocusable --;
+
+   distance = pd->disabled - parent_counter;
+
+   if ((distance < 0) || (distance > 1))
+     {
+        distance = MAX(MIN(tree_unfocusable, 1), 0);
+        pd->disabled = parent_counter + distance;
+     }
+
+   EINA_LIST_FOREACH(pd->subobjs, n, subs)
+     {
+        if (efl_isa(subs, EFL_UI_WIDGET_CLASS))
+          efl_ui_widget_disabled_set(subs, elm_widget_tree_unfocusable_get(obj));
+     }
 
-   tree_unfocusable = !!tree_unfocusable;
-   if (sd->tree_unfocusable == tree_unfocusable) return;
-   sd->tree_unfocusable = tree_unfocusable;
-   //TIZEN_ONLY(20180607): Restore legacy focus
-   //_elm_widget_focus_tree_unfocusable_handle(obj);
-   efl_ui_widget_focus_tree_unfocusable_handle(obj);
-   //
    //focus state eval on all children
-   _elm_widget_full_eval_children(obj, sd);
+   _elm_widget_full_eval_children(obj, pd);
 }
 
 /**
@@ -3660,15 +3683,6 @@ elm_widget_focus_mouse_up_handle(Eo *obj)
      }
 }
 
-EOLIAN static void
-_efl_ui_widget_focus_tree_unfocusable_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
-{
-   if (!elm_widget_parent_get(obj))
-     efl_ui_widget_focused_object_clear(obj);
-   else
-     _if_focused_revert(obj, EINA_TRUE);
-}
-
 /*
  * @internal
  *
index 1196766..12c8979 100644 (file)
@@ -374,6 +374,7 @@ typedef struct _Elm_Widget_Smart_Data
    int                           child_drag_x_locked;
    int                           child_drag_y_locked;
    int                           disabled;
+   int                           tree_unfocusable;
 
    Eina_Inlist                  *translate_strings;
    Eina_List                    *focus_chain;
@@ -426,7 +427,6 @@ typedef struct _Elm_Widget_Smart_Data
    Eina_Bool                     child_can_focus : 1;
    Eina_Bool                     focused : 1;
    Eina_Bool                     top_win_focused : 1;
-   Eina_Bool                     tree_unfocusable : 1;
    Eina_Bool                     focus_move_policy_auto_mode : 1; /* This is TRUE by default */
    Eina_Bool                     highlight_ignore : 1;
    Eina_Bool                     highlight_in_theme : 1;