X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/03f3617bf36573a7c368614191444364267ed718..b53aea81d2e102224b452ef5bf7aee1132f37c6f:/src/common/event.cpp diff --git a/src/common/event.cpp b/src/common/event.cpp index 700084e9cc..85951a1b3e 100644 --- a/src/common/event.cpp +++ b/src/common/event.cpp @@ -38,6 +38,7 @@ #include "wx/window.h" #include "wx/control.h" #include "wx/dc.h" + #include "wx/spinbutt.h" #include "wx/textctrl.h" #include "wx/validate.h" #endif // wxUSE_GUI @@ -232,6 +233,21 @@ wxDEFINE_EVENT( wxEVT_SCROLL_THUMBTRACK, wxScrollEvent ) wxDEFINE_EVENT( wxEVT_SCROLL_THUMBRELEASE, wxScrollEvent ) wxDEFINE_EVENT( wxEVT_SCROLL_CHANGED, wxScrollEvent ) +// Due to a bug in older wx versions, wxSpinEvents were being sent with type of +// wxEVT_SCROLL_LINEUP, wxEVT_SCROLL_LINEDOWN and wxEVT_SCROLL_THUMBTRACK. But +// with the type-safe events in place, these event types are associated with +// wxScrollEvent. To allow handling of spin events, new event types have been +// defined in spinbutt.h/spinnbuttcmn.cpp. To maintain backward compatibility +// the spin event types are being initialized with the scroll event types. + +#if wxUSE_SPINBTN + +wxDEFINE_EVENT_ALIAS( wxEVT_SPIN_UP, wxSpinEvent, wxEVT_SCROLL_LINEUP ) +wxDEFINE_EVENT_ALIAS( wxEVT_SPIN_DOWN, wxSpinEvent, wxEVT_SCROLL_LINEDOWN ) +wxDEFINE_EVENT_ALIAS( wxEVT_SPIN, wxSpinEvent, wxEVT_SCROLL_THUMBTRACK ) + +#endif // wxUSE_SPINBTN + // Scroll events from wxWindow wxDEFINE_EVENT( wxEVT_SCROLLWIN_TOP, wxScrollWinEvent ) wxDEFINE_EVENT( wxEVT_SCROLLWIN_BOTTOM, wxScrollWinEvent ) @@ -352,6 +368,7 @@ wxEvent::wxEvent(int theId, wxEventType commandType ) m_callbackUserData = NULL; m_isCommandEvent = false; m_propagationLevel = wxEVENT_PROPAGATE_NONE; + m_wasProcessed = false; } wxEvent::wxEvent(const wxEvent& src) @@ -364,6 +381,7 @@ wxEvent::wxEvent(const wxEvent& src) , m_propagationLevel(src.m_propagationLevel) , m_skipped(src.m_skipped) , m_isCommandEvent(src.m_isCommandEvent) + , m_wasProcessed(false) { } @@ -380,6 +398,8 @@ wxEvent& wxEvent::operator=(const wxEvent& src) m_skipped = src.m_skipped; m_isCommandEvent = src.m_isCommandEvent; + // don't change m_wasProcessed + return *this; } @@ -1032,12 +1052,7 @@ wxEvtHandler::wxEvtHandler() wxEvtHandler::~wxEvtHandler() { - // Takes itself out of the list of handlers - if (m_previousHandler) - m_previousHandler->m_nextHandler = m_nextHandler; - - if (m_nextHandler) - m_nextHandler->m_previousHandler = m_previousHandler; + Unlink(); if (m_dynamicEvents) { @@ -1099,6 +1114,26 @@ wxEvtHandler::~wxEvtHandler() delete m_clientObject; } +void wxEvtHandler::Unlink() +{ + // this event handler must take itself out of the chain of handlers: + + if (m_previousHandler) + m_previousHandler->SetNextHandler(m_nextHandler); + + if (m_nextHandler) + m_nextHandler->SetPreviousHandler(m_previousHandler); + + m_nextHandler = NULL; + m_previousHandler = NULL; +} + +bool wxEvtHandler::IsUnlinked() const +{ + return m_previousHandler == NULL && + m_nextHandler == NULL; +} + #if wxUSE_THREADS bool wxEvtHandler::ProcessThreadEvent(const wxEvent& event) @@ -1263,22 +1298,35 @@ bool wxEvtHandler::TryParent(wxEvent& event) bool wxEvtHandler::ProcessEvent(wxEvent& event) { // allow the application to hook into event processing - if ( wxTheApp ) + // + // note that we should only do it if we're the first event handler called + // to avoid calling FilterEvent() multiple times as the event goes through + // the event handler chain and possibly upwards the window hierarchy + if ( !event.WasProcessed() ) { - int rc = wxTheApp->FilterEvent(event); - if ( rc != -1 ) + if ( wxTheApp ) { - wxASSERT_MSG( rc == 1 || rc == 0, - _T("unexpected wxApp::FilterEvent return value") ); + int rc = wxTheApp->FilterEvent(event); + if ( rc != -1 ) + { + wxASSERT_MSG( rc == 1 || rc == 0, + "unexpected wxApp::FilterEvent return value" ); - return rc != 0; + return rc != 0; + } + //else: proceed normally } - //else: proceed normally } if ( ProcessEventHere(event) ) return true; + // pass the event to the next handler, notice that we shouldn't call + // TryParent() even if it doesn't handle the event as the last handler in + // the chain will do it + if ( GetNextHandler() ) + return GetNextHandler()->ProcessEvent(event); + // propagate the event upwards the window chain and/or to the application // object if it wasn't processed at this level return TryParent(event); @@ -1286,25 +1334,21 @@ bool wxEvtHandler::ProcessEvent(wxEvent& event) bool wxEvtHandler::ProcessEventHere(wxEvent& event) { - // An event handler can be enabled or disabled - if ( GetEvtHandlerEnabled() ) - { - // if we have a validator, it has higher priority than our own event - // table - if ( TryValidator(event) ) - return true; + // If the event handler is disabled it doesn't process any events + if ( !GetEvtHandlerEnabled() ) + return false; - // Handle per-instance dynamic event tables first - if ( m_dynamicEvents && SearchDynamicEventTable(event) ) - return true; + // If we have a validator, it has higher priority than our own event + // handlers + if ( TryValidator(event) ) + return true; - // Then static per-class event tables - if ( GetEventHashTable().HandleEvent(event, this) ) - return true; - } + // Handle per-instance dynamic event tables first + if ( m_dynamicEvents && SearchDynamicEventTable(event) ) + return true; - // Try going down the event handler chain - if ( GetNextHandler() && GetNextHandler()->ProcessEventHere(event) ) + // Then static per-class event tables + if ( GetEventHashTable().HandleEvent(event, this) ) return true; // We don't have a handler for this event.