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