efl_ui_widget: make treeunfocusable state easier

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
This commit is contained in:
Marcel Hollerbach 2019-08-20 09:20:44 +02:00 committed by Cedric BAIL
parent b4b17993d5
commit 2dd596084b
2 changed files with 34 additions and 15 deletions

View File

@ -188,7 +188,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,
@ -1708,6 +1707,15 @@ elm_widget_child_can_focus_get(const Eo *obj)
return sd->logical.child_count > 0;
}
static int
_tree_unfocusable_counter_get(Eo *widget)
{
ELM_WIDGET_DATA_GET_OR_RETURN(widget, pd, -1);
return pd->tree_unfocusable;
}
/**
* @internal
*
@ -1726,16 +1734,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);
tree_unfocusable = !!tree_unfocusable;
if (sd->tree_unfocusable == tree_unfocusable) return;
sd->tree_unfocusable = tree_unfocusable;
_elm_widget_focus_tree_unfocusable_handle(obj);
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));
}
//focus state eval on all children
_elm_widget_full_eval_children(obj, sd);
_elm_widget_full_eval_children(obj, pd);
}
/**
@ -2943,12 +2968,6 @@ elm_widget_focus_mouse_up_handle(Eo *obj)
}
}
static void
_elm_widget_focus_tree_unfocusable_handle(Eo *obj EINA_UNUSED)
{
//FIXME
}
/*
* @internal
*

View File

@ -355,6 +355,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;
@ -398,7 +399,6 @@ typedef struct _Elm_Widget_Smart_Data
Eina_Bool 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;