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
#ifndef SIGLISTHANDLE_H
00027
#define SIGLISTHANDLE_H
00028
#include <string.h>
00029
#include <vdk/vdkobj.h>
00030
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
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
template <
class T>
00050
class _VDK_Signal_Unit {
00051
00052
public:
00053
typedef bool (T::*PMF)(
VDKObject* sender);
00054
VDKObject* Pm;
00055
00056
char signal[VDK_SIGNAL_NAME_LENGHT+1];
00057 PMF Pmf;
00058 gint slot;
00059
bool connected;
00060 GtkObject* gtkobj;
00061 _VDK_Signal_Unit(
VDKObject* Pm,
char* sign,
00062 PMF Pmf):
00063
00064 Pm(Pm),Pmf(Pmf), slot(-1),connected(true)
00065 {
00066 std::strncpy(signal,sign,VDK_SIGNAL_NAME_LENGHT);
00067
00068 signal[VDK_SIGNAL_NAME_LENGHT] =
'\0';
00069 }
00070
bool operator ==(_VDK_Signal_Unit& su)
00071
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
\
00086 \
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
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
#define DEFINE_SIGNAL_LIST(_owner_class, _ancestor_class)\
00136
\
00137
\
00138
\
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 \
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
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243