Audacity  2.2.2
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 #include "../MemoryX.h"
19 #include "../../include/audacity/IdentInterface.h"
20 #include <vector>
21 #include <wx/defs.h>
22 #include <wx/event.h>
23 #include <wx/panel.h>
24 #include <wx/stattext.h>
25 #include <wx/string.h>
26 #include <wx/textctrl.h>
27 
28 #include "../Audacity.h"
29 #include "../Internat.h"
30 
31 #if wxUSE_ACCESSIBILITY
32 #include <wx/access.h>
33 #include "WindowAccessible.h"
34 #endif
35 
36 // One event type for each type of control. Event is raised when a control
37 // changes its format. Owners of controls of the same type can listen and
38 // update their formats to agree.
39 DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_TIMETEXTCTRL_UPDATED, -1);
40 DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_FREQUENCYTEXTCTRL_UPDATED, -1);
41 DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_BANDWIDTHTEXTCTRL_UPDATED,
42  -1);
43 
47 struct BuiltinFormatString;
48 
49 class NumericField;
50 
51 class DigitInfo;
52 
54 
55 class NumericConverter /* not final */
56 {
57 public:
58 
59  enum Type {
63  };
64 
70 
71  static NumericFormatId LookupFormat( Type type, const wxString& id);
72 
74  const NumericFormatId & formatName = {},
75  double value = 0.0f,
76  double sampleRate = 1.0f /* to prevent div by 0 */);
77 
78  virtual ~NumericConverter();
79 
80  // ValueToControls() formats a raw value (either provided as
81  // argument, or mValue, depending on the version of the function
82  // called). The result is stored to mValueString.
83  virtual void ValueToControls();
84  virtual void ValueToControls(double rawValue, bool nearest = true);
85 
86  // Converts the stored formatted string (mValueString) back to a
87  // raw value (mValue).
88  virtual void ControlsToValue();
89 
90 private:
91  void ParseFormatString(const wxString & format);
92 
93 public:
94  void PrintDebugInfo();
95  void SetFormatName(const NumericFormatId & formatName);
96  void SetFormatString(const wxString & formatString);
97  void SetSampleRate(double sampleRate);
98  void SetValue(double newValue);
99  void SetMinValue(double minValue);
100  void ResetMinValue();
101  void SetMaxValue(double maxValue);
102  void ResetMaxValue();
103 
104  double GetValue();
105 
106  wxString GetString();
107 
108  int GetFormatIndex();
109 
110  int GetNumBuiltins();
111  NumericFormatId GetBuiltinName(const int index);
112  wxString GetBuiltinFormat(const int index);
113  wxString GetBuiltinFormat(const NumericFormatId & name);
114 
115  // Adjust the value by the number "steps" in the active format.
116  // Increment if "dir" is 1, decrement if "dir" is -1.
117  void Adjust(int steps, int dir);
118 
119  void Increment();
120  void Decrement();
121 
122 protected:
124 
125  double mValue;
126 
127  double mMinValue;
128  double mMaxValue;
130 
131  wxString mFormatString;
132 
133  std::vector<NumericField> mFields;
134  wxString mPrefix;
135  wxString mValueTemplate;
136  wxString mValueMask;
137  // Formatted mValue, by ValueToControls().
138  wxString mValueString;
139 
141  double mSampleRate;
142  bool mNtscDrop;
143 
145  std::vector<DigitInfo> mDigits;
146 
148  const size_t mNBuiltins;
150 };
151 
152 class NumericTextCtrl final : public wxControl, public NumericConverter
153 {
154  friend class NumericTextCtrlAx;
155 
156  public:
157  DECLARE_DYNAMIC_CLASS(NumericTextCtrl)
158 
159  struct Options {
160  bool autoPos { true };
161  bool readOnly { false };
162  bool menuEnabled { true };
163  bool hasInvalidValue { false };
164  double invalidValue { -1.0 };
165  wxString format {};
166  bool hasValue { false };
167  double value{ -1.0 };
168 
169  Options() {}
170 
171  Options &AutoPos (bool value) { autoPos = value; return *this; }
172  Options &ReadOnly (bool value) { readOnly = value; return *this; }
173  Options &MenuEnabled (bool value) { menuEnabled = value; return *this; }
174  Options &InvalidValue (bool has, double value = -1.0)
175  { hasInvalidValue = has, invalidValue = value; return *this; }
176  // use a custom format not in the tables:
177  Options &Format (const wxString &value)
178  { format = value; return *this; }
179  Options &Value (bool has, double v)
180  { hasValue = has, value = v; return *this; }
181  };
182 
183  NumericTextCtrl(wxWindow *parent, wxWindowID winid,
185  const NumericFormatId &formatName = {},
186  double value = 0.0,
187  double sampleRate = 44100,
188  const Options &options = {},
189  const wxPoint &pos = wxDefaultPosition,
190  const wxSize &size = wxDefaultSize);
191 
192  virtual ~NumericTextCtrl();
193 
194  bool Layout() override;
195  void Fit() override;
196 
197  void SetSampleRate(double sampleRate);
198  void SetValue(double newValue);
199  void SetFormatString(const wxString & formatString);
200  void SetFormatName(const NumericFormatId & formatName);
201 
202  void SetFieldFocus(int /* digit */);
203 
204  void SetReadOnly(bool readOnly = true);
205  void EnableMenu(bool enable = true);
206 
207  // The text control permits typing DELETE to make the value invalid only if this
208  // function has previously been called.
209  // Maybe you want something other than the default of -1 to indicate the invalid value
210  // this control returns to the program, so you can specify.
211  void SetInvalidValue(double invalidValue);
212 
213  int GetFocusedField() { return mLastField; }
214  int GetFocusedDigit() { return mFocusedDigit; }
215 
216 private:
217 
218  void OnCaptureKey(wxCommandEvent &event);
219  void OnKeyDown(wxKeyEvent &event);
220  void OnKeyUp(wxKeyEvent &event);
221  void OnMouse(wxMouseEvent &event);
222  void OnErase(wxEraseEvent &event);
223  void OnPaint(wxPaintEvent &event);
224  void OnFocus(wxFocusEvent &event);
225  void OnContext(wxContextMenuEvent &event);
226 
227  // Formats mValue into mValueString, using the method of the base class.
228  // Triggers a refresh of the wx window only when the value actually
229  // changed since last time a refresh was triggered.
230  void ValueToControls() override;
231  void ControlsToValue() override;
232 
233  // If autoPos was enabled, focus the first non-zero digit
234  void UpdateAutoFocus();
235 
236  void Updated(bool keyup = false);
237 
238 private:
239 
241  bool mReadOnly;
242 
243  std::unique_ptr<wxBitmap> mBackgroundBitmap;
244 
245  std::unique_ptr<wxFont> mDigitFont, mLabelFont;
248  int mDigitW;
249  int mDigitH;
254  int mWidth;
255  int mHeight;
257 
259 
260  // If true, the focus will be set to the first non-zero digit
261  bool mAutoPos;
262 
263  // Keeps track of extra fractional scrollwheel steps
265 
267 
269 
270  DECLARE_EVENT_TABLE()
271 };
272 
273 #if wxUSE_ACCESSIBILITY
274 
275 class NumericTextCtrlAx final : public WindowAccessible
276 {
277 public:
279 
280  virtual ~ NumericTextCtrlAx();
281 
282  // Performs the default action. childId is 0 (the action for this object)
283  // or > 0 (the action for a child).
284  // Return wxACC_NOT_SUPPORTED if there is no default action for this
285  // window (e.g. an edit control).
286  wxAccStatus DoDefaultAction(int childId) override;
287 
288  // Retrieves the address of an IDispatch interface for the specified child.
289  // All objects must support this property.
290  wxAccStatus GetChild(int childId, wxAccessible **child) override;
291 
292  // Gets the number of children.
293  wxAccStatus GetChildCount(int *childCount) override;
294 
295  // Gets the default action for this object (0) or > 0 (the action for a child).
296  // Return wxACC_OK even if there is no action. actionName is the action, or the empty
297  // string if there is no action.
298  // The retrieved string describes the action that is performed on an object,
299  // not what the object does as a result. For example, a toolbar button that prints
300  // a document has a default action of "Press" rather than "Prints the current document."
301  wxAccStatus GetDefaultAction(int childId, wxString *actionName) override;
302 
303  // Returns the description for this object or a child.
304  wxAccStatus GetDescription(int childId, wxString *description) override;
305 
306  // Gets the window with the keyboard focus.
307  // If childId is 0 and child is NULL, no object in
308  // this subhierarchy has the focus.
309  // If this object has the focus, child should be 'this'.
310  wxAccStatus GetFocus(int *childId, wxAccessible **child) override;
311 
312  // Returns help text for this object or a child, similar to tooltip text.
313  wxAccStatus GetHelpText(int childId, wxString *helpText) override;
314 
315  // Returns the keyboard shortcut for this object or child.
316  // Return e.g. ALT+K
317  wxAccStatus GetKeyboardShortcut(int childId, wxString *shortcut) override;
318 
319  // Returns the rectangle for this object (id = 0) or a child element (id > 0).
320  // rect is in screen coordinates.
321  wxAccStatus GetLocation(wxRect & rect, int elementId) override;
322 
323  // Gets the name of the specified object.
324  wxAccStatus GetName(int childId, wxString *name) override;
325 
326  // Returns a role constant.
327  wxAccStatus GetRole(int childId, wxAccRole *role) override;
328 
329  // Gets a variant representing the selected children
330  // of this object.
331  // Acceptable values:
332  // - a null variant (IsNull() returns TRUE)
333  // - a list variant (GetType() == wxT("list"))
334  // - an integer representing the selected child element,
335  // or 0 if this object is selected (GetType() == wxT("long"))
336  // - a "void*" pointer to a wxAccessible child object
337  wxAccStatus GetSelections(wxVariant *selections) override;
338 
339  // Returns a state constant.
340  wxAccStatus GetState(int childId, long *state) override;
341 
342  // Returns a localized string representing the value for the object
343  // or child.
344  wxAccStatus GetValue(int childId, wxString *strValue) override;
345 
346 private:
347  NumericTextCtrl *mCtrl;
348  int mLastField;
349  int mLastDigit;
350 };
351 
352 #endif // wxUSE_ACCESSIBILITY
353 
354 #endif // __AUDACITY_TIME_TEXT_CTRL__
void SetFormatString(const wxString &formatString)
const BuiltinFormatString * mBuiltinFormatStrings
Options & InvalidValue(bool has, double value=-1.0)
void Adjust(int steps, int dir)
std::vector< NumericField > mFields
std::unique_ptr< wxFont > mDigitFont
Options & Value(bool has, double v)
std::unique_ptr< wxBitmap > mBackgroundBitmap
void OnContext(wxContextMenuEvent &event)
NumericTextCtrlAx gives the NumericTextCtrl Accessibility.
void SetReadOnly(bool readOnly=true)
void SetSampleRate(double sampleRate)
void OnKeyDown(wxKeyEvent &event)
std::unique_ptr< wxFont > mLabelFont
NumericConverter(Type type, const NumericFormatId &formatName={}, double value=0.0f, double sampleRate=1.0f)
void EnableMenu(bool enable=true)
void SetFormatString(const wxString &formatString)
std::vector< DigitInfo > mDigits
virtual ~NumericConverter()
static NumericFormatId TimeAndSampleFormat()
void SetFormatName(const NumericFormatId &formatName)
NumericField is a class used in NumericTextCtrl.
virtual void ControlsToValue()
void SetMaxValue(double maxValue)
An alternative to using wxWindowAccessible, which in wxWidgets 3.1.1 contained GetParent() which was ...
void ValueToControls() override
DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_TIMETEXTCTRL_UPDATED,-1)
void OnMouse(wxMouseEvent &event)
int format
Definition: ExportPCM.cpp:56
static NumericFormatId SecondsFormat()
NumericConverter provides the advanced formatting control used in the selection bar of Audacity...
static NumericFormatId LookupFormat(Type type, const wxString &id)
Options & MenuEnabled(bool value)
DigitInfo is a class used in NumericTextCtrl.
void OnErase(wxEraseEvent &event)
void Updated(bool keyup=false)
void ControlsToValue() override
IdentInterfaceSymbol pairs a persistent string identifier used internally with an optional...
const size_t mNBuiltins
void SetValue(double newValue)
wxString GetBuiltinFormat(const int index)
void SetMinValue(double minValue)
void SetFormatName(const NumericFormatId &formatName)
void OnCaptureKey(wxCommandEvent &event)
NumericFormatId GetBuiltinName(const int index)
Options & ReadOnly(bool value)
void SetInvalidValue(double invalidValue)
NumericTextCtrl(wxWindow *parent, wxWindowID winid, NumericConverter::Type type, const NumericFormatId &formatName={}, double value=0.0, double sampleRate=44100, const Options &options={}, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize)
const wxChar * name
Definition: Distortion.cpp:94
void Fit() override
bool Layout() override
static NumericFormatId HundredthsFormat()
Options & Format(const wxString &value)
Options & AutoPos(bool value)
static NumericFormatId DefaultSelectionFormat()
void SetValue(double newValue)
NumericConverter::Type mType
void OnKeyUp(wxKeyEvent &event)
virtual void ValueToControls()
static NumericFormatId HertzFormat()
void ParseFormatString(const wxString &format)
struct to hold a formatting control string and its user facing name Used in an array to hold the buil...
virtual ~NumericTextCtrl()
void SetSampleRate(double sampleRate)
void OnPaint(wxPaintEvent &event)
void OnFocus(wxFocusEvent &event)