wx/dynload.h \
wx/encconv.h \
wx/event.h \
+ wx/eventfilter.h \
wx/evtloop.h \
wx/except.h \
wx/features.h \
wx/dynload.h \
wx/encconv.h \
wx/event.h \
+ wx/eventfilter.h \
wx/evtloop.h \
wx/except.h \
wx/features.h \
wx/dynload.h
wx/encconv.h
wx/event.h
+ wx/eventfilter.h
wx/evtloop.h
wx/except.h
wx/features.h
# End Source File\r
# Begin Source File\r
\r
+SOURCE=..\..\include\wx\eventfilter.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\include\wx\evtloop.h\r
# End Source File\r
# Begin Source File\r
RelativePath="..\..\include\wx\event.h">\r
</File>\r
<File\r
+ RelativePath="..\..\include\wx\eventfilter.h">
+ </File>
+ <File
RelativePath="..\..\include\wx\evtloop.h">\r
</File>\r
<File\r
>\r
</File>\r
<File\r
+ RelativePath="..\..\include\wx\eventfilter.h"
+ >
+ </File>
+ <File
RelativePath="..\..\include\wx\evtloop.h"\r
>\r
</File>\r
>\r
</File>\r
<File\r
+ RelativePath="..\..\include\wx\eventfilter.h"
+ >
+ </File>
+ <File
RelativePath="..\..\include\wx\evtloop.h"\r
>\r
</File>\r
- Fix parsing of negated long options in wxCmdLineParser (roed_bis).
- Fix crash in wxArray::insert() overload taking iterator range (wsu).
+- Added wxEventFilter class and wxEvtHandler::{Add,Remove}Filter().
All (GUI):
// ----------------------------------------------------------------------------
#include "wx/event.h" // for the base class
+#include "wx/eventfilter.h" // (and another one)
#include "wx/build.h"
#include "wx/cmdargs.h" // for wxCmdLineArgsArray used by wxApp::argv
#include "wx/init.h" // we must declare wxEntry()
// wxAppConsoleBase: wxApp for non-GUI applications
// ----------------------------------------------------------------------------
-class WXDLLIMPEXP_BASE wxAppConsoleBase : public wxEvtHandler
+class WXDLLIMPEXP_BASE wxAppConsoleBase : public wxEvtHandler,
+ public wxEventFilter
{
public:
// ctor and dtor
// event processing functions
// --------------------------
- // this method allows to filter all the events processed by the program, so
- // you should try to return quickly from it to avoid slowing down the
- // program to the crawl
- //
- // return value should be -1 to continue with the normal event processing,
- // or TRUE or FALSE to stop further processing and pretend that the event
- // had been already processed or won't be processed at all, respectively
+ // Implement the inherited wxEventFilter method but just return -1 from it
+ // to indicate that default processing should take place.
virtual int FilterEvent(wxEvent& event);
// return true if we're running event loop, i.e. if the events can
class WXDLLIMPEXP_FWD_BASE wxList;
class WXDLLIMPEXP_FWD_BASE wxEvent;
+class WXDLLIMPEXP_FWD_BASE wxEventFilter;
#if wxUSE_GUI
class WXDLLIMPEXP_FWD_CORE wxDC;
class WXDLLIMPEXP_FWD_CORE wxMenu;
bool IsUnlinked() const;
+ // Global event filters
+ // --------------------
+
+ // Add an event filter whose FilterEvent() method will be called for each
+ // and every event processed by wxWidgets. The filters are called in LIFO
+ // order and wxApp is registered as an event filter by default. The pointer
+ // must remain valid until it's removed with RemoveFilter() and is not
+ // deleted by wxEvtHandler.
+ static void AddFilter(wxEventFilter* filter);
+
+ // Remove a filter previously installed with AddFilter().
+ static void RemoveFilter(wxEventFilter* filter);
+
// Event queuing and processing
// ----------------------------
// try to process events in all handlers chained to this one
bool DoTryChain(wxEvent& event);
+ // Head of the event filter linked list.
+ static wxEventFilter* ms_filterList;
+
DECLARE_DYNAMIC_CLASS_NO_COPY(wxEvtHandler)
};
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: wx/eventfilter.h
+// Purpose: wxEventFilter class declaration.
+// Author: Vadim Zeitlin
+// Created: 2011-11-21
+// RCS-ID: $Id: wxhead.h,v 1.12 2010-04-22 12:44:51 zeitlin Exp $
+// Copyright: (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org>
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_EVENTFILTER_H_
+#define _WX_EVENTFILTER_H_
+
+#include "wx/defs.h"
+
+class WXDLLIMPEXP_FWD_BASE wxEvent;
+class WXDLLIMPEXP_FWD_BASE wxEvtHandler;
+
+// ----------------------------------------------------------------------------
+// wxEventFilter is used with wxEvtHandler::AddFilter() and ProcessEvent().
+// ----------------------------------------------------------------------------
+
+class wxEventFilter
+{
+public:
+ // Possible return values for FilterEvent().
+ //
+ // Notice that the values of these enum elements are fixed due to backwards
+ // compatibility constraints.
+ enum
+ {
+ // Process event as usual.
+ Event_Skip = -1,
+
+ // Don't process the event normally at all.
+ Event_Ignore = 0,
+
+ // Event was already handled, don't process it normally.
+ Event_Processed = 1
+ };
+
+ wxEventFilter()
+ {
+ m_next = NULL;
+ }
+
+ virtual ~wxEventFilter()
+ {
+ wxASSERT_MSG( !m_next, "Forgot to call wxEvtHandler::RemoveFilter()?" );
+ }
+
+ // This method allows to filter all the events processed by the program, so
+ // you should try to return quickly from it to avoid slowing down the
+ // program to the crawl.
+ //
+ // Return value should be -1 to continue with the normal event processing,
+ // or true or false to stop further processing and pretend that the event
+ // had been already processed or won't be processed at all, respectively.
+ virtual int FilterEvent(wxEvent& event) = 0;
+
+private:
+ // Objects of this class are made to be stored in a linked list in
+ // wxEvtHandler so put the next node ponter directly in the class itself.
+ wxEventFilter* m_next;
+
+ // And provide access to it for wxEvtHandler [only].
+ friend class wxEvtHandler;
+
+ wxDECLARE_NO_COPY_CLASS(wxEventFilter);
+};
+
+#endif // _WX_EVENTFILTER_H_
@see @ref overview_app, wxApp, wxAppTraits, wxEventLoopBase
*/
-class wxAppConsole : public wxEvtHandler
+class wxAppConsole : public wxEvtHandler,
+ public wxEventFilter
{
protected:
/**
virtual void ExitMainLoop();
/**
+ Overridden wxEventFilter method.
+
This function is called before processing any event and allows the application
- to preempt the processing of some events.
+ to preempt the processing of some events, see wxEventFilter
+ documentation for more information.
- If this method returns -1 the event is processed normally, otherwise either
- @true or @false should be returned and the event processing stops immediately
- considering that the event had been already processed (for the former return
- value) or that it is not going to be processed at all (for the latter one).
+ wxApp implementation of this method always return -1 indicating that
+ the event should be processed normally.
*/
virtual int FilterEvent(wxEvent& event);
//@}
+ /**
+ @name Global event filters.
+
+ Methods for working with the global list of event filters.
+
+ Event filters can be defined to pre-process all the events that happen
+ in an application, see wxEventFilter documentation for more information.
+ */
+ //@{
+
+ /**
+ Add an event filter whose FilterEvent() method will be called for each
+ and every event processed by wxWidgets.
+
+ The filters are called in LIFO order and wxApp is registered as an
+ event filter by default. The pointer must remain valid until it's
+ removed with RemoveFilter() and is not deleted by wxEvtHandler.
+
+ @since 2.9.3
+ */
+ static void AddFilter(wxEventFilter* filter);
+
+ /**
+ Remove a filter previously installed with AddFilter().
+
+ It's an error to remove a filter that hadn't been previously added or
+ was already removed.
+
+ @since 2.9.3
+ */
+ static void RemoveFilter(wxEventFilter* filter);
+
+ //@}
+
protected:
/**
Method called by ProcessEvent() before examining this object event
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: interface/wx/eventfilter.h
+// Purpose: wxEventFilter class documentation
+// Author: Vadim Zeitlin
+// Created: 2011-11-21
+// RCS-ID: $Id$
+// Copyright: (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org>
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ A global event filter for pre-processing all the events generated in the
+ program.
+
+ This is a very simple class which just provides FilterEvent() virtual
+ method to be called by wxEvtHandler before starting process of any event.
+ Thus, inheriting from this class and overriding FilterEvent() allows to
+ capture and possibly handle or ignore all the events happening in the
+ program. Of course, having event filters adds additional overhead to every
+ event processing and so should not be used lightly and your FilterEvent()
+ code should try to return as quickly as possible, especially for the events
+ it is not interested in.
+
+ An example of using this class:
+ @code
+ // This class allows to determine the last time the user has worked with
+ // this application:
+ class LastActivityTimeDetector : public wxEventFilter
+ {
+ public:
+ LastActivityTimeDetector()
+ {
+ wxEvtHandler::AddFilter(this);
+
+ m_last = wxDateTime::Now();
+ }
+
+ virtual ~LastActivityTimeDetector()
+ {
+ wxEvtHandler::RemoveFilter(this);
+ }
+
+ virtual int FilterEvent(wxEvent& event)
+ {
+ // Update the last user activity
+ const wxEventType t = event.GetEventType();
+ if ( t == wxEVT_KEY_DOWN || t == wxEVT_MOTION ||
+ t == wxEVT_LEFT_DOWN ||
+ t == wxEVT_RIGHT_DOWN ||
+ t == wxEVT_MIDDLE_DOWN )
+ {
+ m_last = wxDateTime::Now();
+ }
+
+ // Continue processing the event normally as well.
+ return Event_Skip;
+ }
+
+ // This function could be called periodically from some timer to
+ // do something (e.g. hide sensitive data or log out from remote
+ // server) if the user has been inactive for some time period.
+ bool IsInactiveFor(const wxTimeSpan& diff) const
+ {
+ return wxDateTime::Now() - diff > m_last;
+ }
+
+ private:
+ wxDateTime m_last;
+ };
+ @endcode
+
+ Notice that wxApp derives from wxEventFilter and is registered as an event
+ filter during its creation so you may also override FilterEvent() method in
+ your wxApp-derived class and, in fact, this is often the most convenient
+ way to do it. However creating a new class deriving directly from
+ wxEventFilter allows to isolate the event filtering code in its own
+ separate class and also to have several independent filters, if necessary.
+
+ @category{events}
+
+ @since 2.9.3
+ */
+class wxEventFilter
+{
+public:
+ /// Possible return values for FilterEvent().
+ enum
+ {
+ /// Process event as usual.
+ Event_Skip = -1,
+
+ /// Don't process the event normally at all.
+ Event_Ignore = 0,
+
+ /// Event was already handled, don't process it normally.
+ Event_Processed = 1
+ };
+
+ /**
+ Default constructor.
+
+ Constructor does not register this filter using
+ wxEvtHandler::AddFilter(), it's your responsibility to do it when
+ necessary.
+
+ Notice that the objects of this class can't be copied.
+ */
+ wxEventFilter();
+
+ /**
+ Destructor.
+
+ You must call wxEvtHandler::RemoveFilter() before destroying this
+ object (possibly from the derived class destructor), failure to do this
+ is indicated by an assert unless assertions are disabled.
+ */
+ virtual ~wxEventFilter();
+
+ /**
+ Override this method to implement event pre-processing.
+
+ This method allows to filter all the events processed by the program,
+ so you should try to return quickly from it to avoid slowing down the
+ program to the crawl.
+
+ Although the return type of this method is @c int, this is only due to
+ backwards compatibility concerns and the actual return value must be
+ one of the @c Event_XXX constants defined above:
+ - Event_Skip to continue processing the event normally (this should
+ be used in most cases).
+ - Event_Ignore to not process this event at all (this can be used
+ to suppress some events).
+ - Event_Processed to not process this event normally but indicate
+ that it was already processed by the event filter and so no default
+ processing should take place neither (this should only be used if
+ the filter really did process the event).
+ */
+ virtual int FilterEvent(wxEvent& event) = 0;
+};
wxDELETE(m_traits);
#endif
#endif
+
+ wxEvtHandler::AddFilter(this);
}
wxAppConsoleBase::~wxAppConsoleBase()
{
+ wxEvtHandler::RemoveFilter(this);
+
// we're being destroyed and using this object from now on may not work or
// even crash so don't leave dangling pointers to it
ms_appInstance = NULL;
int wxAppConsoleBase::FilterEvent(wxEvent& WXUNUSED(event))
{
// process the events normally by default
- return -1;
+ return Event_Skip;
}
void wxAppConsoleBase::DelayPendingEventHandler(wxEvtHandler* toDelay)
#endif
#include "wx/event.h"
+#include "wx/eventfilter.h"
#include "wx/evtloop.h"
#ifndef WX_PRECOMP
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)
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
}
wx/dynload.h
wx/encconv.h
wx/event.h
+wx/eventfilter.h
wx/evtloop.h
wx/except.h
wx/features.h
wx/dynload.h
wx/encconv.h
wx/event.h
+wx/eventfilter.h
wx/evtloop.h
wx/except.h
wx/features.h
wx/dynload.h
wx/encconv.h
wx/event.h
+wx/eventfilter.h
wx/evtloop.h
wx/except.h
wx/features.h