From c4fa5aa7b0e550b2779cc6fa99f6d588724da304 Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Sun, 4 Feb 2007 00:12:50 +0000
Subject: [PATCH] added wxEventBlocker class (patch 1622444)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@44352 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/latex/wx/classes.tex    |  1 +
 docs/latex/wx/evtblocker.tex | 69 ++++++++++++++++++++++++++++++++++++
 include/wx/event.h           | 27 ++++++++++++++
 src/common/event.cpp         | 34 ++++++++++++++++++
 4 files changed, 131 insertions(+)
 create mode 100644 docs/latex/wx/evtblocker.tex

diff --git a/docs/latex/wx/classes.tex b/docs/latex/wx/classes.tex
index 6bd13aaacf..50f5926823 100644
--- a/docs/latex/wx/classes.tex
+++ b/docs/latex/wx/classes.tex
@@ -130,6 +130,7 @@
 \input encconv.tex
 \input eraseevt.tex
 \input event.tex
+\input evtblocker.tex
 \input evthand.tex
 \input ffile.tex
 \input ffilestr.tex
diff --git a/docs/latex/wx/evtblocker.tex b/docs/latex/wx/evtblocker.tex
new file mode 100644
index 0000000000..ced50c7b06
--- /dev/null
+++ b/docs/latex/wx/evtblocker.tex
@@ -0,0 +1,69 @@
+\section{\class{wxEventBlocker}}\label{wxeventblocker}
+
+This class is a special event handler which allows to discard
+any event (or a set of event types) directed to a specific window.
+
+Example:
+
+\begin{verbatim}
+
+  {
+    // block all events directed to this window while
+    // we do the 1000 FuncWhichSendsEvents() calls
+    wxEventBlocker blocker(this);
+
+    for ( int i = 0; i < 1000; i++ )
+       FuncWhichSendsEvents(i);
+
+  } // ~wxEventBlocker called, old event handler is restored
+
+  // the event generated by this call will be processed
+  FuncWhichSendsEvents(0)
+\end{verbatim}
+
+
+\wxheading{Derived from}
+
+\helpref{wxEvtHandler}{wxevthandler}\\
+\helpref{wxObject}{wxobject}
+
+\wxheading{Include files}
+
+<wx/event.h>
+
+\wxheading{See also}
+
+\overview{Event handling overview}{eventhandlingoverview},
+\helpref{wxEvtHandler}{wxevthandler}
+
+
+\latexignore{\rtfignore{\wxheading{Members}}}
+
+\membersection{wxEventBlocker::wxEventBlocker}\label{wxeventblockerctor}
+
+\func{}{wxEventBlocker}{\param{wxWindow* }{win}, \param{wxEventType}{type = wxEVT\_ANY}}
+
+Constructs the blocker for the given window and for the given event type.
+If \arg{type} is \texttt{wxEVT\_ANY}, then all events for that window are
+blocked. You can call \helpref{Block}{wxeventblockerblock} after creation to
+add other event types to the list of events to block.
+
+Note that the \arg{win} window \textbf{must} remain alive until the
+wxEventBlocker object destruction.
+
+
+\membersection{wxEventBlocker::\destruct{wxEventBlocker}}\label{wxeventblockerdtor}
+
+\func{}{\destruct{wxEventBlocker}}{\void}
+
+Destructor. The blocker will remove itself from the chain of event handlers for
+the window provided in the constructor, thus restoring normal processing of
+events.
+
+
+\membersection{wxEventBlocker::Block}\label{wxeventblockerblock}
+
+\func{void}{Block}{\param{wxEventType }{eventType}}
+
+Adds to the list of event types which should be blocked the given \arg{eventType}.
+
diff --git a/include/wx/event.h b/include/wx/event.h
index 538c1be5d4..d4342e8b06 100644
--- a/include/wx/event.h
+++ b/include/wx/event.h
@@ -47,6 +47,8 @@ class WXDLLIMPEXP_BASE wxEvtHandler;
 
 typedef int wxEventType;
 
+#define wxEVT_ANY           ((wxEventType)-1)
+
 // this is used to make the event table entry type safe, so that for an event
 // handler only a function with proper parameter list can be given.
 #define wxStaticCastEvent(type, val) wx_static_cast(type, val)
@@ -467,6 +469,7 @@ private:
     DECLARE_NO_COPY_CLASS(wxPropagateOnce)
 };
 
+
 #if wxUSE_GUI
 
 
@@ -2570,6 +2573,30 @@ typedef void (wxEvtHandler::*wxEventFunction)(wxEvent&);
 
 #if wxUSE_GUI
 
+// ----------------------------------------------------------------------------
+// wxEventBlocker: helper class to temporarily disable event handling for a window
+// ----------------------------------------------------------------------------
+
+class WXDLLIMPEXP_BASE wxEventBlocker : public wxEvtHandler
+{
+public:
+    wxEventBlocker(wxWindow *win, wxEventType type = wxEVT_ANY);
+    virtual ~wxEventBlocker();
+
+    void Block(wxEventType type)
+    {
+        m_eventsToBlock.push_back(type);
+    }
+
+    virtual bool ProcessEvent(wxEvent& event);
+
+protected:
+    wxArrayInt m_eventsToBlock;
+    wxWindow *m_window;
+
+    DECLARE_NO_COPY_CLASS(wxEventBlocker)
+};
+
 typedef void (wxEvtHandler::*wxCommandEventFunction)(wxCommandEvent&);
 typedef void (wxEvtHandler::*wxScrollEventFunction)(wxScrollEvent&);
 typedef void (wxEvtHandler::*wxScrollWinEventFunction)(wxScrollWinEvent&);
diff --git a/src/common/event.cpp b/src/common/event.cpp
index 598b66ae99..06dbaf5644 100644
--- a/src/common/event.cpp
+++ b/src/common/event.cpp
@@ -1460,4 +1460,38 @@ wxWindow* wxFindFocusDescendant(wxWindow* ancestor)
     return focusWin;
 }
 
+// ----------------------------------------------------------------------------
+// wxEventBlocker
+// ----------------------------------------------------------------------------
+
+wxEventBlocker::wxEventBlocker(wxWindow *win, wxEventType type)
+{
+    wxCHECK_RET(win, wxT("Null window given to wxEventBlocker"));
+
+    m_window = win;
+
+    Block(type);
+    m_window->PushEventHandler(this);
+}
+
+wxEventBlocker::~wxEventBlocker()
+{
+    wxEvtHandler *popped = m_window->PopEventHandler(false);
+    wxCHECK_RET(popped == this, 
+        wxT("Don't push other event handlers into a window managed by wxEventBlocker!"));
+}
+
+bool wxEventBlocker::ProcessEvent(wxEvent& event)
+{
+    // should this event be blocked?
+    for ( size_t i = 0; i < m_eventsToBlock.size(); i++ )
+    {
+        wxEventType t = (wxEventType)m_eventsToBlock[i];
+        if ( t == wxEVT_ANY || t == event.GetEventType() )
+            return true;   // yes, it should: mark this event as processed
+    }
+
+    return false;
+}
+
 #endif // wxUSE_GUI
-- 
2.50.0

