Implement ability to rapidly change spin value of SpinCtrl property editor by moving mouse while one of the spin buttons is depressed
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57076 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -1369,7 +1369,7 @@ void FormMain::PopulateWithExamples ()
|
|||||||
|
|
||||||
pg->SetPropertyEditor( wxT("SpinCtrl"), wxPGEditor_SpinCtrl );
|
pg->SetPropertyEditor( wxT("SpinCtrl"), wxPGEditor_SpinCtrl );
|
||||||
pg->SetPropertyAttribute( wxT("SpinCtrl"), wxPG_ATTR_MIN, (long)-10 ); // Use constants instead of string
|
pg->SetPropertyAttribute( wxT("SpinCtrl"), wxPG_ATTR_MIN, (long)-10 ); // Use constants instead of string
|
||||||
pg->SetPropertyAttribute( wxT("SpinCtrl"), wxPG_ATTR_MAX, (long)10 ); // for reduced binary size.
|
pg->SetPropertyAttribute( wxT("SpinCtrl"), wxPG_ATTR_MAX, (long)16384 ); // for reduced binary size.
|
||||||
pg->SetPropertyAttribute( wxT("SpinCtrl"), wxT("Step"), (long)2 );
|
pg->SetPropertyAttribute( wxT("SpinCtrl"), wxT("Step"), (long)2 );
|
||||||
//pg->SetPropertyAttribute( wxT("SpinCtrl"), wxT("Wrap"), true );
|
//pg->SetPropertyAttribute( wxT("SpinCtrl"), wxT("Wrap"), true );
|
||||||
|
|
||||||
|
@@ -108,6 +108,116 @@ bool operator == (const wxArrayInt& array1, const wxArrayInt& array2)
|
|||||||
#if wxUSE_SPINBTN
|
#if wxUSE_SPINBTN
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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 )
|
||||||
|
{
|
||||||
|
Capture();
|
||||||
|
int dy = m_ptPosition.y - event.GetPosition().y;
|
||||||
|
m_ptPosition = event.GetPosition();
|
||||||
|
|
||||||
|
wxSpinEvent evtscroll( (dy >= 0) ? wxEVT_SCROLL_LINEUP :
|
||||||
|
wxEVT_SCROLL_LINEDOWN,
|
||||||
|
GetId() );
|
||||||
|
evtscroll.SetEventObject(this);
|
||||||
|
|
||||||
|
m_spins = abs(dy);
|
||||||
|
GetEventHandler()->ProcessEvent(evtscroll);
|
||||||
|
m_spins = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event.Skip();
|
||||||
|
}
|
||||||
|
void OnMouseCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
Release();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
WX_PG_IMPLEMENT_INTERNAL_EDITOR_CLASS(SpinCtrl,
|
WX_PG_IMPLEMENT_INTERNAL_EDITOR_CLASS(SpinCtrl,
|
||||||
wxPGSpinCtrlEditor,
|
wxPGSpinCtrlEditor,
|
||||||
wxPGEditor)
|
wxPGEditor)
|
||||||
@@ -128,7 +238,10 @@ wxPGWindowList wxPGSpinCtrlEditor::CreateControls( wxPropertyGrid* propgrid, wxP
|
|||||||
wxSize tcSz(sz.x - butSz.x - margin, sz.y);
|
wxSize tcSz(sz.x - butSz.x - margin, sz.y);
|
||||||
wxPoint butPos(pos.x + tcSz.x + margin, pos.y);
|
wxPoint butPos(pos.x + tcSz.x + margin, pos.y);
|
||||||
|
|
||||||
wxSpinButton* wnd2 = new wxSpinButton();
|
wxSpinButton* wnd2;
|
||||||
|
|
||||||
|
wnd2 = new wxPGSpinButton();
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
wnd2->Hide();
|
wnd2->Hide();
|
||||||
#endif
|
#endif
|
||||||
@@ -152,6 +265,7 @@ bool wxPGSpinCtrlEditor::OnEvent( wxPropertyGrid* propgrid, wxPGProperty* proper
|
|||||||
{
|
{
|
||||||
int evtType = event.GetEventType();
|
int evtType = event.GetEventType();
|
||||||
int keycode = -1;
|
int keycode = -1;
|
||||||
|
int spins = 1;
|
||||||
bool bigStep = false;
|
bool bigStep = false;
|
||||||
|
|
||||||
if ( evtType == wxEVT_KEY_DOWN )
|
if ( evtType == wxEVT_KEY_DOWN )
|
||||||
@@ -177,6 +291,12 @@ 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 )
|
||||||
{
|
{
|
||||||
|
wxPGSpinButton* spinButton =
|
||||||
|
(wxPGSpinButton*) propgrid->GetEditorControlSecondary();
|
||||||
|
|
||||||
|
if ( spinButton )
|
||||||
|
spins = spinButton->GetSpins();
|
||||||
|
|
||||||
wxString s;
|
wxString s;
|
||||||
// Can't use wnd since it might be clipper window
|
// Can't use wnd since it might be clipper window
|
||||||
wxTextCtrl* tc = wxDynamicCast(propgrid->GetEditorControl(), wxTextCtrl);
|
wxTextCtrl* tc = wxDynamicCast(propgrid->GetEditorControl(), wxTextCtrl);
|
||||||
@@ -202,6 +322,8 @@ bool wxPGSpinCtrlEditor::OnEvent( wxPropertyGrid* propgrid, wxPGProperty* proper
|
|||||||
if ( bigStep )
|
if ( bigStep )
|
||||||
step *= 10.0;
|
step *= 10.0;
|
||||||
|
|
||||||
|
step *= (double) spins;
|
||||||
|
|
||||||
if ( evtType == wxEVT_SCROLL_LINEUP ) v_d += step;
|
if ( evtType == wxEVT_SCROLL_LINEUP ) v_d += step;
|
||||||
else v_d -= step;
|
else v_d -= step;
|
||||||
|
|
||||||
@@ -226,6 +348,8 @@ bool wxPGSpinCtrlEditor::OnEvent( wxPropertyGrid* propgrid, wxPGProperty* proper
|
|||||||
if ( bigStep )
|
if ( bigStep )
|
||||||
step *= 10;
|
step *= 10;
|
||||||
|
|
||||||
|
step *= spins;
|
||||||
|
|
||||||
if ( evtType == wxEVT_SCROLL_LINEUP ) v_ll += step;
|
if ( evtType == wxEVT_SCROLL_LINEUP ) v_ll += step;
|
||||||
else v_ll -= step;
|
else v_ll -= step;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user