X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/4732e2dca973b039b9a7db604a8adf59d99dc1a7..70405f7e3d3a1274d54c05ca8124d8bfb0bc3bb1:/include/wx/event.h diff --git a/include/wx/event.h b/include/wx/event.h index 109c842ffb..23f1f35376 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -20,6 +20,7 @@ #if wxUSE_GUI #include "wx/gdicmn.h" #include "wx/cursor.h" + #include "wx/mousestate.h" #endif #include "wx/dynarray.h" @@ -38,7 +39,24 @@ class WXDLLIMPEXP_FWD_BASE wxList; class WXDLLIMPEXP_FWD_CORE wxWindowBase; #endif // wxUSE_GUI -class WXDLLIMPEXP_FWD_BASE wxEvtHandler; +// We operate with pointer to members of wxEvtHandler (such functions are used +// as event handlers in the event tables or as arguments to Connect()) but by +// default MSVC uses a restricted (but more efficient) representation of +// pointers to members which can't deal with multiple base classes. To avoid +// mysterious (as the compiler is not good enough to detect this and give a +// sensible error message) errors in the user code as soon as it defines +// classes inheriting from both wxEvtHandler (possibly indirectly, e.g. via +// wxWindow) and something else (including our own wxTrackable but not limited +// to it), we use the special MSVC keyword telling the compiler to use a more +// general pointer to member representation for the classes inheriting from +// wxEvtHandler. +#ifdef __VISUALC__ + #define wxMSVC_FWD_MULTIPLE_BASES __multiple_inheritance +#else + #define wxMSVC_FWD_MULTIPLE_BASES +#endif + +class WXDLLIMPEXP_FWD_BASE wxMSVC_FWD_MULTIPLE_BASES wxEvtHandler; class wxEventConnectionRef; // ---------------------------------------------------------------------------- @@ -51,7 +69,7 @@ typedef int wxEventType; // this is used to make the event table entry type safe, so that for an event // handler only a function with proper parameter list can be given. -#define wxStaticCastEvent(type, val) wx_static_cast(type, val) +#define wxStaticCastEvent(type, val) static_cast(val) #define DECLARE_EVENT_TABLE_ENTRY(type, winid, idLast, fn, obj) \ wxEventTableEntry(type, winid, idLast, fn, obj) @@ -99,6 +117,7 @@ extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_TOOL_RCLICKED; extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_TOOL_DROPDOWN_CLICKED; extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_TOOL_ENTER; extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_SPINCTRL_UPDATED; +extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_SPINCTRLDOUBLE_UPDATED; // Sockets and timers send events, too extern WXDLLIMPEXP_BASE const wxEventType wxEVT_SOCKET; @@ -277,12 +296,6 @@ enum Propagation_state class WXDLLIMPEXP_BASE wxEvent : public wxObject { -private: - wxEvent& operator=(const wxEvent&); - -protected: - wxEvent(const wxEvent&); // for implementing Clone() - public: wxEvent(int winid = 0, wxEventType commandType = wxEVT_NULL ); @@ -349,10 +362,13 @@ protected: // backwards compatibility as it is new int m_propagationLevel; -protected: bool m_skipped; bool m_isCommandEvent; +protected: + wxEvent(const wxEvent&); // for implementing Clone() + wxEvent& operator=(const wxEvent&); // for derived classes operator=() + private: // it needs to access our m_propagationLevel friend class WXDLLIMPEXP_FWD_BASE wxPropagateOnce; @@ -626,12 +642,17 @@ enum wxMOUSE_BTN_MAX }; -class WXDLLIMPEXP_CORE wxMouseEvent : public wxEvent +class WXDLLIMPEXP_CORE wxMouseEvent : public wxEvent, + public wxMouseState { public: wxMouseEvent(wxEventType mouseType = wxEVT_NULL); - wxMouseEvent(const wxMouseEvent& event) : wxEvent(event) - { Assign(event); } + wxMouseEvent(const wxMouseEvent& event) + : wxEvent(event), + wxMouseState(event) + { + Assign(event); + } // Was it a button event? (*doesn't* mean: is any button *down*?) bool IsButton() const { return Button(wxMOUSE_BTN_ANY); } @@ -654,20 +675,6 @@ public: // Get the button which is changing state (wxMOUSE_BTN_NONE if none) int GetButton() const; - // Find state of shift/control keys - bool ControlDown() const { return m_controlDown; } - bool MetaDown() const { return m_metaDown; } - bool AltDown() const { return m_altDown; } - bool ShiftDown() const { return m_shiftDown; } - bool CmdDown() const - { -#if defined(__WXMAC__) || defined(__WXCOCOA__) - return MetaDown(); -#else - return ControlDown(); -#endif - } - // Find which event was just generated bool LeftDown() const { return (m_eventType == wxEVT_LEFT_DOWN); } bool MiddleDown() const { return (m_eventType == wxEVT_MIDDLE_DOWN); } @@ -774,7 +781,12 @@ public: virtual wxEvent *Clone() const { return new wxMouseEvent(*this); } - wxMouseEvent& operator=(const wxMouseEvent& event) { if (&event != this) Assign(event); return *this; } + wxMouseEvent& operator=(const wxMouseEvent& event) + { + if (&event != this) + Assign(event); + return *this; + } public: wxCoord m_x, m_y; @@ -785,11 +797,6 @@ public: bool m_aux1Down; bool m_aux2Down; - bool m_controlDown; - bool m_shiftDown; - bool m_altDown; - bool m_metaDown; - int m_clickCount; int m_wheelAxis; @@ -852,48 +859,13 @@ private: wxEVT_HOTKEY */ -class WXDLLIMPEXP_CORE wxKeyEvent : public wxEvent +class WXDLLIMPEXP_CORE wxKeyEvent : public wxEvent, + public wxKeyboardState { public: wxKeyEvent(wxEventType keyType = wxEVT_NULL); wxKeyEvent(const wxKeyEvent& evt); - // can be used check if the key event has exactly the given modifiers: - // "GetModifiers() = wxMOD_CONTROL" is easier to write than "ControlDown() - // && !MetaDown() && !AltDown() && !ShiftDown()" - int GetModifiers() const - { - return (m_controlDown ? wxMOD_CONTROL : 0) | - (m_shiftDown ? wxMOD_SHIFT : 0) | - (m_metaDown ? wxMOD_META : 0) | - (m_altDown ? wxMOD_ALT : 0); - } - - // Find state of shift/control keys - bool ControlDown() const { return m_controlDown; } - bool ShiftDown() const { return m_shiftDown; } - bool MetaDown() const { return m_metaDown; } - bool AltDown() const { return m_altDown; } - - // "Cmd" is a pseudo key which is Control for PC and Unix platforms but - // Apple ("Command") key under Macs: it makes often sense to use it instead - // of, say, ControlDown() because Cmd key is used for the same thing under - // Mac as Ctrl elsewhere (but Ctrl still exists, just not used for this - // purpose under Mac) - bool CmdDown() const - { -#if defined(__WXMAC__) || defined(__WXCOCOA__) - return MetaDown(); -#else - return ControlDown(); -#endif - } - - // exclude MetaDown() from HasModifiers() because NumLock under X is often - // configured as mod2 modifier, yet the key events even when it is pressed - // should be processed normally, not like Ctrl- or Alt-key - bool HasModifiers() const { return ControlDown() || AltDown(); } - // get the key code: an ASCII7 char or an element of wxKeyCode enum int GetKeyCode() const { return (int)m_keyCode; } @@ -936,17 +908,19 @@ public: // example) wxKeyEvent& operator=(const wxKeyEvent& evt) { - if (&evt != this) + if ( &evt != this ) { + wxEvent::operator=(evt); + + // Borland C++ 5.82 doesn't compile an explicit call to an + // 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_controlDown = evt.m_controlDown; - m_shiftDown = evt.m_shiftDown; - m_altDown = evt.m_altDown; - m_metaDown = evt.m_metaDown; m_scanCode = evt.m_scanCode; m_rawCode = evt.m_rawCode; m_rawFlags = evt.m_rawFlags; @@ -962,12 +936,6 @@ public: long m_keyCode; - // TODO: replace those with a single m_modifiers bitmask of wxMOD_XXX? - bool m_controlDown; - bool m_shiftDown; - bool m_altDown; - bool m_metaDown; - // FIXME: what is this for? relation to m_rawXXX? bool m_scanCode; @@ -1348,7 +1316,13 @@ public: { m_show = event.m_show; } void SetShow(bool show) { m_show = show; } - bool GetShow() const { return m_show; } + + // return true if the window was shown, false if hidden + bool IsShown() const { return m_show; } + +#if WXWIN_COMPATIBILITY_2_8 + wxDEPRECATED( bool GetShow() const { return IsShown(); } ) +#endif virtual wxEvent *Clone() const { return new wxShowEvent(*this); } @@ -1373,8 +1347,11 @@ public: : wxEvent(event) { m_iconized = event.m_iconized; } +#if WXWIN_COMPATIBILITY_2_8 + wxDEPRECATED( bool Iconized() const { return IsIconized(); } ) +#endif // return true if the frame was iconized, false if restored - bool Iconized() const { return m_iconized; } + bool IsIconized() const { return m_iconized; } virtual wxEvent *Clone() const { return new wxIconizeEvent(*this); } @@ -2097,10 +2074,16 @@ private: // event handler and related classes // ============================================================================ -// for backwards compatibility and to prevent eVC 4 for ARM from crashing with -// internal compiler error when compiling wx, we define wxObjectEventFunction -// as a wxObject method even though it can only be a wxEvtHandler one -typedef void (wxObject::*wxObjectEventFunction)(wxEvent&); +typedef void (wxEvtHandler::*wxEventFunction)(wxEvent&); + +// We had some trouble (specifically with eVC for ARM WinCE build) with using +// wxEventFunction in the past so we had introduced wxObjectEventFunction which +// used to be a typedef for a member of wxObject and not wxEvtHandler to work +// around this but as eVC is not really supported any longer we now only keep +// this for backwards compatibility and, despite its name, this is a typedef +// for wxEvtHandler member now -- but if we have the same problem with another +// compiler we can restore its old definition for it. +typedef wxEventFunction wxObjectEventFunction; // struct containing the members common to static and dynamic event tables // entries @@ -2259,9 +2242,7 @@ protected: // ---------------------------------------------------------------------------- class WXDLLIMPEXP_BASE wxEvtHandler : public wxObject -#if wxUSE_WEAKREF , public wxTrackable -#endif { public: wxEvtHandler(); @@ -2275,7 +2256,9 @@ public: void SetEvtHandlerEnabled(bool enabled) { m_enabled = enabled; } bool GetEvtHandlerEnabled() const { return m_enabled; } - // process an event right now + // 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. virtual bool ProcessEvent(wxEvent& event); // Process an event by calling ProcessEvent and handling any exceptions @@ -2284,8 +2267,25 @@ public: // wouldn't correctly propagate to wxEventLoop. bool SafelyProcessEvent(wxEvent& event); - // add an event to be processed later - virtual void AddPendingEvent(const 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 + // fields of the event object are deep copies and not use the same string + // buffer as other wxString objects in this thread. + virtual void QueueEvent(wxEvent *event); + + // Add an event to be processed later: notice that this function is not + // safe to call from threads other than main, use QueueEvent() + virtual void AddPendingEvent(const wxEvent& event) + { + // notice that the thread-safety problem comes from the fact that + // Clone() doesn't make deep copies of wxString fields of wxEvent + // object and so the same wxString could be used from both threads when + // the event object is destroyed in this one -- QueueEvent() avoids + // this problem as the event pointer is not used any more in this + // thread at all after it is called. + QueueEvent(event.Clone()); + } void ProcessPendingEvents(); @@ -2297,21 +2297,21 @@ public: // winid and event type void Connect(int winid, int lastId, - int eventType, + wxEventType eventType, wxObjectEventFunction func, wxObject *userData = (wxObject *) NULL, wxEvtHandler *eventSink = (wxEvtHandler *) NULL); // Convenience function: take just one id void Connect(int winid, - int eventType, + wxEventType eventType, wxObjectEventFunction func, wxObject *userData = (wxObject *) NULL, wxEvtHandler *eventSink = (wxEvtHandler *) NULL) { Connect(winid, wxID_ANY, eventType, func, userData, eventSink); } // Even more convenient: without id (same as using id of wxID_ANY) - void Connect(int eventType, + void Connect(wxEventType eventType, wxObjectEventFunction func, wxObject *userData = (wxObject *) NULL, wxEvtHandler *eventSink = (wxEvtHandler *) NULL) @@ -2346,6 +2346,10 @@ public: void SetClientData( void *data ) { DoSetClientData(data); } void *GetClientData() const { return DoGetClientData(); } + + // implementation from now on + // -------------------------- + // check if the given event table entry matches this event and call the // handler if it does // @@ -2355,15 +2359,26 @@ public: wxEvtHandler *handler, wxEvent& event); - // implementation from now on virtual bool SearchEventTable(wxEventTable& table, wxEvent& event); bool SearchDynamicEventTable( wxEvent& event ); // Avoid problems at exit by cleaning up static hash table gracefully void ClearEventHashTable() { GetEventHashTable().Clear(); } -#if wxUSE_WEAKREF void OnSinkDestroyed( wxEvtHandler *sink ); -#endif + + + // The method processing the event in this event handler (or rather in this + // event handler chain as it also tries the next handler and so on), i.e. + // it returns true if we processed this event or false if we didn't but + // does not call TryParent() in the latter case. It also doesn't call + // wxApp::FilterEvent() before processing it, this is supposed to be done + // by the public ProcessEvent() only once for every event we handle. + // + // 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. + bool ProcessEventHere(wxEvent& event); + private: static const wxEventTableEntry sm_eventTableEntries[]; @@ -2430,16 +2445,13 @@ protected: virtual void DoSetClientData( void *data ); virtual void *DoGetClientData() const; -#if wxUSE_WEAKREF // Search tracker objects for event connection with this sink wxEventConnectionRef *FindRefInTrackerList(wxEvtHandler *eventSink); -#endif private: DECLARE_DYNAMIC_CLASS_NO_COPY(wxEvtHandler) }; -#if wxUSE_WEAKREF // ---------------------------------------------------------------------------- // wxEventConnectionRef represents all connections between two event handlers // and enables automatic disconnect when an event handler sink goes out of @@ -2488,17 +2500,28 @@ private: DECLARE_NO_ASSIGN_CLASS(wxEventConnectionRef) }; -#endif // wxUSE_WEAKREF -// Post a message to the given eventhandler which will be processed during the -// next event loop iteration +// Post a message to the given event handler which will be processed during the +// next event loop iteration. +// +// Notice that this one is not thread-safe, use wxQueueEvent() inline void wxPostEvent(wxEvtHandler *dest, const wxEvent& event) { - wxCHECK_RET( dest, wxT("need an object to post event to in wxPostEvent") ); + wxCHECK_RET( dest, "need an object to post event to" ); dest->AddPendingEvent(event); } +// Wrapper around wxEvtHandler::QueueEvent(): adds an event for later +// processing, unlike wxPostEvent it is safe to use from different thread even +// for events with wxString members +inline void wxQueueEvent(wxEvtHandler *dest, wxEvent *event) +{ + wxCHECK_RET( dest, "need an object to queue event for" ); + + dest->QueueEvent(event); +} + typedef void (wxEvtHandler::*wxEventFunction)(wxEvent&); typedef void (wxEvtHandler::*wxIdleEventFunction)(wxIdleEvent&);