Audacity  2.3.1
WaveTrackVZoomHandle.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3 Audacity: A Digital Audio Editor
4 
5 WaveTrackVZoomHandle.cpp
6 
7 Paul Licameli split from TrackPanel.cpp
8 
9 **********************************************************************/
10 
11 #include "../../../../Audacity.h"
12 #include "WaveTrackVZoomHandle.h"
13 #include "../../../../Experimental.h"
15 
16 #include "../../../../HitTestResult.h"
17 #include "../../../../NumberScale.h"
18 #include "../../../../prefs/SpectrogramSettings.h"
19 #include "../../../../prefs/WaveformSettings.h"
20 #include "../../../../Project.h"
21 #include "../../../../RefreshCode.h"
22 #include "../../../../TrackPanelMouseEvent.h"
23 #include "../../../../WaveTrack.h"
24 #include "../../../../widgets/PopupMenuTable.h"
25 #include "../../../../../images/Cursors.h"
26 #include "../../../../Prefs.h"
27 
28 namespace
29 {
30 
31 struct InitMenuData
32 {
33 public:
34  WaveTrack *pTrack;
35  wxRect rect;
36  unsigned result;
37  int yy;
38 };
39 
40 bool IsDragZooming(int zoomStart, int zoomEnd)
41 {
42  const int DragThreshold = 3;// Anything over 3 pixels is a drag, else a click.
43  bool bVZoom;
44  gPrefs->Read(wxT("/GUI/VerticalZooming"), &bVZoom, false);
45  return bVZoom && (abs(zoomEnd - zoomStart) > DragThreshold);
46 }
47 
48 }
49 
51 (const std::shared_ptr<WaveTrack> &pTrack, const wxRect &rect, int y)
52  : mpTrack{ pTrack } , mZoomStart(y), mZoomEnd(y), mRect(rect)
53 {
54 }
55 
57 {
58 #ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING
60 #endif
61 }
62 
63 // ZoomKind says how to zoom.
64 // If ZoomStart and ZoomEnd are not equal, this may override
65 // the zoomKind and cause a drag-zoom-in.
67  (AudacityProject *pProject,
68  WaveTrack *pTrack, bool allChannels, int ZoomKind,
69  const wxRect &rect, int zoomStart, int zoomEnd,
70  bool fixedMousePoint)
71 {
72  static const float ZOOMLIMIT = 0.001f;
73 
74  int height = rect.height;
75  int ypos = rect.y;
76 
77  // Ensure start and end are in order (swap if not).
78  if (zoomEnd < zoomStart)
79  std::swap( zoomStart, zoomEnd );
80 
81  float min, max, minBand = 0;
82  const double rate = pTrack->GetRate();
83  const float halfrate = rate / 2;
84  float maxFreq = 8000.0;
85  const SpectrogramSettings &specSettings = pTrack->GetSpectrogramSettings();
86  NumberScale scale;
87  const bool spectral = (pTrack->GetDisplay() == WaveTrack::Spectrum);
88  const bool spectrumLinear = spectral &&
90 
91 
92  bool bDragZoom = IsDragZooming(zoomStart, zoomEnd);
93  // Add 100 if spectral to separate the kinds of zoom.
94  const int kSpectral = 100;
95 
96  // Possibly override the zoom kind.
97  if( bDragZoom )
98  ZoomKind = kZoomInByDrag;
99 
100  // If we are actually zooming a spectrum rather than a wave.
101  ZoomKind += spectral ? kSpectral:0;
102 
103  float top=2.0;
104  float half=0.5;
105 
106  if (spectral) {
107  pTrack->GetSpectrumBounds(&min, &max);
108  scale = (specSettings.GetScale(min, max));
109  const auto fftLength = specSettings.GetFFTLength();
110  const float binSize = rate / fftLength;
111  maxFreq = gPrefs->Read(wxT("/Spectrum/MaxFreq"), 8000L);
112  // JKC: Following discussions of Bug 1208 I'm allowing zooming in
113  // down to one bin.
114  // const int minBins =
115  // std::min(10, fftLength / 2); //minimum 10 freq bins, unless there are less
116  const int minBins = 1;
117  minBand = minBins * binSize;
118  }
119  else{
120  pTrack->GetDisplayBounds(&min, &max);
121  const WaveformSettings &waveSettings = pTrack->GetWaveformSettings();
122  const bool linear = waveSettings.isLinear();
123  if( !linear ){
124  top = (LINEAR_TO_DB(2.0) + waveSettings.dBRange) / waveSettings.dBRange;
125  half = (LINEAR_TO_DB(0.5) + waveSettings.dBRange) / waveSettings.dBRange;
126  }
127  }
128 
129 
130  // Compute min and max.
131  switch(ZoomKind)
132  {
133  default:
134  // If we have covered all the cases, this won't happen.
135  // In release builds Audacity will ignore the zoom.
136  wxFAIL_MSG("Zooming Case not implemented by Audacity");
137  break;
138  case kZoomReset:
139  case kZoom1to1:
140  {
141  // Zoom out full
142  min = -1.0;
143  max = 1.0;
144  }
145  break;
146  case kZoomDiv2:
147  {
148  // Zoom out even more than full :-)
149  // -2.0..+2.0 (or logarithmic equivalent)
150  min = -top;
151  max = top;
152  }
153  break;
154  case kZoomTimes2:
155  {
156  // Zoom in to -0.5..+0.5
157  min = -half;
158  max = half;
159  }
160  break;
161  case kZoomHalfWave:
162  {
163  // Zoom to show fractionally more than the top half of the wave.
164  min = -0.01f;
165  max = 1.0;
166  }
167  break;
168  case kZoomInByDrag:
169  {
170  const float tmin = min, tmax = max;
171  const float p1 = (zoomStart - ypos) / (float)height;
172  const float p2 = (zoomEnd - ypos) / (float)height;
173  max = (tmax * (1.0 - p1) + tmin * p1);
174  min = (tmax * (1.0 - p2) + tmin * p2);
175 
176  // Waveform view - allow zooming down to a range of ZOOMLIMIT
177  if (max - min < ZOOMLIMIT) { // if user attempts to go smaller...
178  float c = (min + max) / 2; // ...set centre of view to centre of dragged area and top/bottom to ZOOMLIMIT/2 above/below
179  min = c - ZOOMLIMIT / 2.0;
180  max = c + ZOOMLIMIT / 2.0;
181  }
182  }
183  break;
184  case kZoomIn:
185  {
186  // Enforce maximum vertical zoom
187  const float oldRange = max - min;
188  const float l = std::max(ZOOMLIMIT, 0.5f * oldRange);
189  const float ratio = l / (max - min);
190 
191  const float p1 = (zoomStart - ypos) / (float)height;
192  float c = (max * (1.0 - p1) + min * p1);
193  if (fixedMousePoint)
194  min = c - ratio * (1.0f - p1) * oldRange,
195  max = c + ratio * p1 * oldRange;
196  else
197  min = c - 0.5 * l,
198  max = c + 0.5 * l;
199  }
200  break;
201  case kZoomOut:
202  {
203  // Zoom out
204  if (min <= -1.0 && max >= 1.0) {
205  min = -top;
206  max = top;
207  }
208  else {
209  // limit to +/- 1 range unless already outside that range...
210  float minRange = (min < -1) ? -top : -1.0;
211  float maxRange = (max > 1) ? top : 1.0;
212  // and enforce vertical zoom limits.
213  const float p1 = (zoomStart - ypos) / (float)height;
214  if (fixedMousePoint) {
215  const float oldRange = max - min;
216  const float c = (max * (1.0 - p1) + min * p1);
217  min = std::min(maxRange - ZOOMLIMIT,
218  std::max(minRange, c - 2 * (1.0f - p1) * oldRange));
219  max = std::max(minRange + ZOOMLIMIT,
220  std::min(maxRange, c + 2 * p1 * oldRange));
221  }
222  else {
223  const float c = p1 * min + (1 - p1) * max;
224  const float l = (max - min);
225  min = std::min(maxRange - ZOOMLIMIT,
226  std::max(minRange, c - l));
227  max = std::max(minRange + ZOOMLIMIT,
228  std::min(maxRange, c + l));
229  }
230  }
231  }
232  break;
233 
234  // VZooming on spectral we don't implement the other zoom presets.
235  // They are also not in the menu.
236  case kZoomReset + kSpectral:
237  {
238  // Zoom out to normal level.
239  min = spectrumLinear ? 0.0f : 1.0f;
240  max = maxFreq;
241  }
242  break;
243  case kZoom1to1 + kSpectral:
244  case kZoomDiv2 + kSpectral:
245  case kZoomTimes2 + kSpectral:
246  case kZoomHalfWave + kSpectral:
247  {
248  // Zoom out full
249  min = spectrumLinear ? 0.0f : 1.0f;
250  max = halfrate;
251  }
252  break;
253  case kZoomInByDrag + kSpectral:
254  {
255  double xmin = 1 - (zoomEnd - ypos) / (float)height;
256  double xmax = 1 - (zoomStart - ypos) / (float)height;
257  const float middle = (xmin + xmax) / 2;
258  const float middleValue = scale.PositionToValue(middle);
259 
260  min = std::max(spectrumLinear ? 0.0f : 1.0f,
261  std::min(middleValue - minBand / 2,
262  scale.PositionToValue(xmin)
263  ));
264  max = std::min(halfrate,
265  std::max(middleValue + minBand / 2,
266  scale.PositionToValue(xmax)
267  ));
268  }
269  break;
270  case kZoomIn + kSpectral:
271  {
272  // Center the zoom-in at the click
273  const float p1 = (zoomStart - ypos) / (float)height;
274  const float middle = 1.0f - p1;
275  const float middleValue = scale.PositionToValue(middle);
276 
277  if (fixedMousePoint) {
278  min = std::max(spectrumLinear ? 0.0f : 1.0f,
279  std::min(middleValue - minBand * middle,
280  scale.PositionToValue(0.5f * middle)
281  ));
282  max = std::min(halfrate,
283  std::max(middleValue + minBand * p1,
284  scale.PositionToValue(middle + 0.5f * p1)
285  ));
286  }
287  else {
288  min = std::max(spectrumLinear ? 0.0f : 1.0f,
289  std::min(middleValue - minBand / 2,
290  scale.PositionToValue(middle - 0.25f)
291  ));
292  max = std::min(halfrate,
293  std::max(middleValue + minBand / 2,
294  scale.PositionToValue(middle + 0.25f)
295  ));
296  }
297  }
298  break;
299  case kZoomOut + kSpectral:
300  {
301  // Zoom out
302  const float p1 = (zoomStart - ypos) / (float)height;
303  // (Used to zoom out centered at midline, ignoring the click, if linear view.
304  // I think it is better to be consistent. PRL)
305  // Center zoom-out at the midline
306  const float middle = // spectrumLinear ? 0.5f :
307  1.0f - p1;
308 
309  if (fixedMousePoint) {
310  min = std::max(spectrumLinear ? 0.0f : 1.0f, scale.PositionToValue(-middle));
311  max = std::min(halfrate, scale.PositionToValue(1.0f + p1));
312  }
313  else {
314  min = std::max(spectrumLinear ? 0.0f : 1.0f, scale.PositionToValue(middle - 1.0f));
315  max = std::min(halfrate, scale.PositionToValue(middle + 1.0f));
316  }
317  }
318  break;
319  }
320 
321  // Now actually apply the zoom.
322  for (auto channel : TrackList::Channels(pTrack)) {
323  if (!allChannels && channel != pTrack)
324  continue;
325  if (spectral)
326  channel->SetSpectrumBounds(min, max);
327  else
328  channel->SetDisplayBounds(min, max);
329  }
330 
331  zoomEnd = zoomStart = 0;
332  if( pProject )
333  pProject->ModifyState(true);
334 }
335 
336 enum {
344 
345  // Reserve an ample block of ids for waveform scale types
348 
349  // Reserve an ample block of ids for spectrum scale types
352 };
353 
355 // Table class
356 
358 {
359 protected:
361 
362  void InitMenu(Menu *pMenu, void *pUserData) override;
363 
364 private:
365  void DestroyMenu() override
366  {
367  mpData = nullptr;
368  }
369 
370 protected:
371  InitMenuData *mpData {};
372 
373  void OnZoom( int iZoomCode );
374  void OnZoomFitVertical(wxCommandEvent&){ OnZoom( kZoom1to1 );};
375  void OnZoomReset(wxCommandEvent&){ OnZoom( kZoomReset );};
376  void OnZoomDiv2Vertical(wxCommandEvent&){ OnZoom( kZoomDiv2 );};
377  void OnZoomTimes2Vertical(wxCommandEvent&){ OnZoom( kZoomTimes2 );};
378  void OnZoomHalfWave(wxCommandEvent&){ OnZoom( kZoomHalfWave );};
379  void OnZoomInVertical(wxCommandEvent&){ OnZoom( kZoomIn );};
380  void OnZoomOutVertical(wxCommandEvent&){ OnZoom( kZoomOut );};
381 };
382 
383 void WaveTrackVRulerMenuTable::InitMenu(Menu *, void *pUserData)
384 {
385  mpData = static_cast<InitMenuData*>(pUserData);
386 }
387 
388 
389 void WaveTrackVRulerMenuTable::OnZoom( int iZoomCode )
390 {
392  (::GetActiveProject(), mpData->pTrack, true,
393  iZoomCode, mpData->rect, mpData->yy, mpData->yy, false);
394 
395  using namespace RefreshCode;
396  mpData->result = UpdateVRuler | RefreshAll;
397 }
398 
400 // Table class
401 
403 {
407 
408 public:
409  static WaveformVRulerMenuTable &Instance();
410 
411 private:
412  virtual void InitMenu(Menu *pMenu, void *pUserData) override;
413 
414  void OnWaveformScaleType(wxCommandEvent &evt);
415 };
416 
418 {
419  static WaveformVRulerMenuTable instance;
420  return instance;
421 }
422 
423 void WaveformVRulerMenuTable::InitMenu(Menu *pMenu, void *pUserData)
424 {
425  WaveTrackVRulerMenuTable::InitMenu(pMenu, pUserData);
426 
427 // DB setting is already on track drop down.
428 #if 0
429  WaveTrack *const wt = mpData->pTrack;
430  const int id =
432  pMenu->Check(id, true);
433 #endif
434 }
435 
437 
438  POPUP_MENU_ITEM(OnZoomFitVerticalID, _("Zoom Reset\tShift-Right-Click"), OnZoomReset)
441 
442 #ifdef EXPERIMENTAL_HALF_WAVE
444 #endif
445 
447  POPUP_MENU_ITEM(OnZoomInVerticalID, _("Zoom In\tLeft-Click/Left-Drag"), OnZoomInVertical)
448  POPUP_MENU_ITEM(OnZoomOutVerticalID, _("Zoom Out\tShift-Left-Click"), OnZoomOutVertical)
449 // The log and linear options are already available as waveform db.
450 // So don't repeat them here.
451 #if 0
453  {
454  const wxArrayString & names = WaveformSettings::GetScaleNames();
455  for (int ii = 0, nn = names.size(); ii < nn; ++ii) {
457  OnWaveformScaleType);
458  }
459  }
460 #endif
462 
463 void WaveformVRulerMenuTable::OnWaveformScaleType(wxCommandEvent &evt)
464 {
465  WaveTrack *const wt = mpData->pTrack;
466  // Assume linked track is wave or null
467  const WaveformSettings::ScaleType newScaleType =
469  std::max(0,
471  evt.GetId() - OnFirstWaveformScaleID
472  )));
473 
474  if (wt->GetWaveformSettings().scaleType != newScaleType) {
475  for (auto channel : TrackList::Channels(wt)) {
476  channel->GetIndependentWaveformSettings().scaleType = newScaleType;
477  }
478 
480 
481  using namespace RefreshCode;
482  mpData->result = UpdateVRuler | RefreshAll;
483  }
484 }
485 
487 // Table class
488 
490 {
494 
495 public:
496  static SpectrumVRulerMenuTable &Instance();
497 
498 private:
499  void InitMenu(Menu *pMenu, void *pUserData) override;
500 
501  void OnSpectrumScaleType(wxCommandEvent &evt);
502 };
503 
505 {
506  static SpectrumVRulerMenuTable instance;
507  return instance;
508 }
509 
510 void SpectrumVRulerMenuTable::InitMenu(Menu *pMenu, void *pUserData)
511 {
512  WaveTrackVRulerMenuTable::InitMenu(pMenu, pUserData);
513 
514  WaveTrack *const wt = mpData->pTrack;
515  const int id =
517  pMenu->Check(id, true);
518 }
519 
521 
522  {
523  const wxArrayString & names = SpectrogramSettings::GetScaleNames();
524  for (int ii = 0, nn = names.size(); ii < nn; ++ii) {
526  OnSpectrumScaleType);
527  }
528  }
529 
531  POPUP_MENU_ITEM(OnZoomResetID, _("Zoom Reset"), OnZoomReset)
532  POPUP_MENU_ITEM(OnZoomFitVerticalID, _("Zoom to Fit\tShift-Right-Click"), OnZoomFitVertical)
533  POPUP_MENU_ITEM(OnZoomInVerticalID, _("Zoom In\tLeft-Click/Left-Drag"), OnZoomInVertical)
534  POPUP_MENU_ITEM(OnZoomOutVerticalID, _("Zoom Out\tShift-Left-Click"), OnZoomOutVertical)
536 
537 void SpectrumVRulerMenuTable::OnSpectrumScaleType(wxCommandEvent &evt)
538 {
539  WaveTrack *const wt = mpData->pTrack;
540 
541  const SpectrogramSettings::ScaleType newScaleType =
543  std::max(0,
545  evt.GetId() - OnFirstSpectrumScaleID
546  )));
547  if (wt->GetSpectrogramSettings().scaleType != newScaleType) {
548  for (auto channel : TrackList::Channels(wt))
549  channel->GetIndependentSpectrogramSettings().scaleType = newScaleType;
550 
552 
553  using namespace RefreshCode;
554  mpData->result = UpdateVRuler | RefreshAll;
555  }
556 }
557 
559 
561 {
562  static auto zoomInCursor =
563  ::MakeCursor(wxCURSOR_MAGNIFIER, ZoomInCursorXpm, 19, 15);
564  static auto zoomOutCursor =
565  ::MakeCursor(wxCURSOR_MAGNIFIER, ZoomOutCursorXpm, 19, 15);
566  static wxCursor arrowCursor{ wxCURSOR_ARROW };
567  bool bVZoom;
568  gPrefs->Read(wxT("/GUI/VerticalZooming"), &bVZoom, false);
569  bVZoom &= !state.RightIsDown();
570  const auto message = bVZoom ?
571  _("Click to vertically zoom in. Shift-click to zoom out. Drag to specify a zoom region.") :
572  _("Right-click for menu.");
573 
574  return {
575  message,
576  bVZoom ? (state.ShiftDown() ? &*zoomOutCursor : &*zoomInCursor) : &arrowCursor
577  // , message
578  };
579 }
580 
582 {
583 }
584 
587 {
589 }
590 
592 (const TrackPanelMouseEvent &evt, AudacityProject *pProject)
593 {
594  using namespace RefreshCode;
595  auto pTrack = pProject->GetTracks()->Lock(mpTrack);
596  if (!pTrack)
597  return Cancelled;
598 
599  const wxMouseEvent &event = evt.event;
600  if ( event.RightIsDown() )
601  return RefreshNone;
602  mZoomEnd = event.m_y;
603  if (IsDragZooming(mZoomStart, mZoomEnd))
604  return RefreshAll;
605  return RefreshNone;
606 }
607 
610 {
611  return HitPreview(st.state);
612 }
613 
615 (const TrackPanelMouseEvent &evt, AudacityProject *pProject,
616  wxWindow *pParent)
617 {
618  using namespace RefreshCode;
619  auto pTrack = pProject->GetTracks()->Lock(mpTrack);
620  if (!pTrack)
621  return RefreshNone;
622 
623  const wxMouseEvent &event = evt.event;
624  const bool shiftDown = event.ShiftDown();
625  const bool rightUp = event.RightUp();
626 
627 
628  bool bVZoom;
629  gPrefs->Read(wxT("/GUI/VerticalZooming"), &bVZoom, false);
630 
631  // Popup menu...
632  if (
633  rightUp &&
634  !(event.ShiftDown() || event.CmdDown()))
635  {
636  InitMenuData data {
637  pTrack.get(), mRect, RefreshCode::RefreshNone, event.m_y
638  };
639 
640  PopupMenuTable *const pTable =
641  (pTrack->GetDisplay() == WaveTrack::Spectrum)
644  std::unique_ptr<PopupMenuTable::Menu>
645  pMenu(PopupMenuTable::BuildMenu(pParent, pTable, &data));
646 
647  // Accelerators only if zooming enabled.
648  if( !bVZoom )
649  {
650  wxMenuItemList & L = pMenu->GetMenuItems();
651  // let's iterate over the list in STL syntax
652  wxMenuItemList::iterator iter;
653  for (iter = L.begin(); iter != L.end(); ++iter)
654  {
655  wxMenuItem *pItem = *iter;
656  // Remove accelerator, if any.
657  pItem->SetItemLabel( (pItem->GetItemLabel() + "\t" ).BeforeFirst('\t') );
658  }
659  }
660 
661 
662  pParent->PopupMenu(pMenu.get(), event.m_x, event.m_y);
663 
664  return data.result;
665  }
666  else{
667  // Ignore Capture Lost event
668  bVZoom &= event.GetId() != kCaptureLostEventId;
669  // shiftDown | rightUp | ZoomKind
670  // T | T | 1to1
671  // T | F | Out
672  // F | - | In
673  if( bVZoom ){
674  if( shiftDown )
675  mZoomStart=mZoomEnd;
676  DoZoom(pProject, pTrack.get(), true,
677  shiftDown ? (rightUp ? kZoom1to1 : kZoomOut) : kZoomIn,
678  mRect, mZoomStart, mZoomEnd, !shiftDown);
679  }
680  }
681 
682  return UpdateVRuler | RefreshAll;
683 }
684 
686 {
687  // Cancel is implemented! And there is no initial state to restore,
688  // so just return a code.
690 }
691 
693 (DrawingPass pass, wxDC * dc, const wxRegion &, const wxRect &panelRect)
694 {
695  if (!mpTrack.lock()) // TrackList::Lock()?
696  return;
697 
698  if ( pass == UIHandle::Cells &&
699  IsDragZooming( mZoomStart, mZoomEnd ) )
701  ( dc, mRect, panelRect, mZoomStart, mZoomEnd );
702 }
703 
#define POPUP_MENU_SEPARATOR()
static wxArrayString names()
Definition: Tags.cpp:703
AudacityPrefs * gPrefs
Definition: Prefs.cpp:73
bool isLinear() const
void Enter(bool forward) override
const int kZoomHalfWave
static SpectrumVRulerMenuTable & Instance()
Spectrogram settings, either for one track or as defaults.
const int DragThreshold
Definition: TrackPanel.h:234
const WaveformSettings & GetWaveformSettings() const
Definition: WaveTrack.cpp:754
float PositionToValue(float pp) const
Definition: NumberScale.h:154
void GetSpectrumBounds(float *min, float *max) const
Definition: WaveTrack.cpp:340
#define POPUP_MENU_RADIO_ITEM(id, string, memFn)
static HitTestPreview HitPreview(const wxMouseState &state)
void OnZoomReset(wxCommandEvent &)
size_t GetFFTLength() const
static const wxArrayString & GetScaleNames()
HitTestPreview Preview(const TrackPanelMouseState &state, const AudacityProject *pProject) override
static void DoZoom(AudacityProject *pProject, WaveTrack *pTrack, bool allChannels, int ZoomKind, const wxRect &rect, int zoomStart, int zoomEnd, bool fixedMousePoint)
#define END_POPUP_MENU()
const SpectrogramSettings & GetSpectrogramSettings() const
Definition: WaveTrack.cpp:706
Result Click(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
void OnZoomDiv2Vertical(wxCommandEvent &)
Result mChangeHighlight
Definition: UIHandle.h:150
NumberScale GetScale(float minFreq, float maxFreq) const
void GetDisplayBounds(float *min, float *max) const
Definition: WaveTrack.cpp:328
AudacityProject provides the main window, with tools and tracks contained within it.
Definition: Project.h:175
const int kZoomOut
unsigned Result
Definition: UIHandle.h:37
void InitMenu(Menu *pMenu, void *pUserData) override
const int kZoomTimes2
A Track that contains audio waveform data.
Definition: WaveTrack.h:60
Result Release(const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *pParent) override
static std::unique_ptr< Menu > BuildMenu(wxEvtHandler *pParent, PopupMenuTable *pTable, void *pUserData=NULL)
WaveTrackVZoomHandle(const WaveTrackVZoomHandle &)
int min(int a, int b)
#define DECLARE_POPUP_MENU(HandlerClass)
static const wxArrayString & GetScaleNames()
std::shared_ptr< Subclass > Lock(const std::weak_ptr< Subclass > &wTrack)
Definition: Track.h:1384
void OnZoomFitVertical(wxCommandEvent &)
void OnZoomTimes2Vertical(wxCommandEvent &)
void ModifyState(bool bWantsAutoSave)
Definition: Project.cpp:4662
Result Cancel(AudacityProject *pProject) override
Result Drag(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom")).Raw()), OnMoveTrack)#define SET_TRACK_NAME_PLUGIN_SYMBOLclass SetTrackNameCommand:public AudacityCommand
const int kZoom1to1
const int kZoomInByDrag
#define LINEAR_TO_DB(x)
Definition: Audacity.h:217
POPUP_MENU_ITEM(OnMoveUpID, _("Move Track &Up")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveUp")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveDownID
AUDACITY_DLL_API AudacityProject * GetActiveProject()
Definition: Project.cpp:312
static WaveformVRulerMenuTable & Instance()
std::unique_ptr< wxCursor > MakeCursor(int WXUNUSED(CursorId), const char *const pXpm[36], int HotX, int HotY)
Definition: TrackPanel.cpp:261
const int kZoomReset
void InitMenu(Menu *pMenu, void *pUserData) override
const int kCaptureLostEventId
void DrawExtras(DrawingPass pass, wxDC *dc, const wxRegion &updateRegion, const wxRect &panelRect) override
double GetRate() const
Definition: WaveTrack.cpp:401
TrackList * GetTracks()
Definition: Project.h:192
WaveTrackDisplay GetDisplay() const
Definition: WaveTrack.h:597
const int kZoomDiv2
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1305
const int kZoomIn
void OnZoomHalfWave(wxCommandEvent &)
void OnZoomInVertical(wxCommandEvent &)
static void DrawZooming(wxDC *dc, const wxRect &cellRect, const wxRect &panelRect, int zoomStart, int zoomEnd)
DrawingPass
Definition: UIHandle.h:43
void OnZoomOutVertical(wxCommandEvent &)
virtual void InitMenu(Menu *pMenu, void *pUserData) override
BEGIN_POPUP_MENU(SpectrumVRulerMenuTable)
Waveform settings, either for one track or as defaults.