diff --git a/include/wx/generic/spinctlg.h b/include/wx/generic/spinctlg.h index ced305ef97..b931f3457c 100644 --- a/include/wx/generic/spinctlg.h +++ b/include/wx/generic/spinctlg.h @@ -384,7 +384,7 @@ public: double inc = 1, const wxString& name = wxT("wxSpinCtrlDouble")) { - DetermineDigits(inc); + DoSetDigits(DetermineDigits(inc)); return wxSpinCtrlGenericBase::Create(parent, id, value, pos, size, style, min, max, initial, inc, name); @@ -426,8 +426,9 @@ private: DoSetDigits(0); } - // Update m_digits and m_format to correspond to the given increment. - void DetermineDigits(double inc); + // Return the number of digits required to show the numbers using the + // specified increment without loss of precision. + static unsigned DetermineDigits(double inc); // Set the number of digits and the format unconditionally. void DoSetDigits(unsigned digits); diff --git a/interface/wx/spinctrl.h b/interface/wx/spinctrl.h index 6371aeec7c..dd213178d5 100644 --- a/interface/wx/spinctrl.h +++ b/interface/wx/spinctrl.h @@ -354,8 +354,15 @@ public: /** Sets the increment value. - @note You may also need to change the precision of the value - using SetDigits(). + + Using this method changes the number of digits used by the control to + at least match the value of @a inc, e.g. using the increment of @c 0.01 + sets the number of digits to 2 if it had been less than 2 before. + However it doesn't change the number of digits if it had been already + high enough. + + In any case, you may call SetDigits() explicitly to override the + automatic determination of the number of digits. */ void SetIncrement(double inc); diff --git a/src/generic/spinctlg.cpp b/src/generic/spinctlg.cpp index 98feb4b5a3..f9749f052b 100644 --- a/src/generic/spinctlg.cpp +++ b/src/generic/spinctlg.cpp @@ -753,9 +753,17 @@ void wxSpinCtrlDouble::SetIncrement(double inc) DoSetIncrement(inc); - DetermineDigits(inc); + const unsigned digits = DetermineDigits(inc); - UpdateAfterDigitsChange(); + // We don't decrease the number of digits here, as this is unnecessary and + // could be undesirable, but we do increase it if the current number is not + // high enough to show the numbers without losing precision. + if ( digits > m_digits ) + { + DoSetDigits(digits); + + UpdateAfterDigitsChange(); + } } void wxSpinCtrlDouble::SetDigits(unsigned digits) @@ -794,21 +802,18 @@ void wxSpinCtrlDouble::ResetTextValidator() #endif // wxUSE_VALIDATORS } -void wxSpinCtrlDouble::DetermineDigits(double inc) +/* static */ +unsigned wxSpinCtrlDouble::DetermineDigits(double inc) { - unsigned digits; - inc = fabs(inc); if ( inc > 0.0 && inc < 1.0 ) { - digits = wxMin(SPINCTRLDBL_MAX_DIGITS, -static_cast(floor(log10(inc)))); + return wxMin(SPINCTRLDBL_MAX_DIGITS, -static_cast(floor(log10(inc)))); } else { - digits = 0; + return 0; } - - DoSetDigits(digits); } #endif // wxUSE_SPINBTN diff --git a/tests/controls/spinctrldbltest.cpp b/tests/controls/spinctrldbltest.cpp index f4dcf380f2..e8a8f32459 100644 --- a/tests/controls/spinctrldbltest.cpp +++ b/tests/controls/spinctrldbltest.cpp @@ -231,6 +231,11 @@ TEST_CASE_METHOD(SpinCtrlDoubleTestCase, CHECK( m_spin->GetDigits() == 5 ); m_spin->SetValue(1.23456789); CHECK( m_spin->GetTextValue() == "1.23457" ); + + // The number of digits shouldn't (implicitly) decrease however. + m_spin->SetIncrement(0.001); + m_spin->SetValue(1.23456789); + CHECK( m_spin->GetTextValue() == "1.23457" ); } static inline unsigned int GetInitialDigits(double inc)