focus: add focus_move_policy_automatic_set/get function 98/66998/1
authorJonghee Choi <joi.choi@samsung.com>
Fri, 22 Apr 2016 11:14:18 +0000 (20:14 +0900)
committerJonghee Choi <joi.choi@samsung.com>
Fri, 22 Apr 2016 11:20:21 +0000 (20:20 +0900)
Summary:
After setting specific focus move policy to one winset object,
if it should not follow the system focus move policy change,
this new api can be used.

(porting opensource code for Tizen Platform
opensource commit id : 09e7ffe7f06f4612ea6e3740447bdbdc81a083e9)

Change-Id: I2014353e45477d24a8e8ffb5a64162caccdf1980

src/bin/test_focus.c
src/lib/elm_config.c
src/lib/elm_focus.h
src/lib/elm_main.c
src/lib/elm_priv.h
src/lib/elm_widget.c
src/lib/elm_widget.eo
src/lib/elm_widget.h
src/lib/elm_win.c

index 2782299..ffee78f 100644 (file)
@@ -77,10 +77,23 @@ _focus_anim_changed(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
      elm_win_focus_highlight_animate_set(data, EINA_FALSE);
 }
 
+static void
+_rd_changed_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+   int value = elm_radio_state_value_get(obj);
+
+   if (value == 0)
+     elm_config_focus_move_policy_set(ELM_FOCUS_MOVE_POLICY_CLICK);
+   else if (value == 1)
+     elm_config_focus_move_policy_set(ELM_FOCUS_MOVE_POLICY_IN);
+   else
+     elm_config_focus_move_policy_set(ELM_FOCUS_MOVE_POLICY_KEY_ONLY);
+}
+
 void
 test_focus(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
 {
-   Evas_Object *win, *tbx, *tbar, *menu;
+   Evas_Object *win, *tbx, *tbar, *mainbx, *menu, *ttb;
    Elm_Object_Item *tb_it;
    Elm_Object_Item *menu_it;
    unsigned int i, j;
@@ -131,7 +144,7 @@ test_focus(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_inf
    elm_box_pack_end(tbx, tbar);
    evas_object_show(tbar);
 
-   Evas_Object *mainbx = elm_box_add(win);
+   mainbx = elm_box_add(win);
    elm_box_horizontal_set(mainbx, EINA_TRUE);
    evas_object_size_hint_weight_set(mainbx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
    elm_box_pack_end(tbx, mainbx);
@@ -304,8 +317,7 @@ test_focus(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_inf
         Evas_Object *ly = elm_layout_add(win);
         snprintf(buf, sizeof(buf), "%s/objects/test.edj", elm_app_data_dir_get());
         elm_layout_file_set(ly, buf, "twolines");
-        evas_object_size_hint_weight_set(ly, EVAS_HINT_EXPAND,
-                                         EVAS_HINT_EXPAND);
+        evas_object_size_hint_weight_set(ly, EVAS_HINT_EXPAND, 0.0);
         elm_box_pack_end(mainbx, ly);
         my_show(ly);
 
@@ -362,6 +374,30 @@ test_focus(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_inf
                   evas_object_smart_callback_add(bt2, "clicked", my_enable, bt);
                   my_show(bt2);
                   elm_object_focus_custom_chain_append(bx2, bt2, NULL);
+
+                  Evas_Object *bt3;
+                  bt3 = elm_button_add(win);
+                  elm_object_text_set(bt3, "KeyOnly with Auto");
+                  elm_object_focus_move_policy_set(bt3, ELM_FOCUS_MOVE_POLICY_KEY_ONLY);
+                  elm_object_focus_move_policy_automatic_set(bt, EINA_TRUE); // EINA_TURE is default
+                  evas_object_size_hint_align_set(bt3, EVAS_HINT_FILL,
+                                                  EVAS_HINT_FILL);
+                  evas_object_size_hint_weight_set(bt3, 0.0, 0.0);
+                  elm_box_pack_end(bx2, bt3);
+                  my_show(bt3);
+                  elm_object_focus_custom_chain_append(bx2, bt3, NULL);
+
+                  Evas_Object *bt4;
+                  bt4 = elm_button_add(win);
+                  elm_object_text_set(bt4, "KeyOnly without Auto");
+                  elm_object_focus_move_policy_set(bt4, ELM_FOCUS_MOVE_POLICY_KEY_ONLY);
+                  elm_object_focus_move_policy_automatic_set(bt4, EINA_FALSE);
+                  evas_object_size_hint_align_set(bt4, EVAS_HINT_FILL,
+                                                  EVAS_HINT_FILL);
+                  evas_object_size_hint_weight_set(bt4, 0.0, 0.0);
+                  elm_box_pack_end(bx2, bt4);
+                  my_show(bt4);
+                  elm_object_focus_custom_chain_append(bx2, bt4, NULL);
                }
 
           }
@@ -430,33 +466,65 @@ test_focus(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_inf
           }
      }
 
-   Evas_Object *bx = elm_box_add(win);
-   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND,
-                                    EVAS_HINT_EXPAND);
-   elm_box_pack_end(tbx, bx);
-   my_show(bx);
+   ttb = elm_table_add(win);
+   evas_object_size_hint_weight_set(ttb, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_box_pack_end(tbx, ttb);
+   my_show(ttb);
 
      {
         Evas_Object *ck;
 
-        ck = elm_check_add(bx);
+        ck = elm_check_add(ttb);
         elm_object_text_set(ck, "Focus Highlight Enable");
         elm_check_state_set(ck, elm_win_focus_highlight_enabled_get(win));
-        elm_box_pack_end(bx, ck);
+        evas_object_size_hint_align_set(ck, 0.0, EVAS_HINT_FILL);
+        elm_table_pack(ttb, ck, 0, 0, 1, 1);
         my_show(ck);
         evas_object_smart_callback_add(ck, "changed",
                                        _focus_highlight_changed,
                                        win);
 
-        ck = elm_check_add(bx);
+        ck = elm_check_add(ttb);
         elm_object_text_set(ck, "Focus Highlight Animation Enable");
         elm_check_state_set(ck, elm_win_focus_highlight_animate_get(win));
-        elm_box_pack_end(bx, ck);
+        evas_object_size_hint_align_set(ck, 0.0, EVAS_HINT_FILL);
+        elm_table_pack(ttb, ck, 0, 1, 1, 1);
         my_show(ck);
         evas_object_smart_callback_add(ck, "changed",
                                        _focus_anim_changed,
                                        win);
      }
+
+     {
+        Evas_Object *rd, *rdg;
+
+        for (i = 0; i < 3; i++)
+          {
+             rd = elm_radio_add(ttb);
+             elm_radio_state_value_set(rd, i);
+             evas_object_size_hint_weight_set(rd, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+             evas_object_size_hint_align_set(rd, 0.0, EVAS_HINT_FILL);
+             elm_table_pack(ttb, rd, 1, i, 1, 1);
+             evas_object_show(rd);
+             evas_object_smart_callback_add(rd, "changed", _rd_changed_cb, NULL);
+
+             if (i == 0)
+               {
+                  rdg = rd;
+                  elm_object_text_set(rd, "Move Policy: Key+Click(Default)");
+               }
+             else if (i == 1)
+               {
+                  elm_radio_group_add(rd, rdg);
+                  elm_object_text_set(rd, "Move Policy: Key+Click+In");
+               }
+             else
+               {
+                  elm_radio_group_add(rd, rdg);
+                  elm_object_text_set(rd, "Move Policy: Key Only");
+               }
+          }
+     }
 }
 
 /**** focus 2 ****/
index 7ee67eb..087b772 100644 (file)
@@ -2691,6 +2691,7 @@ EAPI void
 elm_config_focus_move_policy_set(Elm_Focus_Move_Policy policy)
 {
    _elm_config->focus_move_policy = policy;
+   _elm_win_focus_reconfigure();
 }
 
 EAPI Eina_Bool
index 158a437..a5c5174 100644 (file)
@@ -381,3 +381,33 @@ EAPI void                       elm_object_focus_region_show_mode_set(Evas_Objec
  * @ingroup Focus
  */
 EAPI Elm_Focus_Region_Show_Mode elm_object_focus_region_show_mode_get(const Evas_Object *obj);
+
+/**
+ * Returns the widget's focus movement policy mode setting.
+ *
+ * @param obj The widget.
+ * @return focus movement policy mode setting of the object.
+ *
+ * @see elm_object_focus_move_policy_automatic_set
+ *
+ * @since 1.18
+ *
+ * @ingroup Focus
+ */
+EAPI Eina_Bool elm_object_focus_move_policy_automatic_get(const Evas_Object *obj);
+
+/**
+ * Sets the widget's focus movement policy mode setting.
+ * When widget in automatic mode, it follows the system focus movement policy mode
+ * set by elm_config_focus_move_policy_set().
+ * @param obj The widget.
+ * @param automatic @c EINA_TRUE for auto focus_move_policy mode. @c EINA_FALSE for
+ * manual.
+ *
+ * @see elm_object_focus_move_policy_automatic_get
+ *
+ * @since 1.18
+ *
+ * @ingroup Focus
+ */
+EAPI void      elm_object_focus_move_policy_automatic_set(Evas_Object *obj, Eina_Bool automatic);
index 13f3f7e..5cbea63 100644 (file)
@@ -464,7 +464,7 @@ EAPI void
 elm_app_base_scale_set(double base_scale)
 {
    if (base_scale < 0.0) return;
-   if (fabs(base_scale) < DBL_EPSILON) return; 
+   if (fabs(base_scale) < DBL_EPSILON) return;
    app_base_scale = base_scale;
 }
 
@@ -1518,6 +1518,20 @@ elm_object_focus_move_policy_get(const Evas_Object *obj)
    return elm_widget_focus_move_policy_get(obj);
 }
 
+EAPI Eina_Bool
+elm_object_focus_move_policy_automatic_get(const Evas_Object *obj)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
+   return elm_widget_focus_move_policy_automatic_get(obj);
+}
+
+EAPI void
+elm_object_focus_move_policy_automatic_set(Evas_Object *obj, Eina_Bool automatic)
+{
+   EINA_SAFETY_ON_NULL_RETURN(obj);
+   elm_widget_focus_move_policy_automatic_set(obj, automatic);
+}
+
 EAPI void
 elm_object_scroll_hold_push(Evas_Object *obj)
 {
index 46fafe7..1aa0ae7 100644 (file)
@@ -369,6 +369,7 @@ void                 _elm_win_rescale(Elm_Theme *th,
                                       Eina_Bool use_theme);
 void                 _elm_win_access(Eina_Bool is_access);
 void                 _elm_win_translate(void);
+void                 _elm_win_focus_reconfigure(void);
 
 Ecore_X_Window       _elm_ee_xwin_get(const Ecore_Evas *ee);
 
index eba4257..fab3e37 100644 (file)
@@ -359,6 +359,7 @@ _elm_widget_evas_object_smart_add(Eo *obj, Elm_Widget_Smart_Data *priv)
    priv->obj = obj;
    priv->mirrored_auto_mode = EINA_TRUE; /* will follow system locale
                                           * settings */
+   priv->focus_move_policy_auto_mode = EINA_TRUE;
    priv->focus_region_show_mode = ELM_FOCUS_REGION_SHOW_WIDGET;
    elm_widget_can_focus_set(obj, EINA_TRUE);
    priv->is_mirrored = elm_config_mirrored_get();
@@ -3624,6 +3625,46 @@ _elm_widget_translate(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSE
    return EINA_TRUE;
 }
 
+/**
+ * @internal
+ *
+ * Resets the focus_move_policy mode from the system one
+ * for widgets that are in automatic mode.
+ *
+ * @param obj The widget.
+ *
+ */
+static void
+_elm_widget_focus_move_policy_reload(Evas_Object *obj)
+{
+   API_ENTRY return;
+   Elm_Focus_Move_Policy focus_move_policy = elm_config_focus_move_policy_get();
+
+   if (elm_widget_focus_move_policy_automatic_get(obj) &&
+       (sd->focus_move_policy != focus_move_policy))
+     {
+        sd->focus_move_policy = focus_move_policy;
+     }
+}
+
+EOLIAN static void
+_elm_widget_focus_reconfigure(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
+{
+   const Eina_List *l;
+   Evas_Object *child;
+   API_ENTRY return;
+
+   EINA_LIST_FOREACH(sd->subobjs, l, child)
+     {
+        if (elm_widget_is(child))
+          elm_widget_focus_reconfigure(child);
+     }
+
+   if (sd->hover_obj) elm_widget_focus_reconfigure(sd->hover_obj);
+
+   _elm_widget_focus_move_policy_reload(obj);
+}
+
 EAPI void
 elm_widget_content_part_set(Evas_Object *obj,
                             const char *part,
@@ -3633,6 +3674,42 @@ elm_widget_content_part_set(Evas_Object *obj,
    eo_do(obj, elm_obj_container_content_set(part, content));
 }
 
+/**
+ * Returns the widget's focus_move_policy mode setting.
+ *
+ * @param obj The widget.
+ * @return focus_move_policy mode setting of the object.
+ *
+ **/
+EOLIAN static Eina_Bool
+_elm_widget_focus_move_policy_automatic_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
+{
+   return sd->focus_move_policy_auto_mode;
+}
+
+/**
+ * @internal
+ *
+ * Sets the widget's focus_move_policy mode setting.
+ * When widget in automatic mode, it follows the system focus_move_policy mode set by
+ * elm_config_focus_move_policy_set().
+ * @param obj The widget.
+ * @param automatic EINA_TRUE for auto focus_move_policy mode. EINA_FALSE for manual.
+ */
+EOLIAN static void
+_elm_widget_focus_move_policy_automatic_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool automatic)
+{
+   if (sd->focus_move_policy_auto_mode != automatic)
+     {
+        sd->focus_move_policy_auto_mode = automatic;
+
+        if (automatic)
+          {
+             elm_widget_focus_move_policy_set(obj, elm_config_focus_move_policy_get());
+          }
+     }
+}
+
 EAPI Evas_Object *
 elm_widget_content_part_get(const Evas_Object *obj,
                             const char *part)
index 1f82db7..dfee0d9 100644 (file)
@@ -745,6 +745,18 @@ abstract Elm.Widget (Evas.Object_Smart, Elm_Interface_Atspi_Accessible, Elm_Inte
             policy: Elm_Focus_Move_Policy; [[Object's focus move policy.]]
          }
       }
+      @property focus_move_policy_automatic {
+         [[Control the widget's focus_move_policy mode setting.]]
+         set {
+         }
+         get {
+         }
+         values {
+            automatic: bool; [[$true to follow system focus move policy change, $false otherwise]]
+         }
+      }
+      focus_reconfigure {
+      }
    }
    implements {
       class.constructor;
index 4113cd7..e0f383a 100644 (file)
@@ -440,6 +440,7 @@ typedef struct _Elm_Widget_Smart_Data
    Eina_Bool                     focused : 1;
    Eina_Bool                     top_win_focused : 1;
    Eina_Bool                     tree_unfocusable : 1;
+   Eina_Bool                     focus_move_policy_auto_mode : 1; /* This is TRUE by default */
    Eina_Bool                     highlight_ignore : 1;
    Eina_Bool                     highlight_in_theme : 1;
    Eina_Bool                     access_highlight_in_theme : 1;
@@ -810,8 +811,11 @@ EAPI void             elm_widget_focus_highlight_geometry_get(const Evas_Object
 void                  _elm_widget_item_highlight_in_theme(Evas_Object *obj, Elm_Object_Item *it);
 EAPI void             elm_widget_focus_move_policy_set(Evas_Object *obj, Elm_Focus_Move_Policy policy);
 EAPI Elm_Focus_Move_Policy elm_widget_focus_move_policy_get(const Evas_Object *obj);
+EAPI Eina_Bool        elm_widget_focus_move_policy_automatic_get(const Evas_Object *obj);
+EAPI void             elm_widget_focus_move_policy_automatic_set(Evas_Object *obj, Eina_Bool automatic);
 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 void             elm_widget_focus_reconfigure(Evas_Object *obj);
 
 /**
  * Function to operate on a given widget's scrollabe children when necessary.
index 432e61d..1ff2523 100644 (file)
@@ -2796,6 +2796,16 @@ _elm_win_translate(void)
      elm_widget_translate(obj);
 }
 
+void
+_elm_win_focus_reconfigure(void)
+{
+   const Eina_List *l;
+   Evas_Object *obj;
+
+   EINA_LIST_FOREACH(_elm_win_list, l, obj)
+     elm_widget_focus_reconfigure(obj);
+}
+
 #ifdef HAVE_ELEMENTARY_X
 static Eina_Bool
 _elm_win_client_message(void *data,