From 7d627d90f7f1e9aa93fe40400e04e0f2f414b041 Mon Sep 17 00:00:00 2001 From: Jaeun Choi Date: Fri, 28 Feb 2014 10:36:15 +0900 Subject: [PATCH] elementary key binding feature implementation Summary: This patch implements elementary key binding feature. Test Plan: None Reviewers: Hermet, raster CC: seoz Differential Revision: https://phab.enlightenment.org/D506 Conflicts: src/lib/elm_config.c --- config/default/base.src | 31 +++++++++++ config/standard/Makefile.am | 4 +- config/standard/base.src | 31 +++++++++++ src/lib/elm_config.c | 133 ++++++++++++++++++++++++++++++++++++++++++++ src/lib/elm_panel.c | 20 ++++--- src/lib/elm_priv.h | 23 ++++++++ src/lib/elm_widget.h | 8 +++ 7 files changed, 241 insertions(+), 9 deletions(-) diff --git a/config/default/base.src b/config/default/base.src index 124f5bf..edce1e6 100644 --- a/config/default/base.src +++ b/config/default/base.src @@ -244,4 +244,35 @@ group "Elm_Config" struct { } } } + group "bindings" list { + group "Elm_Config_Bindings_Widget" struct { + value "name" string: "Elm_Panel"; + group "key_bindings" list { + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "modifiers" string: "None"; + value "key" string: "Return"; + value "action" string: "toggle"; + value "params" string: ""; + value "any_mod" uchar: 1; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "modifiers" string: "None"; + value "key" string: "KP_Enter"; + value "action" string: "toggle"; + value "params" string: ""; + value "any_mod" uchar: 1; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "modifiers" string: "None"; + value "key" string: "space"; + value "action" string: "toggle"; + value "params" string: ""; + value "any_mod" uchar: 1; + } + } + } + } } diff --git a/config/standard/Makefile.am b/config/standard/Makefile.am index 60ce44b..b84899d 100644 --- a/config/standard/Makefile.am +++ b/config/standard/Makefile.am @@ -5,13 +5,13 @@ EET_EET = @eet_eet@ EXTRA_DIST = \ profile.desktop \ icon.png \ - base.src + base.src filesdir = $(datadir)/elementary/config/standard files_DATA = \ profile.desktop \ icon.png \ - base.cfg + base.cfg %.cfg: %.src $(EET_EET) -e \ diff --git a/config/standard/base.src b/config/standard/base.src index cf61b79..bd7ae56 100644 --- a/config/standard/base.src +++ b/config/standard/base.src @@ -245,4 +245,35 @@ group "Elm_Config" struct { } } } + group "bindings" list { + group "Elm_Config_Bindings_Widget" struct { + value "name" string: "Elm_Panel"; + group "key_bindings" list { + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "modifiers" string: "None"; + value "key" string: "Return"; + value "action" string: "toggle"; + value "params" string: ""; + value "any_mod" uchar: 1; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "modifiers" string: "None"; + value "key" string: "KP_Enter"; + value "action" string: "toggle"; + value "params" string: ""; + value "any_mod" uchar: 1; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "modifiers" string: "None"; + value "key" string: "space"; + value "action" string: "toggle"; + value "params" string: ""; + value "any_mod" uchar: 1; + } + } + } + } } diff --git a/src/lib/elm_config.c b/src/lib/elm_config.c index 7a93b90..daa67aa 100644 --- a/src/lib/elm_config.c +++ b/src/lib/elm_config.c @@ -19,12 +19,16 @@ static Eet_Data_Descriptor *_config_font_overlay_edd = NULL; static Eet_Data_Descriptor *_config_color_edd = NULL; static Eet_Data_Descriptor *_config_color_palette_edd = NULL; static Eet_Data_Descriptor *_config_color_overlay_edd = NULL; +static Eet_Data_Descriptor *_config_bindings_widget_edd = NULL; +static Eet_Data_Descriptor *_config_binding_key_edd = NULL; const char *_elm_preferred_engine = NULL; Eina_List *_font_overlays_del = NULL; Eina_List *_color_overlays_del = NULL; static Ecore_Poller *_elm_cache_flush_poller = NULL; +Eina_Hash *_elm_key_bindings = NULL; + const char *_elm_engines[] = { "software_x11", "fb", @@ -359,6 +363,31 @@ _desc_init(void) return; } + EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Elm_Config_Bindings_Widget); + eddc.func.str_direct_alloc = NULL; + eddc.func.str_direct_free = NULL; + + _config_bindings_widget_edd = eet_data_descriptor_stream_new(&eddc); + if (!_config_bindings_widget_edd) + { + ERR("EEEK! eet_data_descriptor_stream_new() failed."); + eet_data_descriptor_free(_config_edd); + return; + } + + memset(&eddc, 0, sizeof(eddc)); /* just in case... */ + EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Elm_Config_Binding_Key); + eddc.func.str_direct_alloc = NULL; + eddc.func.str_direct_free = NULL; + + _config_binding_key_edd = eet_data_descriptor_stream_new(&eddc); + if (!_config_binding_key_edd) + { + ERR("EEEK! eet_data_descriptor_stream_new() failed."); + eet_data_descriptor_free(_config_edd); + return; + } + #define T_INT EET_T_INT #define T_DOUBLE EET_T_DOUBLE #define T_STRING EET_T_STRING @@ -406,6 +435,24 @@ _desc_init(void) #undef T #undef D +#define T Elm_Config_Bindings_Widget +#define D _config_bindings_widget_edd + ELM_CONFIG_VAL(D, T, name, EET_T_STRING); + ELM_CONFIG_LIST(D, T, key_bindings, _config_binding_key_edd); +#undef T +#undef D + +#define T Elm_Config_Binding_Key +#define D _config_binding_key_edd + ELM_CONFIG_VAL(D, T, context, EET_T_INT); + ELM_CONFIG_VAL(D, T, modifiers, EET_T_STRING); + ELM_CONFIG_VAL(D, T, key, EET_T_STRING); + ELM_CONFIG_VAL(D, T, action, EET_T_STRING); + ELM_CONFIG_VAL(D, T, params, EET_T_STRING); + ELM_CONFIG_VAL(D, T, any_mod, EET_T_UCHAR); +#undef T +#undef D + #define T Elm_Config #define D _config_edd ELM_CONFIG_VAL(D, T, config_version, T_INT); @@ -510,6 +557,7 @@ _desc_init(void) ELM_CONFIG_VAL(D, T, audio_mute_input, T_UCHAR); ELM_CONFIG_VAL(D, T, audio_mute_alert, T_UCHAR); ELM_CONFIG_VAL(D, T, audio_mute_all, T_UCHAR); + ELM_CONFIG_LIST(D, T, bindings, _config_bindings_widget_edd); #undef T #undef D #undef T_INT @@ -550,6 +598,18 @@ _desc_shutdown(void) eet_data_descriptor_free(_config_color_overlay_edd); _config_color_overlay_edd = NULL; } + + if (_config_bindings_widget_edd) + { + eet_data_descriptor_free(_config_bindings_widget_edd); + _config_bindings_widget_edd = NULL; + } + + if (_config_binding_key_edd) + { + eet_data_descriptor_free(_config_binding_key_edd); + _config_binding_key_edd = NULL; + } } static int @@ -1208,6 +1268,8 @@ _config_free(Elm_Config *cfg) Elm_Custom_Palette *palette; Elm_Color_RGBA *color; char *color_class; + Elm_Config_Bindings_Widget *wb; + Elm_Config_Binding_Key *kb; if (!cfg) return; EINA_LIST_FREE(cfg->font_dirs, fontdir) @@ -1234,6 +1296,19 @@ _config_free(Elm_Config *cfg) EINA_LIST_FREE(palette->color_list, color) free(color); free(palette); } + EINA_LIST_FREE(cfg->bindings, wb) + { + eina_stringshare_del(wb->name); + EINA_LIST_FREE(wb->key_bindings, kb) + { + eina_stringshare_del(kb->modifiers); + eina_stringshare_del(kb->key); + eina_stringshare_del(kb->action); + eina_stringshare_del(kb->params); + free(kb); + } + free(wb); + } eina_stringshare_del(cfg->theme); eina_stringshare_del(cfg->modules); eina_stringshare_del(cfg->indicator_service_0); @@ -2041,6 +2116,58 @@ _env_get(void) if (s) _elm_config->magnifier_scale = _elm_atof(s); } +void +_elm_config_key_binding_hash(void) +{ + Elm_Config_Bindings_Widget *wb; + Eina_List *l; + + if (_elm_key_bindings) + eina_hash_free(_elm_key_bindings); + + _elm_key_bindings = eina_hash_string_superfast_new(NULL); + EINA_LIST_FOREACH(_elm_config->bindings, l, wb) + { + eina_hash_add(_elm_key_bindings, wb->name, wb->key_bindings); + } +} + +Eina_Bool +_elm_config_key_binding_call(Evas_Object *obj, + const Evas_Event_Key_Down *ev, + const Elm_Action *actions) +{ + Elm_Config_Binding_Key *binding; + Eina_List *binding_list, *l; + int i = 0; + + binding_list = eina_hash_find(_elm_key_bindings, elm_widget_type_get(obj)); + + if (binding_list) + { + EINA_LIST_FOREACH(binding_list, l, binding) + { + if (binding->key && (!strcmp(binding->key, ev->keyname)) + && ((evas_key_modifier_is_set + (ev->modifiers, binding->modifiers) + || (binding->any_mod)))) + { + while (actions[i].name) + { + if (!strcmp(binding->action, actions[i].name)) + { + actions[i].func(obj, binding->params); + return EINA_TRUE; + } + i++; + } + break; + } + } + } + return EINA_FALSE; +} + EAPI Eina_Bool elm_config_mirrored_get(void) { @@ -2884,6 +3011,7 @@ _elm_config_init(void) _elm_config_color_overlay_apply(); _elm_recache(); _elm_clouseau_reload(); + _elm_config_key_binding_hash(); } void @@ -2987,6 +3115,7 @@ _elm_config_reload(void) _elm_rescale(); _elm_recache(); _elm_clouseau_reload(); + _elm_config_key_binding_hash(); ecore_event_add(ELM_EVENT_CONFIG_ALL_CHANGED, NULL, NULL, NULL); } @@ -3059,6 +3188,7 @@ _elm_config_profile_set(const char *profile) _elm_rescale(); _elm_recache(); _elm_clouseau_reload(); + _elm_config_key_binding_hash(); } void @@ -3084,4 +3214,7 @@ _elm_config_shutdown(void) #endif _desc_shutdown(); + + if (_elm_key_bindings) + eina_hash_free(_elm_key_bindings); } diff --git a/src/lib/elm_panel.c b/src/lib/elm_panel.c index 060c82f..a6d3072 100644 --- a/src/lib/elm_panel.c +++ b/src/lib/elm_panel.c @@ -20,6 +20,13 @@ static const Evas_Smart_Cb_Description _smart_callbacks[] = { {NULL, NULL} }; +void _key_action_toggle(Evas_Object *obj, const char *params); + +static const Elm_Action key_actions[] = { + {"toggle", _key_action_toggle}, + {NULL, NULL} +}; + static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl) @@ -247,10 +254,14 @@ _panel_toggle(void *data EINA_UNUSED, edje_object_message_signal_process(wd->resize_obj); } +void _key_action_toggle(Evas_Object *obj, const char *params EINA_UNUSED) +{ + _panel_toggle(NULL, obj, NULL, NULL); +} + static void _elm_panel_smart_event(Eo *obj, void *_pd EINA_UNUSED, va_list *list) { - Evas_Object *src = va_arg(*list, Evas_Object *); Evas_Callback_Type type = va_arg(*list, Evas_Callback_Type); Evas_Event_Key_Down *ev = va_arg(*list, void *); @@ -263,12 +274,7 @@ _elm_panel_smart_event(Eo *obj, void *_pd EINA_UNUSED, va_list *list) if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return; if (src != obj) return; - if ((strcmp(ev->key, "Return")) && - (strcmp(ev->key, "KP_Enter")) && - (strcmp(ev->key, "space"))) - return; - - _panel_toggle(NULL, obj, NULL, NULL); + _elm_config_key_binding_call(obj, ev, key_actions); ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; if (ret) *ret = EINA_TRUE; diff --git a/src/lib/elm_priv.h b/src/lib/elm_priv.h index 5d18a9f..e1081e3 100644 --- a/src/lib/elm_priv.h +++ b/src/lib/elm_priv.h @@ -76,6 +76,8 @@ typedef struct _Elm_Theme_Files Elm_Theme_Files; typedef struct _Edje_Signal_Data Edje_Signal_Data; typedef struct _Elm_Config Elm_Config; +typedef struct _Elm_Config_Bindings_Widget Elm_Config_Bindings_Widget; +typedef struct _Elm_Config_Binding_Key Elm_Config_Binding_Key; typedef struct _Elm_Module Elm_Module; typedef struct _Elm_Datetime_Module_Data Elm_Datetime_Module_Data; @@ -275,12 +277,29 @@ struct _Elm_Config unsigned char audio_mute_input; unsigned char audio_mute_alert; unsigned char audio_mute_all; + Eina_List *bindings; /* Not part of the EET file */ Eina_Bool is_mirrored : 1; Eina_Bool translate : 1; }; +struct _Elm_Config_Bindings_Widget +{ + const char *name; + Eina_List *key_bindings; +}; + +struct _Elm_Config_Binding_Key +{ + int context; + const char *modifiers; + const char *key; + const char *action; + const char *params; + unsigned char any_mod; +}; + struct _Elm_Module { int version; @@ -421,6 +440,10 @@ void _elm_config_color_overlay_apply(void); Eina_Bool _elm_config_access_get(void); void _elm_config_access_set(Eina_Bool is_access); +Eina_Bool _elm_config_key_binding_call(Evas_Object *obj, + const Evas_Event_Key_Down *ev, + const Elm_Action *actions); + Elm_Font_Properties *_elm_font_properties_get(Eina_Hash **font_hash, const char *font); Eina_Hash *_elm_font_available_hash_add(Eina_Hash *font_hash, diff --git a/src/lib/elm_widget.h b/src/lib/elm_widget.h index 1377179..a205ed9 100644 --- a/src/lib/elm_widget.h +++ b/src/lib/elm_widget.h @@ -456,6 +456,8 @@ typedef struct _Elm_Access_Info Elm_Access_Info; /**< accessibility info item */ typedef struct _Elm_Access_Item Elm_Access_Item; +typedef struct _Elm_Action Elm_Action; + typedef void (*Elm_Widget_Text_Set_Cb)(void *data, const char *part, const char *text); typedef void (*Elm_Widget_Content_Set_Cb)(void *data, const char *part, Evas_Object *content); typedef const char *(*Elm_Widget_Text_Get_Cb)(const void *data, const char *part); @@ -503,6 +505,12 @@ struct _Elm_Access_Info Evas_Object *prev; }; +struct _Elm_Action +{ + const char *name; + void (*func)(Evas_Object *obj, const char *params); +}; + void _elm_access_shutdown(); void _elm_access_mouse_event_enabled_set(Eina_Bool enabled); -- 2.7.4