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
This commit is contained in:
Gustavo Sverzut Barbieri 2007-07-24 14:20:07 +00:00
parent 35495cc97f
commit eda1f13b33
9 changed files with 107 additions and 13 deletions

View File

@ -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)
{

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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
*

View File

@ -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;
}

View File

@ -450,6 +450,8 @@ struct _Evas_Object
unsigned short precise_is_inside : 1;
Evas_Object_Pointer_Mode pointer_mode;
unsigned char delete_me;
};