Audacity 3.2.0
TimeToolBar.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 TimeToolBar.cpp
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 *//*******************************************************************/
13
14
15
16// For compilers that support precompilation, includes "wx/wx.h".
17#include <wx/wxprec.h>
18
19#include <wx/setup.h> // for wxUSE_* macros
20
21#ifndef WX_PRECOMP
22#include <wx/sizer.h>
23#endif
24
25#include "TimeToolBar.h"
27#include "ToolManager.h"
28
29#include "AudioIO.h"
30#include "Project.h"
31#include "ProjectAudioIO.h"
33#include "ProjectRate.h"
34#include "ViewInfo.h"
35
37
38// Having a fixed ID for the Audio Position is helpful for
39// the Jaws screen reader script for Audacity.
40enum {
43};
44
45BEGIN_EVENT_TABLE(TimeToolBar, ToolBar)
46 EVT_COMMAND(AudioPositionID, EVT_TIMETEXTCTRL_UPDATED, TimeToolBar::OnUpdate)
47 EVT_SIZE(TimeToolBar::OnSize)
48 EVT_IDLE(TimeToolBar::OnIdle)
50
52{
53 return wxT("Time");
54}
55
57: ToolBar(project, XO("Time"), ID(), true),
58 mListener(NULL),
59 mAudioTime(NULL)
60{
63}
64
66{
67}
68
70{
71 return BotDockID;
72}
73
75{
76 auto &toolManager = ToolManager::Get(project);
77 return *static_cast<TimeToolBar*>(toolManager.GetToolBar(ID()));
78}
79
81{
82 return Get(const_cast<AudacityProject&>(project)) ;
83}
84
86{
87 const auto &formats = ProjectNumericFormats::Get(mProject);
88
89 // Get the default sample rate
90 auto rate = ProjectRate::Get(mProject).GetRate();
91
92 // Get the default time format
93 auto format = formats.GetAudioTimeFormat();
94
95 // Create the read-only time control
97 mAudioTime->SetName(XO("Audio Position"));
99
100 // Add it to the toolbar
101 Add(mAudioTime, 0, wxALIGN_CENTER, 0);
102
103 // Calculate the width to height ratio
104 wxSize digitSize = mAudioTime->GetDigitSize();
105 mDigitRatio = (float)digitSize.x / digitSize.y;
106
107 // During initialization, we need to bypass some resizing to prevent the "best size"
108 // from being used as we want to ensure the saved size is used instead. See SetDocked()
109 // and OnUpdate() for more info.
110 mSettingInitialSize = true;
111
112 // Establish initial resizing limits
113// SetResizingLimits();
114}
115
117{
118 // Since the language may have changed, we need to force an update to accommodate
119 // different length text
120 wxCommandEvent e;
121 e.SetInt(mAudioTime->GetFormatIndex());
122 OnUpdate(e);
123
124 // Language may have changed so reset label
125 SetLabel(XO("Time"));
126
127 // Give the toolbar a chance
129}
130
132{
133 // Reset
134 SetMaxSize(wxDefaultSize);
135 SetMinSize(wxDefaultSize);
136
137 // Set the default time format
139
140 // Set the default size
141 SetSize(GetInitialWidth(), 48);
142
143 // Inform others the toobar has changed
144 Updated();
145}
146
148{
149 wxSize sz = GetSize();
150
151 // Anything less than a single height bar becomes single height
152 if (sz.y <= toolbarSingle) {
153 sz.y = toolbarSingle;
154 }
155 // Otherwise it will be a double height bar
156 else {
157 sz.y = 2 * toolbarSingle + toolbarGap;
158 }
159
160 return sz;
161}
162
163void TimeToolBar::SetDocked(ToolDock *dock, bool pushed)
164{
165 // It's important to call this FIRST since it unhides the resizer control.
166 // Not doing so causes the calculated best size to be off by the width
167 // of the resizer.
168 ToolBar::SetDocked(dock, pushed);
169
170 // Recalculate the min and max limits
172
173 // When moving from floater to dock, fit to toolbar since the resizer will
174 // be mispositioned
175 if (dock) {
176 // During initialization, the desired size is already set, so do not
177 // override it with the "best size". See OnUpdate for further info.
178 if (!mSettingInitialSize) {
179 // Fit() while retaining height
180 SetSize(GetBestSize().x, GetSize().y);
181
182 // Inform others the toolbar has changed
183 Updated();
184 }
185 }
186}
187
189{
190 // Remember the listener
191 mListener = l;
192
193 // Get (and set) the saved time format
195
196 // During initialization, if the saved format is the same as the default,
197 // OnUpdate() will not be called and need it to set the initial size.
199 wxCommandEvent e;
200 e.SetInt(mAudioTime->GetFormatIndex());
201 OnUpdate(e);
202 }
203}
204
206{
207 // Set the format if it's different from previous
209 // Simulate an update since the format has changed.
210 wxCommandEvent e;
211 e.SetInt(mAudioTime->GetFormatIndex());
212 OnUpdate(e);
213 }
214}
215
216// The intention of this is to get the resize handle in the
217// correct position, after we've let go in dragging.
219{
220 // Fit() while retaining height
221 SetSize(GetBestSize().x, GetSize().y);
222
223 // Inform others the toobar has changed
224 Updated();
225}
226
228{
229 // Reset limits
230 SetMinSize(wxDefaultSize);
231 SetMaxSize(wxDefaultSize);
232
233 // If docked we use the current bar height since it's always a single or double height
234 // toolbar. For floaters, single height toolbar is the minimum height.
235 int minH = IsDocked() ? GetSize().y : toolbarSingle;
236
237 // Get the content size given the smallest digit height we allow
238 wxSize minSize = ComputeSizing(minDigitH);
239
240 // Account for any borders added by the window manager
241 minSize.x += (mAudioTime->GetSize().x - mAudioTime->GetClientSize().x);
242
243 // Calculate the space used by other controls and sizer borders with this toolbar
244 wxSize outer = (GetSize() - GetSizer()->GetSize());
245
246 // And account for them in the width
247 minSize.x += outer.x;
248
249 // Override the height
250 minSize.y = minH;
251
252 // Get the maximum digit height we can use. This is restricted to the toolbar's
253 // current height minus any control borders
254 int digH = minH - (mAudioTime->GetSize().y - mAudioTime->GetClientSize().y);
255
256 // Get the content size using the digit height, if docked. Otherwise use the
257 // maximum digit height we allow.
258 wxSize maxSize = ComputeSizing(IsDocked() ? digH : maxDigitH);
259
260 // Account for the other controls and sizer borders within this toolbar
261 maxSize.x += outer.x;
262
263 // Account for any borders added by the window manager and +1 to keep toolbar
264 // from dropping to next smaller size when grabbing the resizer.
265 maxSize.x += (mAudioTime->GetSize().x - mAudioTime->GetClientSize().x) + 1;
266
267 // Override the height
268 maxSize.y = IsDocked() ? minH : wxDefaultCoord;
269
270 // And finally set them both
271 SetMinSize(minSize);
272 SetMaxSize(maxSize);
273}
274
275// Called when the project rate changes
277{
278 if (mAudioTime)
280}
281
282// Called when the format drop downs is changed.
283// This causes recreation of the toolbar contents.
284void TimeToolBar::OnUpdate(wxCommandEvent &evt)
285{
286 evt.Skip(false);
287
289
290 // Reset to allow resizing to work
291 SetMinSize(wxDefaultSize);
292 SetMaxSize(wxDefaultSize);
293
294 // Save format name before recreating the controls so they resize properly
295 if (mListener) {
297 }
298
299 // During initialization, the desired size will have already been set at this point
300 // and the "best" size" would override it, so we simply send a size event to force
301 // the content to fit inside the toolbar.
303 mSettingInitialSize = false;
304 SendSizeEvent();
305 }
306 // Otherwise we want the toolbar to resize to fit around the content
307 else {
308 // Fit() while retaining height
309 SetSize(GetBestSize().x, GetSize().y);
310 }
311
312 // Go set the new size limits
314
315 // Inform others the toobar has changed
316 Updated();
317}
318
319void TimeToolBar::OnSize(wxSizeEvent &evt)
320{
321 evt.Skip();
322
323 // Can fire before we're ready
324 if (!mAudioTime) {
325 return;
326 }
327
328 // Make sure everything is where it's supposed to be
329 Layout();
330
331 // Get the sizer's size and remove any borders the time control might have.
332 wxSize sizerBR = GetSizer()->GetSize() - (mAudioTime->GetSize() - mAudioTime->GetClientSize());
333
334 // Get the content size of the time control. This can be different than the
335 // control itself due to borders and sizer enduced changes.
336 wxSize timeBR = mAudioTime->GetDimensions();
337
338 // Get the current digit box height
339 int h = mAudioTime->GetDigitSize().y;
340
341 // Increase current size to find the best fit within the new size
342 if (sizerBR.x >= timeBR.x && sizerBR.y >= timeBR.y) {
343 do {
344 h++;
345 timeBR = ComputeSizing(h);
346 } while (h < maxDigitH && sizerBR.x >= timeBR.x && sizerBR.y >= timeBR.y);
347 h--;
348 }
349 // In all other cases, we need to decrease current size to fit within new size
350 else if (sizerBR.x < timeBR.x || sizerBR.y < timeBR.y) {
351 do {
352 h--;
353 timeBR = ComputeSizing(h);
354 } while (h >= minDigitH && (sizerBR.x < timeBR.x || sizerBR.y < timeBR.y));
355 }
356
357 if (h != mAudioTime->GetDigitSize().y) {
359 }
360
361 // Redraw the display immediately to smooth out resizing
362 Update();
363}
364
365void TimeToolBar::OnIdle(wxIdleEvent &evt)
366{
367 evt.Skip();
368
369 double audioTime;
370
371 auto &projectAudioIO = ProjectAudioIO::Get(mProject);
372 if (projectAudioIO.IsAudioActive()) {
373 auto gAudioIO = AudioIO::Get();
374 audioTime = gAudioIO->GetStreamTime();
375 }
376 else {
377 const auto &playRegion = ViewInfo::Get(mProject).playRegion;
378 audioTime = playRegion.GetStart();
379 }
380
381 mAudioTime->SetValue(wxMax(0.0, audioTime));
382}
383
385 []( AudacityProject &project )
386 {
387 return ToolBar::Holder{ safenew TimeToolBar{ project } };
388 }
389};
390
391namespace {
393{
395 wxT("ShowTimeTB"),
396 /* i18n-hint: Clicking this menu item shows the toolbar
397 for viewing actual time of the cursor */
398 XXO("&Time Toolbar"),
399 {
401 "ShowSelectionTB"
402 }
403};
404}
405
static const wxPoint2DDouble outer[]
Definition: ASlider.cpp:397
wxT("CloseDown"))
END_EVENT_TABLE()
int format
Definition: ExportPCM.cpp:53
XO("Cut/Copy/Paste")
XXO("&Cut/Copy/Paste Toolbar")
EVT_COMMAND(wxID_ANY, EVT_FREQUENCYTEXTCTRL_UPDATED, LabelDialog::OnFreqUpdate) LabelDialog
Definition: LabelDialog.cpp:88
#define safenew
Definition: MemoryX.h:10
an object holding per-project preferred sample rate
@ AudioPositionID
Definition: TimeToolBar.cpp:42
@ TimeBarFirstID
Definition: TimeToolBar.cpp:41
static RegisteredToolbarFactory factory
IMPLEMENT_CLASS(TimeToolBar, ToolBar)
#define toolbarSingle
Definition: ToolBar.h:59
#define toolbarGap
Definition: ToolBar.h:64
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
static AudioIO * Get()
Definition: AudioIO.cpp:147
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
An explicitly nonlocalized string, not meant for the user to see.
Definition: Identifier.h:22
FormatStrings GetBuiltinFormat(const int index)
NumericFormatSymbol GetBuiltinName(const int index)
static NumericFormatSymbol HoursMinsSecondsFormat()
wxSize GetDimensions()
bool SetFormatString(const FormatStrings &formatString)
void SetReadOnly(bool readOnly=true)
void SetSampleRate(double sampleRate)
wxSize GetDigitSize()
void SetDigitSize(int width, int height)
void SetName(const TranslatableString &name)
void SetValue(double newValue)
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
Definition: Observer.h:199
double GetStart() const
Definition: ViewInfo.h:128
static ProjectAudioIO & Get(AudacityProject &project)
static ProjectNumericFormats & Get(AudacityProject &project)
static ProjectRate & Get(AudacityProject &project)
Definition: ProjectRate.cpp:28
double GetRate() const
Definition: ProjectRate.cpp:53
TimeToolBarListener * mListener
Definition: TimeToolBar.h:59
static const int minDigitH
Definition: TimeToolBar.h:64
void SetAudioTimeFormat(const NumericFormatSymbol &format)
void OnRateChanged(double)
void OnIdle(wxIdleEvent &evt)
void OnSize(wxSizeEvent &evt)
static TimeToolBar & Get(AudacityProject &project)
Definition: TimeToolBar.cpp:74
wxSize GetDockedSize() override
DockID DefaultDockID() const override
Which dock the toolbar defaults into. Default implementation chooses the top dock.
Definition: TimeToolBar.cpp:69
static const int maxDigitH
Definition: TimeToolBar.h:65
void SetToDefaultSize() override
void SetListener(TimeToolBarListener *l)
void OnUpdate(wxCommandEvent &evt)
NumericTextCtrl * mAudioTime
Definition: TimeToolBar.h:60
void SetDocked(ToolDock *dock, bool pushed) override
static Identifier ID()
Definition: TimeToolBar.cpp:51
void SetResizingLimits()
virtual ~TimeToolBar()
Definition: TimeToolBar.cpp:65
float mDigitRatio
Definition: TimeToolBar.h:61
void ResizingDone() override
Observer::Subscription mSubscription
Definition: TimeToolBar.h:67
void UpdatePrefs() override
int GetInitialWidth() override
Resizable toolbars should implement these.
Definition: TimeToolBar.h:41
void Populate() override
Definition: TimeToolBar.cpp:85
bool mSettingInitialSize
Definition: TimeToolBar.h:62
wxSize ComputeSizing(int digitH)
Definition: TimeToolBar.h:75
TimeToolBar(AudacityProject &project)
Definition: TimeToolBar.cpp:56
virtual void TT_SetAudioTimeFormat(const NumericFormatSymbol &format)=0
virtual const NumericFormatSymbol & TT_GetAudioTimeFormat()=0
Works with ToolManager and ToolDock to provide a dockable window in which buttons can be placed.
Definition: ToolBar.h:74
AudacityProject & mProject
Definition: ToolBar.h:248
bool IsDocked() const
Definition: ToolBar.cpp:433
DockID
Identifies one of the docking areas for toolbars.
Definition: ToolBar.h:92
@ BotDockID
Definition: ToolBar.h:94
void Add(wxWindow *window, int proportion=0, int flag=wxALIGN_TOP, int border=0, wxObject *userData=NULL)
Definition: ToolBar.cpp:709
virtual void SetDocked(ToolDock *dock, bool pushed)
Definition: ToolBar.cpp:661
virtual void ReCreateButtons()
Definition: ToolBar.cpp:533
void SetLabel(const wxString &label) override
Definition: ToolBar.cpp:408
wxBoxSizer * GetSizer()
Definition: ToolBar.cpp:701
void UpdatePrefs() override
Definition: ToolBar.cpp:622
void Updated()
Definition: ToolBar.cpp:684
wxWindowPtr< ToolBar > Holder
Definition: ToolBar.h:78
A dynamic panel where a ToolBar can be docked.
Definition: ToolDock.h:292
static ToolManager & Get(AudacityProject &project)
PlayRegion playRegion
Definition: ViewInfo.h:220
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:235
AttachedToolBarMenuItem sAttachment