forked from enlightenment/efl
focus: item focus moves by geometry.
In the widget code, focus origin is added. It can know the focus movement is originated by which action. The widgets can choose the item focus moves to last focused item or geometrically nearby item by focus origin. In gengrid, focus moves to last focused item if focus origin is ELM_FOCUS_REVERT. It moves to nearby item if focus origin is from ELM_FOCUS_UP to ELM_FOCUS_LEFT. TODO: widgets have items should add the direction feature if it want the focus to move to nearby item. @feature
This commit is contained in:
parent
085734310a
commit
1bc01460c4
|
@ -45,7 +45,9 @@ typedef enum
|
|||
ELM_FOCUS_UP, /**< up direction */
|
||||
ELM_FOCUS_DOWN, /**< down direction */
|
||||
ELM_FOCUS_RIGHT, /**< right direction */
|
||||
ELM_FOCUS_LEFT /**< left direction */
|
||||
ELM_FOCUS_LEFT, /**< left direction */
|
||||
ELM_FOCUS_MOUSE, /**< direction is from mouse */
|
||||
ELM_FOCUS_REVERT /**< direction is from focus revert */
|
||||
} Elm_Focus_Direction;
|
||||
|
||||
/**
|
||||
|
|
|
@ -3524,12 +3524,47 @@ _elm_gengrid_nearest_visible_item_get(Evas_Object *obj, Elm_Object_Item *eo_it)
|
|||
return eo_it;
|
||||
}
|
||||
|
||||
static Elm_Object_Item *
|
||||
_elm_gengrid_direction_item_get(Evas_Object *obj, Elm_Focus_Direction dir)
|
||||
{
|
||||
double max_weight = 0.0, weight = 0.0;
|
||||
Eina_List *item_list = NULL, *l = NULL;
|
||||
Elm_Object_Item *eo_item = NULL, *best_item = NULL;
|
||||
Evas_Object *fobj = _elm_widget_focus_highlight_object_get(obj);
|
||||
|
||||
double degree = 0.0;
|
||||
if (dir == ELM_FOCUS_UP) degree = 0.0;
|
||||
else if (dir == ELM_FOCUS_DOWN) degree = 180.0;
|
||||
else if (dir == ELM_FOCUS_RIGHT) degree = 90.0;
|
||||
else if (dir == ELM_FOCUS_LEFT) degree = 270.0;
|
||||
|
||||
item_list = elm_gengrid_realized_items_get(obj);
|
||||
best_item = elm_gengrid_first_item_get(obj);
|
||||
|
||||
EINA_LIST_FOREACH(item_list, l, eo_item)
|
||||
{
|
||||
ELM_GENGRID_ITEM_DATA_GET(eo_item, item);
|
||||
weight = _elm_widget_focus_direction_weight_get(fobj, VIEW(item), degree);
|
||||
if ((weight == -1.0) ||
|
||||
((weight != 0.0) && (max_weight != -1.0) &&
|
||||
((int)(max_weight * 100000000) < (int)(weight * 100000000))))
|
||||
{
|
||||
best_item = eo_item;
|
||||
max_weight = weight;
|
||||
}
|
||||
}
|
||||
eina_list_free(item_list);
|
||||
|
||||
return best_item;
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_elm_gengrid_elm_widget_on_focus(Eo *obj, Elm_Gengrid_Data *sd)
|
||||
{
|
||||
Eina_Bool int_ret = EINA_FALSE;
|
||||
Elm_Object_Item *eo_it = NULL;
|
||||
Eina_Bool is_sel = EINA_FALSE;
|
||||
Elm_Focus_Direction focus_origin;
|
||||
|
||||
eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_on_focus());
|
||||
if (!int_ret) return EINA_FALSE;
|
||||
|
@ -3543,7 +3578,10 @@ _elm_gengrid_elm_widget_on_focus(Eo *obj, Elm_Gengrid_Data *sd)
|
|||
|
||||
if (elm_widget_focus_get(obj) && !sd->mouse_down)
|
||||
{
|
||||
if (sd->last_focused_item)
|
||||
focus_origin = elm_widget_focus_origin_get(obj);
|
||||
if (focus_origin >= ELM_FOCUS_UP && focus_origin <= ELM_FOCUS_LEFT)
|
||||
eo_it = _elm_gengrid_direction_item_get(obj, focus_origin);
|
||||
else if (sd->last_focused_item)
|
||||
eo_it = sd->last_focused_item;
|
||||
else if (sd->last_selected_item)
|
||||
eo_it = sd->last_selected_item;
|
||||
|
|
|
@ -63,6 +63,7 @@ struct _Elm_Translate_String_Data
|
|||
|
||||
/* local subsystem globals */
|
||||
static unsigned int focus_order = 0;
|
||||
Elm_Focus_Direction focus_origin = -1;
|
||||
|
||||
static inline Eina_Bool
|
||||
_elm_widget_is(const Evas_Object *obj)
|
||||
|
@ -173,6 +174,16 @@ _elm_widget_focus_highlight_start(const Evas_Object *obj)
|
|||
_elm_win_focus_highlight_start(top);
|
||||
}
|
||||
|
||||
Evas_Object *
|
||||
_elm_widget_focus_highlight_object_get(const Evas_Object *obj)
|
||||
{
|
||||
Evas_Object *top = elm_widget_top_get(obj);
|
||||
|
||||
if (top && eo_isa(top, ELM_WIN_CLASS))
|
||||
return _elm_win_focus_highlight_object_get(top);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
elm_widget_focus_highlight_enabled_get(const Evas_Object *obj)
|
||||
{
|
||||
|
@ -385,6 +396,7 @@ _if_focused_revert(Evas_Object *obj,
|
|||
if (!sd->focused) return;
|
||||
if (!sd->parent_obj) return;
|
||||
|
||||
focus_origin = ELM_FOCUS_REVERT;
|
||||
top = elm_widget_top_get(sd->parent_obj);
|
||||
if (top)
|
||||
{
|
||||
|
@ -1835,6 +1847,7 @@ _elm_widget_focus_cycle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Elm_Foc
|
|||
Evas_Object *target = NULL;
|
||||
if (!_elm_widget_is(obj))
|
||||
return;
|
||||
focus_origin = dir;
|
||||
elm_widget_focus_next_get(obj, dir, &target);
|
||||
if (target)
|
||||
{
|
||||
|
@ -1892,8 +1905,8 @@ _elm_widget_focus_direction_go(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED,
|
|||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static double
|
||||
_direction_weight_get(const Evas_Object *obj1,
|
||||
double
|
||||
_elm_widget_focus_direction_weight_get(const Evas_Object *obj1,
|
||||
const Evas_Object *obj2,
|
||||
double degree)
|
||||
{
|
||||
|
@ -2260,7 +2273,7 @@ _elm_widget_focus_direction_get(const Eo *obj, Elm_Widget_Smart_Data *sd, const
|
|||
if (!elm_widget_can_focus_get(obj) || elm_widget_focus_get(obj))
|
||||
return EINA_FALSE;
|
||||
|
||||
c_weight = _direction_weight_get(base, obj, degree);
|
||||
c_weight = _elm_widget_focus_direction_weight_get(base, obj, degree);
|
||||
if ((c_weight == -1.0) ||
|
||||
((c_weight != 0.0) && (*weight != -1.0) &&
|
||||
((int)(*weight * 1000000) <= (int)(c_weight * 1000000))))
|
||||
|
@ -2353,6 +2366,7 @@ _elm_widget_focus_next_get(const Eo *obj, Elm_Widget_Smart_Data *sd, Elm_Focus_D
|
|||
return EINA_FALSE;
|
||||
*next = NULL;
|
||||
|
||||
focus_origin = dir;
|
||||
/* Ignore if disabled */
|
||||
if (_elm_config->access_mode && _elm_access_auto_highlight_get())
|
||||
{
|
||||
|
@ -3993,6 +4007,12 @@ _elm_widget_focused_item_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EIN
|
|||
return NULL;
|
||||
}
|
||||
|
||||
EOLIAN static Elm_Focus_Direction
|
||||
_elm_widget_focus_origin_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
|
||||
{
|
||||
return focus_origin;
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_elm_widget_focus_region_show_mode_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd, Elm_Focus_Region_Show_Mode mode)
|
||||
{
|
||||
|
|
|
@ -364,6 +364,11 @@ abstract Elm.Widget (Evas.Object_Smart, Elm_Interface_Atspi_Accessible, Elm_Inte
|
|||
return: Evas.Object *;
|
||||
}
|
||||
}
|
||||
@property focus_origin {
|
||||
get {
|
||||
return: Elm_Focus_Direction;
|
||||
}
|
||||
}
|
||||
@property parent2 {
|
||||
set {
|
||||
}
|
||||
|
|
|
@ -534,6 +534,7 @@ void _elm_widget_highlight_in_theme_update(Eo *obj);
|
|||
// win focus highlight
|
||||
void _elm_win_focus_highlight_start(Evas_Object *obj);
|
||||
void _elm_win_focus_highlight_in_theme_update(Evas_Object *obj, Eina_Bool in_theme);
|
||||
Evas_Object *_elm_win_focus_highlight_object_get(Evas_Object *obj);
|
||||
void _elm_win_focus_auto_show(Evas_Object *obj);
|
||||
void _elm_win_focus_auto_hide(Evas_Object *obj);
|
||||
|
||||
|
@ -690,6 +691,8 @@ EAPI Evas_Object *elm_widget_newest_focus_order_get(const Evas_Object *obj,
|
|||
EAPI void elm_widget_display_mode_set(Evas_Object *obj, Evas_Display_Mode dispmode);
|
||||
EAPI Eina_Bool elm_widget_focus_highlight_enabled_get(const Evas_Object *obj);
|
||||
EAPI void elm_widget_focus_highlight_focus_part_geometry_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
|
||||
Evas_Object *_elm_widget_focus_highlight_object_get(const Evas_Object *obj);
|
||||
double _elm_widget_focus_direction_weight_get(const Evas_Object *obj1, const Evas_Object *obj2, double degree);
|
||||
EAPI const Elm_Widget_Smart_Class *elm_widget_smart_class_get(void);
|
||||
|
||||
/**
|
||||
|
@ -776,6 +779,7 @@ EAPI void elm_widget_focus_move_policy_set(Evas_Object *obj, Elm_Foc
|
|||
EAPI Elm_Focus_Move_Policy elm_widget_focus_move_policy_get(const Evas_Object *obj);
|
||||
EAPI void elm_widget_focus_region_show_mode_set(Evas_Object *obj, Elm_Focus_Region_Show_Mode mode);
|
||||
EAPI Elm_Focus_Region_Show_Mode elm_widget_focus_region_show_mode_get(const Evas_Object *obj);
|
||||
EAPI Elm_Focus_Direction elm_widget_focus_origin_get(const Evas_Object *obj);
|
||||
|
||||
/**
|
||||
* Function to operate on a given widget's scrollabe children when necessary.
|
||||
|
|
|
@ -880,6 +880,14 @@ _elm_win_focus_highlight_visible_set(Elm_Win_Data *sd,
|
|||
}
|
||||
}
|
||||
|
||||
Evas_Object *
|
||||
_elm_win_focus_highlight_object_get(Evas_Object *obj)
|
||||
{
|
||||
ELM_WIN_DATA_GET(obj, sd);
|
||||
|
||||
return sd->focus_highlight.fobj;
|
||||
}
|
||||
|
||||
static void
|
||||
_elm_win_focus_highlight_anim_setup(Elm_Win_Data *sd,
|
||||
Evas_Object *obj)
|
||||
|
@ -992,7 +1000,15 @@ _elm_win_focus_highlight_reconfigure_job(void *data)
|
|||
elm_widget_signal_emit(target, sig, "elm");
|
||||
|
||||
if ((!target) || (!common_visible) || (sd->focus_highlight.cur.in_theme))
|
||||
goto the_end;
|
||||
{
|
||||
if (target)
|
||||
{
|
||||
Elm_Focus_Direction focus_origin = elm_widget_focus_origin_get(target);
|
||||
if (focus_origin >= ELM_FOCUS_UP && focus_origin <= ELM_FOCUS_LEFT)
|
||||
_elm_win_focus_highlight_simple_setup(sd, fobj);
|
||||
}
|
||||
goto the_end;
|
||||
}
|
||||
|
||||
if (previous)
|
||||
focus_style_previous = elm_widget_focus_highlight_style_get(previous);
|
||||
|
|
Loading…
Reference in New Issue