X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a79a6671e405bc0630e819e3c2a2c1f3fea6d2e9..3f8cdda4851796e5f5f5bcd82d9e867a30581a6f:/src/common/wincmn.cpp diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 964585411a..5b3fb6b853 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -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); }