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