Make DetermineDigits() reusable in other ports

Move this function, and the associated constant, to common code.

This required moving wxSpinCtrlDouble::Create() implementation to the
source file, but there are no real changes.
This commit is contained in:
Vadim Zeitlin
2021-04-25 20:14:46 +01:00
parent c16f85bd4d
commit a44bb13a0c
4 changed files with 47 additions and 31 deletions

View File

@@ -382,13 +382,7 @@ public:
long style = wxSP_ARROW_KEYS,
double min = 0, double max = 100, double initial = 0,
double inc = 1,
const wxString& name = wxT("wxSpinCtrlDouble"))
{
DoSetDigits(DetermineDigits(inc));
return wxSpinCtrlGenericBase::Create(parent, id, value, pos, size,
style, min, max, initial,
inc, name);
}
const wxString& name = wxT("wxSpinCtrlDouble"));
// accessors
double GetValue(wxSPINCTRL_GETVALUE_FIX) const { return DoGetValue(); }
@@ -426,10 +420,6 @@ private:
DoSetDigits(0);
}
// Return the number of digits required to show the numbers using the
// specified increment without loss of precision.
static unsigned DetermineDigits(double inc);
// Just set the number of digits and the format unconditionally.
void DoSetDigits(unsigned digits);

View File

@@ -28,6 +28,14 @@ extern wxSize GetBestSize(const wxControl* spin, int minVal, int maxVal, int bas
// Helper function to check if given combination of range and base is valid.
extern bool IsBaseCompatibleWithRange(int minVal, int maxVal, int base);
// Maximum number of digits returned by DetermineDigits().
const unsigned SPINCTRLDBL_MAX_DIGITS = 20;
// Return the number of digits required to show the numbers using the
// specified increment without loss of precision.
extern unsigned DetermineDigits(double inc);
} // namespace wxSpinCtrlImpl
#endif // _WX_PRIVATE_SPINCTRL_H_

View File

@@ -26,6 +26,8 @@
#include "wx/private/spinctrl.h"
#include <math.h>
wxDEFINE_EVENT(wxEVT_SPINCTRL, wxSpinEvent);
wxDEFINE_EVENT(wxEVT_SPINCTRLDOUBLE, wxSpinDoubleEvent);
@@ -140,4 +142,19 @@ bool wxSpinCtrlImpl::IsBaseCompatibleWithRange(int minVal, int maxVal, int base)
return base == 10 || (minVal >= 0 && maxVal >= 0);
}
unsigned wxSpinCtrlImpl::DetermineDigits(double inc)
{
// TODO-C++11: Use std::modf() to get the fractional part.
inc = fabs(inc);
inc -= static_cast<int>(inc);
if ( inc > 0.0 )
{
return wxMin(SPINCTRLDBL_MAX_DIGITS, -static_cast<int>(floor(log10(inc))));
}
else
{
return 0;
}
}
#endif // wxUSE_SPINCTRL

View File

@@ -723,10 +723,26 @@ void wxSpinCtrl::ResetTextValidator()
// wxSpinCtrlDouble
//-----------------------------------------------------------------------------
#define SPINCTRLDBL_MAX_DIGITS 20
wxIMPLEMENT_DYNAMIC_CLASS(wxSpinCtrlDouble, wxSpinCtrlGenericBase);
bool
wxSpinCtrlDouble::Create(wxWindow *parent,
wxWindowID id,
const wxString& value,
const wxPoint& pos,
const wxSize& size,
long style,
double min, double max, double initial,
double inc,
const wxString& name)
{
DoSetDigits(wxSpinCtrlImpl::DetermineDigits(inc));
return wxSpinCtrlGenericBase::Create(parent, id, value, pos, size,
style, min, max, initial,
inc, name);
}
void wxSpinCtrlDouble::DoSendEvent()
{
wxSpinDoubleEvent event( wxEVT_SPINCTRLDOUBLE, GetId());
@@ -753,7 +769,7 @@ void wxSpinCtrlDouble::SetIncrement(double inc)
DoSetIncrement(inc);
const unsigned digits = DetermineDigits(inc);
const unsigned digits = wxSpinCtrlImpl::DetermineDigits(inc);
// 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
@@ -764,7 +780,8 @@ void wxSpinCtrlDouble::SetIncrement(double inc)
void wxSpinCtrlDouble::SetDigits(unsigned digits)
{
wxCHECK_RET( digits <= SPINCTRLDBL_MAX_DIGITS, "too many digits for wxSpinCtrlDouble" );
wxCHECK_RET( digits <= wxSpinCtrlImpl::SPINCTRLDBL_MAX_DIGITS,
"too many digits for wxSpinCtrlDouble" );
if ( digits == m_digits )
return;
@@ -798,22 +815,6 @@ void wxSpinCtrlDouble::ResetTextValidator()
#endif // wxUSE_VALIDATORS
}
/* static */
unsigned wxSpinCtrlDouble::DetermineDigits(double inc)
{
// TODO-C++11: Use std::modf() to get the fractional part.
inc = fabs(inc);
inc -= static_cast<int>(inc);
if ( inc > 0.0 )
{
return wxMin(SPINCTRLDBL_MAX_DIGITS, -static_cast<int>(floor(log10(inc))));
}
else
{
return 0;
}
}
#endif // wxUSE_SPINBTN
#endif // !wxPort-with-native-spinctrl