X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/58791ef89072afde66bfbb8a2419727695e57e63..0cc1991e2a3ae8df8f716d5a9bf1a59e2a17d0b3:/include/wx/event.h diff --git a/include/wx/event.h b/include/wx/event.h index 42d24634e4..338ce78a09 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -26,6 +26,8 @@ #include "wx/dynarray.h" #include "wx/thread.h" #include "wx/tracker.h" +#include "wx/typeinfo.h" +#include "wx/any.h" #ifdef wxHAS_EVENT_BIND #include "wx/meta/convertible.h" @@ -77,25 +79,12 @@ typedef int wxEventType; // the wxEVENT_HANDLER_CAST-macro. #define wxStaticCastEvent(type, val) static_cast(val) -#define DECLARE_EVENT_TABLE_ENTRY(type, winid, idLast, fn, obj) \ +#define wxDECLARE_EVENT_TABLE_ENTRY(type, winid, idLast, fn, obj) \ wxEventTableEntry(type, winid, idLast, wxNewEventTableFunctor(type, fn), obj) -#define DECLARE_EVENT_TABLE_TERMINATOR() \ +#define wxDECLARE_EVENT_TABLE_TERMINATOR() \ wxEventTableEntry(wxEVT_NULL, 0, 0, 0, 0) -// obsolete event declaration/definition macros, we don't need them any longer -// but we keep them for compatibility as it doesn't cost us anything anyhow -#define BEGIN_DECLARE_EVENT_TYPES() -#define END_DECLARE_EVENT_TYPES() -#define DECLARE_EXPORTED_EVENT_TYPE(expdecl, name, value) \ - extern expdecl const wxEventType name; -#define DECLARE_EVENT_TYPE(name, value) \ - DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_CORE, name, value) -#define DECLARE_LOCAL_EVENT_TYPE(name, value) \ - DECLARE_EXPORTED_EVENT_TYPE(wxEMPTY_PARAMETER_VALUE, name, value) -#define DEFINE_EVENT_TYPE(name) const wxEventType name = wxNewEventType(); -#define DEFINE_LOCAL_EVENT_TYPE(name) DEFINE_EVENT_TYPE(name) - // generate a new unique event type extern WXDLLIMPEXP_BASE wxEventType wxNewEventType(); @@ -189,16 +178,6 @@ typedef void (wxEvtHandler::*wxEventFunction)(wxEvent&); // compiler we can restore its old definition for it. typedef wxEventFunction wxObjectEventFunction; - -// wxEventFunctorClassInfo is used as a unique identifier for wxEventFunctor- -// derived classes; it is more light weight than wxClassInfo and can be used in -// template classes -typedef void (*wxEventFunctorClassInfo)(); - -// this macro must be used in wxEventFunctor-derived classes -#define wxDEFINE_EVENT_FUNCTOR_CLASS_INFO( classInfoName ) \ - static void classInfoName() {} - // The event functor which is stored in the static and dynamic event tables: class WXDLLIMPEXP_BASE wxEventFunctor { @@ -212,11 +191,6 @@ public: // finding it in an event table in Unbind(), by the given functor: virtual bool IsMatching(const wxEventFunctor& functor) const = 0; - // Test whether the given class info is the same as from this functor. This - // allows us in IsMatching to safely downcast the given wxEventFunctor without - // the usage of dynamic_cast<>(). - virtual bool IsSameClass(wxEventFunctorClassInfo classInfo) const = 0; - // If the functor holds an wxEvtHandler, then get access to it and track // its lifetime with wxEventConnectionRef: virtual wxEvtHandler *GetEvtHandler() const @@ -228,6 +202,9 @@ public: // wxEventFunction: virtual wxEventFunction GetEvtMethod() const { return NULL; } + +private: + WX_DECLARE_ABSTRACT_TYPEINFO(wxEventFunctor) }; // A plain method functor for the untyped legacy event types: @@ -238,16 +215,11 @@ public: : m_handler( handler ), m_method( method ) { } - virtual void operator()(wxEvtHandler *handler, wxEvent& event) - { - wxEvtHandler * const realHandler = m_handler ? m_handler : handler; - - (realHandler->*m_method)(event); - } + virtual void operator()(wxEvtHandler *handler, wxEvent& event); virtual bool IsMatching(const wxEventFunctor& functor) const { - if ( functor.IsSameClass( sm_classInfo )) + if ( wxTypeId(functor) == wxTypeId(*this) ) { const wxObjectEventFunctor &other = static_cast< const wxObjectEventFunctor & >( functor ); @@ -262,9 +234,6 @@ public: return false; } - virtual bool IsSameClass( wxEventFunctorClassInfo otherClassInfo ) const - { return sm_classInfo == otherClassInfo; } - virtual wxEvtHandler *GetEvtHandler() const { return m_handler; } @@ -275,7 +244,10 @@ private: wxEvtHandler *m_handler; wxEventFunction m_method; - wxDEFINE_EVENT_FUNCTOR_CLASS_INFO( sm_classInfo ); + // Provide a dummy default ctor for type info purposes + wxObjectEventFunctor() { } + + WX_DECLARE_TYPEINFO_INLINE(wxObjectEventFunctor) }; // Create a functor for the legacy events: used by Connect() @@ -287,7 +259,7 @@ wxNewEventFunctor(const wxEventType& WXUNUSED(evtType), return new wxObjectEventFunctor(method, handler); } -// This version is used by DECLARE_EVENT_TABLE_ENTRY() +// This version is used by wxDECLARE_EVENT_TABLE_ENTRY() inline wxObjectEventFunctor * wxNewEventTableFunctor(const wxEventType& WXUNUSED(evtType), wxObjectEventFunction method) @@ -424,22 +396,19 @@ public: virtual bool IsMatching(const wxEventFunctor& functor) const { - if ( !functor.IsSameClass(sm_classInfo) ) + if ( wxTypeId(functor) != wxTypeId(*this) ) return false; typedef wxEventFunctorMethod ThisFunctor; - // the cast is valid because IsSameClass() returned true above + // the cast is valid because wxTypeId()s matched above const ThisFunctor& other = static_cast(functor); return (m_method == other.m_method || other.m_method == NULL) && (m_handler == other.m_handler || other.m_handler == NULL); } - virtual bool IsSameClass( wxEventFunctorClassInfo otherClassInfo ) const - { return sm_classInfo == otherClassInfo; } - virtual wxEvtHandler *GetEvtHandler() const { return this->ConvertToEvtHandler(m_handler); } @@ -450,7 +419,12 @@ private: EventHandler *m_handler; void (Class::*m_method)(EventArg&); - wxDEFINE_EVENT_FUNCTOR_CLASS_INFO( sm_classInfo ); + // Provide a dummy default ctor for type info purposes + wxEventFunctorMethod() { } + + typedef wxEventFunctorMethod thisClass; + WX_DECLARE_TYPEINFO_INLINE(thisClass) }; @@ -488,7 +462,7 @@ public: virtual bool IsMatching(const wxEventFunctor &functor) const { - if ( !functor.IsSameClass(sm_classInfo) ) + if ( wxTypeId(functor) != wxTypeId(*this) ) return false; typedef wxEventFunctorFunction ThisFunctor; @@ -498,13 +472,14 @@ public: return m_handler == other.m_handler; } - virtual bool IsSameClass( wxEventFunctorClassInfo otherClassInfo ) const - { return sm_classInfo == otherClassInfo; } - private: void (*m_handler)(EventArg&); - wxDEFINE_EVENT_FUNCTOR_CLASS_INFO( sm_classInfo ); + // Provide a dummy default ctor for type info purposes + wxEventFunctorFunction() { } + + typedef wxEventFunctorFunction thisClass; + WX_DECLARE_TYPEINFO_INLINE(thisClass) }; @@ -532,7 +507,7 @@ public: virtual bool IsMatching(const wxEventFunctor &functor) const { - if ( !functor.IsSameClass(sm_classInfo) ) + if ( wxTypeId(functor) != wxTypeId(*this) ) return false; typedef wxEventFunctorFunctor FunctorThis; @@ -544,9 +519,6 @@ public: return m_handlerAddr == other.m_handlerAddr; } - virtual bool IsSameClass( wxEventFunctorClassInfo otherClassInfo ) const - { return sm_classInfo == otherClassInfo; } - private: // Store a copy of the functor to prevent using/calling an already // destroyed instance: @@ -555,7 +527,11 @@ private: // Use the address of the original functor for comparison in IsMatching: const void *m_handlerAddr; - wxDEFINE_EVENT_FUNCTOR_CLASS_INFO( sm_classInfo ); + // Provide a dummy default ctor for type info purposes + wxEventFunctorFunctor() { } + + typedef wxEventFunctorFunctor thisClass; + WX_DECLARE_TYPEINFO_INLINE(thisClass) }; // Create functors for the templatized events, either allocated on the heap for @@ -617,7 +593,7 @@ wxMakeEventFunctor(const EventTag&, method, handler); } -// Create an event functor for the event table via DECLARE_EVENT_TABLE_ENTRY: +// Create an event functor for the event table via wxDECLARE_EVENT_TABLE_ENTRY: // in this case we don't have the handler (as it's always the same as the // object which generated the event) so we must use Class as its type template @@ -639,8 +615,9 @@ extern WXDLLIMPEXP_BASE const wxEventType wxEVT_FIRST; extern WXDLLIMPEXP_BASE const wxEventType wxEVT_USER_FIRST; // Need events declared to do this +class WXDLLIMPEXP_FWD_BASE wxIdleEvent; +class WXDLLIMPEXP_FWD_BASE wxThreadEvent; class WXDLLIMPEXP_FWD_CORE wxCommandEvent; -class WXDLLIMPEXP_FWD_CORE wxThreadEvent; class WXDLLIMPEXP_FWD_CORE wxMouseEvent; class WXDLLIMPEXP_FWD_CORE wxFocusEvent; class WXDLLIMPEXP_FWD_CORE wxChildFocusEvent; @@ -673,7 +650,6 @@ class WXDLLIMPEXP_FWD_CORE wxPaletteChangedEvent; class WXDLLIMPEXP_FWD_CORE wxJoystickEvent; class WXDLLIMPEXP_FWD_CORE wxDropFilesEvent; class WXDLLIMPEXP_FWD_CORE wxInitDialogEvent; -class WXDLLIMPEXP_FWD_CORE wxIdleEvent; class WXDLLIMPEXP_FWD_CORE wxUpdateUIEvent; class WXDLLIMPEXP_FWD_CORE wxClipboardTextEvent; class WXDLLIMPEXP_FWD_CORE wxHelpEvent; @@ -702,7 +678,7 @@ wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_COMBOBOX_DROPDOWN, wxCo wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_COMBOBOX_CLOSEUP, wxCommandEvent); // Thread events -wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_THREAD, wxThreadEvent); +wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_BASE, wxEVT_THREAD, wxThreadEvent); // Mouse event types wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_LEFT_DOWN, wxMouseEvent); @@ -737,6 +713,10 @@ wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_KEY_UP, wxKeyEvent); #if wxUSE_HOTKEY wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_HOTKEY, wxKeyEvent); #endif +// This is a private event used by wxMSW code only and subject to change or +// disappear in the future. Don't use. +wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_AFTER_CHAR, wxKeyEvent); + // Set cursor event wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_SET_CURSOR, wxSetCursorEvent); @@ -1002,6 +982,25 @@ public: return false; } + // This is also used only internally by ProcessEvent() to check if it + // should process the event normally or only restrict the search for the + // event handler to this object itself. + bool ShouldProcessOnlyIn(wxEvtHandler *h) const + { + return h == m_handlerToProcessOnlyIn; + } + + // Called to indicate that the result of ShouldProcessOnlyIn() wasn't taken + // into account. The existence of this function may seem counterintuitive + // but unfortunately it's needed by wxScrollHelperEvtHandler, see comments + // there. Don't even think of using this in your own code, this is a gross + // hack and is only needed because of wx complicated history and should + // never be used anywhere else. + void DidntHonourProcessOnlyIn() + { + m_handlerToProcessOnlyIn = NULL; + } + protected: wxObject* m_eventObject; wxEventType m_eventType; @@ -1012,6 +1011,10 @@ public: // m_callbackUserData is for internal usage only wxObject* m_callbackUserData; +private: + // If this handler + wxEvtHandler *m_handlerToProcessOnlyIn; + protected: // the propagation level: while it is positive, we propagate the event to // the parent window (if any) @@ -1034,6 +1037,10 @@ private: // it needs to access our m_propagationLevel friend class WXDLLIMPEXP_FWD_BASE wxPropagateOnce; + // and this one needs to access our m_handlerToProcessOnlyIn + friend class WXDLLIMPEXP_FWD_BASE wxEventProcessInHandlerOnly; + + DECLARE_ABSTRACT_CLASS(wxEvent) }; @@ -1085,6 +1092,171 @@ private: wxDECLARE_NO_COPY_CLASS(wxPropagateOnce); }; +// A helper object used to temporarily make wxEvent::ShouldProcessOnlyIn() +// return true for the handler passed to its ctor. +class wxEventProcessInHandlerOnly +{ +public: + wxEventProcessInHandlerOnly(wxEvent& event, wxEvtHandler *handler) + : m_event(event), + m_handlerToProcessOnlyInOld(event.m_handlerToProcessOnlyIn) + { + m_event.m_handlerToProcessOnlyIn = handler; + } + + ~wxEventProcessInHandlerOnly() + { + m_event.m_handlerToProcessOnlyIn = m_handlerToProcessOnlyInOld; + } + +private: + wxEvent& m_event; + wxEvtHandler * const m_handlerToProcessOnlyInOld; + + wxDECLARE_NO_COPY_CLASS(wxEventProcessInHandlerOnly); +}; + + +class WXDLLIMPEXP_BASE wxEventBasicPayloadMixin +{ +public: + wxEventBasicPayloadMixin() + : m_commandInt(0), + m_extraLong(0) + { + } + + void SetString(const wxString& s) { m_cmdString = s; } + const wxString& GetString() const { return m_cmdString; } + + void SetInt(int i) { m_commandInt = i; } + int GetInt() const { return m_commandInt; } + + void SetExtraLong(long extraLong) { m_extraLong = extraLong; } + long GetExtraLong() const { return m_extraLong; } + +protected: + // Note: these variables have "cmd" or "command" in their name for backward compatibility: + // they used to be part of wxCommandEvent, not this mixin. + wxString m_cmdString; // String event argument + int m_commandInt; + long m_extraLong; // Additional information (e.g. select/deselect) + + wxDECLARE_NO_ASSIGN_CLASS(wxEventBasicPayloadMixin); +}; + +class WXDLLIMPEXP_BASE wxEventAnyPayloadMixin : public wxEventBasicPayloadMixin +{ +public: + wxEventAnyPayloadMixin() : wxEventBasicPayloadMixin() {} + +#if wxUSE_ANY && (!defined(__VISUALC__) || wxCHECK_VISUALC_VERSION(7)) + template + void SetPayload(const T& payload) + { + m_payload = payload; + } + + template + T GetPayload() const + { + return m_payload.As(); + } + +protected: + wxAny m_payload; +#endif // wxUSE_ANY && (!defined(__VISUALC__) || wxCHECK_VISUALC_VERSION(7)) + + wxDECLARE_NO_ASSIGN_CLASS(wxEventBasicPayloadMixin); +}; + + +// Idle event +/* + wxEVT_IDLE + */ + +// Whether to always send idle events to windows, or +// to only send update events to those with the +// wxWS_EX_PROCESS_IDLE style. + +enum wxIdleMode +{ + // Send idle events to all windows + wxIDLE_PROCESS_ALL, + + // Send idle events to windows that have + // the wxWS_EX_PROCESS_IDLE flag specified + wxIDLE_PROCESS_SPECIFIED +}; + +class WXDLLIMPEXP_BASE wxIdleEvent : public wxEvent +{ +public: + wxIdleEvent() + : wxEvent(0, wxEVT_IDLE), + m_requestMore(false) + { } + wxIdleEvent(const wxIdleEvent& event) + : wxEvent(event), + m_requestMore(event.m_requestMore) + { } + + void RequestMore(bool needMore = true) { m_requestMore = needMore; } + bool MoreRequested() const { return m_requestMore; } + + virtual wxEvent *Clone() const { return new wxIdleEvent(*this); } + + // Specify how wxWidgets will send idle events: to + // all windows, or only to those which specify that they + // will process the events. + static void SetMode(wxIdleMode mode) { sm_idleMode = mode; } + + // Returns the idle event mode + static wxIdleMode GetMode() { return sm_idleMode; } + +protected: + bool m_requestMore; + static wxIdleMode sm_idleMode; + +private: + DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxIdleEvent) +}; + + +// Thread event + +class WXDLLIMPEXP_BASE wxThreadEvent : public wxEvent, + public wxEventAnyPayloadMixin +{ +public: + wxThreadEvent(wxEventType eventType = wxEVT_THREAD, int id = wxID_ANY) + : wxEvent(id, eventType) + { } + + wxThreadEvent(const wxThreadEvent& event) + : wxEvent(event), + wxEventAnyPayloadMixin(event) + { + // make sure our string member (which uses COW, aka refcounting) is not + // shared by other wxString instances: + SetString(GetString().c_str()); + } + + virtual wxEvent *Clone() const + { + return new wxThreadEvent(*this); + } + + // this is important to avoid that calling wxEventLoopBase::YieldFor thread events + // gets processed when this is unwanted: + virtual wxEventCategory GetEventCategory() const + { return wxEVT_CATEGORY_THREAD; } + +private: + DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxThreadEvent) +}; + #if wxUSE_GUI @@ -1108,16 +1280,15 @@ private: wxEVT_COMMAND_TOGGLEBUTTON_CLICKED */ -class WXDLLIMPEXP_CORE wxCommandEvent : public wxEvent +class WXDLLIMPEXP_CORE wxCommandEvent : public wxEvent, + public wxEventBasicPayloadMixin { public: wxCommandEvent(wxEventType commandType = wxEVT_NULL, int winid = 0); wxCommandEvent(const wxCommandEvent& event) : wxEvent(event), - m_cmdString(event.m_cmdString), - m_commandInt(event.m_commandInt), - m_extraLong(event.m_extraLong), + wxEventBasicPayloadMixin(event), m_clientData(event.m_clientData), m_clientObject(event.m_clientObject) { } @@ -1130,32 +1301,23 @@ public: void SetClientObject(wxClientData* clientObject) { m_clientObject = clientObject; } wxClientData *GetClientObject() const { return m_clientObject; } + // Note: this shadows wxEventBasicPayloadMixin::GetString(), because it does some + // GUI-specific hacks + wxString GetString() const; + // Get listbox selection if single-choice int GetSelection() const { return m_commandInt; } - // Set/Get listbox/choice selection string - void SetString(const wxString& s) { m_cmdString = s; } - wxString GetString() const; - // Get checkbox value bool IsChecked() const { return m_commandInt != 0; } // true if the listbox event was a selection. bool IsSelection() const { return (m_extraLong != 0); } - void SetExtraLong(long extraLong) { m_extraLong = extraLong; } - long GetExtraLong() const { return m_extraLong; } - - void SetInt(int i) { m_commandInt = i; } - int GetInt() const { return m_commandInt; } - virtual wxEvent *Clone() const { return new wxCommandEvent(*this); } virtual wxEventCategory GetEventCategory() const { return wxEVT_CATEGORY_USER_INPUT; } protected: - wxString m_cmdString; // String event argument - int m_commandInt; - long m_extraLong; // Additional information (e.g. select/deselect) void* m_clientData; // Arbitrary client data wxClientData* m_clientObject; // Arbitrary client object @@ -1195,44 +1357,6 @@ private: }; -// Thread event - -class WXDLLIMPEXP_CORE wxThreadEvent : public wxCommandEvent -{ -public: - wxThreadEvent(wxEventType eventType = wxEVT_COMMAND_THREAD, int id = wxID_ANY) - : wxCommandEvent(eventType, id) - { } - - wxThreadEvent(const wxThreadEvent& event) - : wxCommandEvent(event) - { - // make sure our string member (which uses COW, aka refcounting) is not - // shared by other wxString instances: - SetString(GetString().c_str()); - } - - virtual wxEvent *Clone() const - { - wxThreadEvent* ev = new wxThreadEvent(*this); - - // make sure our string member (which uses COW, aka refcounting) is not - // shared by other wxString instances: - ev->SetString(GetString().c_str()); - return ev; - } - - // this is important to avoid that calling wxEventLoopBase::YieldFor thread events - // gets processed when this is unwanted: - virtual wxEventCategory GetEventCategory() const - { return wxEVT_CATEGORY_THREAD; } - -private: - DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxThreadEvent) -}; - - - // Scroll event class, derived form wxCommandEvent. wxScrollEvents are // sent by wxSlider and wxScrollBar. /* @@ -1482,7 +1606,7 @@ public: void SetCursor(const wxCursor& cursor) { m_cursor = cursor; } const wxCursor& GetCursor() const { return m_cursor; } - bool HasCursor() const { return m_cursor.Ok(); } + bool HasCursor() const { return m_cursor.IsOk(); } virtual wxEvent *Clone() const { return new wxSetCursorEvent(*this); } @@ -1649,6 +1773,7 @@ public: { m_eventType = wxEVT_SIZING; m_id = id; } wxSize GetSize() const { return m_size; } + void SetSize(wxSize size) { m_size = size; } wxRect GetRect() const { return m_rect; } void SetRect(const wxRect& rect) { m_rect = rect; } @@ -2679,59 +2804,6 @@ private: DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxContextMenuEvent) }; -#endif // wxUSE_GUI - -// Idle event -/* - wxEVT_IDLE - */ - -// Whether to always send idle events to windows, or -// to only send update events to those with the -// wxWS_EX_PROCESS_IDLE style. - -enum wxIdleMode -{ - // Send idle events to all windows - wxIDLE_PROCESS_ALL, - - // Send idle events to windows that have - // the wxWS_EX_PROCESS_IDLE flag specified - wxIDLE_PROCESS_SPECIFIED -}; - -class WXDLLIMPEXP_BASE wxIdleEvent : public wxEvent -{ -public: - wxIdleEvent() - : wxEvent(0, wxEVT_IDLE), - m_requestMore(false) - { } - wxIdleEvent(const wxIdleEvent& event) - : wxEvent(event), - m_requestMore(event.m_requestMore) - { } - - void RequestMore(bool needMore = true) { m_requestMore = needMore; } - bool MoreRequested() const { return m_requestMore; } - - virtual wxEvent *Clone() const { return new wxIdleEvent(*this); } - - // Specify how wxWidgets will send idle events: to - // all windows, or only to those which specify that they - // will process the events. - static void SetMode(wxIdleMode mode) { sm_idleMode = mode; } - - // Returns the idle event mode - static wxIdleMode GetMode() { return sm_idleMode; } - -protected: - bool m_requestMore; - static wxIdleMode sm_idleMode; - -private: - DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxIdleEvent) -}; /* TODO wxEVT_MOUSE_CAPTURE_CHANGED, @@ -2743,6 +2815,7 @@ private: wxEVT_COMPARE_ITEM */ +#endif // wxUSE_GUI // ============================================================================ @@ -2956,6 +3029,20 @@ public: bool SafelyProcessEvent(wxEvent& event); // NOTE: uses ProcessEvent() + // This method tries to process the event in this event handler, including + // any preprocessing done by TryBefore() and all the handlers chained to + // it, but excluding the post-processing done in TryAfter(). + // + // It is meant to be called from ProcessEvent() only and is not virtual, + // additional event handlers can be hooked into the normal event processing + // logic using TryBefore() and TryAfter() hooks. + // + // You can also call it yourself to forward an event to another handler but + // without propagating it upwards if it's unhandled (this is usually + // unwanted when forwarding as the original handler would already do it if + // needed normally). + bool ProcessEventLocally(wxEvent& event); + // Schedule the given event to be processed later. It takes ownership of // the event pointer, i.e. it will be deleted later. This is safe to call // from multiple threads although you still need to ensure that wxString @@ -3168,14 +3255,6 @@ public: void OnSinkDestroyed( wxEvtHandler *sink ); - // The method tries to process the event in this event handler. - // - // It is meant to be called from ProcessEvent() only and is not virtual, - // additional event handlers can be hooked into the normal event processing - // logic using TryBefore() and TryAfter() hooks. - bool ProcessEventHere(wxEvent& event); - - private: void DoBind(int winid, int lastId, @@ -3200,6 +3279,20 @@ protected: // validators. virtual bool TryBefore(wxEvent& event); + // This one is not a hook but just a helper which looks up the handler in + // this object itself. + // + // It is called from ProcessEventLocally() and normally shouldn't be called + // directly as doing it would ignore any chained event handlers + bool TryHereOnly(wxEvent& event); + + // Another helper which simply calls pre-processing hook and then tries to + // handle the event at this handler level. + bool TryBeforeAndHere(wxEvent& event) + { + return TryBefore(event) || TryHereOnly(event); + } + // this one is called after failing to find the event handle in our own // table to give a chance to the other windows to process it // @@ -3264,11 +3357,25 @@ private: // pass the event to wxTheApp instance, called from TryAfter() bool DoTryApp(wxEvent& event); + // try to process events in all handlers chained to this one + bool DoTryChain(wxEvent& event); + DECLARE_DYNAMIC_CLASS_NO_COPY(wxEvtHandler) }; WX_DEFINE_ARRAY_WITH_DECL_PTR(wxEvtHandler *, wxEvtHandlerArray, class WXDLLIMPEXP_BASE); + +// Define an inline method of wxObjectEventFunctor which couldn't be defined +// before wxEvtHandler declaration: at least Sun CC refuses to compile function +// calls through pointer to member for forward-declared classes (see #12452). +inline void wxObjectEventFunctor::operator()(wxEvtHandler *handler, wxEvent& event) +{ + wxEvtHandler * const realHandler = m_handler ? m_handler : handler; + + (realHandler->*m_method)(event); +} + // ---------------------------------------------------------------------------- // wxEventConnectionRef represents all connections between two event handlers // and enables automatic disconnect when an event handler sink goes out of @@ -3341,11 +3448,14 @@ inline void wxQueueEvent(wxEvtHandler *dest, wxEvent *event) typedef void (wxEvtHandler::*wxEventFunction)(wxEvent&); typedef void (wxEvtHandler::*wxIdleEventFunction)(wxIdleEvent&); +typedef void (wxEvtHandler::*wxThreadEventFunction)(wxThreadEvent&); #define wxEventHandler(func) \ wxEVENT_HANDLER_CAST(wxEventFunction, func) #define wxIdleEventHandler(func) \ wxEVENT_HANDLER_CAST(wxIdleEventFunction, func) +#define wxThreadEventHandler(func) \ + wxEVENT_HANDLER_CAST(wxThreadEventFunction, func) #if wxUSE_GUI @@ -3374,7 +3484,6 @@ protected: }; typedef void (wxEvtHandler::*wxCommandEventFunction)(wxCommandEvent&); -typedef void (wxEvtHandler::*wxThreadEventFunction)(wxThreadEvent&); typedef void (wxEvtHandler::*wxScrollEventFunction)(wxScrollEvent&); typedef void (wxEvtHandler::*wxScrollWinEventFunction)(wxScrollWinEvent&); typedef void (wxEvtHandler::*wxSizeEventFunction)(wxSizeEvent&); @@ -3414,8 +3523,6 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent& #define wxCommandEventHandler(func) \ wxEVENT_HANDLER_CAST(wxCommandEventFunction, func) -#define wxThreadEventHandler(func) \ - wxEVENT_HANDLER_CAST(wxThreadEventFunction, func) #define wxScrollEventHandler(func) \ wxEVENT_HANDLER_CAST(wxScrollEventFunction, func) #define wxScrollWinEventHandler(func) \ @@ -3493,20 +3600,20 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent& // N.B. In GNU-WIN32, you *have* to take the address of a member function // (use &) or the compiler crashes... -#define DECLARE_EVENT_TABLE() \ - private: \ - static const wxEventTableEntry sm_eventTableEntries[]; \ - protected: \ - static const wxEventTable sm_eventTable; \ - virtual const wxEventTable* GetEventTable() const; \ - static wxEventHashTable sm_eventHashTable; \ - virtual wxEventHashTable& GetEventHashTable() const; +#define wxDECLARE_EVENT_TABLE() \ + private: \ + static const wxEventTableEntry sm_eventTableEntries[]; \ + protected: \ + static const wxEventTable sm_eventTable; \ + virtual const wxEventTable* GetEventTable() const; \ + static wxEventHashTable sm_eventHashTable; \ + virtual wxEventHashTable& GetEventHashTable() const // N.B.: when building DLL with Borland C++ 5.5 compiler, you must initialize // sm_eventTable before using it in GetEventTable() or the compiler gives // E2233 (see http://groups.google.com/groups?selm=397dcc8a%241_2%40dnews) -#define BEGIN_EVENT_TABLE(theClass, baseClass) \ +#define wxBEGIN_EVENT_TABLE(theClass, baseClass) \ const wxEventTable theClass::sm_eventTable = \ { &baseClass::sm_eventTable, &theClass::sm_eventTableEntries[0] }; \ const wxEventTable *theClass::GetEventTable() const \ @@ -3516,7 +3623,7 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent& { return theClass::sm_eventHashTable; } \ const wxEventTableEntry theClass::sm_eventTableEntries[] = { \ -#define BEGIN_EVENT_TABLE_TEMPLATE1(theClass, baseClass, T1) \ +#define wxBEGIN_EVENT_TABLE_TEMPLATE1(theClass, baseClass, T1) \ template \ const wxEventTable theClass::sm_eventTable = \ { &baseClass::sm_eventTable, &theClass::sm_eventTableEntries[0] }; \ @@ -3531,7 +3638,7 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent& template \ const wxEventTableEntry theClass::sm_eventTableEntries[] = { \ -#define BEGIN_EVENT_TABLE_TEMPLATE2(theClass, baseClass, T1, T2) \ +#define wxBEGIN_EVENT_TABLE_TEMPLATE2(theClass, baseClass, T1, T2) \ template \ const wxEventTable theClass::sm_eventTable = \ { &baseClass::sm_eventTable, &theClass::sm_eventTableEntries[0] }; \ @@ -3546,7 +3653,7 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent& template \ const wxEventTableEntry theClass::sm_eventTableEntries[] = { \ -#define BEGIN_EVENT_TABLE_TEMPLATE3(theClass, baseClass, T1, T2, T3) \ +#define wxBEGIN_EVENT_TABLE_TEMPLATE3(theClass, baseClass, T1, T2, T3) \ template \ const wxEventTable theClass::sm_eventTable = \ { &baseClass::sm_eventTable, &theClass::sm_eventTableEntries[0] }; \ @@ -3561,7 +3668,7 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent& template \ const wxEventTableEntry theClass::sm_eventTableEntries[] = { \ -#define BEGIN_EVENT_TABLE_TEMPLATE4(theClass, baseClass, T1, T2, T3, T4) \ +#define wxBEGIN_EVENT_TABLE_TEMPLATE4(theClass, baseClass, T1, T2, T3, T4) \ template \ const wxEventTable theClass::sm_eventTable = \ { &baseClass::sm_eventTable, &theClass::sm_eventTableEntries[0] }; \ @@ -3576,7 +3683,7 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent& template \ const wxEventTableEntry theClass::sm_eventTableEntries[] = { \ -#define BEGIN_EVENT_TABLE_TEMPLATE5(theClass, baseClass, T1, T2, T3, T4, T5) \ +#define wxBEGIN_EVENT_TABLE_TEMPLATE5(theClass, baseClass, T1, T2, T3, T4, T5) \ template \ const wxEventTable theClass::sm_eventTable = \ { &baseClass::sm_eventTable, &theClass::sm_eventTableEntries[0] }; \ @@ -3591,7 +3698,7 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent& template \ const wxEventTableEntry theClass::sm_eventTableEntries[] = { \ -#define BEGIN_EVENT_TABLE_TEMPLATE7(theClass, baseClass, T1, T2, T3, T4, T5, T6, T7) \ +#define wxBEGIN_EVENT_TABLE_TEMPLATE7(theClass, baseClass, T1, T2, T3, T4, T5, T6, T7) \ template \ const wxEventTable theClass::sm_eventTable = \ { &baseClass::sm_eventTable, &theClass::sm_eventTableEntries[0] }; \ @@ -3606,7 +3713,7 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent& template \ const wxEventTableEntry theClass::sm_eventTableEntries[] = { \ -#define BEGIN_EVENT_TABLE_TEMPLATE8(theClass, baseClass, T1, T2, T3, T4, T5, T6, T7, T8) \ +#define wxBEGIN_EVENT_TABLE_TEMPLATE8(theClass, baseClass, T1, T2, T3, T4, T5, T6, T7, T8) \ template \ const wxEventTable theClass::sm_eventTable = \ { &baseClass::sm_eventTable, &theClass::sm_eventTableEntries[0] }; \ @@ -3621,7 +3728,8 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent& template \ const wxEventTableEntry theClass::sm_eventTableEntries[] = { \ -#define END_EVENT_TABLE() DECLARE_EVENT_TABLE_TERMINATOR() }; +#define wxEND_EVENT_TABLE() \ + wxDECLARE_EVENT_TABLE_TERMINATOR() }; /* * Event table macros @@ -3635,7 +3743,7 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent& // - id1, id2 ids of the first/last id // - fn the function (should be cast to the right type) #define wx__DECLARE_EVT2(evt, id1, id2, fn) \ - DECLARE_EVENT_TABLE_ENTRY(evt, id1, id2, fn, NULL), + wxDECLARE_EVENT_TABLE_ENTRY(evt, id1, id2, fn, NULL), #define wx__DECLARE_EVT1(evt, id, fn) \ wx__DECLARE_EVT2(evt, id, wxID_ANY, fn) #define wx__DECLARE_EVT0(evt, fn) \ @@ -3898,7 +4006,9 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent& #define EVT_TEXT_PASTE(winid, func) wx__DECLARE_EVT1(wxEVT_COMMAND_TEXT_PASTE, winid, wxClipboardTextEventHandler(func)) // Thread events -#define EVT_THREAD(id, func) wx__DECLARE_EVT1(wxEVT_COMMAND_THREAD, id, wxThreadEventHandler(func)) +#define EVT_THREAD(id, func) wx__DECLARE_EVT1(wxEVT_THREAD, id, wxThreadEventHandler(func)) +// alias for backward compatibility with 2.9.0: +#define wxEVT_COMMAND_THREAD wxEVT_THREAD // ---------------------------------------------------------------------------- // Helper functions @@ -3930,12 +4040,12 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent& #ifdef wxHAS_EVENT_BIND #define wxBIND_OR_CONNECT_HACK_BASE_CLASS #define wxBIND_OR_CONNECT_HACK_ONLY_BASE_CLASS - #define wxBIND_OR_CONNECT_HACK(w, evt, handler, func, obj) \ + #define wxBIND_OR_CONNECT_HACK(win, evt, handler, func, obj) \ win->Bind(evt, &func, obj) #else // wxHAS_EVENT_BIND #define wxBIND_OR_CONNECT_HACK_BASE_CLASS public wxEvtHandler, #define wxBIND_OR_CONNECT_HACK_ONLY_BASE_CLASS : public wxEvtHandler - #define wxBIND_OR_CONNECT_HACK(w, evt, handler, func, obj) \ + #define wxBIND_OR_CONNECT_HACK(win, evt, handler, func, obj) \ win->Connect(evt, handler(func), NULL, obj) #endif // wxHAS_EVENT_BIND @@ -3947,4 +4057,39 @@ WXDLLIMPEXP_CORE wxWindow* wxFindFocusDescendant(wxWindow* ancestor); #endif // wxUSE_GUI + +// ---------------------------------------------------------------------------- +// Compatibility macro aliases +// ---------------------------------------------------------------------------- + +// deprecated variants _not_ requiring a semicolon after them and without wx prefix +// (note that also some wx-prefixed macro do _not_ require a semicolon because +// it's not always possible to force the compire to require it) + +#define DECLARE_EVENT_TABLE_ENTRY(type, winid, idLast, fn, obj) \ + wxDECLARE_EVENT_TABLE_ENTRY(type, winid, idLast, fn, obj) +#define DECLARE_EVENT_TABLE_TERMINATOR() wxDECLARE_EVENT_TABLE_TERMINATOR() +#define DECLARE_EVENT_TABLE() wxDECLARE_EVENT_TABLE(); +#define BEGIN_EVENT_TABLE(a,b) wxBEGIN_EVENT_TABLE(a,b) +#define BEGIN_EVENT_TABLE_TEMPLATE1(a,b,c) wxBEGIN_EVENT_TABLE_TEMPLATE1(a,b,c) +#define BEGIN_EVENT_TABLE_TEMPLATE2(a,b,c,d) wxBEGIN_EVENT_TABLE_TEMPLATE1(a,b,c,d) +#define BEGIN_EVENT_TABLE_TEMPLATE3(a,b,c,d,e) wxBEGIN_EVENT_TABLE_TEMPLATE1(a,b,c,d,e) +#define BEGIN_EVENT_TABLE_TEMPLATE4(a,b,c,d,e,f) wxBEGIN_EVENT_TABLE_TEMPLATE1(a,b,c,d,e,f) +#define BEGIN_EVENT_TABLE_TEMPLATE5(a,b,c,d,e,f,g) wxBEGIN_EVENT_TABLE_TEMPLATE1(a,b,c,d,e,f,g) +#define BEGIN_EVENT_TABLE_TEMPLATE6(a,b,c,d,e,f,g,h) wxBEGIN_EVENT_TABLE_TEMPLATE1(a,b,c,d,e,f,g,h) +#define END_EVENT_TABLE() wxEND_EVENT_TABLE() + +// other obsolete event declaration/definition macros; we don't need them any longer +// but we keep them for compatibility as it doesn't cost us anything anyhow +#define BEGIN_DECLARE_EVENT_TYPES() +#define END_DECLARE_EVENT_TYPES() +#define DECLARE_EXPORTED_EVENT_TYPE(expdecl, name, value) \ + extern expdecl const wxEventType name; +#define DECLARE_EVENT_TYPE(name, value) \ + DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_CORE, name, value) +#define DECLARE_LOCAL_EVENT_TYPE(name, value) \ + DECLARE_EXPORTED_EVENT_TYPE(wxEMPTY_PARAMETER_VALUE, name, value) +#define DEFINE_EVENT_TYPE(name) const wxEventType name = wxNewEventType(); +#define DEFINE_LOCAL_EVENT_TYPE(name) DEFINE_EVENT_TYPE(name) + #endif // _WX_EVENT_H_