focus: Added optional focus feature - item focus on selection.
authorAmitesh Singh <amitesh.sh@samsung.com>
Thu, 3 Apr 2014 10:11:57 +0000 (19:11 +0900)
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>
Thu, 3 Apr 2014 10:11:57 +0000 (19:11 +0900)
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

config/default/base.src
config/mobile/base.src
config/standard/base.src
src/bin/test_list.c
src/lib/elm_config.c
src/lib/elm_config.h
src/lib/elm_list.c
src/lib/elm_priv.h

index f8ca711..842b8c9 100644 (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;
index 5192c56..97773a9 100644 (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;
index b2e68d3..fa846ab 100644 (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;
index faa7a05..2003ff1 100644 (file)
@@ -1318,6 +1318,13 @@ test_list_focus_item_loop_enable_check_changed(void *data, Evas_Object *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)
 {
    printf("%s: %p\n", (char *)data, 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);
index cf66511..05ac9cc 100644 (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);
 
@@ -2600,6 +2605,18 @@ elm_config_focus_move_policy_set(Elm_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)
 {
    return _elm_config->thumbscroll_bounce_enable;
index e1494e0..5af8833 100644 (file)
@@ -1278,6 +1278,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.
  *
index beca47d..43b9e9e 100644 (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");
 }
 
index 3e66b10..4ebccb1 100644 (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;