Add wxEventFilter and related functionality.

Allow defining event filters to globally pre-process all application events
without having to override wxApp::FilterEvent().

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@69794 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2011-11-22 13:18:50 +00:00
parent feb32e3165
commit 58cc15871d
18 changed files with 350 additions and 24 deletions

View File

@@ -25,6 +25,7 @@
#endif
#include "wx/event.h"
#include "wx/eventfilter.h"
#include "wx/evtloop.h"
#ifndef WX_PRECOMP
@@ -1132,6 +1133,43 @@ bool wxEvtHandler::IsUnlinked() const
m_nextHandler == NULL;
}
wxEventFilter* wxEvtHandler::ms_filterList = NULL;
/* static */ void wxEvtHandler::AddFilter(wxEventFilter* filter)
{
wxCHECK_RET( filter, "NULL filter" );
filter->m_next = ms_filterList;
ms_filterList = filter;
}
/* static */ void wxEvtHandler::RemoveFilter(wxEventFilter* filter)
{
wxEventFilter* prev = NULL;
for ( wxEventFilter* f = ms_filterList; f; f = f->m_next )
{
if ( f == filter )
{
// Set the previous list element or the list head to the next
// element.
if ( prev )
prev->m_next = f->m_next;
else
ms_filterList = f->m_next;
// Also reset the next pointer in the filter itself just to avoid
// having possibly dangling pointers, even though it's not strictly
// necessary.
f->m_next = NULL;
// Skip the assert below.
return;
}
}
wxFAIL_MSG( "Filter not found" );
}
#if wxUSE_THREADS
bool wxEvtHandler::ProcessThreadEvent(const wxEvent& event)
@@ -1360,23 +1398,24 @@ bool wxEvtHandler::TryAfter(wxEvent& event)
bool wxEvtHandler::ProcessEvent(wxEvent& event)
{
// The very first thing we do is to allow the application to hook into
// event processing in order to globally pre-process all events.
// The very first thing we do is to allow any registered filters to hook
// into event processing in order to globally pre-process all events.
//
// 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() )
{
if ( wxTheApp )
for ( wxEventFilter* f = ms_filterList; f; f = f->m_next )
{
int rc = wxTheApp->FilterEvent(event);
if ( rc != -1 )
int rc = f->FilterEvent(event);
if ( rc != wxEventFilter::Event_Skip )
{
wxASSERT_MSG( rc == 1 || rc == 0,
"unexpected wxApp::FilterEvent return value" );
wxASSERT_MSG( rc == wxEventFilter::Event_Ignore ||
rc == wxEventFilter::Event_Processed,
"unexpected FilterEvent() return value" );
return rc != 0;
return rc != wxEventFilter::Event_Ignore;
}
//else: proceed normally
}