From 57ffa5851d26ec3b2aa16b6f3d6713fbeb8b897b Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Thu, 4 May 2006 02:03:39 +0000 Subject: [PATCH] Redo (again) how the stock objects are initialized in wxPython. Factor out the wxPyTwoIntItem_helper template function so it can be used in other extension modules. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@39008 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- wxPython/include/wx/wxPython/twoitem.h | 52 +++++++ wxPython/include/wx/wxPython/wxPython_int.h | 35 ----- wxPython/src/_app_ex.py | 9 ++ wxPython/src/_stockobjs.i | 160 ++++++++------------ wxPython/src/core.i | 1 + wxPython/src/helpers.cpp | 14 +- 6 files changed, 139 insertions(+), 132 deletions(-) create mode 100644 wxPython/include/wx/wxPython/twoitem.h diff --git a/wxPython/include/wx/wxPython/twoitem.h b/wxPython/include/wx/wxPython/twoitem.h new file mode 100644 index 0000000000..eebf28221e --- /dev/null +++ b/wxPython/include/wx/wxPython/twoitem.h @@ -0,0 +1,52 @@ +//////////////////////////////////////////////////////////////////////////// +// Name: twoitem.h +// Purpose: A template function to help with converting a python object +// to some wx class that takes two integer value parameters. +// Factored out of wxPython_int.h +// +// Author: Robin Dunn +// +// Created: 25-April-2006 +// RCS-ID: $Id$ +// Copyright: (c) 2006 by Total Control Software +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __twoitem_h__ +#define __twoitem_h__ + +template +bool wxPyTwoIntItem_helper(PyObject* source, T** obj, const wxChar* name) +{ + // If source is an object instance then it may already be the right type + if (wxPySwigInstance_Check(source)) { + T* ptr; + if (! wxPyConvertSwigPtr(source, (void **)&ptr, name)) + goto error; + *obj = ptr; + return true; + } + // otherwise a 2-tuple of integers is expected + else if (PySequence_Check(source) && PyObject_Length(source) == 2) { + PyObject* o1 = PySequence_GetItem(source, 0); + PyObject* o2 = PySequence_GetItem(source, 1); + if (!PyNumber_Check(o1) || !PyNumber_Check(o2)) { + Py_DECREF(o1); + Py_DECREF(o2); + goto error; + } + **obj = T(PyInt_AsLong(o1), PyInt_AsLong(o2)); + Py_DECREF(o1); + Py_DECREF(o2); + return true; + } + + error: + wxString msg; + msg.Printf(wxT("Expected a 2-tuple of integers or a %s object."), name); + PyErr_SetString(PyExc_TypeError, msg.mb_str()); + return false; +} + + +#endif diff --git a/wxPython/include/wx/wxPython/wxPython_int.h b/wxPython/include/wx/wxPython/wxPython_int.h index c0754621fa..74c15c9e6a 100644 --- a/wxPython/include/wx/wxPython/wxPython_int.h +++ b/wxPython/include/wx/wxPython/wxPython_int.h @@ -226,41 +226,6 @@ bool wxColour_typecheck(PyObject* source); bool wxPyCheckForApp(); - -template -bool wxPyTwoIntItem_helper(PyObject* source, T** obj, const wxChar* name) -{ - // If source is an object instance then it may already be the right type - if (wxPySwigInstance_Check(source)) { - T* ptr; - if (! wxPyConvertSwigPtr(source, (void **)&ptr, name)) - goto error; - *obj = ptr; - return true; - } - // otherwise a 2-tuple of integers is expected - else if (PySequence_Check(source) && PyObject_Length(source) == 2) { - PyObject* o1 = PySequence_GetItem(source, 0); - PyObject* o2 = PySequence_GetItem(source, 1); - if (!PyNumber_Check(o1) || !PyNumber_Check(o2)) { - Py_DECREF(o1); - Py_DECREF(o2); - goto error; - } - **obj = T(PyInt_AsLong(o1), PyInt_AsLong(o2)); - Py_DECREF(o1); - Py_DECREF(o2); - return true; - } - - error: - wxString msg; - msg.Printf(wxT("Expected a 2-tuple of integers or a %s object."), name); - PyErr_SetString(PyExc_TypeError, msg.mb_str()); - return false; -} - - // Other helpful stuff bool wxPy2int_seq_helper(PyObject* source, int* i1, int* i2); diff --git a/wxPython/src/_app_ex.py b/wxPython/src/_app_ex.py index f08eef9f41..60ee313fea 100644 --- a/wxPython/src/_app_ex.py +++ b/wxPython/src/_app_ex.py @@ -173,6 +173,15 @@ your Mac.""" self._BootstrapApp() + def OnPreInit(self): + """ + Things that must be done after _BootstrapApp has done its + thing, but would be nice if they were already done by the time + that OnInit is called. + """ + wx.StockGDI._initStockObjects() + + def __del__(self, destroy=wx.PyApp.__del__): self.RestoreStdio() # Just in case the MainLoop was overridden destroy(self) diff --git a/wxPython/src/_stockobjs.i b/wxPython/src/_stockobjs.i index 08a5956c28..158ee436ce 100644 --- a/wxPython/src/_stockobjs.i +++ b/wxPython/src/_stockobjs.i @@ -70,82 +70,54 @@ public: static const wxPen* GetPen(Item item); virtual const wxFont* GetFont(Item item); + + %pythoncode { + def _initStockObjects(): + import wx + wx.ITALIC_FONT = StockGDI.instance().GetFont(StockGDI.FONT_ITALIC) + wx.NORMAL_FONT = StockGDI.instance().GetFont(StockGDI.FONT_NORMAL) + wx.SMALL_FONT = StockGDI.instance().GetFont(StockGDI.FONT_SMALL) + wx.SWISS_FONT = StockGDI.instance().GetFont(StockGDI.FONT_SWISS) + + wx.BLACK_DASHED_PEN = StockGDI.GetPen(StockGDI.PEN_BLACKDASHED) + wx.BLACK_PEN = StockGDI.GetPen(StockGDI.PEN_BLACK) + wx.CYAN_PEN = StockGDI.GetPen(StockGDI.PEN_CYAN) + wx.GREEN_PEN = StockGDI.GetPen(StockGDI.PEN_GREEN) + wx.GREY_PEN = StockGDI.GetPen(StockGDI.PEN_GREY) + wx.LIGHT_GREY_PEN = StockGDI.GetPen(StockGDI.PEN_LIGHTGREY) + wx.MEDIUM_GREY_PEN = StockGDI.GetPen(StockGDI.PEN_MEDIUMGREY) + wx.RED_PEN = StockGDI.GetPen(StockGDI.PEN_RED) + wx.TRANSPARENT_PEN = StockGDI.GetPen(StockGDI.PEN_TRANSPARENT) + wx.WHITE_PEN = StockGDI.GetPen(StockGDI.PEN_WHITE) + + wx.BLACK_BRUSH = StockGDI.GetBrush(StockGDI.BRUSH_BLACK) + wx.BLUE_BRUSH = StockGDI.GetBrush(StockGDI.BRUSH_BLUE) + wx.CYAN_BRUSH = StockGDI.GetBrush(StockGDI.BRUSH_CYAN) + wx.GREEN_BRUSH = StockGDI.GetBrush(StockGDI.BRUSH_GREEN) + wx.GREY_BRUSH = StockGDI.GetBrush(StockGDI.BRUSH_GREY) + wx.LIGHT_GREY_BRUSH = StockGDI.GetBrush(StockGDI.BRUSH_LIGHTGREY) + wx.MEDIUM_GREY_BRUSH = StockGDI.GetBrush(StockGDI.BRUSH_MEDIUMGREY) + wx.RED_BRUSH = StockGDI.GetBrush(StockGDI.BRUSH_RED) + wx.TRANSPARENT_BRUSH = StockGDI.GetBrush(StockGDI.BRUSH_TRANSPARENT) + wx.WHITE_BRUSH = StockGDI.GetBrush(StockGDI.BRUSH_WHITE) + + wx.BLACK = StockGDI.GetColour(StockGDI.COLOUR_BLACK) + wx.BLUE = StockGDI.GetColour(StockGDI.COLOUR_BLUE) + wx.CYAN = StockGDI.GetColour(StockGDI.COLOUR_CYAN) + wx.GREEN = StockGDI.GetColour(StockGDI.COLOUR_GREEN) + wx.LIGHT_GREY = StockGDI.GetColour(StockGDI.COLOUR_LIGHTGREY) + wx.RED = StockGDI.GetColour(StockGDI.COLOUR_RED) + wx.WHITE = StockGDI.GetColour(StockGDI.COLOUR_WHITE) + + wx.CROSS_CURSOR = StockGDI.GetCursor(StockGDI.CURSOR_CROSS) + wx.HOURGLASS_CURSOR = StockGDI.GetCursor(StockGDI.CURSOR_HOURGLASS) + wx.STANDARD_CURSOR = StockGDI.GetCursor(StockGDI.CURSOR_STANDARD) + + _initStockObjects = staticmethod(_initStockObjects) + } }; -%pythoncode { -%# This function makes a class used to do delayed initialization of some -%# stock wx objects. When they are used the first time then an init function -%# is called to make the real instance, which is then used to replace the -%# original instance and class seen by the programmer. -def _wxPyMakeDelayedInitWrapper(initFunc): - class _wxPyStockObjectWrapper(object): - def __init__(self, *args): - self._args = args - def __getattr__(self, name): - obj = initFunc(*self._args) - self.__class__ = obj.__class__ - self.__dict__ = obj.__dict__ - return getattr(self, name) - def __str__(self): - return self.__getattr__("__str__")() - def __repr__(self): - return self.__getattr__("__repr__")() - return _wxPyStockObjectWrapper - -def _wxPyFontInit(id): - return StockGDI.instance().GetFont(id) - -_wxPyStockPen = _wxPyMakeDelayedInitWrapper(StockGDI.GetPen) -_wxPyStockBrush = _wxPyMakeDelayedInitWrapper(StockGDI.GetBrush) -_wxPyStockCursor = _wxPyMakeDelayedInitWrapper(StockGDI.GetCursor) -_wxPyStockColour = _wxPyMakeDelayedInitWrapper(StockGDI.GetColour) -_wxPyStockFont = _wxPyMakeDelayedInitWrapper(_wxPyFontInit) - - -ITALIC_FONT = _wxPyStockCursor(StockGDI.FONT_ITALIC) -NORMAL_FONT = _wxPyStockCursor(StockGDI.FONT_NORMAL) -SMALL_FONT = _wxPyStockCursor(StockGDI.FONT_SMALL) -SWISS_FONT = _wxPyStockCursor(StockGDI.FONT_SWISS) - -BLACK_DASHED_PEN = _wxPyStockPen(StockGDI.PEN_BLACKDASHED) -BLACK_PEN = _wxPyStockPen(StockGDI.PEN_BLACK) -CYAN_PEN = _wxPyStockPen(StockGDI.PEN_CYAN) -GREEN_PEN = _wxPyStockPen(StockGDI.PEN_GREEN) -GREY_PEN = _wxPyStockPen(StockGDI.PEN_GREY) -LIGHT_GREY_PEN = _wxPyStockPen(StockGDI.PEN_LIGHTGREY) -MEDIUM_GREY_PEN = _wxPyStockPen(StockGDI.PEN_MEDIUMGREY) -RED_PEN = _wxPyStockPen(StockGDI.PEN_RED) -TRANSPARENT_PEN = _wxPyStockPen(StockGDI.PEN_TRANSPARENT) -WHITE_PEN = _wxPyStockPen(StockGDI.PEN_WHITE) - -BLACK_BRUSH = _wxPyStockBrush(StockGDI.BRUSH_BLACK) -BLUE_BRUSH = _wxPyStockBrush(StockGDI.BRUSH_BLUE) -CYAN_BRUSH = _wxPyStockBrush(StockGDI.BRUSH_CYAN) -GREEN_BRUSH = _wxPyStockBrush(StockGDI.BRUSH_GREEN) -GREY_BRUSH = _wxPyStockBrush(StockGDI.BRUSH_GREY) -LIGHT_GREY_BRUSH = _wxPyStockBrush(StockGDI.BRUSH_LIGHTGREY) -MEDIUM_GREY_BRUSH = _wxPyStockBrush(StockGDI.BRUSH_MEDIUMGREY) -RED_BRUSH = _wxPyStockBrush(StockGDI.BRUSH_RED) -TRANSPARENT_BRUSH = _wxPyStockBrush(StockGDI.BRUSH_TRANSPARENT) -WHITE_BRUSH = _wxPyStockBrush(StockGDI.BRUSH_WHITE) - -BLACK = _wxPyStockColour(StockGDI.COLOUR_BLACK) -BLUE = _wxPyStockColour(StockGDI.COLOUR_BLUE) -CYAN = _wxPyStockColour(StockGDI.COLOUR_CYAN) -GREEN = _wxPyStockColour(StockGDI.COLOUR_GREEN) -LIGHT_GREY = _wxPyStockColour(StockGDI.COLOUR_LIGHTGREY) -RED = _wxPyStockColour(StockGDI.COLOUR_RED) -WHITE = _wxPyStockColour(StockGDI.COLOUR_WHITE) - -CROSS_CURSOR = _wxPyStockCursor(StockGDI.CURSOR_CROSS) -HOURGLASS_CURSOR = _wxPyStockCursor(StockGDI.CURSOR_HOURGLASS) -STANDARD_CURSOR = _wxPyStockCursor(StockGDI.CURSOR_STANDARD) - -} - - - %immutable; %threadWrapperOff; @@ -163,29 +135,6 @@ const wxColour wxNullColour; %mutable; -// %inline { -// const wxBitmap& _wxPyInitNullBitmap() { return wxNullBitmap; } -// const wxIcon& _wxPyInitNullIcon() { return wxNullIcon; } -// const wxCursor& _wxPyInitNullCursor() { return wxNullCursor; } -// const wxPen& _wxPyInitNullPen() { return wxNullPen; } -// const wxBrush& _wxPyInitNullBrush() { return wxNullBrush; } -// const wxPalette& _wxPyInitNullPalette() { return wxNullPalette; } -// const wxFont& _wxPyInitNullFont() { return wxNullFont; } -// const wxColour& _wxPyInitNullColour() { return wxNullColour; } -// } - -// %pythoncode { -// NullBitmap = _wxPyMakeDelayedInitWrapper(_wxPyInitNullBitmap)() -// NullIcon = _wxPyMakeDelayedInitWrapper(_wxPyInitNullIcon)() -// NullCursor = _wxPyMakeDelayedInitWrapper(_wxPyInitNullCursor)() -// NullPen = _wxPyMakeDelayedInitWrapper(_wxPyInitNullPen)() -// NullBrush = _wxPyMakeDelayedInitWrapper(_wxPyInitNullBrush)() -// NullPalette = _wxPyMakeDelayedInitWrapper(_wxPyInitNullPalette)() -// NullFont = _wxPyMakeDelayedInitWrapper(_wxPyInitNullFont)() -// NullColour = _wxPyMakeDelayedInitWrapper(_wxPyInitNullColour)() -// } - - //--------------------------------------------------------------------------- @@ -280,6 +229,25 @@ public: } %pythoncode { +%# This function makes a class used to do delayed initialization of some +%# stock wx objects. When they are used the first time then an init function +%# is called to make the real instance, which is then used to replace the +%# original instance and class seen by the programmer. +def _wxPyMakeDelayedInitWrapper(initFunc): + class _wxPyStockObjectWrapper(object): + def __init__(self, *args): + self._args = args + def __getattr__(self, name): + obj = initFunc(*self._args) + self.__class__ = obj.__class__ + self.__dict__ = obj.__dict__ + return getattr(self, name) + def __str__(self): + return self.__getattr__("__str__")() + def __repr__(self): + return self.__getattr__("__repr__")() + return _wxPyStockObjectWrapper + wxTheFontList = _wxPyMakeDelayedInitWrapper(_wxPyInitTheFontList)() wxThePenList = _wxPyMakeDelayedInitWrapper(_wxPyInitThePenList)() wxTheBrushList = _wxPyMakeDelayedInitWrapper(_wxPyInitTheBrushList)() diff --git a/wxPython/src/core.i b/wxPython/src/core.i index c86b6fd9b0..729240def6 100644 --- a/wxPython/src/core.i +++ b/wxPython/src/core.i @@ -15,6 +15,7 @@ %{ #include "wx/wxPython/wxPython_int.h" #include "wx/wxPython/pyclasses.h" +#include "wx/wxPython/twoitem.h" %} diff --git a/wxPython/src/helpers.cpp b/wxPython/src/helpers.cpp index f45bafc9bb..572ada736f 100644 --- a/wxPython/src/helpers.cpp +++ b/wxPython/src/helpers.cpp @@ -16,6 +16,7 @@ #include "wx/wxPython/wxPython_int.h" #include "wx/wxPython/pyistream.h" #include "wx/wxPython/swigver.h" +#include "wx/wxPython/twoitem.h" #ifdef __WXMSW__ #include @@ -469,8 +470,19 @@ void wxPyApp::_BootstrapApp() // It's now ok to generate exceptions for assertion errors. wxPythonApp->SetStartupComplete(true); - // Call the Python wxApp's OnInit function + + // Call the Python wxApp's OnPreInit and OnInit functions blocked = wxPyBeginBlockThreads(); + if (wxPyCBH_findCallback(m_myInst, "OnPreInit")) { + PyObject* method = m_myInst.GetLastFound(); + PyObject* argTuple = PyTuple_New(0); + retval = PyEval_CallObject(method, argTuple); + m_myInst.clearRecursionGuard(method); + Py_DECREF(argTuple); + Py_DECREF(method); + if (retval == NULL) + goto error; + } if (wxPyCBH_findCallback(m_myInst, "OnInit")) { PyObject* method = m_myInst.GetLastFound();