Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | Related Pages

siglisthandle.h

00001 /*
00002  * ===========================
00003  * VDK Visual Develeopment Kit
00004  * Version 0.4
00005  * October 1998
00006  * ===========================
00007  *
00008  * Copyright (C) 1998, Mario Motta
00009  * Developed by Mario Motta <mmotta@guest.net>
00010  *
00011  * This library is free software; you can redistribute it and/or
00012  * modify it under the terms of the GNU Library General Public
00013  * License as published by the Free Software Foundation; either
00014  * version 2 of the License, or (at your option) any later version.
00015  *
00016  * This library 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 GNU
00019  * Library General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU Library General Public
00022  * License along with this library; if not, write to the Free Software
00023  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00024  * 02111-1307, USA.
00025  */
00026 #ifndef SIGLISTHANDLE_H
00027 #define SIGLISTHANDLE_H
00028 #include <string.h>
00029 #include <vdk/vdkobj.h>
00030 // #include <vdk/vdkstring.h>
00031 #include <vdk/value_sem_list.h>
00032 #include <gdk/gdktypes.h>
00033 #include <cstring>
00034 #define VDK_SIGNAL_NAME_LENGHT 63
00035 /*
00036 ==============================================
00037          SIGNAL LIST ROUTINES
00038 ==============================================
00039 */
00040 /*
00041 A signal unit is a single signal package
00042 generated by SignalConnect and added to
00043 object callback list. As a signal is emitted
00044 by a gtk+ widget this list is searched to
00045 find informations to compute response method
00046 address and call it with sender object as
00047 argument
00048  */
00049 template <class T>
00050 class _VDK_Signal_Unit {
00051   
00052   public:
00053   typedef bool (T::*PMF)(VDKObject* sender);
00054   VDKObject* Pm;
00055   // *** VDKString signal; /* signal name ala Gtk+ */
00056   char signal[VDK_SIGNAL_NAME_LENGHT+1];
00057   PMF    Pmf;  /* <class T> member function offset */
00058   gint slot;  /* gtk+ slot returned by gtk_signal_connect() */
00059   bool connected;
00060   GtkObject* gtkobj; /* gtk object */
00061   _VDK_Signal_Unit(VDKObject* Pm, char* sign,
00062                    PMF Pmf):
00063     //***    Pm(Pm),signal(sign),Pmf(Pmf), slot(-1),connected(true) {}
00064     Pm(Pm),Pmf(Pmf), slot(-1),connected(true) 
00065     {
00066       std::strncpy(signal,sign,VDK_SIGNAL_NAME_LENGHT);
00067       // for safe
00068       signal[VDK_SIGNAL_NAME_LENGHT] = '\0';
00069     }
00070   bool operator ==(_VDK_Signal_Unit& su)
00071     //***    { return (signal == su.signal) && (Pm == su.Pm); }
00072     { return ((!std::strcmp(signal,su.signal)) && (Pm == su.Pm)); }
00073 };
00074 
00075 
00076 
00077 #define DECLARE_SIGNAL_LIST(_owner_class) \
00078 \
00079 private:\
00080 typedef _VDK_Signal_Unit<_owner_class> _SignalUnit;\
00081 typedef VDKValueList< _SignalUnit >  _CallbackList;\
00082 typedef VDKValueListIterator< _SignalUnit >  _CallbackListIterator;\
00083 _CallbackList _cbList;\
00084 public:\
00085 /*virtual bool FindSignalAtClassLevel(VDKObject* Pm, VDKString& signal);*/\
00086 /*virtual bool FindSignalAtParentLevel(VDKObject* Pm, VDKString& signal);*/\
00087 virtual bool FindSignalAtClassLevel(VDKObject* Pm, char* signal);\
00088 virtual bool FindSignalAtParentLevel(VDKObject* Pm, char* signal);\
00089 virtual int VDKSignalUnitResponse(GtkWidget* , char* , void*);\
00090 \
00091 \
00092 \
00093 int SignalConnect(VDKObject* object, char* signal,\
00094   bool (_owner_class::*Pmf)(VDKObject* sender), bool gtk = true, bool after = false);\
00095 int SignalConnect(char* signal,\
00096   bool (_owner_class::*Pmf)(VDKObject* sender), bool gtk = true, bool after = false)\
00097 {\
00098 return SignalConnect(this, signal, Pmf,gtk, after);\
00099 }\
00100 \
00101 virtual int  VDKSignalResponseListSize() { return _cbList.size(); }\
00102 \
00103 bool SignalDisconnect(int slot);
00104 
00105 /*
00106 Routines logic: (valid also for events)
00107 
00108 1. Signal connecting: SignalConnect()
00109 
00110     A signal unit is generated and a recursive visiting
00111     algorithm are called: FindSignalAtClassLevel() and
00112     FindSignalAtParentLevel(). If the signal is not found
00113     into ancestor or parent classes callback lists a "real" 
00114     Gtk+ connecting  is called (in this case slot number 
00115     will be positive), otherwise no "real" Gtk+ is used 
00116     (slot number < 0). Signal unit is added to object callback list.
00117 
00118 2.Signal emitted: VDKSignalUnitResponse()
00119 
00120     This routine receives signal name and sender address.
00121     Search into callback list to find a match. If found
00122     computes response method address and call it with
00123     sender as argument. If response method answers true
00124     flag the signal as treated and return. Otherwise
00125     recursively call himself into ancestor class.
00126 
00127 3. Signal disconnecting: SignalDisconnect()
00128 
00129    Callback list is searched to find a match with slot.
00130    If found and slot number is > 0 a "real" Gtk+ disconnecting
00131    is called too.
00132    Signal unit is removed from callback list.
00133  */
00134 
00135 #define DEFINE_SIGNAL_LIST(_owner_class, _ancestor_class)\
00136 \
00137 \
00138 /*bool _owner_class::FindSignalAtClassLevel(VDKObject* Pm, VDKString& signal)*/\
00139 bool _owner_class::FindSignalAtClassLevel(VDKObject* Pm, char* signal)\
00140 {\
00141 _SignalUnit su(Pm,signal, (bool (_owner_class::*)(VDKObject*)) NULL);\
00142 if(_cbList.find(su))\
00143  return true;\
00144 else\
00145   return _ancestor_class::FindSignalAtClassLevel(Pm,signal);\
00146 }\
00147 \
00148 \
00149 /*bool _owner_class::FindSignalAtParentLevel(VDKObject* Pm, VDKString& signal)*/\
00150 bool _owner_class::FindSignalAtParentLevel(VDKObject* Pm, char* signal)\
00151 {\
00152 VDKObject* parent;\
00153 for(parent = Parent(); parent; parent = parent->Parent())\
00154     if(parent->FindSignalAtClassLevel(Pm,signal))\
00155       return true;\
00156 return false;\
00157 }\
00158 \
00159 \
00160 \
00161 int _owner_class::SignalConnect(VDKObject* obj,char* signal,\
00162   bool (_owner_class::*Pmf)(VDKObject* sender), bool gtk, bool after)\
00163 {\
00164 bool found = false;\
00165 VDKObjectSignalUnit* su = new VDKObjectSignalUnit(this,obj,signal);\
00166 suList.add(su);\
00167 _SignalUnit sigUnit(obj,signal,Pmf);\
00168 found = obj->FindSignalAtClassLevel(sigUnit.Pm,sigUnit.signal) || \
00169       obj->FindSignalAtParentLevel(sigUnit.Pm,sigUnit.signal);\
00170 if(!found && gtk)\
00171 sigUnit.slot = after ? gtk_signal_connect_after(GTK_OBJECT(obj->ConnectingWidget()),signal,\
00172                      GTK_SIGNAL_FUNC(VDKObject::VDKSignalUnitPipe),\
00173                      reinterpret_cast<gpointer>(su) ):\
00174                      gtk_signal_connect(GTK_OBJECT(obj->ConnectingWidget()),signal,\
00175                      GTK_SIGNAL_FUNC(VDKObject::VDKSignalUnitPipe),\
00176                      reinterpret_cast<gpointer>(su) );\
00177 else\
00178  sigUnit.slot = (_cbList.size()+1)*-1;\
00179 sigUnit.gtkobj = obj->ConnectingWidget() != NULL ? \
00180     GTK_OBJECT(obj->ConnectingWidget()) : NULL;\
00181 _cbList.add(sigUnit);\
00182 return sigUnit.slot;\
00183 }\
00184 \
00185 \
00186 \
00187 bool _owner_class::SignalDisconnect(int slot)\
00188 {\
00189 int t = 0;\
00190 _CallbackListIterator li(_cbList);\
00191 for(;li;li++,t++)\
00192 {\
00193 _SignalUnit su = li.current();\
00194 if(su.slot == slot)\
00195   {\
00196   if(su.slot > 0)\
00197     gtk_signal_disconnect(su.gtkobj,su.slot);\
00198   _cbList.unlink(t);\
00199   return true;\
00200   }\
00201 }\
00202 return false;\
00203 }\
00204 \
00205 \
00206 int _owner_class::VDKSignalUnitResponse(GtkWidget* mobj,\
00207                                         char* signal, void* obj)\
00208 {\
00209 bool treated = false;\
00210 VDKObject* vdkobj = reinterpret_cast<VDKObject*>(obj);\
00211 _CallbackListIterator li(_cbList);\
00212 for(;li;li++)\
00213 {\
00214 _SignalUnit su = li.current();\
00215 if ( (su.Pm == vdkobj) &&\
00216      (!std::strcmp(su.signal,signal) && su.connected))\
00217    {\
00218         bool(_owner_class::*response)(VDKObject* sender)= \
00219                               su.Pmf;\
00220         if(((*this).*response)(vdkobj) == true)\
00221             treated = true;\
00222    }\
00223 }\
00224 if(treated)\
00225    return 1;\
00226 else\
00227    return _ancestor_class::VDKSignalUnitResponse(mobj,signal,obj);\
00228 }
00229 
00230 #endif
00231 /*
00232 if(!found && gtk)\
00233   sigUnit.slot = after ? gtk_signal_connect_after(GTK_OBJECT(obj->ConnectingWidget()),signal,\
00234                      GTK_SIGNAL_FUNC(VDKObject::VDKSignalUnitPipe),\
00235                      reinterpret_cast<gpointer>(su) ):\
00236                      gtk_signal_connect(GTK_OBJECT(obj->ConnectingWidget()),signal,\
00237                      GTK_SIGNAL_FUNC(VDKObject::VDKSignalUnitPipe),\
00238                      reinterpret_cast<gpointer>(su) );\
00239 */
00240 
00241 
00242 
00243 

Generated on Sat Sep 3 12:10:19 2005 for vdk 2.4.0 by  doxygen 1.4.4