vdk 2.4.0
|
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 EVHANDLE_H 00027 #define EVHANDLE_H 00028 #include <vdk/vdkobj.h> 00029 #include <gdk/gdktypes.h> 00030 #include <cstring> 00031 /* 00032 ============================================== 00033 SIGNAL DISPATCHER ROUTINES 00034 ============================================== 00035 */ 00036 /* 00037 _VDKSignalTable_: 00038 Obj/Signal/Response method Table 00039 */ 00040 template <class T> 00041 class _VDKSignalTable_ { 00042 public: 00043 typedef bool (T::*PMF)(VDKObject* sender); 00044 VDKObject* T::*Pm; /* <class T> member offset */ 00045 int signal; /* signal type (see enum VDKSignal in vdkobj.h) */ 00046 PMF Pmf; /* <class T> member function offset */ 00047 bool connected; /* connected flag, if false denies signal */ 00048 }; 00049 00050 /* 00051 Signal response function map declaration: 00052 declare a static signal table for each form 00053 */ 00054 00055 #define DECLARE_SIGNAL_MAP(_Parent_Class_) \ 00056 private:\ 00057 static _VDKSignalTable_< _Parent_Class_ > _STEntries_[];\ 00058 typedef _VDKSignalTable_< _Parent_Class_ >::PMF _Member_;\ 00059 typedef _Parent_Class_ _Parent_MyClass_;\ 00060 protected:\ 00061 virtual int VDKSignalResponseTableSize();\ 00062 public:\ 00063 virtual int VDKSignalResponse(GtkWidget* , int signal, void*, void*,bool);\ 00064 virtual int SignalDetach(VDKObject* Pm, int signal);\ 00065 virtual bool SignalAttach(int slot); 00066 00067 /* 00068 define form signal response function that in turn call 00069 object signal response function 00070 algorithm: 00071 1. scan table until find table end 00072 2. if matches object and signal then slot is found 00073 3. if slot is connected 00074 4. bind object address with member function class offset 00075 5. call callback 00076 6. if callback return true consider signal "treated" 00077 7. if signal is treated finish 00078 otherwise recursively call himself to ancestor class 00079 */ 00080 00081 #define DEFINE_SIGNAL_MAP(_Parent_Class_,base)\ 00082 \ 00083 int _Parent_Class_::VDKSignalResponse(GtkWidget* mobj, \ 00084 int signal, void* obj, void* real_sender, bool treated) \ 00085 {\ 00086 int t=0;\ 00087 /*bool treated = false;*/\ 00088 VDKObject* vdkobj = reinterpret_cast<VDKObject*>(obj);\ 00089 VDKObject* real = reinterpret_cast<VDKObject*>(real_sender);\ 00090 for(;_STEntries_[t].Pm != NULL ;t++)\ 00091 {\ 00092 VDKObject* _Parent_Class_::*memberOffset = _STEntries_[t].Pm;\ 00093 if ( ((*this).*memberOffset == vdkobj) &&\ 00094 (_STEntries_[t].signal == signal) )\ 00095 {\ 00096 if (_STEntries_[t].connected)\ 00097 {\ 00098 bool(_Parent_Class_::*response)(VDKObject* sender)= \ 00099 _STEntries_[t].Pmf;\ 00100 if(((*this).*response)(real) == true)\ 00101 treated = true;\ 00102 }\ 00103 /*break;*/\ 00104 }\ 00105 }\ 00106 if(treated) return 1;\ 00107 else return base::VDKSignalResponse(mobj,signal,obj,real_sender, treated);\ 00108 }\ 00109 \ 00110 \ 00111 int _Parent_Class_::VDKSignalResponseTableSize()\ 00112 {\ 00113 int t = 0;\ 00114 for(;_STEntries_[t].Pm != NULL;t++)\ 00115 ;\ 00116 return t;\ 00117 }\ 00118 \ 00119 \ 00120 \ 00121 int _Parent_Class_::SignalDetach(VDKObject* Pm, int signal)\ 00122 {\ 00123 int t=0;\ 00124 for(;_STEntries_[t].Pm != NULL ;t++)\ 00125 {\ 00126 VDKObject* _Parent_Class_::*memberOffset = _STEntries_[t].Pm;\ 00127 if ( ((*this).*memberOffset == Pm) &&\ 00128 (_STEntries_[t].signal == signal) &&\ 00129 _STEntries_[t].connected != false)\ 00130 {\ 00131 _STEntries_[t].connected = false;\ 00132 return t;\ 00133 }\ 00134 }\ 00135 return -1;\ 00136 }\ 00137 \ 00138 \ 00139 \ 00140 bool _Parent_Class_::SignalAttach(int slot)\ 00141 {\ 00142 if( (slot >= 0) && (slot <= VDKSignalResponseTableSize()) )\ 00143 {\ 00144 _STEntries_[slot].connected = true;\ 00145 return true;\ 00146 }\ 00147 else\ 00148 return false;\ 00149 }\ 00150 \ 00151 \ 00152 _VDKSignalTable_< _Parent_Class_ > _Parent_Class_::_STEntries_[] = { 00153 /* 00154 fill static signal table 00155 */ 00156 #define ON_SIGNAL(_obj_,_SIGNAL_,_member_) \ 00157 { reinterpret_cast<VDKObject* _Parent_MyClass_::*>(&_Parent_MyClass_::_obj_),\ 00158 _SIGNAL_,&_Parent_MyClass_::_member_,true} 00159 /* 00160 */ 00161 #define END_SIGNAL_MAP ,{ NULL, 0, NULL, false} }; 00162 /* 00163 */ 00164 00165 /* 00166 ============================================== 00167 EVENT DISPATCHER ROUTINES 00168 ============================================== 00169 */ 00170 /* 00171 EVENTTableEntry: 00172 Event-ObjectCallback Table Entry 00173 */ 00174 template <class T> 00175 class EVENTTableEntry { 00176 public: 00177 // typedef void (T::*PMF)(VDKObject* sender, GdkEvent* event); 00178 typedef bool (T::*PMF)(VDKObject* sender, GdkEvent* event); 00179 VDKObject* T::*Pm; /* pointer to <class T> member offset */ 00180 GdkEventType event; /* event type (see enum VDKevent in vdkobj.h) */ 00181 PMF Pmf; /* pointer to <class T> member function */ 00182 bool connected; 00183 }; 00184 /* 00185 Events response function map declaration: 00186 declare a static events table for each form 00187 */ 00188 #define DECLARE_EVENT_MAP(_EVENTclass_) \ 00189 private:\ 00190 static EVENTTableEntry< _EVENTclass_ > __OCBEventEntries[];\ 00191 typedef EVENTTableEntry< _EVENTclass_ >::PMF _EvMember_;\ 00192 typedef _EVENTclass_ _EVENTmyclass_;\ 00193 protected:\ 00194 virtual int VDKEventResponseTableSize();\ 00195 public:\ 00196 virtual int VDKEventResponse(GtkWidget* , GdkEvent* , void*, void*,bool);\ 00197 virtual int EventDetach(VDKObject* , VDKEvent event);\ 00198 virtual bool EventAttach(int slot); 00199 /* 00200 define form EVENT response function that in turn call 00201 object EVENT response function 00202 */ 00203 #define DEFINE_EVENT_MAP(_EVENTclass_,base) \ 00204 int _EVENTclass_::VDKEventResponse(GtkWidget* wid, GdkEvent* event, void* obj, void* real_sender, bool treated) \ 00205 \ 00206 {\ 00207 int t=0;\ 00208 /*bool treated = false;*/\ 00209 VDKObject* vdkobj = reinterpret_cast<VDKObject*>(obj);\ 00210 VDKObject* real = reinterpret_cast<VDKObject*>(real_sender);\ 00211 for(;__OCBEventEntries[t].Pm != NULL ;t++)\ 00212 {\ 00213 VDKObject* _EVENTclass_::*memberOffset = __OCBEventEntries[t].Pm;\ 00214 if( ((*this).*memberOffset == vdkobj) &&\ 00215 (__OCBEventEntries[t].event == ((GdkEventAny*)event)->type) )\ 00216 {\ 00217 if (__OCBEventEntries[t].connected)\ 00218 {\ 00219 bool (_EVENTclass_::*response)\ 00220 (VDKObject* , GdkEvent* ) = \ 00221 __OCBEventEntries[t].Pmf;\ 00222 if(((*this).*response)(real,event))\ 00223 treated = true;\ 00224 }\ 00225 /*break;*/\ 00226 }\ 00227 }\ 00228 if(treated) return 1;\ 00229 else return base::VDKEventResponse(wid,event,obj,real_sender, treated); \ 00230 }\ 00231 \ 00232 \ 00233 \ 00234 int _EVENTclass_::VDKEventResponseTableSize()\ 00235 {\ 00236 int t = 0;\ 00237 for(;__OCBEventEntries[t].Pm != NULL;t++)\ 00238 ;\ 00239 return t;\ 00240 }\ 00241 \ 00242 \ 00243 \ 00244 int _EVENTclass_::EventDetach(VDKObject* Pm, VDKEvent event)\ 00245 {\ 00246 int t=0;\ 00247 for(;__OCBEventEntries[t].Pm != NULL ;t++)\ 00248 {\ 00249 VDKObject* _EVENTclass_::*memberOffset = __OCBEventEntries[t].Pm;\ 00250 if ( ((*this).*memberOffset == Pm) &&\ 00251 (__OCBEventEntries[t].event == (GdkEventType) event)&&\ 00252 __OCBEventEntries[t].connected != false)\ 00253 {\ 00254 __OCBEventEntries[t].connected = false;\ 00255 return t;\ 00256 }\ 00257 }\ 00258 return -1;\ 00259 }\ 00260 \ 00261 \ 00262 \ 00263 bool _EVENTclass_::EventAttach(int slot)\ 00264 {\ 00265 if( (slot >= 0) && (slot <= VDKEventResponseTableSize()) )\ 00266 {\ 00267 __OCBEventEntries[slot].connected = true;\ 00268 return true;\ 00269 }\ 00270 else\ 00271 return false;\ 00272 }\ 00273 \ 00274 \ 00275 EVENTTableEntry< _EVENTclass_ > _EVENTclass_::__OCBEventEntries[] = { 00276 /* 00277 fill static EVENT table 00278 */ 00279 #define ON_EVENT(_obj_,_EVENT_,_member_) \ 00280 /* {reinterpret_cast<VDKObject* _EVENTmyclass_::*>(&_EVENTmyclass_::_obj_), (GdkEventType) _EVENT_,&(_EVENTmyclass_::_member_),true} */ \ 00281 {reinterpret_cast<VDKObject* _EVENTmyclass_::*>(&_EVENTmyclass_::_obj_), (GdkEventType) _EVENT_,&_EVENTmyclass_::_member_,true} 00282 00283 /* 00284 */ 00285 #define END_EVENT_MAP ,{ NULL , (GdkEventType) 0, NULL,false} }; 00286 00287 #endif 00288 00289 00290 00291 00292 00293 00294