X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c4021a7920ab9f41b1553e28f1177b6e39a6d901..c099b53353ec8c689681a1bc8f5117a584e4098d:/include/wx/event.h diff --git a/include/wx/event.h b/include/wx/event.h index 4711b4d353..cc363146e4 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -126,10 +126,6 @@ extern WXDLLIMPEXP_BASE wxEventType wxNewEventType(); #define wxDECLARE_EVENT( name, type ) \ wxDECLARE_EXPORTED_EVENT( wxEMPTY_PARAMETER_VALUE, name, type ); - // Try to cast the given event handler to the correct handler type: - - #define wxEVENT_HANDLER_CAST( functype, func ) \ - ( wxObjectEventFunction )( wxEventFunction )wxStaticCastEvent( functype, &func ) #else // Define/Declare a templatized event type with the corresponding event as // a nested typedef: @@ -155,13 +151,13 @@ extern WXDLLIMPEXP_BASE wxEventType wxNewEventType(); #define wxDECLARE_EVENT( name, type ) \ wxDECLARE_EXPORTED_EVENT( wxEMPTY_PARAMETER_VALUE, name, type ); - // Don't cast the given event handler so that wxEvtHandler::Connect() sees - // the actual type: - - #define wxEVENT_HANDLER_CAST( functype, func ) \ - ( &func ) #endif +// Try to cast the given event handler to the correct handler type: + +#define wxEVENT_HANDLER_CAST( functype, func ) \ + ( wxObjectEventFunction )( wxEventFunction )wxStaticCastEvent( functype, &func ) + // Template which associates the correct event object with the event type #if !wxEVENTS_COMPATIBILITY_2_8 @@ -237,12 +233,7 @@ public: 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 Matches(const wxEventFunctor& func) const { @@ -390,7 +381,7 @@ struct HandlerImpl // allowed to handle different events in the same handler taking wxEvent&, for // example template - + class wxEventFunctorMethod : public wxEventFunctor, private wxPrivate::HandlerImpl @@ -408,7 +399,7 @@ public: typedef typename wxPrivate::EventClassOf::type EventClass; - wxEventFunctorMethod(void (Class::*method)(EventArg&), ObjClass *handler) + wxEventFunctorMethod(void (Class::*method)(EventArg&), EventHandler *handler) { wxASSERT_MSG( handler || this->IsEvtHandler(), "handlers defined in non-wxEvtHandler-derived classes " @@ -466,17 +457,15 @@ public: } private: - ObjClass *m_handler; + EventHandler *m_handler; void (Class::*m_method)(EventArg&); }; -// // Create functors for the templatized events, either allocated on the heap for -// wxNewXXX() variants (this is needed in wxEvtHandler::Connect() to store them +// wxNewXXX() variants (this is needed in wxEvtHandler::Bind<>() to store them // in dynamic event table) or just by returning them as temporary objects (this -// is enough for Disconnect() and we allocate unnecessary heap allocation like -// this) +// is enough for Unbind<>() and we avoid unnecessary heap allocation like this). // Create functors wrapping other functors (including functions): @@ -497,29 +486,29 @@ wxMakeEventFunctor(const EventTag&, Functor func) // Create functors for methods: template - -inline wxEventFunctorMethod * + +inline wxEventFunctorMethod * wxNewEventFunctor(const EventTag&, void (Class::*method)(EventArg&), - ObjClass *handler) + EventHandler *handler) { - return new wxEventFunctorMethod( + return new wxEventFunctorMethod( method, handler); } template - -inline wxEventFunctorMethod + +inline wxEventFunctorMethod wxMakeEventFunctor(const EventTag&, void (Class::*method)(EventArg&), - ObjClass *handler) + EventHandler *handler) { - return wxEventFunctorMethod( + return wxEventFunctorMethod( method, handler); } // Special case for the wxNewEventFunctor() calls used inside the event table -// macros: they don't specify the handler so ObjClass can't be deduced +// macros: they don't specify the handler so EventHandler can't be deduced template inline wxEventFunctorMethod * wxNewEventFunctor(const EventTag&, void (Class::*method)(EventArg&)) @@ -529,7 +518,7 @@ wxNewEventFunctor(const EventTag&, void (Class::*method)(EventArg&)) } template - + inline wxEventFunctorMethod wxMakeEventFunctor(const EventTag&, void (Class::*method)(EventArg&)) { @@ -607,6 +596,8 @@ wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_COMBOBOX_SELECTED, wxCo wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_TOOL_RCLICKED, wxCommandEvent); wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_TOOL_DROPDOWN_CLICKED, wxCommandEvent); wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_TOOL_ENTER, wxCommandEvent); +wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_COMBOBOX_DROPDOWN, wxCommandEvent); +wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_COMBOBOX_CLOSEUP, wxCommandEvent); // Thread events wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_THREAD, wxThreadEvent); @@ -820,7 +811,8 @@ enum wxEventCategory // used in wxEventLoopBase::YieldFor to specify all event categories should be processed: wxEVT_CATEGORY_ALL = wxEVT_CATEGORY_UI|wxEVT_CATEGORY_USER_INPUT|wxEVT_CATEGORY_SOCKET| \ - wxEVT_CATEGORY_TIMER|wxEVT_CATEGORY_THREAD + wxEVT_CATEGORY_TIMER|wxEVT_CATEGORY_THREAD|wxEVT_CATEGORY_UNKNOWN| \ + wxEVT_CATEGORY_CLIPBOARD }; /* @@ -1110,6 +1102,14 @@ public: : 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); @@ -1636,7 +1636,9 @@ private: wxEVT_PAINT_ICON */ -#if defined(__WXDEBUG__) && (defined(__WXMSW__) || defined(__WXPM__)) +#if wxDEBUG_LEVEL && (defined(__WXMSW__) || defined(__WXPM__)) + #define wxHAS_PAINT_DEBUG + // see comments in src/msw|os2/dcclient.cpp where g_isPainting is defined extern WXDLLIMPEXP_CORE int g_isPainting; #endif // debug @@ -1647,15 +1649,15 @@ public: wxPaintEvent(int Id = 0) : wxEvent(Id, wxEVT_PAINT) { -#if defined(__WXDEBUG__) && (defined(__WXMSW__) || defined(__WXPM__)) - // set the internal flag for the duration of processing of WM_PAINT +#ifdef wxHAS_PAINT_DEBUG + // set the internal flag for the duration of redrawing g_isPainting++; #endif // debug } // default copy ctor and dtor are normally fine, we only need them to keep // g_isPainting updated in debug build -#if defined(__WXDEBUG__) && (defined(__WXMSW__) || defined(__WXPM__)) +#ifdef wxHAS_PAINT_DEBUG wxPaintEvent(const wxPaintEvent& event) : wxEvent(event) { @@ -2425,7 +2427,7 @@ public: virtual wxEvent *Clone() const { return new wxNavigationKeyEvent(*this); } - enum + enum wxNavigationKeyEventFlags { IsBackward = 0x0000, IsForward = 0x0001, @@ -2804,10 +2806,11 @@ public: // Clear table void Clear(); -#if defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING - // Clear all tables +#if wxUSE_MEMORY_TRACING + // Clear all tables: only used to work around problems in memory tracing + // code static void ClearAll(); -#endif // __WXDEBUG__ && wxUSE_MEMORY_TRACING +#endif // wxUSE_MEMORY_TRACING protected: // Init the hash table with the entries of the static event table. @@ -2865,7 +2868,6 @@ public: // Event queuing and processing // ---------------------------- - // Process an event right now: this can only be called from the main // thread, use QueueEvent() for scheduling the events for // processing from other threads. @@ -2901,9 +2903,11 @@ public: void ProcessPendingEvents(); // NOTE: uses ProcessEvent() + void DeletePendingEvents(); + #if wxUSE_THREADS bool ProcessThreadEvent(const wxEvent& event); - // NOTE: uses AddPendingEvent() + // NOTE: uses AddPendingEvent(); call only from secondary threads #endif @@ -2974,259 +2978,63 @@ public: { return Disconnect(wxID_ANY, eventType, func, userData, eventSink); } #if !wxEVENTS_COMPATIBILITY_2_8 - // Event handling in functions (including generalized functors): - + // Bind arbitrary functor (including just a function) to an event: template - void Connect(int winid, - int lastId, - const EventTag& eventType, - Functor func) + void Bind(const EventTag& eventType, + Functor functor, + int winid = wxID_ANY, + int lastId = wxID_ANY, + wxObject *userData = NULL) { DoConnect(winid, lastId, eventType, - wxNewEventFunctor(eventType, func)); - } - - template - void Connect(int winid, const EventTag& eventType, Functor func) - { Connect(winid, wxID_ANY, eventType, func); } - - template - void Connect(const EventTag& eventType, Functor func) - { Connect(wxID_ANY, eventType, func); } - - - template - bool Disconnect(int winid, - int lastId, - const EventTag& eventType, - Functor func) - { - return DoDisconnect(winid, lastId, eventType, - wxMakeEventFunctor(eventType, func)); - } - - template - bool Disconnect(int winid, const EventTag& eventType, Functor func) - { return Disconnect(winid, wxID_ANY, eventType, func); } - - template - bool Disconnect(const EventTag& eventType, Functor func) - { return Disconnect(wxID_ANY, eventType, func); } - - - - // Event handling in class methods: the object handling the event (i.e. - // this object itself by default or eventSink if specified) must be - // convertible to this class. - // - // Notice that we need to have separate overloads for the versions with and - // without eventSink because in the latter case we must check that this - // object itself derives from Class while in the former this is not - // necessarily true - - // Methods connecting/disconnecting event to this object itself - - template - void Connect(int winid, - int lastId, - const EventTag& eventType, - void (Class::*func)(EventArg&), - wxObject *userData = NULL) - { - DoConnect(winid, lastId, eventType, - wxNewEventFunctor(eventType, func, static_cast(this)), + wxNewEventFunctor(eventType, functor), userData); } - template - void Connect(int winid, - const EventTag& eventType, - void (Class::*func)(EventArg&), - wxObject *userData = NULL) - { Connect(winid, wxID_ANY, eventType, func, userData); } - - template - void Connect(const EventTag& eventType, - void (Class::*func)(EventArg&), - wxObject *userData = NULL) - { Connect(wxID_ANY, eventType, func, userData); } - - template - bool Disconnect(int winid, - int lastId, - const EventTag& eventType, - void (Class::*func)(EventArg&), - wxObject *userData = NULL) + template + bool Unbind(const EventTag& eventType, + Functor functor, + int winid = wxID_ANY, + int lastId = wxID_ANY, + wxObject *userData = NULL) { return DoDisconnect(winid, lastId, eventType, - wxMakeEventFunctor(eventType, func, - static_cast(this)), + wxMakeEventFunctor(eventType, functor), userData); } - template - bool Disconnect(int winid, - const EventTag& eventType, - void (Class::*func)(EventArg&), - wxObject *userData = NULL) - { return Disconnect(winid, wxID_ANY, eventType, func, userData); } - - template - bool Disconnect(const EventTag& eventType, - void (Class::*func)(EventArg&), - wxObject *userData = NULL) - { return Disconnect(wxID_ANY, eventType, func, userData); } - - // Methods connecting/disconnecting event to another object + // Bind a method of a class (called on the specified handler which must + // be convertible to this class) object to an event: - template - - void Connect(int winid, - int lastId, - const EventTag& eventType, - void (Class::*func)(EventArg&), - wxObject *userData, - ObjClass *eventSink) + template + void Bind(const EventTag &eventType, + void (Class::*method)(EventArg &), + EventHandler *handler, + int winid = wxID_ANY, + int lastId = wxID_ANY, + wxObject *userData = NULL) { DoConnect(winid, lastId, eventType, - wxNewEventFunctor(eventType, func, eventSink), + wxNewEventFunctor(eventType, method, handler), userData); } - template - - void Connect(int winid, - const EventTag& eventType, - void (Class::*func)(EventArg&), - wxObject *userData, - ObjClass *eventSink) - { Connect(winid, wxID_ANY, eventType, func, userData, eventSink); } - - template - - void Connect(const EventTag& eventType, - void (Class::*func)(EventArg&), - wxObject *userData, - ObjClass *eventSink) - { Connect(wxID_ANY, eventType, func, userData, eventSink); } - - - template - - bool Disconnect(int winid, - int lastId, - const EventTag& eventType, - void (Class::*func)(EventArg&), - wxObject *userData, - ObjClass *eventSink) + template + bool Unbind(const EventTag &eventType, + void (Class::*method)(EventArg&), + EventHandler *handler, + int winid = wxID_ANY, + int lastId = wxID_ANY, + wxObject *userData = NULL ) { return DoDisconnect(winid, lastId, eventType, - wxMakeEventFunctor(eventType, func, eventSink), + wxMakeEventFunctor(eventType, method, handler), userData); } - - template - - bool Disconnect(int winid, - const EventTag& eventType, - void (Class::*func)(EventArg&), - wxObject *userData, - ObjClass *eventSink) - { return Disconnect(winid, wxID_ANY, eventType, func, - userData, eventSink); } - - template - - bool Disconnect(const EventTag& eventType, - void (Class::*func)(EventArg&), - wxObject *userData, - ObjClass *eventSink) - { return Disconnect(wxID_ANY, eventType, func, userData, eventSink); } - - - - // Static version of Connect() which allows to specify the event source and - // event handler in a more symmetric way - template - static void Connect(ObjSource *eventSrc, - int winid, - int lastId, - const EventTag& eventType, - void (Class::*func)(EventArg&), - wxObject *userData = NULL, - ObjClass *eventSink = NULL) - { - eventSrc->Connect(winid, lastId, eventType, func, userData, eventSink); - } - - template - static void Connect(ObjSource *eventSrc, - int winid, - const EventTag& eventType, - void (Class::*func)(EventArg&), - wxObject *userData = NULL, - ObjClass *eventSink = NULL) - { - Connect(eventSrc, winid, wxID_ANY, eventType, func, userData, eventSink); - } - - template - static void Connect(ObjSource *eventSrc, - const EventTag& eventType, - void (Class::*func)(EventArg&), - wxObject *userData = NULL, - ObjClass *eventSink = NULL) - { - Connect(eventSrc, wxID_ANY, eventType, func, userData, eventSink); - } - - - template - static bool Disconnect(ObjSource *eventSrc, - int winid, - int lastId, - const EventTag& eventType, - void (Class::*func)(EventArg&), - wxObject *userData = NULL, - ObjClass *eventSink = NULL) - { - return eventSrc->Disconnect(winid, lastId, eventType, func, - userData, eventSink); - } - - template - static bool Disconnect(ObjSource *eventSrc, - int winid, - const EventTag& eventType, - void (Class::*func)(EventArg&), - wxObject *userData = NULL, - ObjClass *eventSink = NULL) - { - return Disconnect(eventSrc, winid, wxID_ANY, eventType, func, - userData, eventSink); - } - - template - static bool Disconnect(ObjSource *eventSrc, - const EventTag& eventType, - void (Class::*func)(EventArg&), - wxObject *userData = NULL, - ObjClass *eventSink = NULL) - { - return Disconnect(eventSrc, wxID_ANY, eventType, func, - userData, eventSink); - } #endif // !wxEVENTS_COMPATIBILITY_2_8 - wxList* GetDynamicEventTable() const { return m_dynamicEvents ; } // User data can be associated with each wxEvtHandler @@ -3262,7 +3070,7 @@ public: // // 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 TryValidator() hook. + // logic using TryBefore() and TryAfter() hooks. bool ProcessEventHere(wxEvent& event); @@ -3285,21 +3093,25 @@ protected: // hooks for wxWindow used by ProcessEvent() // ----------------------------------------- - // This one is called before trying our own event table to allow plugging - // in the validators. - // - // NB: This method is intentionally *not* inside wxUSE_VALIDATORS! - // It is part of wxBase which doesn't use validators and the code - // is compiled out when building wxBase w/o GUI classes, which affects - // binary compatibility and wxBase library can't be used by GUI - // ports. - virtual bool TryValidator(wxEvent& WXUNUSED(event)) { return false; } + // this one is called before trying our own event table to allow plugging + // in the event handlers overriding the default logic, this is used by e.g. + // validators. + virtual bool TryBefore(wxEvent& 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 TryParent(wxEvent& event); + virtual bool TryAfter(wxEvent& event); + +#ifdef 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; ) + + wxDEPRECATED_BUT_USED_INTERNALLY_INLINE( + virtual bool TryParent(wxEvent& event), return DoTryApp(event); ) +#endif // WXWIN_COMPATIBILITY_2_8 static const wxEventTable sm_eventTable; @@ -3344,13 +3156,16 @@ protected: virtual void *DoGetClientData() const; // Search tracker objects for event connection with this sink - wxEventConnectionRef *FindRefInTrackerList(wxEvtHandler *eventSink); + wxEventConnectionRef *FindRefInTrackerList(wxEvtHandler *handler); private: + // pass the event to wxTheApp instance, called from TryAfter() + bool DoTryApp(wxEvent& event); + DECLARE_DYNAMIC_CLASS_NO_COPY(wxEvtHandler) }; -WX_DEFINE_EXPORTED_ARRAY_PTR(wxEvtHandler*, wxEvtHandlerArray); +WX_DEFINE_ARRAY_WITH_DECL_PTR(wxEvtHandler *, wxEvtHandlerArray, class WXDLLIMPEXP_BASE); // ---------------------------------------------------------------------------- // wxEventConnectionRef represents all connections between two event handlers @@ -3401,6 +3216,13 @@ private: wxDECLARE_NO_ASSIGN_CLASS(wxEventConnectionRef); }; +inline void wxObjectEventFunctor::operator()(wxEvtHandler *handler, wxEvent& event) +{ + wxEvtHandler * const realHandler = m_handler ? m_handler : handler; + + (realHandler->*m_method)(event); +} + // Post a message to the given event handler which will be processed during the // next event loop iteration. // @@ -3932,6 +3754,8 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent& #define EVT_TOOL_RCLICKED_RANGE(id1, id2, func) wx__DECLARE_EVT2(wxEVT_COMMAND_TOOL_RCLICKED, id1, id2, wxCommandEventHandler(func)) #define EVT_TOOL_ENTER(winid, func) wx__DECLARE_EVT1(wxEVT_COMMAND_TOOL_ENTER, winid, wxCommandEventHandler(func)) #define EVT_CHECKLISTBOX(winid, func) wx__DECLARE_EVT1(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, winid, wxCommandEventHandler(func)) +#define EVT_COMBOBOX_DROPDOWN(winid, func) wx__DECLARE_EVT1(wxEVT_COMMAND_COMBOBOX_DROPDOWN, winid, wxCommandEventHandler(func)) +#define EVT_COMBOBOX_CLOSEUP(winid, func) wx__DECLARE_EVT1(wxEVT_COMMAND_COMBOBOX_CLOSEUP, winid, wxCommandEventHandler(func)) // Generic command events #define EVT_COMMAND_LEFT_CLICK(winid, func) wx__DECLARE_EVT1(wxEVT_COMMAND_LEFT_CLICK, winid, wxCommandEventHandler(func)) @@ -3985,6 +3809,41 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent& // Helper functions // ---------------------------------------------------------------------------- +// This is an ugly hack to allow the use of Bind() instead of Connect() inside +// the library code if the library was built with support for it, here is how +// it is used: +// +// class SomeEventHandlingClass : wxBIND_OR_CONNECT_HACK_BASE_CLASS +// public SomeBaseClass +// { +// public: +// SomeEventHandlingClass(wxWindow *win) +// { +// // connect to the event for the given window +// wxBIND_OR_CONNECT_HACK(win, wxEVT_SOMETHING, wxSomeEventHandler, +// SomeEventHandlingClass::OnSomeEvent, this); +// } +// +// private: +// void OnSomeEvent(wxSomeEvent&) { ... } +// }; +// +// This is *not* meant to be used by library users, it is only defined here +// (and not in a private header) because the base class must be visible from +// other public headers, please do NOT use this in your code, it will be +// removed from future wx versions without warning. +#if wxEVENTS_COMPATIBILITY_2_8 + #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) \ + win->Connect(evt, handler(func), NULL, obj) +#else // wxEVENTS_COMPATIBILITY_2_8 + #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) \ + win->Bind(evt, &func, obj) +#endif // wxEVENTS_COMPATIBILITY_2_8/!wxEVENTS_COMPATIBILITY_2_8 + #if wxUSE_GUI // Find a window with the focus, that is also a descendant of the given window.