Audacity 3.2.0
ViewMenus.cpp
Go to the documentation of this file.
1#include "../CommonCommandFlags.h"
2#include "../Menus.h"
3#include "PlayableTrack.h"
4#include "Prefs.h"
5#include "Project.h"
6#include "ProjectHistory.h"
7#include "../ProjectSettings.h"
8#include "../ProjectWindow.h"
9#include "../TrackInfo.h"
10#include "../TrackPanel.h"
11#include "UndoManager.h"
12#include "ViewInfo.h"
13#include "../commands/CommandContext.h"
14#include "../commands/CommandManager.h"
15#include "../prefs/GUIPrefs.h"
16#include "../prefs/TracksPrefs.h"
17#include "../tracks/ui/ChannelView.h"
18
19
20#include <wx/app.h>
21#include <wx/scrolbar.h>
22
23#include <numeric>
24
25// private helper classes and functions
26namespace {
27
29{
30 auto &viewInfo = ViewInfo::Get( project );
31 auto &window = ProjectWindow::Get( project );
32
33 const double lowerBound =
34 std::max(viewInfo.selectedRegion.t0(),
35 window.ScrollingLowerBoundTime());
36 const double denom =
37 viewInfo.selectedRegion.t1() - lowerBound;
38 if (denom <= 0.0)
39 return viewInfo.GetZoom();
40
41 // LL: The "-1" is just a hack to get around an issue where zooming to
42 // selection doesn't actually get the entire selected region within the
43 // visible area. This causes a problem with scrolling at end of playback
44 // where the selected region may be scrolled off the left of the screen.
45 // I know this isn't right, but until the real rounding or 1-off issue is
46 // found, this will have to work.
47 // PRL: Did I fix this? I am not sure, so I leave the hack in place.
48 // Fixes might have resulted from commits
49 // 1b8f44d0537d987c59653b11ed75a842b48896ea and
50 // e7c7bb84a966c3b3cc4b3a9717d5f247f25e7296
51 auto width = viewInfo.GetTracksUsableWidth();
52 return (width - 1) / denom;
53}
54
56{
57
58 // Sets a limit on how far we will zoom out as a factor over zoom to fit.
59 const double maxZoomOutFactor = 4.0;
60 // Sets how many pixels we allow for one uint, such as seconds.
61 const double pixelsPerUnit = 5.0;
62
63 double result = 1.0;
64 auto &window = ProjectWindow::Get( project );
65 double zoomToFit = window.GetZoomOfToFit();
66 using namespace WaveChannelViewConstants;
67 switch(preset) {
68 default:
69 case kZoomDefault:
70 result = ZoomInfo::GetDefaultZoom();
71 break;
72 case kZoomToFit:
73 result = zoomToFit;
74 break;
76 result = GetZoomOfSelection( project );
77 break;
78 case kZoomMinutes:
79 result = pixelsPerUnit * 1.0/60;
80 break;
81 case kZoomSeconds:
82 result = pixelsPerUnit * 1.0;
83 break;
84 case kZoom5ths:
85 result = pixelsPerUnit * 5.0;
86 break;
87 case kZoom10ths:
88 result = pixelsPerUnit * 10.0;
89 break;
90 case kZoom20ths:
91 result = pixelsPerUnit * 20.0;
92 break;
93 case kZoom50ths:
94 result = pixelsPerUnit * 50.0;
95 break;
96 case kZoom100ths:
97 result = pixelsPerUnit * 100.0;
98 break;
99 case kZoom500ths:
100 result = pixelsPerUnit * 500.0;
101 break;
103 result = pixelsPerUnit * 1000.0;
104 break;
105 case kZoomSamples:
106 result = 44100.0;
107 break;
108 case kZoom4To1:
109 result = 44100.0 * 4;
110 break;
111 case kMaxZoom:
112 result = ZoomInfo::GetMaxZoom();
113 break;
114 };
115 if( result < (zoomToFit/maxZoomOutFactor) )
116 result = zoomToFit / maxZoomOutFactor;
117 return result;
118}
119
120}
121
122namespace {
124{
125 auto &viewInfo = ViewInfo::Get( project );
126 auto &tracks = TrackList::Get( project );
127
128 // Only nonminimized audio tracks will be resized
129 // Assume all channels of the track have the same minimization state
130 auto range = tracks.Any<AudioTrack>()
131 - [](const Track *pTrack){
132 return ChannelView::Get(*pTrack->GetChannel(0)).GetMinimized(); };
133 auto count = range.sum(&Track::NChannels);
134 if (count == 0)
135 return;
136
137 // Find total height to apportion
138 auto height = viewInfo.GetHeight();
139 height -= 28;
140
141 // The height of minimized and non-audio tracks cannot be apportioned
142 height -=
145
146 // Give each resized track the average of the remaining height
147 // Bug 2803: Cast count to int, because otherwise the result of
148 // division will be unsigned too, and will be a very large number
149 // if height was negative!
150 height = height / (int)count;
151 // Use max() so that we don't set a negative height when there is
152 // not enough room.
153 height = std::max( (int)TrackInfo::MinimumTrackHeight(), height );
154
155 for (auto t : range)
156 for (auto pChannel : t->Channels())
157 ChannelView::Get(*pChannel).SetExpandedHeight(height);
158}
159}
160
161namespace ViewActions {
162
163// Menu handler functions
164
165struct Handler final
166 : CommandHandlerObject // MUST be the first base class!
168{
169
170void OnZoomIn(const CommandContext &context)
171{
172 auto &project = context.project;
173 auto &trackPanel = TrackPanel::Get( project );
174 auto &window = ProjectWindow::Get( project );
175 window.ZoomInByFactor( 2.0 );
176 trackPanel.Refresh(false);
177}
178
179void OnZoomNormal(const CommandContext &context)
180{
181 auto &project = context.project;
182 auto &trackPanel = TrackPanel::Get( project );
183 auto &window = ProjectWindow::Get( project );
184
185 window.Zoom(ZoomInfo::GetDefaultZoom());
186 trackPanel.Refresh(false);
187}
188
189void OnZoomOut(const CommandContext &context)
190{
191 auto &project = context.project;
192 auto &window = ProjectWindow::Get( project );
193 window.ZoomOutByFactor( 1 /2.0 );
194}
195
196void OnZoomSel(const CommandContext &context)
197{
198 auto &project = context.project;
199 auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
200 auto &window = ProjectWindow::Get( project );
201
202 window.Zoom( GetZoomOfSelection( project ) );
203 window.TP_ScrollWindow(selectedRegion.t0());
204}
205
206void OnZoomToggle(const CommandContext &context)
207{
208 auto &project = context.project;
209 auto &viewInfo = ViewInfo::Get( project );
210 auto &trackPanel = TrackPanel::Get( project );
211 auto &window = ProjectWindow::Get( project );
212
213// const double origLeft = viewInfo.h;
214// const double origWidth = viewInfo.GetScreenEndTime() - origLeft;
215
216 // Choose the zoom that is most different to the current zoom.
219 double Z = viewInfo.GetZoom();// Current Zoom.
220 double ChosenZoom =
221 fabs(log(Zoom1 / Z)) > fabs(log( Z / Zoom2)) ? Zoom1:Zoom2;
222
223 window.Zoom(ChosenZoom);
224 trackPanel.Refresh(false);
225// const double newWidth = GetScreenEndTime() - viewInfo.h;
226// const double newh = origLeft + (origWidth - newWidth) / 2;
227// TP_ScrollWindow(newh);
228}
229
230void OnZoomFit(const CommandContext &context)
231{
232 auto &project = context.project;
233 auto &window = ProjectWindow::Get( project );
234 window.DoZoomFit();
235}
236
237void OnZoomFitV(const CommandContext &context)
238{
239 auto &project = context.project;
240 auto &window = ProjectWindow::Get( project );
241
243
244 window.GetVerticalScrollBar().SetThumbPosition(0);
246}
247
248void OnAdvancedVZoom(const CommandContext &context)
249{
250 auto &project = context.project;
251 auto &commandManager = CommandManager::Get( project );
252
253 bool checked = !gPrefs->Read(wxT("/GUI/VerticalZooming"), 0L);
254 gPrefs->Write(wxT("/GUI/VerticalZooming"), checked);
255 gPrefs->Flush();
256 commandManager.Check(wxT("AdvancedVZoom"), checked);
258}
259
261{
262 auto &project = context.project;
263 auto &tracks = TrackList::Get( project );
264 auto &window = ProjectWindow::Get( project );
265
266 for (auto t : tracks)
267 for (auto pChannel : t->Channels())
268 ChannelView::Get(*pChannel).SetMinimized(true);
269
271}
272
274{
275 auto &project = context.project;
276 auto &tracks = TrackList::Get( project );
277 auto &window = ProjectWindow::Get( project );
278
279 for (auto t : tracks)
280 for (auto pChannel : t->Channels())
281 ChannelView::Get(*pChannel).SetMinimized(false);
282
284}
285
286void OnGoSelStart(const CommandContext &context)
287{
288 auto &project = context.project;
289 auto &viewInfo = ViewInfo::Get( project );
290 auto &selectedRegion = viewInfo.selectedRegion;
291 auto &window = ProjectWindow::Get( project );
292
293 if (selectedRegion.isPoint())
294 return;
295
296 window.TP_ScrollWindow(
297 selectedRegion.t0() - ((viewInfo.GetScreenEndTime() - viewInfo.h) / 2));
298}
299
300void OnGoSelEnd(const CommandContext &context)
301{
302 auto &project = context.project;
303 auto &viewInfo = ViewInfo::Get( project );
304 auto &selectedRegion = viewInfo.selectedRegion;
305 auto &window = ProjectWindow::Get( project );
306
307 if (selectedRegion.isPoint())
308 return;
309
310 window.TP_ScrollWindow(
311 selectedRegion.t1() - ((viewInfo.GetScreenEndTime() - viewInfo.h) / 2));
312}
313
315{
316 auto &project = context.project;
317 auto &commandManager = CommandManager::Get( project );
318
319 bool checked = !gPrefs->Read(wxT("/GUI/ShowExtraMenus"), 0L);
320 gPrefs->Write(wxT("/GUI/ShowExtraMenus"), checked);
321 gPrefs->Flush();
322 commandManager.Check(wxT("ShowExtraMenus"), checked);
324}
325
326void OnShowClipping(const CommandContext &context)
327{
328 auto &project = context.project;
329 auto &commandManager = CommandManager::Get( project );
330 auto &trackPanel = TrackPanel::Get( project );
331
332 bool checked = !gPrefs->Read(wxT("/GUI/ShowClipping"), 0L);
333 gPrefs->Write(wxT("/GUI/ShowClipping"), checked);
334 gPrefs->Flush();
335 commandManager.Check(wxT("ShowClipping"), checked);
336
338
339 trackPanel.Refresh(false);
340}
341
343{
344 auto &project = context.project;
345 auto &commandManager = CommandManager::Get( project );
346 auto &trackPanel = TrackPanel::Get( project );
347
348 bool checked = !gPrefs->Read(wxT("/GUI/ShowTrackNameInWaveform"), 0L);
349 gPrefs->Write(wxT("/GUI/ShowTrackNameInWaveform"), checked);
350 gPrefs->Flush();
351 commandManager.Check(wxT("ShowTrackNameInWaveform"), checked);
352
354
355 trackPanel.Refresh(false);
356}
357
358// Not a menu item, but a listener for events
360{
361 if (message.type == UndoRedoMessage::Pushed) {
362 const auto &settings = ProjectSettings::Get( mProject );
363 if (settings.GetTracksFitVerticallyZoomed())
365 }
366}
367
369 : mProject{ project }
370{
373}
374
375Handler( const Handler & ) = delete;
376Handler &operator=( const Handler & ) = delete;
377
380
381}; // struct Handler
382
383} // namespace
384
385// Handler needs a back-reference to the project, so needs a factory registered
386// with AudacityProject.
388 []( AudacityProject &project ) {
389 return std::make_unique< ViewActions::Handler >( project ); } };
390
392 return project.AttachedObjects::Get< ViewActions::Handler >( key );
393};
394
395// Menu definitions
396
397#define FN(X) (& ViewActions::Handler :: X)
398
399// Under /MenuBar
400namespace {
401using namespace MenuTable;
403{
405
406 static BaseItemSharedPtr menu{
408 Menu( wxT("View"), XXO("&View"),
409 Section( "Basic",
410 Menu( wxT("Zoom"), XXO("&Zoom"),
411 Section( "",
412 Command( wxT("ZoomIn"), XXO("Zoom &In"), FN(OnZoomIn),
413 ZoomInAvailableFlag(), wxT("Ctrl+1") ),
414 Command( wxT("ZoomNormal"), XXO("Zoom &Normal"), FN(OnZoomNormal),
415 TracksExistFlag(), wxT("Ctrl+2") ),
416 Command( wxT("ZoomOut"), XXO("Zoom &Out"), FN(OnZoomOut),
417 ZoomOutAvailableFlag(), wxT("Ctrl+3") ),
418 Command( wxT("ZoomSel"), XXO("&Zoom to Selection"), FN(OnZoomSel),
419 TimeSelectedFlag(), wxT("Ctrl+E") ),
420 Command( wxT("ZoomToggle"), XXO("Zoom &Toggle"), FN(OnZoomToggle),
421 TracksExistFlag(), wxT("Shift+Z") )
422 ),
423 Section( "",
424 Command( wxT("AdvancedVZoom"), XXO("Advanced &Vertical Zooming"),
425 FN(OnAdvancedVZoom), AlwaysEnabledFlag,
426 Options{}.CheckTest( wxT("/GUI/VerticalZooming"), false ) )
427 )
428 ),
429
430 Menu( wxT("TrackSize"), XXO("T&rack Size"),
431 Command( wxT("FitInWindow"), XXO("&Fit to Width"), FN(OnZoomFit),
432 TracksExistFlag(), wxT("Ctrl+F") ),
433 Command( wxT("FitV"), XXO("Fit to &Height"), FN(OnZoomFitV),
434 TracksExistFlag(), wxT("Ctrl+Shift+F") ),
435 Command( wxT("CollapseAllTracks"), XXO("&Collapse All Tracks"),
436 FN(OnCollapseAllTracks), TracksExistFlag(), wxT("Ctrl+Shift+C") ),
437 Command( wxT("ExpandAllTracks"), XXO("E&xpand Collapsed Tracks"),
438 FN(OnExpandAllTracks), TracksExistFlag(), wxT("Ctrl+Shift+X") )
439 ),
440
441 Menu( wxT("SkipTo"), XXO("Sk&ip to"),
442 Command( wxT("SkipSelStart"), XXO("Selection Sta&rt"),
443 FN(OnGoSelStart), TimeSelectedFlag(),
444 Options{ wxT("Ctrl+["), XO("Skip to Selection Start") } ),
445 Command( wxT("SkipSelEnd"), XXO("Selection En&d"), FN(OnGoSelEnd),
447 Options{ wxT("Ctrl+]"), XO("Skip to Selection End") } )
448 )
449 ),
450
451 Section( "Windows" ),
452
453 Section( "Other",
454 Command( wxT("ShowExtraMenus"), XXO("Enable &Extra Menus"),
455 FN(OnShowExtraMenus), AlwaysEnabledFlag,
456 Options{}.CheckTest( wxT("/GUI/ShowExtraMenus"), false ) ),
457 Command( wxT("ShowTrackNameInWaveform"), XXO("Show Track &Name as overlay"),
458 FN(OnShowNameOverlay), AlwaysEnabledFlag,
459 Options{}.CheckTest( wxT("/GUI/ShowTrackNameInWaveform"), false ) ),
460 Command( wxT("ShowClipping"), XXO("&Show Clipping in Waveform"),
461 FN(OnShowClipping), AlwaysEnabledFlag,
462 Options{}.CheckTest( wxT("/GUI/ShowClipping"), false ) )
463 )
464 ) ) };
465 return menu;
466
467}
468
470 wxT(""),
472};
473}
474
475#undef FN
wxT("CloseDown"))
AttachedItem sAttachment1
constexpr CommandFlag AlwaysEnabledFlag
Definition: CommandFlag.h:34
wxEvtHandler CommandHandlerObject
const ReservedCommandFlag & ZoomInAvailableFlag()
const ReservedCommandFlag & ZoomOutAvailableFlag()
const ReservedCommandFlag & TimeSelectedFlag()
const ReservedCommandFlag & TracksExistFlag()
XO("Cut/Copy/Paste")
XXO("&Cut/Copy/Paste Toolbar")
int ShowTrackNameInWaveformPrefsID()
Definition: GUIPrefs.cpp:245
int ShowClippingPrefsID()
Definition: GUIPrefs.cpp:239
Extends Track with notions of mute and solo setting.
audacity::BasicSettings * gPrefs
Definition: Prefs.cpp:68
EffectReverbSettings preset
Definition: Reverb.cpp:44
const auto tracks
const auto project
static Settings & settings()
Definition: TrackInfo.cpp:83
static const AudacityProject::AttachedObjects::RegisteredFactory key
Definition: ViewMenus.cpp:387
#define FN(X)
Definition: ViewMenus.cpp:397
static CommandHandlerObject & findCommandHandler(AudacityProject &project)
Definition: ViewMenus.cpp:391
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
Track subclass holding data representing sound (as notes, or samples, or ...)
Definition: PlayableTrack.h:21
virtual size_t NChannels() const =0
Report the number of channels.
std::shared_ptr< ChannelType > GetChannel(size_t iChannel)
Retrieve a channel, cast to the given type.
Definition: Channel.h:344
static ChannelView & Get(Channel &channel)
bool GetMinimized() const
Definition: ChannelView.h:68
void SetMinimized(bool minimized)
static int GetChannelGroupHeight(const Track *pTrack)
Definition: ChannelView.cpp:32
void SetExpandedHeight(int height)
Client code makes static instance from a factory of attachments; passes it to Get or Find as a retrie...
Definition: ClientData.h:266
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
AudacityProject & project
static CommandManager & Get(AudacityProject &project)
static void RebuildAllMenuBars()
Definition: Menus.cpp:614
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
Definition: Observer.h:199
A move-only handle representing a connection to a Publisher.
Definition: Observer.h:70
static void Broadcast(int id=0)
Call this static function to notify all PrefsListener objects.
Definition: Prefs.cpp:99
void ModifyState(bool bWantsAutoSave)
static ProjectHistory & Get(AudacityProject &project)
static ProjectSettings & Get(AudacityProject &project)
static ProjectWindow & Get(AudacityProject &project)
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:123
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:354
static TrackPanel & Get(AudacityProject &project)
Definition: TrackPanel.cpp:232
static WaveChannelViewConstants::ZoomPresets Zoom1Choice()
static WaveChannelViewConstants::ZoomPresets Zoom2Choice()
static UndoManager & Get(AudacityProject &project)
Definition: UndoManager.cpp:71
NotifyingSelectedRegion selectedRegion
Definition: ViewInfo.h:219
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:235
static double GetDefaultZoom()
Definition: ZoomInfo.h:113
static double GetMaxZoom()
Definition: ZoomInfo.cpp:83
virtual bool Flush() noexcept=0
virtual bool Write(const wxString &key, bool value)=0
virtual bool Read(const wxString &key, bool *value) const =0
constexpr auto Section
constexpr auto Menu
Items will appear in a main toolbar menu or in a sub-menu.
constexpr auto Command
std::unique_ptr< detail::IndirectItem< Item > > Indirect(const std::shared_ptr< Item > &ptr)
A convenience function.
Definition: Registry.h:113
std::shared_ptr< BaseItem > BaseItemSharedPtr
Definition: Registry.h:78
AUDACITY_DLL_API unsigned MinimumTrackHeight()
Definition: TrackInfo.cpp:192
double GetZoomOfPreset(const AudacityProject &project, int preset)
Definition: ViewMenus.cpp:55
void DoZoomFitV(AudacityProject &project)
Definition: ViewMenus.cpp:123
double GetZoomOfSelection(const AudacityProject &project)
Definition: ViewMenus.cpp:28
A convenient default parameter for class template Site.
Definition: ClientData.h:28
Options && CheckTest(const CheckFn &fn) &&
Type of message published by UndoManager.
Definition: UndoManager.h:55
enum UndoRedoMessage::Type type
void OnCollapseAllTracks(const CommandContext &context)
Definition: ViewMenus.cpp:260
void OnExpandAllTracks(const CommandContext &context)
Definition: ViewMenus.cpp:273
void OnGoSelStart(const CommandContext &context)
Definition: ViewMenus.cpp:286
void OnUndoPushed(UndoRedoMessage message)
Definition: ViewMenus.cpp:359
Handler(AudacityProject &project)
Definition: ViewMenus.cpp:368
void OnGoSelEnd(const CommandContext &context)
Definition: ViewMenus.cpp:300
AudacityProject & mProject
Definition: ViewMenus.cpp:379
Handler(const Handler &)=delete
void OnZoomFit(const CommandContext &context)
Definition: ViewMenus.cpp:230
void OnZoomFitV(const CommandContext &context)
Definition: ViewMenus.cpp:237
Handler & operator=(const Handler &)=delete
void OnZoomIn(const CommandContext &context)
Definition: ViewMenus.cpp:170
void OnShowClipping(const CommandContext &context)
Definition: ViewMenus.cpp:326
void OnZoomOut(const CommandContext &context)
Definition: ViewMenus.cpp:189
void OnZoomToggle(const CommandContext &context)
Definition: ViewMenus.cpp:206
Observer::Subscription mUndoSubscription
Definition: ViewMenus.cpp:378
void OnAdvancedVZoom(const CommandContext &context)
Definition: ViewMenus.cpp:248
void OnShowExtraMenus(const CommandContext &context)
Definition: ViewMenus.cpp:314
void OnShowNameOverlay(const CommandContext &context)
Definition: ViewMenus.cpp:342
void OnZoomNormal(const CommandContext &context)
Definition: ViewMenus.cpp:179
void OnZoomSel(const CommandContext &context)
Definition: ViewMenus.cpp:196