Audacity 3.2.0
ToolManager.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 ToolManager.cpp
6
7 Dominic Mazzoni
8 Shane T. Mueller
9 Leland Lucius
10
11 See ToolManager.h for details.
12
13*******************************************************************//*******************************************************************//**********************************************************************/
26
27
28#include "ToolManager.h"
29
30#include "../commands/CommandContext.h"
31
32// For compilers that support precompilation, includes "wx/wx.h".
33#include <wx/wxprec.h>
34
35#ifndef WX_PRECOMP
36#include <wx/dcclient.h>
37#include <wx/defs.h>
38#include <wx/frame.h>
39#include <wx/gdicmn.h>
40#include <wx/region.h>
41#include <wx/settings.h>
42#include <wx/sizer.h>
43#include <wx/sysopt.h>
44#include <wx/utils.h>
45#include <wx/window.h>
46#endif /* */
47
48#include <wx/minifram.h>
49#include <wx/popupwin.h>
50
51#include "AColor.h"
52#include "AllThemeResources.h"
53#include "ImageManipulation.h"
54#include "Menus.h"
55#include "Prefs.h"
56#include "Project.h"
57#include "ProjectWindows.h"
58#include "widgets/AButton.h"
59#include "widgets/ASlider.h"
61#include "widgets/Grabber.h"
62
66#define sizerW 11
67
68//
69// Constructor
70//
72 ( AudacityProject *parent, ToolManager *manager, ToolBar *bar, wxPoint pos )
73 : wxFrame( FindProjectFrame( parent ),
74 bar->GetId(),
75 wxEmptyString,
76 pos,
77 wxDefaultSize,
78 wxNO_BORDER |
79 wxFRAME_NO_TASKBAR |
80#if !defined(__WXMAC__) // bug1358
81 wxFRAME_TOOL_WINDOW |
82#endif
83 wxFRAME_FLOAT_ON_PARENT )
84 , mParent{ parent }
85{
86 int width = bar->GetSize().x;
87 int border = 1;
88
89 // Save parameters
91 mBar = bar;
92
93 // Transfer the bar to the ferry
94 bar->Reparent(this);
95
96 // Bug 2120 (comment 6 residual): No need to set a minimum size
97 // if the toolbar is not resizable. On GTK, setting a minimum
98 // size will prevent the frame from shrinking if the toolbar gets
99 // reconfigured and needs to resize smaller.
100 if (bar->IsResizable())
101 {
102 SetMinSize(bar->GetDockedSize());
103 }
104
105 {
106 // We use a sizer to maintain proper spacing
107 auto s = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
108
109 // Add the bar to the sizer
110 s->Add(bar, 1, wxEXPAND | wxALL, border);
111
112 // Add space for the resize grabber
113 if (bar->IsResizable())
114 {
115 s->Add(sizerW, 1);
116 width += sizerW;
117 }
118
119 SetSize(width + 2 * ToolBarFloatMargin,
120 bar->GetDockedSize().y + 2 * ToolBarFloatMargin);
121
122 // Attach the sizer and resize the window to fit
123 SetSizer(s.release());
124 }
125
126 Layout();
127
128 // Inform toolbar of change
129 bar->SetDocked( NULL, true );
130
131 // Make sure resizable floaters don't get any smaller than initial size
132 if( bar->IsResizable() )
133 {
134 // Calc the minimum size of the frame
135 mMinSize = bar->GetMinSize() + ( GetSize() - bar->GetSize() );
136 }
137}
138
140{
141 if(HasCapture())
142 ReleaseMouse();
143}
144
146{
147 // Pass it on to the manager since it isn't in the handling hierarchy
148 mManager->ProcessEvent( event );
149}
150
151// The current size determines the min size for resizing...
152// the 'lock in' is at that aspect ratio.
154{
155 mBar = pBar;
156
157 wxSize sz = mBar->GetSize();
158 SetClientSize( sz );
159 int yDesiredMin = 26;
160 int y = sz.GetHeight();
161 if (y > yDesiredMin) {
162 sz.SetWidth((sz.GetWidth() * yDesiredMin) / y);
163 sz.SetHeight( yDesiredMin );
164 }
165 mMinSize = sz -wxSize( 10, 0);
166}
167
168void ToolFrame::OnToolBarUpdate( wxCommandEvent & event )
169{
170 // Resize floater window to exactly contain toolbar
171 // use actual size rather than minimum size.
172 if (mBar)
173 mBar->GetParent()->SetClientSize( mBar->GetSize() );// ->GetMinSize() );
174
175 // Allow it to propagate to our parent
176 event.Skip();
177}
178
179void ToolFrame::OnPaint( wxPaintEvent & WXUNUSED(event) )
180{
181 wxPaintDC dc( this );
182 wxSize sz = GetSize();
183 wxRect r;
184
185 dc.SetPen( theTheme.Colour( clrTrackPanelText ) );
186 dc.SetBackground( wxBrush( theTheme.Colour( clrMedium ) ) );
187 dc.Clear();
188 dc.SetBrush( *wxTRANSPARENT_BRUSH );
189 dc.DrawRectangle( 0, 0, sz.GetWidth(), sz.GetHeight() );
190
191 if( mBar && mBar->IsResizable() )
192 {
193 r.x = sz.x - sizerW - 2,
194 r.y = sz.y - sizerW - 2;
195 r.width = sizerW + 2;
196 r.height = sizerW + 2;
197
198 AColor::Line(dc, r.GetLeft(), r.GetBottom(), r.GetRight(), r.GetTop() );
199 AColor::Line(dc, r.GetLeft() + 3, r.GetBottom(), r.GetRight(), r.GetTop() + 3 );
200 AColor::Line(dc, r.GetLeft() + 6, r.GetBottom(), r.GetRight(), r.GetTop() + 6 );
201 AColor::Line(dc, r.GetLeft() + 9, r.GetBottom(), r.GetRight(), r.GetTop() + 9 );
202 }
203
204}
205
206void ToolFrame::OnMotion( wxMouseEvent & event )
207{
208 // Don't do anything if we're docked or not resizeable
209 if( !mBar || mBar->IsDocked() || !mBar->IsResizable() )
210 {
211 return;
212 }
213
214 // Retrieve the mouse position
215 wxPoint pos = ClientToScreen( event.GetPosition() );
216 if( HasCapture() && event.Dragging() )
217 {
218 wxRect rect = GetRect();
219
220 rect.SetBottomRight( pos );
221
222 // Keep it within max size, if specified
223 wxSize maxsz = mBar->GetMaxSize();
224 if (maxsz != wxDefaultSize)
225 {
226 if (maxsz.x != wxDefaultCoord && rect.width > maxsz.x)
227 {
228 rect.width = maxsz.x;
229 }
230 if (maxsz.y != wxDefaultCoord && rect.height > maxsz.y)
231 {
232 rect.height = maxsz.y;
233 }
234 }
235
236 if( rect.width < mMinSize.x )
237 {
238 rect.width = mMinSize.x;
239 }
240
241 if( rect.height < mMinSize.y )
242 {
243 rect.height = mMinSize.y;
244 }
245
246 Resize( rect.GetSize() );
247 }
248 else if( HasCapture() && event.LeftUp() )
249 {
250 ReleaseMouse();
251 }
252 else if( !HasCapture() )
253 {
254 wxRect rect = GetRect();
255 wxRect r;
256
257 r.x = rect.GetRight() - sizerW - 2,
258 r.y = rect.GetBottom() - sizerW - 2;
259 r.width = sizerW + 2;
260 r.height = sizerW + 2;
261
262 // Is left click within resize grabber?
263 if( r.Contains( pos ) && !event.Leaving() )
264 {
265 mOrigSize = GetSize();
266
267 SetCursor( wxCURSOR_SIZENWSE );
268 if( event.LeftDown() )
269 {
270 CaptureMouse();
271 }
272 }
273 else
274 {
275 SetCursor( wxCURSOR_ARROW );
276 }
277 }
278}
279
280void ToolFrame::OnCaptureLost( wxMouseCaptureLostEvent & WXUNUSED(event) )
281{
282 if( HasCapture() )
283 {
284 ReleaseMouse();
285 }
286}
287
288void ToolFrame::OnClose( wxCloseEvent & event )
289{
290 event.Veto();
291}
292
293void ToolFrame::OnKeyDown( wxKeyEvent &event )
294{
295 event.Skip();
296 if( HasCapture() && event.GetKeyCode() == WXK_ESCAPE ) {
297 Resize( mOrigSize );
298 ReleaseMouse();
299 }
300}
301
302void ToolFrame::Resize( const wxSize &size )
303{
304 SetMinSize( size );
305 SetSize( size );
306 Layout();
307 Refresh( false );
308}
309
311
312BEGIN_EVENT_TABLE( ToolFrame, wxFrame )
314 EVT_PAINT( ToolFrame::OnPaint )
315 EVT_MOUSE_EVENTS( ToolFrame::OnMotion )
316 EVT_MOUSE_CAPTURE_LOST( ToolFrame::OnCaptureLost )
317 EVT_CLOSE( ToolFrame::OnClose )
318 EVT_COMMAND( wxID_ANY, EVT_TOOLBAR_UPDATED, ToolFrame::OnToolBarUpdate )
319 EVT_KEY_DOWN( ToolFrame::OnKeyDown )
321
323
327
328BEGIN_EVENT_TABLE( ToolManager, wxEvtHandler )
329 EVT_GRABBER( wxID_ANY, ToolManager::OnGrabber )
330 EVT_TIMER( wxID_ANY, ToolManager::OnTimer )
332
333static const AudacityProject::AttachedObjects::RegisteredFactory key{
334 []( AudacityProject &parent ){
335 return std::make_shared< ToolManager >( &parent ); }
336};
337
339{
340 return project.AttachedObjects::Get< ToolManager >( key );
341}
342
344{
345 return Get( const_cast< AudacityProject & >( project ) );
346}
347
348//
349// Constructor
350//
352: wxEvtHandler()
353{
354 wxPoint pt[ 3 ];
355
356#if defined(__WXMAC__)
357 // Save original transition
358 mTransition = wxSystemOptions::GetOptionInt( wxMAC_WINDOW_PLAIN_TRANSITION );
359#endif
360
361 // Initialize everything
362 mParent = parent;
363 mLastPos.x = mBarPos.x = -1;
364 mLastPos.y = mBarPos.y = -1;
365 mDragWindow = NULL;
366 mDragDock = NULL;
367 mDragBar = NULL;
368
369 // Create the down arrow
370 pt[ 0 ].x = 0;
371 pt[ 0 ].y = 0;
372 pt[ 1 ].x = 9;
373 pt[ 1 ].y = 9;
374 pt[ 2 ].x = 18;
375 pt[ 2 ].y = 0;
376
377 // Create the shaped region
378 mDown = std::make_unique<wxRegion>( 3, &pt[0] );
379
380 // Create the down arrow
381 pt[ 0 ].x = 9;
382 pt[ 0 ].y = 0;
383 pt[ 1 ].x = 0;
384 pt[ 1 ].y = 9;
385 pt[ 2 ].x = 9;
386 pt[ 2 ].y = 18;
387
388 // Create the shaped region
389 mLeft = std::make_unique<wxRegion>( 3, &pt[0] );
390
391 // Create the indicator frame
392 // parent is null but FramePtr ensures destruction
393 mIndicator = FramePtr{ safenew wxFrame( NULL,
394 wxID_ANY,
395 wxEmptyString,
396 wxDefaultPosition,
397 wxSize( 32, 32 ),
398 wxFRAME_TOOL_WINDOW |
399 wxFRAME_SHAPED |
400 wxNO_BORDER |
401 wxFRAME_NO_TASKBAR |
402 wxSTAY_ON_TOP )
403 };
404
405 // Hook the creation event...only needed on GTK, but doesn't hurt for all
406 mIndicator->Bind( wxEVT_CREATE,
408 this );
409
410 // Hook the paint event...needed for all
411 mIndicator->Bind( wxEVT_PAINT,
413 this );
414
415 // It's a little shy
416 mIndicator->Hide();
417}
418
420{
421 auto parent = mParent;
422 auto &window = GetProjectFrame( *parent );
423
424 // Hook the parents mouse events...using the parent helps greatly
425 // under GTK
426 window.Bind( wxEVT_LEFT_UP,
428 this );
429 window.Bind( wxEVT_MOTION,
431 this );
432 window.Bind( wxEVT_MOUSE_CAPTURE_LOST,
434 this );
435
436 wxWindow *topDockParent = TopPanelHook::Call( window );
437 wxASSERT(topDockParent);
438
439 // Create the top and bottom docks
440 mTopDock = safenew ToolDock( this, topDockParent, TopDockID );
441 mBotDock = safenew ToolDock( this, &window, BotDockID );
442
443 // Create all of the toolbars
444 // All have the project as parent window
445 wxASSERT(parent);
446
447 for (const auto &factory : RegisteredToolbarFactory::GetFactories()) {
448 if (factory) {
449 auto bar = factory( *parent );
450 if (bar) {
451 auto &slot = mBars[bar->GetSection()];
452 if (slot) {
453 // Oh no, name collision of registered toolbars
454 assert(false);
455 bar->Destroy();
456 continue;
457 }
458 slot = std::move(bar);
459 }
460 }
461 else
462 wxASSERT( false );
463 }
464
466 ForEach([ii = 0](ToolBar *bar) mutable { bar->SetIndex(ii++); });
467
468 // We own the timer
469 mTimer.SetOwner( this );
470
471 // Process the toolbar config settings
472 ReadConfig();
473
474 wxEvtHandler::AddFilter(this);
475
478}
479
480//
481// Destructor
482//
483
485{
486 if ( mTopDock || mBotDock ) { // destroy at most once
487 wxEvtHandler::RemoveFilter(this);
488
489 // Save the toolbar states
490 WriteConfig();
491
492 // This function causes the toolbars to be destroyed, so
493 // clear the configuration of the ToolDocks which refer to
494 // these toolbars. This change was needed to stop Audacity
495 // crashing when running with Jaws on Windows 10 1703.
498
499 mTopDock = mBotDock = nullptr; // indicate that it has been destroyed
500
501 for (auto &pair : mBars)
502 pair.second.reset();
503
504 mIndicator.reset();
505 }
506}
507
509{
510 Destroy();
511}
512
513// This table describes the default configuration of the toolbars as
514// a "tree" and must be kept in pre-order traversal.
515
516// In fact this tree is more of a broom -- nothing properly branches except
517// at the root.
518
519// "Root" corresponds to left edge of the main window, and successive siblings
520// go from top to bottom. But in practice layout may wrap this abstract
521// configuration if the window size is narrow.
522
523static struct DefaultConfigEntry {
526 Identifier below; // preceding sibling
527} DefaultConfigTable [] = {
528 // Top dock row, may wrap
529 { wxT("Control"), {}, {} },
530 { wxT("Tools"), wxT("Control"), {} },
531 { wxT("Edit"), wxT("Tools"), {} },
532 { wxT("CutCopyPaste"), wxT("Edit"), {} },
533 { wxT("Audio Setup"), wxT("CutCopyPaste"), {} },
534#ifdef HAS_AUDIOCOM_UPLOAD
535 { wxT("Share Audio"), wxT("Audio Setup"), {} },
536 { wxT("RecordMeter"), wxT("Share Audio"), {} },
537#else
538 { wxT("RecordMeter"), wxT("Audio Setup"), {} },
539#endif
540 { wxT("PlayMeter"), wxT("RecordMeter"), {} },
541
542 // start another top dock row
543 { wxT("Scrub"), {}, wxT("Control") },
544 { wxT("Device"), wxT("Scrub"), wxT("Control") },
545
546 // Hidden by default in top dock
547 { wxT("CombinedMeter"), {}, {} },
548
549 // Bottom dock
550 { wxT("Selection"), {}, {} },
551 { wxT("Time"), wxT("Selection"), {} },
552
553// DA: Transcription Toolbar not docked, by default.
554#ifdef EXPERIMENTAL_DA
555 { wxT("Transcription"), {}, {} },
556#else
557 { wxT("Transcription"), wxT("Time"), {} },
558#endif
559
560 // Hidden by default in bottom dock
561 { wxT("SpectralSelection"), {}, {} },
563
564// Static member function.
566{
567 auto &project = context.project;
568 auto &toolManager = ToolManager::Get( project );
569
570 toolManager.Reset();
571 Get(project).ModifyToolbarMenus(project);
572}
573
574
576{
577 // Disconnect all docked bars
578 for ( const auto &entry : DefaultConfigTable )
579 {
580 const auto &ndx = entry.barID;
581 ToolBar *bar = GetToolBar(ndx);
582 if (!bar)
583 continue;
584
586 (entry.rightOf == Identifier{}) ? nullptr : GetToolBar(entry.rightOf),
587 (entry.below == Identifier{}) ? nullptr : GetToolBar(entry.below)
588 };
589
590 bar->SetSize( 20,20 );
591
592 wxWindow *floater;
593 ToolDock *dock;
594 bool expose = true;
595
596 // Disconnect the bar
597 if( bar->IsDocked() )
598 {
599 bar->GetDock()->Undock( bar );
600 floater = NULL;
601 }
602 else
603 {
604 floater = bar->GetParent();
605 }
606
607 // Decide which dock.
608 dock = (bar->DefaultDockID() == ToolBar::TopDockID)
609 ? mTopDock : mBotDock;
610
611 // PRL: Destroy the tool frame before recreating buttons.
612 // This fixes some subtle sizing problems on macOs.
613 bar->Reparent( dock );
614 //OK (and good) to DELETE floater, as bar is no longer in it.
615 if( floater )
616 floater->Destroy();
617
618 // Recreate bar buttons (and resize it)
619 bar->SetToDefaultSize();
620 bar->ReCreateButtons();
622
623#if 0
624 if( bar->IsResizable() )
625 {
626 bar->SetSize(bar->GetBestFittingSize());
627 }
628#endif
629
630 // Hide some bars.
631 expose = bar->ShownByDefault() || bar->HideAfterReset();
632
633 // Next condition will always (?) be true, as the reset configuration is
634 // with no floating toolbars.
635 if( dock != NULL )
636 {
637 // when we dock, we reparent, so bar is no longer a child of floater.
638 dock->Dock( bar, false, position );
639 Expose( bar->GetSection(), expose );
640 }
641 else
642 {
643 // The (tool)bar has a dragger window round it, the floater.
644 // in turn floater will have mParent (the entire App) as its
645 // parent.
646
647 // Maybe construct a NEW floater
648 // this happens if we have just been bounced out of a dock.
649 if( floater == NULL ) {
650 wxASSERT(mParent);
651 floater = safenew ToolFrame( mParent, this, bar, wxPoint(-1,-1) );
652 bar->Reparent( floater );
653 }
654
655 // This bar is undocked and invisible.
656 // We are doing a reset toolbars, so even the invisible undocked bars should
657 // be moved somewhere sensible. Put bar near center of window.
658 // If there were multiple hidden toobars the * 10 adjustment means
659 // they won't overlap too much.
660 floater->CentreOnParent( );
661 const auto index = bar->GetIndex();
662 floater->Move(
663 floater->GetPosition() + wxSize{ index * 10 - 200, index * 10 });
664 bar->SetDocked( NULL, false );
665 Expose( bar->GetSection(), false );
666 }
667 }
668
669 ForEach([this](auto bar){
670 if (bar && bar->HideAfterReset())
671 Expose(bar->GetSection(), false);
672 });
673 // TODO:??
674 // If audio was playing, we stopped the VU meters,
675 // It would be nice to show them again, but hardly essential as
676 // they will show up again on the next play.
677 // SetVUMeters(AudacityProject *p);
678 Updated();
679}
680
682{
683 ForEach([](auto bar){
684 if (bar)
685 bar->RegenerateTooltips();
686 });
687}
688
689int ToolManager::FilterEvent(wxEvent &event)
690{
691 // Snoop the global event stream for changes of focused window. Remember
692 // the last one of our own that is not a grabber.
693
694 if (event.GetEventType() == wxEVT_KILL_FOCUS) {
695 auto &focusEvent = static_cast<wxFocusEvent&>(event);
696 auto window = focusEvent.GetWindow();
697 auto top = wxGetTopLevelParent(window);
698 if(auto toolFrame = dynamic_cast<ToolFrame*>(top))
699 top = toolFrame->GetParent();
700 // window is that which will GET the focus
701 if ( window &&
702 !dynamic_cast<Grabber*>( window ) &&
703 !dynamic_cast<ToolFrame*>( window ) &&
704 top == FindProjectFrame( mParent ) )
705 // Note this is a dangle-proof wxWindowRef:
706 mLastFocus = window;
707 }
708
709 return Event_Skip;
710}
711
712//
713// Read the toolbar states
714//
716{
717 wxString oldpath = gPrefs->GetPath();
718 std::vector<Identifier> unordered[ DockCount ];
719 std::vector<ToolBar*> dockedAndHidden;
720 std::map<Identifier, bool> show;
721 std::map<Identifier, int> width;
722 std::map<Identifier, int> height;
723 int x, y;
724 int dock;
725 bool someFound { false };
726
727#if defined(__WXMAC__)
728 // Disable window animation
729 wxSystemOptions::SetOption( wxMAC_WINDOW_PLAIN_TRANSITION, 1 );
730#endif
731
732 // Change to the bar root
733 gPrefs->SetPath( wxT("/GUI/ToolBars") );
734
735 ToolBarConfiguration::Legacy topLegacy, botLegacy;
736
737 int vMajor, vMinor, vMicro;
738 gPrefs->GetVersionKeysInit(vMajor, vMinor, vMicro);
739 bool useLegacyDock = false;
740 // note that vMajor, vMinor, and vMicro will all be zero if either it's a new audacity.cfg file
741 // or the version is less than 1.3.13 (when there were no version keys according to the comments in
742 // InitPreferences()). So for new audacity.cfg
743 // file useLegacyDock will be true, but this doesn't matter as there are no Dock or DockV2 keys in the file yet.
744 if (vMajor <= 1 ||
745 (vMajor == 2 && (vMinor <= 1 || (vMinor == 2 && vMicro <= 1)))) // version <= 2.2.1
746 useLegacyDock = true;
747
748
749 // Load and apply settings for each bar
750 ForEach([&](ToolBar *bar){
751 //wxPoint Center = mParent->GetPosition() + (mParent->GetSize() * 0.33);
752 //wxPoint Center(
753 // wxSystemSettings::GetMetric( wxSYS_SCREEN_X ) /2 ,
754 // wxSystemSettings::GetMetric( wxSYS_SCREEN_Y ) /2 );
755
756 // Change to the bar subkey
757 auto ndx = bar->GetSection();
758 gPrefs->SetPath( ndx.GET() );
759
760 const bool bShownByDefault = bar->ShownByDefault();
761 const int defaultDock = bar->DefaultDockID();
762
763 // Read in all the settings
764
765 if (useLegacyDock)
766 gPrefs->Read( wxT("Dock"), &dock, -1); // legacy version of DockV2
767 else
768 gPrefs->Read( wxT("DockV2"), &dock, -1);
769
770 const bool found = (dock != -1);
771 if (found)
772 someFound = true;
773 if (!found)
774 dock = defaultDock;
775
776 ToolDock *d;
778 switch(dock)
779 {
780 case TopDockID: d = mTopDock; pLegacy = &topLegacy; break;
781 case BotDockID: d = mBotDock; pLegacy = &botLegacy; break;
782 default: d = nullptr; pLegacy = nullptr; break;
783 }
784
785 bool ordered = ToolBarConfiguration::Read(
786 d ? &d->GetConfiguration() : nullptr,
787 pLegacy,
788 bar, show[ ndx ], bShownByDefault)
789 && found;
790
791 gPrefs->Read( wxT("X"), &x, -1 );
792 gPrefs->Read( wxT("Y"), &y, -1 );
793 gPrefs->Read( wxT("W"), &width[ ndx ], -1 );
794 gPrefs->Read( wxT("H"), &height[ ndx ], -1 );
795
796 bar->SetVisible( show[ ndx ] );
797
798 // Docked or floating?
799 if( dock )
800 {
801 // Default to top dock if the ID isn't valid
802 if( dock < NoDockID || dock > DockCount ) {
803 dock = TopDockID;
804 }
805
806 // Create the bar with the correct parent
807 if( dock == TopDockID )
808 {
809 bar->Create( mTopDock );
810 }
811 else
812 {
813 bar->Create( mBotDock );
814 }
815
816 // Set the width and height
817 if( width[ ndx ] != -1 && height[ ndx ] != -1 )
818 {
819 wxSize sz( width[ ndx ], height[ ndx ] );
820 bar->SetSize( sz );
821 bar->ResizingDone();
822 }
823
824#ifdef EXPERIMENTAL_SYNC_LOCK
825 // Set the width
826 if( width[ ndx ] >= bar->GetSize().x )
827 {
828 wxSize sz( width[ ndx ], bar->GetSize().y );
829 bar->SetSize( sz );
830 bar->Layout();
831 }
832#else
833 // note that this section is here because if you had been using sync-lock and now you aren't,
834 // the space for the extra button is stored in audacity.cfg, and so you get an extra space
835 // in the EditToolbar.
836 // It is needed so that the meterToolbar size gets preserved.
837 // Longer-term we should find a better fix for this.
838 wxString thisBar = bar->GetSection();
839 if( thisBar != wxT("Edit"))
840 {
841 // Set the width
842 if( width[ ndx ] >= bar->GetSize().x )
843 {
844 wxSize sz( width[ ndx ], bar->GetSize().y );
845 bar->SetSize( sz );
846 bar->Layout();
847 }
848 }
849#endif
850 // make a note of docked and hidden toolbars
851 if (!show[ndx])
852 dockedAndHidden.push_back(bar);
853
854 if (!ordered)
855 {
856 // These must go at the end
857 unordered[ dock - 1 ].push_back( ndx );
858 }
859 }
860 else
861 {
862 // Create the bar (with the top dock being temporary parent)
863 bar->Create( mTopDock );
864
865 // Construct a NEW floater
866 wxASSERT(mParent);
867 ToolFrame *f = safenew ToolFrame( mParent, this, bar, wxPoint( x, y ) );
868
869 // Set the width and height
870 if( width[ ndx ] != -1 && height[ ndx ] != -1 )
871 {
872 wxSize sz( width[ ndx ], height[ ndx ] );
873 f->SetSizeHints( sz );
874 f->SetSize( sz );
875 f->Layout();
876 if( (x!=-1) && (y!=-1) )
877 bar->SetPositioned();
878 }
879
880 // Required on Linux Xfce
881 wxSize msz(width[ndx],height[ndx]-1);
882 bar->GetParent()->SetMinSize(msz);
883
884 // Inform toolbar of change
885 bar->SetDocked( NULL, false );
886
887 // Show or hide it
888 Expose( bar->GetSection(), show[ ndx ] );
889 }
890
891 // Change back to the bar root
892 //gPrefs->SetPath( wxT("..") ); <-- Causes a warning...
893 // May or may not have gone into a subdirectory,
894 // so use an absolute path.
895 gPrefs->SetPath( wxT("/GUI/ToolBars") );
896 });
897
898 mTopDock->GetConfiguration().PostRead(topLegacy);
899 mBotDock->GetConfiguration().PostRead(botLegacy);
900
901 // Add all toolbars to their target dock
902 for( dock = 0; dock < DockCount; dock++ )
903 {
904 ToolDock *d = ( dock + 1 == TopDockID ? mTopDock : mBotDock );
905
906 d->LoadConfig();
907
908 // Add all unordered toolbars
909 for( int ord = 0; ord < (int) unordered[ dock ].size(); ord++ )
910 {
911 ToolBar *t = mBars[unordered[dock][ord]].get();
912
913 // Dock it
914 d->Dock( t, false );
915
916 // Show or hide the bar
917 Expose( t->GetSection(), show[ t->GetSection() ] );
918 }
919 }
920
921 // hidden docked toolbars
922 for (auto bar : dockedAndHidden) {
923 bar->SetVisible(false );
924 bar->GetDock()->Dock(bar, false);
925 bar->Expose(false);
926 }
927
928 // Restore original config path
929 gPrefs->SetPath( oldpath );
930
931#if defined(__WXMAC__)
932 // Reinstate original transition
933 wxSystemOptions::SetOption( wxMAC_WINDOW_PLAIN_TRANSITION, mTransition );
934#endif
935
936 // Setup the neighbors according to the
937 // default config
938
939 for (const auto& entry : DefaultConfigTable)
940 {
941 const auto &ndx = entry.barID;
942 const auto bar = GetToolBar(ndx);
943 bar->SetPreferredNeighbors(entry.rightOf, entry.below);
944 }
945
946 if (!someFound)
947 Reset();
948}
949
950//
951// Save the toolbar states
952//
954{
955 if( !gPrefs )
956 {
957 return;
958 }
959
960 wxString oldpath = gPrefs->GetPath();
961 int ndx;
962
963 // Change to the bar root
964 gPrefs->SetPath( wxT("/GUI/ToolBars") );
965
966 // Save state of each bar
967 ForEach([this](ToolBar *bar){
968 // Change to the bar subkey
969 gPrefs->SetPath( bar->GetSection().GET() );
970
971 // Search both docks for toolbar order
972 bool to = mTopDock->GetConfiguration().Contains( bar );
973 bool bo = mBotDock->GetConfiguration().Contains( bar );
974
975 // Save
976 // Note that DockV2 was introduced in 2.2.2 to fix bug #1554. Dock is retained so that
977 // the toolbar layout is not changed when opening a version before 2.2.2, and in particular
978 // its value is compatible with versions 2.1.3 to 2.2.1 which have this bug.
979 ToolDock* dock = bar->GetDock(); // dock for both shown and hidden toolbars
980 gPrefs->Write( wxT("DockV2"), static_cast<int>(dock == mTopDock ? TopDockID : dock == mBotDock ? BotDockID : NoDockID ));
981
982 gPrefs->Write( wxT("Dock"), static_cast<int>( to ? TopDockID : bo ? BotDockID : NoDockID));
983
984 dock = to ? mTopDock : bo ? mBotDock : nullptr; // dock for shown toolbars
986 (dock ? &dock->GetConfiguration() : nullptr, bar);
987
988 wxPoint pos( -1, -1 );
989 wxSize sz = bar->GetSize();
990 if( !bar->IsDocked() && bar->IsPositioned() )
991 {
992 pos = bar->GetParent()->GetPosition();
993 sz = bar->GetParent()->GetSize();
994 }
995 gPrefs->Write( wxT("X"), pos.x );
996 gPrefs->Write( wxT("Y"), pos.y );
997 gPrefs->Write( wxT("W"), sz.x );
998 gPrefs->Write( wxT("H"), sz.y );
999
1000 // Change back to the bar root
1001 gPrefs->SetPath( wxT("..") );
1002 });
1003
1004 // Restore original config path
1005 gPrefs->SetPath( oldpath );
1006 gPrefs->Flush();
1007}
1008
1009//
1010// Return a pointer to the specified toolbar or nullptr
1011//
1013{
1014 auto end = mBars.end(), iter = mBars.find(type);
1015 return (iter == end) ? nullptr : iter->second.get();
1016}
1017
1018//
1019// Return a pointer to the top dock
1020//
1022{
1023 return mTopDock;
1024}
1025
1027{
1028 return mTopDock;
1029}
1030
1031//
1032// Return a pointer to the bottom dock
1033//
1035{
1036 return mBotDock;
1037}
1038
1040{
1041 return mBotDock;
1042}
1043
1044//
1045// Queues an EVT_TOOLBAR_UPDATED command event to notify any
1046// interest parties of an updated toolbar or dock layout
1047//
1049{
1050 // Queue an update event
1051 wxCommandEvent e( EVT_TOOLBAR_UPDATED );
1052 GetProjectFrame( *mParent ).GetEventHandler()->AddPendingEvent( e );
1053}
1054
1055//
1056// Return docked state of specified toolbar
1057//
1059{
1060 if (auto pBar = GetToolBar(type))
1061 return pBar->IsDocked();
1062 return false;
1063}
1064
1065//
1066// Returns the visibility of the specified toolbar
1067//
1069{
1070 if (auto pBar = GetToolBar(type))
1071 return pBar->IsVisible();
1072 return false;
1073
1074#if 0
1075 // If toolbar is floating
1076 if( !t->IsDocked() )
1077 {
1078 // Must return state of floater window
1079 return t->GetParent()->IsShown();
1080 }
1081
1082 // Return state of docked toolbar
1083 return t->IsShown();
1084#endif
1085}
1086
1087//
1088// Toggles the visible/hidden state of a toolbar
1089//
1091{
1092 Expose( type, !mBars[type]->IsVisible() );
1093 Updated();
1094}
1095
1096//
1097// Set the visible/hidden state of a toolbar
1098//
1099void ToolManager::Expose( Identifier type, bool show )
1100{
1101 ToolBar *t = mBars[type].get();
1102
1103 // Handle docked and floaters differently
1104 if( t->IsDocked() )
1105 {
1106 t->GetDock()->Expose( t->GetSection(), show );
1107 }
1108 else
1109 {
1110 t->Expose( show );
1111 }
1112}
1113
1114//
1115// Ask both docks to (re)layout their bars
1116//
1118{
1119 // Update the layout
1120 if (mTopDock)
1121 {
1123 }
1124
1125 if (mBotDock)
1126 {
1128 }
1129}
1130
1131//
1132// Handle toolbar dragging
1133//
1134void ToolManager::OnMouse( wxMouseEvent & event )
1135{
1136 // Go ahead and set the event to propagate
1137 event.Skip();
1138
1139 // Can't do anything if we're not dragging. This also prevents
1140 // us from intercepting events that don't belong to us from the
1141 // parent since we're Connect()ed to a couple.
1142 if( !mClicked )
1143 {
1144 return;
1145 }
1146
1147#if defined(__WXMAC__)
1148 // Disable window animation
1149 wxSystemOptions::SetOption( wxMAC_WINDOW_PLAIN_TRANSITION, 1 );
1150#endif
1151
1152 // Retrieve the event position
1153 wxPoint pos =
1154 ( (wxWindow *)event.GetEventObject() )->ClientToScreen( event.GetPosition() ) - mDragOffset;
1155
1156
1157 if( !event.LeftIsDown() )
1158 {
1159 // Button was released...finish the drag
1160 // Transition the bar to a dock
1161 if (!mDidDrag) {
1162 if (mPrevDock)
1164 DoneDragging();
1165 return;
1166 }
1167 else if( mDragDock && !event.ShiftDown() )
1168 {
1169 // Trip over...everyone ashore that's going ashore...
1171 Updated();
1173
1174 // Done with the floater
1175 mDragWindow->Destroy();
1176 mDragWindow = nullptr;
1177 mDragBar->Refresh(false);
1178 }
1179 else
1180 {
1181 // Calling SetDocked() to force the grabber button to popup
1182 mDragBar->SetDocked( NULL, false );
1183 }
1184
1185 DoneDragging();
1186 }
1187 else if( event.Dragging() && pos != mLastPos )
1188 {
1189 if (!mDidDrag) {
1190 // Must set the bar afloat if it's currently docked
1191 mDidDrag = true;
1192 wxPoint mp = event.GetPosition();
1193 mp = GetProjectFrame( *mParent ).ClientToScreen(mp);
1194 if (!mDragWindow) {
1195 // We no longer have control
1196 if (mPrevDock)
1198 UndockBar(mp);
1199 // Rearrange the remaining toolbars before trying to re-insert this one.
1201 }
1202 }
1203
1204 // Make toolbar follow the mouse
1205 mDragWindow->Move( pos );
1206
1207 // Remember to prevent excessive movement
1208 mLastPos = pos;
1209
1210 // Calc the top dock hittest rectangle
1211 wxRect tr = mTopDock->GetRect();
1212 tr.SetBottom( tr.GetBottom() + 10 );
1213 tr.SetPosition( mTopDock->GetParent()->ClientToScreen( tr.GetPosition() ) );
1214
1215 // Calc the bottom dock hittest rectangle
1216 wxRect br = mBotDock->GetRect();
1217 br.SetTop( br.GetTop() - 10 );
1218 br.SetBottom( br.GetBottom() + 20 );
1219 br.SetPosition( mBotDock->GetParent()->ClientToScreen( br.GetPosition() ) );
1220
1221
1222 // Add half the bar height. We could use the actual bar height, but that would be confusing as a
1223 // bar removed at a place might not dock back there if just let go.
1224 // Also add 5 pixels in horizontal direction, so that a click without a move (or a very small move)
1225 // lands back where we started.
1226 pos += wxPoint( 5, 20 );
1227
1228
1229 // To find which dock, rather than test against pos, test against the whole dragger rect.
1230 // This means it is enough to overlap the dock to dock with it.
1231 wxRect barRect = mDragWindow->GetRect();
1232 ToolDock *dock = NULL;
1233 if( tr.Intersects( barRect ) )
1234 dock = mTopDock;
1235 else if( br.Intersects( barRect ) )
1236 dock = mBotDock;
1237
1238 // Looks like we have a winner...
1239 if( dock )
1240 {
1241 wxPoint p;
1242 wxRect r;
1243
1244 // Calculate where the bar would be placed
1245 mDragBefore = dock->PositionBar( mDragBar, pos, r );
1246
1247 // If different than the last time, the indicator must be moved
1248 if( r != mBarPos )
1249 {
1250 wxRect dr = dock->GetRect();
1251
1252 // Hide the indicator before changing the shape
1253 mIndicator->Hide();
1254
1255 // Decide which direction the arrow should point
1256 if( r.GetTop() >= dr.GetHeight() )
1257 {
1258 const auto &box = mDown->GetBox();
1259 p.x = dr.GetLeft() + ( dr.GetWidth() / 2 )
1260 - (box.GetWidth() / 2);
1261 p.y = dr.GetBottom() - box.GetHeight();
1262 mCurrent = mDown.get();
1263 }
1264 else
1265 {
1266 // r is the rectangle of the toolbar being dragged.
1267 // A tall undocked toolbar will become at most 2 tbs
1268 // high when docked, so the triangular drop indicator
1269 // needs to use that height, h, not the bar height
1270 // for calculating where to be drawn.
1271 const int tbs = toolbarSingle + toolbarGap;
1272 int h = wxMin(r.GetHeight(), 2*tbs-1);
1273 p.x = dr.GetLeft() + r.GetLeft();
1274 p.y = dr.GetTop() + r.GetTop() +
1275 ( ( h - mLeft->GetBox().GetHeight() ) / 2 );
1276 mCurrent = mLeft.get();
1277 }
1278
1279 // Change the shape while hidden and then show it if okay
1280 mIndicator->SetShape( *mCurrent );
1281 if( !event.ShiftDown() )
1282 {
1283 mIndicator->Show();
1284 mIndicator->Update();
1285 }
1286
1287 // Move it into position
1288 // LL: Do this after the Show() since KDE doesn't move the window
1289 // if it's not shown. (Do it outside if the previous IF as well)
1290 mIndicator->Move( dock->GetParent()->ClientToScreen( p ) );
1291
1292 // Remember for next go round
1293 mBarPos = r;
1294 }
1295 }
1296 else
1297 {
1298 // Hide the indicator if it's still shown
1299 if( mBarPos.x != -1 )
1300 {
1301 // Hide any
1302 mIndicator->Hide();
1303 mBarPos.x = -1;
1304 mBarPos.y = -1;
1305 }
1306 }
1307
1308 // Remember to which dock the drag bar belongs.
1309 mDragDock = dock;
1310 }
1311
1312#if defined(__WXMAC__)
1313 // Reinstate original transition
1314 wxSystemOptions::SetOption( wxMAC_WINDOW_PLAIN_TRANSITION, mTransition );
1315#endif
1316}
1317
1318//
1319// Deal with NEW capture lost event
1320//
1321void ToolManager::OnCaptureLost( wxMouseCaptureLostEvent & event )
1322{
1323 // Can't do anything if we're not dragging. This also prevents
1324 // us from intercepting events that don't belong to us from the
1325 // parent since we're Connect()ed to a couple.
1326 if( !mDragWindow )
1327 {
1328 event.Skip();
1329 return;
1330 }
1331
1332 // Simulate button up
1333 wxMouseEvent e(wxEVT_LEFT_UP);
1334 e.SetEventObject(mParent);
1335 OnMouse(e);
1336}
1337
1339{
1341}
1342
1343//
1344// Watch for shift key changes
1345//
1346void ToolManager::OnTimer( wxTimerEvent & event )
1347{
1348 // Go ahead and set the event to propagate
1349 event.Skip();
1350
1351 // Can't do anything if we're not dragging. This also prevents
1352 // us from intercepting events that don't belong to us from the
1353 // parent since we're Connect()ed to a couple.
1354 if( !mDragWindow )
1355 {
1356 return;
1357 }
1358
1359 bool state = wxGetKeyState( WXK_SHIFT );
1360 if( mLastState != state )
1361 {
1362 mLastState = state;
1363
1364#if defined(__WXMAC__)
1365 // Disable window animation
1366 wxSystemOptions::SetOption( wxMAC_WINDOW_PLAIN_TRANSITION, 1 );
1367#endif
1368
1369 mIndicator->Show( !state );
1370
1371#if defined(__WXMAC__)
1372 // Disable window animation
1373 wxSystemOptions::SetOption( wxMAC_WINDOW_PLAIN_TRANSITION, mTransition );
1374#endif
1375 }
1376
1377 return;
1378}
1379
1380//
1381// Handle Indicator paint events
1382//
1383// Really only needed for the Mac since SetBackgroundColour()
1384// doesn't seem to work with shaped frames.
1385//
1386void ToolManager::OnIndicatorPaint( wxPaintEvent & event )
1387{
1388 // TODO: Better to use a bitmap than a triangular region.
1389 wxWindow *w = (wxWindow *)event.GetEventObject();
1390 wxPaintDC dc( w );
1391 // TODO: Better (faster) to use the existing spare brush.
1392 wxBrush brush( theTheme.Colour( clrTrackPanelText ) );
1393 dc.SetBackground( brush );
1394 dc.Clear();
1395}
1396
1397//
1398// Handle Indicator creation event
1399//
1400// Without this, the initial Indicator window will be a solid blue square
1401// until the next time it changes.
1402//
1403void ToolManager::OnIndicatorCreate( wxWindowCreateEvent & event )
1404{
1405#if defined(__WXGTK__)
1406 mIndicator->SetShape( *mCurrent );
1407#endif
1408 event.Skip();
1409}
1410
1411void ToolManager::UndockBar( wxPoint mp )
1412{
1413#if defined(__WXMAC__)
1414 // Disable window animation
1415 wxSystemOptions::SetOption( wxMAC_WINDOW_PLAIN_TRANSITION, 1 );
1416#endif
1417
1418 // Adjust the starting position
1419 mp -= mDragOffset;
1420
1421 // Inform toolbar of change
1422 mDragBar->SetDocked( NULL, true );
1424
1425 // Construct a NEW floater
1426 wxASSERT(mParent);
1428 mDragWindow->SetLayoutDirection(wxLayout_LeftToRight);
1429 // Make sure the ferry is visible
1430 mDragWindow->Show();
1431
1432 // Notify parent of change
1433 Updated();
1434
1435#if defined(__WXMAC__)
1436 // Reinstate original transition
1437 wxSystemOptions::SetOption( wxMAC_WINDOW_PLAIN_TRANSITION, mTransition );
1438#endif
1439}
1440
1441//
1442// Transition a toolbar from float to dragging
1443//
1445{
1446 // No need to propagate any further
1447 event.Skip( false );
1448
1449 if(event.IsEscaping())
1450 return HandleEscapeKey();
1451
1452 // Remember which bar we're dragging
1453 mDragBar = GetToolBar(event.BarId());
1454
1455 // Remember state, in case of ESCape key later
1456 if (mDragBar->IsDocked()) {
1457 mPrevDock = dynamic_cast<ToolDock*>(mDragBar->GetParent());
1458 wxASSERT(mPrevDock);
1461 }
1462 else
1463 mPrevPosition = mDragBar->GetParent()->GetPosition();
1464
1465 // Calculate the drag offset
1466 wxPoint mp = event.GetPosition();
1467 mDragOffset = mp -
1468 mDragBar->GetParent()->ClientToScreen( mDragBar->GetPosition() ) +
1469 wxPoint( 1, 1 );
1470
1471 mClicked = true;
1472 if( mPrevDock )
1473 {
1474 mDragWindow = nullptr;
1475 }
1476 else
1477 {
1478 mDragWindow = (ToolFrame *) mDragBar->GetParent();
1479 }
1480
1481 // We want all mouse events from this point on
1482 auto &window = GetProjectFrame( *mParent );
1483 if( !window.HasCapture() )
1484 window.CaptureMouse();
1485
1486 // Start monitoring shift key changes
1487 mLastState = wxGetKeyState( WXK_SHIFT );
1488 mTimer.Start( 100 );
1489}
1490
1491
1493{
1494 if (mDragBar) {
1495 if(mPrevDock) {
1496 // Sheriff John Stone,
1497 // Why don't you leave me alone?
1498 // Well, I feel so break up
1499 // I want to go home.
1501 mPrevDock->Dock( mDragBar, true, mPrevSlot );
1502 Updated();
1503
1504 // Done with the floater
1506 mDragWindow->Destroy();
1507 mDragWindow = nullptr;
1508 mDragBar->Refresh(false);
1509 }
1510 else {
1511 // Floater remains, and returns to where it begain
1512 auto parent = mDragBar->GetParent();
1513 parent->SetPosition(mPrevPosition);
1514 mDragBar->SetDocked(NULL, false);
1515 }
1516
1517 DoneDragging();
1518 }
1519}
1520
1522{
1523 // Done dragging - ensure grabber button isn't pushed
1524 if( mDragBar )
1525 {
1526 mDragBar->SetDocked( mDragBar->GetDock(), false );
1527 }
1528
1529 // Release capture
1530 auto &window = GetProjectFrame( *mParent );
1531 if( window.HasCapture() )
1532 {
1533 window.ReleaseMouse();
1534 }
1535
1536 // Hide the indicator
1537 mIndicator->Hide();
1538
1539 mDragWindow = NULL;
1540 mDragDock = NULL;
1541 mDragBar = NULL;
1542 mPrevDock = NULL;
1545 mLastPos.x = mBarPos.x = -1;
1546 mLastPos.y = mBarPos.y = -1;
1547 mTimer.Stop();
1548 mDidDrag = false;
1549 mClicked = false;
1550
1551 RestoreFocus();
1552}
1553
1555{
1556 if (mLastFocus) {
1557 auto temp1 = AButton::TemporarilyAllowFocus();
1558 auto temp2 = ASlider::TemporarilyAllowFocus();
1560 mLastFocus->SetFocus();
1561 return true;
1562 }
1563 return false;
1564}
1565
1567{
1568 for (auto pProject : AllProjects{}) {
1569 auto &project = *pProject;
1570 ModifyToolbarMenus(project);
1571 }
1572}
1573
1574#include "../commands/CommandManager.h"
1575#include "../ProjectSettings.h"
1577{
1578 // Refreshes can occur during shutdown and the toolmanager may already
1579 // be deleted, so protect against it.
1580 auto &toolManager = ToolManager::Get( project );
1581
1582 auto &settings = ProjectSettings::Get( project );
1583
1584 // Now, go through each toolbar, and call EnableDisableButtons()
1585 toolManager.ForEach([](auto bar){
1586 if (bar)
1587 bar->EnableDisableButtons();
1588 });
1589
1590 // These don't really belong here, but it's easier and especially so for
1591 // the Edit toolbar and the sync-lock menu item.
1592 bool active;
1593
1594 gPrefs->Read(wxT("/GUI/SyncLockTracks"), &active, false);
1595 settings.SetSyncLock(active);
1596
1597 CommandManager::Get( project ).UpdateCheckmarks( project );
1598}
1599
1601 Identifier id, const CommandID &name, const TranslatableString &label_in,
1602 const Registry::OrderingHint &hint,
1603 std::vector< Identifier > excludeIDs
1604) : mId{ id }
1605 , mAttachedItem{
1606 Registry::Placement{ wxT("View/Other/Toolbars/Toolbars/Other"), hint },
1607 ( MenuTable::FinderScope(
1609 { return *this; } ),
1610 MenuTable::Command( name, label_in,
1614 auto &toolManager = ToolManager::Get( project );
1615 return toolManager.IsVisible( id ); } ) ) ) }
1616 , mExcludeIds{ std::move( excludeIDs ) }
1617{}
1618
1620{
1621 auto &project = context.project;
1622 auto &toolManager = ToolManager::Get( project );
1623
1624 if( !toolManager.IsVisible( mId ) )
1625 {
1626 for ( const auto excludedID : mExcludeIds )
1627 toolManager.Expose( excludedID, false );
1628 }
1629
1630 toolManager.ShowHide(mId);
1631 ToolManager::Get(project).ModifyToolbarMenus(project);
1632}
wxT("CloseDown"))
END_EVENT_TABLE()
constexpr CommandFlag AlwaysEnabledFlag
Definition: CommandFlag.h:34
wxEvtHandler CommandHandlerObject
const TranslatableString name
Definition: Distortion.cpp:74
#define EVT_GRABBER(id, fn)
Definition: Grabber.h:97
EVT_COMMAND(wxID_ANY, EVT_FREQUENCYTEXTCTRL_UPDATED, LabelDialog::OnFreqUpdate) LabelDialog
Definition: LabelDialog.cpp:88
#define safenew
Definition: MemoryX.h:10
FileConfig * gPrefs
Definition: Prefs.cpp:70
static ProjectFileIORegistry::AttributeWriterEntry entry
wxFrame * FindProjectFrame(AudacityProject *project)
Get a pointer to the window associated with a project, or null if the given pointer is null,...
AUDACITY_DLL_API wxFrame & GetProjectFrame(AudacityProject &project)
Get the top-level window associated with the project (as a wxFrame only, when you do not need to use ...
accessors for certain important windows associated with each project
static const AttachedProjectObjects::RegisteredFactory manager
THEME_API Theme theTheme
Definition: Theme.cpp:82
#define toolbarSingle
Definition: ToolBar.h:59
@ ToolBarFloatMargin
Definition: ToolBar.h:67
#define toolbarGap
Definition: ToolBar.h:64
@ BotDockID
Definition: ToolDock.h:44
@ DockCount
Definition: ToolDock.h:45
@ TopDockID
Definition: ToolDock.h:43
@ NoDockID
Definition: ToolDock.h:42
static const AudacityProject::AttachedObjects::RegisteredFactory key
Methods for ToolManager.
#define sizerW
Methods for ToolFrame.
Definition: ToolManager.cpp:66
IMPLEMENT_CLASS(ToolFrame, wxFrame)
static struct DefaultConfigEntry DefaultConfigTable[]
static Settings & settings()
Definition: TrackInfo.cpp:87
int id
static TempAllowFocus TemporarilyAllowFocus()
Definition: AButton.cpp:658
static void Line(wxDC &dc, wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
Definition: AColor.cpp:187
static TempAllowFocus TemporarilyAllowFocus()
Definition: ASlider.cpp:1894
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
AudacityProject & project
void UpdateCheckmarks(AudacityProject &project)
static CommandManager & Get(AudacityProject &project)
void GetVersionKeysInit(int &major, int &minor, int &micro) const
Definition: FileConfig.h:56
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:143
virtual const wxString & GetPath() const wxOVERRIDE
Definition: FileConfig.cpp:98
virtual void SetPath(const wxString &strPath) wxOVERRIDE
Definition: FileConfig.cpp:93
static result_type Call(Arguments &&...arguments)
Null check of the installed function is done for you.
Grabber Class.
Definition: Grabber.h:48
bool IsEscaping() const
Definition: Grabber.h:75
Identifier BarId() const
Definition: Grabber.h:77
The widget to the left of a ToolBar that allows it to be dragged around to NEW positions.
Definition: Grabber.h:107
An explicitly nonlocalized string, not meant for the user to see.
Definition: Identifier.h:22
const wxString & GET() const
Explicit conversion to wxString, meant to be ugly-looking and demanding of a comment why it's correct...
Definition: Identifier.h:66
static MenuManager & Get(AudacityProject &project)
Definition: Menus.cpp:69
static TempAllowFocus TemporarilyAllowFocus()
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
Definition: Observer.h:199
static ProjectSettings & Get(AudacityProject &project)
wxColour & Colour(int iIndex)
static bool Read(ToolBarConfiguration *pConfiguration, Legacy *pLegacy, ToolBar *bar, bool &visible, bool defaultVisible)
Definition: ToolDock.cpp:281
static const Position UnspecifiedPosition
Definition: ToolDock.h:106
bool Contains(const ToolBar *bar) const
Definition: ToolDock.h:235
static void Write(const ToolBarConfiguration *pConfiguration, const ToolBar *bar)
Definition: ToolDock.cpp:355
void PostRead(Legacy &legacy)
Definition: ToolDock.cpp:334
Position Find(const ToolBar *bar) const
Definition: ToolDock.cpp:87
void Remove(const ToolBar *bar)
Definition: ToolDock.cpp:224
Works with ToolManager and ToolDock to provide a dockable window in which buttons can be placed.
Definition: ToolBar.h:74
void SetIndex(int index)
Set a value used for computing cascading positions of undocked bars.
Definition: ToolBar.h:114
virtual void EnableDisableButtons()=0
bool IsDocked() const
Definition: ToolBar.cpp:433
@ TopDockID
Definition: ToolBar.h:93
virtual void SetDocked(ToolDock *dock, bool pushed)
Definition: ToolBar.cpp:661
virtual void ReCreateButtons()
Definition: ToolBar.cpp:533
void SetVisible(bool bVisible)
Definition: ToolBar.cpp:446
bool IsResizable() const
Definition: ToolBar.cpp:425
int GetIndex() const
Get a value used for computing cascading positions of undocked bars.
Definition: ToolBar.h:112
virtual void ResizingDone()
Definition: ToolBar.h:197
ToolDock * GetDock()
Definition: ToolBar.cpp:647
bool IsPositioned()
Definition: ToolBar.h:138
void SetPositioned()
Definition: ToolBar.h:140
Identifier GetSection()
Definition: ToolBar.cpp:400
virtual bool Expose(bool show=true)
Definition: ToolBar.cpp:459
virtual void SetToDefaultSize()
Definition: ToolBar.cpp:513
virtual bool HideAfterReset() const
Default implementation returns false.
Definition: ToolBar.cpp:370
void SetPreferredNeighbors(Identifier left, Identifier top={})
Definition: ToolBar.cpp:652
virtual bool ShownByDefault() const
Whether the toolbar should be shown by default. Default implementation returns true.
Definition: ToolBar.cpp:365
virtual void Create(wxWindow *parent)
Definition: ToolBar.cpp:492
virtual wxSize GetDockedSize()
Definition: ToolBar.h:146
virtual DockID DefaultDockID() const
Which dock the toolbar defaults into. Default implementation chooses the top dock.
Definition: ToolBar.cpp:375
A dynamic panel where a ToolBar can be docked.
Definition: ToolDock.h:292
void Expose(Identifier type, bool show)
Definition: ToolDock.cpp:858
void Undock(ToolBar *bar)
Definition: ToolDock.cpp:426
void RestoreConfiguration(ToolBarConfiguration &backup)
Definition: ToolDock.cpp:848
void LoadConfig()
Definition: ToolDock.cpp:466
void WrapConfiguration(ToolBarConfiguration &backup)
Definition: ToolDock.cpp:841
ToolBarConfiguration & GetConfiguration()
Definition: ToolDock.h:311
ToolBarConfiguration::Position PositionBar(ToolBar *t, const wxPoint &pos, wxRect &rect)
Definition: ToolDock.cpp:744
void LayoutToolBars()
Definition: ToolDock.cpp:687
void Dock(ToolBar *bar, bool deflate, ToolBarConfiguration::Position ndx=ToolBarConfiguration::UnspecifiedPosition)
Definition: ToolDock.cpp:438
class ToolFrame
Definition: ToolManager.h:190
ToolFrame(AudacityProject *parent, ToolManager *manager, ToolBar *bar, wxPoint pos)
Definition: ToolManager.cpp:72
wxSize mOrigSize
Definition: ToolManager.h:236
ToolBar * mBar
Definition: ToolManager.h:234
void OnMotion(wxMouseEvent &event)
wxSize mMinSize
Definition: ToolManager.h:235
ToolManager * mManager
Definition: ToolManager.h:233
void Resize(const wxSize &size)
void OnClose(wxCloseEvent &event)
void OnGrabber(GrabberEvent &event)
void OnPaint(wxPaintEvent &WXUNUSED(event))
void OnCaptureLost(wxMouseCaptureLostEvent &WXUNUSED(event))
void LockInMinSize(ToolBar *pBar)
void ClearBar()
Definition: ToolManager.h:198
void OnToolBarUpdate(wxCommandEvent &event)
void OnKeyDown(wxKeyEvent &event)
class ToolManager
Definition: ToolManager.h:56
static ToolManager & Get(AudacityProject &project)
void OnIndicatorCreate(wxWindowCreateEvent &event)
bool IsDocked(Identifier type) const
bool mLastState
Definition: ToolManager.h:158
ToolDock * GetBotDock()
void OnMenuUpdate(struct MenuUpdateMessage)
ToolBar * mDragBar
Definition: ToolManager.h:145
static void OnResetToolBars(const CommandContext &context)
void OnGrabber(GrabberEvent &event)
void ReadConfig()
void OnCaptureLost(wxMouseCaptureLostEvent &event)
ToolDock * mTopDock
Definition: ToolManager.h:164
void OnTimer(wxTimerEvent &event)
void Expose(Identifier type, bool show)
bool mTransition
Definition: ToolManager.h:161
void ShowHide(Identifier type)
std::map< Identifier, ToolBar::Holder > mBars
map not unordered_map, for the promise made by ForEach
Definition: ToolManager.h:168
void CreateWindows()
wxPoint mPrevPosition
Definition: ToolManager.h:170
wxTimer mTimer
Definition: ToolManager.h:157
ToolDock * GetTopDock()
ToolFrame * mDragWindow
Definition: ToolManager.h:143
void WriteConfig()
int FilterEvent(wxEvent &event) override
std::unique_ptr< wxRegion > mLeft
Definition: ToolManager.h:154
void RegenerateTooltips()
void UndockBar(wxPoint mp)
Observer::Subscription mMenuManagerSubscription
Definition: ToolManager.h:139
void LayoutToolBars()
void Destroy()
AudacityProject * mParent
Definition: ToolManager.h:140
void OnIndicatorPaint(wxPaintEvent &event)
void HandleEscapeKey()
ToolBarConfiguration mPrevConfiguration
Definition: ToolManager.h:174
std::unique_ptr< wxRegion > mDown
Definition: ToolManager.h:154
ToolDock * mPrevDock
Definition: ToolManager.h:171
static void ModifyToolbarMenus(AudacityProject &project)
ToolBarConfiguration::Position mPrevSlot
Definition: ToolManager.h:173
void DoneDragging()
void ForEach(F &&fun)
Visit bars, lexicographically by their textual ids.
Definition: ToolManager.h:103
ToolDock * mDragDock
Definition: ToolManager.h:144
void OnMouse(wxMouseEvent &event)
ToolBarConfiguration::Position mDragBefore
Definition: ToolManager.h:147
bool RestoreFocus()
Destroy_ptr< wxFrame > FramePtr
Definition: ToolManager.h:152
wxRegion * mCurrent
Definition: ToolManager.h:155
wxRect mBarPos
Definition: ToolManager.h:150
ToolDock * mBotDock
Definition: ToolManager.h:165
static void ModifyAllProjectToolbarMenus()
wxWindowRef mLastFocus
Definition: ToolManager.h:141
ToolManager(AudacityProject *parent)
ToolBar * GetToolBar(const Identifier &type) const
wxPoint mDragOffset
Definition: ToolManager.h:146
FramePtr mIndicator
Definition: ToolManager.h:153
wxPoint mLastPos
Definition: ToolManager.h:149
bool IsVisible(Identifier type) const
Holds a msgid for the translation catalog; may also bind format arguments.
std::unique_ptr< CommandItem > Command(const CommandID &name, const TranslatableString &label_in, void(Handler::*pmf)(const CommandContext &), CommandFlag flags, const CommandManager::Options &options={}, CommandHandlerFinder finder=FinderScope::DefaultFinder())
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159
Definition: Menus.h:35
static RegisteredToolbarFactory factory
void OnShowToolBar(const CommandContext &context)
const std::vector< Identifier > mExcludeIds
Definition: ToolManager.h:259
const Identifier mId
Definition: ToolManager.h:257
AttachedToolBarMenuItem(Identifier id, const CommandID &name, const TranslatableString &label_in, const Registry::OrderingHint &hint={}, std::vector< Identifier > excludeIds={})
Options && CheckTest(const CheckFn &fn) &&
Identifier rightOf
Identifier barID
Identifier below
Sent when menus update (such as for changing enablement of items)
Definition: Menus.h:74
static const Functions & GetFactories()
Definition: ToolBar.cpp:1047