X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f8a7dd5f4162313d76ae2e2df46740f3a9e49071..b02dd12239c8a59b9a545d9fcb04974f8ad02c6b:/include/wx/event.h?ds=sidebyside diff --git a/include/wx/event.h b/include/wx/event.h index 225da47b42..16f91819d9 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -27,6 +27,7 @@ #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" @@ -38,6 +39,7 @@ class WXDLLIMPEXP_FWD_BASE wxList; class WXDLLIMPEXP_FWD_BASE wxEvent; +class WXDLLIMPEXP_FWD_BASE wxEventFilter; #if wxUSE_GUI class WXDLLIMPEXP_FWD_CORE wxDC; class WXDLLIMPEXP_FWD_CORE wxMenu; @@ -78,25 +80,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(); @@ -227,12 +216,7 @@ 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 { @@ -241,10 +225,13 @@ public: const wxObjectEventFunctor &other = static_cast< const wxObjectEventFunctor & >( functor ); - // FIXME-VC6: amazing but true: replacing "method == NULL" here - // with "!method" makes VC6 crash with an ICE in DLL build (only!) + // FIXME-VC6: amazing but true: replacing "m_method == 0" here + // with "!m_method" makes VC6 crash with an ICE in DLL build (only!) + // Also notice that using "NULL" instead of "0" results in warnings + // about "using NULL in arithmetics" from arm-linux-androideabi-g++ + // 4.4.3 used for wxAndroid build. - return ( m_method == other.m_method || other.m_method == NULL ) && + return ( m_method == other.m_method || other.m_method == 0 ) && ( m_handler == other.m_handler || other.m_handler == NULL ); } else @@ -276,7 +263,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) @@ -610,7 +597,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 @@ -632,8 +619,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; @@ -666,7 +654,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; @@ -695,7 +682,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); @@ -730,6 +717,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); @@ -995,6 +986,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; @@ -1005,6 +1015,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) @@ -1027,6 +1041,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) }; @@ -1078,6 +1096,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 @@ -1101,16 +1284,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) { } @@ -1123,32 +1305,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 @@ -1188,39 +1361,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 - { - 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) -}; - - - // Scroll event class, derived form wxCommandEvent. wxScrollEvents are // sent by wxSlider and wxScrollBar. /* @@ -1306,18 +1446,6 @@ private: wxEVT_LEFT_DCLICK wxEVT_MIDDLE_DCLICK wxEVT_RIGHT_DCLICK - wxEVT_NC_LEFT_DOWN - wxEVT_NC_LEFT_UP, - wxEVT_NC_MIDDLE_DOWN, - wxEVT_NC_MIDDLE_UP, - wxEVT_NC_RIGHT_DOWN, - wxEVT_NC_RIGHT_UP, - wxEVT_NC_MOTION, - wxEVT_NC_ENTER_WINDOW, - wxEVT_NC_LEAVE_WINDOW, - wxEVT_NC_LEFT_DCLICK, - wxEVT_NC_MIDDLE_DCLICK, - wxEVT_NC_RIGHT_DCLICK, */ class WXDLLIMPEXP_CORE wxMouseEvent : public wxEvent, @@ -1366,8 +1494,8 @@ public: bool LeftDClick() const { return (m_eventType == wxEVT_LEFT_DCLICK); } bool MiddleDClick() const { return (m_eventType == wxEVT_MIDDLE_DCLICK); } bool RightDClick() const { return (m_eventType == wxEVT_RIGHT_DCLICK); } - bool Aux1DClick() const { return (m_eventType == wxEVT_AUX1_UP); } - bool Aux2DClick() const { return (m_eventType == wxEVT_AUX2_UP); } + bool Aux1DClick() const { return (m_eventType == wxEVT_AUX1_DCLICK); } + bool Aux2DClick() const { return (m_eventType == wxEVT_AUX2_DCLICK); } // True if a button is down and the mouse is moving bool Dragging() const @@ -1470,7 +1598,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); } @@ -1524,7 +1652,12 @@ class WXDLLIMPEXP_CORE wxKeyEvent : public wxEvent, { public: wxKeyEvent(wxEventType keyType = wxEVT_NULL); + + // Normal copy ctor and a ctor creating a new event for the same key as the + // given one but a different event type (this is used in implementation + // code only, do not use outside of the library). wxKeyEvent(const wxKeyEvent& evt); + wxKeyEvent(wxEventType eventType, const wxKeyEvent& evt); // get the key code: an ASCII7 char or an element of wxKeyCode enum int GetKeyCode() const { return (int)m_keyCode; } @@ -1565,6 +1698,15 @@ public: // Get Y position wxCoord GetY() const { return m_y; } + // Can be called from wxEVT_CHAR_HOOK handler to allow generation of normal + // key events even though the event had been handled (by default they would + // not be generated in this case). + void DoAllowNextEvent() { m_allowNext = true; } + + // Return the value of the "allow next" flag, for internal use only. + bool IsNextEventAllowed() const { return m_allowNext; } + + virtual wxEvent *Clone() const { return new wxKeyEvent(*this); } virtual wxEventCategory GetEventCategory() const { return wxEVT_CATEGORY_USER_INPUT; } @@ -1580,16 +1722,7 @@ public: // implicitly defined operator=() so need to do it this way: *static_cast(this) = evt; - m_x = evt.m_x; - m_y = evt.m_y; - - m_keyCode = evt.m_keyCode; - - m_rawCode = evt.m_rawCode; - m_rawFlags = evt.m_rawFlags; -#if wxUSE_UNICODE - m_uniChar = evt.m_uniChar; -#endif + DoAssignMembers(evt); } return *this; } @@ -1611,6 +1744,37 @@ public: wxUint32 m_rawFlags; private: + // Set the event to propagate if necessary, i.e. if it's of wxEVT_CHAR_HOOK + // type. This is used by all ctors. + void InitPropagation() + { + if ( m_eventType == wxEVT_CHAR_HOOK ) + m_propagationLevel = wxEVENT_PROPAGATE_MAX; + + m_allowNext = false; + } + + // Copy only the event data present in this class, this is used by + // AssignKeyData() and copy ctor. + void DoAssignMembers(const wxKeyEvent& evt) + { + m_x = evt.m_x; + m_y = evt.m_y; + + m_keyCode = evt.m_keyCode; + + m_rawCode = evt.m_rawCode; + m_rawFlags = evt.m_rawFlags; +#if wxUSE_UNICODE + m_uniChar = evt.m_uniChar; +#endif + } + + // If this flag is true, the normal key events should still be generated + // even if wxEVT_CHAR_HOOK had been handled. By default it is false as + // handling wxEVT_CHAR_HOOK suppresses all the subsequent events. + bool m_allowNext; + DECLARE_DYNAMIC_CLASS(wxKeyEvent) }; @@ -1637,6 +1801,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; } @@ -1694,7 +1859,6 @@ private: /* wxEVT_PAINT wxEVT_NC_PAINT - wxEVT_PAINT_ICON */ #if wxDEBUG_LEVEL && (defined(__WXMSW__) || defined(__WXPM__)) @@ -2667,59 +2831,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, @@ -2731,6 +2842,7 @@ private: wxEVT_COMPARE_ITEM */ +#endif // wxUSE_GUI // ============================================================================ @@ -2928,6 +3040,19 @@ public: bool IsUnlinked() const; + // Global event filters + // -------------------- + + // Add an event filter whose FilterEvent() method will be called for each + // and every event processed by wxWidgets. The filters are called in LIFO + // order and wxApp is registered as an event filter by default. The pointer + // must remain valid until it's removed with RemoveFilter() and is not + // deleted by wxEvtHandler. + static void AddFilter(wxEventFilter* filter); + + // Remove a filter previously installed with AddFilter(). + static void RemoveFilter(wxEventFilter* filter); + // Event queuing and processing // ---------------------------- @@ -2944,6 +3069,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 @@ -3156,14 +3295,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, @@ -3188,13 +3319,27 @@ 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 // // base class implementation passes the event to wxTheApp virtual bool TryAfter(wxEvent& event); -#ifdef WXWIN_COMPATIBILITY_2_8 +#if WXWIN_COMPATIBILITY_2_8 // deprecated method: override TryBefore() instead of this one wxDEPRECATED_BUT_USED_INTERNALLY_INLINE( virtual bool TryValidator(wxEvent& WXUNUSED(event)), return false; ) @@ -3252,11 +3397,28 @@ 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); + + // Head of the event filter linked list. + static wxEventFilter* ms_filterList; + 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 @@ -3329,11 +3491,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 @@ -3362,7 +3527,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&); @@ -3402,8 +3566,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) \ @@ -3481,20 +3643,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 \ @@ -3504,7 +3666,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] }; \ @@ -3519,7 +3681,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] }; \ @@ -3534,7 +3696,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] }; \ @@ -3549,7 +3711,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] }; \ @@ -3564,7 +3726,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] }; \ @@ -3579,7 +3741,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] }; \ @@ -3594,7 +3756,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] }; \ @@ -3609,7 +3771,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 @@ -3623,7 +3786,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) \ @@ -3886,7 +4049,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 @@ -3935,4 +4100,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_