From ba4e1c944ef3298d400498a9b328a08812874c7c Mon Sep 17 00:00:00 2001 From: Tiago Rezende Campos Falcao Date: Tue, 21 Sep 2010 02:02:24 +0000 Subject: [PATCH] Elementary event propagation to widget parents The Elm Widgets aren't disposed exactly as trees of Evas Objects, so need store widget parents separated from Evas Smart Object parents. The Evas propagation events don't satisfy all use cases. Like managing events in elm_win or try if one parent manage the event before manage it. In this, I add hook to each widget manage their interested events or from their child. SVN revision: 52527 --- legacy/elementary/src/lib/elm_widget.c | 76 ++++++++++++++++++++++++++ legacy/elementary/src/lib/elm_widget.h | 2 + 2 files changed, 78 insertions(+) diff --git a/legacy/elementary/src/lib/elm_widget.c b/legacy/elementary/src/lib/elm_widget.c index 37aa6dcba4..d406f4cea8 100644 --- a/legacy/elementary/src/lib/elm_widget.c +++ b/legacy/elementary/src/lib/elm_widget.c @@ -28,6 +28,7 @@ struct _Smart_Data void (*activate_func) (Evas_Object *obj); void (*disable_func) (Evas_Object *obj); void (*theme_func) (Evas_Object *obj); + Eina_Bool (*event_func) (Evas_Object *obj, Evas_Object *source, Evas_Callback_Type type, void *event_info); void (*signal_func) (Evas_Object *obj, const char *emission, const char *source); void (*callback_add_func) (Evas_Object *obj, const char *emission, @@ -155,6 +156,40 @@ _propagate_y_drag_lock(Evas_Object *obj, int dir) } } +static void +_propagate_event(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info) +{ + INTERNAL_ENTRY; + Evas_Callback_Type type = (Evas_Callback_Type)(long) data; + Evas_Event_Flags *event_flags = NULL; + + switch (type) + { + case EVAS_CALLBACK_KEY_DOWN: + { + Evas_Event_Key_Down *ev = event_info; + event_flags = &(ev->event_flags); + break; + } + case EVAS_CALLBACK_KEY_UP: + { + Evas_Event_Key_Up *ev = event_info; + event_flags = &(ev->event_flags); + break; + } + default: + break; + } + + if (event_flags && (*event_flags & EVAS_EVENT_FLAG_ON_HOLD)) + return; + + if (sd->event_func && sd->event_func(obj, obj, type, event_info)) + return; + + elm_widget_parent_event_propagate(obj, type, event_info); +} + static void _parent_focus(Evas_Object *obj) { @@ -250,6 +285,13 @@ elm_widget_theme_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj)) sd->theme_func = func; } +EAPI void +elm_widget_event_hook_set(Evas_Object *obj, Eina_Bool (*func) (Evas_Object *obj, Evas_Object *source, Evas_Callback_Type type, void *event_info)) +{ + API_ENTRY return; + sd->event_func = func; +} + EAPI void elm_widget_changed_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj)) { @@ -458,6 +500,22 @@ elm_widget_can_focus_set(Evas_Object *obj, int can_focus) { API_ENTRY return; sd->can_focus = can_focus; + if (can_focus) + { + evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN, + _propagate_event, + (void *)(long) EVAS_CALLBACK_KEY_DOWN); + evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_UP, + _propagate_event, + (void *)(long) EVAS_CALLBACK_KEY_UP); + } + else + { + evas_object_event_callback_del(obj, EVAS_CALLBACK_KEY_DOWN, + _propagate_event); + evas_object_event_callback_del(obj, EVAS_CALLBACK_KEY_UP, + _propagate_event); + } } EAPI int @@ -565,6 +623,24 @@ elm_widget_parent_widget_get(const Evas_Object *obj) return parent; } +EAPI Eina_Bool +elm_widget_parent_event_propagate(Evas_Object *obj, Evas_Callback_Type type, void *event_info) +{ + API_ENTRY return EINA_FALSE; + Evas_Object *parent = sd->parent_obj; + while (parent) + { + sd = evas_object_smart_data_get(parent); + if ((!sd) || (!_elm_widget_is(obj))) + return EINA_FALSE; //Not Elm Widget + if (sd->event_func && sd->event_func(parent, obj, type, event_info)) + return EINA_TRUE; + parent = sd->parent_obj; + } + + return EINA_FALSE; +} + EAPI int elm_widget_focus_jump(Evas_Object *obj, int forward) { diff --git a/legacy/elementary/src/lib/elm_widget.h b/legacy/elementary/src/lib/elm_widget.h index fe5236a8fe..de191262e3 100644 --- a/legacy/elementary/src/lib/elm_widget.h +++ b/legacy/elementary/src/lib/elm_widget.h @@ -213,6 +213,7 @@ EAPI void elm_widget_focus_hook_set(Evas_Object *obj, void (*func) ( EAPI void elm_widget_activate_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj)); EAPI void elm_widget_disable_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj)); EAPI void elm_widget_theme_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj)); +EAPI void elm_widget_event_hook_set(Evas_Object *obj, Eina_Bool (*func) (Evas_Object *obj, Evas_Object *source, Evas_Callback_Type type, void *event_info)); EAPI void elm_widget_changed_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj)); EAPI void elm_widget_signal_emit_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj, const char *emission, const char *source)); EAPI void elm_widget_signal_callback_add_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source), void *data)); @@ -239,6 +240,7 @@ EAPI Evas_Object *elm_widget_focused_object_get(const Evas_Object *obj); EAPI Evas_Object *elm_widget_top_get(const Evas_Object *obj); EAPI Eina_Bool elm_widget_is(const Evas_Object *obj); EAPI Evas_Object *elm_widget_parent_widget_get(const Evas_Object *obj); +EAPI Eina_Bool elm_widget_parent_event_propagate(Evas_Object *obj, Evas_Callback_Type type, void *event_info); EAPI int elm_widget_focus_jump(Evas_Object *obj, int forward); EAPI void elm_widget_focus_set(Evas_Object *obj, int first); EAPI void elm_widget_focused_object_clear(Evas_Object *obj);