]> git.saurik.com Git - wxWidgets.git/blobdiff - src/propgrid/advprops.cpp
no real change: rename wxPendingEvents to wxHandlersWithPendingEvents since its curre...
[wxWidgets.git] / src / propgrid / advprops.cpp
index dac42ea3209a42a4358841d5d38c07110829ad90..83d392b3102ddda516e10aee58a061d537d9e442 100644 (file)
@@ -108,6 +108,131 @@ bool operator == (const wxArrayInt& array1, const wxArrayInt& array2)
 #if wxUSE_SPINBTN
 
 
 #if wxUSE_SPINBTN
 
 
+#ifdef __WXMSW__
+  #define IS_MOTION_SPIN_SUPPORTED  1
+#else
+  #define IS_MOTION_SPIN_SUPPORTED  0
+#endif
+
+#if IS_MOTION_SPIN_SUPPORTED
+
+//
+// This class implements ability to rapidly change "spin" value
+// by moving mouse when one of the spin buttons is depressed.
+class wxPGSpinButton : public wxSpinButton
+{
+public:
+    wxPGSpinButton() : wxSpinButton()
+    {
+        m_bLeftDown = false;
+        m_hasCapture = false;
+        m_spins = 1;
+
+        Connect( wxEVT_LEFT_DOWN,
+                 wxMouseEventHandler(wxPGSpinButton::OnMouseEvent) );
+        Connect( wxEVT_LEFT_UP,
+                 wxMouseEventHandler(wxPGSpinButton::OnMouseEvent) );
+        Connect( wxEVT_MOTION,
+                 wxMouseEventHandler(wxPGSpinButton::OnMouseEvent) );
+        Connect( wxEVT_MOUSE_CAPTURE_LOST,
+          wxMouseCaptureLostEventHandler(wxPGSpinButton::OnMouseCaptureLost) );
+    }
+
+    int GetSpins() const
+    {
+        return m_spins;
+    }
+
+private:
+    wxPoint m_ptPosition;
+
+    // Having a separate spins variable allows us to handle validation etc. for
+    // multiple spin events at once (with quick mouse movements there could be
+    // hundreds of 'spins' being done at once). Technically things like this
+    // should be stored in event (wxSpinEvent in this case), but there probably
+    // isn't anything there that can be reliably reused.
+    int     m_spins;
+
+    bool    m_bLeftDown;
+
+    // SpinButton seems to be a special for mouse capture, so we may need track
+    // privately whether mouse is actually captured.
+    bool    m_hasCapture;
+
+    void Capture()
+    {
+        if ( !m_hasCapture )
+        {
+            CaptureMouse();
+            m_hasCapture = true;
+        }
+
+        SetCursor(wxCURSOR_SIZENS);
+    }
+    void Release()
+    {
+        m_bLeftDown = false;
+
+        if ( m_hasCapture )
+        {
+            ReleaseMouse();
+            m_hasCapture = false;
+        }
+
+        wxWindow *parent = GetParent();
+        if ( parent )
+            SetCursor(parent->GetCursor());
+        else
+            SetCursor(wxNullCursor);
+    }
+
+    void OnMouseEvent(wxMouseEvent& event)
+    {
+        if ( event.GetEventType() == wxEVT_LEFT_DOWN )
+        {
+            m_bLeftDown = true;
+            m_ptPosition = event.GetPosition();
+        }
+        else if ( event.GetEventType() == wxEVT_LEFT_UP )
+        {
+            Release();
+            m_bLeftDown = false;
+        }
+        else if ( event.GetEventType() == wxEVT_MOTION )
+        {
+            if ( m_bLeftDown )
+            {
+                int dy = m_ptPosition.y - event.GetPosition().y;
+                if ( dy )
+                {
+                    Capture();
+                    m_ptPosition = event.GetPosition();
+
+                    wxSpinEvent evtscroll( (dy >= 0) ? wxEVT_SCROLL_LINEUP :
+                                                       wxEVT_SCROLL_LINEDOWN,
+                                           GetId() );
+                    evtscroll.SetEventObject(this);
+
+                    wxASSERT( m_spins == 1 );
+
+                    m_spins = abs(dy);
+                    GetEventHandler()->ProcessEvent(evtscroll);
+                    m_spins = 1;
+                }
+            }
+        }
+
+        event.Skip();
+    }
+    void OnMouseCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(event))
+    {
+        Release();
+    }
+};
+
+#endif  // IS_MOTION_SPIN_SUPPORTED
+
+
 WX_PG_IMPLEMENT_INTERNAL_EDITOR_CLASS(SpinCtrl,
                                       wxPGSpinCtrlEditor,
                                       wxPGEditor)
 WX_PG_IMPLEMENT_INTERNAL_EDITOR_CLASS(SpinCtrl,
                                       wxPGSpinCtrlEditor,
                                       wxPGEditor)
@@ -128,7 +253,19 @@ wxPGWindowList wxPGSpinCtrlEditor::CreateControls( wxPropertyGrid* propgrid, wxP
     wxSize tcSz(sz.x - butSz.x - margin, sz.y);
     wxPoint butPos(pos.x + tcSz.x + margin, pos.y);
 
     wxSize tcSz(sz.x - butSz.x - margin, sz.y);
     wxPoint butPos(pos.x + tcSz.x + margin, pos.y);
 
-    wxSpinButton* wnd2 = new wxSpinButton();
+    wxSpinButton* wnd2;
+
+#if IS_MOTION_SPIN_SUPPORTED
+    if ( property->GetAttributeAsLong(wxT("MotionSpin"), 0) )
+    {
+        wnd2 = new wxPGSpinButton();
+    }
+    else
+#endif
+    {
+        wnd2 = new wxSpinButton();
+    }
+
 #ifdef __WXMSW__
     wnd2->Hide();
 #endif
 #ifdef __WXMSW__
     wnd2->Hide();
 #endif
@@ -152,6 +289,7 @@ bool wxPGSpinCtrlEditor::OnEvent( wxPropertyGrid* propgrid, wxPGProperty* proper
 {
     int evtType = event.GetEventType();
     int keycode = -1;
 {
     int evtType = event.GetEventType();
     int keycode = -1;
+    int spins = 1;
     bool bigStep = false;
 
     if ( evtType == wxEVT_KEY_DOWN )
     bool bigStep = false;
 
     if ( evtType == wxEVT_KEY_DOWN )
@@ -177,6 +315,17 @@ bool wxPGSpinCtrlEditor::OnEvent( wxPropertyGrid* propgrid, wxPGProperty* proper
 
     if ( evtType == wxEVT_SCROLL_LINEUP || evtType == wxEVT_SCROLL_LINEDOWN )
     {
 
     if ( evtType == wxEVT_SCROLL_LINEUP || evtType == wxEVT_SCROLL_LINEDOWN )
     {
+    #if IS_MOTION_SPIN_SUPPORTED
+        if ( property->GetAttributeAsLong(wxT("MotionSpin"), 0) )
+        {
+            wxPGSpinButton* spinButton =
+                (wxPGSpinButton*) propgrid->GetEditorControlSecondary();
+
+            if ( spinButton )
+                spins = spinButton->GetSpins();
+        }
+    #endif
+
         wxString s;
         // Can't use wnd since it might be clipper window
         wxTextCtrl* tc = wxDynamicCast(propgrid->GetEditorControl(), wxTextCtrl);
         wxString s;
         // Can't use wnd since it might be clipper window
         wxTextCtrl* tc = wxDynamicCast(propgrid->GetEditorControl(), wxTextCtrl);
@@ -202,6 +351,8 @@ bool wxPGSpinCtrlEditor::OnEvent( wxPropertyGrid* propgrid, wxPGProperty* proper
                 if ( bigStep )
                     step *= 10.0;
 
                 if ( bigStep )
                     step *= 10.0;
 
+                step *= (double) spins;
+
                 if ( evtType == wxEVT_SCROLL_LINEUP ) v_d += step;
                 else v_d -= step;
 
                 if ( evtType == wxEVT_SCROLL_LINEUP ) v_d += step;
                 else v_d -= step;
 
@@ -226,6 +377,8 @@ bool wxPGSpinCtrlEditor::OnEvent( wxPropertyGrid* propgrid, wxPGProperty* proper
                 if ( bigStep )
                     step *= 10;
 
                 if ( bigStep )
                     step *= 10;
 
+                step *= spins;
+
                 if ( evtType == wxEVT_SCROLL_LINEUP ) v_ll += step;
                 else v_ll -= step;
 
                 if ( evtType == wxEVT_SCROLL_LINEUP ) v_ll += step;
                 else v_ll -= step;
 
@@ -1751,7 +1904,8 @@ void wxMultiChoiceProperty::GenerateValueAsString( wxVariant& value,
 
 wxArrayInt wxMultiChoiceProperty::GetValueAsIndices() const
 {
 
 wxArrayInt wxMultiChoiceProperty::GetValueAsIndices() const
 {
-    const wxArrayInt& valueArr = wxArrayIntRefFromVariant(GetValue());
+    wxVariant variant = GetValue();
+    const wxArrayInt& valueArr = wxArrayIntRefFromVariant(variant);
     unsigned int i;
 
     // Translate values to string indices.
     unsigned int i;
 
     // Translate values to string indices.