X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c1b293bb8df110ae772cd99fde09e5724730653a..a7689c49fe02c0c065facf736ab28b19f5997b7c:/include/wx/event.h diff --git a/include/wx/event.h b/include/wx/event.h index 338ce78a09..6e4805549c 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -33,12 +33,21 @@ #include "wx/meta/convertible.h" #endif +// Currently VC6 and VC7 are known to not be able to compile CallAfter() code, +// so disable it for them. +#if !defined(__VISUALC__) || wxCHECK_VISUALC_VERSION(8) + #include "wx/meta/removeref.h" + + #define wxHAS_CALL_AFTER +#endif + // ---------------------------------------------------------------------------- // forward declarations // ---------------------------------------------------------------------------- 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; @@ -224,10 +233,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 @@ -617,6 +629,7 @@ 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_BASE wxAsyncMethodCallEvent; class WXDLLIMPEXP_FWD_CORE wxCommandEvent; class WXDLLIMPEXP_FWD_CORE wxMouseEvent; class WXDLLIMPEXP_FWD_CORE wxFocusEvent; @@ -677,8 +690,9 @@ wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_TOOL_ENTER, wxCommandEv wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_COMBOBOX_DROPDOWN, wxCommandEvent); wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_COMBOBOX_CLOSEUP, wxCommandEvent); - // Thread events + // Thread and asynchronous method call events wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_BASE, wxEVT_THREAD, wxThreadEvent); +wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_BASE, wxEVT_ASYNC_METHOD_CALL, wxAsyncMethodCallEvent); // Mouse event types wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_LEFT_DOWN, wxMouseEvent); @@ -926,6 +940,10 @@ public: int GetId() const { return m_id; } void SetId(int Id) { m_id = Id; } + // Returns the user data optionally associated with the event handler when + // using Connect() or Bind(). + wxObject *GetEventUserData() const { return m_callbackUserData; } + // Can instruct event processor that we wish to ignore this event // (treat as if the event table entry had not been found): this must be done // to allow the event processing by the base classes (calling event.Skip() @@ -1240,7 +1258,7 @@ public: { // make sure our string member (which uses COW, aka refcounting) is not // shared by other wxString instances: - SetString(GetString().c_str()); + SetString(GetString().Clone()); } virtual wxEvent *Clone() const @@ -1258,6 +1276,164 @@ private: }; +// Asynchronous method call events: these event are processed by wxEvtHandler +// itself and result in a call to its Execute() method which simply calls the +// specified method. The difference with a simple method call is that this is +// done asynchronously, i.e. at some later time, instead of immediately when +// the event object is constructed. + +#ifdef wxHAS_CALL_AFTER + +// This is a base class used to process all method calls. +class wxAsyncMethodCallEvent : public wxEvent +{ +public: + wxAsyncMethodCallEvent(wxObject* object) + : wxEvent(wxID_ANY, wxEVT_ASYNC_METHOD_CALL) + { + SetEventObject(object); + } + + wxAsyncMethodCallEvent(const wxAsyncMethodCallEvent& other) + : wxEvent(other) + { + } + + virtual void Execute() = 0; +}; + +// This is a version for calling methods without parameters. +template +class wxAsyncMethodCallEvent0 : public wxAsyncMethodCallEvent +{ +public: + typedef T ObjectType; + typedef void (ObjectType::*MethodType)(); + + wxAsyncMethodCallEvent0(ObjectType* object, + MethodType method) + : wxAsyncMethodCallEvent(object), + m_object(object), + m_method(method) + { + } + + wxAsyncMethodCallEvent0(const wxAsyncMethodCallEvent0& other) + : wxAsyncMethodCallEvent(other), + m_object(other.m_object), + m_method(other.m_method) + { + } + + virtual wxEvent *Clone() const + { + return new wxAsyncMethodCallEvent0(*this); + } + + virtual void Execute() + { + (m_object->*m_method)(); + } + +private: + ObjectType* const m_object; + const MethodType m_method; +}; + +// This is a version for calling methods with a single parameter. +template +class wxAsyncMethodCallEvent1 : public wxAsyncMethodCallEvent +{ +public: + typedef T ObjectType; + typedef void (ObjectType::*MethodType)(T1 x1); + typedef typename wxRemoveRef::type ParamType1; + + wxAsyncMethodCallEvent1(ObjectType* object, + MethodType method, + const ParamType1& x1) + : wxAsyncMethodCallEvent(object), + m_object(object), + m_method(method), + m_param1(x1) + { + } + + wxAsyncMethodCallEvent1(const wxAsyncMethodCallEvent1& other) + : wxAsyncMethodCallEvent(other), + m_object(other.m_object), + m_method(other.m_method), + m_param1(other.m_param1) + { + } + + virtual wxEvent *Clone() const + { + return new wxAsyncMethodCallEvent1(*this); + } + + virtual void Execute() + { + (m_object->*m_method)(m_param1); + } + +private: + ObjectType* const m_object; + const MethodType m_method; + const ParamType1 m_param1; +}; + +// This is a version for calling methods with two parameters. +template +class wxAsyncMethodCallEvent2 : public wxAsyncMethodCallEvent +{ +public: + typedef T ObjectType; + typedef void (ObjectType::*MethodType)(T1 x1, T2 x2); + typedef typename wxRemoveRef::type ParamType1; + typedef typename wxRemoveRef::type ParamType2; + + wxAsyncMethodCallEvent2(ObjectType* object, + MethodType method, + const ParamType1& x1, + const ParamType2& x2) + : wxAsyncMethodCallEvent(object), + m_object(object), + m_method(method), + m_param1(x1), + m_param2(x2) + { + } + + wxAsyncMethodCallEvent2(const wxAsyncMethodCallEvent2& other) + : wxAsyncMethodCallEvent(other), + m_object(other.m_object), + m_method(other.m_method), + m_param1(other.m_param1), + m_param2(other.m_param2) + { + } + + virtual wxEvent *Clone() const + { + return new wxAsyncMethodCallEvent2(*this); + } + + virtual void Execute() + { + (m_object->*m_method)(m_param1, m_param2); + } + +private: + ObjectType* const m_object; + const MethodType m_method; + const ParamType1 m_param1; + const ParamType2 m_param2; +}; + +#endif // wxHAS_CALL_AFTER + + #if wxUSE_GUI @@ -1291,7 +1467,12 @@ public: wxEventBasicPayloadMixin(event), m_clientData(event.m_clientData), m_clientObject(event.m_clientObject) - { } + { + // Because GetString() can retrieve the string text only on demand, we + // need to copy it explicitly. + if ( m_cmdString.empty() ) + m_cmdString = event.GetString(); + } // Set/Get client data from controls void SetClientData(void* clientData) { m_clientData = clientData; } @@ -1442,20 +1623,14 @@ 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, */ +enum wxMouseWheelAxis +{ + wxMOUSE_WHEEL_VERTICAL, + wxMOUSE_WHEEL_HORIZONTAL +}; + class WXDLLIMPEXP_CORE wxMouseEvent : public wxEvent, public wxMouseState { @@ -1502,8 +1677,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 @@ -1543,10 +1718,10 @@ public: // should occur for each delta. int GetWheelDelta() const { return m_wheelDelta; } - // Gets the axis the wheel operation concerns, 0 being the y axis as on - // most mouse wheels, 1 is the x axis for things like MightyMouse scrolls - // or horizontal trackpad scrolling - int GetWheelAxis() const { return m_wheelAxis; } + // Gets the axis the wheel operation concerns; wxMOUSE_WHEEL_VERTICAL + // (most common case) or wxMOUSE_WHEEL_HORIZONTAL (for horizontal scrolling + // using e.g. a trackpad). + wxMouseWheelAxis GetWheelAxis() const { return m_wheelAxis; } // Returns the configured number of lines (or whatever) to be scrolled per // wheel action. Defaults to one. @@ -1568,7 +1743,7 @@ public: public: int m_clickCount; - int m_wheelAxis; + wxMouseWheelAxis m_wheelAxis; int m_wheelRotation; int m_wheelDelta; int m_linesPerAction; @@ -1660,7 +1835,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; } @@ -1696,10 +1876,19 @@ public: { return wxPoint(m_x, m_y); } // Get X position - wxCoord GetX() const { return m_x; } + wxCoord GetX() const; // Get Y position - wxCoord GetY() const { return m_y; } + wxCoord GetY() const; + + // 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; } @@ -1716,16 +1905,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; } @@ -1747,6 +1927,46 @@ 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_hasPosition = evt.m_hasPosition; + + m_keyCode = evt.m_keyCode; + + m_rawCode = evt.m_rawCode; + m_rawFlags = evt.m_rawFlags; +#if wxUSE_UNICODE + m_uniChar = evt.m_uniChar; +#endif + } + + // Initialize m_x and m_y using the current mouse cursor position if + // necessary. + void InitPositionIfNecessary() const; + + // 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; + + // If true, m_x and m_y were already initialized. If false, try to get them + // when they're requested. + bool m_hasPosition; + DECLARE_DYNAMIC_CLASS(wxKeyEvent) }; @@ -1831,7 +2051,6 @@ private: /* wxEVT_PAINT wxEVT_NC_PAINT - wxEVT_PAINT_ICON */ #if wxDEBUG_LEVEL && (defined(__WXMSW__) || defined(__WXPM__)) @@ -2964,7 +3183,7 @@ public: protected: // Init the hash table with the entries of the static event table. void InitHashTable(); - // Helper funtion of InitHashTable() to insert 1 entry into the hash table. + // Helper function of InitHashTable() to insert 1 entry into the hash table. void AddEntry(const wxEventTableEntry &entry); // Allocate and init with null pointers the base hash table. void AllocEventTypeTable(size_t size); @@ -3013,6 +3232,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 // ---------------------------- @@ -3073,6 +3305,46 @@ public: // NOTE: uses AddPendingEvent(); call only from secondary threads #endif +#ifdef wxHAS_CALL_AFTER + // Asynchronous method calls: these methods schedule the given method + // pointer for a later call (during the next idle event loop iteration). + // + // Notice that the method is called on this object itself, so the object + // CallAfter() is called on must have the correct dynamic type. + // + // These method can be used from another thread. + + template + void CallAfter(void (T::*method)()) + { + QueueEvent( + new wxAsyncMethodCallEvent0(static_cast(this), method) + ); + } + + // Notice that we use P1 and not T1 for the parameter to allow passing + // parameters that are convertible to the type taken by the method + // instead of being exactly the same, to be closer to the usual method call + // semantics. + template + void CallAfter(void (T::*method)(T1 x1), P1 x1) + { + QueueEvent( + new wxAsyncMethodCallEvent1( + static_cast(this), method, x1) + ); + } + + template + void CallAfter(void (T::*method)(T1 x1, T2 x2), P1 x1, P2 x2) + { + QueueEvent( + new wxAsyncMethodCallEvent2( + static_cast(this), method, x1, x2) + ); + } +#endif // wxHAS_CALL_AFTER + // Connecting and disconnecting // ---------------------------- @@ -3299,7 +3571,7 @@ protected: // 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; ) @@ -3360,6 +3632,9 @@ private: // 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) };