Identifier for the window.
+\membersection{wxEvent::m\_propagationLevel}
+
+\member{int}{m\_propagationLevel}
+
+Indicates how many levels the event can propagate. This member is protected and
+should typically only be set in the constructors of the derived classes. It
+may be temporarily changed by \helpref{StopPropagation}{wxeventstoppropagation}
+and \helpref{ResumePropagation}{wxeventresumepropagation} and tested with
+\helpref{ShouldPropagate}{wxeventshouldpropagate}.
+
+The initial value is set to either {\tt wxEVENT\_PROPAGATION\_NONE} (by
+default) meaning that the event shouldn't be propagated at all or to
+{\tt wxEVENT\_PROPAGATION\_MAX} (for command events) meaning that it should be
+propagated as much as necessary.
+
+Any positive number means that the event should be propagated but no more than
+the given number of times. E.g. the propagation level may be set to $1$ to
+propagate the event to its parent only, but not to its grandparent.
+
\membersection{wxEvent::m\_skipped}
\member{bool}{m\_skipped}
\membersection{wxEvent::GetId}
-\func{int}{GetId}{\void}
+\constfunc{int}{GetId}{\void}
Returns the identifier associated with this event, such as a button command id.
\membersection{wxEvent::GetSkipped}
-\func{bool}{GetSkipped}{\void}
+\constfunc{bool}{GetSkipped}{\void}
Returns true if the event handler should be skipped, false otherwise.
Gets the timestamp for the event.
+\membersection{wxEvent::IsCommandEvent}\label{wxeventiscommandevent}
+
+\constfunc{bool}{IsCommandEvent}{\void}
+
+Returns true if the event is or is derived from
+\helpref{wxCommandEvent}{wxcommandevent} else it returns false.
+Note: Exists only for optimization purposes.
+
+
+\membersection{wxEvent::ResumePropagation}\label{wxeventresumepropagation}
+
+\func{void}{ResumePropagation}{\param{int }{propagationLevel}}
+
+Sets the propagation level to the given value (for example returned from an
+earlier call to \helpref{StopPropagation}{wxeventstoppropagation}).
+
+
\membersection{wxEvent::SetEventObject}
\func{void}{SetEventObject}{\param{wxObject* }{object}}
Sets the originating object.
+\membersection{wxEvent::ShouldPropagate}\label{wxeventshouldpropagate}
+
+\constfunc{bool}{ShouldPropagate}{\void}
+
+Test if this event should be propagated or not, i.e. if the propagation level
+is currently greater than $0$.
+
\membersection{wxEvent::Skip}\label{wxeventskip}
\func{void}{Skip}{\param{bool}{ skip = true}}
event handler should be skipped, and the next valid handler used
instead.
+\membersection{wxEvent::StopPropagation}
+
+\func{int}{StopPropagation}{\void}\label{wxeventstoppropagation}
+
+Stop the event from propagating to its parent window.
+
+Returns the old propagation level value which may be later passed to
+\helpref{ResumePropagation}{wxeventresumepropagation} to allow propagating the
+event again.
+
+
in which case the function exits.
\item The search is applied down the entire chain of event handlers (usually the chain has a length
of one). If this succeeds, the function exits.
-\item If the object is a wxWindow and the event is a wxCommandEvent, {\bf ProcessEvent} is
-recursively applied to the parent window's event handler. If this returns true, the function exits.
+\item If the object is a wxWindow and the event is set to set to propagate (in the library only
+wxCommandEvent based events are set to propagate), {\bf ProcessEvent} is recursively applied
+to the parent window's event handler. If this returns true, the function exits.
\item Finally, {\bf ProcessEvent} is called on the wxApp object.
\end{enumerate}
{\bf Pay close attention to Step 5.} People often overlook or get
confused by this powerful feature of the wxWindows event processing
-system. To put it a different way, events derived either directly or
-indirectly from wxCommandEvent will travel up the containment
-hierarchy from child to parent until an event handler is found that
-doesn't call event.Skip(). Events not derived from wxCommandEvent are
-sent only to the window they occurred in and then stop.
+system. To put it a different way, events set to propagate
+(\helpref{See: wxEvent::ShouldPropagate}{wxeventshouldpropagate})
+(most likely derived either directly or indirectly from wxCommandEvent)
+will travel up the containment hierarchy from child to parent until the
+maximal propagation level is reached or an event handler is found that
+doesn't call \helpref{event.Skip()}{wxeventskip}.
Finally, there is another additional complication (which, in fact, simplifies
life of wxWindows programmers significantly): when propagating the command
Note that your application may wish to override ProcessEvent to redirect processing of
events. This is done in the document/view framework, for example, to allow event handlers
to be defined in the document or view. To test for command events (which will probably
-be the only events you wish to redirect), you may use wxEvent::IsCommandEvent for
-efficiency, instead of using the slower run-time type system.
+be the only events you wish to redirect), you may use
+\helpref{wxEvent::IsCommandEvent}{wxeventiscommandevent} for efficiency,
+instead of using the slower run-time type system.
As mentioned above, only command events are recursively applied to the parents event
-handler. As this quite often causes confusion for users, here is a list of system
-events which will NOT get sent to the parent's event handler:
+handler in the libary itself. As this quite often causes confusion for users,
+here is a list of system events which will NOT get sent to the parent's event handler:
\begin{twocollist}\itemsep=0pt
\twocolitem{\helpref{wxEvent}{wxevent}}{The event base class}
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
-#ifndef _WX_EVENTH__
-#define _WX_EVENTH__
+#ifndef _WX_EVENT_H__
+#define _WX_EVENT_H__
#if defined(__GNUG__) && !defined(__APPLE__)
#pragma interface "event.h"
#endif // WXWIN_COMPATIBILITY
+// the predefined constants for the number of times we propagate event
+// upwards window child-parent chain
+enum Propagation_state
+{
+ // don't propagate it at all
+ wxEVENT_PROPAGATE_NONE = 0,
+
+ // propagate it until it is processed
+ wxEVENT_PROPAGATE_MAX = INT_MAX
+};
+
/*
* wxWindows events, covering all interesting things that might happen
* (button clicking, resizing, setting text in widgets, etc.).
void Skip(bool skip = TRUE) { m_skipped = skip; }
bool GetSkipped() const { return m_skipped; };
- // Implementation only: this test is explicitlty anti OO and this functions
- // exists only for optimization purposes.
- bool IsCommandEvent() const { return m_isCommandEvent; }
-
// this function is used to create a copy of the event polymorphically and
// all derived classes must implement it because otherwise wxPostEvent()
// for them wouldn't work (it needs to do a copy of the event)
virtual wxEvent *Clone() const = 0;
+ // Implementation only: this test is explicitlty anti OO and this functions
+ // exists only for optimization purposes.
+ bool IsCommandEvent() const { return m_isCommandEvent; }
+
+ // Determine if this event should be propagating to the parent window.
+ bool ShouldPropagate() const
+ { return m_propagationLevel != wxEVENT_PROPAGATE_NONE; }
+
+ // Stop an event from propagating to its parent window, returns the old
+ // propagation level value
+ int StopPropagation()
+ {
+ int propagationLevel = m_propagationLevel;
+ m_propagationLevel = wxEVENT_PROPAGATE_NONE;
+ return propagationLevel;
+ }
+
+ // Resume the event propagation by restoring the propagation level
+ // (returned by StopPropagation())
+ void ResumePropagation(int propagationLevel)
+ {
+ m_propagationLevel = propagationLevel;
+ }
+
public:
wxObject* m_eventObject;
wxEventType m_eventType;
long m_timeStamp;
int m_id;
wxObject* m_callbackUserData;
+
+protected:
+ // the propagation level: while it is positive, we propagate the event to
+ // the parent window (if any)
+ //
+ // this one doesn't have to be public, we don't have to worry about
+ // backwards compatibility as it is new
+ int m_propagationLevel;
+
+public:
bool m_skipped;
bool m_isCommandEvent;
-
+
private:
+ // it needs to access our m_propagationLevel
+ friend class WXDLLIMPEXP_BASE wxPropagateOnce;
+
DECLARE_ABSTRACT_CLASS(wxEvent)
};
+/*
+ * Helper class to temporarily change an event not to propagate.
+ */
+class WXDLLIMPEXP_BASE wxPropagationDisabler
+{
+public:
+ wxPropagationDisabler(wxEvent& event) : m_event(event)
+ {
+ m_propagationLevelOld = m_event.StopPropagation();
+ }
+
+ ~wxPropagationDisabler()
+ {
+ m_event.ResumePropagation(m_propagationLevelOld);
+ }
+
+private:
+ wxEvent& m_event;
+ int m_propagationLevelOld;
+};
+
+/*
+ * Another one to temporarily lower propagation level.
+ */
+class WXDLLIMPEXP_BASE wxPropagateOnce
+{
+public:
+ wxPropagateOnce(wxEvent& event) : m_event(event)
+ {
+ wxASSERT_MSG( m_event.m_propagationLevel > 0,
+ _T("shouldn't be used unless ShouldPropagate()!") );
+
+ m_event.m_propagationLevel--;
+ }
+
+ ~wxPropagateOnce()
+ {
+ m_event.m_propagationLevel++;
+ }
+
+private:
+ wxEvent& m_event;
+};
+
#if wxUSE_GUI
+
// Item or menu event class
/*
wxEVT_COMMAND_BUTTON_CLICKED
};
// wxChildFocusEvent notifies the parent that a child has got the focus: unlike
-// wxFocusEvent it is propgated upwards the window chain
+// wxFocusEvent it is propagated upwards the window chain
class WXDLLIMPEXP_CORE wxChildFocusEvent : public wxCommandEvent
{
public:
#endif // wxUSE_GUI
-#endif
- // _WX_EVENTH__
+#endif // _WX_EVENT_H__
+
m_skipped = FALSE;
m_callbackUserData = (wxObject *) NULL;
m_isCommandEvent = FALSE;
+ m_propagationLevel = wxEVENT_PROPAGATE_NONE;
}
wxEvent::wxEvent(const wxEvent &src)
, m_callbackUserData(src.m_callbackUserData)
, m_skipped(src.m_skipped)
, m_isCommandEvent(src.m_isCommandEvent)
+ , m_propagationLevel(src.m_propagationLevel)
{
}
m_extraLong = 0;
m_commandInt = 0;
m_isCommandEvent = TRUE;
+
+ // the command events are propagated upwards by default
+ m_propagationLevel = wxEVENT_PROPAGATE_MAX;
}
/*