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:
parent
b5a98acdf2
commit
1648d51bcb
@ -44,6 +44,25 @@ The type of the event, such as wxEVENT\_TYPE\_BUTTON\_COMMAND.
|
||||
|
||||
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}
|
||||
@ -92,13 +111,13 @@ such as wxEVENT\_TYPE\_BUTTON\_COMMAND.
|
||||
|
||||
\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.
|
||||
|
||||
@ -108,6 +127,23 @@ 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}}
|
||||
@ -134,6 +170,13 @@ Sets the timestamp for the event.
|
||||
|
||||
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}}
|
||||
@ -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
|
||||
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.
|
||||
\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
|
||||
@ -182,12 +184,13 @@ event.
|
||||
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}
|
||||
|
@ -9,8 +9,8 @@
|
||||
// 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"
|
||||
@ -335,6 +335,17 @@ END_DECLARE_EVENT_TYPES()
|
||||
|
||||
#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.).
|
||||
@ -374,30 +385,108 @@ public:
|
||||
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
|
||||
@ -1119,7 +1208,7 @@ private:
|
||||
};
|
||||
|
||||
// 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:
|
||||
@ -2635,5 +2724,5 @@ wxWindow* wxFindFocusDescendant(wxWindow* ancestor);
|
||||
|
||||
#endif // wxUSE_GUI
|
||||
|
||||
#endif
|
||||
// _WX_EVENTH__
|
||||
#endif // _WX_EVENT_H__
|
||||
|
||||
|
@ -339,6 +339,7 @@ wxEvent::wxEvent(int theId, wxEventType commandType )
|
||||
m_skipped = FALSE;
|
||||
m_callbackUserData = (wxObject *) NULL;
|
||||
m_isCommandEvent = FALSE;
|
||||
m_propagationLevel = wxEVENT_PROPAGATE_NONE;
|
||||
}
|
||||
|
||||
wxEvent::wxEvent(const wxEvent &src)
|
||||
@ -350,6 +351,7 @@ 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)
|
||||
{
|
||||
}
|
||||
|
||||
@ -370,6 +372,9 @@ wxCommandEvent::wxCommandEvent(wxEventType commandType, int theId)
|
||||
m_extraLong = 0;
|
||||
m_commandInt = 0;
|
||||
m_isCommandEvent = TRUE;
|
||||
|
||||
// the command events are propagated upwards by default
|
||||
m_propagationLevel = wxEVENT_PROPAGATE_MAX;
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user