Audacity 3.2.0
ToolBar.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 ToolBar.cpp
6
7 Dominic Mazzoni
8 Shane T. Mueller
9 Leland Lucius
10
11 See ToolBar.h for details.
12
13*******************************************************************//*******************************************************************//**********************************************************************/
26
27
28#include "ToolBar.h"
29
30// For compilers that support precompilation, includes "wx/wx.h".
31#include <wx/wxprec.h>
32
33#include <wx/setup.h> // for wxUSE_* macros
34
35#ifndef WX_PRECOMP
36#include <wx/dcclient.h>
37#include <wx/defs.h>
38#include <wx/gdicmn.h>
39#include <wx/settings.h>
40#include <wx/sizer.h>
41#include <wx/sysopt.h>
42#include <wx/window.h>
43#endif /* */
44
45#include "ToolDock.h"
46
47#include "AllThemeResources.h"
48#include "AColor.h"
49#include "ImageManipulation.h"
50#include "Project.h"
51#include "CommandManager.h"
52#include "../widgets/AButton.h"
53#include "../widgets/Grabber.h"
54#include "Prefs.h"
55
59
60//
61// Width of the resize grab area
62//
63#define RWIDTH 4
64
68class ToolBarResizer final : public wxWindow
69{
70public:
72 virtual ~ToolBarResizer();
73
74 // We don't need or want to accept focus.
75 // Note that AcceptsFocusFromKeyboard() is overridden rather than
76 // AcceptsFocus(), so that resize can be cancelled by ESC
77 bool AcceptsFocusFromKeyboard() const override {return false;}
78
79private:
80 void OnErase(wxEraseEvent & event);
81 void OnPaint(wxPaintEvent & event);
82 void OnLeftDown(wxMouseEvent & event);
83 void OnLeftUp(wxMouseEvent & event);
84 void OnEnter(wxMouseEvent & event);
85 void OnLeave(wxMouseEvent & event);
86 void OnMotion(wxMouseEvent & event);
87 void ResizeBar(const wxSize &size);
88 void OnCaptureLost(wxMouseCaptureLostEvent & event);
89 void OnKeyDown(wxKeyEvent &event);
90
91private:
94 wxSize mOrigSize;
95 wxWindowRef mOrigFocus{};
96
97 DECLARE_EVENT_TABLE()
98};
99
100//
101// Event table
102//
103BEGIN_EVENT_TABLE( ToolBarResizer, wxWindow )
104 EVT_ERASE_BACKGROUND( ToolBarResizer::OnErase )
105 EVT_PAINT( ToolBarResizer::OnPaint )
106 EVT_LEFT_DOWN( ToolBarResizer::OnLeftDown )
107 EVT_LEFT_UP( ToolBarResizer::OnLeftUp )
108 EVT_ENTER_WINDOW( ToolBarResizer::OnEnter )
109 EVT_LEAVE_WINDOW( ToolBarResizer::OnLeave )
110 EVT_MOTION( ToolBarResizer::OnMotion )
111 EVT_MOUSE_CAPTURE_LOST( ToolBarResizer::OnCaptureLost )
112 EVT_KEY_DOWN( ToolBarResizer::OnKeyDown )
114
116: wxWindow(bar, wxID_ANY, wxDefaultPosition, wxSize(RWIDTH, -1))
117{
118 mBar = bar;
119 SetCursor( wxCURSOR_SIZEWE );
120}
121
123{
124 if(HasCapture())
125 ReleaseMouse();
126}
127
128//
129// Handle background erasure
130//
131void ToolBarResizer::OnErase( wxEraseEvent & WXUNUSED(event) )
132{
133 // Ignore it to prevent flashing
134}
135
136//
137// This draws the background of a toolbar
138//
139void ToolBarResizer::OnPaint( wxPaintEvent & event )
140{
141 wxPaintDC dc( (wxWindow *) event.GetEventObject() );
142
143 // Start with a clean background
144 //
145 // Under GTK, we specifically set the toolbar background to the background
146 // colour in the system theme.
147#if defined( __WXGTK__ )
148// dc.SetBackground( wxBrush( wxSystemSettings::GetColour( wxSYS_COLOUR_BACKGROUND ) ) );
149#endif
150 dc.SetBackground( wxBrush( theTheme.Colour( clrMedium ) ) );
151 dc.Clear();
152
153 wxSize sz = GetSize();
154
155 AColor::Dark( &dc, false );
156 AColor::Line(dc, sz.x - 4, 0, sz.x - 4, sz.y );
157 AColor::Line(dc, sz.x - 1, 0, sz.x - 1, sz.y );
158}
159
160//
161// Handle toolbar resizing
162//
163void ToolBarResizer::OnLeftDown( wxMouseEvent & event )
164{
165 // Go ahead and set the event to propagate
166 event.Skip();
167
168 // Retrieve the mouse position
169 // Bug 1896: This is at time of processing the event, rather than at time
170 // of generation of event. Works around event.GetPosition() giving
171 // incorrect values if position of resizer is changing.
172 mResizeOffset = wxGetMousePosition()-mBar->GetRect().GetBottomRight();
173
174 mOrigSize = mBar->GetSize();
175
176 // We want all of the mouse events
177 if( !HasCapture() )
178 CaptureMouse();
179}
180
181void ToolBarResizer::OnLeftUp( wxMouseEvent & event )
182{
183 // Go ahead and set the event to propagate
184 event.Skip();
185
186 if( HasCapture() )
187 {
188 ReleaseMouse();
189 if (mOrigFocus)
190 mOrigFocus->SetFocus();
191 mOrigFocus = nullptr;
193 }
194}
195
196void ToolBarResizer::OnEnter( wxMouseEvent & /*event*/ )
197{
198 // Bug 1201: On Mac, unsetting and re-setting the tooltip may be needed
199 // to make it pop up when we want it.
200 const auto text = GetToolTipText();
201 UnsetToolTip();
202 SetToolTip(text);
203 if (!mOrigFocus)
205}
206
207void ToolBarResizer::OnLeave( wxMouseEvent & /*event*/ )
208{
209 if (!GetCapture())
210 mOrigFocus = nullptr;
211}
212
213void ToolBarResizer::OnMotion( wxMouseEvent & event )
214{
215 // Go ahead and set the event to propagate
216 event.Skip();
217
218 if( HasCapture() && event.Dragging() )
219 {
220 // Retrieve the mouse position
221 // Bug 1896: This is at time of processing the event, rather than at time
222 // of generation of event. Works around event.GetPosition() giving
223 // incorrect values if position of resizer is changing.
224 wxPoint pos = wxGetMousePosition();
225
226 wxRect r = mBar->GetRect();
227 wxSize minsz = mBar->GetMinSize();
228 wxSize maxsz = mBar->GetMaxSize();
229 wxSize psz = mBar->GetParent()->GetClientSize();
230
231 // Adjust the size based on updated mouse position.
232 r.width = ( pos.x - mResizeOffset.x ) - r.x;
233
234 // Keep it within max size, if specified
235 if( maxsz != wxDefaultSize )
236 {
237 if( r.width > maxsz.x )
238 {
239 r.width = maxsz.x;
240 }
241 if( r.height > maxsz.y )
242 {
243 r.height = maxsz.y;
244 }
245 }
246
247 // Constrain
248 if( r.width < minsz.x )
249 {
250 // Don't allow resizing to go too small
251 r.width = minsz.x;
252 }
253 else if( r.GetRight() > psz.x - 3 )
254 {
255 // Don't allow resizing to go too large
256 //
257 // The 3 magic pixels are because I'm too chicken to change the
258 // calculations in ToolDock::LayoutToolBars() even though I'm
259 // the one that set them up. :-)
260 r.SetRight( psz.x - 3 );
261 }
262
263 ResizeBar( r.GetSize() );
264 }
265}
266
268{
269 mBar->SetSize( size );
270
271 // Tell everyone we've changed sizes
272 mBar->Updated();
273
274 // Refresh our world
275 mBar->GetParent()->Refresh();
276 mBar->GetParent()->Update();
277}
278
279void ToolBarResizer::OnCaptureLost( wxMouseCaptureLostEvent & WXUNUSED(event) )
280{
281 if( HasCapture() )
282 {
283 ReleaseMouse();
284 if (mOrigFocus)
285 mOrigFocus->SetFocus();
286 mOrigFocus = nullptr;
287 }
288}
289
290void ToolBarResizer::OnKeyDown(wxKeyEvent &event)
291{
292 event.Skip();
293 if (HasCapture() && WXK_ESCAPE == event.GetKeyCode()) {
295 ReleaseMouse();
296 if (mOrigFocus)
297 mOrigFocus->SetFocus();
298 mOrigFocus = nullptr;
299 }
300}
301
305
306//
307// Define class to RTTI
308//
310
311//
312// Custom event
313//
314DEFINE_EVENT_TYPE(EVT_TOOLBAR_UPDATED)
315
316//
317// Event table
318//
319BEGIN_EVENT_TABLE( ToolBar, wxPanelWrapper )
320 EVT_PAINT( ToolBar::OnPaint )
321 EVT_ERASE_BACKGROUND( ToolBar::OnErase )
322 EVT_MOUSE_EVENTS( ToolBar::OnMouseEvents )
324
325//
326// Constructor
327//
330 const Identifier &section,
331 bool resizable )
333, mProject{ project }
334{
335 // Save parameters
336 mLabel = label;
337 mSection = section;
338 mResizable = resizable;
339
340 // Initialize everything
341 mParent = NULL;
342 mHSizer = NULL;
343 mVisible = false;
344 mPositioned = false;
345
346 mGrabber = NULL;
347 mResizer = NULL;
348}
349
350//
351// Destructor
352//
354{
355}
356
358{
359 for(auto& child : GetChildren())
360 if(child->AcceptsFocusFromKeyboard())
361 return true;
362 return false;
363}
364
366{
367 return true;
368}
369
371{
372 return false;
373}
374
376{
377 return TopDockID;
378}
379
380//
381// Returns the toolbar title
382//
384{
385 /* i18n-hint: %s will be replaced by the name of the kind of toolbar.*/
386 return XO("Audacity %s Toolbar").Format( GetLabel() );
387}
388
389//
390// Returns the toolbar label
391//
393{
394 return mLabel;
395}
396
397//
398// Returns the toolbar preferences section
399//
401{
402 return mSection;
403}
404
405//
406// Set the toolbar label
407//
408void ToolBar::SetLabel(const wxString & label)
409{
410 // Probably shouldn't reach this overload, but perhaps virtual function
411 // dispatch will take us here from a pointer to the wxPanel base class
412 mLabel = Verbatim( label );
413}
414
416{
417 // Only this overload is publicly accessible when you have a pointer to
418 // Toolbar or a subclass of it
419 mLabel = label;
420}
421
422//
423// Returns whether the toolbar is resizable or not
424//
426{
427 return mResizable;
428}
429
430//
431// Returns the dock state of the toolbar
432//
434{
435 return const_cast<ToolBar*>(this)->GetDock() != nullptr;
436}
437
438//
439// Returns the visibility of the toolbar
440//
442{
443 return mVisible;
444}
445
446void ToolBar::SetVisible( bool bVisible )
447{
448 mVisible = bVisible;
449}
450
451std::pair<Identifier, Identifier> ToolBar::PreferredNeighbors() const noexcept
452{
454}
455
456//
457// Show or hide the toolbar
458//
459bool ToolBar::Expose( bool show )
460{
461 bool was = mVisible;
462
463 SetVisible( show );
464
465 if( IsDocked() )
466 {
467 Show( show );
468 if( show )
469 {
470 Refresh();
471 }
472 }
473 else
474 {
475 wxWindow * pParent = GetParent();
476 if( !IsPositioned() && show ){
478 pParent->CentreOnParent();
479 // Cascade the undocked bars
480 pParent->Move( pParent->GetPosition() +
481 wxSize{ mIndex * 10, mIndex * 10 });
482 }
483 pParent->Show( show );
484 }
485
486 return was;
487}
488
489//
490// Initialize the toolbar
491//
492void ToolBar::Create( wxWindow *parent )
493{
494 // Save parameters
495 mParent = parent;
496
497 // Create the window and label it
499 wxID_ANY,
500 wxDefaultPosition,
501 wxDefaultSize,
502 wxNO_BORDER | wxTAB_TRAVERSAL,
503 GetTitle() );
505
506 // Go do the rest of the creation
508
509 // ToolManager depends on this appearing to be visible for proper dock construction
510 mVisible = true;
511}
512
514 wxSize sz;
515 sz.SetHeight( -1 );
516 sz.SetWidth( GetInitialWidth());
517 SetSize( sz );
518}
519
521{
522 const int tbs = toolbarSingle + toolbarGap;
523 wxSize sz = GetSize();
524 // 46 is the size where we switch from expanded to compact.
525 if( sz.y < 46 )
526 sz.y = tbs-1;
527 else
528 sz.y = 2 * tbs -1;
529 return sz;
530}
531
532
534{
535 wxSize sz3 = GetSize();
536 //wxLogDebug( "x:%i y:%i",sz3.x, sz3.y);
537
538 // SetSizer(NULL) detaches mHSizer and deletes it.
539 // Do not use Detach() here, as that attempts to detach mHSizer from itself!
540 SetSizer( NULL );
541
542 // Get rid of any children we may have
543 DestroyChildren();
544 mGrabber = NULL;
545 mResizer = NULL;
546 SetLayoutDirection(wxLayout_LeftToRight);
547
548 // Refresh the background before populating
549 if (!IsDocked())
550 {
551 GetParent()->Refresh();
552 }
553
554 {
555 // Create the main sizer
556 auto ms = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
557
558 // Create the grabber and add it to the main sizer
560 ms->Add(mGrabber, 0, wxEXPAND | wxALIGN_LEFT | wxALIGN_TOP | wxRIGHT, 1);
561
562 // Use a box sizer for laying out controls
563 ms->Add((mHSizer = safenew wxBoxSizer(wxHORIZONTAL)), 1, wxEXPAND);
564
565 // Go add all the rest of the gadgets
566 Populate();
567
568 // Add some space for the resize border
569 if (IsResizable())
570 {
571 // Create the resizer and add it to the main sizer
573 ms->Add(mResizer, 0, wxEXPAND | wxALIGN_TOP | wxLEFT, 1);
574 mResizer->SetToolTip(_("Click and drag to resize toolbar"));
575 }
576
577 // Set dock after possibly creating resizer.
578 // (Re)Establish dock state
579 SetDocked(GetDock(), false);
580
581 // Set the sizer
582 SetSizerAndFit(ms.release());
583 }
584
585 // Recalculate the height to be a multiple of toolbarSingle
586 const int tbs = toolbarSingle + toolbarGap;
587 wxSize sz = GetSize();
588 sz.y = ( ( ( sz.y + tbs -1) / tbs ) * tbs ) - 1;
589
590 // Set the true AND minimum sizes and do final layout
591 if(IsResizable())
592 {
593 // JKC we're going to allow all resizable toolbars to be resized
594 // to 1 unit high, typically 27 pixels.
595 wxSize sz2 = sz;
596 sz2.SetWidth(GetMinToolbarWidth());
597 sz2.y = tbs -1;
598 SetMinSize(sz2);
599
600 // sz2 is now the minimum size.
601 // sz3 is the size we were.
602
603 // We're recreating buttons, and we want to preserve original size.
604 // But not if that makes the size too small.
605
606 // Size at least as big as minimum.
607 if( sz3.y < sz2.y )
608 sz3.y = sz2.y;
609 if( sz3.x < sz2.x )
610 sz3.x = sz2.x;
611 SetSize(sz3);
612 }
613 else
614 {
615 SetInitialSize(sz);
616 }
617 Layout();
618}
619
620// The application preferences have changed, so update any elements that may
621// depend on them.
623{
624#if wxUSE_TOOLTIPS
625 // Change the tooltip of the grabber
626 if ( mGrabber )
627 {
629 }
630
631 // Change the tooltip of the resizer
632 if ( mResizer )
633 {
634 mResizer->SetToolTip( _("Click and drag to resize toolbar") );
635 wxSizeEvent e;
636 GetParent()->GetEventHandler()->AddPendingEvent( e );
637 GetParent()->Refresh();
638 }
639#endif
640
641 return;
642}
643
644//
645// Return the pointer to the ToolBock where this bar lives
646//
648{
649 return dynamic_cast<ToolDock*>(GetParent());
650}
651
653{
656}
657
658//
659// Toggle the docked/floating state
660//
661void ToolBar::SetDocked( ToolDock *dock, bool pushed )
662{
663 // Remember it
664// mDock = dock;
665
666 // Change the tooltip of the grabber
667#if wxUSE_TOOLTIPS
669#endif
670
671 // Set the grabber button state
672 mGrabber->PushButton( pushed );
673
674 if (mResizer)
675 {
676 mResizer->Show(dock != NULL);
677 Layout();
678 }
679}
680
681//
682// Notify parent of changes
683//
685{
686 if( IsDocked() )
687 GetDock()->Updated();
688 else
689 // Bug 2120. Changing the choice also changes the size of the toolbar so
690 // we need to update the client size, even if undocked.
691 // If modifying/improving this, remember to test both changing the choice,
692 // and clicking on the choice but not actually changing it.
693 GetParent()->SetClientSize( GetSize() + wxSize( 2,2));
694 //wxCommandEvent e( EVT_TOOLBAR_UPDATED, GetId() );
695 //GetParent()->GetEventHandler()->AddPendingEvent( e );
696}
697
698//
699// Returns a pointer to the main sizer
700//
701wxBoxSizer *ToolBar::GetSizer()
702{
703 return mHSizer;
704}
705
706//
707// Add a window to the main sizer
708//
709void ToolBar::Add( wxWindow *window,
710 int proportion,
711 int flag,
712 int border,
713 wxObject* userData )
714{
715 mHSizer->Add( window,
716 proportion,
717 flag,
718 border,
719 userData );
720}
721
722//
723// Add a child sizer to the main sizer
724//
725void ToolBar::Add( wxSizer *sizer,
726 int proportion,
727 int flag,
728 int border,
729 wxObject* userData )
730{
731 mHSizer->Add( sizer,
732 proportion,
733 flag,
734 border,
735 userData );
736}
737
738//
739// Add some space to the main sizer
740//
741void ToolBar::Add( int width,
742 int height,
743 int proportion,
744 int flag,
745 int border,
746 wxObject* userData )
747{
748 mHSizer->Add( width,
749 height,
750 proportion,
751 flag,
752 border,
753 userData );
754}
755
756//
757// Adds a spacer to the main sizer
758//
760{
761 mHSizer->AddSpacer( size );
762}
763
764//
765// Adds a strechable spacer to the main sizer
766//
768{
769 mHSizer->AddStretchSpacer( prop );
770}
771
772//
773// Detach a window from the main sizer
774//
775void ToolBar::Detach( wxWindow *window )
776{
777 mHSizer->Detach( window );
778}
779
780//
781// Detach a child sizer from the main sizer
782//
783void ToolBar::Detach( wxSizer *sizer )
784{
785 mHSizer->Detach( sizer );
786}
787
789{
790 theTheme.ReplaceImage( eBmpOut, &theTheme.Image( eBmpIn ));
791}
792
793void ToolBar::MakeMacRecoloredImageSize(teBmps eBmpOut, teBmps eBmpIn, const wxSize& size)
794{
795 MakeMacRecoloredImage( eBmpOut, eBmpIn );
796 theTheme.Image( eBmpOut ).Rescale( size.GetWidth(), size.GetHeight() );
797}
798
800{
801 // Don't recolour the buttons...
802 MakeMacRecoloredImage( eBmpOut, eBmpIn );
803}
804
805void ToolBar::MakeRecoloredImageSize(teBmps eBmpOut, teBmps eBmpIn, const wxSize& size)
806{
807 MakeRecoloredImage( eBmpOut, eBmpIn );
808 theTheme.Image( eBmpOut ).Rescale( size.GetWidth(), size.GetHeight() );
809}
810
812{
813
814 bool bUseAqua = false;
815
816#ifdef EXPERIMENTAL_THEME_PREFS
817 gPrefs->Read( wxT("/GUI/ShowMac"), &bUseAqua, false);
818#endif
819
820#ifdef USE_AQUA_THEME
821 bUseAqua = !bUseAqua;
822#endif
823
824 if( bUseAqua ){
825 MakeMacRecoloredImage( bmpRecoloredUpLarge, bmpMacUpButton );
826 MakeMacRecoloredImage( bmpRecoloredDownLarge, bmpMacDownButton );
827 MakeMacRecoloredImage( bmpRecoloredUpHiliteLarge, bmpMacHiliteUpButton );
828 MakeMacRecoloredImage( bmpRecoloredHiliteLarge, bmpMacHiliteButton );
829 } else {
830 MakeRecoloredImage( bmpRecoloredUpLarge, bmpUpButtonLarge );
831 MakeRecoloredImage( bmpRecoloredDownLarge, bmpDownButtonLarge );
832 MakeRecoloredImage( bmpRecoloredUpHiliteLarge, bmpHiliteUpButtonLarge );
833 MakeRecoloredImage( bmpRecoloredHiliteLarge, bmpHiliteButtonLarge );
834 }
835}
836
838{
839
840 bool bUseAqua = false;
841
842#ifdef EXPERIMENTAL_THEME_PREFS
843 gPrefs->Read( wxT("/GUI/ShowMac"), &bUseAqua, false);
844#endif
845
846#ifdef USE_AQUA_THEME
847 bUseAqua = !bUseAqua;
848#endif
849
850 if( bUseAqua ){
851 MakeMacRecoloredImage( bmpRecoloredUpSmall, bmpMacUpButtonSmall );
852 MakeMacRecoloredImage( bmpRecoloredDownSmall, bmpMacDownButtonSmall );
853 MakeMacRecoloredImage( bmpRecoloredUpHiliteSmall, bmpMacHiliteUpButtonSmall );
854 MakeMacRecoloredImage( bmpRecoloredHiliteSmall, bmpMacHiliteButtonSmall );
855 } else {
856 MakeRecoloredImage( bmpRecoloredUpSmall, bmpUpButtonSmall );
857 MakeRecoloredImage( bmpRecoloredDownSmall, bmpDownButtonSmall );
858 MakeRecoloredImage( bmpRecoloredUpHiliteSmall, bmpHiliteUpButtonSmall );
859 MakeRecoloredImage( bmpRecoloredHiliteSmall, bmpHiliteButtonSmall );
860 }
861}
862
875AButton * ToolBar::MakeButton(wxWindow *parent,
876 teBmps eUp,
877 teBmps eDown,
878 teBmps eHilite,
879 teBmps eDownHi,
880 teBmps eStandardUp,
881 teBmps eStandardDown,
882 teBmps eDisabled,
883 wxWindowID id,
884 wxPoint placement,
885 bool processdownevents,
886 wxSize size)
887{
888 // wxMax to cater for case of image being bigger than the button.
889 int xoff = wxMax( 0, (size.GetWidth() - theTheme.Image(eStandardUp).GetWidth())/2);
890 int yoff = wxMax( 0, (size.GetHeight() - theTheme.Image(eStandardUp).GetHeight())/2);
891
892 typedef std::unique_ptr<wxImage> wxImagePtr;
893 wxImagePtr up2 (OverlayImage(eUp, eStandardUp, xoff, yoff));
894 wxImagePtr hilite2 (OverlayImage(eHilite, eStandardUp, xoff, yoff));
895 wxImagePtr down2 (OverlayImage(eDown, eStandardDown, xoff + 1, yoff + 1));
896 wxImagePtr downHi2 (OverlayImage(eDownHi, eStandardDown, xoff + 1, yoff + 1));
897 wxImagePtr disable2 (OverlayImage(eUp, eDisabled, xoff, yoff));
898
899 wxASSERT(parent); // to justify safenew
900 AButton * button =
901 safenew AButton(parent, id, placement, size, *up2, *hilite2, *down2, *downHi2,
902 *disable2, processdownevents);
903
904 return button;
905}
906
907// This is a convenience function that allows for button creation in
908// MakeButtons() with fewer arguments
917 teBmps eEnabledUp,
918 teBmps eEnabledDown,
919 teBmps eDisabled,
920 int id,
921 bool processdownevents,
923{
924 AButton *r = ToolBar::MakeButton(parent,
925 bmpRecoloredUpLarge, bmpRecoloredDownLarge, bmpRecoloredUpHiliteLarge, bmpRecoloredHiliteLarge,
926 eEnabledUp, eEnabledDown, eDisabled,
927 wxWindowID( id ),
928 wxDefaultPosition, processdownevents,
929 theTheme.ImageSize( bmpRecoloredUpLarge ));
930 r->SetLabel( label );
931 enum {
932 deflation =
933#ifdef __WXMAC__
934 6
935#else
936 12
937#endif
938 };
939 r->SetFocusRect( r->GetClientRect().Deflate( deflation, deflation ) );
940
941 return r;
942}
943
944//static
946 teBmps eUp,
947 teBmps eDown,
948 teBmps eHilite,
949 teBmps eDownHi,
950 teBmps eStandardUp,
951 teBmps eStandardDown,
952 teBmps eDisabled,
953 wxSize size)
954{
955 // wxMax to cater for case of image being bigger than the button.
956 int xoff = wxMax( 0, (size.GetWidth() - theTheme.Image(eStandardUp).GetWidth())/2);
957 int yoff = wxMax( 0, (size.GetHeight() - theTheme.Image(eStandardUp).GetHeight())/2);
958
959 typedef std::unique_ptr<wxImage> wxImagePtr;
960 wxImagePtr up (OverlayImage(eUp, eStandardUp, xoff, yoff));
961 wxImagePtr hilite (OverlayImage(eHilite, eStandardUp, xoff, yoff));
962 wxImagePtr down (OverlayImage(eDown, eStandardDown, xoff + 1, yoff + 1));
963 wxImagePtr downHi (OverlayImage(eDownHi, eStandardDown, xoff + 1, yoff + 1));
964 wxImagePtr disable (OverlayImage(eUp, eDisabled, xoff, yoff));
965
966 button.SetAlternateImages(idx, *up, *hilite, *down, *downHi, *disable);
967}
968
970(AudacityProject &theProject,
971 AButton &button, const ComponentInterfaceSymbol commands[], size_t nCommands)
972{
973 TranslatableString result;
974 const auto project = &theProject;
975 const auto commandManager =
976 project ? &CommandManager::Get( *project ) : nullptr;
977 if (commandManager)
978 result =
979 commandManager->DescribeCommandsAndShortcuts(commands, nCommands);
980 button.SetToolTip( result );
981}
982
983//
984// This changes the state a button (from up to down or vice versa)
985//
986void ToolBar::SetButton( bool down, AButton * button )
987{
988 if( down )
989 {
990 button->PushDown();
991 }
992 else
993 {
994 button->PopUp();
995 }
996}
997
998//
999// Handle background erasure
1000//
1001void ToolBar::OnErase( wxEraseEvent & WXUNUSED(event) )
1002{
1003 // Ignore it to prevent flashing
1004}
1005
1006//
1007// This draws the background of a toolbar
1008//
1009void ToolBar::OnPaint( wxPaintEvent & WXUNUSED(event) )
1010{
1011 wxPaintDC dc( this );
1012
1013 // Themed background colour.
1014 dc.SetBackground( wxBrush( theTheme.Colour( clrMedium ) ) );
1015 dc.Clear();
1016
1017 Repaint( &dc );
1018}
1019
1020void ToolBar::OnMouseEvents(wxMouseEvent &event)
1021{
1022 // Do this hack so scrubber can detect mouse drags anywhere
1023 event.ResumePropagation(wxEVENT_PROPAGATE_MAX);
1024 event.Skip();
1025}
1026
1028{
1029 return RWIDTH;
1030}
1031
1032namespace {
1033
1035{
1036 static RegisteredToolbarFactory::Functions factories;
1037 return factories;
1038}
1039
1040}
1041
1043{
1044 GetFunctions().emplace_back(function);
1045}
1046
1048{
1049 return GetFunctions();
1050}
wxT("CloseDown"))
DEFINE_EVENT_TYPE(EVT_FREQWINDOW_RECALC)
XO("Cut/Copy/Paste")
std::unique_ptr< wxImage > OverlayImage(wxImage *background, wxImage *foreground, wxImage *mask, int xoff, int yoff)
int teBmps
#define _(s)
Definition: Internat.h:73
#define safenew
Definition: MemoryX.h:9
audacity::BasicSettings * gPrefs
Definition: Prefs.cpp:68
TranslatableString label
Definition: TagsEditor.cpp:165
const auto project
THEME_API Theme theTheme
Definition: Theme.cpp:82
END_EVENT_TABLE()
IMPLEMENT_CLASS(ToolBar, wxPanelWrapper)
Methods for ToolBar.
#define RWIDTH
ToolBarResizer.
Definition: ToolBar.cpp:63
#define toolbarSingle
Definition: ToolBar.h:59
#define toolbarGap
Definition: ToolBar.h:64
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
static std::once_flag flag
A wxButton with mouse-over behaviour.
Definition: AButton.h:104
void PushDown()
Definition: AButton.cpp:577
void SetToolTip(const TranslatableString &toolTip)
Definition: AButton.cpp:184
void SetFocusRect(const wxRect &r)
Definition: AButton.cpp:249
void PopUp()
Definition: AButton.cpp:585
void SetAlternateImages(unsigned idx, const wxImage &up, const wxImage &over, const wxImage &down, const wxImage &overDown, const wxImage &dis)
Definition: AButton.cpp:210
void SetLabel(const TranslatableString &label)
Definition: AButton.cpp:189
static void Line(wxDC &dc, wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
Definition: AColor.cpp:187
static void Dark(wxDC *dc, bool selected, bool highlight=false)
Definition: AColor.cpp:435
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
static CommandManager & Get(AudacityProject &project)
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
The widget to the left of a ToolBar that allows it to be dragged around to NEW positions.
Definition: Grabber.h:107
void SetToolTip(const TranslatableString &toolTip)
Definition: Grabber.cpp:109
void PushButton(bool state)
Definition: Grabber.cpp:187
An explicitly nonlocalized string, not meant for the user to see.
Definition: Identifier.h:22
wxColour & Colour(int iIndex)
wxImage & Image(int iIndex)
void ReplaceImage(int iIndex, wxImage *pImage)
wxSize ImageSize(int iIndex)
Works with ToolManager and ToolDock to provide a dockable window in which buttons can be placed.
Definition: ToolBar.h:74
Identifier mPreferredTopNeighbor
Definition: ToolBar.h:263
Identifier mSection
Definition: ToolBar.h:250
virtual ~ToolBar()
Definition: ToolBar.cpp:353
static void MakeAlternateImages(AButton &button, int idx, teBmps eUp, teBmps eDown, teBmps eHilite, teBmps eDownHi, teBmps eStandardUp, teBmps eStandardDown, teBmps eDisabled, wxSize size)
Definition: ToolBar.cpp:945
friend class ToolBarResizer
Definition: ToolBar.h:274
bool mVisible
Definition: ToolBar.h:265
bool IsDocked() const
Definition: ToolBar.cpp:433
virtual void Populate()=0
wxSize GetSmartDockedSize()
Definition: ToolBar.cpp:520
static void MakeRecoloredImageSize(teBmps eBmpOut, teBmps eBmpIn, const wxSize &size)
Definition: ToolBar.cpp:805
wxWindow * mParent
Definition: ToolBar.h:255
DockID
Identifies one of the docking areas for toolbars.
Definition: ToolBar.h:92
@ TopDockID
Definition: ToolBar.h:93
static void MakeMacRecoloredImage(teBmps eBmpOut, teBmps eBmpIn)
Definition: ToolBar.cpp:788
void Add(wxWindow *window, int proportion=0, int flag=wxALIGN_TOP, int border=0, wxObject *userData=NULL)
Definition: ToolBar.cpp:709
Identifier mPreferredLeftNeighbor
Definition: ToolBar.h:262
std::pair< Identifier, Identifier > PreferredNeighbors() const noexcept
Defaults to (NoBarID, NoBarId)
Definition: ToolBar.cpp:451
virtual void SetDocked(ToolDock *dock, bool pushed)
Definition: ToolBar.cpp:661
virtual int GetMinToolbarWidth()
Definition: ToolBar.h:145
virtual void ReCreateButtons()
Definition: ToolBar.cpp:533
static AButton * MakeButton(wxWindow *parent, teBmps eUp, teBmps eDown, teBmps eHilite, teBmps eDownHi, teBmps eStandardUp, teBmps eStandardDown, teBmps eDisabled, wxWindowID id, wxPoint placement, bool processdownevents, wxSize size)
Definition: ToolBar.cpp:875
void SetVisible(bool bVisible)
Definition: ToolBar.cpp:446
TranslatableString mLabel
Definition: ToolBar.h:249
bool IsResizable() const
Definition: ToolBar.cpp:425
void AddSpacer(int size=14)
Definition: ToolBar.cpp:759
void SetLabel(const wxString &label) override
Definition: ToolBar.cpp:408
TranslatableString GetTitle()
Definition: ToolBar.cpp:383
static void MakeButtonBackgroundsLarge()
Definition: ToolBar.cpp:811
virtual void ResizingDone()
Definition: ToolBar.h:197
wxBoxSizer * mHSizer
Definition: ToolBar.h:260
ToolDock * GetDock()
Definition: ToolBar.cpp:647
void OnPaint(wxPaintEvent &event)
Definition: ToolBar.cpp:1009
bool IsPositioned()
Definition: ToolBar.h:138
void SetButton(bool down, AButton *button)
Definition: ToolBar.cpp:986
static void MakeButtonBackgroundsSmall()
Definition: ToolBar.cpp:837
void SetPositioned()
Definition: ToolBar.h:140
void AddStretchSpacer(int prop=1)
Definition: ToolBar.cpp:767
bool mResizable
Definition: ToolBar.h:266
virtual int GetInitialWidth()
Resizable toolbars should implement these.
Definition: ToolBar.h:144
Identifier GetSection()
Definition: ToolBar.cpp:400
bool IsVisible() const
Definition: ToolBar.cpp:441
virtual bool Expose(bool show=true)
Definition: ToolBar.cpp:459
wxBoxSizer * GetSizer()
Definition: ToolBar.cpp:701
virtual void SetToDefaultSize()
Definition: ToolBar.cpp:513
void UpdatePrefs() override
Definition: ToolBar.cpp:622
virtual bool HideAfterReset() const
Default implementation returns false.
Definition: ToolBar.cpp:370
int GetResizeGrabberWidth()
Returns the width in pixels of the resizer element.
Definition: ToolBar.cpp:1027
bool AcceptsFocusFromKeyboard() const override
Definition: ToolBar.cpp:357
static void MakeMacRecoloredImageSize(teBmps eBmpOut, teBmps eBmpIn, const wxSize &size)
Definition: ToolBar.cpp:793
virtual void Repaint(wxDC *dc)=0
Grabber * mGrabber
Definition: ToolBar.h:257
ToolBarResizer * mResizer
Definition: ToolBar.h:258
void SetPreferredNeighbors(Identifier left, Identifier top={})
Definition: ToolBar.cpp:652
void Updated()
Definition: ToolBar.cpp:684
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
void OnMouseEvents(wxMouseEvent &event)
Definition: ToolBar.cpp:1020
TranslatableString GetLabel()
Definition: ToolBar.cpp:392
void Detach(wxWindow *window)
Definition: ToolBar.cpp:775
void OnErase(wxEraseEvent &event)
Definition: ToolBar.cpp:1001
virtual DockID DefaultDockID() const
Which dock the toolbar defaults into. Default implementation chooses the top dock.
Definition: ToolBar.cpp:375
static void SetButtonToolTip(AudacityProject &project, AButton &button, const ComponentInterfaceSymbol commands[], size_t nCommands)
Definition: ToolBar.cpp:970
static void MakeRecoloredImage(teBmps eBmpOut, teBmps eBmpIn)
Definition: ToolBar.cpp:799
a wxWindow that provides the resizer for a toolbar on the right hand side. Responsible for drawing th...
Definition: ToolBar.cpp:69
ToolBar * mBar
Definition: ToolBar.cpp:92
wxWindowRef mOrigFocus
Definition: ToolBar.cpp:95
ToolBarResizer(ToolBar *mBar)
Definition: ToolBar.cpp:115
void OnLeave(wxMouseEvent &event)
Definition: ToolBar.cpp:207
bool AcceptsFocusFromKeyboard() const override
Definition: ToolBar.cpp:77
void OnMotion(wxMouseEvent &event)
Definition: ToolBar.cpp:213
virtual ~ToolBarResizer()
Definition: ToolBar.cpp:122
void OnCaptureLost(wxMouseCaptureLostEvent &event)
Definition: ToolBar.cpp:279
void OnKeyDown(wxKeyEvent &event)
Definition: ToolBar.cpp:290
wxSize mOrigSize
Definition: ToolBar.cpp:94
void ResizeBar(const wxSize &size)
Definition: ToolBar.cpp:267
void OnLeftDown(wxMouseEvent &event)
Definition: ToolBar.cpp:163
void OnLeftUp(wxMouseEvent &event)
Definition: ToolBar.cpp:181
void OnErase(wxEraseEvent &event)
Definition: ToolBar.cpp:131
wxPoint mResizeOffset
Definition: ToolBar.cpp:93
void OnPaint(wxPaintEvent &event)
Definition: ToolBar.cpp:139
void OnEnter(wxMouseEvent &event)
Definition: ToolBar.cpp:196
A dynamic panel where a ToolBar can be docked.
Definition: ToolDock.h:292
void Updated()
Definition: ToolDock.cpp:877
Holds a msgid for the translation catalog; may also bind format arguments.
virtual bool Read(const wxString &key, bool *value) const =0
void SetLabel(const TranslatableString &label)
bool Create(wxWindow *parent, wxWindowID winid=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL|wxNO_BORDER, const TranslatableString &name=XO("Panel"))
std::unique_ptr< WindowPlacement > FindFocus()
Find the window that is accepting keyboard input, if any.
Definition: BasicUI.h:375
IMPORT_EXPORT_API ExportResult Show(ExportTask exportTask)
RegisteredToolbarFactory::Functions & GetFunctions()
Definition: ToolBar.cpp:1034
RegisteredToolbarFactory(const Function &function)
Definition: ToolBar.cpp:1042
std::vector< Function > Functions
Definition: ToolBar.h:279
std::function< ToolBar::Holder(AudacityProject &) > Function
Definition: ToolBar.h:278
static const Functions & GetFactories()
Definition: ToolBar.cpp:1047