!!! マウスイベント * マウスを動かしたり、ボタンを押すと送られる !! マウスイベントの種類 ||-種類-|-発生状況- ||motion_notify_event|マウスが移動した ||button_press_event|マウスボタンが押された ||button_release_event|マウスボタンが離された ||scroll_event|ホイールが回された ||2button_press_event|ダブルクリックされた ||3button_press_event|トリプルクリックされた * 他にもあるかもしれません !! イベントの設定 8< void gtk_widget_set_events (GtkWidget *widget, gint events); >8 * [gtk_widget_set_events|https://developer.gnome.org/gtk2/2.24/GtkWidget.html#gtk-widget-set-events] ** [events|https://developer.gnome.org/gdk2/2.24/gdk2-Events.html#GdkEventMask] ** 入門GTK+ 3版pdf:249(261)ページ 8< #define g_signal_connect(instance, detailed_signal, c_handler, data) >8 * [g_signal_connect|https://developer.gnome.org/gobject/2.34/gobject-Signals.html#g-signal-connect] ** 入門GTK+ 3版pdf:40(52)ページ 8< GdkWindow* gdk_window_get_pointer (GdkWindow *window, gint *x, gint *y, GdkModifierType *mask); >8 * [gdk_window_get_pointer|https://developer.gnome.org/gdk2/2.24/gdk2-Windows.html#gdk-window-get-pointer] ** [GdkModifierType|https://developer.gnome.org/gdk2/2.24/gdk2-Windows.html#GdkModifierType] 8< union GdkEvent >8 * [GdkEvent|https://developer.gnome.org/gdk2/2.24/gdk2-Event-Structures.html#GdkEvent] 8< struct GdkEventMotion >8 * [GdkEventMotion|https://developer.gnome.org/gdk2/2.24/gdk2-Event-Structures.html#GdkEventMotion] 8< struct GdkEventButton >8 * [GdkEventButton|https://developer.gnome.org/gdk2/2.24/gdk2-Event-Structures.html#GdkEventButton] 8< struct GdkEventScroll >8 * [GdkEventScroll|https://developer.gnome.org/gdk2/2.24/gdk2-Event-Structures.html#GdkEventScroll] !!! motion_notify_event * マウスが移動したときに発生 !! GDK_POINTER_MOTION_HINT_MASKなし * 移動するたびにイベントが発生 * コールバックの処理時間によっては、キューにたまってしまう ** マウスを止めても、キューが解消されるまで処理を続ける ** 普通は問題になる * サンプル No Hint ** わかりにくい場合は、cb_event.c の124行目(たぶん)にある、処理時間増加テスト用のスリープを有効にして make すればはっきりする !! GDK_POINTER_MOTION_HINT_MASKあり * 移動するたびにイベントが発生しない * コールバックの処理が遅くても、キューには「マウスが移動した」ことだけを示す、単一のイベントがたまる ** マウスの動いた座標はコールバック内で、明示的に得なければならない ((img hint_mask.png)) !! コールバックの登録 * main関数 8< g_signal_connect(G_OBJECT(drawing_area), "motion_notify_event", G_CALLBACK(cb_motion_notify_event), NULL); gtk_widget_set_events(drawing_area, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK); >8 * コールバック関数 8< gint cb_motion_notify_event(GtkWidget *widget, GdkEventMotion *event) { int x, y; GdkModifierType state; if(event->is_hint) { /* hintだったらポインタの位置を再取得 */ gdk_window_get_pointer(event->window, &x, &y, &state); } else { x = event->x; y = event->y; state = event->state; } if(state & GDK_BUTTON1_MASK) { /* マウスの左ボタンが押されていたら(ドラッグ) */ /* 何かやりたいことを書く */ } /* 何かやりたいことを書く */ return TRUE; } >8 !!! button_press_event * マウスボタンが押されたときに発生 * 押されたボタンの判定はコールバック側で行う !! コールバックの登録 * main関数 8< g_signal_connect(G_OBJECT(drawing_area), "button_press_event", G_CALLBACK(cb_button_press_event), NULL); gtk_widget_set_events(drawing_area, GDK_BUTTON_PRESS_MASK); >8 * コールバック関数 8< gint cb_button_press_event(GtkWidget *widget, GdkEventButton *event) { int x, y, button; GdkModifierType state; x = event->x; y = event->y; state = event->state; button = event->button; if(button == 1) { /* マウスの左ボタンが押されていたら */ if(state & GDK_SHIFT_MASK) { /* さらにshiftが押されていたら */ /* 何かやりたいことを書く */ } else { /* 何かやりたいことを書く */ } } return TRUE; } >8 !!! button_release_event * マウスボタンが離されたときに発生 * 離されたボタンの判定はコールバック側で行う !! コールバックの登録 * main関数 8< g_signal_connect(G_OBJECT(drawing_area), "button_release_event", G_CALLBACK(cb_button_release_event), NULL); gtk_widget_set_events(drawing_area, GDK_BUTTON_RELEASE_MASK); >8 * コールバック関数 8< gint cb_button_release_event(GtkWidget *widget, GdkEventButton *event) { int button; button = event->button; if(button == 3) { /* マウスの右ボタンが離されていたら /* 何かやりたいことを書く */ } return TRUE; } >8 !!! scroll_event * マウスホイールが回されたときに発生 * 回された方向の判定はコールバック側で行う !! コールバックの登録 * main関数 8< g_signal_connect(G_OBJECT(drawing_area), "scroll_event", G_CALLBACK(cb_scroll_event), NULL); gtk_widget_set_events(drawing_area, GDK_SCROLL_MASK); >8 * コールバック関数 8< gint cb_scroll_event(GtkWidget *widget, GdkEventButton *event) { GdkScrollDirection direction; direction = event->direction; if(direction & GDK_SCROLL_DOWN) { /* ホイールがdown方向に回ったら */ /* 何かやりたいことを書く */ } else { /* ホイールがup方向に回ったら */ /* 何かやりたいことを書く */ } return TRUE; } >8