IMPLEMENT_DYNAMIC_CLASS(wxEvtHandler, wxObject)
IMPLEMENT_ABSTRACT_CLASS(wxEvent, wxObject)
IMPLEMENT_DYNAMIC_CLASS(wxIdleEvent, wxEvent)
+ IMPLEMENT_DYNAMIC_CLASS(wxThreadEvent, wxEvent)
#endif // wxUSE_BASE
#if wxUSE_GUI
IMPLEMENT_DYNAMIC_CLASS(wxCommandEvent, wxEvent)
- IMPLEMENT_DYNAMIC_CLASS(wxThreadEvent, wxCommandEvent)
IMPLEMENT_DYNAMIC_CLASS(wxNotifyEvent, wxCommandEvent)
IMPLEMENT_DYNAMIC_CLASS(wxScrollEvent, wxCommandEvent)
IMPLEMENT_DYNAMIC_CLASS(wxScrollWinEvent, wxEvent)
wxEventHashTable wxEvtHandler::sm_eventHashTable(wxEvtHandler::sm_eventTable);
const wxEventTableEntry wxEvtHandler::sm_eventTableEntries[] =
- { DECLARE_EVENT_TABLE_TERMINATOR() };
+ { wxDECLARE_EVENT_TABLE_TERMINATOR() };
// wxUSE_MEMORY_TRACING considers memory freed from the static objects dtors
const wxEventType wxEVT_FIRST = 10000;
const wxEventType wxEVT_USER_FIRST = wxEVT_FIRST + 2000;
+const wxEventType wxEVT_NULL = wxNewEventType();
-DEFINE_EVENT_TYPE(wxEVT_NULL)
wxDEFINE_EVENT( wxEVT_IDLE, wxIdleEvent );
+// Thread event
+wxDEFINE_EVENT( wxEVT_THREAD, wxThreadEvent );
+
#endif // wxUSE_BASE
#if wxUSE_GUI
// Character input event type
wxDEFINE_EVENT( wxEVT_CHAR, wxKeyEvent );
+wxDEFINE_EVENT( wxEVT_AFTER_CHAR, wxKeyEvent );
wxDEFINE_EVENT( wxEVT_CHAR_HOOK, wxKeyEvent );
wxDEFINE_EVENT( wxEVT_NAVIGATION_KEY, wxNavigationKeyEvent );
wxDEFINE_EVENT( wxEVT_KEY_DOWN, wxKeyEvent );
wxDEFINE_EVENT( wxEVT_HELP, wxHelpEvent );
wxDEFINE_EVENT( wxEVT_DETAILED_HELP, wxHelpEvent );
-// Thread event
-wxDEFINE_EVENT( wxEVT_COMMAND_THREAD, wxThreadEvent );
-
#endif // wxUSE_GUI
#if wxUSE_BASE
m_id = theId;
m_skipped = false;
m_callbackUserData = NULL;
+ m_handlerToProcessOnlyIn = NULL;
m_isCommandEvent = false;
m_propagationLevel = wxEVENT_PROPAGATE_NONE;
m_wasProcessed = false;
- m_processHereOnly = false;
}
wxEvent::wxEvent(const wxEvent& src)
, m_timeStamp(src.m_timeStamp)
, m_id(src.m_id)
, m_callbackUserData(src.m_callbackUserData)
+ , m_handlerToProcessOnlyIn(NULL)
, m_propagationLevel(src.m_propagationLevel)
, m_skipped(src.m_skipped)
, m_isCommandEvent(src.m_isCommandEvent)
, m_wasProcessed(false)
- , m_processHereOnly(false)
{
}
m_timeStamp = src.m_timeStamp;
m_id = src.m_id;
m_callbackUserData = src.m_callbackUserData;
+ m_handlerToProcessOnlyIn = NULL;
m_propagationLevel = src.m_propagationLevel;
m_skipped = src.m_skipped;
m_isCommandEvent = src.m_isCommandEvent;
- // don't change m_wasProcessed nor m_processHereOnly
+ // don't change m_wasProcessed
return *this;
}
{
m_clientData = NULL;
m_clientObject = NULL;
- m_extraLong = 0;
- m_commandInt = 0;
m_isCommandEvent = true;
// the command events are propagated upwards by default
((win->GetExtraStyle() & wxWS_EX_PROCESS_UI_UPDATES) == 0)))
return false;
+ // Don't update children of the hidden windows: this is useless as any
+ // change to their state won't be seen by the user anyhow. Notice that this
+ // argument doesn't apply to the hidden windows (with visible parent)
+ // themselves as they could be shown by their EVT_UPDATE_UI handler.
+ if ( win->GetParent() && !win->GetParent()->IsShownOnScreen() )
+ return false;
+
if (sm_updateInterval == -1)
return false;
wxKeyEvent::wxKeyEvent(wxEventType type)
{
m_eventType = type;
- m_keyCode = 0;
+ m_keyCode = WXK_NONE;
#if wxUSE_UNICODE
- m_uniChar = 0;
+ m_uniChar = WXK_NONE;
#endif
}
delete eTTnode;
}
- delete[] m_eventTypeTable;
- m_eventTypeTable = NULL;
+ wxDELETEA(m_eventTypeTable);
m_size = 0;
}
table = table->baseTable;
}
- // Lets free some memory.
+ // Let's free some memory.
size_t i;
for(i = 0; i < m_size; i++)
{
// Short circuit the event processing logic if we're requested to process
// this event in this handler only, see DoTryChain() for more details.
- if ( event.ShouldProcessHereOnly() )
- return ProcessEventHere(event);
+ if ( event.ShouldProcessOnlyIn(this) )
+ return TryBeforeAndHere(event);
// Try to process the event in this handler itself.
if ( ProcessEventLocally(event) )
- return true;
+ {
+ // It is possible that DoTryChain() called from ProcessEventLocally()
+ // returned true but the event was not really processed: this happens
+ // if a custom handler ignores the request to process the event in this
+ // handler only and in this case we should skip the post processing
+ // done in TryAfter() but still return the correct value ourselves to
+ // indicate whether we did or did not find a handler for this event.
+ return !event.GetSkipped();
+ }
// If we still didn't find a handler, propagate the event upwards the
// window chain and/or to the application object.
bool wxEvtHandler::ProcessEventLocally(wxEvent& event)
{
- // First try the hooks which should be called before our own handlers
- if ( TryBefore(event) )
- return true;
-
- // Then try this handler itself, notice that we should not call
- // ProcessEvent() on this one as we're already called from it, which
- // explains why we do it here and not in DoTryChain()
- if ( ProcessEventHere(event) )
- return true;
-
- // Finally try the event handlers chained to this one,
- if ( DoTryChain(event) )
- return true;
-
- // And return false to indicate that we didn't find any handler at this
- // level.
- return false;
+ // Try the hooks which should be called before our own handlers and this
+ // handler itself first. Notice that we should not call ProcessEvent() on
+ // this one as we're already called from it, which explains why we do it
+ // here and not in DoTryChain()
+ return TryBeforeAndHere(event) || DoTryChain(event);
}
bool wxEvtHandler::DoTryChain(wxEvent& event)
// ProcessEvent() from which we were called or will be done by it when
// we return.
//
- // However we must call ProcessEvent() and not ProcessEventHere()
- // because the existing code (including some in wxWidgets itself)
- // expects the overridden ProcessEvent() in its custom event handlers
- // pushed on a window to be called.
+ // However we must call ProcessEvent() and not TryHereOnly() because the
+ // existing code (including some in wxWidgets itself) expects the
+ // overridden ProcessEvent() in its custom event handlers pushed on a
+ // window to be called.
//
// So we must call ProcessEvent() but it must not do what it usually
- // does. To resolve this paradox we pass a special "process here only"
- // flag to ProcessEvent() via the event object itself. This ensures
- // that if our own, base class, version is called, it will just call
- // ProcessEventHere() and won't do anything else, just as we want it to.
- wxEventProcessHereOnly processHereOnly(event);
+ // does. To resolve this paradox we set up a special flag inside the
+ // object itself to let ProcessEvent() know that it shouldn't do any
+ // pre/post-processing for this event if it gets it. Note that this
+ // only applies to this handler, if the event is passed to another one
+ // by explicitly calling its ProcessEvent(), pre/post-processing should
+ // be done as usual.
+ //
+ // Final complication is that if the implementation of ProcessEvent()
+ // called wxEvent::DidntHonourProcessOnlyIn() (as the gross hack that
+ // is wxScrollHelperEvtHandler::ProcessEvent() does) and ignored our
+ // request to process event in this handler only, we have to compensate
+ // for it by not processing the event further because this was already
+ // done by that rogue event handler.
+ wxEventProcessInHandlerOnly processInHandlerOnly(event, h);
if ( h->ProcessEvent(event) )
+ {
+ // Make sure "skipped" flag is not set as the event was really
+ // processed in this case. Normally it shouldn't be set anyhow but
+ // make sure just in case the user code does something strange.
+ event.Skip(false);
+
return true;
+ }
+
+ if ( !event.ShouldProcessOnlyIn(h) )
+ {
+ // Still return true to indicate that no further processing should
+ // be undertaken but ensure that "skipped" flag is set so that the
+ // caller knows that the event was not really processed.
+ event.Skip();
+
+ return true;
+ }
}
return false;
}
-bool wxEvtHandler::ProcessEventHere(wxEvent& event)
+bool wxEvtHandler::TryHereOnly(wxEvent& event)
{
// If the event handler is disabled it doesn't process any events
if ( !GetEvtHandlerEnabled() )