]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/event.h
refactor wxStaticText::Ellipsize so it's a static public utility function; document...
[wxWidgets.git] / include / wx / event.h
index 4a456f1dbbd24a0b616e699c2d5bb35aaccc51ba..23f1f353766161d4875c69aec522820da80267c2 100644 (file)
@@ -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<type>(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<wxKeyboardState *>(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
@@ -2258,7 +2241,8 @@ protected:
 // wxEvtHandler: the base class for all objects handling wxWidgets events
 // ----------------------------------------------------------------------------
 
-class WXDLLIMPEXP_BASE wxEvtHandler : public wxObject, public wxTrackable
+class WXDLLIMPEXP_BASE wxEvtHandler : public wxObject
+                                    , public wxTrackable
 {
 public:
     wxEvtHandler();
@@ -2272,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
@@ -2281,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();
 
@@ -2294,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)
@@ -2343,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
     //
@@ -2352,7 +2359,6 @@ public:
                                       wxEvtHandler *handler,
                                       wxEvent& event);
 
-    // implementation from now on
     virtual bool SearchEventTable(wxEventTable& table, wxEvent& event);
     bool SearchDynamicEventTable( wxEvent& event );
 
@@ -2360,6 +2366,20 @@ public:
     void ClearEventHashTable() { GetEventHashTable().Clear(); }
     void OnSinkDestroyed( wxEvtHandler *sink );
 
+
+    // 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[];
 
@@ -2481,19 +2501,34 @@ private:
     DECLARE_NO_ASSIGN_CLASS(wxEventConnectionRef)
 };
 
-// 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&);
 
 #define wxEventHandler(func) \
     (wxObjectEventFunction)wxStaticCastEvent(wxEventFunction, &func)
+#define wxIdleEventHandler(func) \
+    (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxIdleEventFunction, &func)
 
 #if wxUSE_GUI
 
@@ -2541,7 +2576,6 @@ typedef void (wxEvtHandler::*wxInitDialogEventFunction)(wxInitDialogEvent&);
 typedef void (wxEvtHandler::*wxSysColourChangedEventFunction)(wxSysColourChangedEvent&);
 typedef void (wxEvtHandler::*wxDisplayChangedEventFunction)(wxDisplayChangedEvent&);
 typedef void (wxEvtHandler::*wxUpdateUIEventFunction)(wxUpdateUIEvent&);
-typedef void (wxEvtHandler::*wxIdleEventFunction)(wxIdleEvent&);
 typedef void (wxEvtHandler::*wxCloseEventFunction)(wxCloseEvent&);
 typedef void (wxEvtHandler::*wxShowEventFunction)(wxShowEvent&);
 typedef void (wxEvtHandler::*wxIconizeEventFunction)(wxIconizeEvent&);
@@ -2601,8 +2635,6 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent&
     (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxDisplayChangedEventFunction, &func)
 #define wxUpdateUIEventHandler(func) \
     (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxUpdateUIEventFunction, &func)
-#define wxIdleEventHandler(func) \
-    (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxIdleEventFunction, &func)
 #define wxCloseEventHandler(func) \
     (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxCloseEventFunction, &func)
 #define wxShowEventHandler(func) \