From 73b16ef2103de1468a9e21fa9d014b581a4f3dbd Mon Sep 17 00:00:00 2001 From: Amitesh Singh Date: Thu, 3 Apr 2014 19:11:57 +0900 Subject: [PATCH] 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 --- legacy/elementary/config/default/base.src | 1 + legacy/elementary/config/mobile/base.src | 1 + legacy/elementary/config/standard/base.src | 1 + legacy/elementary/src/bin/test_list.c | 17 +++ legacy/elementary/src/lib/elm_config.c | 17 +++ legacy/elementary/src/lib/elm_config.h | 20 ++++ legacy/elementary/src/lib/elm_list.c | 116 ++++++++++++++------- legacy/elementary/src/lib/elm_priv.h | 1 + 8 files changed, 136 insertions(+), 38 deletions(-) diff --git a/legacy/elementary/config/default/base.src b/legacy/elementary/config/default/base.src index f8ca71175e..842b8c98c4 100644 --- a/legacy/elementary/config/default/base.src +++ b/legacy/elementary/config/default/base.src @@ -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; diff --git a/legacy/elementary/config/mobile/base.src b/legacy/elementary/config/mobile/base.src index 5192c56eca..97773a9e8e 100644 --- a/legacy/elementary/config/mobile/base.src +++ b/legacy/elementary/config/mobile/base.src @@ -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; diff --git a/legacy/elementary/config/standard/base.src b/legacy/elementary/config/standard/base.src index b2e68d3d4e..fa846abd9d 100644 --- a/legacy/elementary/config/standard/base.src +++ b/legacy/elementary/config/standard/base.src @@ -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; diff --git a/legacy/elementary/src/bin/test_list.c b/legacy/elementary/src/bin/test_list.c index faa7a05d64..2003ff1117 100644 --- a/legacy/elementary/src/bin/test_list.c +++ b/legacy/elementary/src/bin/test_list.c @@ -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); diff --git a/legacy/elementary/src/lib/elm_config.c b/legacy/elementary/src/lib/elm_config.c index cf665113eb..05ac9ccc24 100644 --- a/legacy/elementary/src/lib/elm_config.c +++ b/legacy/elementary/src/lib/elm_config.c @@ -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) { diff --git a/legacy/elementary/src/lib/elm_config.h b/legacy/elementary/src/lib/elm_config.h index e1494e02ea..5af8833895 100644 --- a/legacy/elementary/src/lib/elm_config.h +++ b/legacy/elementary/src/lib/elm_config.h @@ -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. diff --git a/legacy/elementary/src/lib/elm_list.c b/legacy/elementary/src/lib/elm_list.c index beca47d076..43b9e9eb30 100644 --- a/legacy/elementary/src/lib/elm_list.c +++ b/legacy/elementary/src/lib/elm_list.c @@ -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"); } diff --git a/legacy/elementary/src/lib/elm_priv.h b/legacy/elementary/src/lib/elm_priv.h index 3e66b10c29..4ebccb1f08 100644 --- a/legacy/elementary/src/lib/elm_priv.h +++ b/legacy/elementary/src/lib/elm_priv.h @@ -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;