forked from enlightenment/efl
elementary : Focus movement is possible with arrow keys. You can check
this feature in elementary_test -> focus. SVN revision: 62125
This commit is contained in:
parent
813e805e28
commit
85351c10c5
|
@ -91,7 +91,8 @@ test_focus(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info
|
|||
{
|
||||
Evas_Object *lb = elm_label_add(win);
|
||||
elm_object_text_set(lb,
|
||||
"<b>Use Tab and Shift+Tab</b>"
|
||||
"<b>Use Tab, Shift+Tab, and<br>"
|
||||
"Arrow Keys</b>"
|
||||
);
|
||||
evas_object_size_hint_weight_set(lb, 0.0, 0.0);
|
||||
evas_object_size_hint_align_set(lb, EVAS_HINT_FILL,
|
||||
|
|
|
@ -320,7 +320,11 @@ extern "C" {
|
|||
typedef enum _Elm_Focus_Direction
|
||||
{
|
||||
ELM_FOCUS_PREVIOUS,
|
||||
ELM_FOCUS_NEXT
|
||||
ELM_FOCUS_NEXT,
|
||||
ELM_FOCUS_UP,
|
||||
ELM_FOCUS_DOWN,
|
||||
ELM_FOCUS_LEFT,
|
||||
ELM_FOCUS_RIGHT
|
||||
} Elm_Focus_Direction;
|
||||
|
||||
typedef enum _Elm_Text_Format
|
||||
|
|
|
@ -158,6 +158,10 @@ static void _if_focused_revert(Evas_Object *obj,
|
|||
static Evas_Object *_newest_focus_order_get(Evas_Object *obj,
|
||||
unsigned int *newest_focus_order,
|
||||
Eina_Bool can_focus_only);
|
||||
static Eina_Bool _focus_list_direction_nearest_get(Evas_Object *obj,
|
||||
Eina_List *list,
|
||||
Elm_Focus_Direction dir,
|
||||
Evas_Object **nearest);
|
||||
|
||||
/* local subsystem globals */
|
||||
static Evas_Smart *_e_smart = NULL;
|
||||
|
@ -399,6 +403,96 @@ _elm_widget_focus_region_show(const Evas_Object *obj)
|
|||
}
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_focus_list_direction_nearest_get(Evas_Object *obj,
|
||||
Eina_List *list,
|
||||
Elm_Focus_Direction dir,
|
||||
Evas_Object **nearest)
|
||||
{
|
||||
Evas_Object *cur, *next = NULL;
|
||||
Eina_List *l;
|
||||
double weight = 0.0;
|
||||
Evas_Coord x, y, w, h, cx, cy;
|
||||
|
||||
if (!nearest) return EINA_FALSE;
|
||||
*nearest = NULL;
|
||||
|
||||
evas_object_geometry_get(obj, &x, &y, &w, &h);
|
||||
cx = x + (w / 2);
|
||||
cy = y + (h / 2);
|
||||
|
||||
EINA_LIST_FOREACH(list, l, cur)
|
||||
{
|
||||
if (obj == cur) continue;
|
||||
Evas_Coord cur_x, cur_y, cur_w, cur_h;
|
||||
int w_gap = 0, h_gap = 0;
|
||||
double cur_weight = 0.0;
|
||||
|
||||
evas_object_geometry_get(cur, &cur_x, &cur_y, &cur_w, &cur_h);
|
||||
|
||||
if (dir == ELM_FOCUS_LEFT)
|
||||
{
|
||||
if (x < (cur_x + cur_w)) continue;
|
||||
w_gap = x - (cur_x + cur_w);
|
||||
if ((cy >= cur_y) && (cy <= (cur_y + cur_h)))
|
||||
h_gap = 0;
|
||||
else if (cy > (cur_y + cur_h))
|
||||
h_gap = cy - (cur_y + cur_h);
|
||||
else if (cy < (cur_y))
|
||||
h_gap = cur_y - cy;
|
||||
}
|
||||
else if (dir == ELM_FOCUS_RIGHT)
|
||||
{
|
||||
if ((x + w) > cur_x) continue;
|
||||
w_gap = cur_x - (x + w);
|
||||
if ((cy >= cur_y) && (cy <= (cur_y + cur_h)))
|
||||
h_gap = 0;
|
||||
else if (cy > (cur_y + cur_h))
|
||||
h_gap = cy - (cur_y + cur_h);
|
||||
else if (cy < (cur_y))
|
||||
h_gap = cur_y - cy;
|
||||
}
|
||||
else if (dir == ELM_FOCUS_UP)
|
||||
{
|
||||
if (y < (cur_y + cur_h)) continue;
|
||||
h_gap = y - (cur_y + cur_h);
|
||||
if ((cx >= cur_x) && (cx <= (cur_x + cur_w)))
|
||||
w_gap = 0;
|
||||
else if (cx < cur_x)
|
||||
w_gap = cur_x - cx;
|
||||
else if (cx > (cur_x + cur_w))
|
||||
w_gap = cur_x + cur_w - cx;
|
||||
}
|
||||
else if (dir == ELM_FOCUS_DOWN)
|
||||
{
|
||||
if ((y + h) > cur_y) continue;
|
||||
h_gap = cur_y - (y + h);
|
||||
if ((cx >= cur_x) && (cx <= (cur_x + cur_w))) w_gap = 0;
|
||||
else if (cx < cur_x)
|
||||
w_gap = cur_x - cx;
|
||||
else if (cx > (cur_x + cur_w))
|
||||
w_gap = cur_x + cur_w - cx;
|
||||
}
|
||||
cur_weight = (w_gap * w_gap) + (h_gap * h_gap);
|
||||
|
||||
if (cur_weight == 0.0)
|
||||
{
|
||||
*nearest = cur;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
cur_weight = 1.0 / cur_weight;
|
||||
if (cur_weight > weight)
|
||||
{
|
||||
weight = cur_weight;
|
||||
next = cur;
|
||||
}
|
||||
}
|
||||
if (!next) return EINA_FALSE;
|
||||
*nearest = next;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup Widget Widget
|
||||
*
|
||||
|
@ -1147,6 +1241,47 @@ elm_widget_tree_unfocusable_get(const Evas_Object *obj)
|
|||
return sd->tree_unfocusable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Get the list of focusable child objects.
|
||||
*
|
||||
* This function retruns list of child objects which can get focus.
|
||||
*
|
||||
* @param obj The parent widget
|
||||
* @retrun list of focusable child objects.
|
||||
*
|
||||
* @ingroup Widget
|
||||
*/
|
||||
EAPI Eina_List *
|
||||
elm_widget_can_focus_child_list_get(const Evas_Object *obj)
|
||||
{
|
||||
API_ENTRY return NULL;
|
||||
|
||||
const Eina_List *l;
|
||||
Eina_List *child_list = NULL;
|
||||
Evas_Object *child;
|
||||
|
||||
if (sd->subobjs)
|
||||
{
|
||||
EINA_LIST_FOREACH(sd->subobjs, l, child)
|
||||
{
|
||||
if ((elm_widget_can_focus_get(child)) &&
|
||||
(evas_object_visible_get(child)) &&
|
||||
(!elm_widget_disabled_get(child)))
|
||||
child_list = eina_list_append(child_list, child);
|
||||
else if (elm_widget_is(child))
|
||||
{
|
||||
Eina_List *can_focus_list;
|
||||
can_focus_list = elm_widget_can_focus_child_list_get(child);
|
||||
if (can_focus_list)
|
||||
child_list = eina_list_merge(child_list, can_focus_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
return child_list;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
elm_widget_highlight_ignore_set(Evas_Object *obj,
|
||||
Eina_Bool ignore)
|
||||
|
@ -1598,7 +1733,7 @@ elm_widget_focus_list_next_get(const Evas_Object *obj,
|
|||
Elm_Focus_Direction dir,
|
||||
Evas_Object **next)
|
||||
{
|
||||
Eina_List *(*list_next)(const Eina_List * list);
|
||||
Eina_List *(*list_next)(const Eina_List * list) = NULL;
|
||||
|
||||
if (!next)
|
||||
return EINA_FALSE;
|
||||
|
@ -1617,64 +1752,110 @@ elm_widget_focus_list_next_get(const Evas_Object *obj,
|
|||
list_next = eina_list_prev;
|
||||
}
|
||||
else if (dir == ELM_FOCUS_NEXT)
|
||||
list_next = eina_list_next;
|
||||
{
|
||||
list_next = eina_list_next;
|
||||
}
|
||||
else if ((dir == ELM_FOCUS_LEFT) || (dir == ELM_FOCUS_RIGHT) ||
|
||||
(dir == ELM_FOCUS_UP) || (dir == ELM_FOCUS_DOWN))
|
||||
{
|
||||
list_next = eina_list_next;
|
||||
}
|
||||
else
|
||||
return EINA_FALSE;
|
||||
|
||||
const Eina_List *l = items;
|
||||
|
||||
/* Recovery last focused sub item */
|
||||
if (elm_widget_focus_get(obj))
|
||||
for (; l; l = list_next(l))
|
||||
{
|
||||
Evas_Object *cur = list_data_get(l);
|
||||
if (elm_widget_focus_get(cur)) break;
|
||||
}
|
||||
|
||||
const Eina_List *start = l;
|
||||
Evas_Object *to_focus = NULL;
|
||||
|
||||
/* Interate sub items */
|
||||
/* Go to end of list */
|
||||
for (; l; l = list_next(l))
|
||||
if ((dir == ELM_FOCUS_PREVIOUS) || (dir == ELM_FOCUS_NEXT))
|
||||
{
|
||||
Evas_Object *tmp = NULL;
|
||||
Evas_Object *cur = list_data_get(l);
|
||||
const Eina_List *l = items;
|
||||
|
||||
if (elm_widget_parent_get(cur) != obj)
|
||||
continue;
|
||||
/* Recovery last focused sub item */
|
||||
if (elm_widget_focus_get(obj))
|
||||
for (; l; l = list_next(l))
|
||||
{
|
||||
Evas_Object *cur = list_data_get(l);
|
||||
if (elm_widget_focus_get(cur)) break;
|
||||
}
|
||||
|
||||
/* Try Focus cycle in subitem */
|
||||
if (elm_widget_focus_next_get(cur, dir, &tmp))
|
||||
const Eina_List *start = l;
|
||||
Evas_Object *to_focus = NULL;
|
||||
|
||||
/* Interate sub items */
|
||||
/* Go to end of list */
|
||||
for (; l; l = list_next(l))
|
||||
{
|
||||
*next = tmp;
|
||||
return EINA_TRUE;
|
||||
Evas_Object *tmp = NULL;
|
||||
Evas_Object *cur = list_data_get(l);
|
||||
|
||||
if (elm_widget_parent_get(cur) != obj)
|
||||
continue;
|
||||
|
||||
/* Try Focus cycle in subitem */
|
||||
if (elm_widget_focus_next_get(cur, dir, &tmp))
|
||||
{
|
||||
*next = tmp;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
else if ((tmp) && (!to_focus))
|
||||
to_focus = tmp;
|
||||
}
|
||||
else if ((tmp) && (!to_focus))
|
||||
to_focus = tmp;
|
||||
}
|
||||
|
||||
l = items;
|
||||
l = items;
|
||||
|
||||
/* Get First possible */
|
||||
for (; l != start; l = list_next(l))
|
||||
{
|
||||
Evas_Object *tmp = NULL;
|
||||
Evas_Object *cur = list_data_get(l);
|
||||
|
||||
if (elm_widget_parent_get(cur) != obj)
|
||||
continue;
|
||||
|
||||
/* Try Focus cycle in subitem */
|
||||
elm_widget_focus_next_get(cur, dir, &tmp);
|
||||
if (tmp)
|
||||
/* Get First possible */
|
||||
for (; l != start; l = list_next(l))
|
||||
{
|
||||
*next = tmp;
|
||||
return EINA_FALSE;
|
||||
Evas_Object *tmp = NULL;
|
||||
Evas_Object *cur = list_data_get(l);
|
||||
|
||||
if (elm_widget_parent_get(cur) != obj)
|
||||
continue;
|
||||
|
||||
/* Try Focus cycle in subitem */
|
||||
elm_widget_focus_next_get(cur, dir, &tmp);
|
||||
if (tmp)
|
||||
{
|
||||
*next = tmp;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
*next = to_focus;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
else if ((dir == ELM_FOCUS_LEFT) || (dir == ELM_FOCUS_RIGHT) ||
|
||||
(dir == ELM_FOCUS_UP) || (dir == ELM_FOCUS_DOWN))
|
||||
{
|
||||
Eina_List *can_focus_list;
|
||||
Evas_Object *tmp = NULL;
|
||||
Evas_Object *cur;
|
||||
|
||||
can_focus_list = elm_widget_can_focus_child_list_get(obj);
|
||||
if (can_focus_list)
|
||||
{
|
||||
Eina_List *l;
|
||||
EINA_LIST_FOREACH(can_focus_list, l, cur)
|
||||
{
|
||||
if (elm_widget_focus_get(cur))
|
||||
{
|
||||
if (_focus_list_direction_nearest_get(cur, can_focus_list, dir, &tmp))
|
||||
{
|
||||
*next = tmp;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
*next = cur;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (elm_widget_focus_get(obj))
|
||||
{
|
||||
*next = list_data_get(can_focus_list);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*next = to_focus;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -269,6 +269,7 @@ EAPI void *elm_widget_signal_callback_del(Evas_Object *obj, const cha
|
|||
EAPI void elm_widget_can_focus_set(Evas_Object *obj, Eina_Bool can_focus);
|
||||
EAPI Eina_Bool elm_widget_can_focus_get(const Evas_Object *obj);
|
||||
EAPI Eina_Bool elm_widget_child_can_focus_get(const Evas_Object *obj);
|
||||
EAPI Eina_List *elm_widget_can_focus_child_list_get(const Evas_Object *obj);
|
||||
EAPI void elm_widget_tree_unfocusable_set(Evas_Object *obj, Eina_Bool tree_unfocusable);
|
||||
EAPI Eina_Bool elm_widget_tree_unfocusable_get(const Evas_Object *obj);
|
||||
EAPI void elm_widget_highlight_ignore_set(Evas_Object *obj, Eina_Bool ignore);
|
||||
|
|
|
@ -397,6 +397,34 @@ _elm_win_event_cb(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_T
|
|||
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
else if ((!strcmp(ev->keyname, "Left")) ||
|
||||
(!strcmp(ev->keyname, "KP_Left")))
|
||||
{
|
||||
elm_widget_focus_cycle(obj, ELM_FOCUS_LEFT);
|
||||
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
else if ((!strcmp(ev->keyname, "Right")) ||
|
||||
(!strcmp(ev->keyname, "KP_Right")))
|
||||
{
|
||||
elm_widget_focus_cycle(obj, ELM_FOCUS_RIGHT);
|
||||
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
else if ((!strcmp(ev->keyname, "Up")) ||
|
||||
(!strcmp(ev->keyname, "KP_Up")))
|
||||
{
|
||||
elm_widget_focus_cycle(obj, ELM_FOCUS_UP);
|
||||
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
else if ((!strcmp(ev->keyname, "Down")) ||
|
||||
(!strcmp(ev->keyname, "KP_Down")))
|
||||
{
|
||||
elm_widget_focus_cycle(obj, ELM_FOCUS_DOWN);
|
||||
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return EINA_FALSE;
|
||||
|
|
Loading…
Reference in New Issue