Audacity 3.2.0
SelectionBar.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 SelectionBar.cpp
6
7 Copyright 2005 Dominic Mazzoni
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14*******************************************************************//****************************************************************//*******************************************************************/
27
28
29
30#include "SelectionBar.h"
31
33#include "ToolManager.h"
34
35// For compilers that support precompilation, includes "wx/wx.h".
36#include <wx/wxprec.h>
37
38#include <wx/setup.h> // for wxUSE_* macros
39
40#ifndef WX_PRECOMP
41#include <wx/checkbox.h>
42#include <wx/combobox.h>
43#include <wx/settings.h>
44#include <wx/sizer.h>
45#include <wx/valtext.h>
46#include <wx/stattext.h>
47#endif
48#include <wx/statline.h>
49
50
51#include "AudioIO.h"
52#include "AColor.h"
53#include "../KeyboardCapture.h"
54#include "Prefs.h"
55#include "Project.h"
56#include "ProjectAudioIO.h"
57#include "../ProjectSettings.h"
58#include "../Snap.h"
59#include "ViewInfo.h"
60#include "QualitySettings.h"
61#include "AllThemeResources.h"
62#include "../widgets/auStaticText.h"
63
64#if wxUSE_ACCESSIBILITY
65#include "WindowAccessible.h"
66#endif
67
69
70const static wxChar *numbers[] =
71{
72 wxT("0"), wxT("1"), wxT("2"), wxT("3"), wxT("4"),
73 wxT("5"), wxT("6"), wxT("7"), wxT("8"), wxT("9")
74};
75
76enum {
81
83
88
90};
91
92BEGIN_EVENT_TABLE(SelectionBar, ToolBar)
93 EVT_SIZE(SelectionBar::OnSize)
100 EVT_IDLE( SelectionBar::OnIdle )
101 EVT_COMBOBOX(RateID, SelectionBar::OnRate)
103
104 EVT_COMMAND(wxID_ANY, EVT_TIMETEXTCTRL_UPDATED, SelectionBar::OnUpdate)
105 EVT_COMMAND(wxID_ANY, EVT_CAPTURE_KEY, SelectionBar::OnCaptureKey)
107
109{
110 return wxT("Selection");
111}
112
114: ToolBar(project, XO("Selection"), ID()),
115 mListener(NULL), mRate(0.0),
116 mStart(0.0), mEnd(0.0), mLength(0.0), mCenter(0.0), mAudio(0.0),
117 mDrive1( StartTimeID), mDrive2( EndTimeID ),
118 mSelectionMode(0),
119 mStartTime(NULL), mCenterTime(NULL), mLengthTime(NULL), mEndTime(NULL),
120 mAudioTime(NULL),
121 mChoice(NULL)
122{
123 // Make sure we have a valid rate as the NumericTextCtrl()s
124 // created in Populate()
125 // depend on it. Otherwise, division-by-zero floating point exceptions
126 // will occur.
127 // Refer to bug #462 for a scenario where the division-by-zero causes
128 // Audacity to fail.
129 // We expect mRate to be set from the project later.
131
132 // Selection mode of 0 means showing 'start' and 'end' only.
133 mSelectionMode = gPrefs->ReadLong(wxT("/SelectionToolbarMode"), 0);
134}
135
137{
138}
139
141{
142 return
143#ifdef EXPERIMENTAL_DA
144 false
145#else
146 true
147#endif
148 ;
149}
150
152{
153 return BotDockID;
154}
155
157{
158 auto &toolManager = ToolManager::Get( project );
159 return *static_cast<SelectionBar*>(toolManager.GetToolBar(ID()));
160}
161
163{
164 return Get( const_cast<AudacityProject&>( project )) ;
165}
166
167void SelectionBar::Create(wxWindow * parent)
168{
169 ToolBar::Create(parent);
170 UpdatePrefs();
171}
172
173
175 const TranslatableString & Title, wxSizer * pSizer ){
176 const auto translated = Title.Translation();
177 auStaticText * pTitle = safenew auStaticText(this, translated );
178 pTitle->SetBackgroundColour( theTheme.Colour( clrMedium ));
179 pTitle->SetForegroundColour( theTheme.Colour( clrTrackPanelText ) );
180 pSizer->Add( pTitle, 0, wxEXPAND | wxALIGN_CENTER_VERTICAL | wxRIGHT, 5 );
181
182 return pTitle;
183}
184
185
187 const TranslatableString &Name, int id, wxSizer * pSizer ){
188 auto formatName = mListener ? mListener->AS_GetSelectionFormat()
190 auto pCtrl = safenew NumericTextCtrl(
191 this, id, NumericConverter::TIME, formatName, 0.0, mRate);
192 pCtrl->SetName( Name );
193 pSizer->Add(pCtrl, 0, wxALIGN_TOP | wxRIGHT, 5);
194 return pCtrl;
195}
196
197void SelectionBar::AddVLine( wxSizer * pSizer ){
198 pSizer->Add(safenew wxStaticLine(this, -1, wxDefaultPosition,
199 wxSize(1, toolbarSingle-10),
200 wxLI_VERTICAL),
201 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
202}
203
205{
206 SetBackgroundColour( theTheme.Colour( clrMedium ) );
207
209
210 // Outer sizer has space top and left.
211 // Inner sizers have space on right only.
212 // This choice makes for a nice border and internal spacing and places clear responsibility
213 // on each sizer as to what spacings it creates.
214 wxFlexGridSizer *mainSizer = safenew wxFlexGridSizer(SIZER_COLS, 1, 1);
215 Add(mainSizer, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 5);
216
217 // Top row (mostly labels)
218 wxColour clrText = theTheme.Colour( clrTrackPanelText );
219 wxColour clrText2 = *wxBLUE;
220 auStaticText *rateLabel = AddTitle( XO("Project Rate (Hz)"), mainSizer );
221 AddVLine( mainSizer );
222 auStaticText *snapLabel = AddTitle( XO("Snap-To"), mainSizer );
223 AddVLine( mainSizer );
224#ifdef TIME_IN_SELECT_TOOLBAR
225 AddTitle( XO("Audio Position"), mainSizer );
226 AddVLine( mainSizer );
227#endif
228
229 {
230 const wxString choices[4] = {
231 _("Start and End of Selection"),
232 _("Start and Length of Selection"),
233 _("Length and End of Selection"),
234 _("Length and Center of Selection"),
235 };
236 mChoice = safenew wxChoice
237 (this, ChoiceID, wxDefaultPosition, wxDefaultSize, 4, choices,
238 0, wxDefaultValidator, _("Show"));
239 mChoice->SetSelection(0);
240#if wxUSE_ACCESSIBILITY
241 // so that name can be set on a standard control
242 mChoice->SetAccessible(safenew WindowAccessible(mChoice));
243#endif
244 mainSizer->Add(mChoice, 0, wxEXPAND | wxALIGN_TOP | wxRIGHT, 6);
245 }
246
247 // Bottom row, (mostly time controls)
248 mRateBox = safenew wxComboBox(this, RateID,
249 wxT(""),
250 wxDefaultPosition, wxDefaultSize);
251#if wxUSE_ACCESSIBILITY
252 // so that name can be set on a standard control
253 mRateBox->SetAccessible(safenew WindowAccessible(mRateBox));
254#endif
255 mRateBox->SetName(_("Project Rate (Hz)"));
256 //mRateBox->SetForegroundColour( clrText2 );
257 wxTextValidator vld(wxFILTER_INCLUDE_CHAR_LIST);
258 vld.SetIncludes(wxArrayString(10, numbers));
259 mRateBox->SetValidator(vld);
260 mRateBox->SetValue(wxString::Format(wxT("%d"), (int)mRate));
261 UpdateRates(); // Must be done _after_ setting value on mRateBox!
262
263 // We need to capture the SetFocus and KillFocus events to set up
264 // for keyboard capture. On Windows and GTK it's easy since the
265 // combobox is presented as one control to hook into.
267
268#if defined(__WXMAC__)
269 // The Mac uses a standard wxTextCtrl for the edit portion and that's
270 // the control that gets the focus events. So we have to find the
271 // textctrl.
272 wxWindowList kids = mRateBox->GetChildren();
273 for (unsigned int i = 0; i < kids.size(); i++) {
274 wxClassInfo *ci = kids[i]->GetClassInfo();
275 if (ci->IsKindOf(CLASSINFO(wxTextCtrl))) {
276 mRateText = kids[i];
277 break;
278 }
279 }
280#endif
281
282 mRateText->Bind(wxEVT_SET_FOCUS,
284 this);
285 mRateText->Bind(wxEVT_KILL_FOCUS,
287 this);
288
289 mainSizer->Add(mRateBox, 0, wxEXPAND | wxALIGN_TOP | wxRIGHT, 5);
290
291 AddVLine( mainSizer );
292
293 mSnapTo = safenew wxChoice(this, SnapToID,
294 wxDefaultPosition, wxDefaultSize,
295 transform_container< wxArrayStringEx >(
297 std::mem_fn( &TranslatableString::Translation ) ) );
298
299#if wxUSE_ACCESSIBILITY
300 // so that name can be set on a standard control
301 mSnapTo->SetAccessible(safenew WindowAccessible(mSnapTo));
302#endif
303 mSnapTo->SetName(_("Snap To"));
304 //mSnapTo->SetForegroundColour( clrText2 );
305 mSnapTo->SetSelection(mListener ? mListener->AS_GetSnapTo() : SNAP_OFF);
306
307 mSnapTo->Bind(wxEVT_SET_FOCUS,
309 this);
310 mSnapTo->Bind(wxEVT_KILL_FOCUS,
312 this);
313
314 mainSizer->Add(mSnapTo, 0, wxEXPAND | wxALIGN_TOP | wxRIGHT, 5);
315
316 AddVLine( mainSizer );
317
318#ifdef TIME_IN_SELECT_TOOLBAR
319 mAudioTime = AddTime( XO("Audio Position"), AudioTimeID, mainSizer );
320 // This vertical line is NOT just for decoration!
321 // It works around a wxWidgets-on-Windows RadioButton bug, where tabbing
322 // into the radiobutton group jumps to selecting the first item in the
323 // group even if some other item had been selected.
324 // It is an important bug to work around for screen reader users, who use TAB
325 // a lot in navigation.
326 // More about the bug here:
327 // https://forums.wxwidgets.org/viewtopic.php?t=41120
328 AddVLine( mainSizer );
329#endif
330
331 {
332 auto hSizer = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
333
334 mStartTime = AddTime( XO("Start"), StartTimeID, hSizer.get() );
335 mLengthTime = AddTime( XO("Length"), LengthTimeID, hSizer.get() );
336 mCenterTime = AddTime( XO("Center"), CenterTimeID, hSizer.get() );
337 mEndTime = AddTime( XO("End"), EndTimeID, hSizer.get() );
338 mainSizer->Add(hSizer.release(), 0, wxALIGN_TOP | wxRIGHT, 0);
339 }
340
341#if defined(__WXGTK3__)
342 // Nothing special
343#elif defined(__WXGTK__)
344 // Ensure the font fits inside (hopefully)
345 wxFont font = mChoice->GetFont();
346 font.Scale((double) toolbarSingle / mChoice->GetSize().GetHeight());
347
348 rateLabel->SetFont(font);
349 snapLabel->SetFont(font);
350 mChoice->SetFont(font);
351 mRateBox->SetFont(font);
352 mRateText->SetFont(font);
353 mSnapTo->SetFont(font);
354#endif
355
356 // Make sure they are fully expanded to the longest item
357 mChoice->SetMinSize(wxSize(mChoice->GetBestSize().x, toolbarSingle));
358 mRateBox->SetMinSize(wxSize(mRateBox->GetBestSize().x, toolbarSingle));
359 mSnapTo->SetMinSize(wxSize(mSnapTo->GetBestSize().x, toolbarSingle));
360
361 mChoice->MoveBeforeInTabOrder( mStartTime );
362 // This shows/hides controls.
363 // Do this before layout so that we are sized right.
365 mainSizer->Layout();
367 Layout();
368}
369
371{
372 // The project rate is no longer driven from here.
373 // When preferences change, the Project learns about it too.
374 // If necessary we can drive the SelectionBar mRate via the Project
375 // calling our SetRate().
376 // As of 13-Sep-2018, changes to the sample rate pref will only affect
377 // creation of new projects, not the sample rate in existing ones.
378
379 // This will only change the selection mode during a "Reset Configuration"
380 // action since the read value will be the same during a normal preferences
381 // update.
382 mSelectionMode = gPrefs->ReadLong(wxT("/SelectionToolbarMode"), 0);
383
384 // This will only change the time format during a "Reset Configuration"
385 // action since the read value will be the same during a normal preferences
386 // update.
387 wxCommandEvent e;
390 gPrefs->Read(wxT("/SelectionFormat"), wxT(""))).Internal());
391 OnUpdate(e);
392
393 // Set label to pull in language change
394 SetLabel(XO("Selection"));
395
397 // Give base class a chance
399}
400
402{
403 mListener = l;
407};
408
410{
411#if wxUSE_TOOLTIPS
412 auto formatName =
416 mSnapTo->SetToolTip(
417 wxString::Format(
418 _("Snap Clicks/Selections to %s"), formatName.Translation() ));
419#endif
420}
421
422void SelectionBar::OnSize(wxSizeEvent &evt)
423{
424 Refresh( true );
425
426 evt.Skip();
427}
428
429// When a control value is changed, this function is called.
430// It determines the values for the other controls.
431void SelectionBar::ModifySelection(int newDriver, bool done)
432{
433 // If the user moved to a different control, then update which
434 // two controls drive the others.
435 if( newDriver != mDrive2 )
436 SetDrivers( mDrive2, newDriver);
437
438 // Only update a value if user typed something in.
439 // The reason is the controls may be less accurate than
440 // the values.
441 if( newDriver == StartTimeID )
443 if( newDriver == EndTimeID )
445 if( newDriver == LengthTimeID )
447 if( newDriver == CenterTimeID )
449
450 // There are four controls, and two constraints, which are:
451 // mid = (start+end)/2
452 // length = (end-start)
453 // Therefore we can select any two controls as 'drivers' of
454 // the other two.
455 // Here we compute 'i' which combines the identity of the two
456 // driving controls, to use it as an index.
457 // The order of the two drivers generally does not matter much,
458 // except that we want:
459 // start < end
460 // and preserve that by adjusting the least dominant driving
461 // control.
462 int i = mDrive1 + 4 * mDrive2;
463 switch(i) {
464 case StartTimeID + 4 * EndTimeID:
465 if( mEnd < mStart )
466 mStart = mEnd;
467 case StartTimeID * 4 + EndTimeID:
468 if( mStart > mEnd )
469 mEnd = mStart;
470 mLength = mEnd - mStart;
471 mCenter = (mStart+mEnd)/2.0;
472 break;
473
474 case StartTimeID + 4 * LengthTimeID:
475 case StartTimeID * 4 + LengthTimeID:
477 mCenter = (mStart+mEnd)/2.0;
478 break;
479
480 case EndTimeID + 4 * LengthTimeID:
481 if( mEnd - mLength < 0 )
482 mEnd += (mLength - mEnd);
483 case EndTimeID * 4 + LengthTimeID:
484 if( mEnd - mLength < 0)
485 mLength -= (mLength - mEnd);
486 mStart = mEnd - mLength;
487 mCenter = (mStart+mEnd)/2.0;
488 break;
489
490 case LengthTimeID + 4 * CenterTimeID:
491 if( mCenter - (mLength / 2) < 0 )
492 mLength = (mCenter * 2);
493 case LengthTimeID * 4 + CenterTimeID:
494 if( mCenter - (mLength / 2) < 0 )
495 mCenter = (mLength / 2);
496 mStart = mCenter - mLength/2.0;
497 mEnd = mCenter + mLength/2.0;
498 break;
499
500 default:
501 // The above should cover all legal combinations of two distinct controls.
502 wxFAIL_MSG( "Illegal sequence of selection changes");
503 }
504
505 // Refresh the controls now
507
508 // Places the start-end markers on the track panel.
510}
511
512void SelectionBar::OnChangedTime(wxCommandEvent & event)
513{
514 ModifySelection(event.GetId(), event.GetInt() != 0);
515}
516
517// Called when one of the format drop downs is changed.
518void SelectionBar::OnUpdate(wxCommandEvent &evt)
519{
520 wxWindow *w = FindFocus();
522 int i;
523 int iFocus = -1;
524 for(i=0;i<5;i++)
525 if( w == *Ctrls[i] )
526 iFocus = i;
527
528 evt.Skip(false);
529
531
532 // Save format name before recreating the controls so they resize properly
533 if (mStartTime)
534 {
535 if (mListener)
537 }
538
539 // ReCreateButtons() will get rid of our sizers and controls
540 // so reset pointers first.
541 for( i=0;i<5;i++)
542 *Ctrls[i]=NULL;
543
544 mChoice = NULL;
545 mRateBox = NULL;
546 mRateText = NULL;
547 mSnapTo = NULL;
548
550
552
553 for( i=0;i<5;i++)
554 if( *Ctrls[i] )
555 (*Ctrls[i])->SetFormatName( format );
556
557 if( iFocus >=0 )
558 if( *Ctrls[iFocus] )
559 (*Ctrls[iFocus])->SetFocus();
560
562
563 Updated();
564}
565
566// The two drivers are the numbers of the two controls which drive the other ones.
567// The user gets to see which controls are drivers and which driven.
568void SelectionBar::SetDrivers( int driver1, int driver2 )
569{
570 mDrive1 = driver1;
571 mDrive2 = driver2;
572
574 static TranslatableString Text[4] = {
575 /* i18n-hint noun */
576 XO("Start"),
577 XO("Center"),
578 XO("Length"),
579 /* i18n-hint noun */
580 XO("End")
581 };
582
583 for(int i=0;i<4;i++){
584 int id = i + StartTimeID;
585 int fixed = (( id == mDrive2 )?mDrive1:mDrive2)-StartTimeID;
586
587 const auto &Temp = Text[i];
588 auto Title = ( (id!=mDrive1) && (id!=mDrive2 ) )
589 /* i18n-hint: %s is replaced e.g by one of 'Length', 'Center',
590 'Start', or 'End' (translated), to indicate that it will be
591 calculated from other parameters. */
592 ? XO("%s - driven").Format( Temp )
593 : Temp ;
594 auto VoiceOverText =
595 /* i18n-hint: each string is replaced by one of 'Length', 'Center',
596 'Start', or 'End' (translated) */
597 XO("Selection %s. %s won't change.").Format( Temp, Text[fixed] );
598 if( *Ctrls[i] ){
599 (*Ctrls[i])->SetName( Temp );
600 }
601 }
602}
603
604void SelectionBar::OnChoice(wxCommandEvent & WXUNUSED(event))
605{
606 int mode = mChoice->GetSelection();
607 SetSelectionMode( mode );
609}
610
611void SelectionBar::OnIdle( wxIdleEvent &evt )
612{
613 evt.Skip();
614 auto &project = mProject;
615 const auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
616
617 double audioTime;
618
619 auto &projectAudioIO = ProjectAudioIO::Get( project );
620 if ( projectAudioIO.IsAudioActive() ){
621 auto gAudioIO = AudioIO::Get();
622 audioTime = gAudioIO->GetStreamTime();
623 }
624 else {
625 const auto &playRegion = ViewInfo::Get( project ).playRegion;
626 audioTime = playRegion.GetStart();
627 }
628
629 SetTimes(selectedRegion.t0(), selectedRegion.t1(), audioTime);
630}
631
633{
634 // We just changed the mode. Remember it.
635 gPrefs->Write(wxT("/SelectionToolbarMode"), mSelectionMode);
636 gPrefs->Flush();
637
638 wxSize sz = GetMinSize();
639 sz.SetWidth( 10 );
640 SetMinSize( sz );
641 Fit();
642 Layout();
643 Updated();
644}
645
646// We used to have 8 modes which showed different combinations of the
647// length, start, end, center controls.
648// Mode 7 for example showed all four at the same time.
650{
651 // Only modes 0 to 3 are now supported,
652 // so fix up a mode that could have come from the config.
653 const int maxMode = 3;
654
655 if( mode > maxMode )
656 mode = 0;
657 if( mode < 0 )
658 mode = 0;
659 mSelectionMode = mode;
660 mChoice->SetSelection( mode );
661
662 // First decide which two controls drive the others...
663 // For example the last option is with all controls shown, and in that mode we
664 // initially have start and end driving.
667 int Drive1[] = { EndTimeID, LengthTimeID, EndTimeID, CenterTimeID,
669
670 SetDrivers( Drive1[mode], Drive2[mode] );
671 // Then show/hide the relevant controls.
672 ShowHideControls( mode );
673}
674
675// Our mode determines which controls are visible.
677{
678 // The bits in these say which controls are visible.
679 int masks[8]= {
680 9, 5, 12, 6, // 2 items shown
681 13, 7, 11,// 3 items shown
682 15};
683 int mask = masks[mode];
684
686 for(int i=0;i<4;i++){
687 if( *Ctrls[i]){
688 (*Ctrls[i])->Show( (mask & (1<<i))!=0 );
689 (*Ctrls[i])->Refresh();
690 }
691 }
692}
693
695{
697 double Values[5] = {mStart, mEnd, mLength, mCenter, mAudio };
698 int i;
699 for(i=0;i<5;i++)
700 if( *Ctrls[i] )
701 (*Ctrls[i])->SetValue( Values[i] );
702}
703
704// A time has been set. Update the control values.
705void SelectionBar::SetTimes(double start, double end, double audio)
706{
707 if ( start != mStart || end != mEnd || audio != mAudio
709 ) {
710 mStart = start;
711 mEnd = end;
712 mLength = end-start;
713 mCenter = (end+start)/2.0;
714 mAudio = audio;
716
718 }
719}
720
722{
723 mSnapTo->SetSelection(snap);
724}
725
727{
728 bool changed =
730
731 // Test first whether changed, to avoid infinite recursion from OnUpdate
732 if ( changed ) {
733 wxCommandEvent e;
734 e.SetString(format.Internal());
735 OnUpdate(e);
736 }
737}
738
739void SelectionBar::SetRate(double rate)
740{
741 if (rate != mRate) {
742 // if the rate is actually being changed
743 mRate = rate; // update the stored rate
744 mRateBox->SetValue(wxString::Format(wxT("%d"), (int)rate));
745
746 // update the TimeTextCtrls if they exist
748 int i;
749 for(i=0;i<5;i++)
750 if( *Ctrls[i] )
751 (*Ctrls[i])->SetSampleRate( rate );
752 }
753}
754
755void SelectionBar::OnRate(wxCommandEvent & WXUNUSED(event))
756{
757 auto value = mRateBox->GetValue();
758
759 if (value.ToDouble(&mRate) && // is a numeric value
760 (mRate != 0.0))
761 {
763 int i;
764 for(i=0;i<5;i++)
765 if( *Ctrls[i] )
766 (*Ctrls[i])->SetSampleRate( mRate );
768
769 mLastValidText = value;
770 }
771 else
772 {
773 // Bug 2497 - Undo paste into text box if it's not numeric
774 mRateBox->SetValue(mLastValidText);
775 }
776}
777
779{
780 wxString oldValue = mRateBox->GetValue();
781 mRateBox->Clear();
782 for (int i = 0; i < AudioIOBase::NumStandardRates; i++) {
783 mRateBox->Append(
784 wxString::Format(wxT("%d"), AudioIOBase::StandardRates[i]));
785 }
786 mRateBox->SetValue(oldValue);
787}
788
789void SelectionBar::OnFocus(wxFocusEvent &event)
790{
791 KeyboardCapture::OnFocus( *this, event );
792}
793
794void SelectionBar::OnCaptureKey(wxCommandEvent &event)
795{
796 wxKeyEvent *kevent = (wxKeyEvent *)event.GetEventObject();
797 wxWindow *w = FindFocus();
798 int keyCode = kevent->GetKeyCode();
799
800 // Convert numeric keypad entries.
801 if ((keyCode >= WXK_NUMPAD0) && (keyCode <= WXK_NUMPAD9)) {
802 keyCode -= WXK_NUMPAD0 - '0';
803 }
804
805 if (keyCode >= '0' && keyCode <= '9') {
806 return;
807 }
808
809 // UP/DOWN/LEFT/RIGHT for mRateText
810 if (w == mRateText) {
811 switch (keyCode)
812 {
813 case WXK_LEFT:
814 case WXK_RIGHT:
815 case WXK_UP:
816 case WXK_DOWN:
817 case WXK_DELETE:
818 case WXK_BACK:
819 return;
820 }
821 }
822
823 event.Skip();
824}
825
826void SelectionBar::OnSnapTo(wxCommandEvent & WXUNUSED(event))
827{
828 mListener->AS_SetSnapTo(mSnapTo->GetSelection());
829}
830
832 []( AudacityProject &project ){
833 return ToolBar::Holder{ safenew SelectionBar{ project } }; }
834};
835
836namespace {
838 /* i18n-hint: Clicking this menu item shows the toolbar
839 for selecting a time range of audio */
840 SelectionBar::ID(), wxT("ShowSelectionTB"), XXO("&Selection Toolbar")
841};
842}
843
wxT("CloseDown"))
@ Internal
Indicates internal failure from Audacity.
END_EVENT_TABLE()
int format
Definition: ExportPCM.cpp:53
XO("Cut/Copy/Paste")
XXO("&Cut/Copy/Paste Toolbar")
#define _(s)
Definition: Internat.h:73
EVT_COMMAND(wxID_ANY, EVT_FREQUENCYTEXTCTRL_UPDATED, LabelDialog::OnFreqUpdate) LabelDialog
Definition: LabelDialog.cpp:88
#define safenew
Definition: MemoryX.h:10
gPrefs Read(wxT("/GUI/VerticalZooming"), &bVZoom, false)
FileConfig * gPrefs
Definition: Prefs.cpp:70
@ SNAP_OFF
IMPLEMENT_CLASS(SelectionBar, ToolBar)
static RegisteredToolbarFactory factory
@ EndTimeID
@ RateID
@ SnapToID
@ SelectionBarFirstID
@ StartTimeID
@ OnMenuID
@ AudioTimeID
@ ChoiceID
@ CenterTimeID
@ LengthTimeID
static const wxChar * numbers[]
#define SIZER_COLS
Definition: SelectionBar.h:31
THEME_API Theme theTheme
Definition: Theme.cpp:82
#define toolbarSingle
Definition: ToolBar.h:59
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 const int StandardRates[]
Array of common audio sample rates.
Definition: AudioIOBase.h:189
static const int NumStandardRates
How many standard sample rates there are.
Definition: AudioIOBase.h:191
static AudioIO * Get()
Definition: AudioIO.cpp:147
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:143
An explicitly nonlocalized string, not meant for the user to see.
Definition: Identifier.h:22
FormatStrings GetBuiltinFormat(const int index)
static NumericFormatSymbol LookupFormat(Type type, const wxString &id)
bool SetFormatString(const FormatStrings &formatString)
double GetStart() const
Definition: ViewInfo.h:128
static ProjectAudioIO & Get(AudacityProject &project)
(not quite a Toolbar) at foot of screen for setting and viewing the selection range.
Definition: SelectionBar.h:46
void OnIdle(wxIdleEvent &evt)
NumericTextCtrl * mStartTime
Definition: SelectionBar.h:111
void SetSelectionFormat(const NumericFormatSymbol &format)
auStaticText * AddTitle(const TranslatableString &Title, wxSizer *pSizer)
NumericTextCtrl * AddTime(const TranslatableString &Name, int id, wxSizer *pSizer)
void OnRate(wxCommandEvent &event)
virtual ~SelectionBar()
void OnSnapTo(wxCommandEvent &event)
void SelectionModeUpdated()
void RegenerateTooltips() override
void SetRate(double rate)
void SetSelectionMode(int mode)
double mLength
Definition: SelectionBar.h:101
void ShowHideControls(int mode)
static Identifier ID()
NumericTextCtrl * mAudioTime
Definition: SelectionBar.h:115
wxString mLastValidText
Definition: SelectionBar.h:122
NumericTextCtrl * mLengthTime
Definition: SelectionBar.h:113
void Create(wxWindow *parent) override
void OnFocus(wxFocusEvent &event)
void OnSize(wxSizeEvent &evt)
wxComboBox * mRateBox
Definition: SelectionBar.h:118
void OnUpdate(wxCommandEvent &evt)
bool ShownByDefault() const override
Whether the toolbar should be shown by default. Default implementation returns true.
void SetListener(SelectionBarListener *l)
void AddVLine(wxSizer *pSizer)
void SetDrivers(int driver1, int driver2)
static SelectionBar & Get(AudacityProject &project)
NumericTextCtrl * mEndTime
Definition: SelectionBar.h:114
wxChoice * mChoice
Definition: SelectionBar.h:116
double mCenter
Definition: SelectionBar.h:101
void SetSnapTo(int)
void ValuesToControls()
int mLastSelectionMode
Definition: SelectionBar.h:109
void Populate() override
void OnCaptureKey(wxCommandEvent &event)
void OnChoice(wxCommandEvent &event)
SelectionBar(AudacityProject &project)
void ModifySelection(int newDriver, bool done=false)
DockID DefaultDockID() const override
Which dock the toolbar defaults into. Default implementation chooses the top dock.
void UpdatePrefs() override
NumericTextCtrl * mCenterTime
Definition: SelectionBar.h:112
wxChoice * mSnapTo
Definition: SelectionBar.h:119
wxWindow * mRateText
Definition: SelectionBar.h:120
void SetTimes(double start, double end, double audio)
SelectionBarListener * mListener
Definition: SelectionBar.h:99
void UpdateRates()
void OnChangedTime(wxCommandEvent &evt)
A parent class of SelectionBar, used to forward events to do with changes in the SelectionBar.
virtual const NumericFormatSymbol & AS_GetSelectionFormat()=0
virtual void AS_SetRate(double rate)=0
virtual void AS_ModifySelection(double &start, double &end, bool done)=0
virtual void AS_SetSnapTo(int snap)=0
virtual int AS_GetSnapTo()=0
virtual double AS_GetRate()=0
virtual void AS_SetSelectionFormat(const NumericFormatSymbol &format)=0
static const TranslatableStrings & GetSnapLabels()
Definition: Snap.cpp:320
wxColour & Colour(int iIndex)
Works with ToolManager and ToolDock to provide a dockable window in which buttons can be placed.
Definition: ToolBar.h:74
AudacityProject & mProject
Definition: ToolBar.h:248
DockID
Identifies one of the docking areas for toolbars.
Definition: ToolBar.h:92
@ BotDockID
Definition: ToolBar.h:94
void Add(wxWindow *window, int proportion=0, int flag=wxALIGN_TOP, int border=0, wxObject *userData=NULL)
Definition: ToolBar.cpp:709
virtual void ReCreateButtons()
Definition: ToolBar.cpp:533
void SetLabel(const wxString &label) override
Definition: ToolBar.cpp:408
void UpdatePrefs() override
Definition: ToolBar.cpp:622
void Updated()
Definition: ToolBar.cpp:684
virtual void Create(wxWindow *parent)
Definition: ToolBar.cpp:492
wxWindowPtr< ToolBar > Holder
Definition: ToolBar.h:78
static ToolManager & Get(AudacityProject &project)
Holds a msgid for the translation catalog; may also bind format arguments.
wxString Translation() const
PlayRegion playRegion
Definition: ViewInfo.h:220
NotifyingSelectedRegion selectedRegion
Definition: ViewInfo.h:219
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:235
An alternative to using wxWindowAccessible, which in wxWidgets 3.1.1 contained GetParent() which was ...
is like wxStaticText, except it can be themed. wxStaticText can't be.
Definition: auStaticText.h:20
void SetFocus(const WindowPlacement &focus)
Set the window that accepts keyboard input.
Definition: BasicUI.h:352
std::unique_ptr< WindowPlacement > FindFocus()
Find the window that is accepting keyboard input, if any.
Definition: BasicUI.h:343
void OnFocus(wxWindow &window, wxFocusEvent &event)
a function useful to implement a focus event handler The window releases the keyboard if the event is...
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159
PROJECT_RATE_API IntSetting DefaultSampleRate
AttachedToolBarMenuItem sAttachment