notepad_gtk_source.h

Go to the documentation of this file.
00001 #ifndef GTK_SOURCE_H_
00002 #define GTK_SOURCE_H_
00003 
00004 /*
00005  * File Name: notepad_gtk_source.h
00006  */
00007 
00008 /*
00009  * This file is part of notepad.
00010  *
00011  * notepad is free software: you can redistribute it and/or modify
00012  * it under the terms of the GNU General Public License as published by
00013  * the Free Software Foundation, either version 2 of the License, or
00014  * (at your option) any later version.
00015  *
00016  * notepad is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00023  */
00024 
00025 /**
00026  * Copyright (C) 2010 IREX Technologies B.V.
00027  * All rights reserved.
00028  */
00029  
00030 #include <gtk/gtk.h>
00031 
00032 namespace gtk
00033 {
00034     /// @brief Enable caller to handle GTK events without inheriting from any class.
00035     /// One-one connection. It's better to use template based technology. 
00036     /// By GtkEventSource caller is able to handle multiple widgets' events.
00037     template <class T>
00038     class GtkEventSource 
00039     {
00040     public:
00041         enum EventType 
00042         {
00043             EVENT_EXPOSE = 0,       // signal expose_event
00044             EVENT_VISIBILITY_NOTIFY,// signal visibility_notify_event
00045             EVENT_CONFIG,           // signal configure_event
00046             EVENT_BUTTON_PRESS,     // signal button_press_event
00047             EVENT_BUTTON_RELEASE,   // signal button_release_event
00048             EVENT_MOTION_NOTIFY,    // signal motion_notify_event
00049             EVENT_KEY_PRESS,        // signal key_press_event
00050             EVENT_KEY_RELEASE,      // signal key_release_event
00051             EVENT_DELETE,           // signal delete_event
00052             EVENT_MAX,          // number of events
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         /// Disconnect all connected signal handlers.
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         /// @brief Connect the event handler(slot) with the gtk event(signal)
00080         void connect_event_handlers(GtkWidget* widget)
00081         {
00082             // events 
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             // install event handlers.
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         /// @brief Set event handler of gtk event (from event loop)
00128         inline void set_event_handler(EventType type, 
00129                                       void (T::*func)(GdkEvent* event) )
00130         {
00131             callbacks[type] = func;
00132         }
00133         
00134     private:
00135         /// static: wraps from GTK to C++ 
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         // invoker, translates GDK event type to enum EventType
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; // receiver object
00198         void (T::*callbacks[EVENT_MAX])(GdkEvent* event); // list of callback member functionpointers
00199 
00200         gulong handler_ids[EVENT_MAX]; // used to disconnect events
00201     };
00202 
00203 }; //namespace gtk
00204 
00205 #endif
Generated by  doxygen 1.6.2-20100208