Audacity 3.2.0
NumericTextCtrl.h
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 NumericTextCtrl.h
6
7 Dominic Mazzoni
8
9 See NumericTextCtrl.cpp for documentation on how to use the
10 format string to specify how a NumericTextCtrl's fields are
11 laid out.
12
13**********************************************************************/
14
15#ifndef __AUDACITY_TIME_TEXT_CTRL__
16#define __AUDACITY_TIME_TEXT_CTRL__
17
18
19
20#include "MemoryX.h"
21#include "ComponentInterface.h"
23#include <vector>
24#include <wx/setup.h> // for wxUSE_* macros
25#include <wx/defs.h>
26#include <wx/control.h> // to inherit
27
28#include "Internat.h"
29
30// One event type for each type of control. Event is raised when a control
31// changes its format. Owners of controls of the same type can listen and
32// update their formats to agree.
33DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_TIMETEXTCTRL_UPDATED, -1);
34DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_FREQUENCYTEXTCTRL_UPDATED, -1);
35DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_BANDWIDTHTEXTCTRL_UPDATED,
36 -1);
37
42
43class NumericField;
44
45class DigitInfo;
46
47class AUDACITY_DLL_API NumericConverter /* not final */
48{
49public:
50
51 enum Type {
53 ATIME, // for Audio time control.
56 };
57
60 // How to name the fraction of the unit; not necessary for time formats
61 // or when the format string has no decimal point
63
65 const TranslatableString &format = {},
66 const TranslatableString &fraction = {})
67 : formatStr{ format }, fraction{ fraction }
68 {}
69
70 friend bool operator == ( const FormatStrings &x, const FormatStrings &y )
71 { return x.formatStr == y.formatStr && x.fraction == y.fraction; }
72 friend bool operator != ( const FormatStrings &x, const FormatStrings &y )
73 { return !(x == y); }
74 };
75
76 static NumericFormatSymbol DefaultSelectionFormat();
77 static NumericFormatSymbol TimeAndSampleFormat();
78 static NumericFormatSymbol SecondsFormat();
79 static NumericFormatSymbol HoursMinsSecondsFormat();
80 static NumericFormatSymbol HundredthsFormat();
81 static NumericFormatSymbol HertzFormat();
82
83 static NumericFormatSymbol LookupFormat( Type type, const wxString& id);
84
85 NumericConverter(Type type,
86 const NumericFormatSymbol & formatName = {},
87 double value = 0.0f,
88 double sampleRate = 1.0f /* to prevent div by 0 */);
90
91 virtual ~NumericConverter();
92
93 // ValueToControls() formats a raw value (either provided as
94 // argument, or mValue, depending on the version of the function
95 // called). The result is stored to mValueString.
96 virtual void ValueToControls();
97 virtual void ValueToControls(double rawValue, bool nearest = true);
98
99 // Converts the stored formatted string (mValueString) back to a
100 // raw value (mValue).
101 virtual void ControlsToValue();
102
103private:
104 void ParseFormatString(const TranslatableString & untranslatedFormat);
105
106public:
107 void PrintDebugInfo();
108
109 // returns true iff the format name really changed:
110 bool SetFormatName(const NumericFormatSymbol & formatName);
111
112 // returns true iff the format string really changed:
113 bool SetFormatString(const FormatStrings & formatString);
114
115 void SetSampleRate(double sampleRate);
116 void SetValue(double newValue);
117 void SetMinValue(double minValue);
118 void ResetMinValue();
119 void SetMaxValue(double maxValue);
120 void ResetMaxValue();
121
122 double GetValue();
123
124 wxString GetString();
125
126 int GetFormatIndex();
127
128 int GetNumBuiltins();
129 NumericFormatSymbol GetBuiltinName(const int index);
130 FormatStrings GetBuiltinFormat(const int index);
131 FormatStrings GetBuiltinFormat(const NumericFormatSymbol & name);
132
133 // Adjust the value by the number "steps" in the active format.
134 // Increment if "dir" is 1, decrement if "dir" is -1.
135 void Adjust(int steps, int dir);
136
137 void Increment();
138 void Decrement();
139
140protected:
142
143 double mValue;
144
145 double mMinValue;
146 double mMaxValue;
148
150
151 std::vector<NumericField> mFields;
152 wxString mPrefix;
154 wxString mValueMask;
155 // Formatted mValue, by ValueToControls().
156 wxString mValueString;
157
161
163 std::vector<DigitInfo> mDigits;
164
166 const size_t mNBuiltins;
168};
169
170class AUDACITY_DLL_API NumericTextCtrl final
171 : public wxControl, public NumericConverter
172{
173 friend class NumericTextCtrlAx;
174
175 public:
176 DECLARE_DYNAMIC_CLASS(NumericTextCtrl)
177
178 struct Options {
179 bool autoPos { true };
180 bool readOnly { false };
181 bool menuEnabled { true };
182 bool hasInvalidValue { false };
183 double invalidValue { -1.0 };
185 bool hasValue { false };
186 double value{ -1.0 };
187
189
190 Options &AutoPos (bool enable) { autoPos = enable; return *this; }
191 Options &ReadOnly (bool enable) { readOnly = enable; return *this; }
192 Options &MenuEnabled (bool enable) { menuEnabled = enable; return *this; }
193 Options &InvalidValue (bool has, double v = -1.0)
194 { hasInvalidValue = has, invalidValue = v; return *this; }
195 // use a custom format not in the tables:
197 { format = f; return *this; }
198 Options &Value (bool has, double v)
199 { hasValue = has, value = v; return *this; }
200 };
201
202 NumericTextCtrl(wxWindow *parent, wxWindowID winid,
204 const NumericFormatSymbol &formatName = {},
205 double value = 0.0,
206 double sampleRate = 44100,
207 const Options &options = {},
208 const wxPoint &pos = wxDefaultPosition,
209 const wxSize &size = wxDefaultSize);
210
211 virtual ~NumericTextCtrl();
212
213 // Hide the inherited function that takes wxString
214 void SetName( const TranslatableString &name );
215
216 wxSize ComputeSizing(bool update = true, wxCoord digitW = 0, wxCoord digitH = 0);
217 bool Layout() override;
218 void Fit() override;
219
220 void SetSampleRate(double sampleRate);
221 void SetValue(double newValue);
222
223 // returns true iff the format string really changed:
224 bool SetFormatString(const FormatStrings & formatString);
225
226 // returns true iff the format name really changed:
227 bool SetFormatName(const NumericFormatSymbol & formatName);
228
229 void SetFieldFocus(int /* digit */);
230
231 wxSize GetDimensions() { return wxSize(mWidth + mButtonWidth, mHeight); }
232 wxSize GetDigitSize() { return wxSize(mDigitBoxW, mDigitBoxH); }
233 void SetDigitSize(int width, int height);
234 void SetReadOnly(bool readOnly = true);
235 void EnableMenu(bool enable = true);
236
237 // The text control permits typing DELETE to make the value invalid only if this
238 // function has previously been called.
239 // Maybe you want something other than the default of -1 to indicate the invalid value
240 // this control returns to the program, so you can specify.
241 void SetInvalidValue(double invalidValue);
242
243 int GetFocusedField() { return mLastField; }
244 int GetFocusedDigit() { return mFocusedDigit; }
245
246private:
247
248 void OnCaptureKey(wxCommandEvent &event);
249 void OnKeyDown(wxKeyEvent &event);
250 void OnKeyUp(wxKeyEvent &event);
251 void OnMouse(wxMouseEvent &event);
252 void OnErase(wxEraseEvent &event);
253 void OnPaint(wxPaintEvent &event);
254 void OnFocus(wxFocusEvent &event);
255 void OnContext(wxContextMenuEvent &event);
256
257 // Formats mValue into mValueString, using the method of the base class.
258 // Triggers a refresh of the wx window only when the value actually
259 // changed since last time a refresh was triggered.
260 void ValueToControls() override;
261 void ControlsToValue() override;
262
263 // If autoPos was enabled, focus the first non-zero digit
264 void UpdateAutoFocus();
265
266 void Updated(bool keyup = false);
267
268private:
269
272
273 std::unique_ptr<wxBitmap> mBackgroundBitmap;
274
275 std::unique_ptr<wxFont> mDigitFont, mLabelFont;
287
289
290 // If true, the focus will be set to the first non-zero digit
292
293 // Keeps track of extra fractional scrollwheel steps
295
297
299
300 DECLARE_EVENT_TABLE()
301};
302
303#endif // __AUDACITY_TIME_TEXT_CTRL__
const TranslatableString name
Definition: Distortion.cpp:82
int format
Definition: ExportPCM.cpp:56
DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_TIMETEXTCTRL_UPDATED, -1)
bool operator==(const Tags &lhs, const Tags &rhs)
Definition: Tags.cpp:332
bool operator!=(const Tags &lhs, const Tags &rhs)
Definition: Tags.h:133
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
DigitInfo is a class used in NumericTextCtrl.
NumericConverter provides the advanced formatting control used in the selection bar of Audacity.
FormatStrings mFormatString
const BuiltinFormatString * mBuiltinFormatStrings
std::vector< DigitInfo > mDigits
const size_t mNBuiltins
std::vector< NumericField > mFields
NumericConverter(const NumericConverter &)
NumericField is a class used in NumericTextCtrl.
NumericTextCtrlAx gives the NumericTextCtrl Accessibility.
wxSize GetDimensions()
std::unique_ptr< wxFont > mDigitFont
std::unique_ptr< wxBitmap > mBackgroundBitmap
NumericConverter::Type mType
Holds a msgid for the translation catalog; may also bind format arguments.
void OnFocus(wxWindow &window, wxFocusEvent &event)
a function useful to implement a focus event handler The window releases the keyboard if the event is...
std::vector< CommandFlagOptions > & Options()
Definition: Menus.cpp:535
struct to hold a formatting control string and its user facing name Used in an array to hold the buil...
FormatStrings(const TranslatableString &format={}, const TranslatableString &fraction={})
Options & Format(const FormatStrings &f)
Options & MenuEnabled(bool enable)
Options & Value(bool has, double v)
Options & AutoPos(bool enable)
Options & InvalidValue(bool has, double v=-1.0)
Options & ReadOnly(bool enable)