diff --git a/docs/changes.txt b/docs/changes.txt index c8e851886d..27f23deb7e 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -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: diff --git a/include/wx/valnum.h b/include/wx/valnum.h index 42f7675a76..3f9be1d99c 100644 --- a/include/wx/valnum.h +++ b/include/wx/valnum.h @@ -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; diff --git a/interface/wx/valnum.h b/interface/wx/valnum.h index 7f65786821..8bb6d6346d 100644 --- a/interface/wx/valnum.h +++ b/interface/wx/valnum.h @@ -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); }; /** diff --git a/samples/validate/validate.cpp b/samples/validate/validate.cpp index 5ffc7f1af2..b5594fcf34 100644 --- a/samples/validate/validate.cpp +++ b/samples/validate/validate.cpp @@ -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 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 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 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); diff --git a/samples/validate/validate.h b/samples/validate/validate.h index 48a4ca5cf6..226f703ba3 100644 --- a/samples/validate/validate.h +++ b/samples/validate/validate.h @@ -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; diff --git a/src/common/valnum.cpp b/src/common/valnum.cpp index 4f11072b1c..c2522d1075 100644 --- a/src/common/valnum.cpp +++ b/src/common/valnum.cpp @@ -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