From 0153a6673e540d81b41b604397f0d951111ff21a Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 25 Apr 2021 19:54:27 +0100 Subject: [PATCH] Don't decrease the number of digits implicitly wxSpinCtrlDouble::SetIncrement() should increase the number of digits if necessary because not doing it would be inconsistent with the initial determination of the number of digits in the ctor and would actually lose the digits displayed, but it seems unnecessary to decrease the number of digits and it might be surprising, so don't do it. Add a test for this behaviour and document it. --- include/wx/generic/spinctlg.h | 7 ++++--- interface/wx/spinctrl.h | 11 +++++++++-- src/generic/spinctlg.cpp | 23 ++++++++++++++--------- tests/controls/spinctrldbltest.cpp | 5 +++++ 4 files changed, 32 insertions(+), 14 deletions(-) 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)