From eda1f13b33abf797eccbd64a3e664dd7cee9d65c Mon Sep 17 00:00:00 2001 From: Gustavo Sverzut Barbieri Date: Tue, 24 Jul 2007 14:20:07 +0000 Subject: [PATCH] Support for selectable pointer_mode. Evas now support objects that do not grab mouse down event (NOGRAB) aside with the default (AUTOGRAB). API is meant to be extensible. SVN revision: 30950 --- legacy/edje/src/bin/edje_cc_handlers.c | 19 +++++++ legacy/edje/src/lib/edje_data.c | 1 + legacy/edje/src/lib/edje_load.c | 10 +++- legacy/edje/src/lib/edje_private.h | 1 + legacy/edje/src/lib/edje_util.c | 2 + legacy/evas/src/lib/Evas.h | 9 +++ legacy/evas/src/lib/canvas/evas_callbacks.c | 14 +++-- legacy/evas/src/lib/canvas/evas_events.c | 62 +++++++++++++++++++-- legacy/evas/src/lib/include/evas_private.h | 2 + 9 files changed, 107 insertions(+), 13 deletions(-) diff --git a/legacy/edje/src/bin/edje_cc_handlers.c b/legacy/edje/src/bin/edje_cc_handlers.c index d80f8b5da5..0867233fae 100644 --- a/legacy/edje/src/bin/edje_cc_handlers.c +++ b/legacy/edje/src/bin/edje_cc_handlers.c @@ -43,6 +43,7 @@ static void st_collections_group_parts_part_type(void); static void st_collections_group_parts_part_effect(void); static void st_collections_group_parts_part_mouse_events(void); static void st_collections_group_parts_part_repeat_events(void); +static void st_collections_group_parts_part_pointer_mode(void); static void st_collections_group_parts_part_precise_is_inside(void); static void st_collections_group_parts_part_use_alternate_font_metrics(void); static void st_collections_group_parts_part_clip_to_id(void); @@ -180,6 +181,7 @@ New_Statement_Handler statement_handlers[] = {"collections.group.parts.part.effect", st_collections_group_parts_part_effect}, {"collections.group.parts.part.mouse_events", st_collections_group_parts_part_mouse_events}, {"collections.group.parts.part.repeat_events", st_collections_group_parts_part_repeat_events}, + {"collections.group.parts.part.pointer_mode", st_collections_group_parts_part_pointer_mode}, {"collections.group.parts.part.precise_is_inside", st_collections_group_parts_part_precise_is_inside}, {"collections.group.parts.part.use_alternate_font_metrics", st_collections_group_parts_part_use_alternate_font_metrics}, {"collections.group.parts.part.clip_to", st_collections_group_parts_part_clip_to_id}, @@ -901,6 +903,7 @@ ob_collections_group_parts_part(void) ep->type = EDJE_PART_TYPE_IMAGE; ep->mouse_events = 1; ep->repeat_events = 0; + ep->pointer_mode = EVAS_OBJECT_POINTER_MODE_AUTOGRAB; ep->precise_is_inside = 0; ep->use_alternate_font_metrics = 0; ep->clip_to_id = -1; @@ -986,6 +989,22 @@ st_collections_group_parts_part_repeat_events(void) ep->repeat_events = parse_bool(0); } +static void +st_collections_group_parts_part_pointer_mode(void) +{ + Edje_Part_Collection *pc; + Edje_Part *ep; + + check_arg_count(1); + + pc = evas_list_data(evas_list_last(edje_collections)); + ep = evas_list_data(evas_list_last(pc->parts)); + ep->pointer_mode = parse_enum(0, + "AUTOGRAB", EVAS_OBJECT_POINTER_MODE_AUTOGRAB, + "NOGRAB", EVAS_OBJECT_POINTER_MODE_NOGRAB, + NULL); +} + static void st_collections_group_parts_part_precise_is_inside(void) { diff --git a/legacy/edje/src/lib/edje_data.c b/legacy/edje/src/lib/edje_data.c index 556839ca9c..ff8b7ab4c9 100644 --- a/legacy/edje/src/lib/edje_data.c +++ b/legacy/edje/src/lib/edje_data.c @@ -345,6 +345,7 @@ _edje_edd_setup(void) EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "effect", effect, EET_T_CHAR); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "mouse_events", mouse_events, EET_T_CHAR); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "repeat_events", repeat_events, EET_T_CHAR); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "pointer_mode", pointer_mode, EET_T_CHAR); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "precise_is_inside", precise_is_inside, EET_T_CHAR); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "clip_to_id", clip_to_id, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "use_alternate_font_metrics", use_alternate_font_metrics, EET_T_UCHAR); diff --git a/legacy/edje/src/lib/edje_load.c b/legacy/edje/src/lib/edje_load.c index 53c9e3414f..779db512cb 100644 --- a/legacy/edje/src/lib/edje_load.c +++ b/legacy/edje/src/lib/edje_load.c @@ -303,6 +303,7 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *p rp->object = evas_object_rectangle_add(ed->evas); evas_object_color_set(rp->object, 0, 0, 0, 0); evas_object_pass_events_set(rp->object, 1); + evas_object_pointer_mode_set(rp->object, EVAS_OBJECT_POINTER_MODE_NOGRAB); } else if (ep->type == EDJE_PART_TYPE_TEXTBLOCK) rp->object = evas_object_textblock_add(ed->evas); @@ -323,9 +324,15 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *p _edje_callbacks_add(rp->object, ed, rp); if (ep->repeat_events) evas_object_repeat_events_set(rp->object, 1); + + if (ep->pointer_mode != EVAS_OBJECT_POINTER_MODE_AUTOGRAB) + evas_object_pointer_mode_set(rp->object, ep->pointer_mode); } else - evas_object_pass_events_set(rp->object, 1); + { + evas_object_pass_events_set(rp->object, 1); + evas_object_pointer_mode_set(rp->object, EVAS_OBJECT_POINTER_MODE_NOGRAB); + } if (ep->precise_is_inside) evas_object_precise_is_inside_set(rp->object, 1); } @@ -368,6 +375,7 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *p if (rp->clip_to) { evas_object_pass_events_set(rp->clip_to->object, 1); + evas_object_pointer_mode_set(rp->clip_to->object, EVAS_OBJECT_POINTER_MODE_NOGRAB); evas_object_clip_set(rp->object, rp->clip_to->object); } } diff --git a/legacy/edje/src/lib/edje_private.h b/legacy/edje/src/lib/edje_private.h index 19966faf65..1913cba755 100644 --- a/legacy/edje/src/lib/edje_private.h +++ b/legacy/edje/src/lib/edje_private.h @@ -429,6 +429,7 @@ struct _Edje_Part unsigned char repeat_events; /* it will repeat events to objects below */ unsigned char precise_is_inside; unsigned char use_alternate_font_metrics; + Evas_Object_Pointer_Mode pointer_mode; }; struct _Edje_Part_Image_Id diff --git a/legacy/edje/src/lib/edje_util.c b/legacy/edje/src/lib/edje_util.c index b7984e67a4..1c45c9874b 100644 --- a/legacy/edje/src/lib/edje_util.c +++ b/legacy/edje/src/lib/edje_util.c @@ -2117,6 +2117,8 @@ _edje_real_part_swallow(Edje_Real_Part *rp, Evas_Object *obj_swallow) _edje_callbacks_add(obj_swallow, rp->edje, rp); if (rp->part->repeat_events) evas_object_repeat_events_set(obj_swallow, 1); + if (rp->part->pointer_mode != EVAS_OBJECT_POINTER_MODE_AUTOGRAB) + evas_object_pointer_mode_set(obj_swallow, rp->part->pointer_mode); } else evas_object_pass_events_set(obj_swallow, 1); diff --git a/legacy/evas/src/lib/Evas.h b/legacy/evas/src/lib/Evas.h index 28e5bd6279..7d63aa1572 100644 --- a/legacy/evas/src/lib/Evas.h +++ b/legacy/evas/src/lib/Evas.h @@ -330,6 +330,12 @@ struct _Evas_Event_Key_Up /** Key release event */ unsigned int timestamp; }; +typedef enum _Evas_Object_Pointer_Mode +{ + EVAS_OBJECT_POINTER_MODE_AUTOGRAB, /**< default, X11-like */ + EVAS_OBJECT_POINTER_MODE_NOGRAB +} Evas_Object_Pointer_Mode; + #ifdef __cplusplus extern "C" { #endif @@ -767,6 +773,9 @@ extern "C" { EAPI Evas_Bool evas_object_repeat_events_get (Evas_Object *obj); EAPI void evas_object_propagate_events_set (Evas_Object *obj, Evas_Bool prop); EAPI Evas_Bool evas_object_propagate_events_get (Evas_Object *obj); + EAPI void evas_object_pointer_mode_set (Evas_Object *obj, Evas_Object_Pointer_Mode setting); + EAPI Evas_Object_Pointer_Mode evas_object_pointer_mode_get(Evas_Object *obj); + EAPI void evas_object_precise_is_inside_set (Evas_Object *obj, Evas_Bool precise); EAPI Evas_Bool evas_object_precise_is_inside_get (Evas_Object *obj); diff --git a/legacy/evas/src/lib/canvas/evas_callbacks.c b/legacy/evas/src/lib/canvas/evas_callbacks.c index 50945d86ac..7fc7a570cc 100644 --- a/legacy/evas/src/lib/canvas/evas_callbacks.c +++ b/legacy/evas/src/lib/canvas/evas_callbacks.c @@ -218,12 +218,14 @@ evas_object_event_callback_call(Evas_Object *obj, Evas_Callback_Type type, void * EVAS_CALLBACK_MOUSE_DOWN: event_info = pointer to Evas_Event_Mouse_Down * * This event is triggered by a mouse button being depressed while over an - * object. This causes this object to passively grab the mouse until all mouse - * buttons have been released. That means if this mouse button is the first to - * be pressed, all future mouse events will be reported to only this object - * until no buttons are down. That includes mouse move events, in and out - * events, and further button presses. When all buttons are released, event - * propagation occurs as normal. + * object. If pointermode is EVAS_OBJECT_POINTER_MODE_AUTOGRAB (default) + * this causes this object to passively grab the mouse until all mouse + * buttons have been released. + * That means if this mouse button is the first to be pressed, all future + * mouse events will be reported to only this object until no buttons are + * down. That includes mouse move events, in and out events, and further + * button presses. When all buttons are released, event propagation occurs + * as normal. * * EVAS_CALLBACK_MOUSE_UP: event_info = pointer to Evas_Event_Mouse_Up * diff --git a/legacy/evas/src/lib/canvas/evas_events.c b/legacy/evas/src/lib/canvas/evas_events.c index 3ce9c2391e..af853e21df 100644 --- a/legacy/evas/src/lib/canvas/evas_events.c +++ b/legacy/evas/src/lib/canvas/evas_events.c @@ -245,8 +245,11 @@ evas_event_feed_mouse_down(Evas *e, int b, Evas_Button_Flags flags, unsigned int Evas_Event_Mouse_Down ev; obj = l->data; - obj->mouse_grabbed++; - e->pointer.mouse_grabbed++; + if (obj->pointer_mode != EVAS_OBJECT_POINTER_MODE_NOGRAB) + { + obj->mouse_grabbed++; + e->pointer.mouse_grabbed++; + } ev.button = b; ev.output.x = e->pointer.x; @@ -299,10 +302,12 @@ evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags, unsigned int t Evas_Event_Mouse_Up ev; obj = l->data; -// if (obj->mouse_grabbed > 0) - obj->mouse_grabbed--; -// if (e->pointer.mouse_grabbed > 0) - e->pointer.mouse_grabbed--; + if ((obj->pointer_mode != EVAS_OBJECT_POINTER_MODE_NOGRAB) && + (obj->mouse_in) && (obj->mouse_grabbed > 0)) + { + obj->mouse_grabbed--; + e->pointer.mouse_grabbed--; + } ev.button = b; ev.output.x = e->pointer.x; ev.output.y = e->pointer.y; @@ -399,6 +404,11 @@ evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags, unsigned int t if (e->pointer.inside) evas_event_feed_mouse_move(e, e->pointer.x, e->pointer.y, timestamp, data); } + + if (e->pointer.mouse_grabbed < 0) + fprintf(stderr, "BUG? e->pointer.mouse_grabbed (=%d) < 0!\n", + e->pointer.mouse_grabbed); + if ((e->pointer.button == 0) && (e->pointer.mouse_grabbed)) { e->pointer.mouse_grabbed = 0; @@ -1114,3 +1124,43 @@ evas_object_propagate_events_get(Evas_Object *obj) MAGIC_CHECK_END(); return !(obj->no_propagate); } + +/** + * Set pointer behavior. + * + * @param obj + * @param setting desired behavior. + * + * This function has direct effect on event callbacks related to mouse. + * + * If @p setting is EVAS_OBJECT_POINTER_MODE_AUTOGRAB, then when mouse is + * down at this object, events will be restricted to it as source, mouse + * moves, for example, will be emitted even if outside this object area. + * + * If @p setting is EVAS_OBJECT_POINTER_MODE_NOGRAB, then events will be + * emitted just when inside this object area. + * + * The default value is EVAS_OBJECT_POINTER_MODE_AUTOGRAB. + */ +EAPI void +evas_object_pointer_mode_set(Evas_Object *obj, Evas_Object_Pointer_Mode setting) +{ + MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); + return; + MAGIC_CHECK_END(); + obj->pointer_mode = setting; +} + +/** + * Determine how pointer will behave. + * @param obj + * @return pointer behavior. + */ +EAPI Evas_Object_Pointer_Mode +evas_object_pointer_mode_get(Evas_Object *obj) +{ + MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); + return 0; + MAGIC_CHECK_END(); + return obj->pointer_mode; +} diff --git a/legacy/evas/src/lib/include/evas_private.h b/legacy/evas/src/lib/include/evas_private.h index 08cf9fafae..158ab948c8 100644 --- a/legacy/evas/src/lib/include/evas_private.h +++ b/legacy/evas/src/lib/include/evas_private.h @@ -450,6 +450,8 @@ struct _Evas_Object unsigned short precise_is_inside : 1; + Evas_Object_Pointer_Mode pointer_mode; + unsigned char delete_me; };