// 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
{
IMPLEMENT_DYNAMIC_CLASS(wxEventTableEntryModule, wxModule)
-#endif // __WXDEBUG__ && wxUSE_MEMORY_TRACING
+#endif // wxUSE_MEMORY_TRACING
// ----------------------------------------------------------------------------
// global variables
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 );
#if wxUSE_GUI
-/*
- * Command events
- *
- */
+// ----------------------------------------------------------------------------
+// wxCommandEvent
+// ----------------------------------------------------------------------------
#ifdef __VISUALC__
// 'this' : used in base member initializer list (for m_commandString)
}
}
-/*
- * UI update events
- */
+// ----------------------------------------------------------------------------
+// wxUpdateUIEvent
+// ----------------------------------------------------------------------------
#if wxUSE_LONGLONG
wxLongLong wxUpdateUIEvent::sm_lastUpdate = 0;
#endif
}
-/*
- * Scroll events
- */
+// ----------------------------------------------------------------------------
+// wxScrollEvent
+// ----------------------------------------------------------------------------
wxScrollEvent::wxScrollEvent(wxEventType commandType,
int id,
m_commandInt = pos;
}
-/*
- * ScrollWin events
- */
+// ----------------------------------------------------------------------------
+// wxScrollWinEvent
+// ----------------------------------------------------------------------------
wxScrollWinEvent::wxScrollWinEvent(wxEventType commandType,
int pos,
m_commandInt = pos;
}
-/*
- * Mouse events
- *
- */
+// ----------------------------------------------------------------------------
+// wxMouseEvent
+// ----------------------------------------------------------------------------
wxMouseEvent::wxMouseEvent(wxEventType commandType)
{
}
}
-bool wxMouseEvent::ButtonIsDown(int but) const
-{
- switch (but)
- {
- default:
- wxFAIL_MSG(wxT("invalid parameter in wxMouseEvent::ButtonIsDown"));
- // fall through
-
- case wxMOUSE_BTN_ANY:
- return LeftIsDown() || MiddleIsDown() || RightIsDown() || Aux1Down() || Aux2Down();
-
- case wxMOUSE_BTN_LEFT:
- return LeftIsDown();
-
- case wxMOUSE_BTN_MIDDLE:
- return MiddleIsDown();
-
- case wxMOUSE_BTN_RIGHT:
- return RightIsDown();
-
- case wxMOUSE_BTN_AUX1:
- return Aux1IsDown();
-
- case wxMOUSE_BTN_AUX2:
- return Aux2IsDown();
- }
-}
-
int wxMouseEvent::GetButton() const
{
for ( int i = 1; i < wxMOUSE_BTN_MAX; i++ )
return pt;
}
-
-/*
- * Keyboard event
- *
- */
+// ----------------------------------------------------------------------------
+// wxKeyEvent
+// ----------------------------------------------------------------------------
wxKeyEvent::wxKeyEvent(wxEventType type)
{
m_eventType = type;
m_keyCode = 0;
- m_scanCode = 0;
#if wxUSE_UNICODE
m_uniChar = 0;
#endif
m_y = evt.m_y;
m_keyCode = evt.m_keyCode;
-
- m_scanCode = evt.m_scanCode;
m_rawCode = evt.m_rawCode;
m_rawFlags = evt.m_rawFlags;
#endif
}
+bool wxKeyEvent::IsKeyInCategory(int category) const
+{
+ switch ( GetKeyCode() )
+ {
+ case WXK_LEFT:
+ case WXK_RIGHT:
+ case WXK_UP:
+ case WXK_DOWN:
+ case WXK_NUMPAD_LEFT:
+ case WXK_NUMPAD_RIGHT:
+ case WXK_NUMPAD_UP:
+ case WXK_NUMPAD_DOWN:
+ return (category & WXK_CATEGORY_ARROW) != 0;
+
+ case WXK_PAGEDOWN:
+ case WXK_END:
+ case WXK_NUMPAD_PAGEUP:
+ case WXK_NUMPAD_PAGEDOWN:
+ return (category & WXK_CATEGORY_PAGING) != 0;
+
+ case WXK_HOME:
+ case WXK_PAGEUP:
+ case WXK_NUMPAD_HOME:
+ case WXK_NUMPAD_END:
+ return (category & WXK_CATEGORY_JUMP) != 0;
+
+ case WXK_TAB:
+ case WXK_NUMPAD_TAB:
+ return (category & WXK_CATEGORY_TAB) != 0;
+
+ case WXK_BACK:
+ case WXK_DELETE:
+ case WXK_NUMPAD_DELETE:
+ return (category & WXK_CATEGORY_CUT) != 0;
+
+ default:
+ return false;
+ }
+}
+
+// ----------------------------------------------------------------------------
+// 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)
{
m_size = 0;
}
-#if defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING
+#if wxUSE_MEMORY_TRACING
// Clear all tables
void wxEventHashTable::ClearAll()
}
}
-#endif // __WXDEBUG__ && wxUSE_MEMORY_TRACING
+#endif // wxUSE_MEMORY_TRACING
bool wxEventHashTable::HandleEvent(wxEvent &event, wxEvtHandler *self)
{
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 )
{
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;
}
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
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;
}
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()
{
// 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 );
// 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;
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
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
{
if ( wxTheApp )
{
-/*
- CANNOT ENABLE: ProcessEvent() must always immediately process the event!
-
- if (wxTheApp->IsYielding() &&
- !wxTheApp->IsEventAllowedInsideYield(event.GetEventCategory()))
- {
- wxEvent* queuedEv = event.Clone();
-
- // queue this event rather than processing it now
- QueueEvent(queuedEv);
- // the wxWakeUpIdle call shouldn't probably be done
- // in this context (there's wxYield in the call stack)
-
- return true;
- // it's not completely true that the event was processed;
- // but we cannot even say it was skipped or discarded...
- }
- //else: either we're not inside a wxYield() call or if we are,
- // we can process this event immediately.
-*/
-
int rc = wxTheApp->FilterEvent(event);
if ( rc != -1 )
{
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)
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
}
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 )
#endif // wxUSE_EXCEPTIONS
}
-
bool wxEvtHandler::SearchEventTable(wxEventTable& table, wxEvent& event)
{
const wxEventType eventType = event.GetEventType();
return false;
}
-void wxEvtHandler::DoConnect(int id,
- int lastId,
- wxEventType eventType,
- wxEventFunctor *func,
- wxObject *userData)
+void wxEvtHandler::DoBind(int id,
+ int lastId,
+ wxEventType eventType,
+ wxEventFunctor *func,
+ wxObject *userData)
{
wxDynamicEventTableEntry *entry =
new wxDynamicEventTableEntry(eventType, id, lastId, func, userData);
}
bool
-wxEvtHandler::DoDisconnect(int id,
- int lastId,
- wxEventType eventType,
- const wxEventFunctor& func,
- wxObject *userData)
+wxEvtHandler::DoUnbind(int id,
+ int lastId,
+ wxEventType eventType,
+ const wxEventFunctor& func,
+ wxObject *userData)
{
if (!m_dynamicEvents)
return false;
if ((entry->m_id == id) &&
((entry->m_lastId == lastId) || (lastId == wxID_ANY)) &&
((entry->m_eventType == eventType) || (eventType == wxEVT_NULL)) &&
- entry->m_fn->Matches(func) &&
+ entry->m_fn->IsMatching(func) &&
((entry->m_callbackUserData == userData) || !userData))
{
delete entry->m_callbackUserData;