X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f8f7cff4368ee960f63f61d0dd32eacdd471800b..f63c36c378c55a4a727e3fcd732bd6b7cdced1bd:/src/common/event.cpp diff --git a/src/common/event.cpp b/src/common/event.cpp index 7d98a3e6d0..7b58e77c3c 100644 --- a/src/common/event.cpp +++ b/src/common/event.cpp @@ -126,7 +126,7 @@ const wxEventTableEntry wxEvtHandler::sm_eventTableEntries[] = // the memory leaks when using it, however this breaks re-initializing the // library (i.e. repeated calls to wxInitialize/wxUninitialize) because the // event tables won't be rebuilt the next time, so disable this by default -#if defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING +#if wxUSE_MEMORY_TRACING class wxEventTableEntryModule: public wxModule { @@ -140,7 +140,7 @@ public: IMPLEMENT_DYNAMIC_CLASS(wxEventTableEntryModule, wxModule) -#endif // __WXDEBUG__ && wxUSE_MEMORY_TRACING +#endif // wxUSE_MEMORY_TRACING // ---------------------------------------------------------------------------- // global variables @@ -177,6 +177,8 @@ wxDEFINE_EVENT( wxEVT_COMMAND_TOOL_ENTER, wxCommandEvent ); wxDEFINE_EVENT( wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEvent ); wxDEFINE_EVENT( wxEVT_COMMAND_SPINCTRLDOUBLE_UPDATED, wxCommandEvent ); wxDEFINE_EVENT( wxEVT_COMMAND_TOOL_DROPDOWN_CLICKED, wxCommandEvent ); +wxDEFINE_EVENT( wxEVT_COMMAND_COMBOBOX_DROPDOWN, wxCommandEvent); +wxDEFINE_EVENT( wxEVT_COMMAND_COMBOBOX_CLOSEUP, wxCommandEvent); // Mouse event types wxDEFINE_EVENT( wxEVT_LEFT_DOWN, wxMouseEvent ); @@ -402,10 +404,9 @@ wxEvent& wxEvent::operator=(const wxEvent& src) #if wxUSE_GUI -/* - * Command events - * - */ +// ---------------------------------------------------------------------------- +// wxCommandEvent +// ---------------------------------------------------------------------------- #ifdef __VISUALC__ // 'this' : used in base member initializer list (for m_commandString) @@ -447,9 +448,9 @@ wxString wxCommandEvent::GetString() const } } -/* - * UI update events - */ +// ---------------------------------------------------------------------------- +// wxUpdateUIEvent +// ---------------------------------------------------------------------------- #if wxUSE_LONGLONG wxLongLong wxUpdateUIEvent::sm_lastUpdate = 0; @@ -506,9 +507,9 @@ void wxUpdateUIEvent::ResetUpdateTime() #endif } -/* - * Scroll events - */ +// ---------------------------------------------------------------------------- +// wxScrollEvent +// ---------------------------------------------------------------------------- wxScrollEvent::wxScrollEvent(wxEventType commandType, int id, @@ -520,9 +521,9 @@ wxScrollEvent::wxScrollEvent(wxEventType commandType, m_commandInt = pos; } -/* - * ScrollWin events - */ +// ---------------------------------------------------------------------------- +// wxScrollWinEvent +// ---------------------------------------------------------------------------- wxScrollWinEvent::wxScrollWinEvent(wxEventType commandType, int pos, @@ -533,10 +534,9 @@ wxScrollWinEvent::wxScrollWinEvent(wxEventType commandType, m_commandInt = pos; } -/* - * Mouse events - * - */ +// ---------------------------------------------------------------------------- +// wxMouseEvent +// ---------------------------------------------------------------------------- wxMouseEvent::wxMouseEvent(wxEventType commandType) { @@ -751,11 +751,9 @@ wxPoint wxMouseEvent::GetLogicalPosition(const wxDC& dc) const return pt; } - -/* - * Keyboard event - * - */ +// ---------------------------------------------------------------------------- +// wxKeyEvent +// ---------------------------------------------------------------------------- wxKeyEvent::wxKeyEvent(wxEventType type) { @@ -782,18 +780,30 @@ wxKeyEvent::wxKeyEvent(const wxKeyEvent& evt) #endif } +// ---------------------------------------------------------------------------- +// wxWindowCreateEvent +// ---------------------------------------------------------------------------- + wxWindowCreateEvent::wxWindowCreateEvent(wxWindow *win) { SetEventType(wxEVT_CREATE); SetEventObject(win); } +// ---------------------------------------------------------------------------- +// wxWindowDestroyEvent +// ---------------------------------------------------------------------------- + wxWindowDestroyEvent::wxWindowDestroyEvent(wxWindow *win) { SetEventType(wxEVT_DESTROY); SetEventObject(win); } +// ---------------------------------------------------------------------------- +// wxChildFocusEvent +// ---------------------------------------------------------------------------- + wxChildFocusEvent::wxChildFocusEvent(wxWindow *win) : wxCommandEvent(wxEVT_CHILD_FOCUS) { @@ -868,7 +878,7 @@ void wxEventHashTable::Clear() m_size = 0; } -#if defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING +#if wxUSE_MEMORY_TRACING // Clear all tables void wxEventHashTable::ClearAll() @@ -881,7 +891,7 @@ void wxEventHashTable::ClearAll() } } -#endif // __WXDEBUG__ && wxUSE_MEMORY_TRACING +#endif // wxUSE_MEMORY_TRACING bool wxEventHashTable::HandleEvent(wxEvent &event, wxEvtHandler *self) { @@ -1071,14 +1081,11 @@ wxEvtHandler::~wxEvtHandler() delete m_dynamicEvents; } - if (m_pendingEvents) - m_pendingEvents->DeleteContents(true); - delete m_pendingEvents; - // Remove us from the list of the pending events if necessary. - wxEventLoopBase *loop = wxEventLoopBase::GetActive(); - if (loop) - loop->RemovePendingEventHandler(this); + if (wxTheApp) + wxTheApp->RemovePendingEventHandler(this); + + DeletePendingEvents(); // we only delete object data, not untyped if ( m_clientDataType == wxClientData_Object ) @@ -1124,12 +1131,15 @@ void wxEvtHandler::QueueEvent(wxEvent *event) { wxCHECK_RET( event, "NULL event can't be posted" ); - wxEventLoopBase* loop = wxEventLoopBase::GetActive(); - if (!loop) + if (!wxTheApp) { // we need an event loop which manages the list of event handlers with // pending events... cannot proceed without it! - wxLogDebug("No event loop is running!"); + wxLogDebug("No application object! Cannot queue this event!"); + + // anyway delete the given event to avoid memory leaks + delete event; + return; } @@ -1137,14 +1147,14 @@ void wxEvtHandler::QueueEvent(wxEvent *event) wxENTER_CRIT_SECT( m_pendingEventsLock ); if ( !m_pendingEvents ) - m_pendingEvents = new wxList; + m_pendingEvents = new wxList; m_pendingEvents->Append(event); // 2) Add this event handler to list of event handlers that // have pending events. - loop->AppendPendingEventHandler(this); + wxTheApp->AppendPendingEventHandler(this); // only release m_pendingEventsLock now because otherwise there is a race // condition as described in the ticket #9093: we could process the event @@ -1159,14 +1169,20 @@ void wxEvtHandler::QueueEvent(wxEvent *event) wxWakeUpIdle(); } +void wxEvtHandler::DeletePendingEvents() +{ + if (m_pendingEvents) + m_pendingEvents->DeleteContents(true); + wxDELETE(m_pendingEvents); +} + void wxEvtHandler::ProcessPendingEvents() { - wxEventLoopBase* loop = wxEventLoopBase::GetActive(); - if (!loop) + if (!wxTheApp) { // we need an event loop which manages the list of event handlers with // pending events... cannot proceed without it! - wxLogDebug("No event loop is running!"); + wxLogDebug("No application object! Cannot process pending events!"); return; } @@ -1197,7 +1213,7 @@ void wxEvtHandler::ProcessPendingEvents() if (!node) { // all our events are NOT processable now... signal this: - loop->DelayPendingEventHandler(this); + wxTheApp->DelayPendingEventHandler(this); // see the comment at the beginning of evtloop.h header for the // logic behind YieldFor() and behind DelayPendingEventHandler() @@ -1219,7 +1235,7 @@ void wxEvtHandler::ProcessPendingEvents() { // if there are no more pending events left, we don't need to // stay in this list - loop->RemovePendingEventHandler(this); + wxTheApp->RemovePendingEventHandler(this); } wxLEAVE_CRIT_SECT( m_pendingEventsLock ); @@ -1231,13 +1247,10 @@ void wxEvtHandler::ProcessPendingEvents() // of this object any more } -/* - * Event table stuff - */ -/* static */ bool -wxEvtHandler::ProcessEventIfMatchesId(const wxEventTableEntryBase& entry, - wxEvtHandler *handler, - wxEvent& event) +/* static */ +bool wxEvtHandler::ProcessEventIfMatchesId(const wxEventTableEntryBase& entry, + wxEvtHandler *handler, + wxEvent& event) { int tableId1 = entry.m_id, tableId2 = entry.m_lastId; @@ -1275,15 +1288,8 @@ wxEvtHandler::ProcessEventIfMatchesId(const wxEventTableEntryBase& entry, return false; } -bool wxEvtHandler::TryParent(wxEvent& event) +bool wxEvtHandler::DoTryApp(wxEvent& event) { - if ( GetNextHandler() ) - { - // the next handler will pass it to wxTheApp if it doesn't process it, - // so return from here to avoid doing it again - return GetNextHandler()->TryParent(event); - } - if ( wxTheApp && (this != wxTheApp) ) { // Special case: don't pass wxEVT_IDLE to wxApp, since it'll always @@ -1299,6 +1305,27 @@ bool wxEvtHandler::TryParent(wxEvent& event) return false; } +bool wxEvtHandler::TryBefore(wxEvent& event) +{ +#if WXWIN_COMPATIBILITY_2_8 + // call the old virtual function to keep the code overriding it working + return TryValidator(event); +#else + wxUnusedVar(event); + return false; +#endif +} + +bool wxEvtHandler::TryAfter(wxEvent& event) +{ +#if WXWIN_COMPATIBILITY_2_8 + // as above, call the old virtual function for compatibility + return TryParent(event); +#else + return DoTryApp(event); +#endif +} + bool wxEvtHandler::ProcessEvent(wxEvent& event) { // allow the application to hook into event processing @@ -1326,14 +1353,14 @@ bool wxEvtHandler::ProcessEvent(wxEvent& 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 + // TryAfter() 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); + return TryAfter(event); } bool wxEvtHandler::ProcessEventHere(wxEvent& event) @@ -1342,9 +1369,8 @@ bool wxEvtHandler::ProcessEventHere(wxEvent& event) if ( !GetEvtHandlerEnabled() ) return false; - // If we have a validator, it has higher priority than our own event - // handlers - if ( TryValidator(event) ) + // Try the hooks which should be called before our own handlers + if ( TryBefore(event) ) return true; // Handle per-instance dynamic event tables first @@ -1370,9 +1396,15 @@ bool wxEvtHandler::SafelyProcessEvent(wxEvent& event) } catch ( ... ) { - wxEventLoopBase *loop = wxEventLoopBase::GetActive(); + // notice that we do it in 2 steps to avoid warnings about possibly + // uninitialized loop variable from some versions of g++ which are not + // smart enough to figure out that GetActive() doesn't throw and so + // that loop will always be initialized + wxEventLoopBase *loop = NULL; try { + loop = wxEventLoopBase::GetActive(); + if ( !wxTheApp || !wxTheApp->OnExceptionInMainLoop() ) { if ( loop ) @@ -1395,7 +1427,6 @@ bool wxEvtHandler::SafelyProcessEvent(wxEvent& event) #endif // wxUSE_EXCEPTIONS } - bool wxEvtHandler::SearchEventTable(wxEventTable& table, wxEvent& event) { const wxEventType eventType = event.GetEventType();