Clutter 中处理事件的函数调用过程是:
void _clutter_process_event (ClutterEvent*event)--à
staticvoid _clutter_process_event_details (ClutterActor *stage, ClutterMainContext *context, ClutterEvent *event)-à
staticinline void emit_keyboard_event (ClutterEvent *event)-à
gbooleanclutter_actor_event (ClutterActor *actor, ClutterEvent *event, gboolean capture)-à
g_signal_emit(actor, actor_signals[signal_num], 0, event, &retval);
Clutter能收到的输入事件包括指针事件和键盘事件:
1, 对于actor接收指针事件,必须用clutter_actor_set_reactive()
将其设置为active状态,stage始终处于active状态,当有重叠actor层时,事件可以穿透非active actor层;
2, 事件是由g_singal_connect()连接处理的;
3, 如果处理后的事件返回为TRUE,则终止事件信号链,否则将会继续传递事件信号;
4, 对于键盘事件,须用clutter_stage_set_key_focus()
或clutter_actor_grab_key_focus()
将actor设置为focus状态;
5, 对于motion events(motion, enter,leave),须在clutter_set_motion_events_ enabled()
返回为TRUE时方能发出;
6, 一个事件的发射有两个阶段:capture 和 bubble。一个发射事件从stage开始,穿过每一层到达事件信号的源actor(参考clutterActor::captured-event),接着进入bubble阶段,从源actor开始,逐层传递给父actor,直到stage。任何一层处理后如果返回TRUE,则中止事件传递。
Clutter event flow chat:
图中每一个“?”位置都可以是应用程序的事件入口点,在每一个入口处理事件后,返回TRUE则直接进入End EventProcessing。
信号传递示例:
Capture 阶段:事件信号由stage传给group,再由group传给actor;
Bubble阶段:事件信号由actor传给group, 然后再传递给stage。
Example:
static gboolean
_pointer_key_actor_after(ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
g_debug("key-press-actor_after");
returnFALSE; ------------àTRUE
}
static gboolean
_pointer_key_stage_after(ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
g_debug("key-press-stage_after");
return TRUE;
}
#include <clutter/clutter.h>
…………
ClutterActor *stage;
ClutterActor*rectangle;
…………
clutter_actor_set_reactive(rectangle, TRUE);
clutter_actor_grab_key_focus(rectangle);
//g_signal_connect(rectangle, "button-press-event",G_CALLBACK(_pointer_key_actor_after),NULL);
//g_signal_connect(stage, "button-press-event",G_CALLBACK(_pointer_key_stage_after),NULL);
g_signal_connect (rectangle, "event",G_CALLBACK(_pointer_key_actor_after),NULL);
g_signal_connect (stage, "event",G_CALLBACK(_pointer_key_stage_after),NULL);
//g_signal_connect(rectangle, "captured-event",G_CALLBACK(_pointer_key_actor_after),NULL);
//g_signal_connect(stage, "captured-event",G_CALLBACK (_pointer_key_stage_after),NULL);
//g_signal_connect(rectangle, "key-press-event",G_CALLBACK(_pointer_key_actor_after),NULL);
//g_signal_connect(stage, "key-press-event",G_CALLBACK(_pointer_key_stage_after),NULL);
…………
对于指针事件,只要将Actor设置成reactive,均可接收相关事件信号:"button-press-event"、"button-release-event"、"enter-event"、"motion-event"、"leave-event"、"scroll-event"等;
对于键盘事件,首先要将对象actor设置成focus状态,相关的事件信号有: "key-press-event"、"key-release-event"等。
"event"、"captured-event"可接收所有的信号:
“event” signal:这个信号在每一个经过的actor上都接收,根据信号链,直到stage中止,在任一阶段的处理函数中,如果返回为TRUE,则信号中止发射, 如上例中的_pointer_key_actor_after ()回调函数,返回的是FALSE,则处理后事件信号仍继续传递,若改为return TRUE,则处理完这个回调函数后就停止了;
“captured-event”signal:这个信号是从顶层(stage)向下传递,直到传递到事件的源actor,即设置为focus的actor,由于这个信号是有capture阶段发生的,所以可以中断”event” 和“button-press-event”、“key-press-event”等发生在bubble阶段的事件,
上例中,运行后输出结果为:
key-press-actor_after
key-press-stage_after
若将_pointer_key_actor_after ()函数的返回值改为return TRUE,则输出结果为:
key-press-actor_after
可以看出,当actor 接收到信号后,处理函数返回TRUE,就此中止,信号不再传递。
与事件相关的几个处理函数:
static inline void emit_event (ClutterEvent*event, gboolean is_key_event)
static inline void emit_pointer_event(ClutterEvent *event,
ClutterInputDevice *device)
static inline void emit_keyboard_event(ClutterEvent *event)