Audacity  3.0.3
NoteTrackVZoomHandle.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3 Audacity: A Digital Audio Editor
4 
5 NoteTrackVZoomHandle.cpp
6 
7 Paul Licameli split from TrackPanel.cpp
8 
9 **********************************************************************/
10 
11 
12 #ifdef USE_MIDI
13 #include "NoteTrackVZoomHandle.h"
14 
15 #include "../../../ui/TrackVRulerControls.h"
16 
17 #include "../../../../HitTestResult.h"
18 #include "../../../../NoteTrack.h"
19 #include "Project.h"
20 #include "../../../../ProjectHistory.h"
21 #include "../../../../RefreshCode.h"
22 #include "../../../../TrackArtist.h"
23 #include "../../../../TrackPanelMouseEvent.h"
24 #include "../../../../widgets/PopupMenuTable.h"
25 #include "../../../../../images/Cursors.h"
26 #include "Prefs.h"
27 
28 #include <wx/event.h>
29 
30 namespace
31 {
32 
33  struct InitMenuData
34  {
35  public:
38  wxRect rect;
39  unsigned result;
40  int yy;
41  };
42 
43  bool IsDragZooming(int zoomStart, int zoomEnd)
44  {
45  const int DragThreshold = 3;// Anything over 3 pixels is a drag, else a click.
46  bool bVZoom;
47  gPrefs->Read(wxT("/GUI/VerticalZooming"), &bVZoom, false);
48  return bVZoom && (abs(zoomEnd - zoomStart) > DragThreshold);
49  }
50 
51 }
52 
54 
56 (const std::shared_ptr<NoteTrack> &pTrack, const wxRect &rect, int y)
57  : mpTrack{ pTrack } , mZoomStart(y), mZoomEnd(y), mRect(rect)
58 {
59 }
60 
62 {
63 #ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING
65 #endif
66 }
67 
69 {
70  static auto zoomInCursor =
71  ::MakeCursor(wxCURSOR_MAGNIFIER, ZoomInCursorXpm, 19, 15);
72  static auto zoomOutCursor =
73  ::MakeCursor(wxCURSOR_MAGNIFIER, ZoomOutCursorXpm, 19, 15);
74  static wxCursor arrowCursor{ wxCURSOR_ARROW };
75 
76  bool bVZoom;
77  gPrefs->Read(wxT("/GUI/VerticalZooming"), &bVZoom, false);
78  bVZoom &= !state.RightIsDown();
79  const auto message = bVZoom ?
80  XO("Click to vertically zoom in. Shift-click to zoom out. Drag to specify a zoom region.") :
81  XO("Right-click for menu.");
82 
83  return {
84  message,
85  bVZoom ? (state.ShiftDown() ? &*zoomOutCursor : &*zoomInCursor) : &arrowCursor
86  // , message
87  };
88 }
89 
91 (std::weak_ptr<NoteTrackVZoomHandle> &holder,
92  const wxMouseState &state,
93  const std::shared_ptr<NoteTrack> &pTrack, const wxRect &rect)
94 {
95  if (pTrack) {
96  auto result = std::make_shared<NoteTrackVZoomHandle>(
97  pTrack, rect, state.m_y);
98  result = AssignUIHandlePtr(holder, result);
99  return result;
100  }
101  return {};
102 }
103 
105 {
106 }
107 
109 {
110  return true;
111 }
112 
115 {
116  // change note track to zoom like audio track
117  // mpTrack->StartVScroll();
118 
120 }
121 
123 (const TrackPanelMouseEvent &evt, AudacityProject *pProject)
124 {
125  using namespace RefreshCode;
126  auto pTrack = TrackList::Get( *pProject ).Lock(mpTrack);
127  if (!pTrack)
128  return Cancelled;
129 
130  const wxMouseEvent &event = evt.event;
131  mZoomEnd = event.m_y;
133  // changed Note track to work like audio track
134  // pTrack->VScroll(mZoomStart, mZoomEnd);
135  return RefreshAll;
136  }
137  return RefreshNone;
138 }
139 
142 {
143  return HitPreview(st.state);
144 }
145 
146 enum {
154 
156 
159 };
161 // Table class
162 
164  : public PopupMenuTable
165  , private PrefsListener
166 {
168  : PopupMenuTable{ "NoteTrackVRuler" }
169  {};
172 
173 public:
174  static NoteTrackVRulerMenuTable &Instance();
175 
176 protected:
177  enum {
178 // Note that these can be with or without spectrum view which
179 // adds a constant.
180 //const int kZoom1to1 = 1;
181 //const int kZoomTimes2 = 2;
182 //const int kZoomDiv2 = 3;
183 //const int kZoomHalfWave = 4;
184 //const int kZoomInByDrag = 5;
185  kZoomIn = 6,
186  kZoomOut = 7,
188  kZoomMax = 9,
189  kUpOctave = 10,
190  kDownOctave = 11,
191  };
192 
193  InitMenuData *mpData {};
194  void OnZoom( int iZoomCode );
195 // void OnZoomFitVertical(wxCommandEvent&){ OnZoom( kZoom1to1 );};
196  void OnZoomReset(wxCommandEvent&){ OnZoom( kZoomReset );};
197 // void OnZoomDiv2Vertical(wxCommandEvent&){ OnZoom( kZoomDiv2 );};
198 // void OnZoomTimes2Vertical(wxCommandEvent&){ OnZoom( kZoomTimes2 );};
199 // void OnZoomHalfWave(wxCommandEvent&){ OnZoom( kZoomHalfWave );};
200  void OnZoomInVertical(wxCommandEvent&){ OnZoom( kZoomIn );};
201  void OnZoomOutVertical(wxCommandEvent&){ OnZoom( kZoomOut );};
202  void OnZoomMax(wxCommandEvent&){ OnZoom( kZoomMax );};
203  void OnUpOctave(wxCommandEvent&){ OnZoom( kUpOctave );};
204  void OnDownOctave(wxCommandEvent&){ OnZoom( kDownOctave );};
205 
206 private:
207  void InitUserData(void *pUserData) override;
208 
209  void UpdatePrefs() override
210  {
211  // Because labels depend on advanced vertical zoom setting
213  }
214 };
215 
217 {
218  static NoteTrackVRulerMenuTable instance;
219  return instance;
220 }
221 
223 {
224  mpData = static_cast<InitMenuData*>(pUserData);
225 }
226 
227 void NoteTrackVRulerMenuTable::OnZoom( int iZoomCode ){
228  switch( iZoomCode ){
229  case kZoomReset:
230  mpData->pTrack->ZoomAllNotes();
231  break;
232  case kZoomIn:
233  mpData->pTrack->ZoomIn(mpData->rect, mpData->yy);
234  break;
235  case kZoomOut:
236  mpData->pTrack->ZoomOut(mpData->rect, mpData->yy);
237  break;
238  case kZoomMax:
239  mpData->pTrack->ZoomMaxExtent();
240  break;
241  case kUpOctave:
242  mpData->pTrack->ShiftNoteRange(12);
243  break;
244  case kDownOctave:
245  mpData->pTrack->ShiftNoteRange(-12);
246  break;
247  }
248  AudacityProject *const project = &mpData->project;
249  ProjectHistory::Get( *project ).ModifyState(false);
250  using namespace RefreshCode;
251  mpData->result = UpdateVRuler | RefreshAll;
252 }
253 
254 
256 
257  // Accelerators only if zooming enabled.
258  bool bVZoom;
259  gPrefs->Read(wxT("/GUI/VerticalZooming"), &bVZoom, false);
260 
261  BeginSection( "Zoom" );
262  BeginSection( "Basic" );
264  MakeLabel( XXO("Zoom Reset"), bVZoom, XXO("Shift-Right-Click")),
265  POPUP_MENU_FN( OnZoomReset ) );
266  AppendItem( "Max", OnZoomMaxID, XXO("Max Zoom"), POPUP_MENU_FN( OnZoomMax ) );
268 
269  BeginSection( "InOut" );
271  MakeLabel( XXO("Zoom In"), bVZoom, XXO("Left-Click/Left-Drag") ),
272  POPUP_MENU_FN( OnZoomInVertical ) );
274  MakeLabel( XXO("Zoom Out"), bVZoom, XXO("Shift-Left-Click") ),
275  POPUP_MENU_FN( OnZoomOutVertical ) );
276  EndSection();
277  EndSection();
278 
279  BeginSection( "Pan" );
280  BeginSection( "Octaves" );
281  AppendItem( "Up", OnUpOctaveID, XXO("Up &Octave"), POPUP_MENU_FN( OnUpOctave) );
282  AppendItem( "Down", OnDownOctaveID, XXO("Down Octa&ve"), POPUP_MENU_FN( OnDownOctave ) );
283  EndSection();
284  EndSection();
285 
287 
288 
289 
291 (const TrackPanelMouseEvent &evt, AudacityProject *pProject,
292  wxWindow *pParent)
293 {
294  using namespace RefreshCode;
295  auto pTrack = TrackList::Get( *pProject ).Lock(mpTrack);
296  if (!pTrack)
297  return RefreshNone;
298 
299  const wxMouseEvent &event = evt.event;
300  //const bool shiftDown = event.ShiftDown();
301  const bool rightUp = event.RightUp();
302 
303 
304  // Popup menu...
305  if (
306  rightUp &&
307  !(event.ShiftDown() || event.CmdDown()))
308  {
309  InitMenuData data {
310  *pProject, pTrack.get(), mRect, RefreshNone, event.m_y
311  };
312 
313  PopupMenuTable *const pTable =
315  auto pMenu = PopupMenuTable::BuildMenu(pTable, &data);
316 
317  pMenu->Popup( *pParent, { event.m_x, event.m_y } );
318 
319  return data.result;
320  }
321 
322  bool bVZoom;
323  gPrefs->Read(wxT("/GUI/VerticalZooming"), &bVZoom, false);
324  bVZoom &= event.GetId() != kCaptureLostEventId;
325  if( !bVZoom )
326  return RefreshAll;
327 
329  pTrack->ZoomTo(evt.rect, mZoomStart, mZoomEnd);
330  }
331  else if (event.ShiftDown() || event.RightUp()) {
332  if (event.ShiftDown() && event.RightUp()) {
333  auto oldBotNote = pTrack->GetBottomNote();
334  auto oldTopNote = pTrack->GetTopNote();
335  // Zoom out to show all notes
336  pTrack->ZoomAllNotes();
337  if (pTrack->GetBottomNote() == oldBotNote &&
338  pTrack->GetTopNote() == oldTopNote) {
339  // However if we are already showing all notes, zoom out further
340  pTrack->ZoomMaxExtent();
341  }
342  } else {
343  // Zoom out
344  pTrack->ZoomOut(evt.rect, mZoomEnd);
345  }
346  }
347  else {
348  pTrack->ZoomIn(evt.rect, mZoomEnd);
349  }
350 
351  mZoomEnd = mZoomStart = 0;
352  ProjectHistory::Get( *pProject ).ModifyState(false);
353 
354  return RefreshAll;
355 }
356 
358 {
359  // Cancel is implemented! And there is no initial state to restore,
360  // so just return a code.
362 }
363 
365  TrackPanelDrawingContext &context,
366  const wxRect &rect, unsigned iPass )
367 {
368  if ( iPass == TrackArtist::PassZooming ) {
369  if (!mpTrack.lock()) //? TrackList::Lock()
370  return;
371 
374  ( context, rect, mZoomStart, mZoomEnd );
375  }
376 }
377 
380  const wxRect &rect, const wxRect &panelRect, unsigned iPass )
381 {
382  if ( iPass == TrackArtist::PassZooming )
383  return TrackVRulerControls::ZoomingArea( rect, panelRect );
384  else
385  return rect;
386 }
387 
388 #endif
OnZoomDiv2ID
@ OnZoomDiv2ID
Definition: NoteTrackVZoomHandle.cpp:149
ProjectHistory::ModifyState
void ModifyState(bool bWantsAutoSave)
Definition: ProjectHistory.cpp:124
NoteTrackVZoomHandle::mRect
wxRect mRect
Definition: NoteTrackVZoomHandle.h:72
OnDownOctaveID
@ OnDownOctaveID
Definition: NoteTrackVZoomHandle.cpp:158
NoteTrackVZoomHandle::HitTest
static UIHandlePtr HitTest(std::weak_ptr< NoteTrackVZoomHandle > &holder, const wxMouseState &state, const std::shared_ptr< NoteTrack > &pTrack, const wxRect &rect)
Definition: NoteTrackVZoomHandle.cpp:91
NoteTrackVRulerMenuTable::DECLARE_POPUP_MENU
DECLARE_POPUP_MENU(NoteTrackVRulerMenuTable)
OnZoomMaxID
@ OnZoomMaxID
Definition: NoteTrackVZoomHandle.cpp:155
NoteTrackVRulerMenuTable::NoteTrackVRulerMenuTable
NoteTrackVRulerMenuTable()
Definition: NoteTrackVZoomHandle.cpp:167
RefreshCode::RefreshAll
@ RefreshAll
Definition: RefreshCode.h:26
RefreshCode::RefreshNone
@ RefreshNone
Definition: RefreshCode.h:21
anonymous_namespace{NoteTrackVZoomHandle.cpp}::InitMenuData::result
unsigned result
Definition: NoteTrackVZoomHandle.cpp:39
gPrefs
FileConfig * gPrefs
Definition: Prefs.cpp:70
OnZoomHalfWaveID
@ OnZoomHalfWaveID
Definition: NoteTrackVZoomHandle.cpp:151
BeginSection
BeginSection("Zoom")
TrackList::Lock
std::shared_ptr< Subclass > Lock(const std::weak_ptr< Subclass > &wTrack)
Definition: Track.h:1542
Project.h
PopupMenuTable
Definition: PopupMenuTable.h:115
NoteTrackVRulerMenuTable::Instance
static NoteTrackVRulerMenuTable & Instance()
Definition: NoteTrackVZoomHandle.cpp:216
TrackPanelDrawingContext
Definition: TrackPanelDrawingContext.h:22
MakeCursor
std::unique_ptr< wxCursor > MakeCursor(int WXUNUSED(CursorId), const char *const pXpm[36], int HotX, int HotY)
Definition: TrackPanel.cpp:182
bVZoom
bool bVZoom
Definition: NoteTrackVZoomHandle.cpp:258
RefreshCode::Cancelled
@ Cancelled
Definition: RefreshCode.h:23
XO
#define XO(s)
Definition: Internat.h:31
NoteTrackVZoomHandle::HitPreview
static HitTestPreview HitPreview(const wxMouseState &state)
Definition: NoteTrackVZoomHandle.cpp:68
OnZoomResetID
@ OnZoomResetID
Definition: NoteTrackVZoomHandle.cpp:148
NoteTrackVRulerMenuTable::~NoteTrackVRulerMenuTable
virtual ~NoteTrackVRulerMenuTable()
Definition: NoteTrackVZoomHandle.cpp:170
anonymous_namespace{NoteTrackVZoomHandle.cpp}::InitMenuData::project
AudacityProject & project
Definition: NoteTrackVZoomHandle.cpp:36
NoteTrackVRulerMenuTable::OnZoomMax
void OnZoomMax(wxCommandEvent &)
Definition: NoteTrackVZoomHandle.cpp:202
NoteTrackVZoomHandle::Click
Result Click(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
Definition: NoteTrackVZoomHandle.cpp:114
OnZoomFitVerticalID
@ OnZoomFitVerticalID
Definition: NoteTrackVZoomHandle.cpp:147
UIHandle
Short-lived drawing and event-handling object associated with a TrackPanelCell.
Definition: UIHandle.h:35
PrefsListener
A listener notified of changes in preferences.
Definition: Prefs.h:392
NoteTrackVRulerMenuTable::OnZoom
void OnZoom(int iZoomCode)
Definition: NoteTrackVZoomHandle.cpp:227
NoteTrackVZoomHandle::Draw
void Draw(TrackPanelDrawingContext &context, const wxRect &rect, unsigned iPass) override
Definition: NoteTrackVZoomHandle.cpp:364
NoteTrackVZoomHandle::Release
Result Release(const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *pParent) override
Definition: NoteTrackVZoomHandle.cpp:291
DragThreshold
const int DragThreshold
Definition: TrackPanel.h:60
XXO
#define XXO(s)
Definition: Internat.h:44
UIHandle::mChangeHighlight
Result mChangeHighlight
Definition: UIHandle.h:139
NoteTrackVZoomHandle::HandlesRightClick
bool HandlesRightClick() override
Whether the handle has any special right-button handling.
Definition: NoteTrackVZoomHandle.cpp:108
TrackVRulerControls::ZoomingArea
static wxRect ZoomingArea(const wxRect &rect, const wxRect &panelRect)
Definition: TrackVRulerControls.cpp:81
UIHandle::Result
unsigned Result
Definition: UIHandle.h:38
NoteTrackVZoomHandle.h
NoteTrackVZoomHandle::~NoteTrackVZoomHandle
virtual ~NoteTrackVZoomHandle()
Definition: NoteTrackVZoomHandle.cpp:104
NoteTrackVZoomHandle::Preview
HitTestPreview Preview(const TrackPanelMouseState &state, AudacityProject *pProject) override
Definition: NoteTrackVZoomHandle.cpp:141
UIHandlePtr
std::shared_ptr< UIHandle > UIHandlePtr
Definition: CellularPanel.h:28
anonymous_namespace{NoteTrackVZoomHandle.cpp}::IsDragZooming
bool IsDragZooming(int zoomStart, int zoomEnd)
Definition: NoteTrackVZoomHandle.cpp:43
NoteTrackVRulerMenuTable::OnZoomInVertical
void OnZoomInVertical(wxCommandEvent &)
Definition: NoteTrackVZoomHandle.cpp:200
NoteTrackVZoomHandle::Enter
void Enter(bool forward, AudacityProject *) override
Definition: NoteTrackVZoomHandle.cpp:61
NoteTrackVZoomHandle::mpTrack
std::weak_ptr< NoteTrack > mpTrack
Definition: NoteTrackVZoomHandle.h:69
HitTestPreview
Definition: HitTestResult.h:20
AppendItem
AppendItem("Reset", OnZoomResetID, MakeLabel(XXO("Zoom Reset"), bVZoom, XXO("Shift-Right-Click")), POPUP_MENU_FN(OnZoomReset))
NoteTrackVRulerMenuTable::OnDownOctave
void OnDownOctave(wxCommandEvent &)
Definition: NoteTrackVZoomHandle.cpp:204
NoteTrackVZoomHandle
Definition: NoteTrackVZoomHandle.h:20
RefreshCode::UpdateVRuler
@ UpdateVRuler
Definition: RefreshCode.h:30
WaveTrackViewConstants::kZoomIn
@ kZoomIn
Definition: WaveTrackViewConstants.h:77
RefreshCode::RefreshCell
@ RefreshCell
Definition: RefreshCode.h:24
EndSection
EndSection()
POPUP_MENU_FN
#define POPUP_MENU_FN(memFn)
Definition: PopupMenuTable.h:324
NoteTrackVRulerMenuTable
Definition: NoteTrackVZoomHandle.cpp:166
WaveTrackViewConstants::kZoomReset
@ kZoomReset
Definition: WaveTrackViewConstants.h:79
NoteTrackVZoomHandle::NoteTrackVZoomHandle
NoteTrackVZoomHandle(const NoteTrackVZoomHandle &)
PopupMenuTable::Clear
void Clear()
Definition: PopupMenuTable.h:155
anonymous_namespace{NoteTrackVZoomHandle.cpp}::InitMenuData::yy
int yy
Definition: NoteTrackVZoomHandle.cpp:40
BEGIN_POPUP_MENU
#define BEGIN_POPUP_MENU(HandlerClass)
Definition: PopupMenuTable.h:316
Read
gPrefs Read(wxT("/GUI/VerticalZooming"), &bVZoom, false)
TrackList::Get
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:506
OnZoomOutVerticalID
@ OnZoomOutVerticalID
Definition: NoteTrackVZoomHandle.cpp:153
TrackVRulerControls::DrawZooming
static void DrawZooming(TrackPanelDrawingContext &context, const wxRect &rect, int zoomStart, int zoomEnd)
Definition: TrackVRulerControls.cpp:61
NoteTrackVZoomHandle::Drag
Result Drag(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
Definition: NoteTrackVZoomHandle.cpp:123
NoteTrackVZoomHandle::mZoomEnd
int mZoomEnd
Definition: NoteTrackVZoomHandle.h:71
NoteTrackVZoomHandle::DrawingArea
wxRect DrawingArea(TrackPanelDrawingContext &, const wxRect &rect, const wxRect &panelRect, unsigned iPass) override
Definition: NoteTrackVZoomHandle.cpp:378
AudacityProject
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:92
NoteTrackVRulerMenuTable::OnZoomOutVertical
void OnZoomOutVertical(wxCommandEvent &)
Definition: NoteTrackVZoomHandle.cpp:201
TrackPanelMouseEvent
Definition: TrackPanelMouseEvent.h:46
NoteTrackVZoomHandle::mZoomStart
int mZoomStart
Definition: NoteTrackVZoomHandle.h:71
NoteTrackVRulerMenuTable::OnUpOctave
void OnUpOctave(wxCommandEvent &)
Definition: NoteTrackVZoomHandle.cpp:203
TrackPanelMouseState
Definition: TrackPanelMouseEvent.h:28
anonymous_namespace{NoteTrackVZoomHandle.cpp}::InitMenuData
Definition: NoteTrackVZoomHandle.cpp:34
WaveTrackViewConstants::kZoomOut
@ kZoomOut
Definition: WaveTrackViewConstants.h:78
NoteTrackVZoomHandle::Cancel
Result Cancel(AudacityProject *pProject) override
Definition: NoteTrackVZoomHandle.cpp:357
TrackArtist::PassZooming
@ PassZooming
Definition: TrackArtist.h:85
kCaptureLostEventId
const int kCaptureLostEventId
Definition: TrackPanelMouseEvent.h:23
PopupMenuTable::BuildMenu
static std::unique_ptr< PopupMenu > BuildMenu(PopupMenuTable *pTable, void *pUserData=NULL)
Definition: PopupMenuTable.cpp:190
anonymous_namespace{NoteTrackVZoomHandle.cpp}::InitMenuData::rect
wxRect rect
Definition: NoteTrackVZoomHandle.cpp:38
Prefs.h
anonymous_namespace{NoteTrackVZoomHandle.cpp}::InitMenuData::pTrack
NoteTrack * pTrack
Definition: NoteTrackVZoomHandle.cpp:37
AssignUIHandlePtr
std::shared_ptr< Subclass > AssignUIHandlePtr(std::weak_ptr< Subclass > &holder, const std::shared_ptr< Subclass > &pNew)
Definition: UIHandle.h:151
OnZoomTimes2ID
@ OnZoomTimes2ID
Definition: NoteTrackVZoomHandle.cpp:150
RefreshCode
Namespace containing an enum 'what to do on a refresh?'.
Definition: RefreshCode.h:16
NoteTrackVRulerMenuTable::UpdatePrefs
void UpdatePrefs() override
Definition: NoteTrackVZoomHandle.cpp:209
NoteTrackVRulerMenuTable::OnZoomReset
void OnZoomReset(wxCommandEvent &)
Definition: NoteTrackVZoomHandle.cpp:196
OnZoomInVerticalID
@ OnZoomInVerticalID
Definition: NoteTrackVZoomHandle.cpp:152
TrackPanelMouseEvent::event
wxMouseEvent & event
Definition: TrackPanelMouseEvent.h:58
TrackPanelMouseState::state
wxMouseState & state
Definition: TrackPanelMouseEvent.h:38
NoteTrackVRulerMenuTable::InitUserData
void InitUserData(void *pUserData) override
Called before the menu items are appended.
Definition: NoteTrackVZoomHandle.cpp:222
ProjectHistory::Get
static ProjectHistory & Get(AudacityProject &project)
Definition: ProjectHistory.cpp:26
NoteTrack
A Track that is used for Midi notes. (Somewhat old code).
Definition: NoteTrack.h:67
OnUpOctaveID
@ OnUpOctaveID
Definition: NoteTrackVZoomHandle.cpp:157
END_POPUP_MENU
#define END_POPUP_MENU()
Definition: PopupMenuTable.h:331