diff options
author | Marcel Hollerbach <marcel-hollerbach@t-online.de> | 2015-12-18 16:39:36 +0100 |
---|---|---|
committer | Marcel Hollerbach <marcel-hollerbach@t-online.de> | 2015-12-18 16:44:56 +0100 |
commit | affee1ec099bc61b45b0073717d8cd930cb32891 (patch) | |
tree | ef3e09e7afe1e6536b108c940e51dd41855e5ee0 | |
parent | f129e78b203436aebd9858d62734cc2d0d9e8134 (diff) | |
download | elementary-devs/bu5hm4n/key_bindings.tar.gz |
elm: Add new key bindings infrastucturedevs/bu5hm4n/key_bindings
With the 2 new calls widgets can add keybindings.
The config now supports to convert the given config key bindngs struct
to a new generel key binding struct.
With this infra the keybindings are not depending anymore on the
elm_widget_type_get string.
ref T2891
-rw-r--r-- | src/lib/elm_config.c | 70 | ||||
-rw-r--r-- | src/lib/elm_general.eot | 17 | ||||
-rw-r--r-- | src/lib/elm_priv.h | 3 | ||||
-rw-r--r-- | src/lib/elm_widget.c | 65 | ||||
-rw-r--r-- | src/lib/elm_widget.eo | 20 |
5 files changed, 174 insertions, 1 deletions
diff --git a/src/lib/elm_config.c b/src/lib/elm_config.c index 29ef12de6..2c403a210 100644 --- a/src/lib/elm_config.c +++ b/src/lib/elm_config.c @@ -2174,6 +2174,76 @@ _elm_config_modifier_check(const Evas_Modifier *m, return EINA_TRUE; } +static Eina_List* +_mods_copy(Eina_List *mods) +{ + Eina_List *l, *result = NULL; + Elm_Config_Binding_Modifier *mod; + + EINA_LIST_FOREACH(mods, l, mod) { + Elm_Key_Binding_Modifier *result_mod; + + result_mod = calloc(1, sizeof(Elm_Key_Binding_Modifier)); + + result_mod->mod = mod->mod; + result_mod->flag = mod->flag; + + result = eina_list_append(result, result_mod); + } + return result; +} + +static void +_mods_free(Eina_List *lst) +{ + Elm_Key_Binding_Modifier *result_mod; + + EINA_LIST_FREE(lst, result_mod) + free(result_mod); + +} + +Eina_List* +_elm_config_config_to_key_bindings(const char *name) +{ + Elm_Config_Binding_Key *binding; + Eina_List *binding_list, *l, *result = NULL; + + binding_list = eina_hash_find(_elm_key_bindings, name); + + if (!binding_list) return NULL; + + EINA_LIST_FOREACH(binding_list, l, binding) + { + Elm_Key_Binding *key; + + key = calloc(1, sizeof(Elm_Key_Binding)); + key->key = eina_stringshare_ref(binding->key); + key->action = eina_stringshare_ref(binding->action); + key->params = eina_stringshare_ref(binding->params); + key->mods = _mods_copy(binding->modifiers); + printf("%s %s %s\n", key->params, key->action, key->key); + result = eina_list_append(result, key); + } + + return result; +} + +void +_elm_config_key_bindings_free(Eina_List *bindings) +{ + Elm_Key_Binding *key; + + EINA_LIST_FREE(bindings, key) + { + eina_stringshare_del(key->key); + eina_stringshare_del(key->action); + eina_stringshare_del(key->params); + _mods_free(key->mods); + free(key); + } +} + Eina_Bool _elm_config_key_binding_call(Evas_Object *obj, const Evas_Event_Key_Down *ev, diff --git a/src/lib/elm_general.eot b/src/lib/elm_general.eot index 6388b30fc..936f790de 100644 --- a/src/lib/elm_general.eot +++ b/src/lib/elm_general.eot @@ -119,3 +119,20 @@ enum Elm.Focus_Direction left, [[ left direction ]] } +struct Elm.Key_Binding +{ + [[Hold information about a key binding. + If the given key is pressed with the given mods, + the action will be executed with the given params. + ]] + key : const(char)*; + action : const(char)*; + params : const(char)*; + mods : list<Elm.Key_Binding_Modifier*>*; +} + +struct Elm.Key_Binding_Modifier +{ + mod : const(char)*; + flag : ubyte; +}
\ No newline at end of file diff --git a/src/lib/elm_priv.h b/src/lib/elm_priv.h index be92f1513..aab9c4f96 100644 --- a/src/lib/elm_priv.h +++ b/src/lib/elm_priv.h @@ -459,6 +459,9 @@ void _elm_config_color_overlay_apply(void); Eina_Bool _elm_config_access_get(void); void _elm_config_access_set(Eina_Bool is_access); +Eina_List* _elm_config_config_to_key_bindings(const char *name); +void _elm_config_key_bindings_free(Eina_List *bindings); + Eina_Bool _elm_config_key_binding_call(Evas_Object *obj, const Evas_Event_Key_Down *ev, const Elm_Action *actions); diff --git a/src/lib/elm_widget.c b/src/lib/elm_widget.c index c850e4656..1eb3a3d7f 100644 --- a/src/lib/elm_widget.c +++ b/src/lib/elm_widget.c @@ -5724,6 +5724,12 @@ elm_widget_tree_dot_dump(const Evas_Object *top, #endif } +EOLIAN static Eina_List * +_elm_widget_key_bindings_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd EINA_UNUSED) { + return NULL; +} + + EOLIAN static Eo * _elm_widget_eo_base_constructor(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED) { @@ -5794,9 +5800,66 @@ _elm_widget_disable(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED) return EINA_FALSE; } +static Eina_Bool +_modifier_check(const Evas_Modifier *m, + Eina_List *mod_list) +{ + Eina_List *l; + Elm_Key_Binding_Modifier *mod; + EINA_LIST_FOREACH(mod_list, l, mod) + { + if ((evas_key_modifier_is_set(m, mod->mod)) ^ (mod->flag)) + return EINA_FALSE; + } + return EINA_TRUE; +} + +Eina_Bool +_elm_widget_key_binding_callback(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd EINA_UNUSED, const char *action EINA_UNUSED, const char *params EINA_UNUSED) +{ + return EINA_FALSE; +} + +static Eina_Bool +_key_bindings_execute(Evas_Object *obj, Evas_Event_Key_Down *ev) +{ + Elm_Key_Binding *binding; + Eina_List *node, *key_bindings; + + eo_do(obj, key_bindings = elm_obj_widget_key_bindings_get()); + + EINA_LIST_FOREACH(key_bindings, node, binding) + { + printf("binding %p %p\n",binding, binding->mods); + if (binding->key && (!strcmp(binding->key, ev->key)) && + _modifier_check(ev->modifiers, binding->mods)) + { + Eina_Bool ret; + eo_do_ret(obj, ret, elm_obj_widget_key_binding_callback(binding->action, binding->params)); + if (ret) return EINA_TRUE; + } + } + + return EINA_FALSE; +} + EOLIAN static Eina_Bool -_elm_widget_event(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Evas_Object *source EINA_UNUSED, Evas_Callback_Type type EINA_UNUSED, void *event_info EINA_UNUSED) +_elm_widget_event(Eo *obj, Elm_Widget_Smart_Data *_pd, Evas_Object *source EINA_UNUSED, Evas_Callback_Type type EINA_UNUSED, void *event_info EINA_UNUSED) { + //check if there are key bindings for this widget + if (_pd->disabled) return EINA_FALSE; + + Evas_Event_Key_Down *ev = event_info; + if ((type == EVAS_CALLBACK_KEY_DOWN) && + !(ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)) + { + if (_key_bindings_execute(obj, event_info)) + { + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + return EINA_TRUE; + } + } + return EINA_FALSE; } diff --git a/src/lib/elm_widget.eo b/src/lib/elm_widget.eo index 35bed55f1..e88444734 100644 --- a/src/lib/elm_widget.eo +++ b/src/lib/elm_widget.eo @@ -556,6 +556,26 @@ abstract Elm.Widget (Evas.Object_Smart, Elm_Interface_Atspi_Accessible, Elm_Inte @in event_flags: Evas_Event_Flags *; } } + @property key_bindings { + [[Returns a list of keybindings. + The list is used to resolve a keyboard event to actions and paramters. + key_binding_callback will be called later. + ]] + get { + + } + values { + key_bindings : list<Elm.Key_Binding*>*; + } + } + key_binding_callback { + [[Called when a key binding action is executed]] + params { + action : const(char)*; [[Name of the action which is executed]] + params : const(char)*; [[The params which where passed to the key press]] + } + return : bool; + } signal_callback_add { params { @in emission: const(char)*; |