X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/4caf847c87568a6bb1defcc5fc3a9b5db37680b4..52cd14b1c8c74a8d52d5a4ae9a31cfa1d123297a:/src/common/event.cpp diff --git a/src/common/event.cpp b/src/common/event.cpp index 60ebe589a7..ee22ca1062 100644 --- a/src/common/event.cpp +++ b/src/common/event.cpp @@ -44,6 +44,9 @@ #if wxUSE_GUI #include "wx/validate.h" +#if wxUSE_STOPWATCH + #include "wx/stopwatch.h" +#endif #endif // wxUSE_GUI // ---------------------------------------------------------------------------- @@ -120,8 +123,22 @@ wxList *wxPendingEvents = (wxList *)NULL; // common event types are defined here, other event types are defined by the // components which use them + +const wxEventType wxEVT_FIRST = 10000; +const wxEventType wxEVT_USER_FIRST = wxEVT_FIRST + 2000; DEFINE_EVENT_TYPE(wxEVT_NULL) +DEFINE_EVENT_TYPE(wxEVT_IDLE) +DEFINE_EVENT_TYPE(wxEVT_SOCKET) + +#endif // !WXWIN_COMPATIBILITY_EVENT_TYPES + +#endif // wxUSE_BASE + +#if wxUSE_GUI + +#if !WXWIN_COMPATIBILITY_EVENT_TYPES + DEFINE_EVENT_TYPE(wxEVT_COMMAND_BUTTON_CLICKED) DEFINE_EVENT_TYPE(wxEVT_COMMAND_CHECKBOX_CLICKED) DEFINE_EVENT_TYPE(wxEVT_COMMAND_CHOICE_SELECTED) @@ -140,7 +157,6 @@ DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOOL_ENTER) DEFINE_EVENT_TYPE(wxEVT_COMMAND_SPINCTRL_UPDATED) // Sockets and timers send events, too -DEFINE_EVENT_TYPE(wxEVT_SOCKET) DEFINE_EVENT_TYPE(wxEVT_TIMER) // Mouse event types @@ -181,6 +197,9 @@ DEFINE_EVENT_TYPE(wxEVT_CHAR_HOOK) DEFINE_EVENT_TYPE(wxEVT_NAVIGATION_KEY) DEFINE_EVENT_TYPE(wxEVT_KEY_DOWN) DEFINE_EVENT_TYPE(wxEVT_KEY_UP) +#if wxUSE_HOTKEY +DEFINE_EVENT_TYPE(wxEVT_HOTKEY) +#endif // Set cursor event DEFINE_EVENT_TYPE(wxEVT_SET_CURSOR) @@ -245,7 +264,6 @@ DEFINE_EVENT_TYPE(wxEVT_DRAW_ITEM) DEFINE_EVENT_TYPE(wxEVT_MEASURE_ITEM) DEFINE_EVENT_TYPE(wxEVT_COMPARE_ITEM) DEFINE_EVENT_TYPE(wxEVT_INIT_DIALOG) -DEFINE_EVENT_TYPE(wxEVT_IDLE) DEFINE_EVENT_TYPE(wxEVT_UPDATE_UI) // Generic command events @@ -264,6 +282,10 @@ DEFINE_EVENT_TYPE(wxEVT_DETAILED_HELP) #endif // !WXWIN_COMPATIBILITY_EVENT_TYPES +#endif // wxUSE_GUI + +#if wxUSE_BASE + // ============================================================================ // implementation // ============================================================================ @@ -346,6 +368,84 @@ wxCommandEvent::wxCommandEvent(wxEventType commandType, int theId) m_isCommandEvent = TRUE; } +/* + * UI update events + */ + +#if wxUSE_LONGLONG +wxLongLong wxUpdateUIEvent::sm_lastUpdate = 0; +#endif + +long wxUpdateUIEvent::sm_updateInterval = 0; + +wxUpdateUIMode wxUpdateUIEvent::sm_updateMode = wxUPDATE_UI_PROCESS_ALL; + +// Can we update? +bool wxUpdateUIEvent::CanUpdate(wxWindow* win) +{ + // Don't update if we've switched global updating off + // and this window doesn't support updates. + if (win && + (GetMode() == wxUPDATE_UI_PROCESS_SPECIFIED && + ((win->GetExtraStyle() & wxWS_EX_PROCESS_UI_UPDATES) == 0))) + return FALSE; + + if (sm_updateInterval == -1) + return FALSE; + else if (sm_updateInterval == 0) + return TRUE; + else + { +#if wxUSE_STOPWATCH && wxUSE_LONGLONG + wxLongLong now = wxGetLocalTimeMillis(); + if (now > (sm_lastUpdate + sm_updateInterval)) + { + return TRUE; + } +#else + // If we don't have wxStopWatch or wxLongLong, we + // should err on the safe side and update now anyway. + return TRUE; +#endif + } + return FALSE; +} + +// Reset the update time to provide a delay until the next +// time we should update +void wxUpdateUIEvent::ResetUpdateTime() +{ +#if wxUSE_STOPWATCH && wxUSE_LONGLONG + if (sm_updateInterval > 0) + { + wxLongLong now = wxGetLocalTimeMillis(); + if (now > (sm_lastUpdate + sm_updateInterval)) + { + sm_lastUpdate = now; + } + } +#endif +} + +/* + * Idle events + */ + +wxIdleMode wxIdleEvent::sm_idleMode = wxIDLE_PROCESS_ALL; + +// Can we send an idle event? +bool wxIdleEvent::CanSend(wxWindow* win) +{ + // Don't update if we've switched global updating off + // and this window doesn't support updates. + if (win && + (GetMode() == wxIDLE_PROCESS_SPECIFIED && + ((win->GetExtraStyle() & wxWS_EX_PROCESS_IDLE) == 0))) + return FALSE; + + return TRUE; +} + /* * Scroll events */ @@ -642,19 +742,19 @@ wxEvtHandler::~wxEvtHandler() if (m_dynamicEvents) { - wxNode *node = m_dynamicEvents->GetFirst(); - while (node) + wxList::iterator it = m_dynamicEvents->begin(), + en = m_dynamicEvents->end(); + for (;it != en; ++it) { #if WXWIN_COMPATIBILITY_EVENT_TYPES - wxEventTableEntry *entry = (wxEventTableEntry*)node->GetData(); + wxEventTableEntry *entry = (wxEventTableEntry*)*it; #else // !WXWIN_COMPATIBILITY_EVENT_TYPES - wxDynamicEventTableEntry *entry = (wxDynamicEventTableEntry*)node->GetData(); + wxDynamicEventTableEntry *entry = (wxDynamicEventTableEntry*)*it; #endif // WXWIN_COMPATIBILITY_EVENT_TYPES/!WXWIN_COMPATIBILITY_EVENT_TYPES if (entry->m_callbackUserData) delete entry->m_callbackUserData; delete entry; - node = node->GetNext(); } delete m_dynamicEvents; }; @@ -748,11 +848,11 @@ void wxEvtHandler::ProcessPendingEvents() wxENTER_CRIT_SECT( *m_eventsLocker); #endif - wxNode *node = m_pendingEvents->GetFirst(); + wxList::compatibility_iterator node = m_pendingEvents->GetFirst(); while ( node ) { wxEvent *event = (wxEvent *)node->GetData(); - delete node; + m_pendingEvents->Erase(node); // In ProcessEvent, new events might get added and // we can safely leave the crtical section here. @@ -779,8 +879,6 @@ void wxEvtHandler::ProcessPendingEvents() #endif } -#endif // wxUSE_BASE - /* * Event table stuff */ @@ -821,24 +919,25 @@ bool wxEvtHandler::ProcessEvent(wxEvent& event) // An event handler can be enabled or disabled if ( GetEvtHandlerEnabled() ) { - // 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 + // table #if wxUSE_VALIDATORS if ( TryValidator(event) ) return TRUE; #endif // wxUSE_VALIDATORS - // Then static per-class event tables - const wxEventTable *table = GetEventTable(); + // Handle per-instance dynamic event tables first + if ( m_dynamicEvents && SearchDynamicEventTable(event) ) + return TRUE; - // Search upwards through the inheritance hierarchy - while (table) + // Then static per-class event tables (and search upwards through the + // inheritance hierarchy) + for ( const wxEventTable *table = GetEventTable(); + table; + table = table->baseTable ) { if ( SearchEventTable((wxEventTable&)*table, event) ) return TRUE; - table = table->baseTable; } } @@ -849,11 +948,11 @@ bool wxEvtHandler::ProcessEvent(wxEvent& event) return TRUE; } + // Finally propagate the event upwards the window chain and/or to the + // application object as necessary return TryParent(event); } -#if wxUSE_BASE - bool wxEvtHandler::SearchEventTable(wxEventTable& table, wxEvent& event) { wxEventType eventType = event.GetEventType(); @@ -901,7 +1000,8 @@ bool wxEvtHandler::SearchEventTable(wxEventTable& table, wxEvent& event) void wxEvtHandler::Connect( int id, int lastId, int eventType, wxObjectEventFunction func, - wxObject *userData ) + wxObject *userData, + wxEvtHandler* eventSink ) { #if WXWIN_COMPATIBILITY_EVENT_TYPES wxEventTableEntry *entry = new wxEventTableEntry; @@ -912,7 +1012,7 @@ void wxEvtHandler::Connect( int id, int lastId, entry->m_callbackUserData = userData; #else // !WXWIN_COMPATIBILITY_EVENT_TYPES wxDynamicEventTableEntry *entry = - new wxDynamicEventTableEntry(eventType, id, lastId, func, userData); + new wxDynamicEventTableEntry(eventType, id, lastId, func, userData, eventSink); #endif // WXWIN_COMPATIBILITY_EVENT_TYPES/!WXWIN_COMPATIBILITY_EVENT_TYPES if (!m_dynamicEvents) @@ -924,12 +1024,13 @@ void wxEvtHandler::Connect( int id, int lastId, bool wxEvtHandler::Disconnect( int id, int lastId, wxEventType eventType, wxObjectEventFunction func, - wxObject *userData ) + wxObject *userData, + wxEvtHandler* eventSink ) { if (!m_dynamicEvents) return FALSE; - wxNode *node = m_dynamicEvents->GetFirst(); + wxList::compatibility_iterator node = m_dynamicEvents->GetFirst(); while (node) { #if WXWIN_COMPATIBILITY_EVENT_TYPES @@ -942,11 +1043,12 @@ bool wxEvtHandler::Disconnect( int id, int lastId, wxEventType eventType, ((entry->m_lastId == lastId) || (lastId == -1)) && ((entry->m_eventType == eventType) || (eventType == wxEVT_NULL)) && ((entry->m_fn == func) || (func == (wxObjectEventFunction)NULL)) && + ((entry->m_eventSink == eventSink) || (eventSink == (wxEvtHandler*)NULL)) && ((entry->m_callbackUserData == userData) || (userData == (wxObject*)NULL))) { if (entry->m_callbackUserData) delete entry->m_callbackUserData; - m_dynamicEvents->DeleteNode( node ); + m_dynamicEvents->Erase( node ); delete entry; return TRUE; } @@ -962,7 +1064,7 @@ bool wxEvtHandler::SearchDynamicEventTable( wxEvent& event ) int commandId = event.GetId(); - wxNode *node = m_dynamicEvents->GetFirst(); + wxList::compatibility_iterator node = m_dynamicEvents->GetFirst(); while (node) { #if WXWIN_COMPATIBILITY_EVENT_TYPES @@ -983,7 +1085,12 @@ bool wxEvtHandler::SearchDynamicEventTable( wxEvent& event ) event.Skip(FALSE); event.m_callbackUserData = entry->m_callbackUserData; - (this->*((wxEventFunction) (entry->m_fn)))(event); +#if !WXWIN_COMPATIBILITY_EVENT_TYPES + if (entry->m_eventSink) + ((entry->m_eventSink)->*((wxEventFunction) (entry->m_fn)))(event); + else +#endif + (this->*((wxEventFunction) (entry->m_fn)))(event); if ( ! event.GetSkipped() ) return TRUE;