Added wxClientDataContainer to wxSizer, so sizers can now do OOR in
authorRobin Dunn <robin@alldunn.com>
Sun, 21 Oct 2001 03:56:07 +0000 (03:56 +0000)
committerRobin Dunn <robin@alldunn.com>
Sun, 21 Oct 2001 03:56:07 +0000 (03:56 +0000)
wxPython too.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@12130 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/clntdata.h
include/wx/sizer.h
src/common/clntdata.cpp
wxPython/demo/OOR.py
wxPython/src/_extras.py
wxPython/src/helpers.cpp
wxPython/src/msw/sizers.cpp
wxPython/src/msw/sizers.py
wxPython/src/msw/wx.py
wxPython/src/sizers.i

index 8f2d44ded5537c34a8f7ec872e1f5e02005bf0e8..a632635ad80d9e91975920370f6d8d46d607ff2f 100644 (file)
@@ -50,12 +50,14 @@ private:
 
 
 
-#if 0
 // This class is a mixin that provides storage and management of "client
 // data."  The client data stored can either be a pointer to a wxClientData
 // object in which case it is managed by the container (i.e.  it will delete
 // the data when it's destroyed) or an untyped pointer which won't be deleted
-// by the window - but not both of them
+// by the container - but not both of them
+//
+// NOTE:  This functionality is currently duplicated in wxEvtHandler in order
+//        to avoid having more than one vtable in that class heirachy.
 
 class WXDLLEXPORT wxClientDataContainer
 {
@@ -92,7 +94,7 @@ protected:
     wxClientDataType m_clientDataType;
 
 };
-#endif
+
 // ----------------------------------------------------------------------------
 #endif
 
index bcdeb0339c3e1c873a8b6ad2126121badc321ff1..ccfb67985b4218f812bda27c0be52275794e93a0 100644 (file)
@@ -61,15 +61,15 @@ public:
         { m_ratio = (width && height) ? ((float) width / (float) height) : 1; }
     void SetRatio( wxSize size )
         { m_ratio = (size.x && size.y) ? ((float) size.x / (float) size.y) : 1; }
-    void SetRatio( float ratio ) 
+    void SetRatio( float ratio )
         { m_ratio = ratio; }
-    float GetRatio() const 
+    float GetRatio() const
         { return m_ratio; }
 
     bool IsWindow();
     bool IsSizer();
     bool IsSpacer();
-  
+
     void SetInitSize( int x, int y )
         { m_minSize.x = x; m_minSize.y = y; }
     void SetOption( int option )
@@ -112,7 +112,7 @@ protected:
     //      is shrinked.  it is safer to preserve initial value.
     float        m_ratio;
     wxObject    *m_userData;
-  
+
 private:
     DECLARE_CLASS(wxSizerItem);
 };
@@ -121,7 +121,7 @@ private:
 // wxSizer
 //---------------------------------------------------------------------------
 
-class WXDLLEXPORT wxSizer: public wxObject
+class WXDLLEXPORT wxSizer: public wxObject, public wxClientDataContainer
 {
 public:
     wxSizer();
index d7a984d672a0da6b6ba901173ca195c82ffccb8a..782f51846544b61974ca1486277127c4ccd45779 100644 (file)
@@ -24,7 +24,7 @@
 
 
 // ----------------------------------------------------------------------------
-#if 0
+
 
 wxClientDataContainer::wxClientDataContainer()
 {
@@ -81,7 +81,7 @@ void *wxClientDataContainer::DoGetClientData() const
     return m_clientData;
 }
 
-#endif
+
 // ----------------------------------------------------------------------------
 
 
index 7306ed9efd7b8c0e6f9591f00b7f83165bf0f15d..9b4088fb8d82376664764b43a59b876a900c5977 100644 (file)
@@ -32,6 +32,8 @@ class TestPanel(wxPanel):
         self.SetSizer(sizer)
         self.SetAutoLayout(true)
 
+        self.sizer = sizer  # save it for testing later
+
         EVT_BUTTON(self, BTN1, self.OnFindButton1)
         EVT_BUTTON(self, BTN2, self.OnFindButton2)
 
@@ -68,6 +70,15 @@ class TestPanel(wxPanel):
         else:
             self.log.write("The objects are NOT the same! <frown>\n")
 
+        sizer = self.GetSizer()
+        if sizer is None:
+            self.log.write("***** OOPS! None returned...\n")
+            return
+        if sizer is self.sizer:
+            self.log.write("The objects are the same! <grin>\n")
+        else:
+            self.log.write("The objects are NOT the same! <frown>\n")
+
 
 #----------------------------------------------------------------------
 
index cc7b8ce623340f03fc75a88550e92e02ca57a587..0e8da6d20e07f1ba6358c4c538d2a7f6b80a253a 100644 (file)
@@ -637,7 +637,8 @@ def wxPyTypeCast(obj, typeStr):
     theClass = globals()[typeStr+"Ptr"]
     typeStr = __wxPyPtrTypeMap.get(typeStr, typeStr)
     if hasattr(obj, "this"):
-        if obj.__class__ is theClass:   # if already the right type then just return it
+        # if already the right type then just return it
+        if isinstance(obj, theClass) or obj.__class__ is theClass:
             return obj
         newPtr = ptrcast(obj.this, typeStr+"_p")
     else:
index e4c6354b20035cb3741b7c88652ca90145e4e8c6..95c921d17b63934c0d0356ead8a0d27745de80f5 100644 (file)
@@ -294,6 +294,8 @@ PyObject*  wxPyMake_wxObject(wxObject* source) {
     bool      isEvtHandler = FALSE;
 
     if (source) {
+        // If it's derived from wxEvtHandler then there may
+        // already be a pointer to a Python objec that we can use.
         if (wxIsKindOf(source, wxEvtHandler)) {
             wxEvtHandler* eh = (wxEvtHandler*)source;
             wxPyClientData* data = (wxPyClientData*)eh->GetClientObject();
@@ -302,8 +304,19 @@ PyObject*  wxPyMake_wxObject(wxObject* source) {
                 Py_INCREF(target);
             }
         }
+        else if (wxIsKindOf(source, wxSizer)) {
+            // wxSizers also track the original object
+            wxSizer* sz = (wxSizer*)source;
+            wxPyClientData* data = (wxPyClientData*)sz->GetClientObject();
+            if (data) {
+                target = data->m_obj;
+                Py_INCREF(target);
+            }
+        }
 
         if (! target) {
+            // Otherwise make it the old fashioned way by making a
+            // new shadow object and putting this pointer in it.
             wxClassInfo* info = source->GetClassInfo();
             wxChar*      name = (wxChar*)info->GetClassName();
             PyObject*    klass = wxPyClassExists(name);
@@ -391,42 +404,6 @@ PyObject* wxPyConstructObject(void* ptr,
 
 //---------------------------------------------------------------------------
 
-//  static PyThreadState* myPyThreadState_Get() {
-//      PyThreadState* current;
-//      current = PyThreadState_Swap(NULL);
-//      PyThreadState_Swap(current);
-//      return current;
-//  }
-
-
-//  bool wxPyRestoreThread() {
-//      // NOTE: The Python API docs state that if a thread already has the
-//      // interpreter lock and calls PyEval_RestoreThread again a deadlock
-//      // occurs, so I put in this code as a guard condition since there are
-//      // many possibilites for nested events and callbacks in wxPython.  If
-//      // The current thread is our thread, then we can assume that we
-//      // already have the lock.  (I hope!)
-//      //
-//  #ifdef WXP_WITH_THREAD
-//      if (wxPyEventThreadState != myPyThreadState_Get()) {
-//          PyEval_AcquireThread(wxPyEventThreadState);
-//          return TRUE;
-//      }
-//      else
-//  #endif
-//          return FALSE;
-//  }
-
-
-//  void wxPySaveThread(bool doSave) {
-//  #ifdef WXP_WITH_THREAD
-//      if (doSave) {
-//          PyEval_ReleaseThread(wxPyEventThreadState);
-//      }
-//  #endif
-//  }
-
-
 
 wxPyTState* wxPyBeginBlockThreads() {
     wxPyTState* state = NULL;
@@ -619,7 +596,7 @@ void wxPyCBH_delete(wxPyCallbackHelper* cbh) {
 
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
-// These classes can be derived from in Python and passed through the event
+// These event classes can be derived from in Python and passed through the event
 // system without losing anything.  They do this by keeping a reference to
 // themselves and some special case handling in wxPyCallback::EventThunker.
 
index 1460f4f14c849428c0921df7feb637112c17157b..5690d72d711c2a87a226465ccbc9070bb1d05c05 100644 (file)
@@ -837,6 +837,41 @@ static void *SwigwxSizerTowxObject(void *ptr) {
     return (void *) dest;
 }
 
+static void  wxSizer__setOORInfo(wxSizer *self,PyObject * _self) {
+            self->SetClientObject(new wxPyClientData(_self));
+        }
+static PyObject *_wrap_wxSizer__setOORInfo(PyObject *self, PyObject *args, PyObject *kwargs) {
+    PyObject * _resultobj;
+    wxSizer * _arg0;
+    PyObject * _arg1;
+    PyObject * _argo0 = 0;
+    PyObject * _obj1 = 0;
+    char *_kwnames[] = { "self","_self", NULL };
+
+    self = self;
+    if(!PyArg_ParseTupleAndKeywords(args,kwargs,"OO:wxSizer__setOORInfo",_kwnames,&_argo0,&_obj1)) 
+        return NULL;
+    if (_argo0) {
+        if (_argo0 == Py_None) { _arg0 = NULL; }
+        else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxSizer_p")) {
+            PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxSizer__setOORInfo. Expected _wxSizer_p.");
+        return NULL;
+        }
+    }
+{
+  _arg1 = _obj1;
+}
+{
+    wxPy_BEGIN_ALLOW_THREADS;
+        wxSizer__setOORInfo(_arg0,_arg1);
+
+    wxPy_END_ALLOW_THREADS;
+    if (PyErr_Occurred()) return NULL;
+}    Py_INCREF(Py_None);
+    _resultobj = Py_None;
+    return _resultobj;
+}
+
 static void  wxSizer_Destroy(wxSizer *self) { delete self; }
 static PyObject *_wrap_wxSizer_Destroy(PyObject *self, PyObject *args, PyObject *kwargs) {
     PyObject * _resultobj;
@@ -2912,6 +2947,7 @@ static PyMethodDef sizerscMethods[] = {
         { "wxSizer_AddSizer", (PyCFunction) _wrap_wxSizer_AddSizer, METH_VARARGS | METH_KEYWORDS },
         { "wxSizer_AddWindow", (PyCFunction) _wrap_wxSizer_AddWindow, METH_VARARGS | METH_KEYWORDS },
         { "wxSizer_Destroy", (PyCFunction) _wrap_wxSizer_Destroy, METH_VARARGS | METH_KEYWORDS },
+        { "wxSizer__setOORInfo", (PyCFunction) _wrap_wxSizer__setOORInfo, METH_VARARGS | METH_KEYWORDS },
         { "wxSizerItem_GetUserData", (PyCFunction) _wrap_wxSizerItem_GetUserData, METH_VARARGS | METH_KEYWORDS },
         { "wxSizerItem_SetBorder", (PyCFunction) _wrap_wxSizerItem_SetBorder, METH_VARARGS | METH_KEYWORDS },
         { "wxSizerItem_SetFlag", (PyCFunction) _wrap_wxSizerItem_SetFlag, METH_VARARGS | METH_KEYWORDS },
index e0105a34955e4c6d3cfb71db7409617ccf529976..2eaac713ffc8a1bc67d36e89ba9b691013e17dd9 100644 (file)
@@ -103,6 +103,9 @@ class wxSizerPtr(wxObjectPtr):
     def __init__(self,this):
         self.this = this
         self.thisown = 0
+    def _setOORInfo(self, *_args, **_kwargs):
+        val = apply(sizersc.wxSizer__setOORInfo,(self,) + _args, _kwargs)
+        return val
     def Destroy(self, *_args, **_kwargs):
         val = apply(sizersc.wxSizer_Destroy,(self,) + _args, _kwargs)
         return val
@@ -252,6 +255,7 @@ class wxPySizer(wxPySizerPtr):
         self.this = apply(sizersc.new_wxPySizer,_args,_kwargs)
         self.thisown = 1
         self._setCallbackInfo(self, wxPySizer)
+        self._setOORInfo(self)
 
 
 
@@ -276,6 +280,7 @@ class wxBoxSizer(wxBoxSizerPtr):
     def __init__(self,*_args,**_kwargs):
         self.this = apply(sizersc.new_wxBoxSizer,_args,_kwargs)
         self.thisown = 1
+        self._setOORInfo(self)
 
 
 
@@ -300,6 +305,7 @@ class wxStaticBoxSizer(wxStaticBoxSizerPtr):
     def __init__(self,*_args,**_kwargs):
         self.this = apply(sizersc.new_wxStaticBoxSizer,_args,_kwargs)
         self.thisown = 1
+        self._setOORInfo(self)
 
 
 
@@ -324,6 +330,7 @@ class wxNotebookSizer(wxNotebookSizerPtr):
     def __init__(self,*_args,**_kwargs):
         self.this = apply(sizersc.new_wxNotebookSizer,_args,_kwargs)
         self.thisown = 1
+        self._setOORInfo(self)
 
 
 
@@ -369,6 +376,7 @@ class wxGridSizer(wxGridSizerPtr):
     def __init__(self,*_args,**_kwargs):
         self.this = apply(sizersc.new_wxGridSizer,_args,_kwargs)
         self.thisown = 1
+        self._setOORInfo(self)
 
 
 
@@ -402,6 +410,7 @@ class wxFlexGridSizer(wxFlexGridSizerPtr):
     def __init__(self,*_args,**_kwargs):
         self.this = apply(sizersc.new_wxFlexGridSizer,_args,_kwargs)
         self.thisown = 1
+        self._setOORInfo(self)
 
 
 
index e5f773b4909db3ea4c6c3161734a2d8d5eddd47a..59779e933e2c977a628f2b516563c1ca8c42bcbc 100644 (file)
@@ -1499,7 +1499,8 @@ def wxPyTypeCast(obj, typeStr):
     theClass = globals()[typeStr+"Ptr"]
     typeStr = __wxPyPtrTypeMap.get(typeStr, typeStr)
     if hasattr(obj, "this"):
-        if obj.__class__ is theClass:   # if already the right type then just return it
+        # if already the right type then just return it
+        if isinstance(obj, theClass) or obj.__class__ is theClass:
             return obj
         newPtr = ptrcast(obj.this, typeStr+"_p")
     else:
index c1a6c05373c0b2ad338c0d59c027c1d7c8b9a19e..0a6f3f15cce669629cda640e3df015ef6cfafbba 100644 (file)
@@ -93,6 +93,12 @@ public:
     // wxSizer();      ****  abstract, can't instantiate
     // ~wxSizer();
 
+    %addmethods {
+        void _setOORInfo(PyObject* _self) {
+            self->SetClientObject(new wxPyClientData(_self));
+        }
+    }
+
     %addmethods {
         void Destroy() { delete self; }
 
@@ -268,6 +274,7 @@ public:
     wxPySizer();
     void _setCallbackInfo(PyObject* self, PyObject* _class);
     %pragma(python) addtomethod = "__init__:self._setCallbackInfo(self, wxPySizer)"
+    %pragma(python) addtomethod = "__init__:self._setOORInfo(self)"
 };
 
 
@@ -276,6 +283,7 @@ public:
 class  wxBoxSizer : public wxSizer {
 public:
     wxBoxSizer(int orient = wxHORIZONTAL);
+    %pragma(python) addtomethod = "__init__:self._setOORInfo(self)"
     int GetOrientation();
     void RecalcSizes();
     wxSize CalcMin();
@@ -286,6 +294,7 @@ public:
 class  wxStaticBoxSizer : public wxBoxSizer {
 public:
     wxStaticBoxSizer(wxStaticBox *box, int orient = wxHORIZONTAL);
+    %pragma(python) addtomethod = "__init__:self._setOORInfo(self)"
     wxStaticBox *GetStaticBox();
     void RecalcSizes();
     wxSize CalcMin();
@@ -296,10 +305,9 @@ public:
 class wxNotebookSizer: public wxSizer {
 public:
     wxNotebookSizer( wxNotebook *nb );
-
+    %pragma(python) addtomethod = "__init__:self._setOORInfo(self)"
     void RecalcSizes();
     wxSize CalcMin();
-
     wxNotebook *GetNotebook();
 };
 
@@ -309,6 +317,7 @@ class wxGridSizer: public wxSizer
 {
 public:
     wxGridSizer( int rows=1, int cols=0, int vgap=0, int hgap=0 );
+    %pragma(python) addtomethod = "__init__:self._setOORInfo(self)"
 
     void RecalcSizes();
     wxSize CalcMin();
@@ -329,6 +338,7 @@ class wxFlexGridSizer: public wxGridSizer
 {
 public:
     wxFlexGridSizer( int rows=1, int cols=0, int vgap=0, int hgap=0 );
+    %pragma(python) addtomethod = "__init__:self._setOORInfo(self)"
 
     void RecalcSizes();
     wxSize CalcMin();