allow to change the event propagation level (modified patch 743086)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@22068 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -44,6 +44,25 @@ The type of the event, such as wxEVENT\_TYPE\_BUTTON\_COMMAND.
|
|||||||
|
|
||||||
Identifier for the window.
|
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}
|
\membersection{wxEvent::m\_skipped}
|
||||||
|
|
||||||
\member{bool}{m\_skipped}
|
\member{bool}{m\_skipped}
|
||||||
@@ -92,13 +111,13 @@ such as wxEVENT\_TYPE\_BUTTON\_COMMAND.
|
|||||||
|
|
||||||
\membersection{wxEvent::GetId}
|
\membersection{wxEvent::GetId}
|
||||||
|
|
||||||
\func{int}{GetId}{\void}
|
\constfunc{int}{GetId}{\void}
|
||||||
|
|
||||||
Returns the identifier associated with this event, such as a button command id.
|
Returns the identifier associated with this event, such as a button command id.
|
||||||
|
|
||||||
\membersection{wxEvent::GetSkipped}
|
\membersection{wxEvent::GetSkipped}
|
||||||
|
|
||||||
\func{bool}{GetSkipped}{\void}
|
\constfunc{bool}{GetSkipped}{\void}
|
||||||
|
|
||||||
Returns true if the event handler should be skipped, false otherwise.
|
Returns true if the event handler should be skipped, false otherwise.
|
||||||
|
|
||||||
@@ -108,6 +127,23 @@ Returns true if the event handler should be skipped, false otherwise.
|
|||||||
|
|
||||||
Gets the timestamp for the event.
|
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}
|
\membersection{wxEvent::SetEventObject}
|
||||||
|
|
||||||
\func{void}{SetEventObject}{\param{wxObject* }{object}}
|
\func{void}{SetEventObject}{\param{wxObject* }{object}}
|
||||||
@@ -134,6 +170,13 @@ Sets the timestamp for the event.
|
|||||||
|
|
||||||
Sets the originating 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}
|
\membersection{wxEvent::Skip}\label{wxeventskip}
|
||||||
|
|
||||||
\func{void}{Skip}{\param{bool}{ skip = true}}
|
\func{void}{Skip}{\param{bool}{ skip = true}}
|
||||||
@@ -142,3 +185,14 @@ Called by an event handler to tell the event system that the
|
|||||||
event handler should be skipped, and the next valid handler used
|
event handler should be skipped, and the next valid handler used
|
||||||
instead.
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
@@ -142,18 +142,20 @@ class table is tried, and so on until no more tables exist or an appropriate fun
|
|||||||
in which case the function exits.
|
in which case the function exits.
|
||||||
\item The search is applied down the entire chain of event handlers (usually the chain has a length
|
\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.
|
of one). If this succeeds, the function exits.
|
||||||
\item If the object is a wxWindow and the event is a wxCommandEvent, {\bf ProcessEvent} is
|
\item If the object is a wxWindow and the event is set to set to propagate (in the library only
|
||||||
recursively applied to the parent window's event handler. If this returns true, the function exits.
|
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.
|
\item Finally, {\bf ProcessEvent} is called on the wxApp object.
|
||||||
\end{enumerate}
|
\end{enumerate}
|
||||||
|
|
||||||
{\bf Pay close attention to Step 5.} People often overlook or get
|
{\bf Pay close attention to Step 5.} People often overlook or get
|
||||||
confused by this powerful feature of the wxWindows event processing
|
confused by this powerful feature of the wxWindows event processing
|
||||||
system. To put it a different way, events derived either directly or
|
system. To put it a different way, events set to propagate
|
||||||
indirectly from wxCommandEvent will travel up the containment
|
(\helpref{See: wxEvent::ShouldPropagate}{wxeventshouldpropagate})
|
||||||
hierarchy from child to parent until an event handler is found that
|
(most likely derived either directly or indirectly from wxCommandEvent)
|
||||||
doesn't call event.Skip(). Events not derived from wxCommandEvent are
|
will travel up the containment hierarchy from child to parent until the
|
||||||
sent only to the window they occurred in and then stop.
|
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
|
Finally, there is another additional complication (which, in fact, simplifies
|
||||||
life of wxWindows programmers significantly): when propagating the command
|
life of wxWindows programmers significantly): when propagating the command
|
||||||
@@ -182,12 +184,13 @@ event.
|
|||||||
Note that your application may wish to override ProcessEvent to redirect processing of
|
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
|
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
|
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
|
be the only events you wish to redirect), you may use
|
||||||
efficiency, instead of using the slower run-time type system.
|
\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
|
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
|
handler in the libary itself. As this quite often causes confusion for users,
|
||||||
events which will NOT get sent to the parent's event handler:
|
here is a list of system events which will NOT get sent to the parent's event handler:
|
||||||
|
|
||||||
\begin{twocollist}\itemsep=0pt
|
\begin{twocollist}\itemsep=0pt
|
||||||
\twocolitem{\helpref{wxEvent}{wxevent}}{The event base class}
|
\twocolitem{\helpref{wxEvent}{wxevent}}{The event base class}
|
||||||
|
@@ -9,8 +9,8 @@
|
|||||||
// Licence: wxWindows licence
|
// Licence: wxWindows licence
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifndef _WX_EVENTH__
|
#ifndef _WX_EVENT_H__
|
||||||
#define _WX_EVENTH__
|
#define _WX_EVENT_H__
|
||||||
|
|
||||||
#if defined(__GNUG__) && !defined(__APPLE__)
|
#if defined(__GNUG__) && !defined(__APPLE__)
|
||||||
#pragma interface "event.h"
|
#pragma interface "event.h"
|
||||||
@@ -335,6 +335,17 @@ END_DECLARE_EVENT_TYPES()
|
|||||||
|
|
||||||
#endif // WXWIN_COMPATIBILITY
|
#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
|
* wxWindows events, covering all interesting things that might happen
|
||||||
* (button clicking, resizing, setting text in widgets, etc.).
|
* (button clicking, resizing, setting text in widgets, etc.).
|
||||||
@@ -374,30 +385,108 @@ public:
|
|||||||
void Skip(bool skip = TRUE) { m_skipped = skip; }
|
void Skip(bool skip = TRUE) { m_skipped = skip; }
|
||||||
bool GetSkipped() const { return m_skipped; };
|
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
|
// this function is used to create a copy of the event polymorphically and
|
||||||
// all derived classes must implement it because otherwise wxPostEvent()
|
// all derived classes must implement it because otherwise wxPostEvent()
|
||||||
// for them wouldn't work (it needs to do a copy of the event)
|
// for them wouldn't work (it needs to do a copy of the event)
|
||||||
virtual wxEvent *Clone() const = 0;
|
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:
|
public:
|
||||||
wxObject* m_eventObject;
|
wxObject* m_eventObject;
|
||||||
wxEventType m_eventType;
|
wxEventType m_eventType;
|
||||||
long m_timeStamp;
|
long m_timeStamp;
|
||||||
int m_id;
|
int m_id;
|
||||||
wxObject* m_callbackUserData;
|
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_skipped;
|
||||||
bool m_isCommandEvent;
|
bool m_isCommandEvent;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// it needs to access our m_propagationLevel
|
||||||
|
friend class WXDLLIMPEXP_BASE wxPropagateOnce;
|
||||||
|
|
||||||
DECLARE_ABSTRACT_CLASS(wxEvent)
|
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
|
#if wxUSE_GUI
|
||||||
|
|
||||||
|
|
||||||
// Item or menu event class
|
// Item or menu event class
|
||||||
/*
|
/*
|
||||||
wxEVT_COMMAND_BUTTON_CLICKED
|
wxEVT_COMMAND_BUTTON_CLICKED
|
||||||
@@ -1119,7 +1208,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// wxChildFocusEvent notifies the parent that a child has got the focus: unlike
|
// 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
|
class WXDLLIMPEXP_CORE wxChildFocusEvent : public wxCommandEvent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -2635,5 +2724,5 @@ wxWindow* wxFindFocusDescendant(wxWindow* ancestor);
|
|||||||
|
|
||||||
#endif // wxUSE_GUI
|
#endif // wxUSE_GUI
|
||||||
|
|
||||||
#endif
|
#endif // _WX_EVENT_H__
|
||||||
// _WX_EVENTH__
|
|
||||||
|
@@ -339,6 +339,7 @@ wxEvent::wxEvent(int theId, wxEventType commandType )
|
|||||||
m_skipped = FALSE;
|
m_skipped = FALSE;
|
||||||
m_callbackUserData = (wxObject *) NULL;
|
m_callbackUserData = (wxObject *) NULL;
|
||||||
m_isCommandEvent = FALSE;
|
m_isCommandEvent = FALSE;
|
||||||
|
m_propagationLevel = wxEVENT_PROPAGATE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxEvent::wxEvent(const wxEvent &src)
|
wxEvent::wxEvent(const wxEvent &src)
|
||||||
@@ -350,6 +351,7 @@ wxEvent::wxEvent(const wxEvent &src)
|
|||||||
, m_callbackUserData(src.m_callbackUserData)
|
, m_callbackUserData(src.m_callbackUserData)
|
||||||
, m_skipped(src.m_skipped)
|
, m_skipped(src.m_skipped)
|
||||||
, m_isCommandEvent(src.m_isCommandEvent)
|
, m_isCommandEvent(src.m_isCommandEvent)
|
||||||
|
, m_propagationLevel(src.m_propagationLevel)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,6 +372,9 @@ wxCommandEvent::wxCommandEvent(wxEventType commandType, int theId)
|
|||||||
m_extraLong = 0;
|
m_extraLong = 0;
|
||||||
m_commandInt = 0;
|
m_commandInt = 0;
|
||||||
m_isCommandEvent = TRUE;
|
m_isCommandEvent = TRUE;
|
||||||
|
|
||||||
|
// the command events are propagated upwards by default
|
||||||
|
m_propagationLevel = wxEVENT_PROPAGATE_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user