Audacity  3.0.3
LabelGlyphHandle.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3 Audacity: A Digital Audio Editor
4 
5 LabelGlyphHandle.cpp
6 
7 Paul Licameli split from TrackPanel.cpp
8 
9 **********************************************************************/
10 
11 
12 #include "LabelGlyphHandle.h"
13 
14 #include "LabelTrackView.h"
15 #include "../../../HitTestResult.h"
16 #include "../../../LabelTrack.h"
17 #include "../../../ProjectHistory.h"
18 #include "../../../RefreshCode.h"
19 #include "../../../TrackPanelMouseEvent.h"
20 #include "../../../UndoManager.h"
21 #include "ViewInfo.h"
22 #include "../../../SelectionState.h"
23 #include "../../../ProjectAudioIO.h"
24 #include "../../../images/Cursors.h"
25 #include "../../../tracks/ui/TimeShiftHandle.h"
26 
27 #include <wx/cursor.h>
28 #include <wx/translation.h>
29 
30 LabelTrackHit::LabelTrackHit( const std::shared_ptr<LabelTrack> &pLT )
31  : mpLT{ pLT }
32 {
33  pLT->Bind(
34  EVT_LABELTRACK_PERMUTED, &LabelTrackHit::OnLabelPermuted, this );
35 }
36 
38 {
39  // Must do this because this sink isn't wxEvtHandler
40  mpLT->Unbind(
41  EVT_LABELTRACK_PERMUTED, &LabelTrackHit::OnLabelPermuted, this );
42 }
43 
45 {
46  e.Skip();
47  if ( e.mpTrack.lock() != mpLT )
48  return;
49 
50  auto former = e.mFormerPosition;
51  auto present = e.mPresentPosition;
52 
53  auto update = [=]( int &index ){
54  if ( index == former )
55  index = present;
56  else if ( former < index && index <= present )
57  -- index;
58  else if ( former > index && index >= present )
59  ++ index;
60  };
61 
62  update( mMouseOverLabelLeft );
63  update( mMouseOverLabelRight );
64  update( mMouseOverLabel );
65 }
66 
68 (const std::shared_ptr<LabelTrack> &pLT,
69  const wxRect &rect, const std::shared_ptr<LabelTrackHit> &pHit)
70  : mpHit{ pHit }
71  , mpLT{ pLT }
72  , mRect{ rect }
73 {
74 }
75 
77 {
79 }
80 
82 (const LabelGlyphHandle &oldState, const LabelGlyphHandle &newState)
83 {
84  if (oldState.mpHit->mEdge != newState.mpHit->mEdge)
85  // pointer moves between the circle and the chevron
87  return 0;
88 }
89 
91 (std::weak_ptr<LabelGlyphHandle> &holder,
92  const wxMouseState &state,
93  const std::shared_ptr<LabelTrack> &pLT, const wxRect &rect)
94 {
95  // Allocate on heap because there are pointers to it when it is bound as
96  // an event sink, therefore it's not copyable; make it shared so
97  // LabelGlyphHandle can be copyable:
98  auto pHit = std::make_shared<LabelTrackHit>( pLT );
99 
100  LabelTrackView::OverGlyph(*pLT, *pHit, state.m_x, state.m_y);
101 
102  // IF edge!=0 THEN we've set the cursor and we're done.
103  // signal this by setting the tip.
104  if ( pHit->mEdge & 3 )
105  {
106  auto result = std::make_shared<LabelGlyphHandle>( pLT, rect, pHit );
107  result = AssignUIHandlePtr(holder, result);
108  return result;
109  }
110 
111  return {};
112 }
113 
115 {
116 }
117 
119 (LabelTrackHit &hit, const wxMouseEvent & evt,
120  const wxRect & r, const ZoomInfo &zoomInfo,
121  NotifyingSelectedRegion &newSel)
122 {
123  if (evt.ButtonDown())
124  {
125  //OverGlyph sets mMouseOverLabel to be the chosen label.
126  const auto pTrack = mpLT;
127  LabelTrackView::OverGlyph(*pTrack, hit, evt.m_x, evt.m_y);
128 
129  hit.mIsAdjustingLabel = evt.Button(wxMOUSE_BTN_LEFT) &&
130  ( hit.mEdge & 3 ) != 0;
131 
132  if (hit.mIsAdjustingLabel)
133  {
134  auto& view = LabelTrackView::Get(*pTrack);
135  view.ResetTextSelection();
136 
137  double t = 0.0;
138 
139  // When we start dragging the label(s) we don't want them to jump.
140  // so we calculate the displacement of the mouse from the drag center
141  // and use that in subsequent dragging calculations. The mouse stays
142  // at the same relative displacement throughout dragging.
143 
144  // However, if two label's edges are being dragged
145  // then the displacement is relative to the initial average
146  // position of them, and in that case there can be a jump of at most
147  // a few pixels to bring the two label boundaries to exactly the same
148  // position when we start dragging.
149 
150  // Dragging of three label edges at the same time is not supported (yet).
151 
152  const auto &mLabels = pTrack->GetLabels();
153  if( ( hit.mMouseOverLabelRight >= 0 ) &&
154  ( hit.mMouseOverLabelLeft >= 0 )
155  )
156  {
157  t = (mLabels[ hit.mMouseOverLabelRight ].getT1() +
158  mLabels[ hit.mMouseOverLabelLeft ].getT0()) / 2.0f;
159 
160  // If we're moving two edges of same label then it's a move
161  // (label is shrunk to zero and size of zero is preserved)
162  // If we're on a boundary between two different labels,
163  // then it's an adjust.
164  // In both cases the two points coalesce.
165  //
166  // NOTE: seems that it's not neccessary that hitting the both
167  // left and right handles mean that we're dealing with a point,
168  // but the range will be turned into a point on click
169  bool isPointLabel = hit.mMouseOverLabelLeft == hit.mMouseOverLabelRight;
170  // Except! We don't coalesce if both ends are from the same label and
171  // we have deliberately chosen to preserve length, by holding shift down.
172  if (!(isPointLabel && evt.ShiftDown()))
173  {
174  MayAdjustLabel(hit, hit.mMouseOverLabelLeft, -1, false, t);
175  MayAdjustLabel(hit, hit.mMouseOverLabelRight, 1, false, t);
176  wxASSERT(mLabels[hit.mMouseOverLabelRight].getT1() ==
177  mLabels[hit.mMouseOverLabelLeft].getT0());
178  }
179  }
180  else if( hit.mMouseOverLabelRight >=0)
181  {
182  t = mLabels[ hit.mMouseOverLabelRight ].getT1();
183  }
184  else if( hit.mMouseOverLabelLeft >=0)
185  {
186  t = mLabels[ hit.mMouseOverLabelLeft ].getT0();
187  }
188  else if (hit.mMouseOverLabel >= 0)
189  {
190  t = mLabels[hit.mMouseOverLabel].getT0();
191  }
192  mxMouseDisplacement = zoomInfo.TimeToPosition(t, r.x) - evt.m_x;
193  }
194  }
195 }
196 
198 (const TrackPanelMouseEvent &evt, AudacityProject *pProject)
199 {
200  auto result = LabelDefaultClickHandle::Click( evt, pProject );
201 
202  const wxMouseEvent &event = evt.event;
203  auto& selectionState = SelectionState::Get(*pProject);
204  auto& tracks = TrackList::Get(*pProject);
205 
206  auto &viewInfo = ViewInfo::Get( *pProject );
208  *mpHit, event, mRect, viewInfo, viewInfo.selectedRegion);
209 
210  if (! mpHit->mIsAdjustingLabel )
211  {
212  // The positive hit test should have ensured otherwise
213  //wxASSERT(false);
214  result |= RefreshCode::Cancelled;
215  }
216  else
217  // redraw the track.
218  result |= RefreshCode::RefreshCell;
219 
220  return result;
221 }
222 
229 ( LabelTrackHit &hit, int iLabel, int iEdge, bool bAllowSwapping, double fNewTime)
230 {
231  if( iLabel < 0 )
232  return;
233 
234  const auto pTrack = mpLT;
235  const auto &mLabels = pTrack->GetLabels();
236  auto labelStruct = mLabels[ iLabel ];
237 
238  // Adjust the requested edge.
239  bool flipped = labelStruct.AdjustEdge( iEdge, fNewTime );
240  // If the edges did not swap, then we are done.
241  if( ! flipped ) {
242  pTrack->SetLabel( iLabel, labelStruct );
243  return;
244  }
245 
246  // If swapping's not allowed we must also move the edge
247  // we didn't move. Then we're done.
248  if( !bAllowSwapping )
249  {
250  labelStruct.AdjustEdge( -iEdge, fNewTime );
251  pTrack->SetLabel( iLabel, labelStruct );
252  return;
253  }
254 
255  pTrack->SetLabel( iLabel, labelStruct );
256 
257  // Swap our record of what we are dragging.
259 }
260 
261 // If the index is for a real label, adjust its left and right boundary.
262 void LabelGlyphHandle::MayMoveLabel( int iLabel, int iEdge, double fNewTime)
263 {
264  if( iLabel < 0 )
265  return;
266 
267  const auto pTrack = mpLT;
268  const auto &mLabels = pTrack->GetLabels();
269  auto labelStruct = mLabels[ iLabel ];
270  labelStruct.MoveLabel( iEdge, fNewTime );
271  pTrack->SetLabel( iLabel, labelStruct );
272 }
273 
274 // Constrain function, as in processing/arduino.
275 // returned value will be between min and max (inclusive).
276 static int Constrain( int value, int min, int max )
277 {
278  wxASSERT( min <= max );
279  int result=value;
280  if( result < min )
281  result=min;
282  if( result > max )
283  result=max;
284  return result;
285 }
286 
288 (AudacityProject &project,
289  LabelTrackHit &hit, const wxMouseEvent & evt,
290  wxRect & r, const ZoomInfo &zoomInfo,
291  NotifyingSelectedRegion &newSel)
292 {
293  const auto pTrack = mpLT;
294  const auto &mLabels = pTrack->GetLabels();
295  if(evt.LeftUp())
296  {
297  bool updated = false;
298  if( hit.mMouseOverLabelLeft >= 0 ) {
299  auto labelStruct = mLabels[ hit.mMouseOverLabelLeft ];
300  updated |= labelStruct.updated;
301  labelStruct.updated = false;
302  pTrack->SetLabel( hit.mMouseOverLabelLeft, labelStruct );
303  }
304  if( hit.mMouseOverLabelRight >= 0 ) {
305  auto labelStruct = mLabels[ hit.mMouseOverLabelRight ];
306  updated |= labelStruct.updated;
307  labelStruct.updated = false;
308  pTrack->SetLabel( hit.mMouseOverLabelRight, labelStruct );
309  }
310 
311  if (hit.mMouseOverLabel >= 0)
312  {
313  auto labelStruct = mLabels[hit.mMouseOverLabel];
314  if (!labelStruct.updated)
315  {
316  //happens on click over bar between handles (without moving a cursor)
317  newSel = labelStruct.selectedRegion;
318 
319  // IF the user clicked a label, THEN select all other tracks by Label
320  // do nothing if at least one other track is selected
321  auto& selectionState = SelectionState::Get(project);
322  auto& tracks = TrackList::Get(project);
323 
324  bool done = tracks.Selected().any_of(
325  [&](const Track* track) { return track != static_cast<Track*>(pTrack.get()); }
326  );
327 
328  if (!done) {
329  //otherwise, select all tracks
330  for (auto t : tracks.Any())
331  selectionState.SelectTrack(*t, true, true);
332  }
333 
334  // Do this after, for its effect on TrackPanel's memory of last selected
335  // track (which affects shift-click actions)
336  selectionState.SelectTrack(*pTrack.get(), true, true);
337 
338  // PRL: bug1659 -- make selection change undo correctly
339  updated = !ProjectAudioIO::Get(project).IsAudioActive();
340 
341  auto& view = LabelTrackView::Get(*pTrack);
342  view.SetNavigationIndex(hit.mMouseOverLabel);
343  }
344  else
345  {
346  labelStruct.updated = false;
347  pTrack->SetLabel(hit.mMouseOverLabel, labelStruct);
348  updated = true;
349  }
350  }
351 
352  hit.mIsAdjustingLabel = false;
353  hit.mMouseOverLabelLeft = -1;
354  hit.mMouseOverLabelRight = -1;
355  hit.mMouseOverLabel = -1;
356  return updated;
357  }
358 
359  if(evt.Dragging())
360  {
361  //If we are currently adjusting a label,
362  //just reset its value and redraw.
363  // LL: Constrain to inside track rectangle for now. Should be changed
364  // to allow scrolling while dragging labels
365  int x = Constrain( evt.m_x + mxMouseDisplacement - r.x, 0, r.width);
366 
367  double fNewX = zoomInfo.PositionToTime(x, 0);
368  // Moving the whole ranged label(s)
369  if (hit.mMouseOverLabel != -1)
370  {
371  if (evt.ShiftDown())
372  {
373  auto dt = fNewX - mLabels[hit.mMouseOverLabel].getT0();
374  for (auto i = 0, count = static_cast<int>(mLabels.size()); i < count; ++i)
375  MayMoveLabel(i, -1, mLabels[i].getT0() + dt);
376  }
377  else
378  MayMoveLabel(hit.mMouseOverLabel, -1, fNewX);
379  }
380  // If we're on the 'dot' and nowe're moving,
381  // Though shift-down inverts that.
382  // and if both edges the same, then we're always moving the label.
383  else if((hit.mMouseOverLabelLeft == hit.mMouseOverLabelRight) || evt.ShiftDown())
384  {
385  MayMoveLabel( hit.mMouseOverLabelLeft, -1, fNewX );
386  MayMoveLabel( hit.mMouseOverLabelRight, +1, fNewX );
387  }
388  else
389  {
390  // If exactly one edge is selected we allow swapping
391  bool bAllowSwapping =
392  (hit.mMouseOverLabelLeft >= 0) !=
393  (hit.mMouseOverLabelRight >= 0);
394  MayAdjustLabel( hit, hit.mMouseOverLabelLeft, -1, bAllowSwapping, fNewX );
395  MayAdjustLabel( hit, hit.mMouseOverLabelRight, +1, bAllowSwapping, fNewX );
396  }
397 
398  const auto &view = LabelTrackView::Get( *pTrack );
399  auto navigationIndex = view.GetNavigationIndex(project);
400  if(navigationIndex != -1 &&
401  (navigationIndex == hit.mMouseOverLabel ||
402  navigationIndex == hit.mMouseOverLabelLeft ||
403  navigationIndex == hit.mMouseOverLabelRight))
404  {
405  //Set the selection region to be equal to
406  //the NEW size of the label.
407  newSel = mLabels[navigationIndex].selectedRegion;
408  }
409  pTrack->SortLabels();
410  }
411 
412  return false;
413 }
414 
416 (const TrackPanelMouseEvent &evt, AudacityProject *pProject)
417 {
418  auto result = LabelDefaultClickHandle::Drag( evt, pProject );
419 
420  const wxMouseEvent &event = evt.event;
421  auto &viewInfo = ViewInfo::Get( *pProject );
423  *pProject, *mpHit, event, mRect, viewInfo, viewInfo.selectedRegion);
424 
425  // Refresh all so that the change of selection is redrawn in all tracks
427 }
428 
431 {
432  static wxCursor arrowCursor{ wxCURSOR_ARROW };
433  static auto handOpenCursor =
434  MakeCursor(wxCURSOR_HAND, RearrangeCursorXpm, 16, 16);
435  static auto handClosedCursor =
436  MakeCursor(wxCURSOR_HAND, RearrangingCursorXpm, 16, 16);
437 
438  if (mpHit->mMouseOverLabel != -1)
439  {
440  return {
441  XO("Drag label. Hold shift and drag to move all labels on the same track."),
442  mpHit->mIsAdjustingLabel ? &*handClosedCursor : &*handOpenCursor
443  };
444  }
445  else if ((mpHit->mEdge & 4) != 0)
446  return { XO("Drag one or more label boundaries."), &arrowCursor };
447  else
448  return { XO("Drag label boundary."), &arrowCursor };
449 }
450 
452 (const TrackPanelMouseEvent &evt, AudacityProject *pProject,
453  wxWindow *pParent)
454 {
455  auto result = LabelDefaultClickHandle::Release( evt, pProject, pParent );
456 
457  const wxMouseEvent &event = evt.event;
458  auto &viewInfo = ViewInfo::Get( *pProject );
460  *pProject, *mpHit, event, mRect, viewInfo, viewInfo.selectedRegion)) {
461  ProjectHistory::Get( *pProject ).PushState(XO("Modified Label"),
462  XO("Label Edit"),
464  }
465 
466  // Refresh all so that the change of selection is redrawn in all tracks
468 }
469 
471 {
472  ProjectHistory::Get( *pProject ).RollbackState();
473  auto result = LabelDefaultClickHandle::Cancel( pProject );
474  return result | RefreshCode::RefreshAll;
475 }
RefreshCode::DrawOverlays
@ DrawOverlays
Definition: RefreshCode.h:32
ViewInfo::Get
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:241
LabelDefaultClickHandle::Drag
Result Drag(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
Definition: LabelDefaultClickHandle.cpp:83
LabelDefaultClickHandle::Click
Result Click(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
Definition: LabelDefaultClickHandle.cpp:60
RefreshCode::RefreshAll
@ RefreshAll
Definition: RefreshCode.h:26
ZoomInfo
Definition: ZoomInfo.h:47
MakeCursor
std::unique_ptr< wxCursor > MakeCursor(int WXUNUSED(CursorId), const char *const pXpm[36], int HotX, int HotY)
Definition: TrackPanel.cpp:182
LabelGlyphHandle::Enter
void Enter(bool forward, AudacityProject *) override
Definition: LabelGlyphHandle.cpp:76
LabelTrackEvent::mFormerPosition
int mFormerPosition
Definition: LabelTrack.h:207
RefreshCode::Cancelled
@ Cancelled
Definition: RefreshCode.h:23
XO
#define XO(s)
Definition: Internat.h:31
LabelTrackHit::mpLT
std::shared_ptr< LabelTrack > mpLT
Definition: LabelGlyphHandle.h:44
LabelGlyphHandle::HitTest
static UIHandlePtr HitTest(std::weak_ptr< LabelGlyphHandle > &holder, const wxMouseState &state, const std::shared_ptr< LabelTrack > &pLT, const wxRect &rect)
Definition: LabelGlyphHandle.cpp:91
LabelGlyphHandle::HandleGlyphDragRelease
bool HandleGlyphDragRelease(AudacityProject &project, LabelTrackHit &hit, const wxMouseEvent &evt, wxRect &r, const ZoomInfo &zoomInfo, NotifyingSelectedRegion &newSel)
Definition: LabelGlyphHandle.cpp:288
LabelGlyphHandle::MayAdjustLabel
void MayAdjustLabel(LabelTrackHit &hit, int iLabel, int iEdge, bool bAllowSwapping, double fNewTime)
Definition: LabelGlyphHandle.cpp:229
ProjectAudioIO::Get
static ProjectAudioIO & Get(AudacityProject &project)
Definition: ProjectAudioIO.cpp:22
LabelGlyphHandle::Release
Result Release(const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *pParent) override
Definition: LabelGlyphHandle.cpp:452
LabelTrackEvent::mPresentPosition
int mPresentPosition
Definition: LabelTrack.h:210
ZoomInfo::TimeToPosition
wxInt64 TimeToPosition(double time, wxInt64 origin=0, bool ignoreFisheye=false) const
STM: Converts a project time to screen x position.
Definition: ZoomInfo.cpp:49
LabelGlyphHandle::Drag
Result Drag(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
Definition: LabelGlyphHandle.cpp:416
ProjectAudioIO::IsAudioActive
bool IsAudioActive() const
Definition: ProjectAudioIO.cpp:51
LabelTrackHit::mEdge
int mEdge
Definition: LabelGlyphHandle.h:37
LabelGlyphHandle::~LabelGlyphHandle
virtual ~LabelGlyphHandle()
Definition: LabelGlyphHandle.cpp:114
LabelGlyphHandle::NeedChangeHighlight
static UIHandle::Result NeedChangeHighlight(const LabelGlyphHandle &oldState, const LabelGlyphHandle &newState)
Definition: LabelGlyphHandle.cpp:82
LabelGlyphHandle::mRect
wxRect mRect
Definition: LabelGlyphHandle.h:107
LabelTrackHit::LabelTrackHit
LabelTrackHit(const std::shared_ptr< LabelTrack > &pLT)
Definition: LabelGlyphHandle.cpp:30
UIHandle::mChangeHighlight
Result mChangeHighlight
Definition: UIHandle.h:139
LabelTrackView::OverGlyph
static void OverGlyph(const LabelTrack &track, LabelTrackHit &hit, int x, int y)
Definition: LabelTrackView.cpp:1209
LabelGlyphHandle::Click
Result Click(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
Definition: LabelGlyphHandle.cpp:198
LabelDefaultClickHandle::Cancel
Result Cancel(AudacityProject *pProject) override
Definition: LabelDefaultClickHandle.cpp:96
UIHandle::Result
unsigned Result
Definition: UIHandle.h:38
LabelTrackHit::~LabelTrackHit
~LabelTrackHit()
Definition: LabelGlyphHandle.cpp:37
LabelGlyphHandle::LabelGlyphHandle
LabelGlyphHandle(const std::shared_ptr< LabelTrack > &pLT, const wxRect &rect, const std::shared_ptr< LabelTrackHit > &pHit)
Definition: LabelGlyphHandle.cpp:68
Constrain
static int Constrain(int value, int min, int max)
Definition: LabelGlyphHandle.cpp:276
LabelTrackView.h
UIHandlePtr
std::shared_ptr< UIHandle > UIHandlePtr
Definition: CellularPanel.h:28
LabelTrackHit::mMouseOverLabelRight
int mMouseOverLabelRight
Keeps track of which left label the mouse is currently over.
Definition: LabelGlyphHandle.h:41
HitTestPreview
Definition: HitTestResult.h:20
LabelTrackHit::mMouseOverLabel
int mMouseOverLabel
Definition: LabelGlyphHandle.h:39
LabelTrackView::Get
static LabelTrackView & Get(LabelTrack &)
Definition: LabelTrackView.cpp:162
anonymous_namespace{NoteTrack.cpp}::swap
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
Definition: NoteTrack.cpp:735
LabelTrackEvent
Definition: LabelTrack.h:184
LabelGlyphHandle::HandleGlyphClick
void HandleGlyphClick(LabelTrackHit &hit, const wxMouseEvent &evt, const wxRect &r, const ZoomInfo &zoomInfo, NotifyingSelectedRegion &newSel)
Definition: LabelGlyphHandle.cpp:119
RefreshCode::RefreshCell
@ RefreshCell
Definition: RefreshCode.h:24
ViewInfo.h
LabelGlyphHandle::mxMouseDisplacement
int mxMouseDisplacement
Displacement of mouse cursor from the centre being dragged.
Definition: LabelGlyphHandle.h:110
LabelTrackHit::mIsAdjustingLabel
bool mIsAdjustingLabel
Keeps track of which right label the mouse is currently over.
Definition: LabelGlyphHandle.h:42
LabelDefaultClickHandle::Release
Result Release(const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *pParent) override
Definition: LabelDefaultClickHandle.cpp:89
LabelGlyphHandle.h
SelectionState::Get
static SelectionState & Get(AudacityProject &project)
Definition: SelectionState.cpp:20
min
int min(int a, int b)
Definition: CompareAudioCommand.cpp:106
LabelGlyphHandle
Definition: LabelGlyphHandle.h:50
ProjectHistory::PushState
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
Definition: ProjectHistory.cpp:90
TrackList::Get
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:506
LabelGlyphHandle::Cancel
Result Cancel(AudacityProject *pProject) override
Definition: LabelGlyphHandle.cpp:470
LabelGlyphHandle::mpLT
std::shared_ptr< LabelTrack > mpLT
Definition: LabelGlyphHandle.h:106
LabelGlyphHandle::mpHit
std::shared_ptr< LabelTrackHit > mpHit
Definition: LabelGlyphHandle.h:85
Track
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:239
ProjectHistory::RollbackState
void RollbackState()
Definition: ProjectHistory.cpp:117
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
TrackPanelMouseEvent
Definition: TrackPanelMouseEvent.h:46
LabelGlyphHandle::Preview
HitTestPreview Preview(const TrackPanelMouseState &state, AudacityProject *pProject) override
Definition: LabelGlyphHandle.cpp:430
TrackPanelMouseState
Definition: TrackPanelMouseEvent.h:28
UndoPush::CONSOLIDATE
@ CONSOLIDATE
TrackListEvent::mpTrack
std::weak_ptr< Track > mpTrack
Definition: Track.h:1238
AssignUIHandlePtr
std::shared_ptr< Subclass > AssignUIHandlePtr(std::weak_ptr< Subclass > &holder, const std::shared_ptr< Subclass > &pNew)
Definition: UIHandle.h:151
LabelTrackHit
Definition: LabelGlyphHandle.h:33
LabelTrackHit::mMouseOverLabelLeft
int mMouseOverLabelLeft
Keeps track of which (ranged) label the mouse is currently over.
Definition: LabelGlyphHandle.h:40
TrackPanelMouseEvent::event
wxMouseEvent & event
Definition: TrackPanelMouseEvent.h:58
LabelTrackHit::OnLabelPermuted
void OnLabelPermuted(LabelTrackEvent &e)
Definition: LabelGlyphHandle.cpp:44
ProjectHistory::Get
static ProjectHistory & Get(AudacityProject &project)
Definition: ProjectHistory.cpp:26
ZoomInfo::PositionToTime
double PositionToTime(wxInt64 position, wxInt64 origin=0, bool ignoreFisheye=false) const
Definition: ZoomInfo.cpp:39
LabelGlyphHandle::MayMoveLabel
void MayMoveLabel(int iLabel, int iEdge, double fNewTime)
Definition: LabelGlyphHandle.cpp:262
NotifyingSelectedRegion
Definition: ViewInfo.h:44