elm - focus feature - add config option to automatically show/hide focus
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>
Wed, 4 Mar 2015 08:47:54 +0000 (17:47 +0900)
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>
Wed, 4 Mar 2015 08:47:54 +0000 (17:47 +0900)
this adds logic in elm widget and elm win to figure out how to
automatically show a focus hilight when switching focus, or to hide
it. this really should be the default mode, thus in all default
profiles (default, standard, mobile) it's turned on. this means if you
tab or shif+tab or use arrow keys to switch focus, the focus hilight
will magicallly appear. click with a mouse to change focus and it'll
disappear assuming you want to use the mouse to do things. If focus is
explicitly turned on in config or in the window by api, then this has
no effect and focus will remain on all the time. this adds apis to
change these config values and options in the default elm config tool
to swizzle them as well as config upgrade handling for existing configs.

@feature

config/default/base.src.in
config/mobile/base.src.in
config/standard/base.src.in
src/bin/config.c
src/lib/elm_config.c
src/lib/elm_config.h
src/lib/elm_priv.h
src/lib/elm_widget.c
src/lib/elm_widget.h
src/lib/elm_win.c

index e29aeb2..a0245f3 100644 (file)
@@ -1,5 +1,5 @@
 group "Elm_Config" struct {
-  value "config_version" int: 131073;
+  value "config_version" int: 131074;
   value "engine" string: "";
   value "vsync" uchar: 0;
   value "thumbscroll_enable" uchar: 1;
@@ -94,6 +94,8 @@ group "Elm_Config" struct {
   value "audio_mute_input" uchar: 0;
   value "audio_mute_alert" uchar: 0;
   value "audio_mute_all" uchar: 0;
+  value "win_auto_focus_enable" uchar: 1;
+  value "win_auto_focus_animate" uchar: 1;
   group "color_palette" list {
      group "Elm_Custom_Palette" struct {
         value "palette_name" string: "default";
index ee09115..e9db0a2 100644 (file)
@@ -1,5 +1,5 @@
 group "Elm_Config" struct {
-  value "config_version" int: 131073;
+  value "config_version" int: 131074;
   value "engine" string: "";
   value "vsync" uchar: 0;
   value "thumbscroll_enable" uchar: 1;
@@ -98,6 +98,8 @@ group "Elm_Config" struct {
   value "audio_mute_input" uchar: 0;
   value "audio_mute_alert" uchar: 0;
   value "audio_mute_all" uchar: 0;
+  value "win_auto_focus_enable" uchar: 1;
+  value "win_auto_focus_animate" uchar: 1;
   group "color_palette" list {
      group "Elm_Custom_Palette" struct {
         value "palette_name" string: "default";
index 2ee0271..9cae3a1 100644 (file)
@@ -1,5 +1,5 @@
 group "Elm_Config" struct {
-  value "config_version" int: 131073;
+  value "config_version" int: 131074;
   value "engine" string: "";
   value "vsync" uchar: 0;
   value "thumbscroll_enable" uchar: 0;
@@ -95,6 +95,8 @@ group "Elm_Config" struct {
   value "audio_mute_input" uchar: 0;
   value "audio_mute_alert" uchar: 0;
   value "audio_mute_all" uchar: 0;
+  value "win_auto_focus_enable" uchar: 1;
+  value "win_auto_focus_animate" uchar: 1;
   group "color_palette" list {
      group "Elm_Custom_Palette" struct {
         value "palette_name" string: "default";
index 85f1743..1663d4d 100644 (file)
@@ -1585,6 +1585,30 @@ _status_config_focus_autoscroll_changed_cb(void *data EINA_UNUSED,
 }
 
 static void
+_config_focus_auto_show_cb(void *data EINA_UNUSED, Evas_Object *obj,
+                           void *event_info EINA_UNUSED)
+{
+   Eina_Bool cf = elm_config_window_auto_focus_enable_get();
+   Eina_Bool val = elm_check_state_get(obj);
+
+   if (cf == val) return;
+   elm_config_window_auto_focus_enable_set(val);
+   elm_config_all_flush();
+}
+
+static void
+_config_focus_auto_animate_cb(void *data EINA_UNUSED, Evas_Object *obj,
+                           void *event_info EINA_UNUSED)
+{
+   Eina_Bool cf = elm_config_window_auto_focus_animate_get();
+   Eina_Bool val = elm_check_state_get(obj);
+
+   if (cf == val) return;
+   elm_config_window_auto_focus_animate_set(val);
+   elm_config_all_flush();
+}
+
+static void
 _status_config_focus(Evas_Object *win,
                      Evas_Object *naviframe)
 {
@@ -1618,6 +1642,16 @@ _status_config_focus(Evas_Object *win,
              _config_focus_item_select_on_focus_cb, NULL);
    elm_check_state_set(ck, elm_config_item_select_on_focus_disabled_get());
 
+   CHECK_ADD("Enable Automatic focus display",
+             "Set whether enable/disable focus highlight automatically.",
+             _config_focus_auto_show_cb, NULL);
+   elm_check_state_set(ck, elm_config_window_auto_focus_enable_get());
+   CHECK_ADD("Enable Automatic focus animation",
+             "Set whether enable/disable focus highlight animation<br/>"
+             "automatically when automatic focus shows.",
+             _config_focus_auto_animate_cb, NULL);
+   elm_check_state_set(ck, elm_config_window_auto_focus_enable_get());
+
    fr = elm_frame_add(bx);
    elm_object_text_set(fr, "Focus Autoscroll Mode");
    evas_object_size_hint_weight_set(fr, EVAS_HINT_EXPAND, 0.0);
index 1d6aa75..b11bb0b 100644 (file)
@@ -589,6 +589,8 @@ _desc_init(void)
    ELM_CONFIG_VAL(D, T, audio_mute_all, T_UCHAR);
    ELM_CONFIG_LIST(D, T, bindings, _config_bindings_widget_edd);
    ELM_CONFIG_VAL(D, T, atspi_mode, T_UCHAR);
+   ELM_CONFIG_VAL(D, T, win_auto_focus_enable, T_UCHAR);
+   ELM_CONFIG_VAL(D, T, win_auto_focus_animate, T_UCHAR);
 #undef T
 #undef D
 #undef T_INT
@@ -1610,6 +1612,8 @@ _config_load(void)
    _elm_config->audio_mute_input = 0;
    _elm_config->audio_mute_alert = 0;
    _elm_config->audio_mute_all = 0;
+   _elm_config->win_auto_focus_enable = 1;
+   _elm_config->win_auto_focus_animate = 1;
    _elm_config->atspi_mode = ELM_ATSPI_MODE_OFF;
 }
 
@@ -1830,6 +1834,10 @@ _config_update(void)
    /* we also need to update for property changes in the root window
     * if needed, but that will be dependent on new properties added
     * with each version */
+   IFCFG(0x0002)
+   _elm_config->win_auto_focus_enable = tcfg->win_auto_focus_enable;;
+   _elm_config->win_auto_focus_animate = tcfg->win_auto_focus_animate;
+   IFCFGEND
 
    /**
     * Fix user config for current ELM_CONFIG_EPOCH here.
@@ -3155,6 +3163,30 @@ elm_config_audio_mute_set(Edje_Channel channel, Eina_Bool mute)
    edje_audio_channel_mute_set(channel, mute);
 }
 
+EAPI Eina_Bool
+elm_config_window_auto_focus_enable_get(void)
+{
+   return _elm_config->win_auto_focus_enable;
+}
+
+EAPI void
+elm_config_window_auto_focus_enable_set(Eina_Bool enable)
+{
+   _elm_config->win_auto_focus_enable = enable;
+}
+
+EAPI Eina_Bool
+elm_config_window_auto_focus_animate_get(void)
+{
+   return _elm_config->win_auto_focus_animate;
+}
+
+EAPI void
+elm_config_window_auto_focus_animate_set(Eina_Bool enable)
+{
+   _elm_config->win_auto_focus_animate = enable;
+}
+
 EAPI void
 elm_config_all_flush(void)
 {
index aa1e1b0..6b625b8 100644 (file)
@@ -1724,6 +1724,54 @@ EAPI Eina_Bool elm_config_audio_mute_get(Edje_Channel channel);
 EAPI void      elm_config_audio_mute_set(Edje_Channel channel, Eina_Bool mute);
 
 /**
+ * Get the auto focus enable flag
+ *
+ * This determines if elementary will show a focus box indicating the focused
+ * widget automatically if keyboard controls like "Tab" are used to switch
+ * focus between widgets. Mouse or touch control will hide this auto shown
+ * focus, unless focus display has been expliccitly forced on for the window.
+ * 
+ * @return The enabled state for auto focus display
+ * @since 1.14
+ */
+EAPI Eina_Bool elm_config_window_auto_focus_enable_get(void);
+
+/**
+ * Set the auto focus enabled state
+ *
+ * This determines if elementary will show a focus box indicating the focused
+ * widget automatically if keyboard controls like "Tab" are used to switch
+ * focus between widgets. Mouse or touch control will hide this auto shown
+ * focus, unless focus display has been expliccitly forced on for the window.
+ * 
+ * @param enable the auto focus display enabled state
+ * @since 1.14
+ */
+EAPI void      elm_config_window_auto_focus_enable_set(Eina_Bool enable);
+
+/**
+ * Get the auto focus animate flag
+ *
+ * If auto focus - see elm_config_window_auto_focus_enable_set() , is enabled
+ * then this will determine if the focus display will be animated or not.
+ *
+ * @return The enabled state for auto focus animation
+ * @since 1.14
+ */
+EAPI Eina_Bool elm_config_window_auto_focus_animate_get(void);
+
+/**
+ * Set the auto focus animation flag
+ *
+ * If auto focus - see elm_config_window_auto_focus_enable_set() , is enabled
+ * then this will determine if the focus display will be animated or not.
+ *
+ * @param enable the auto focus animation state
+ * @since 1.14
+ */
+EAPI void      elm_config_window_auto_focus_animate_set(Eina_Bool enable);
+
+/**
  * @defgroup ATSPI AT-SPI2 Accessibility
  * @ingroup Elementary
  *
index dbfb8cb..1ddf9aa 100644 (file)
@@ -123,7 +123,7 @@ struct _Elm_Theme
  * the users config doesn't need to be wiped - simply new values need
  * to be put in
  */
-#define ELM_CONFIG_FILE_GENERATION 0x0001
+#define ELM_CONFIG_FILE_GENERATION 0x0002
 #define ELM_CONFIG_VERSION_EPOCH_OFFSET 16
 #define ELM_CONFIG_VERSION         ((ELM_CONFIG_EPOCH << ELM_CONFIG_VERSION_EPOCH_OFFSET) | \
                                     ELM_CONFIG_FILE_GENERATION)
@@ -286,6 +286,8 @@ struct _Elm_Config
    unsigned char audio_mute_input;
    unsigned char audio_mute_alert;
    unsigned char audio_mute_all;
+   unsigned char win_auto_focus_enable;
+   unsigned char win_auto_focus_animate;
    Eina_List    *bindings;
    Eina_Bool     atspi_mode;
 
index c4d2d69..39e3c32 100644 (file)
@@ -3822,8 +3822,12 @@ elm_widget_focus_mouse_up_handle(Evas_Object *obj)
 EOLIAN static void
 _elm_widget_focus_mouse_up_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
 {
+   Evas_Object *top;
+
    if (!obj) return;
    if (!_is_focusable(obj)) return;
+   top = elm_widget_top_get(obj);
+   if (top && eo_isa(top, ELM_WIN_CLASS)) _elm_win_focus_auto_hide(top);
    elm_widget_focus_steal(obj);
 }
 
index 67cddb0..96a9444 100644 (file)
@@ -534,6 +534,8 @@ void                  _elm_win_focus_highlight_in_theme_update(Evas_Object *obj,
 void                  _elm_win_focus_highlight_signal_emit(Evas_Object *obj, const char *emission, const char *source);
 void                  _elm_win_focus_highlight_signal_callback_add(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb _focus_highlight_signal_cb, void *data);
 void                  _elm_win_focus_highlight_signal_callback_del(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb _focus_highlight_signal_cb);
+void                  _elm_win_focus_auto_show(Evas_Object *obj);
+void                  _elm_win_focus_auto_hide(Evas_Object *obj);
 
 EAPI void             _elm_access_clear(Elm_Access_Info *ac);
 EAPI void             _elm_access_text_set(Elm_Access_Info *ac, int type, const char *text);
index 0056bd7..1bfdd93 100644 (file)
@@ -166,6 +166,8 @@ struct _Elm_Win_Data
       Eina_Bool    animate : 1; /* set true when the focus highlight animate is enabled */
       Eina_Bool    animate_supported : 1; /* set true when the focus highlight animate is supported by theme */
       Eina_Bool    geometry_changed : 1;
+      Eina_Bool    auto_enabled : 1;
+      Eina_Bool    auto_animate : 1;
    } focus_highlight;
 
    Evas_Object *icon;
@@ -967,7 +969,7 @@ _elm_win_focus_highlight_reconfigure_job(void *data)
           (sd->obj, fobj, "focus_highlight", "top", str);
         sd->focus_highlight.theme_changed = EINA_FALSE;
 
-        if (sd->focus_highlight.animate)
+        if ((sd->focus_highlight.animate) || (sd->focus_highlight.auto_animate))
           {
              str = edje_object_data_get(sd->focus_highlight.fobj, "animate");
              sd->focus_highlight.animate_supported = ((str) && (!strcmp(str, "on")));
@@ -1386,7 +1388,10 @@ static Eina_Bool
 _key_action_move(Evas_Object *obj, const char *params)
 {
    const char *dir = params;
+   Evas_Object *top;
 
+   top = elm_widget_top_get(obj);
+   if (top && eo_isa(top, ELM_WIN_CLASS)) _elm_win_focus_auto_show(top);
    if (!strcmp(dir, "previous"))
      elm_widget_focus_cycle(obj, ELM_FOCUS_PREVIOUS);
    else if (!strcmp(dir, "next"))
@@ -4864,7 +4869,7 @@ _elm_win_focus_highlight_enabled_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina
 
    sd->focus_highlight.enabled = enabled;
 
-   if (sd->focus_highlight.enabled)
+   if ((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled))
      _elm_win_focus_highlight_init(sd);
    else
      _elm_win_focus_highlight_shutdown(sd);
@@ -5109,7 +5114,7 @@ void
 _elm_win_focus_highlight_signal_emit(Evas_Object *obj, const char *emission, const char *source)
 {
    ELM_WIN_DATA_GET(obj, sd);
-   if (sd->focus_highlight.enabled)
+   if ((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled))
      edje_object_signal_emit(sd->focus_highlight.fobj, emission, source);
 }
 
@@ -5119,7 +5124,8 @@ _elm_win_focus_highlight_signal_callback_add(Evas_Object *obj, const char *emiss
                                              void *data)
 {
    ELM_WIN_DATA_GET(obj, sd);
-   if (sd->focus_highlight.enabled && sd->focus_highlight.fobj)
+   if (((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled))
+       && (sd->focus_highlight.fobj))
      edje_object_signal_callback_add(sd->focus_highlight.fobj, emission, source, _focus_highlight_signal_cb, data);
 }
 
@@ -5128,7 +5134,8 @@ _elm_win_focus_highlight_signal_callback_del(Evas_Object *obj, const char *emiss
                                              const char *source, Edje_Signal_Cb _focus_highlight_signal_cb)
 {
    ELM_WIN_DATA_GET(obj, sd);
-   if (sd->focus_highlight.enabled && sd->focus_highlight.fobj)
+   if (((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled))
+       && (sd->focus_highlight.fobj))
      edje_object_signal_callback_del(sd->focus_highlight.fobj, emission, source, _focus_highlight_signal_cb);
 }
 
@@ -5143,6 +5150,34 @@ _elm_win_focus_highlight_start(Evas_Object *obj)
    _elm_win_focus_highlight_reconfigure_job(obj);
 }
 
+void
+_elm_win_focus_auto_show(Evas_Object *obj)
+{
+   ELM_WIN_DATA_GET(obj, sd);
+   Eina_Bool pfocus = (sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled);
+   sd->focus_highlight.auto_enabled = _elm_config->win_auto_focus_enable;
+   sd->focus_highlight.auto_animate = _elm_config->win_auto_focus_animate;
+   if (pfocus != ((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled)))
+     {
+        if ((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled))
+          _elm_win_focus_highlight_init(sd);
+     }
+}
+
+void
+_elm_win_focus_auto_hide(Evas_Object *obj)
+{
+   ELM_WIN_DATA_GET(obj, sd);
+   Eina_Bool pfocus = (sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled);
+   sd->focus_highlight.auto_enabled = EINA_FALSE;
+   sd->focus_highlight.auto_animate = EINA_FALSE;
+   if (pfocus != ((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled)))
+     {
+        if (!((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled)))
+          _elm_win_focus_highlight_shutdown(sd);
+     }
+}
+
 EAPI Ecore_Window
 elm_win_window_id_get(const Evas_Object *obj)
 {