aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Hollerbach <marcel-hollerbach@t-online.de>2015-12-18 16:39:36 +0100
committerMarcel Hollerbach <marcel-hollerbach@t-online.de>2015-12-18 16:44:56 +0100
commitaffee1ec099bc61b45b0073717d8cd930cb32891 (patch)
treeef3e09e7afe1e6536b108c940e51dd41855e5ee0
parentelm_widget: correct declaration of function with no parameters (diff)
downloadelementary-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 https://phab.enlightenment.org/T2891
-rw-r--r--src/lib/elm_config.c70
-rw-r--r--src/lib/elm_general.eot17
-rw-r--r--src/lib/elm_priv.h3
-rw-r--r--src/lib/elm_widget.c65
-rw-r--r--src/lib/elm_widget.eo20
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)*;