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