Add wxFloatingPointValidator::SetFactor()

This allows displaying values in percents (or also currency units and
subunits, for example) without changing the actually stored value.
This commit is contained in:
Vadim Zeitlin
2018-01-25 19:30:39 +01:00
parent f836d430e9
commit b1e59a6d60
6 changed files with 75 additions and 11 deletions

View File

@@ -175,6 +175,7 @@ All (GUI):
- Add Scintilla FineTicker methods to wxSTC (NewPagodi).
- Add wxFontPickerCtrl::SetMinPointSize() (Andreas Falkenhahn).
- Add Set/GetFooter/Text/Icon() to wxRichMessageDialog (Tobias Taschner)
- Add wxFloatingPointValidator::SetFactor().
wxGTK:

View File

@@ -352,6 +352,11 @@ public:
// supported by the type handled by the validator.
void SetPrecision(unsigned precision) { m_precision = precision; }
// Set multiplier applied for displaying the value, e.g. 100 if the value
// should be displayed in percents, so that the variable containing 0.5
// would be displayed as 50.
void SetFactor(double factor) { m_factor = factor; }
protected:
// Notice that we can't use "long double" here because it's not supported
// by wxNumberFormatter yet, so restrict ourselves to just double (and
@@ -361,12 +366,14 @@ protected:
wxFloatingPointValidatorBase(int style)
: wxNumValidatorBase(style)
{
m_factor = 1.0;
}
wxFloatingPointValidatorBase(const wxFloatingPointValidatorBase& other)
: wxNumValidatorBase(other)
{
m_precision = other.m_precision;
m_factor = other.m_factor;
m_min = other.m_min;
m_max = other.m_max;
@@ -374,7 +381,7 @@ protected:
// Provide methods for wxNumValidator use.
wxString ToString(LongestValueType value) const;
static bool FromString(const wxString& s, LongestValueType *value);
bool FromString(const wxString& s, LongestValueType *value) const;
void DoSetMin(LongestValueType min) { m_min = min; }
void DoSetMax(LongestValueType max) { m_max = max; }
@@ -391,6 +398,9 @@ private:
// Maximum number of decimals digits after the decimal separator.
unsigned m_precision;
// Factor applied for the displayed the value.
double m_factor;
// Minimal and maximal values accepted (inclusive).
LongestValueType m_min, m_max;

View File

@@ -346,6 +346,19 @@ public:
constructor.
*/
void SetPrecision(unsigned precision);
/**
Set factor used for displaying the value.
The value associated with the validator is multiplied by the factor
before displaying it and divided by it when retrieving its value from
the control. By default, the @a factor is 1, so the actual value is not
affected by it, but it can be set to, for example, 100, to display the
value in percents while still storing it as absolute value.
@since 3.1.1
*/
void SetFactor(double factor);
};
/**

View File

@@ -64,7 +64,9 @@ MyData::MyData()
m_string2 = "Valid text";
m_listbox_choices.Add(0);
m_intValue = 0;
m_smallIntValue = 3;
m_doubleValue = 12354.31;
m_percentValue = 0.25;
}
// ----------------------------------------------------------------------------
@@ -219,7 +221,9 @@ void MyFrame::OnTestDialog(wxCommandEvent& WXUNUSED(event))
m_listbox->Append(wxString(wxT("radiobox: ")) + g_radiobox_choices[g_data.m_radiobox_choice]);
m_listbox->Append(wxString::Format("integer value: %d", g_data.m_intValue));
m_listbox->Append(wxString::Format("small int value: %u", g_data.m_smallIntValue));
m_listbox->Append(wxString::Format("double value: %.3f", g_data.m_doubleValue));
m_listbox->Append(wxString::Format("percent value: %.4f", g_data.m_percentValue));
}
}
@@ -304,6 +308,11 @@ MyDialog::MyDialog( wxWindow *parent, const wxString& title,
// setup a sizer with the controls for numeric validators
// ------------------------------------------------------
wxFlexGridSizer* const
numSizer = new wxFlexGridSizer(5, FromDIP(wxSize(5, 5)));
const wxSizerFlags center = wxSizerFlags().CenterVertical();
wxIntegerValidator<int> valInt(&g_data.m_intValue,
wxNUM_VAL_THOUSANDS_SEPARATOR |
wxNUM_VAL_ZERO_AS_BLANK);
@@ -319,8 +328,11 @@ MyDialog::MyDialog( wxWindow *parent, const wxString& title,
wxTE_RIGHT,
valInt
);
m_numericTextInt->SetToolTip("uses wxIntegerValidator to accept positive "
"integers only");
numSizer->Add(new wxStaticText(this, wxID_ANY, "Positive integer:"),
center);
numSizer->Add(m_numericTextInt, wxSizerFlags(center).Expand());
numSizer->AddSpacer(FromDIP(10));
m_numericTextDouble = new wxTextCtrl
(
@@ -338,12 +350,31 @@ MyDialog::MyDialog( wxWindow *parent, const wxString& title,
wxNUM_VAL_NO_TRAILING_ZEROES
)
);
m_numericTextDouble->SetToolTip("uses wxFloatingPointValidator with 3 decimals");
wxBoxSizer *numSizer = new wxBoxSizer( wxHORIZONTAL );
numSizer->Add( m_numericTextInt, 1, wxALL, 10 );
numSizer->Add( m_numericTextDouble, 1, wxALL, 10 );
numSizer->Add(new wxStaticText(this, wxID_ANY, "Up to 3 decimals:"),
center);
numSizer->Add(m_numericTextDouble, wxSizerFlags(center).Expand());
wxIntegerValidator<unsigned short> smallIntVal(&g_data.m_smallIntValue);
smallIntVal.SetRange(1, 5);
numSizer->Add(new wxStaticText(this, wxID_ANY, "Int between 1 and 5:"),
center);
numSizer->Add(new wxTextCtrl(this, wxID_ANY, "",
wxDefaultPosition, wxDefaultSize, wxTE_RIGHT,
smallIntVal),
wxSizerFlags(center).Expand());
numSizer->AddSpacer(FromDIP(10));
wxFloatingPointValidator<float> percentVal(&g_data.m_percentValue);
percentVal.SetPrecision(2);
percentVal.SetFactor(100.0);
numSizer->Add(new wxStaticText(this, wxID_ANY, "Value displayed in %:"),
center);
numSizer->Add(new wxTextCtrl(this, wxID_ANY, "",
wxDefaultPosition, wxDefaultSize, wxTE_RIGHT,
percentVal),
wxSizerFlags(center).Expand());
// setup the main sizer
// --------------------
@@ -358,7 +389,7 @@ MyDialog::MyDialog( wxWindow *parent, const wxString& title,
wxGenericValidator(&g_data.m_radiobox_choice)),
0, wxGROW | wxLEFT|wxBOTTOM|wxRIGHT, 10);
mainsizer->Add( numSizer, 0, wxGROW | wxALL );
mainsizer->Add( numSizer, wxSizerFlags().Expand().DoubleBorder() );
mainsizer->Add(btn, 0, wxGROW | wxALL, 10);

View File

@@ -76,7 +76,9 @@ public:
// variables handled by wxNumericTextValidator
int m_intValue;
unsigned short m_smallIntValue;
double m_doubleValue;
float m_percentValue;
bool m_checkbox_state;
int m_radiobox_choice;

View File

@@ -251,14 +251,21 @@ wxIntegerValidatorBase::IsCharOk(const wxString& val, int pos, wxChar ch) const
wxString wxFloatingPointValidatorBase::ToString(LongestValueType value) const
{
return wxNumberFormatter::ToString(value, m_precision, GetFormatFlags());
return wxNumberFormatter::ToString(value*m_factor,
m_precision,
GetFormatFlags());
}
bool
wxFloatingPointValidatorBase::FromString(const wxString& s,
LongestValueType *value)
LongestValueType *value) const
{
return wxNumberFormatter::FromString(s, value);
if ( !wxNumberFormatter::FromString(s, value) )
return false;
*value /= m_factor;
return true;
}
bool