Add wxSpinCtrl::SetIncrement() and implement it for all ports

SetIncrement() was already available in wxSpinCtrlDouble and GTK version
of wxSpinCtrl, now implement support for it in wxMSW and wxOSX as well.

In fact, in wxMSW, implement it at wxSpinButton level, so that both this
class and wxSpinCtrl inheriting from it (in wxMSW only) support setting
custom increment now.

Also add support for it to XRC, show it in the sample and add a unit
test verifying that it works.

Closes #2597.
This commit is contained in:
oneeyeman1
2022-01-15 18:13:48 -06:00
committed by Vadim Zeitlin
parent 57b4a11f24
commit 995c6e6df5
19 changed files with 195 additions and 8 deletions

View File

@@ -2057,6 +2057,8 @@ exactly one non-toplevel window as its child.
Minimum allowed value (default: 0).} Minimum allowed value (default: 0).}
@row3col{max, integer, @row3col{max, integer,
Maximum allowed value (default: 100).} Maximum allowed value (default: 100).}
@row3col{inc, integer,
Increment (default: 1). Available since wxWidgets 3.1.6.}
@endTable @endTable

View File

@@ -58,6 +58,8 @@ public:
// returns true if the platform should explicitly apply a theme border // returns true if the platform should explicitly apply a theme border
virtual bool CanApplyThemeBorder() const wxOVERRIDE { return false; } virtual bool CanApplyThemeBorder() const wxOVERRIDE { return false; }
virtual void SetIncrement(int value) wxOVERRIDE;
virtual int GetIncrement() const wxOVERRIDE;
protected: protected:
virtual wxSize DoGetBestSize() const wxOVERRIDE; virtual wxSize DoGetBestSize() const wxOVERRIDE;

View File

@@ -149,8 +149,10 @@ public :
bool ButtonClickDidStateChange() wxOVERRIDE { return true; } bool ButtonClickDidStateChange() wxOVERRIDE { return true; }
void SetMinimum( wxInt32 v ) wxOVERRIDE; void SetMinimum( wxInt32 v ) wxOVERRIDE;
void SetMaximum( wxInt32 v ) wxOVERRIDE; void SetMaximum( wxInt32 v ) wxOVERRIDE;
void SetIncrement(int value) wxOVERRIDE;
wxInt32 GetMinimum() const wxOVERRIDE; wxInt32 GetMinimum() const wxOVERRIDE;
wxInt32 GetMaximum() const wxOVERRIDE; wxInt32 GetMaximum() const wxOVERRIDE;
int GetIncrement() const wxOVERRIDE;
void PulseGauge() wxOVERRIDE; void PulseGauge() wxOVERRIDE;
void SetScrollThumb( wxInt32 value, wxInt32 thumbSize ) wxOVERRIDE; void SetScrollThumb( wxInt32 value, wxInt32 thumbSize ) wxOVERRIDE;

View File

@@ -347,8 +347,10 @@ public :
virtual void Enable( bool enable ) = 0; virtual void Enable( bool enable ) = 0;
virtual void SetMinimum( wxInt32 v ) = 0; virtual void SetMinimum( wxInt32 v ) = 0;
virtual void SetMaximum( wxInt32 v ) = 0; virtual void SetMaximum( wxInt32 v ) = 0;
virtual void SetIncrement(int value) = 0;
virtual wxInt32 GetMinimum() const = 0; virtual wxInt32 GetMinimum() const = 0;
virtual wxInt32 GetMaximum() const = 0; virtual wxInt32 GetMaximum() const = 0;
virtual int GetIncrement() const = 0;
virtual void PulseGauge() = 0; virtual void PulseGauge() = 0;
virtual void SetScrollThumb( wxInt32 value, wxInt32 thumbSize ) = 0; virtual void SetScrollThumb( wxInt32 value, wxInt32 thumbSize ) = 0;

View File

@@ -100,8 +100,10 @@ public :
bool ButtonClickDidStateChange() { return true ;} bool ButtonClickDidStateChange() { return true ;}
void SetMinimum( wxInt32 v ); void SetMinimum( wxInt32 v );
void SetMaximum( wxInt32 v ); void SetMaximum( wxInt32 v );
void SetIncrement(int WXUNUSED(value)) { }
wxInt32 GetMinimum() const; wxInt32 GetMinimum() const;
wxInt32 GetMaximum() const; wxInt32 GetMaximum() const;
int GetIncrement() const { return 1; }
void PulseGauge(); void PulseGauge();
void SetScrollThumb( wxInt32 value, wxInt32 thumbSize ); void SetScrollThumb( wxInt32 value, wxInt32 thumbSize );

View File

@@ -54,6 +54,8 @@ public:
virtual void SetRange(int minVal, int maxVal) wxOVERRIDE; virtual void SetRange(int minVal, int maxVal) wxOVERRIDE;
virtual int GetValue() const wxOVERRIDE; virtual int GetValue() const wxOVERRIDE;
virtual void SetValue(int val) wxOVERRIDE; virtual void SetValue(int val) wxOVERRIDE;
virtual void SetIncrement(int value) wxOVERRIDE;
virtual int GetIncrement() const wxOVERRIDE;
// implementation // implementation

View File

@@ -61,12 +61,13 @@ public:
// is this spin button vertically oriented? // is this spin button vertically oriented?
bool IsVertical() const { return (m_windowStyle & wxSP_VERTICAL) != 0; } bool IsVertical() const { return (m_windowStyle & wxSP_VERTICAL) != 0; }
virtual void SetIncrement(int WXUNUSED(value)) { }
virtual int GetIncrement() const { return 1; }
protected: protected:
// the range value // the range value
int m_min; int m_min;
int m_max; int m_max;
wxDECLARE_NO_COPY_CLASS(wxSpinButtonBase); wxDECLARE_NO_COPY_CLASS(wxSpinButtonBase);
}; };

View File

@@ -54,7 +54,7 @@ public:
A wxSpinButton has two small up and down (or left and right) arrow buttons. A wxSpinButton has two small up and down (or left and right) arrow buttons.
It is often used next to a text control for increment and decrementing a value. It is often used next to a text control for incrementing and decrementing a value.
Portable programs should try to use wxSpinCtrl instead as wxSpinButton is not Portable programs should try to use wxSpinCtrl instead as wxSpinButton is not
implemented for all platforms but wxSpinCtrl is as it degenerates to a simple implemented for all platforms but wxSpinCtrl is as it degenerates to a simple
wxTextCtrl on such platforms. wxTextCtrl on such platforms.
@@ -146,6 +146,15 @@ public:
long style = wxSP_VERTICAL, long style = wxSP_VERTICAL,
const wxString& name = "wxSpinButton"); const wxString& name = "wxSpinButton");
/**
Get the value for increment for a spin control.
The default value is 1 but it can be changed using SetIncrement().
@since 3.1.6
*/
int GetIncrement() const;
/** /**
Returns the maximum permissible value. Returns the maximum permissible value.
@@ -167,6 +176,23 @@ public:
*/ */
virtual int GetValue() const; virtual int GetValue() const;
/**
Sets the increment for the control.
The increment is the number by which the value changes when the up or
down arrow is used.
The default is 1.
This function is currently implemented only in wxMSW and does nothing
under the other platforms.
@since 3.1.6
@see wxSpinCtrl::SetIncrement()
*/
void SetIncrement(int value);
/** /**
Sets the range of the spin button. Sets the range of the spin button.

View File

@@ -145,6 +145,15 @@ public:
*/ */
int GetValue() const; int GetValue() const;
/**
Get the value for increment for a spin control.
The default value is 1 but it can be changed using SetIncrement().
@since 3.1.6
*/
int GetIncrement() const;
/** /**
Sets the base to use for the numbers in this control. Sets the base to use for the numbers in this control.
@@ -214,6 +223,22 @@ public:
Calling this method doesn't generate any @c wxEVT_SPINCTRL events. Calling this method doesn't generate any @c wxEVT_SPINCTRL events.
*/ */
void SetValue(int value); void SetValue(int value);
/**
Sets the increment for the control.
The increment is the number by which the value changes when the up or
down arrow is used.
The default is 1, but it can be useful to set it to a higher value when
using the control for bigger numbers.
Note that it is still possible to enter any value (in the valid range)
into the control manually, whatever is the value of the increment.
@since 3.1.6
*/
void SetIncrement(int value);
}; };
/** /**

View File

@@ -1482,7 +1482,8 @@ wxSpinButton =
stdWindowProperties & stdWindowProperties &
[xrc:p="o"] element value {_, t_integer }* & [xrc:p="o"] element value {_, t_integer }* &
[xrc:p="o"] element min {_, t_integer }* & [xrc:p="o"] element min {_, t_integer }* &
[xrc:p="o"] element max {_, t_integer }* [xrc:p="o"] element max {_, t_integer }* &
[xrc:p="o"] element inc {_, t_integer }*
} }
@@ -1494,7 +1495,8 @@ wxSpinCtrl =
[xrc:p="o"] element value {_, t_integer }* & [xrc:p="o"] element value {_, t_integer }* &
[xrc:p="o"] element min {_, t_integer }* & [xrc:p="o"] element min {_, t_integer }* &
[xrc:p="o"] element max {_, t_integer }* & [xrc:p="o"] element max {_, t_integer }* &
[xrc:p="o"] element base {_, ("10" | "16") }* [xrc:p="o"] element base {_, ("10" | "16") }* &
[xrc:p="o"] element inc {_, t_integer }*
} }

View File

@@ -55,11 +55,13 @@ enum
SpinBtnPage_SetValue, SpinBtnPage_SetValue,
SpinBtnPage_SetMinAndMax, SpinBtnPage_SetMinAndMax,
SpinBtnPage_SetBase, SpinBtnPage_SetBase,
SpinBtnPage_SetIncrement,
SpinBtnPage_CurValueText, SpinBtnPage_CurValueText,
SpinBtnPage_ValueText, SpinBtnPage_ValueText,
SpinBtnPage_MinText, SpinBtnPage_MinText,
SpinBtnPage_MaxText, SpinBtnPage_MaxText,
SpinBtnPage_BaseText, SpinBtnPage_BaseText,
SpinBtnPage_SetIncrementText,
SpinBtnPage_SpinBtn, SpinBtnPage_SpinBtn,
SpinBtnPage_SpinCtrl, SpinBtnPage_SpinCtrl,
SpinBtnPage_SpinCtrlDouble SpinBtnPage_SpinCtrlDouble
@@ -103,7 +105,7 @@ protected:
void OnButtonSetValue(wxCommandEvent& event); void OnButtonSetValue(wxCommandEvent& event);
void OnButtonSetMinAndMax(wxCommandEvent& event); void OnButtonSetMinAndMax(wxCommandEvent& event);
void OnButtonSetBase(wxCommandEvent& event); void OnButtonSetBase(wxCommandEvent& event);
void OnButtonSetIncrement(wxCommandEvent &event);
void OnCheckOrRadioBox(wxCommandEvent& event); void OnCheckOrRadioBox(wxCommandEvent& event);
void OnSpinBtn(wxSpinEvent& event); void OnSpinBtn(wxSpinEvent& event);
@@ -138,6 +140,9 @@ protected:
// and numeric base // and numeric base
int m_base; int m_base;
// the increment
int m_increment;
// the controls // the controls
// ------------ // ------------
@@ -159,7 +164,8 @@ protected:
wxTextCtrl *m_textValue, wxTextCtrl *m_textValue,
*m_textMin, *m_textMin,
*m_textMax, *m_textMax,
*m_textBase; *m_textBase,
*m_textIncrement;
private: private:
wxDECLARE_EVENT_TABLE(); wxDECLARE_EVENT_TABLE();
@@ -175,6 +181,7 @@ wxBEGIN_EVENT_TABLE(SpinBtnWidgetsPage, WidgetsPage)
EVT_BUTTON(SpinBtnPage_SetValue, SpinBtnWidgetsPage::OnButtonSetValue) EVT_BUTTON(SpinBtnPage_SetValue, SpinBtnWidgetsPage::OnButtonSetValue)
EVT_BUTTON(SpinBtnPage_SetMinAndMax, SpinBtnWidgetsPage::OnButtonSetMinAndMax) EVT_BUTTON(SpinBtnPage_SetMinAndMax, SpinBtnWidgetsPage::OnButtonSetMinAndMax)
EVT_BUTTON(SpinBtnPage_SetBase, SpinBtnWidgetsPage::OnButtonSetBase) EVT_BUTTON(SpinBtnPage_SetBase, SpinBtnWidgetsPage::OnButtonSetBase)
EVT_BUTTON(SpinBtnPage_SetIncrement, SpinBtnWidgetsPage::OnButtonSetIncrement)
EVT_UPDATE_UI(SpinBtnPage_SetValue, SpinBtnWidgetsPage::OnUpdateUIValueButton) EVT_UPDATE_UI(SpinBtnPage_SetValue, SpinBtnWidgetsPage::OnUpdateUIValueButton)
EVT_UPDATE_UI(SpinBtnPage_SetMinAndMax, SpinBtnWidgetsPage::OnUpdateUIMinMaxButton) EVT_UPDATE_UI(SpinBtnPage_SetMinAndMax, SpinBtnWidgetsPage::OnUpdateUIMinMaxButton)
@@ -227,12 +234,14 @@ SpinBtnWidgetsPage::SpinBtnWidgetsPage(WidgetsBookCtrl *book,
m_textValue = m_textValue =
m_textMin = m_textMin =
m_textMax = m_textMax =
m_textBase = NULL; m_textBase =
m_textIncrement = NULL;
m_min = 0; m_min = 0;
m_max = 10; m_max = 10;
m_base = 10; m_base = 10;
m_increment = 1;
m_sizerSpin = NULL; m_sizerSpin = NULL;
} }
@@ -311,6 +320,13 @@ void SpinBtnWidgetsPage::CreateContent()
m_textBase->SetValue("10"); m_textBase->SetValue("10");
sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5); sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
sizerRow = CreateSizerWithTextAndButton( SpinBtnPage_SetIncrement,
"Set Increment",
SpinBtnPage_SetIncrementText,
&m_textIncrement );
m_textIncrement->SetValue( "1" );
sizerMiddle->Add( sizerRow, 0, wxALL | wxGROW, 5 );
// right pane // right pane
wxSizer *sizerRight = new wxBoxSizer(wxVERTICAL); wxSizer *sizerRight = new wxBoxSizer(wxVERTICAL);
sizerRight->SetMinSize(150, 0); sizerRight->SetMinSize(150, 0);
@@ -481,6 +497,20 @@ void SpinBtnWidgetsPage::OnButtonSetBase(wxCommandEvent& WXUNUSED(event))
m_sizerSpin->Layout(); m_sizerSpin->Layout();
} }
void SpinBtnWidgetsPage::OnButtonSetIncrement(wxCommandEvent& WXUNUSED (event))
{
int increment = wxAtoi( m_textIncrement->GetValue() );
if ( !increment )
{
wxLogWarning("Invalid increment value.");
return;
}
m_increment = increment;
m_spinctrl->SetIncrement(m_increment);
wxLogWarning("Setting increment to %d.", m_increment);
}
void SpinBtnWidgetsPage::OnButtonSetValue(wxCommandEvent& WXUNUSED(event)) void SpinBtnWidgetsPage::OnButtonSetValue(wxCommandEvent& WXUNUSED(event))
{ {
if ( m_textValue->IsEmpty() ) if ( m_textValue->IsEmpty() )

View File

@@ -962,6 +962,7 @@ lay them out using wxSizers, absolute positioning, everything you like!
<style>wxSP_WRAP</style> <style>wxSP_WRAP</style>
<max>100</max> <max>100</max>
<value>0</value> <value>0</value>
<inc>2</inc>
</object> </object>
</object> </object>
</object> </object>
@@ -985,6 +986,7 @@ lay them out using wxSizers, absolute positioning, everything you like!
<max>100</max> <max>100</max>
<value>17</value> <value>17</value>
<base>16</base> <base>16</base>
<inc>2</inc>
</object> </object>
</object> </object>
</object> </object>

View File

@@ -288,4 +288,24 @@ bool wxSpinButton::MSWCommand(WXUINT WXUNUSED(cmd), WXWORD WXUNUSED(id))
return false; return false;
} }
void wxSpinButton::SetIncrement(int value)
{
UDACCEL accel;
accel.nSec = 0;
accel.nInc = value;
::SendMessage(GetHwnd(), UDM_SETACCEL, 1, (LPARAM) &accel);
}
int wxSpinButton::GetIncrement() const
{
UDACCEL accel;
// If the message is unsupported, this default value won't be modified and
// will be returned below.
accel.nInc = 1;
::SendMessage(GetHwnd(), UDM_GETACCEL, 1, (LPARAM) &accel);
return accel.nInc;
}
#endif // wxUSE_SPINBTN #endif // wxUSE_SPINBTN

View File

@@ -877,5 +877,4 @@ void wxSpinCtrl::DoClientToScreen(int *x, int *y) const
{ {
wxWindow::MSWDoClientToScreen(GetBuddyHwnd(), x, y); wxWindow::MSWDoClientToScreen(GetBuddyHwnd(), x, y);
} }
#endif // wxUSE_SPINCTRL #endif // wxUSE_SPINCTRL

View File

@@ -51,6 +51,8 @@ public :
virtual void SetValue(wxInt32 v) wxOVERRIDE; virtual void SetValue(wxInt32 v) wxOVERRIDE;
virtual void SetMinimum(wxInt32 v) wxOVERRIDE; virtual void SetMinimum(wxInt32 v) wxOVERRIDE;
virtual void SetMaximum(wxInt32 v) wxOVERRIDE; virtual void SetMaximum(wxInt32 v) wxOVERRIDE;
virtual void SetIncrement(int value) wxOVERRIDE;
virtual int GetIncrement() const wxOVERRIDE;
virtual void controlAction(WXWidget slf, void* _cmd, void *sender) wxOVERRIDE; virtual void controlAction(WXWidget slf, void* _cmd, void *sender) wxOVERRIDE;
virtual void mouseEvent(WX_NSEvent event, WXWidget slf, void* _cmd) wxOVERRIDE; virtual void mouseEvent(WX_NSEvent event, WXWidget slf, void* _cmd) wxOVERRIDE;
private: private:
@@ -123,6 +125,16 @@ void wxSpinButtonCocoaImpl::controlAction( WXWidget WXUNUSED(slf), void *WXUNUSE
} }
} }
void wxSpinButtonCocoaImpl::SetIncrement(int value)
{
[(NSStepper*)m_osxView setIncrement:value];
}
int wxSpinButtonCocoaImpl::GetIncrement() const
{
return [(NSStepper *) m_osxView increment];
}
wxWidgetImplType* wxWidgetImpl::CreateSpinButton( wxWindowMac* wxpeer, wxWidgetImplType* wxWidgetImpl::CreateSpinButton( wxWindowMac* wxpeer,
wxWindowMac* WXUNUSED(parent), wxWindowMac* WXUNUSED(parent),
wxWindowID WXUNUSED(id), wxWindowID WXUNUSED(id),

View File

@@ -181,8 +181,10 @@ NSRect wxOSXGetFrameForControl( wxWindowMac* window , const wxPoint& pos , const
- (double)minValue; - (double)minValue;
- (double)maxValue; - (double)maxValue;
- (int)increment;
- (void)setMinValue:(double)aDouble; - (void)setMinValue:(double)aDouble;
- (void)setMaxValue:(double)aDouble; - (void)setMaxValue:(double)aDouble;
- (void)setIncrement:(int)value;
- (void)sizeToFit; - (void)sizeToFit;
@@ -3420,6 +3422,23 @@ wxInt32 wxWidgetCocoaImpl::GetMinimum() const
return 0; return 0;
} }
void wxWidgetCocoaImpl::SetIncrement(int value)
{
if ( [m_osxView respondsToSelector:@selector(setIncrement:)] )
{
[m_osxView setIncrement:value];
}
}
int wxWidgetCocoaImpl::GetIncrement() const
{
if( [m_osxView respondsToSelector:@selector(increment)] )
{
return (int) [m_osxView increment];
}
return 0;
}
wxInt32 wxWidgetCocoaImpl::GetMaximum() const wxInt32 wxWidgetCocoaImpl::GetMaximum() const
{ {
if ( [m_osxView respondsToSelector:@selector(maxValue)] ) if ( [m_osxView respondsToSelector:@selector(maxValue)] )

View File

@@ -142,4 +142,14 @@ void wxSpinButton::TriggerScrollEvent(wxEventType scrollEvent)
SendThumbTrackEvent() ; SendThumbTrackEvent() ;
} }
void wxSpinButton::SetIncrement(int value)
{
GetPeer()->SetIncrement( value );
}
int wxSpinButton::GetIncrement() const
{
return GetPeer()->GetIncrement();
}
#endif // wxUSE_SPINBTN #endif // wxUSE_SPINBTN

View File

@@ -22,6 +22,7 @@
static const long DEFAULT_VALUE = 0; static const long DEFAULT_VALUE = 0;
static const long DEFAULT_MIN = 0; static const long DEFAULT_MIN = 0;
static const long DEFAULT_MAX = 100; static const long DEFAULT_MAX = 100;
static const int DEFAULT_INCREMENT = 1;
wxIMPLEMENT_DYNAMIC_CLASS(wxSpinButtonXmlHandler, wxXmlResourceHandler); wxIMPLEMENT_DYNAMIC_CLASS(wxSpinButtonXmlHandler, wxXmlResourceHandler);
@@ -48,6 +49,7 @@ wxObject *wxSpinButtonXmlHandler::DoCreateResource()
control->SetValue(GetLong( wxT("value"), DEFAULT_VALUE)); control->SetValue(GetLong( wxT("value"), DEFAULT_VALUE));
control->SetRange(GetLong( wxT("min"), DEFAULT_MIN), control->SetRange(GetLong( wxT("min"), DEFAULT_MIN),
GetLong(wxT("max"), DEFAULT_MAX)); GetLong(wxT("max"), DEFAULT_MAX));
control->SetValue(GetLong(wxT( "inc" ), DEFAULT_INCREMENT));
SetupWindow(control); SetupWindow(control);
return control; return control;
@@ -98,6 +100,7 @@ wxObject *wxSpinCtrlXmlHandler::DoCreateResource()
GetLong(wxT("max"), DEFAULT_MAX), GetLong(wxT("max"), DEFAULT_MAX),
GetLong(wxT("value"), DEFAULT_VALUE), GetLong(wxT("value"), DEFAULT_VALUE),
GetName()); GetName());
control->SetIncrement(GetLong(wxT("inc"), DEFAULT_INCREMENT));
const long base = GetLong(wxS("base"), 10); const long base = GetLong(wxS("base"), 10);
if ( base != 10 ) if ( base != 10 )

View File

@@ -368,4 +368,30 @@ TEST_CASE_METHOD(SpinCtrlTestCase3, "SpinCtrl::SetValueInsideEventHandler", "[sp
#endif // wxUSE_UIACTIONSIMULATOR #endif // wxUSE_UIACTIONSIMULATOR
} }
TEST_CASE_METHOD(SpinCtrlTestCase1, "SpinCtrl::Increment", "[spinctrl]")
{
#if wxUSE_UIACTIONSIMULATOR
m_spin->Create(wxTheApp->GetTopWindow(), wxID_ANY, "",
wxDefaultPosition, wxDefaultSize,
wxSP_ARROW_KEYS | wxSP_WRAP);
wxUIActionSimulator sim;
CHECK( m_spin->GetIncrement() == 1 );
m_spin->SetFocus();
wxYield();
m_spin->SetIncrement( 5 );
sim.Char(WXK_UP);
wxYield();
CHECK(m_spin->GetValue() == 5);
int increment = m_spin->GetIncrement();
CHECK( increment == 5 );
#endif
}
#endif #endif