11#ifndef _WIDGETS_VALNUM_H_
12#define _WIDGETS_VALNUM_H_
20#include <wx/textctrl.h>
21#include <wx/validate.h>
28enum class NumValidatorStyle :
int
31 THOUSANDS_SEPARATOR = 0x1,
33 NO_TRAILING_ZEROES = 0x4,
34 ONE_TRAILING_ZERO = 0x8,
35 TWO_TRAILING_ZEROES = 0x10,
36 THREE_TRAILING_ZEROES = 0x20
39inline NumValidatorStyle
operator | (NumValidatorStyle x, NumValidatorStyle y)
40{
return NumValidatorStyle(
int(x) |
int(y) ); }
42inline int operator & (NumValidatorStyle x, NumValidatorStyle y)
43{
return int(x) & int(y); }
49class AUDACITY_DLL_API NumValidatorBase :
public wxValidator
53 void SetStyle(NumValidatorStyle
style) { m_style =
style; }
57 bool Validate(wxWindow * parent)
override;
60 NumValidatorBase(NumValidatorStyle
style)
67 NumValidatorBase(
const NumValidatorBase& other) : wxValidator()
69 m_style = other.m_style;
70 m_minSet = other.m_minSet;
71 m_maxSet = other.m_maxSet;
74 bool HasFlag(NumValidatorStyle
style)
const
76 return (m_style &
style) != 0;
82 wxTextEntry *GetTextEntry()
const;
86 int GetFormatFlags()
const;
91 bool IsMinusOk(
const wxString& val,
int pos)
const;
95 wxString GetValueAfterInsertingChar(
const wxString &valArg,
int pos, wxChar ch)
const
112 virtual bool IsCharOk(
const wxString& val,
int pos, wxChar ch)
const = 0;
116 virtual wxString NormalizeString(
const wxString& s)
const = 0;
124 void OnChar(wxKeyEvent& event);
125 void OnPaste(wxClipboardTextEvent& event);
126 void OnKillFocus(wxFocusEvent& event);
130 void GetCurrentValueAndInsertionPoint(wxString& val,
int& pos)
const;
134 NumValidatorStyle m_style;
136 DECLARE_EVENT_TABLE()
138 DECLARE_NO_ASSIGN_CLASS(NumValidatorBase)
154template <
class B,
typename T>
155class NumValidator :
public B
158 typedef B BaseValidator;
161 typedef typename BaseValidator::LongestValueType LongestValueType;
168 wxCOMPILE_TIME_ASSERT
170 sizeof(
ValueType) <=
sizeof(LongestValueType),
178 BaseValidator::m_minSet = (
min != std::numeric_limits<T>::lowest());
184 BaseValidator::m_maxSet = (max != std::numeric_limits<T>::max());
193 bool TransferToWindow()
override
197 wxTextEntry *
const control = BaseValidator::GetTextEntry();
201 control->ChangeValue(NormalizeValue(*m_value));
207 bool TransferFromWindow()
override
211 wxTextEntry *
const control = BaseValidator::GetTextEntry();
216 if ( !this->m_validatorWindow->IsEnabled() )
219 const wxString s(control->GetValue());
220 LongestValueType value;
221 if ( s.empty() && BaseValidator::HasFlag(NumValidatorStyle::ZERO_AS_BLANK) )
223 else if ( !BaseValidator::FromString(s, &value) )
226 if ( !this->IsInRange(value) )
229 *m_value =
static_cast<ValueType>(value);
237 : BaseValidator(
style),
244 wxString NormalizeString(
const wxString& s)
const override
246 LongestValueType value;
247 return BaseValidator::FromString(s, &value) ? NormalizeValue(value)
255 wxString NormalizeValue(LongestValueType value)
const
258 if ( value != 0 || !BaseValidator::HasFlag(NumValidatorStyle::ZERO_AS_BLANK) )
267 DECLARE_NO_ASSIGN_CLASS(NumValidator)
280class AUDACITY_DLL_API IntegerValidatorBase
281 :
public NumValidatorBase
288 typedef wxLongLong_t LongestValueType;
290 typedef long LongestValueType;
293 IntegerValidatorBase(NumValidatorStyle
style)
294 : NumValidatorBase(
style)
296 wxASSERT_MSG( !(
style & NumValidatorStyle::NO_TRAILING_ZEROES),
297 wxT(
"This style doesn't make sense for integers.") );
298 wxASSERT_MSG( !(
style & NumValidatorStyle::ONE_TRAILING_ZERO),
299 wxT(
"This style doesn't make sense for integers.") );
300 wxASSERT_MSG( !(
style & NumValidatorStyle::TWO_TRAILING_ZEROES),
301 wxT(
"This style doesn't make sense for integers.") );
302 wxASSERT_MSG( !(
style & NumValidatorStyle::THREE_TRAILING_ZEROES),
303 wxT(
"This style doesn't make sense for integers.") );
306 IntegerValidatorBase(
const IntegerValidatorBase& other)
307 : NumValidatorBase(other)
314 wxString
ToString(LongestValueType value)
const;
315 static bool FromString(
const wxString& s, LongestValueType *value);
317 void DoSetMin(LongestValueType
min) { m_min =
min; }
318 void DoSetMax(LongestValueType max) { m_max = max; }
320 bool IsInRange(LongestValueType value)
const
322 return m_min <= value && value <= m_max;
326 bool IsCharOk(
const wxString& val,
int pos, wxChar ch)
const override;
331 LongestValueType m_min, m_max;
333 DECLARE_NO_ASSIGN_CLASS(IntegerValidatorBase)
340class IntegerValidator final
341 :
public Private::NumValidator<IntegerValidatorBase, T>
347 Private::NumValidator<IntegerValidatorBase, T> Base;
355 NumValidatorStyle
style = NumValidatorStyle::DEFAULT,
357 ValueType max = std::numeric_limits<ValueType>::max())
360 this->SetRange(
min, max);
364 wxObject *Clone()
const override {
return safenew IntegerValidator(*
this); }
367 DECLARE_NO_ASSIGN_CLASS(IntegerValidator)
373inline IntegerValidator<T>
374MakeIntegerValidator(T *value, NumValidatorStyle
style = NumValidatorStyle::DEFAULT)
376 return IntegerValidator<T>(value,
style);
385class AUDACITY_DLL_API FloatingPointValidatorBase
386 :
public NumValidatorBase
392 void SetPrecision(
unsigned precision) { m_precision = precision; }
398 typedef double LongestValueType;
400 FloatingPointValidatorBase(NumValidatorStyle
style)
401 : NumValidatorBase(
style)
405 FloatingPointValidatorBase(
const FloatingPointValidatorBase& other)
406 : NumValidatorBase(other)
408 m_precision = other.m_precision;
415 wxString
ToString(LongestValueType value)
const;
416 static bool FromString(
const wxString& s, LongestValueType *value);
418 void DoSetMin(LongestValueType
min) { m_min =
min; }
419 void DoSetMax(LongestValueType max) { m_max = max; }
421 bool IsInRange(LongestValueType value)
const
423 return m_min <= value && value <= m_max;
427 bool IsCharOk(
const wxString& val,
int pos, wxChar ch)
const override;
431 bool ValidatePrecision(
const wxString& s)
const;
435 unsigned m_precision;
438 LongestValueType m_min, m_max;
440 DECLARE_NO_ASSIGN_CLASS(FloatingPointValidatorBase)
446class FloatingPointValidator final
447 :
public Private::NumValidator<FloatingPointValidatorBase, T>
451 typedef Private::NumValidator<FloatingPointValidatorBase, T> Base;
454 FloatingPointValidator(
ValueType *value = NULL,
455 NumValidatorStyle
style = NumValidatorStyle::DEFAULT)
460 this->SetPrecision(std::numeric_limits<ValueType>::digits10);
464 FloatingPointValidator(
int precision,
466 NumValidatorStyle
style = NumValidatorStyle::DEFAULT,
467 ValueType min = std::numeric_limits<ValueType>::lowest(),
468 ValueType max = std::numeric_limits<ValueType>::max())
471 this->SetRange(
min, max );
473 this->SetPrecision(precision);
477 wxObject *Clone()
const override
479 return safenew FloatingPointValidator(*
this);
488 this->DoSetMin( std::numeric_limits<ValueType>::lowest());
489 this->DoSetMax( std::numeric_limits<ValueType>::max());
499inline FloatingPointValidator<T>
500MakeFloatingPointValidator(T *value, NumValidatorStyle
style = NumValidatorStyle::DEFAULT)
502 return FloatingPointValidator<T>(value,
style);
506inline FloatingPointValidator<T>
507MakeFloatingPointValidator(
int precision, T *value, NumValidatorStyle
style = NumValidatorStyle::DEFAULT)
509 return FloatingPointValidator<T>(precision, value,
style);
514AUDACITY_DLL_API
double RoundValue(
int precision,
double value);
UndoPush operator&(UndoPush a, UndoPush b)
UndoPush operator|(UndoPush a, UndoPush b)
Holds a msgid for the translation catalog; may also bind format arguments.
auto ToString(const std::optional< TimeSignature > &ts)