Clutter event handle mechanism

 

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)

 

 

你可能感兴趣的:(Clutter event handle mechanism)