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