From e228c20998c722fa6c0a0e2fd8b6782a4336d6de Mon Sep 17 00:00:00 2001 From: hermet Date: Thu, 27 Oct 2011 10:36:09 +0000 Subject: [PATCH] evas - added new API evas_object_freeze_events_set/get and will handle for the key events also soon. git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@64432 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/lib/Evas.h | 60 +++++++++++++++++++++++++++++++------- src/lib/canvas/evas_events.c | 46 +++++++++++++++++++++++++---- src/lib/canvas/evas_object_smart.c | 19 ++++++++---- src/lib/include/evas_inline.x | 16 ++++++++++ src/lib/include/evas_private.h | 7 +++-- 5 files changed, 125 insertions(+), 23 deletions(-) diff --git a/src/lib/Evas.h b/src/lib/Evas.h index 1e992d7..332f170 100644 --- a/src/lib/Evas.h +++ b/src/lib/Evas.h @@ -3922,6 +3922,7 @@ EAPI void *evas_object_event_callback_del_full(Evas_Object *obj, Eva * @see evas_object_pass_events_get() for an example * @see evas_object_repeat_events_set() * @see evas_object_propagate_events_set() + * @see evas_object_freeze_events_set() */ EAPI void evas_object_pass_events_set (Evas_Object *obj, Eina_Bool pass) EINA_ARG_NONNULL(1); @@ -3942,6 +3943,7 @@ EAPI void evas_object_pass_events_set (Evas_Object *obj, Ein * @see evas_object_pass_events_set() * @see evas_object_repeat_events_get() * @see evas_object_propagate_events_get() + * @see evas_object_freeze_events_get() */ EAPI Eina_Bool evas_object_pass_events_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_PURE; @@ -3967,8 +3969,9 @@ EAPI Eina_Bool evas_object_pass_events_get (const Evas_Object *ob * See the full @ref Example_Evas_Stacking "example". * * @see evas_object_repeat_events_get() - * @see evas_object_pass_events_get() - * @see evas_object_propagate_events_get() + * @see evas_object_pass_events_set() + * @see evas_object_propagate_events_set() + * @see evas_object_freeze_events_set() */ EAPI void evas_object_repeat_events_set (Evas_Object *obj, Eina_Bool repeat) EINA_ARG_NONNULL(1); @@ -3980,8 +3983,9 @@ EAPI void evas_object_repeat_events_set (Evas_Object *obj, Ein * or not (@c EINA_FALSE) * * @see evas_object_repeat_events_set() for an example - * @see evas_object_pass_events_set() - * @see evas_object_propagate_events_set() + * @see evas_object_pass_events_get() + * @see evas_object_propagate_events_get() + * @see evas_object_freeze_events_get() */ EAPI Eina_Bool evas_object_repeat_events_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_PURE; @@ -4002,10 +4006,10 @@ EAPI Eina_Bool evas_object_repeat_events_get (const Evas_Object *ob * not be propagated on to the smart object of which @p obj is a * member. The default value is @c EINA_TRUE. * - * @see evas_object_event_callback_add() * @see evas_object_propagate_events_get() - * @see evas_object_repeat_events_get() - * @see evas_object_pass_events_get() + * @see evas_object_repeat_events_set() + * @see evas_object_pass_events_set() + * @see evas_object_freeze_events_set() */ EAPI void evas_object_propagate_events_set (Evas_Object *obj, Eina_Bool prop) EINA_ARG_NONNULL(1); @@ -4016,14 +4020,50 @@ EAPI void evas_object_propagate_events_set (Evas_Object *obj, Ein * @return whether @p obj is set to propagate events (@c EINA_TRUE) * or not (@c EINA_FALSE) * - * @see evas_object_event_callback_add() * @see evas_object_propagate_events_set() - * @see evas_object_repeat_events_set() - * @see evas_object_pass_events_set() + * @see evas_object_repeat_events_get() + * @see evas_object_pass_events_get() + * @see evas_object_freeze_events_get() */ EAPI Eina_Bool evas_object_propagate_events_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_PURE; /** + * Set whether an Evas object is to freeze (discard) events. + * + * @param obj the Evas object to operate on + * @param pass whether @p obj is to freeze events (@c EINA_TRUE) or not + * (@c EINA_FALSE) + * + * If @p freeze is @c EINA_TRUE, it will make events on @p obj to be @b + * discarded. Unlike evas_object_pass_events_set(), events will not be + * passed to @b next lower object. This API can be used for blocking + * events while @p obj is on transiting. + * + * If @p freeze is @c EINA_FALSE, events will be processed on that + * object as normal. + * + * @see evas_object_freeze_events_get() + * @see evas_object_pass_events_set() + * @see evas_object_repeat_events_set() + * @see evas_object_propagate_events_set() + */ +EAPI void evas_object_freeze_events_set(Evas_Object *obj, Eina_Bool freeze) EINA_ARG_NONNULL(1); + +/** + * Determine whether an object is set to freeze (discard) events. + * + * @param obj the Evas object to get information from. + * @return freeze whether @p obj is set to freeze events (@c EINA_TRUE) or + * not (@c EINA_FALSE) + * + * @see evas_object_freeze_events_set() + * @see evas_object_pass_events_get() + * @see evas_object_repeat_events_get() + * @see evas_object_propagate_events_get() + */ +EAPI Eina_Bool evas_object_freeze_events_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_PURE; + +/** * @} */ diff --git a/src/lib/canvas/evas_events.c b/src/lib/canvas/evas_events.c index fe619da..a8fa6dc 100644 --- a/src/lib/canvas/evas_events.c +++ b/src/lib/canvas/evas_events.c @@ -90,7 +90,8 @@ _evas_event_object_list_in_get(Evas *e, Eina_List *in, if (inside && ((!obj->precise_is_inside) || (evas_object_is_inside(obj, x, y)))) { - in = eina_list_append(in, obj); + if (!evas_event_freezes_through(obj)) + in = eina_list_append(in, obj); if (!obj->repeat_events) { *no_rep = 1; @@ -229,8 +230,10 @@ evas_event_feed_mouse_down(Evas *e, int b, Evas_Button_Flags flags, unsigned int * get a new event list, otherwise, keep the current grabbed list. */ if (e->pointer.mouse_grabbed == 0) { - Eina_List *ins; - ins = evas_event_objects_event_list(e, NULL, e->pointer.x, e->pointer.y); + Eina_List *ins = evas_event_objects_event_list(e, + NULL, + e->pointer.x, + e->pointer.y); /* free our old list of ins */ e->pointer.object.in = eina_list_free(e->pointer.object.in); /* and set up the new one */ @@ -248,7 +251,6 @@ evas_event_feed_mouse_down(Evas *e, int b, Evas_Button_Flags flags, unsigned int EINA_LIST_FOREACH(copy, l, obj) { if (obj->delete_me) continue; - ev.canvas.x = e->pointer.x; ev.canvas.y = e->pointer.y; _evas_event_havemap_adjust(obj, &ev.canvas.x, &ev.canvas.y, obj->mouse_grabbed); @@ -1376,6 +1378,40 @@ evas_event_feed_hold(Evas *e, int hold, unsigned int timestamp, const void *data } EAPI void +evas_object_freeze_events_set(Evas_Object *obj, Eina_Bool freeze) +{ + MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); + return; + MAGIC_CHECK_END(); + + freeze = !!freeze; + if (obj->freeze_events == freeze) return; + obj->freeze_events = freeze; + evas_object_smart_member_cache_invalidate(obj, EINA_FALSE, EINA_TRUE); + if (evas_object_is_in_output_rect(obj, + obj->layer->evas->pointer.x, + obj->layer->evas->pointer.y, 1, 1) && + ((!obj->precise_is_inside) || + (evas_object_is_inside(obj, + obj->layer->evas->pointer.x, + obj->layer->evas->pointer.y)))) + evas_event_feed_mouse_move(obj->layer->evas, + obj->layer->evas->pointer.x, + obj->layer->evas->pointer.y, + obj->layer->evas->last_timestamp, + NULL); +} + +EAPI Eina_Bool +evas_object_freeze_events_get(const Evas_Object *obj) +{ + MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); + return 0; + MAGIC_CHECK_END(); + return obj->freeze_events; +} + +EAPI void evas_object_pass_events_set(Evas_Object *obj, Eina_Bool pass) { MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); @@ -1384,7 +1420,7 @@ evas_object_pass_events_set(Evas_Object *obj, Eina_Bool pass) pass = !!pass; if (obj->pass_events == pass) return; obj->pass_events = pass; - evas_object_smart_member_cache_invalidate(obj); + evas_object_smart_member_cache_invalidate(obj, EINA_TRUE, EINA_FALSE); if (evas_object_is_in_output_rect(obj, obj->layer->evas->pointer.x, obj->layer->evas->pointer.y, 1, 1) && diff --git a/src/lib/canvas/evas_object_smart.c b/src/lib/canvas/evas_object_smart.c index 900c81f..528c0a6 100644 --- a/src/lib/canvas/evas_object_smart.c +++ b/src/lib/canvas/evas_object_smart.c @@ -164,7 +164,7 @@ evas_object_smart_member_add(Evas_Object *obj, Evas_Object *smart_obj) obj->layer->usage++; obj->smart.parent = smart_obj; o->contained = eina_inlist_append(o->contained, EINA_INLIST_GET(obj)); - evas_object_smart_member_cache_invalidate(obj); + evas_object_smart_member_cache_invalidate(obj, EINA_TRUE, EINA_TRUE); obj->restack = 1; evas_object_change(obj); evas_object_mapped_clip_across_mark(obj); @@ -191,7 +191,7 @@ evas_object_smart_member_del(Evas_Object *obj) o = (Evas_Object_Smart *)(obj->smart.parent->object_data); o->contained = eina_inlist_remove(o->contained, EINA_INLIST_GET(obj)); obj->smart.parent = NULL; - evas_object_smart_member_cache_invalidate(obj); + evas_object_smart_member_cache_invalidate(obj, EINA_TRUE, EINA_TRUE); obj->layer->usage--; obj->cur.layer = obj->layer->layer; evas_object_inject(obj, obj->layer->evas); @@ -751,7 +751,9 @@ evas_object_smart_cleanup(Evas_Object *obj) } void -evas_object_smart_member_cache_invalidate(Evas_Object *obj) +evas_object_smart_member_cache_invalidate(Evas_Object *obj, + Eina_Bool pass_events, + Eina_Bool freeze_events) { Evas_Object_Smart *o; Evas_Object *member; @@ -760,13 +762,18 @@ evas_object_smart_member_cache_invalidate(Evas_Object *obj) return; MAGIC_CHECK_END(); - obj->parent_cache.pass_events_valid = EINA_FALSE; + if (pass_events) + obj->parent_cache.pass_events_valid = EINA_FALSE; + if (freeze_events) + obj->parent_cache.freeze_events_valid = EINA_FALSE; o = obj->object_data; if (o->magic != MAGIC_OBJ_SMART) return; - EINA_INLIST_FOREACH(o->contained, member); - evas_object_smart_member_cache_invalidate(member); + EINA_INLIST_FOREACH(o->contained, member) + evas_object_smart_member_cache_invalidate(member, + pass_events, + freeze_events); } void diff --git a/src/lib/include/evas_inline.x b/src/lib/include/evas_inline.x index 874da7c..b41d4d7 100644 --- a/src/lib/include/evas_inline.x +++ b/src/lib/include/evas_inline.x @@ -70,6 +70,22 @@ evas_object_is_opaque(Evas_Object *obj) return 0; } +static inline Eina_Bool +evas_event_freezes_through(Evas_Object *obj) +{ + if (obj->freeze_events) return EINA_TRUE; + if (obj->parent_cache.freeze_events_valid) + return obj->parent_cache.freeze_events; + if (obj->smart.parent) + { + Eina_Bool freeze = evas_event_freezes_through(obj->smart.parent); + obj->parent_cache.freeze_events_valid = EINA_TRUE; + obj->parent_cache.freeze_events = freeze; + return freeze; + } + return EINA_FALSE; +} + static inline int evas_event_passes_through(Evas_Object *obj) { diff --git a/src/lib/include/evas_private.h b/src/lib/include/evas_private.h index e205cdb..3cf2baa 100644 --- a/src/lib/include/evas_private.h +++ b/src/lib/include/evas_private.h @@ -580,11 +580,14 @@ struct _Evas_Object Eina_Bool store : 1; Eina_Bool pass_events : 1; + Eina_Bool freeze_events : 1; + Eina_Bool repeat_events : 1; struct { Eina_Bool pass_events : 1; Eina_Bool pass_events_valid : 1; + Eina_Bool freeze_events : 1; + Eina_Bool freeze_events_valid : 1; } parent_cache; - Eina_Bool repeat_events : 1; Eina_Bool restack : 1; Eina_Bool is_active : 1; Eina_Bool precise_is_inside : 1; @@ -978,7 +981,7 @@ int evas_font_desc_cmp(const Evas_Font_Description *a, const Evas_Font_Descripti Evas_Font_Description *evas_font_desc_ref(Evas_Font_Description *fdesc); void * evas_font_load(Evas *evas, Evas_Font_Description *fdesc, const char *source, Evas_Font_Size size); void evas_font_load_hinting_set(Evas *evas, void *font, int hinting); -void evas_object_smart_member_cache_invalidate(Evas_Object *obj); +void evas_object_smart_member_cache_invalidate(Evas_Object *obj, Eina_Bool pass_events, Eina_Bool freeze_events); void evas_text_style_pad_get(Evas_Text_Style_Type style, int *l, int *r, int *t, int *b); void _evas_object_text_rehint(Evas_Object *obj); void _evas_object_textblock_rehint(Evas_Object *obj); -- 2.7.4