X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/685d0d734b5ae344f05759349fa1a3aa06d26927..2a45803fc3877afd0ae3ce356dfe216505165882:/include/wx/event.h?ds=sidebyside diff --git a/include/wx/event.h b/include/wx/event.h index 5db787ce6c..df5cb310a5 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -33,6 +33,14 @@ #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 // ---------------------------------------------------------------------------- @@ -621,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; @@ -681,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); @@ -1266,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 @@ -1694,18 +1862,23 @@ public: // Find the position of the event void GetPosition(wxCoord *xpos, wxCoord *ypos) const { - if (xpos) *xpos = m_x; - if (ypos) *ypos = m_y; + if (xpos) + *xpos = GetX(); + if (ypos) + *ypos = GetY(); } + // This version if provided only for backwards compatiblity, don't use. void GetPosition(long *xpos, long *ypos) const { - if (xpos) *xpos = (long)m_x; - if (ypos) *ypos = (long)m_y; + if (xpos) + *xpos = GetX(); + if (ypos) + *ypos = GetY(); } wxPoint GetPosition() const - { return wxPoint(m_x, m_y); } + { return wxPoint(GetX(), GetY()); } // Get X position wxCoord GetX() const; @@ -1743,6 +1916,8 @@ public: } public: + // Do not use these fields directly, they are initialized on demand, so + // call GetX() and GetY() or GetPosition() instead. wxCoord m_x, m_y; long m_keyCode; @@ -3137,6 +3312,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 // ----------------------------