00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef TEST_GTK_SOURCE_H_
00028 #define TEST_GTK_SOURCE_H_
00029
00030 #include <gtk/gtk.h>
00031 #include <string.h>
00032
00033 namespace gtk
00034 {
00035
00036
00037
00038
00039 template <class T>
00040 class GtkEventSource
00041 {
00042 public:
00043 enum EventType
00044 {
00045 EVENT_EXPOSE = 0,
00046 EVENT_CONFIG,
00047 EVENT_BUTTON_PRESS,
00048 EVENT_BUTTON_RELEASE,
00049 EVENT_MOTION_NOTIFY,
00050 EVENT_KEY_PRESS,
00051 EVENT_KEY_RELEASE,
00052 EVENT_DELETE,
00053 EVENT_FD_INPUT,
00054 EVENT_UNDEFINED,
00055 };
00056
00057 public:
00058 GtkEventSource(T * r) : receiver(r)
00059 {
00060 memset(&callbacks[0], 0, sizeof(callbacks));
00061 }
00062
00063 ~GtkEventSource()
00064 {
00065 }
00066
00067
00068 void connect_event_handlers(GtkWidget * widget)
00069 {
00070
00071 gtk_widget_set_events (widget,
00072 GDK_EXPOSURE_MASK | GDK_BUTTON_MOTION_MASK |
00073 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
00074 GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
00075
00076
00077 gtk_signal_connect (GTK_OBJECT (widget), "expose_event",
00078 GTK_SIGNAL_FUNC (widget_event_handler), this);
00079
00080 gtk_signal_connect (GTK_OBJECT (widget), "configure_event",
00081 GTK_SIGNAL_FUNC (widget_event_handler), this);
00082
00083 gtk_signal_connect (GTK_OBJECT (widget), "button_press_event",
00084 GTK_SIGNAL_FUNC (widget_event_handler), this);
00085
00086 gtk_signal_connect (GTK_OBJECT (widget), "button_release_event",
00087 GTK_SIGNAL_FUNC (widget_event_handler), this);
00088
00089 gtk_signal_connect (GTK_OBJECT (widget), "motion_notify_event",
00090 GTK_SIGNAL_FUNC (widget_event_handler), this);
00091
00092 gtk_signal_connect (GTK_OBJECT (widget), "key_press_event",
00093 GTK_SIGNAL_FUNC (widget_event_handler), this);
00094
00095 gtk_signal_connect (GTK_OBJECT (widget), "key_release_event",
00096 GTK_SIGNAL_FUNC (widget_event_handler), this);
00097
00098 gtk_signal_connect (GTK_OBJECT (widget), "delete_event",
00099 GTK_SIGNAL_FUNC (widget_event_handler), this);
00100 }
00101
00102
00103 void set_fd_event_watcher(int fd, gboolean
00104 (T::*func)(GtkWidget *widget,
00105 GdkEvent * event))
00106 {
00107 gdk_input_add(fd, GDK_INPUT_READ,
00108 (GdkInputFunction)fd_event_handler,
00109 (gpointer)this);
00110
00111 callbacks[EVENT_FD_INPUT] = func;
00112 }
00113
00114
00115 inline void set_event_handler(EventType type,
00116 gboolean (T::*func)(GtkWidget * widget,
00117 GdkEvent * event))
00118 {
00119 callbacks[type] = func;
00120 }
00121
00122 private:
00123 static gboolean widget_event_handler(GtkWidget * widget,
00124 GdkEvent * event,
00125 gpointer user_data)
00126 {
00127 GtkEventSource* pThis = (GtkEventSource *)user_data;
00128
00129 if (event == 0)
00130 {
00131 return FALSE;
00132 }
00133
00134 switch (event->type)
00135 {
00136 case GDK_EXPOSE:
00137
00138 return pThis->invoke_callback(EVENT_EXPOSE, widget, event);
00139
00140 case GDK_CONFIGURE:
00141
00142 return pThis->invoke_callback(EVENT_CONFIG, widget, event);
00143
00144 case GDK_BUTTON_PRESS:
00145
00146 return pThis->invoke_callback(EVENT_BUTTON_PRESS, widget, event);
00147
00148 case GDK_BUTTON_RELEASE:
00149
00150 return pThis->invoke_callback(EVENT_BUTTON_RELEASE, widget, event);
00151
00152 case GDK_MOTION_NOTIFY:
00153
00154 return pThis->invoke_callback(EVENT_MOTION_NOTIFY, widget, event);
00155
00156 case GDK_KEY_PRESS:
00157
00158 return pThis->invoke_callback(EVENT_KEY_PRESS, widget, event);
00159
00160 case GDK_KEY_RELEASE:
00161
00162 return pThis->invoke_callback(EVENT_KEY_RELEASE, widget, event);
00163
00164 case GDK_DELETE:
00165
00166 return pThis->invoke_callback(EVENT_DELETE, widget, event);
00167
00168 default:
00169 break;
00170 }
00171
00172 return FALSE;
00173 }
00174
00175 static void fd_event_handler(gpointer user_data, gint *fd,
00176 GdkInputCondition id)
00177 {
00178 GtkEventSource *pThis = (GtkEventSource *)user_data;
00179 pThis->invoke_callback(EVENT_FD_INPUT, 0, 0);
00180 }
00181
00182 gboolean invoke_callback(EventType type,
00183 GtkWidget *widget,
00184 GdkEvent *event)
00185 {
00186 if (callbacks[type])
00187 {
00188 return (receiver->*callbacks[type])(widget, event);
00189 }
00190 return FALSE;
00191 }
00192
00193 private:
00194
00195 T * receiver;
00196 gboolean (T::*callbacks[EVENT_UNDEFINED])(GtkWidget *widget,
00197 GdkEvent *event);
00198
00199 };
00200
00201 };
00202
00203 #endif
00204
00205