]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/wincmn.cpp
don't include private headers from wx/unix/evtloop.h
[wxWidgets.git] / src / common / wincmn.cpp
index 964585411ae2aa7b9834a210a6f133389dcb56d7..5b3fb6b85307a644533eb1886a140a83c8af6fe5 100644 (file)
@@ -711,15 +711,36 @@ wxSize wxWindowBase::GetEffectiveMinSize() const
 {
     // merge the best size with the min size, giving priority to the min size
     wxSize min = GetMinSize();
+    
     if (min.x == wxDefaultCoord || min.y == wxDefaultCoord)
     {
         wxSize best = GetBestSize();
         if (min.x == wxDefaultCoord) min.x =  best.x;
         if (min.y == wxDefaultCoord) min.y =  best.y;
     }
+    
     return min;
 }
 
+wxSize wxWindowBase::GetBestSize() const
+{
+    if ((!m_windowSizer) && (m_bestSizeCache.IsFullySpecified()))
+        return m_bestSizeCache;
+        
+    return DoGetBestSize();
+}
+
+void wxWindowBase::SetMinSize(const wxSize& minSize)
+{ 
+    m_minWidth = minSize.x; 
+    m_minHeight = minSize.y; 
+}
+
+void wxWindowBase::SetMaxSize(const wxSize& maxSize)
+{ 
+    m_maxWidth = maxSize.x; 
+    m_maxHeight = maxSize.y;
+}
 
 void wxWindowBase::SetInitialSize(const wxSize& size)
 {
@@ -1096,73 +1117,121 @@ bool wxWindowBase::Reparent(wxWindowBase *newParent)
 // event handler stuff
 // ----------------------------------------------------------------------------
 
-void wxWindowBase::PushEventHandler(wxEvtHandler *handler)
+void wxWindowBase::SetEventHandler(wxEvtHandler *handler)
 {
+    wxCHECK_RET(handler != NULL, "SetEventHandler(NULL) called");
+
+    m_eventHandler = handler;
+}
+
+void wxWindowBase::SetNextHandler(wxEvtHandler *WXUNUSED(handler))
+{
+    // disable wxEvtHandler chain mechanism for wxWindows:
+    // wxWindow uses its own stack mechanism which doesn't mix well with wxEvtHandler's one
+
+    wxFAIL_MSG("wxWindow cannot be part of a wxEvtHandler chain");
+}
+void wxWindowBase::SetPreviousHandler(wxEvtHandler *WXUNUSED(handler))
+{
+    // we can't simply wxFAIL here as in SetNextHandler: in fact the last
+    // handler of our stack when is destroyed will be Unlink()ed and thus
+    // will call this function to update the pointer of this window...
+
+    //wxFAIL_MSG("wxWindow cannot be part of a wxEvtHandler chain");
+}
+
+void wxWindowBase::PushEventHandler(wxEvtHandler *handlerToPush)
+{
+    wxCHECK_RET( handlerToPush != NULL, "PushEventHandler(NULL) called" );
+
+    // the new handler is going to be part of the wxWindow stack of event handlers:
+    // it can't be part also of an event handler double-linked chain:
+    wxASSERT_MSG(handlerToPush->IsUnlinked(),
+        "The handler being pushed in the wxWindow stack shouldn't be part of "
+        "a wxEvtHandler chain; call Unlink() on it first");
+
     wxEvtHandler *handlerOld = GetEventHandler();
+    wxCHECK_RET( handlerOld, "an old event handler is NULL?" );
 
-    handler->SetNextHandler(handlerOld);
+    // now use wxEvtHandler double-linked list to implement a stack:
+    handlerToPush->SetNextHandler(handlerOld);
 
-    if ( handlerOld )
-        GetEventHandler()->SetPreviousHandler(handler);
+    if (handlerOld != this)
+        handlerOld->SetPreviousHandler(handlerToPush);
 
-    SetEventHandler(handler);
+    SetEventHandler(handlerToPush);
+
+#ifdef __WXDEBUG__
+    // final checks of the operations done above:
+    wxASSERT_MSG( handlerToPush->GetPreviousHandler() == NULL,
+        "the first handler of the wxWindow stack should have no previous handlers set" );
+    wxASSERT_MSG( handlerToPush->GetNextHandler() != NULL,
+        "the first handler of the wxWindow stack should have non-NULL next handler" );
+
+    wxEvtHandler* pLast = handlerToPush;
+    while (pLast && pLast != this)
+        pLast = pLast->GetNextHandler();
+    wxASSERT_MSG( pLast->GetNextHandler() == NULL,
+        "the last handler of the wxWindow stack should have this window as next handler" );
+#endif
 }
 
 wxEvtHandler *wxWindowBase::PopEventHandler(bool deleteHandler)
 {
-    wxEvtHandler *handlerA = GetEventHandler();
-    if ( handlerA )
-    {
-        wxEvtHandler *handlerB = handlerA->GetNextHandler();
-        handlerA->SetNextHandler(NULL);
+    // we need to pop the wxWindow stack, i.e. we need to remove the first handler
 
-        if ( handlerB )
-            handlerB->SetPreviousHandler(NULL);
-        SetEventHandler(handlerB);
+    wxEvtHandler *firstHandler = GetEventHandler();
+    wxCHECK_MSG( firstHandler != NULL, NULL, "wxWindow cannot have a NULL event handler" );
+    wxCHECK_MSG( firstHandler != this, NULL, "cannot pop the wxWindow itself" );
+    wxCHECK_MSG( firstHandler->GetPreviousHandler() == NULL, NULL,
+        "the first handler of the wxWindow stack should have no previous handlers set" );
 
-        if ( deleteHandler )
-        {
-            delete handlerA;
-            handlerA = NULL;
-        }
+    wxEvtHandler *secondHandler = firstHandler->GetNextHandler();
+    wxCHECK_MSG( secondHandler != NULL, NULL,
+        "the first handler of the wxWindow stack should have non-NULL next handler" );
+
+    firstHandler->SetNextHandler(NULL);
+    secondHandler->SetPreviousHandler(NULL);
+
+    // now firstHandler is completely unlinked; set secondHandler as the new window event handler
+    SetEventHandler(secondHandler);
+
+    if ( deleteHandler )
+    {
+        delete firstHandler;
+        firstHandler = NULL;
     }
 
-    return handlerA;
+    return firstHandler;
 }
 
-bool wxWindowBase::RemoveEventHandler(wxEvtHandler *handler)
+bool wxWindowBase::RemoveEventHandler(wxEvtHandler *handlerToRemove)
 {
-    wxCHECK_MSG( handler, false, _T("RemoveEventHandler(NULL) called") );
+    wxCHECK_MSG( handlerToRemove != NULL, false, "RemoveEventHandler(NULL) called" );
+    wxCHECK_MSG( handlerToRemove != this, false, "Cannot remove the window itself" );
 
-    wxEvtHandler *handlerPrev = NULL,
-                 *handlerCur = GetEventHandler();
-    while ( handlerCur )
+    if (handlerToRemove == GetEventHandler())
+    {
+        // removing the first event handler is equivalent to "popping" the stack
+        PopEventHandler(false);
+        return true;
+    }
+
+    // NOTE: the wxWindow event handler list is always terminated with "this" handler
+    wxEvtHandler *handlerCur = GetEventHandler()->GetNextHandler();
+    while ( handlerCur != this )
     {
         wxEvtHandler *handlerNext = handlerCur->GetNextHandler();
 
-        if ( handlerCur == handler )
+        if ( handlerCur == handlerToRemove )
         {
-            if ( handlerPrev )
-            {
-                handlerPrev->SetNextHandler(handlerNext);
-            }
-            else
-            {
-                SetEventHandler(handlerNext);
-            }
-
-            if ( handlerNext )
-            {
-                handlerNext->SetPreviousHandler ( handlerPrev );
-            }
-
-            handler->SetNextHandler(NULL);
-            handler->SetPreviousHandler(NULL);
+            handlerCur->Unlink();
 
+            wxASSERT_MSG( handlerCur != GetEventHandler(),
+                        "the case Remove == Pop should was already handled" );
             return true;
         }
 
-        handlerPrev = handlerCur;
         handlerCur = handlerNext;
     }
 
@@ -1173,6 +1242,7 @@ bool wxWindowBase::RemoveEventHandler(wxEvtHandler *handler)
 
 bool wxWindowBase::HandleWindowEvent(wxEvent& event) const
 {
+    // SafelyProcessEvent() will handle exceptions nicely
     return GetEventHandler()->SafelyProcessEvent(event);
 }