Main Page | Class Hierarchy | Alphabetical List | Class List | 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 Wed Jul 28 17:23:53 2004 for vdk 2.0.3 by doxygen 1.3.7