focus: Added optional focus feature - item focus on selection.

Summary:
Currenly focus and selection happens together. This patch makes item focus
on selection optional by configuration and API.

- configuration: "item_focus_on_selection".
- API: elm_config_item_focus_on_selection_get/set.
- Implemented item_focus_on_selection feature in elm list.
@feature

Test Plan: elementary_test->List focus

Reviewers: raster, seoz, woohyun

CC: seoz

Differential Revision: https://phab.enlightenment.org/D676
This commit is contained in:
Amitesh Singh 2014-04-03 19:11:57 +09:00 committed by Carsten Haitzler (Rasterman)
parent e839950126
commit 73b16ef210
8 changed files with 136 additions and 38 deletions

View File

@ -45,6 +45,7 @@ group "Elm_Config" struct {
value "focus_highlight_enable" uchar: 0;
value "focus_highlight_animate" uchar: 0;
value "focus_highlight_clip_disable" uchar: 0;
value "item_focus_on_selection" uchar: 1;
value "focus_move_policy" uchar: 0;
value "toolbar_shrink_mode" int: 3;
value "fileselector_expand_enable" uchar: 0;

View File

@ -45,6 +45,7 @@ group "Elm_Config" struct {
value "focus_highlight_enable" uchar: 0;
value "focus_highlight_animate" uchar: 0;
value "focus_highlight_clip_disable" uchar: 0;
value "item_focus_on_selection" uchar: 1;
value "focus_move_policy" uchar: 0;
value "toolbar_shrink_mode" int: 3;
value "fileselector_expand_enable" uchar: 0;

View File

@ -45,6 +45,7 @@ group "Elm_Config" struct {
value "focus_highlight_enable" uchar: 0;
value "focus_highlight_animate" uchar: 0;
value "focus_highlight_clip_disable" uchar: 1;
value "item_focus_on_selection" uchar: 1;
value "focus_move_policy" uchar: 0;
value "toolbar_shrink_mode" int: 3;
value "fileselector_expand_enable" uchar: 1;

View File

@ -1317,6 +1317,13 @@ test_list_focus_item_loop_enable_check_changed(void *data, Evas_Object *obj,
elm_object_scroll_item_loop_enabled_set(li, elm_check_state_get(obj));
}
static void
test_list_focus_item_focus_on_selection_changed(void *data EINA_UNUSED, Evas_Object *obj,
void *event_info EINA_UNUSED)
{
elm_config_item_focus_on_selection_set(elm_check_state_get(obj));
}
static void
_item_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
{
@ -1515,6 +1522,16 @@ _test_list_focus(const char *name, const char *title, Eina_Bool horiz)
elm_box_pack_end(bx_opt, chk);
evas_object_show(chk);
chk = elm_check_add(bx_opt);
elm_object_text_set(chk, "Item Focus on selection enable");
elm_check_state_set(chk, elm_config_item_focus_on_selection_get());
evas_object_size_hint_weight_set(chk, EVAS_HINT_EXPAND, 0.0);
evas_object_smart_callback_add(chk, "changed",
test_list_focus_item_focus_on_selection_changed,
NULL);
elm_box_pack_end(bx_opt, chk);
evas_object_show(chk);
elm_box_pack_end(bx, bx_opt);
// Focus Movement Policy
fr = elm_frame_add(bx);

View File

@ -507,6 +507,7 @@ _desc_init(void)
ELM_CONFIG_VAL(D, T, focus_highlight_animate, T_UCHAR);
ELM_CONFIG_VAL(D, T, focus_highlight_clip_disable, T_UCHAR);
ELM_CONFIG_VAL(D, T, focus_move_policy, T_UCHAR);
ELM_CONFIG_VAL(D, T, item_focus_on_selection, T_UCHAR);
ELM_CONFIG_VAL(D, T, toolbar_shrink_mode, T_INT);
ELM_CONFIG_VAL(D, T, fileselector_expand_enable, T_UCHAR);
ELM_CONFIG_VAL(D, T, fileselector_double_tap_navigation_enable, T_UCHAR);
@ -1490,6 +1491,7 @@ _config_load(void)
_elm_config->focus_highlight_animate = EINA_TRUE;
_elm_config->focus_highlight_clip_disable = EINA_FALSE;
_elm_config->focus_move_policy = ELM_FOCUS_MOVE_POLICY_CLICK;
_elm_config->item_focus_on_selection = EINA_TRUE;
_elm_config->toolbar_shrink_mode = 2;
_elm_config->fileselector_expand_enable = EINA_FALSE;
_elm_config->fileselector_double_tap_navigation_enable = EINA_FALSE;
@ -2067,6 +2069,9 @@ _env_get(void)
s = getenv("ELM_FOCUS_MOVE_POLICY");
if (s) _elm_config->focus_move_policy = !!atoi(s);
s = getenv("ELM_ITEM_FOCUS_ON_SELECTION");
if (s) _elm_config->item_focus_on_selection = !!atoi(s);
s = getenv("ELM_TOOLBAR_SHRINK_MODE");
if (s) _elm_config->toolbar_shrink_mode = atoi(s);
@ -2599,6 +2604,18 @@ elm_config_focus_move_policy_set(Elm_Focus_Move_Policy policy)
_elm_config->focus_move_policy = policy;
}
EAPI Eina_Bool
elm_config_item_focus_on_selection_get(void)
{
return _elm_config->item_focus_on_selection;
}
EAPI void
elm_config_item_focus_on_selection_set(Eina_Bool enabled)
{
_elm_config->item_focus_on_selection = !!enabled;
}
EAPI Eina_Bool
elm_config_scroll_bounce_enabled_get(void)
{

View File

@ -1277,6 +1277,26 @@ EAPI Elm_Focus_Move_Policy elm_config_focus_move_policy_get(void);
*/
EAPI void elm_config_focus_move_policy_set(Elm_Focus_Move_Policy policy);
/**
* Set elementary item focus on selection
*
* @see elm_config_item_focus_on_selection_set
* @since 1.10
* @ingroup Focus
*/
EAPI Eina_Bool elm_config_item_focus_on_selection_get(void);
/**
* Get elementary item focus on selection
*
* @param enabled Enable item focus on selection if @c EINA_TRUE, disable otherwise
*
* @see elm_config_item_focus_on_selection_get
* @since 1.10
* @ingroup Focus
*/
EAPI void elm_config_item_focus_on_selection_set(Eina_Bool enabled);
/**
* Get the system mirrored mode. This determines the default mirrored mode
* of widgets.

View File

@ -268,16 +268,13 @@ _elm_list_item_content_focus_set(Elm_List_Item *it, Elm_Focus_Direction dir,
return EINA_TRUE;
}
/* NOTE: this code will be used later when the item selection on key press
becomes optional. So do not remove this.
static Elm_List_Item *
_next_item_get(Elm_List_Data *sd, Elm_Focus_Direction dir)
_next_item_get(Elm_List_Data *sd, Elm_List_Item *cur_it, Elm_Focus_Direction dir)
{
Eina_List *list = NULL;
Elm_List_Item *it = NULL;
list = eina_list_data_find_list(sd->items, sd->focused_item);
list = eina_list_data_find_list(sd->items, cur_it);
if (!list) return it;
if ((!sd->h_mode && (dir == ELM_FOCUS_UP)) ||
((sd->h_mode) && (dir == ELM_FOCUS_LEFT)))
@ -297,12 +294,12 @@ _item_focused_next(Evas_Object *obj, Elm_Focus_Direction dir)
sd->prev_focused_item = sd->focused_item;
if (sd->focused_item)
it = _next_item_get(sd, dir);
it = _next_item_get(sd, (Elm_List_Item *)sd->focused_item, dir);
while (it &&
elm_object_item_disabled_get((Elm_Object_Item *)it))
{
it = _next_item_get(sd, dir);
it = _next_item_get(sd, it, dir);
}
if (it)
@ -313,7 +310,6 @@ _item_focused_next(Evas_Object *obj, Elm_Focus_Direction dir)
return EINA_FALSE;
}
*/
EOLIAN static Eina_Bool
_elm_list_elm_widget_event(Eo *obj, Elm_List_Data *sd, Evas_Object *src, Evas_Callback_Type type, void *event_info)
@ -333,6 +329,7 @@ _elm_list_elm_widget_event(Eo *obj, Elm_List_Data *sd, Evas_Object *src, Evas_Ca
Evas_Coord minh = 0;
Elm_List_Item *it = NULL;
Eina_Bool sel_ret = EINA_FALSE;
Eina_Bool foc_ret = EINA_FALSE;
if (elm_widget_disabled_get(obj)) return EINA_FALSE;
if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
@ -356,12 +353,17 @@ _elm_list_elm_widget_event(Eo *obj, Elm_List_Data *sd, Evas_Object *src, Evas_Ca
if ((sd->h_mode && !focused))
{
if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
sel_ret = _item_multi_select_up(sd);
if (_elm_config->item_focus_on_selection)
{
if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
sel_ret = _item_multi_select_up(sd);
else
sel_ret = _item_single_select_up(sd);
}
else
sel_ret = _item_single_select_up(sd);
foc_ret = _item_focused_next(obj, ELM_FOCUS_LEFT);
if (sel_ret)
if (sel_ret || foc_ret)
{
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
return EINA_TRUE;
@ -377,7 +379,10 @@ _elm_list_elm_widget_event(Eo *obj, Elm_List_Data *sd, Evas_Object *src, Evas_Ca
else
{
it = (Elm_List_Item *)elm_list_last_item_get(obj);
elm_list_item_selected_set((Elm_Object_Item *)it, EINA_TRUE);
if (_elm_config->item_focus_on_selection)
elm_list_item_selected_set((Elm_Object_Item *)it, EINA_TRUE);
else
elm_object_item_focus_set((Elm_Object_Item *)it, EINA_TRUE);
}
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
return EINA_TRUE;
@ -395,12 +400,17 @@ _elm_list_elm_widget_event(Eo *obj, Elm_List_Data *sd, Evas_Object *src, Evas_Ca
if (sd->h_mode && !focused)
{
if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
sel_ret = _item_multi_select_down(sd);
if (_elm_config->item_focus_on_selection)
{
if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
sel_ret = _item_multi_select_down(sd);
else
sel_ret = _item_single_select_down(sd);
}
else
sel_ret = _item_single_select_down(sd);
foc_ret = _item_focused_next(obj, ELM_FOCUS_RIGHT);
if (sel_ret)
if (sel_ret || foc_ret)
{
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
return EINA_TRUE;
@ -416,7 +426,10 @@ _elm_list_elm_widget_event(Eo *obj, Elm_List_Data *sd, Evas_Object *src, Evas_Ca
else
{
it = (Elm_List_Item *)elm_list_first_item_get(obj);
elm_list_item_selected_set((Elm_Object_Item *)it, EINA_TRUE);
if (_elm_config->item_focus_on_selection)
elm_list_item_selected_set((Elm_Object_Item *)it, EINA_TRUE);
else
elm_object_item_focus_set((Elm_Object_Item *)it, EINA_TRUE);
}
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
return EINA_TRUE;
@ -434,12 +447,17 @@ _elm_list_elm_widget_event(Eo *obj, Elm_List_Data *sd, Evas_Object *src, Evas_Ca
if (!sd->h_mode && !focused)
{
if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
sel_ret = _item_multi_select_up(sd);
if (_elm_config->item_focus_on_selection)
{
if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
sel_ret = _item_multi_select_up(sd);
else
sel_ret = _item_single_select_up(sd);
}
else
sel_ret = _item_single_select_up(sd);
foc_ret = _item_focused_next(obj, ELM_FOCUS_UP);
if (sel_ret)
if (sel_ret || foc_ret)
{
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
return EINA_TRUE;
@ -455,7 +473,10 @@ _elm_list_elm_widget_event(Eo *obj, Elm_List_Data *sd, Evas_Object *src, Evas_Ca
else
{
it = (Elm_List_Item *)elm_list_last_item_get(obj);
elm_list_item_selected_set((Elm_Object_Item *)it, EINA_TRUE);
if (_elm_config->item_focus_on_selection)
elm_list_item_selected_set((Elm_Object_Item *)it, EINA_TRUE);
else
elm_object_item_focus_set((Elm_Object_Item *)it, EINA_TRUE);
}
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
return EINA_TRUE;
@ -473,12 +494,17 @@ _elm_list_elm_widget_event(Eo *obj, Elm_List_Data *sd, Evas_Object *src, Evas_Ca
if (!sd->h_mode && !focused)
{
if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
sel_ret = _item_multi_select_down(sd);
if (_elm_config->item_focus_on_selection)
{
if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
sel_ret = _item_multi_select_down(sd);
else
sel_ret = _item_single_select_down(sd);
}
else
sel_ret = _item_single_select_down(sd);
foc_ret = _item_focused_next(obj, ELM_FOCUS_DOWN);
if (sel_ret)
if (sel_ret || foc_ret)
{
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
return EINA_TRUE;
@ -494,7 +520,10 @@ _elm_list_elm_widget_event(Eo *obj, Elm_List_Data *sd, Evas_Object *src, Evas_Ca
else
{
it = (Elm_List_Item *)elm_list_first_item_get(obj);
elm_list_item_selected_set((Elm_Object_Item *)it, EINA_TRUE);
if (_elm_config->item_focus_on_selection)
elm_list_item_selected_set((Elm_Object_Item *)it, EINA_TRUE);
else
elm_object_item_focus_set((Elm_Object_Item *)it, EINA_TRUE);
}
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
return EINA_TRUE;
@ -570,7 +599,10 @@ _elm_list_elm_widget_event(Eo *obj, Elm_List_Data *sd, Evas_Object *src, Evas_Ca
(!strcmp(ev->key, "space")))
&& (!sd->multi) && (sd->selected))
{
it = (Elm_List_Item *)elm_list_selected_item_get(obj);
if (_elm_config->item_focus_on_selection)
it = (Elm_List_Item *)elm_list_selected_item_get(obj);
else
it = (Elm_List_Item *)elm_object_focused_item_get(obj);
if (it) evas_object_smart_callback_call(WIDGET(it), SIG_ACTIVATED, it);
}
else if (!strcmp(ev->key, "Escape"))
@ -1204,7 +1236,7 @@ _elm_list_elm_widget_on_focus(Eo *obj, Elm_List_Data *sd)
it = _elm_list_nearest_visible_item_get(obj, it);
if (it)
{
if (is_sel)
if (_elm_config->item_focus_on_selection && is_sel)
elm_list_item_selected_set(it, EINA_TRUE);
else
elm_object_item_focus_set(it, EINA_TRUE);
@ -1675,8 +1707,10 @@ _elm_list_looping_left_cb(void *data,
{
Evas_Object *list = data;
Elm_List_Item *it = (Elm_List_Item *)elm_list_last_item_get(list);
elm_list_item_selected_set((Elm_Object_Item *)it, EINA_TRUE);
elm_object_item_focus_set((Elm_Object_Item *)it, EINA_TRUE);
if (_elm_config->item_focus_on_selection)
elm_list_item_selected_set((Elm_Object_Item *)it, EINA_TRUE);
else
elm_object_item_focus_set((Elm_Object_Item *)it, EINA_TRUE);
elm_layout_signal_emit(list, "elm,action,looping,left,end", "elm");
}
@ -1688,8 +1722,10 @@ _elm_list_looping_right_cb(void *data,
{
Evas_Object *list = data;
Elm_List_Item *it = (Elm_List_Item *)elm_list_first_item_get(list);
elm_list_item_selected_set((Elm_Object_Item *)it, EINA_TRUE);
elm_object_item_focus_set((Elm_Object_Item *)it, EINA_TRUE);
if (_elm_config->item_focus_on_selection)
elm_list_item_selected_set((Elm_Object_Item *)it, EINA_TRUE);
else
elm_object_item_focus_set((Elm_Object_Item *)it, EINA_TRUE);
elm_layout_signal_emit(list, "elm,action,looping,right,end", "elm");
}
@ -1701,8 +1737,10 @@ _elm_list_looping_up_cb(void *data,
{
Evas_Object *list = data;
Elm_List_Item *it = (Elm_List_Item *)elm_list_last_item_get(list);
elm_list_item_selected_set((Elm_Object_Item *)it, EINA_TRUE);
elm_object_item_focus_set((Elm_Object_Item *)it, EINA_TRUE);
if (_elm_config->item_focus_on_selection)
elm_list_item_selected_set((Elm_Object_Item *)it, EINA_TRUE);
else
elm_object_item_focus_set((Elm_Object_Item *)it, EINA_TRUE);
elm_layout_signal_emit(list, "elm,action,looping,up,end", "elm");
}
@ -1714,8 +1752,10 @@ _elm_list_looping_down_cb(void *data,
{
Evas_Object *list = data;
Elm_List_Item *it = (Elm_List_Item *)elm_list_first_item_get(list);
elm_list_item_selected_set((Elm_Object_Item *)it, EINA_TRUE);
elm_object_item_focus_set((Elm_Object_Item *)it, EINA_TRUE);
if (_elm_config->item_focus_on_selection)
elm_list_item_selected_set((Elm_Object_Item *)it, EINA_TRUE);
else
elm_object_item_focus_set((Elm_Object_Item *)it, EINA_TRUE);
elm_layout_signal_emit(list, "elm,action,looping,down,end", "elm");
}

View File

@ -229,6 +229,7 @@ struct _Elm_Config
unsigned char focus_highlight_animate;
unsigned char focus_highlight_clip_disable; /**< This shows disabled status of focus highlight clip feature. This value is false by default so the focus highlight is clipped. */
unsigned char focus_move_policy; /**< This show how the elementary focus is moved to another object. Focus can be moved by click or mouse_in. */
unsigned char item_focus_on_selection; /**< flag for item focus on selection.*/
int toolbar_shrink_mode;
unsigned char fileselector_expand_enable;
unsigned char fileselector_double_tap_navigation_enable;