]> git.saurik.com Git - wxWidgets.git/blob - utils/wxPython/src/helpers.h
54baeab6f644baf2199004eb37610e27c7675208
[wxWidgets.git] / utils / wxPython / src / helpers.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: helpers.h
3 // Purpose: Helper functions/classes for the wxPython extenaion module
4 //
5 // Author: Robin Dunn
6 //
7 // Created: 7/1/97
8 // RCS-ID: $Id$
9 // Copyright: (c) 1998 by Total Control Software
10 // Licence: wxWindows license
11 /////////////////////////////////////////////////////////////////////////////
12
13 #ifndef __wxp_helpers__
14 #define __wxp_helpers__
15
16 #include <wx/wx.h>
17
18
19 //----------------------------------------------------------------------
20
21 // if we want to handle threads and Python threads are available...
22 #if defined(WXP_USE_THREAD) && defined(WITH_THREAD)
23
24 #define WXP_WITH_THREAD
25 #define wxPy_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
26 #define wxPy_END_ALLOW_THREADS Py_END_ALLOW_THREADS
27
28 #else // no Python threads...
29 #undef WXP_WITH_THREAD
30 #define wxPy_BEGIN_ALLOW_THREADS
31 #define wxPy_END_ALLOW_THREADS
32 #endif
33
34
35 //---------------------------------------------------------------------------
36
37 #if defined(__WXMSW__)
38 # define HELPEREXPORT __declspec(dllexport)
39 #else
40 # define HELPEREXPORT
41 #endif
42
43 //----------------------------------------------------------------------
44
45 class wxPyApp: public wxApp
46 {
47 public:
48 wxPyApp();
49 ~wxPyApp();
50 int MainLoop(void);
51 bool OnInit(void);
52 //# void AfterMainLoop(void);
53 };
54
55 extern wxPyApp *wxPythonApp;
56
57 //----------------------------------------------------------------------
58
59 void __wxPreStart();
60 PyObject* __wxStart(PyObject*, PyObject* args);
61
62 extern PyObject* wxPython_dict;
63 PyObject* __wxSetDictionary(PyObject*, PyObject* args);
64
65 void wxPyEventThunker(wxObject*, wxEvent& event);
66
67 HELPEREXPORT PyObject* wxPyConstructObject(void* ptr, char* className);
68 HELPEREXPORT bool wxPyRestoreThread();
69 HELPEREXPORT void wxPySaveThread(bool doSave);
70
71 //----------------------------------------------------------------------
72
73
74 #ifndef SWIGCODE
75 extern "C" void SWIG_MakePtr(char *, void *, char *);
76 extern "C" char *SWIG_GetPtr(char *, void **, char *);
77 extern "C" char *SWIG_GetPtrObj(PyObject *obj, void **ptr, char *type);
78 #endif
79
80
81 #ifdef _MSC_VER
82 # pragma warning(disable:4800)
83 #endif
84
85 typedef unsigned char byte;
86
87
88 // Non-const versions to keep SWIG happy.
89 extern wxPoint wxPyDefaultPosition;
90 extern wxSize wxPyDefaultSize;
91 extern wxString wxPyEmptyStr;
92
93 //----------------------------------------------------------------------
94
95 class wxPyCallback : public wxObject {
96 public:
97 wxPyCallback(PyObject* func);
98 ~wxPyCallback();
99
100 void EventThunker(wxEvent& event);
101
102 PyObject* m_func;
103 };
104
105 //---------------------------------------------------------------------------
106
107 // class wxPyMenu : public wxMenu {
108 // public:
109 // wxPyMenu(const wxString& title = "", PyObject* func=NULL);
110 // ~wxPyMenu();
111
112 // private:
113 // static void MenuCallback(wxMenu& menu, wxCommandEvent& evt);
114 // PyObject* func;
115 // };
116
117
118 //---------------------------------------------------------------------------
119
120 class wxPyTimer : public wxTimer {
121 public:
122 wxPyTimer(PyObject* callback);
123 ~wxPyTimer();
124
125 void Notify();
126
127 private:
128 PyObject* func;
129 };
130
131 //---------------------------------------------------------------------------
132
133 class wxPyEvent : public wxCommandEvent {
134 DECLARE_DYNAMIC_CLASS(wxPyEvent)
135 public:
136 wxPyEvent(wxEventType commandType = wxEVT_NULL, PyObject* userData = Py_None);
137 ~wxPyEvent();
138
139 void SetUserData(PyObject* userData);
140 PyObject* GetUserData();
141
142 private:
143 PyObject* m_userData;
144 };
145
146
147
148
149
150 //---------------------------------------------------------------------------
151 // This class holds an instance of a Python Shadow Class object and assists
152 // with looking up and invoking Python callback methods from C++ virtual
153 // method redirections. For all classes which have virtuals which should be
154 // overridable in wxPython, a new subclass is created that contains a
155 // wxPyCallbackHelper.
156 //
157 // **** This class should be combined with wxPyCallback defined above.
158 //
159 //---------------------------------------------------------------------------
160
161 class HELPEREXPORT wxPyCallbackHelper {
162 public:
163 wxPyCallbackHelper();
164 ~wxPyCallbackHelper();
165
166 void setSelf(PyObject* self);
167
168 bool findCallback(const wxString& name);
169 int callCallback(PyObject* argTuple);
170 PyObject* callCallbackObj(PyObject* argTuple);
171
172 private:
173 PyObject* m_self;
174 PyObject* m_lastFound;
175 };
176
177
178
179 //---------------------------------------------------------------------------
180 // These macros are used to implement the virtual methods that should
181 // redirect to a Python method if one exists. The names designate the
182 // return type, if any as well as any parameter types.
183 //---------------------------------------------------------------------------
184
185 #define PYPRIVATE \
186 void _setSelf(PyObject* self) { \
187 m_myInst.setSelf(self); \
188 } \
189 private: wxPyCallbackHelper m_myInst;
190
191 //---------------------------------------------------------------------------
192
193 #define DEC_PYCALLBACK__(CBNAME) \
194 void CBNAME(); \
195 void base_##CBNAME();
196
197
198 #define IMP_PYCALLBACK__(CLASS, PCLASS, CBNAME) \
199 void CLASS::CBNAME() { \
200 bool doSave = wxPyRestoreThread(); \
201 if (m_myInst.findCallback(#CBNAME)) \
202 m_myInst.callCallback(Py_BuildValue("()")); \
203 else \
204 PCLASS::CBNAME(); \
205 wxPySaveThread(doSave); \
206 } \
207 void CLASS::base_##CBNAME() { \
208 PCLASS::CBNAME(); \
209 }
210
211 //---------------------------------------------------------------------------
212
213 #define DEC_PYCALLBACK_BOOL_INTINT(CBNAME) \
214 bool CBNAME(int a, int b); \
215 bool base_##CBNAME(int a, int b);
216
217
218 #define IMP_PYCALLBACK_BOOL_INTINT(CLASS, PCLASS, CBNAME) \
219 bool CLASS::CBNAME(int a, int b) { \
220 bool rval; \
221 bool doSave = wxPyRestoreThread(); \
222 if (m_myInst.findCallback(#CBNAME)) \
223 rval = m_myInst.callCallback(Py_BuildValue("(ii)",a,b)); \
224 else \
225 rval = PCLASS::CBNAME(a,b); \
226 wxPySaveThread(doSave); \
227 return rval; \
228 } \
229 bool CLASS::base_##CBNAME(int a, int b) { \
230 return PCLASS::CBNAME(a,b); \
231 }
232
233 //---------------------------------------------------------------------------
234
235 #define DEC_PYCALLBACK_BOOL_INT(CBNAME) \
236 bool CBNAME(int a); \
237 bool base_##CBNAME(int a);
238
239
240 #define IMP_PYCALLBACK_BOOL_INT(CLASS, PCLASS, CBNAME) \
241 bool CLASS::CBNAME(int a) { \
242 bool rval; \
243 bool doSave = wxPyRestoreThread(); \
244 if (m_myInst.findCallback(#CBNAME)) \
245 rval = m_myInst.callCallback(Py_BuildValue("(i)",a)); \
246 else \
247 rval = PCLASS::CBNAME(a); \
248 wxPySaveThread(doSave); \
249 return rval; \
250 } \
251 bool CLASS::base_##CBNAME(int a) { \
252 return PCLASS::CBNAME(a); \
253 }
254
255 //---------------------------------------------------------------------------
256
257 #define DEC_PYCALLBACK_BOOL_INT_pure(CBNAME) \
258 bool CBNAME(int a);
259
260
261 #define IMP_PYCALLBACK_BOOL_INT_pure(CLASS, PCLASS, CBNAME) \
262 bool CLASS::CBNAME(int a) { \
263 bool rval; \
264 bool doSave = wxPyRestoreThread(); \
265 if (m_myInst.findCallback(#CBNAME)) \
266 rval = m_myInst.callCallback(Py_BuildValue("(i)",a)); \
267 else rval = false; \
268 wxPySaveThread(doSave); \
269 return rval; \
270 }
271
272
273 //---------------------------------------------------------------------------
274
275 #define DEC_PYCALLBACK__DC(CBNAME) \
276 void CBNAME(wxDC& a); \
277 void base_##CBNAME(wxDC& a);
278
279
280 #define IMP_PYCALLBACK__DC(CLASS, PCLASS, CBNAME) \
281 void CLASS::CBNAME(wxDC& a) { \
282 bool doSave = wxPyRestoreThread(); \
283 if (m_myInst.findCallback(#CBNAME)) \
284 m_myInst.callCallback(Py_BuildValue("(O)", \
285 wxPyConstructObject(&a, "wxDC"))); \
286 else \
287 PCLASS::CBNAME(a); \
288 wxPySaveThread(doSave); \
289 } \
290 void CLASS::base_##CBNAME(wxDC& a) { \
291 PCLASS::CBNAME(a); \
292 }
293
294
295
296 //---------------------------------------------------------------------------
297
298 #define DEC_PYCALLBACK__DCBOOL(CBNAME) \
299 void CBNAME(wxDC& a, bool b); \
300 void base_##CBNAME(wxDC& a, bool b);
301
302
303 #define IMP_PYCALLBACK__DCBOOL(CLASS, PCLASS, CBNAME) \
304 void CLASS::CBNAME(wxDC& a, bool b) { \
305 bool doSave = wxPyRestoreThread(); \
306 if (m_myInst.findCallback(#CBNAME)) \
307 m_myInst.callCallback(Py_BuildValue("(Oi)", \
308 wxPyConstructObject(&a, "wxDC"), (int)b)); \
309 else \
310 PCLASS::CBNAME(a, b); \
311 wxPySaveThread(doSave); \
312 } \
313 void CLASS::base_##CBNAME(wxDC& a, bool b) { \
314 PCLASS::CBNAME(a, b); \
315 }
316
317 //---------------------------------------------------------------------------
318
319 #define DEC_PYCALLBACK__DCBOOL(CBNAME) \
320 void CBNAME(wxDC& a, bool b); \
321 void base_##CBNAME(wxDC& a, bool b);
322
323
324 #define IMP_PYCALLBACK__DCBOOL(CLASS, PCLASS, CBNAME) \
325 void CLASS::CBNAME(wxDC& a, bool b) { \
326 bool doSave = wxPyRestoreThread(); \
327 if (m_myInst.findCallback(#CBNAME)) \
328 m_myInst.callCallback(Py_BuildValue("(Oi)", \
329 wxPyConstructObject(&a, "wxDC"), (int)b)); \
330 else \
331 PCLASS::CBNAME(a, b); \
332 wxPySaveThread(doSave); \
333 } \
334 void CLASS::base_##CBNAME(wxDC& a, bool b) { \
335 PCLASS::CBNAME(a, b); \
336 }
337
338 //---------------------------------------------------------------------------
339
340 #define DEC_PYCALLBACK__2DBL(CBNAME) \
341 void CBNAME(double a, double b); \
342 void base_##CBNAME(double a, double b);
343
344
345 #define IMP_PYCALLBACK__2DBL(CLASS, PCLASS, CBNAME) \
346 void CLASS::CBNAME(double a, double b) { \
347 bool doSave = wxPyRestoreThread(); \
348 if (m_myInst.findCallback(#CBNAME)) \
349 m_myInst.callCallback(Py_BuildValue("(dd)",a,b)); \
350 else \
351 PCLASS::CBNAME(a, b); \
352 wxPySaveThread(doSave); \
353 } \
354 void CLASS::base_##CBNAME(double a, double b) { \
355 PCLASS::CBNAME(a, b); \
356 }
357
358 //---------------------------------------------------------------------------
359
360 #define DEC_PYCALLBACK__2DBL2INT(CBNAME) \
361 void CBNAME(double a, double b, int c, int d); \
362 void base_##CBNAME(double a, double b, int c, int d);
363
364
365 #define IMP_PYCALLBACK__2DBL2INT(CLASS, PCLASS, CBNAME) \
366 void CLASS::CBNAME(double a, double b, int c, int d) { \
367 bool doSave = wxPyRestoreThread(); \
368 if (m_myInst.findCallback(#CBNAME)) \
369 m_myInst.callCallback(Py_BuildValue("(ddii)", \
370 a,b,c,d)); \
371 else \
372 PCLASS::CBNAME(a, b, c, d); \
373 wxPySaveThread(doSave); \
374 } \
375 void CLASS::base_##CBNAME(double a, double b, int c, int d) { \
376 PCLASS::CBNAME(a, b, c, d); \
377 }
378
379 //---------------------------------------------------------------------------
380
381 #define DEC_PYCALLBACK__DC4DBLBOOL(CBNAME) \
382 void CBNAME(wxDC& a, double b, double c, double d, double e, bool f); \
383 void base_##CBNAME(wxDC& a, double b, double c, double d, double e, bool f);
384
385
386 #define IMP_PYCALLBACK__DC4DBLBOOL(CLASS, PCLASS, CBNAME) \
387 void CLASS::CBNAME(wxDC& a, double b, double c, double d, double e, bool f) { \
388 bool doSave = wxPyRestoreThread(); \
389 if (m_myInst.findCallback(#CBNAME)) \
390 m_myInst.callCallback(Py_BuildValue("(Oddddi)", \
391 wxPyConstructObject(&a, "wxDC"), \
392 b, c, d, e, (int)f)); \
393 else \
394 PCLASS::CBNAME(a, b, c, d, e, f); \
395 wxPySaveThread(doSave); \
396 } \
397 void CLASS::base_##CBNAME(wxDC& a, double b, double c, double d, double e, bool f) {\
398 PCLASS::CBNAME(a, b, c, d, e, f); \
399 }
400
401 //---------------------------------------------------------------------------
402
403 #define DEC_PYCALLBACK_BOOL_DC4DBLBOOL(CBNAME) \
404 bool CBNAME(wxDC& a, double b, double c, double d, double e, bool f); \
405 bool base_##CBNAME(wxDC& a, double b, double c, double d, double e, bool f);
406
407
408 #define IMP_PYCALLBACK_BOOL_DC4DBLBOOL(CLASS, PCLASS, CBNAME) \
409 bool CLASS::CBNAME(wxDC& a, double b, double c, double d, double e, bool f) { \
410 bool doSave = wxPyRestoreThread(); \
411 if (m_myInst.findCallback(#CBNAME)) \
412 return m_myInst.callCallback(Py_BuildValue("(Oddddi)", \
413 wxPyConstructObject(&a, "wxDC"), \
414 b, c, d, e, (int)f)); \
415 else \
416 return PCLASS::CBNAME(a, b, c, d, e, f); \
417 wxPySaveThread(doSave); \
418 } \
419 bool CLASS::base_##CBNAME(wxDC& a, double b, double c, double d, double e, bool f) {\
420 return PCLASS::CBNAME(a, b, c, d, e, f); \
421 }
422
423 //---------------------------------------------------------------------------
424
425 #define DEC_PYCALLBACK__BOOL2DBL2INT(CBNAME) \
426 void CBNAME(bool a, double b, double c, int d, int e); \
427 void base_##CBNAME(bool a, double b, double c, int d, int e);
428
429
430 #define IMP_PYCALLBACK__BOOL2DBL2INT(CLASS, PCLASS, CBNAME) \
431 void CLASS::CBNAME(bool a, double b, double c, int d, int e) { \
432 bool doSave = wxPyRestoreThread(); \
433 if (m_myInst.findCallback(#CBNAME)) \
434 m_myInst.callCallback(Py_BuildValue("(idii)", \
435 (int)a,b,c,d,e)); \
436 else \
437 PCLASS::CBNAME(a, b, c, d, e); \
438 wxPySaveThread(doSave); \
439 } \
440 void CLASS::base_##CBNAME(bool a, double b, double c, int d, int e) { \
441 PCLASS::CBNAME(a, b, c, d, e); \
442 }
443
444 //---------------------------------------------------------------------------
445
446 #define DEC_PYCALLBACK__DC4DBL(CBNAME) \
447 void CBNAME(wxDC& a, double b, double c, double d, double e); \
448 void base_##CBNAME(wxDC& a, double b, double c, double d, double e);
449
450
451 #define IMP_PYCALLBACK__DC4DBL(CLASS, PCLASS, CBNAME) \
452 void CLASS::CBNAME(wxDC& a, double b, double c, double d, double e) { \
453 bool doSave = wxPyRestoreThread(); \
454 if (m_myInst.findCallback(#CBNAME)) \
455 m_myInst.callCallback(Py_BuildValue("(Odddd)", \
456 wxPyConstructObject(&a, "wxDC"), \
457 b, c, d, e)); \
458 else \
459 PCLASS::CBNAME(a, b, c, d, e); \
460 wxPySaveThread(doSave); \
461 } \
462 void CLASS::base_##CBNAME(wxDC& a, double b, double c, double d, double e) {\
463 PCLASS::CBNAME(a, b, c, d, e); \
464 }
465
466 //---------------------------------------------------------------------------
467
468 #define DEC_PYCALLBACK__DCBOOL(CBNAME) \
469 void CBNAME(wxDC& a, bool b); \
470 void base_##CBNAME(wxDC& a, bool b);
471
472
473 #define IMP_PYCALLBACK__DCBOOL(CLASS, PCLASS, CBNAME) \
474 void CLASS::CBNAME(wxDC& a, bool b) { \
475 bool doSave = wxPyRestoreThread(); \
476 if (m_myInst.findCallback(#CBNAME)) \
477 m_myInst.callCallback(Py_BuildValue("(Oi)", \
478 wxPyConstructObject(&a, "wxDC"), \
479 (int)b)); \
480 else \
481 PCLASS::CBNAME(a, b); \
482 wxPySaveThread(doSave); \
483 } \
484 void CLASS::base_##CBNAME(wxDC& a, bool b) { \
485 PCLASS::CBNAME(a, b); \
486 }
487
488 //---------------------------------------------------------------------------
489
490 #define DEC_PYCALLBACK__WXCPBOOL2DBL2INT(CBNAME) \
491 void CBNAME(wxControlPoint* a, bool b, double c, double d, int e, int f); \
492 void base_##CBNAME(wxControlPoint* a, bool b, double c, double d, int e, int f);
493
494
495 #define IMP_PYCALLBACK__WXCPBOOL2DBL2INT(CLASS, PCLASS, CBNAME) \
496 void CLASS::CBNAME(wxControlPoint* a, bool b, double c, double d, \
497 int e, int f) { \
498 bool doSave = wxPyRestoreThread(); \
499 if (m_myInst.findCallback(#CBNAME)) \
500 m_myInst.callCallback(Py_BuildValue("(Oiddii)", \
501 wxPyConstructObject(a, "wxControlPoint"), \
502 (int)b, c, d, e, f)); \
503 else \
504 PCLASS::CBNAME(a, b, c, d, e, f); \
505 wxPySaveThread(doSave); \
506 } \
507 void CLASS::base_##CBNAME(wxControlPoint* a, bool b, double c, double d, \
508 int e, int f) { \
509 PCLASS::CBNAME(a, b, c, d, e, f); \
510 }
511
512 //---------------------------------------------------------------------------
513
514 #define DEC_PYCALLBACK__WXCP2DBL2INT(CBNAME) \
515 void CBNAME(wxControlPoint* a, double b, double c, int d, int e); \
516 void base_##CBNAME(wxControlPoint* a, double b, double c, int d, int e);
517
518
519 #define IMP_PYCALLBACK__WXCP2DBL2INT(CLASS, PCLASS, CBNAME) \
520 void CLASS::CBNAME(wxControlPoint* a, double b, double c, int d, int e) { \
521 bool doSave = wxPyRestoreThread(); \
522 if (m_myInst.findCallback(#CBNAME)) \
523 m_myInst.callCallback(Py_BuildValue("(Oddii)", \
524 wxPyConstructObject(a, "wxControlPoint"), \
525 b, c, d, e)); \
526 else \
527 PCLASS::CBNAME(a, b, c, d, e); \
528 wxPySaveThread(doSave); \
529 } \
530 void CLASS::base_##CBNAME(wxControlPoint* a, double b, double c, \
531 int d, int e) { \
532 PCLASS::CBNAME(a, b, c, d, e); \
533 }
534
535 //---------------------------------------------------------------------------
536
537 #define DEC_PYCALLBACK__2DBLINT(CBNAME) \
538 void CBNAME(double a, double b, int c); \
539 void base_##CBNAME(double a, double b, int c);
540
541
542 #define IMP_PYCALLBACK__2DBLINT(CLASS, PCLASS, CBNAME) \
543 void CLASS::CBNAME(double a, double b, int c) { \
544 bool doSave = wxPyRestoreThread(); \
545 if (m_myInst.findCallback(#CBNAME)) \
546 m_myInst.callCallback(Py_BuildValue("(ddi)", a,b,c)); \
547 else \
548 PCLASS::CBNAME(a, b, c); \
549 wxPySaveThread(doSave); \
550 } \
551 void CLASS::base_##CBNAME(double a, double b, int c) { \
552 PCLASS::CBNAME(a, b, c); \
553 }
554
555 //---------------------------------------------------------------------------
556
557 #define DEC_PYCALLBACK__BOOL2DBLINT(CBNAME) \
558 void CBNAME(bool a, double b, double c, int d); \
559 void base_##CBNAME(bool a, double b, double c, int d);
560
561
562 #define IMP_PYCALLBACK__BOOL2DBLINT(CLASS, PCLASS, CBNAME) \
563 void CLASS::CBNAME(bool a, double b, double c, int d) { \
564 bool doSave = wxPyRestoreThread(); \
565 if (m_myInst.findCallback(#CBNAME)) \
566 m_myInst.callCallback(Py_BuildValue("(iddi)", (int)a,b,c,d)); \
567 else \
568 PCLASS::CBNAME(a, b, c, d); \
569 wxPySaveThread(doSave); \
570 } \
571 void CLASS::base_##CBNAME(bool a, double b, double c, int d) { \
572 PCLASS::CBNAME(a, b, c, d); \
573 }
574
575 //---------------------------------------------------------------------------
576 //---------------------------------------------------------------------------
577 //---------------------------------------------------------------------------
578 //---------------------------------------------------------------------------
579
580 #endif
581
582
583