Audacity  2.3.1
Public Member Functions | Static Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
TimeShiftHandle Class Referencefinal

#include <TimeShiftHandle.h>

Inheritance diagram for TimeShiftHandle:
UIHandle

Public Member Functions

 TimeShiftHandle (const std::shared_ptr< Track > &pTrack, bool gripHit)
 
TimeShiftHandleoperator= (const TimeShiftHandle &)=default
 
bool IsGripHit () const
 
std::shared_ptr< TrackGetTrack () const
 
virtual ~TimeShiftHandle ()
 
void Enter (bool forward) override
 
Result Click (const TrackPanelMouseEvent &event, AudacityProject *pProject) override
 
Result Drag (const TrackPanelMouseEvent &event, AudacityProject *pProject) override
 
HitTestPreview Preview (const TrackPanelMouseState &state, const AudacityProject *pProject) override
 
Result Release (const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *pParent) override
 
Result Cancel (AudacityProject *pProject) override
 
void DrawExtras (DrawingPass pass, wxDC *dc, const wxRegion &, const wxRect &panelRect) override
 
bool StopsOnKeystroke () override
 
- Public Member Functions inherited from UIHandle
virtual ~UIHandle ()=0
 
virtual bool HasRotation () const
 
virtual bool Rotate (bool forward)
 
virtual bool HasEscape () const
 
virtual bool Escape ()
 
virtual void OnProjectChange (AudacityProject *pProject)
 
Result GetChangeHighlight () const
 
void SetChangeHighlight (Result val)
 

Static Public Member Functions

static void CreateListOfCapturedClips (ClipMoveState &state, const ViewInfo &viewInfo, Track &capturedTrack, TrackList &trackList, bool syncLocked, double clickTime)
 
static void DoSlideHorizontal (ClipMoveState &state, TrackList &trackList, Track &capturedTrack)
 
static bool DoSlideVertical (ViewInfo &viewInfo, wxCoord xx, ClipMoveState &state, TrackList &trackList, Track &capturedTrack, Track &dstTrack, double &desiredSlideAmount)
 
static UIHandlePtr HitAnywhere (std::weak_ptr< TimeShiftHandle > &holder, const std::shared_ptr< Track > &pTrack, bool gripHit)
 
static UIHandlePtr HitTest (std::weak_ptr< TimeShiftHandle > &holder, const wxMouseState &state, const wxRect &rect, const std::shared_ptr< Track > &pTrack)
 
- Static Public Member Functions inherited from UIHandle
static UIHandle::Result NeedChangeHighlight (const UIHandle &, const UIHandle &)
 

Private Member Functions

 TimeShiftHandle (const TimeShiftHandle &)=delete
 

Static Private Member Functions

static HitTestPreview HitPreview (const AudacityProject *pProject, bool unsafe)
 

Private Attributes

std::shared_ptr< TrackmCapturedTrack
 
wxRect mRect {}
 
bool mDidSlideVertically {}
 
bool mSlideUpDownOnly {}
 
bool mSnapPreferRightEdge {}
 
std::shared_ptr< SnapManagermSnapManager {}
 
ClipMoveState mClipMoveState {}
 
bool mGripHit {}
 

Additional Inherited Members

- Public Types inherited from UIHandle
enum  DrawingPass { Cells, Panel }
 
using Result = unsigned
 
using Cell = TrackPanelCell
 
- Protected Attributes inherited from UIHandle
Result mChangeHighlight { 0 }
 

Detailed Description

Definition at line 47 of file TimeShiftHandle.h.

Constructor & Destructor Documentation

TimeShiftHandle::TimeShiftHandle ( const TimeShiftHandle )
privatedelete
TimeShiftHandle::TimeShiftHandle ( const std::shared_ptr< Track > &  pTrack,
bool  gripHit 
)
explicit

Definition at line 28 of file TimeShiftHandle.cpp.

29  : mCapturedTrack{ pTrack }
30  , mGripHit{ gripHit }
31 {
32 }
std::shared_ptr< Track > mCapturedTrack
TimeShiftHandle::~TimeShiftHandle ( )
virtual

Definition at line 95 of file TimeShiftHandle.cpp.

96 {
97 }

Member Function Documentation

UIHandle::Result TimeShiftHandle::Cancel ( AudacityProject pProject)
overridevirtual

Implements UIHandle.

Definition at line 839 of file TimeShiftHandle.cpp.

References RefreshCode::RefreshAll, and AudacityProject::RollbackState().

840 {
841  pProject->RollbackState();
843 }
void RollbackState()
Definition: Project.cpp:4657
UIHandle::Result TimeShiftHandle::Click ( const TrackPanelMouseEvent event,
AudacityProject pProject 
)
overridevirtual

Implements UIHandle.

Definition at line 350 of file TimeShiftHandle.cpp.

References RefreshCode::Cancelled, TrackList::clear(), TrackPanelMouseEvent::event, WaveTrack::GetClipAtX(), Track::GetSelected(), AudacityProject::GetToolsToolBar(), AudacityProject::GetTracks(), AudacityProject::GetViewInfo(), if(), AudacityProject::IsAudioActive(), multiTool, TrackPanelMouseEvent::pCell, ZoomInfo::PositionToTime(), TrackPanelMouseEvent::rect, ViewInfo::selectedRegion, SelectedRegion::t0(), SelectedRegion::t1(), and Track::TypeSwitch().

351 {
352  using namespace RefreshCode;
353  const bool unsafe = pProject->IsAudioActive();
354  if ( unsafe )
355  return Cancelled;
356 
357  const wxMouseEvent &event = evt.event;
358  const wxRect &rect = evt.rect;
359  const ViewInfo &viewInfo = pProject->GetViewInfo();
360 
361  const auto pTrack = std::static_pointer_cast<Track>(evt.pCell);
362  if (!pTrack)
363  return RefreshCode::Cancelled;
364 
365  TrackList *const trackList = pProject->GetTracks();
366 
368  mDidSlideVertically = false;
369 
370  ToolsToolBar *const ttb = pProject->GetToolsToolBar();
371  const bool multiToolModeActive = (ttb && ttb->IsDown(multiTool));
372 
373  const double clickTime =
374  viewInfo.PositionToTime(event.m_x, rect.x);
376  (pTrack->GetSelected() &&
377  clickTime >= viewInfo.selectedRegion.t0() &&
378  clickTime < viewInfo.selectedRegion.t1());
379 
382 
383  bool ok = true;
384  bool captureClips = false;
385 
386  if (!event.ShiftDown())
387  pTrack->TypeSwitch(
388  [&](WaveTrack *wt) {
389  if (nullptr ==
390  (mClipMoveState.capturedClip = wt->GetClipAtX(event.m_x)))
391  ok = false;
392  else
393  captureClips = true;
394  },
395 #ifdef USE_MIDI
396  [&](NoteTrack *) {
397  captureClips = true;
398  }
399 #endif
400  );
401 
402  if ( ! ok )
403  return Cancelled;
404  else if ( captureClips )
406  ( mClipMoveState, viewInfo, *pTrack, *trackList,
407  pProject->IsSyncLocked(), clickTime );
408 
409  mSlideUpDownOnly = event.CmdDown() && !multiToolModeActive;
410  mRect = rect;
411  mClipMoveState.mMouseClickX = event.m_x;
412  mSnapManager = std::make_shared<SnapManager>(trackList,
413  &viewInfo,
416  true); // don't snap to time
421  (fabs(clickTime - mClipMoveState.capturedClip->GetEndTime()) <
422  fabs(clickTime - mClipMoveState.capturedClip->GetStartTime()));
423 
424  return RefreshNone;
425 }
A list of TrackListNode items.
Definition: Track.h:1115
ViewInfo is used mainly to hold the zooming, selection and scroll information. It also has some statu...
Definition: ViewInfo.h:141
double GetStartTime() const
Definition: WaveClip.cpp:421
bool capturedClipIsSelection
WaveClip * capturedClip
ToolsToolBar * GetToolsToolBar()
Definition: Project.cpp:4972
ClipMoveState mClipMoveState
WaveClip * GetClipAtX(int xcoord)
Definition: WaveTrack.cpp:2176
std::shared_ptr< SnapManager > mSnapManager
A Track that contains audio waveform data.
Definition: WaveTrack.h:60
Fundamental data object of Audacity, placed in the TrackPanel. Classes derived form it include the Wa...
Definition: Track.h:190
TrackClipArray capturedClipArray
if(pTrack &&pTrack->GetDisplay()!=WaveTrack::Spectrum)
bool IsAudioActive() const
Definition: Project.cpp:1462
bool IsSyncLocked()
Definition: Project.cpp:5547
static void CreateListOfCapturedClips(ClipMoveState &state, const ViewInfo &viewInfo, Track &capturedTrack, TrackList &trackList, bool syncLocked, double clickTime)
A kind of ToolBar with Tools on it.
Definition: ToolsToolBar.h:49
double GetEndTime() const
Definition: WaveClip.cpp:427
TrackArray trackExclusions
TrackList * GetTracks()
Definition: Project.h:192
const ViewInfo & GetViewInfo() const
Definition: Project.h:207
A Track that is used for Midi notes. (Somewhat old code).
void TimeShiftHandle::CreateListOfCapturedClips ( ClipMoveState state,
const ViewInfo viewInfo,
Track capturedTrack,
TrackList trackList,
bool  syncLocked,
double  clickTime 
)
static

Definition at line 232 of file TimeShiftHandle.cpp.

References ClipMoveState::capturedClip, ClipMoveState::capturedClipArray, ClipMoveState::capturedClipIsSelection, TrackList::Channels(), Track::GetStartTime(), TrackList::Selected(), and TrackList::SyncLockGroup().

Referenced by MenuCommandHandler::OnClipMove().

234 {
235 // The captured clip is the focus, but we need to create a list
236  // of all clips that have to move, also...
237 
238  state.capturedClipArray.clear();
239 
240  // First, if click was in selection, capture selected clips; otherwise
241  // just the clicked-on clip
242  if ( state.capturedClipIsSelection )
243  for (auto t : trackList.Selected())
244  AddClipsToCaptured( state, viewInfo, t, true );
245  else {
246  state.capturedClipArray.push_back
247  (TrackClip( &capturedTrack, state.capturedClip ));
248 
249  if (state.capturedClip) {
250  // Check for other channels
251  auto wt = static_cast<WaveTrack*>(&capturedTrack);
252  for ( auto channel : TrackList::Channels( wt ).Excluding( wt ) )
253  if (WaveClip *const clip = FindClipAtTime(channel, clickTime))
254  state.capturedClipArray.push_back(TrackClip(channel, clip));
255  }
256  }
257 
258  // Now, if sync-lock is enabled, capture any clip that's linked to a
259  // captured clip.
260  if ( syncLocked ) {
261  // AWD: capturedClipArray expands as the loop runs, so newly-added
262  // clips are considered (the effect is like recursion and terminates
263  // because AddClipsToCaptured doesn't add duplicate clips); to remove
264  // this behavior just store the array size beforehand.
265  for (unsigned int i = 0; i < state.capturedClipArray.size(); ++i) {
266  {
267  auto &trackClip = state.capturedClipArray[i];
268  // Capture based on tracks that have clips -- that means we
269  // don't capture based on links to label tracks for now (until
270  // we can treat individual labels as clips)
271  if ( trackClip.clip ) {
272  // Iterate over sync-lock group tracks.
273  for (auto t : TrackList::SyncLockGroup( trackClip.track ))
274  AddClipsToCaptured(state, t,
275  trackClip.clip->GetStartTime(),
276  trackClip.clip->GetEndTime() );
277  }
278  }
279 #ifdef USE_MIDI
280  {
281  // Beware relocation of array contents! Bind trackClip again.
282  auto &trackClip = state.capturedClipArray[i];
283  // Capture additional clips from NoteTracks
284  trackClip.track->TypeSwitch( [&](NoteTrack *nt) {
285  // Iterate over sync-lock group tracks.
286  for (auto t : TrackList::SyncLockGroup(nt))
287  AddClipsToCaptured
288  ( state, t, nt->GetStartTime(), nt->GetEndTime() );
289  });
290  }
291 #endif
292  }
293  }
294 }
Definition: Snap.h:34
bool capturedClipIsSelection
WaveClip * capturedClip
auto Selected() -> TrackIterRange< TrackType >
Definition: Track.h:1212
This allows multiple clips to be a part of one WaveTrack.
Definition: WaveClip.h:176
A Track that contains audio waveform data.
Definition: WaveTrack.h:60
TrackClipArray capturedClipArray
static TrackIterRange< Track > SyncLockGroup(Track *pTrack)
Definition: Track.cpp:627
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1305
A Track that is used for Midi notes. (Somewhat old code).
void TimeShiftHandle::DoSlideHorizontal ( ClipMoveState state,
TrackList trackList,
Track capturedTrack 
)
static

Definition at line 297 of file TimeShiftHandle.cpp.

References ClipMoveState::capturedClipArray, TrackList::GetEndTime(), TrackList::GetStartTime(), ClipMoveState::hSlideAmount, ClipMoveState::snapLeft, and ClipMoveState::snapRight.

Referenced by MenuCommandHandler::OnClipMove().

298 {
299  // Given a signed slide distance, move clips, but subject to constraint of
300  // non-overlapping with other clips, so the distance may be adjusted toward
301  // zero.
302  if ( state.capturedClipArray.size() )
303  {
304  double allowed;
305  double initialAllowed;
306  double safeBigDistance = 1000 + 2.0 * ( trackList.GetEndTime() -
307  trackList.GetStartTime() );
308 
309  do { // loop to compute allowed, does not actually move anything yet
310  initialAllowed = state.hSlideAmount;
311 
312  for ( auto &trackClip : state.capturedClipArray ) {
313  if (const auto clip = trackClip.clip) {
314  // only audio clips are used to compute allowed
315  const auto track = static_cast<WaveTrack *>( trackClip.track );
316 
317  // Move all other selected clips totally out of the way
318  // temporarily because they're all moving together and
319  // we want to find out if OTHER clips are in the way,
320  // not one of the moving ones
321  DoOffset( state, nullptr, -safeBigDistance, clip );
322  auto cleanup = finally( [&]
323  { DoOffset( state, nullptr, safeBigDistance, clip ); } );
324 
325  if ( track->CanOffsetClip(clip, state.hSlideAmount, &allowed) ) {
326  if ( state.hSlideAmount != allowed ) {
327  state.hSlideAmount = allowed;
328  state.snapLeft = state.snapRight = -1; // see bug 1067
329  }
330  }
331  else {
332  state.hSlideAmount = 0.0;
333  state.snapLeft = state.snapRight = -1; // see bug 1067
334  }
335  }
336  }
337  } while ( state.hSlideAmount != initialAllowed );
338 
339  // finally, here is where clips are moved
340  if ( state.hSlideAmount != 0.0 )
341  DoOffset( state, nullptr, state.hSlideAmount );
342  }
343  else
344  // For Shift key down, or
345  // For non wavetracks, specifically label tracks ...
346  DoOffset( state, &capturedTrack, state.hSlideAmount );
347 }
double GetStartTime() const
Definition: Track.cpp:1165
double GetEndTime() const
Definition: Track.cpp:1170
A Track that contains audio waveform data.
Definition: WaveTrack.h:60
TrackClipArray capturedClipArray
bool TimeShiftHandle::DoSlideVertical ( ViewInfo viewInfo,
wxCoord  xx,
ClipMoveState state,
TrackList trackList,
Track capturedTrack,
Track dstTrack,
double &  desiredSlideAmount 
)
static

Definition at line 609 of file TimeShiftHandle.cpp.

References ClipMoveState::capturedClipArray, ClipMoveState::capturedClipIsSelection, ClipMoveState::hSlideAmount, ClipMoveState::mMouseClickX, SelectedRegion::move(), WaveClip::Offset(), ZoomInfo::PositionToTime(), and ViewInfo::selectedRegion.

612 {
613  if (!FindCorrespondence( trackList, dstTrack, capturedTrack, state))
614  return false;
615 
616  // Having passed that test, remove clips temporarily from their
617  // tracks, so moving clips don't interfere with each other
618  // when we call CanInsertClip()
619  TemporaryClipRemover remover{ state };
620 
621  // Now check that the move is possible
622  double slide = desiredSlideAmount; // remember amount requested.
623  // The test for tolerance will need review with FishEye!
624  // The tolerance is supposed to be the time for one pixel,
625  // i.e. one pixel tolerance at current zoom.
626  double tolerance =
627  viewInfo.PositionToTime(xx + 1) - viewInfo.PositionToTime(xx);
628  bool ok = CheckFit( viewInfo, xx, state, tolerance, desiredSlideAmount );
629 
630  if (!ok) {
631  // Failure, even with using tolerance.
632  remover.Fail();
633 
634  // Failure -- we'll put clips back where they were
635  // ok will next indicate if a horizontal slide is OK.
636  tolerance = 0.0;
637  desiredSlideAmount = slide;
638  ok = CheckFit( viewInfo, xx, state, tolerance, desiredSlideAmount );
639  for ( auto &trackClip : state.capturedClipArray) {
640  WaveClip *const pSrcClip = trackClip.clip;
641  if (pSrcClip){
642 
643  // Attempt to move to a new track did not work.
644  // Put the clip back appropriately shifted!
645  if( ok)
646  trackClip.holder->Offset(slide);
647  }
648  }
649  // Make the offset permanent; start from a "clean slate"
650  if( ok ) {
651  state.mMouseClickX = xx;
652  if (state.capturedClipIsSelection) {
653  // Slide the selection, too
654  viewInfo.selectedRegion.move( slide );
655  }
656  state.hSlideAmount = 0;
657  }
658 
659  return false;
660  }
661 
662  // Make the offset permanent; start from a "clean slate"
663  state.mMouseClickX = xx;
664  return true;
665 }
SelectedRegion selectedRegion
Definition: ViewInfo.h:160
void Offset(double delta)
Definition: WaveClip.h:223
double PositionToTime(wxInt64 position, wxInt64 origin=0, bool ignoreFisheye=false) const
Definition: ViewInfo.cpp:49
bool capturedClipIsSelection
void move(double delta)
This allows multiple clips to be a part of one WaveTrack.
Definition: WaveClip.h:176
TrackClipArray capturedClipArray
UIHandle::Result TimeShiftHandle::Drag ( const TrackPanelMouseEvent event,
AudacityProject pProject 
)
overridevirtual

Implements UIHandle.

Definition at line 668 of file TimeShiftHandle.cpp.

References RefreshCode::Cancelled, TrackPanelMouseEvent::event, AudacityProject::GetTracks(), AudacityProject::GetViewInfo(), AudacityProject::IsAudioActive(), SelectedRegion::move(), TrackPanelMouseEvent::pCell, Track::Pointer(), RefreshCode::RefreshAll, RefreshCode::RefreshNone, ViewInfo::selectedRegion, and Track::TypeSwitch().

669 {
670  using namespace RefreshCode;
671  const bool unsafe = pProject->IsAudioActive();
672  if (unsafe) {
673  this->Cancel(pProject);
674  return RefreshAll | Cancelled;
675  }
676 
677  const wxMouseEvent &event = evt.event;
678  ViewInfo &viewInfo = pProject->GetViewInfo();
679 
680  Track *track = dynamic_cast<Track*>(evt.pCell.get());
681 
682  // Uncommenting this permits drag to continue to work even over the controls area
683  /*
684  track = static_cast<CommonTrackPanelCell*>(evt.pCell)->FindTrack().get();
685  */
686 
687  if (!track) {
688  // Allow sliding if the pointer is not over any track, but only if x is
689  // within the bounds of the tracks area.
690  if (event.m_x >= mRect.GetX() &&
691  event.m_x < mRect.GetX() + mRect.GetWidth())
692  track = mCapturedTrack.get();
693  }
694 
695  // May need a shared_ptr to reassign mCapturedTrack below
696  auto pTrack = Track::Pointer( track );
697  if (!pTrack)
699 
700 
701  TrackList *const trackList = pProject->GetTracks();
702 
703  // GM: DoSlide now implementing snap-to
704  // samples functionality based on sample rate.
705 
706  // Start by undoing the current slide amount; everything
707  // happens relative to the original horizontal position of
708  // each clip...
709  DoOffset(
711 
713  // Slide the selection, too
714  viewInfo.selectedRegion.move( -mClipMoveState.hSlideAmount );
715  }
717 
718  double desiredSlideAmount =
719  FindDesiredSlideAmount( viewInfo, mRect.x, event, mSnapManager.get(),
721  *mCapturedTrack, *pTrack );
722 
723  // Scroll during vertical drag.
724  // EnsureVisible(pTrack); //vvv Gale says this has problems on Linux, per bug 393 thread. Revert for 2.0.2.
725  bool slidVertically = false;
726 
727  // If the mouse is over a track that isn't the captured track,
728  // decide which tracks the captured clips should go to.
729  bool fail = (
731  pTrack != mCapturedTrack
732  /* && !mCapturedClipIsSelection*/
733  && pTrack->TypeSwitch<bool>( [&] (WaveTrack *) {
734  if ( DoSlideVertical( viewInfo, event.m_x, mClipMoveState,
735  *trackList, *mCapturedTrack, *pTrack, desiredSlideAmount ) ) {
736  mCapturedTrack = pTrack;
737  mDidSlideVertically = true;
738  }
739  else
740  return true;
741 
742  // Not done yet, check for horizontal movement.
743  slidVertically = true;
744  return false;
745  })
746  );
747 
748  if (fail)
749  return RefreshAll;
750 
751  if (desiredSlideAmount == 0.0)
752  return RefreshAll;
753 
754  mClipMoveState.hSlideAmount = desiredSlideAmount;
755 
757 
759  // Slide the selection, too
760  viewInfo.selectedRegion.move( mClipMoveState.hSlideAmount );
761  }
762 
763  if (slidVertically) {
764  // NEW origin
766  }
767 
768  return RefreshAll;
769 }
static void DoSlideHorizontal(ClipMoveState &state, TrackList &trackList, Track &capturedTrack)
A list of TrackListNode items.
Definition: Track.h:1115
ViewInfo is used mainly to hold the zooming, selection and scroll information. It also has some statu...
Definition: ViewInfo.h:141
bool capturedClipIsSelection
WaveClip * capturedClip
ClipMoveState mClipMoveState
static bool DoSlideVertical(ViewInfo &viewInfo, wxCoord xx, ClipMoveState &state, TrackList &trackList, Track &capturedTrack, Track &dstTrack, double &desiredSlideAmount)
std::shared_ptr< SnapManager > mSnapManager
A Track that contains audio waveform data.
Definition: WaveTrack.h:60
Fundamental data object of Audacity, placed in the TrackPanel. Classes derived form it include the Wa...
Definition: Track.h:190
Result Cancel(AudacityProject *pProject) override
bool IsAudioActive() const
Definition: Project.cpp:1462
std::shared_ptr< Track > mCapturedTrack
TrackList * GetTracks()
Definition: Project.h:192
static std::shared_ptr< Subclass > Pointer(Track *t)
Definition: Track.h:230
const ViewInfo & GetViewInfo() const
Definition: Project.h:207
void TimeShiftHandle::DrawExtras ( DrawingPass  pass,
wxDC *  dc,
const wxRegion &  ,
const wxRect &  panelRect 
)
overridevirtual

Reimplemented from UIHandle.

Definition at line 846 of file TimeShiftHandle.cpp.

848 {
849  if (pass == Panel) {
850  // Draw snap guidelines if we have any
851  if ( mSnapManager )
852  mSnapManager->Draw
854  }
855 }
ClipMoveState mClipMoveState
std::shared_ptr< SnapManager > mSnapManager
void TimeShiftHandle::Enter ( bool  forward)
overridevirtual

Reimplemented from UIHandle.

Definition at line 34 of file TimeShiftHandle.cpp.

References UIHandle::mChangeHighlight, and RefreshCode::RefreshCell.

35 {
36 #ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING
38 #endif
39 }
Result mChangeHighlight
Definition: UIHandle.h:150
std::shared_ptr<Track> TimeShiftHandle::GetTrack ( ) const
inline

Definition at line 60 of file TimeShiftHandle.h.

References mCapturedTrack.

60 { return mCapturedTrack; }
std::shared_ptr< Track > mCapturedTrack
UIHandlePtr TimeShiftHandle::HitAnywhere ( std::weak_ptr< TimeShiftHandle > &  holder,
const std::shared_ptr< Track > &  pTrack,
bool  gripHit 
)
static

Definition at line 62 of file TimeShiftHandle.cpp.

References AssignUIHandlePtr().

Referenced by WaveTrack::DetailedHitTest(), HitPreview(), and Track::HitTest().

64 {
65  auto result = std::make_shared<TimeShiftHandle>( pTrack, gripHit );
66  result = AssignUIHandlePtr(holder, result);
67  return result;
68 }
std::shared_ptr< Subclass > AssignUIHandlePtr(std::weak_ptr< Subclass > &holder, const std::shared_ptr< Subclass > &pNew)
Definition: UIHandle.h:162
HitTestPreview TimeShiftHandle::HitPreview ( const AudacityProject pProject,
bool  unsafe 
)
staticprivate

Definition at line 42 of file TimeShiftHandle.cpp.

References _(), HitAnywhere(), and MakeCursor().

43 {
44  static auto disabledCursor =
45  ::MakeCursor(wxCURSOR_NO_ENTRY, DisabledCursorXpm, 16, 16);
46  static auto slideCursor =
47  MakeCursor(wxCURSOR_SIZEWE, TimeCursorXpm, 16, 16);
48  // TODO: Should it say "track or clip" ? Non-wave tracks can move, or clips in a wave track.
49  // TODO: mention effects of shift (move all clips of selected wave track) and ctrl (move vertically only) ?
50  // -- but not all of that is available in multi tool.
51  auto message = _("Click and drag to move a track in time");
52 
53  return {
54  message,
55  (unsafe
56  ? &*disabledCursor
57  : &*slideCursor)
58  };
59 }
_("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
std::unique_ptr< wxCursor > MakeCursor(int WXUNUSED(CursorId), const char *const pXpm[36], int HotX, int HotY)
Definition: TrackPanel.cpp:261
UIHandlePtr TimeShiftHandle::HitTest ( std::weak_ptr< TimeShiftHandle > &  holder,
const wxMouseState &  state,
const wxRect &  rect,
const std::shared_ptr< Track > &  pTrack 
)
static

method that tells us if the mouse event landed on a time-slider that allows us to time shift the sequence. (Those are the two "grips" drawn at left and right edges for multi tool mode.)

Definition at line 71 of file TimeShiftHandle.cpp.

Referenced by WaveTrack::DetailedHitTest().

74 {
78 
79  // Perhaps we should delegate this to TrackArtist as only TrackArtist
80  // knows what the real sizes are??
81 
82  // The drag Handle width includes border, width and a little extra margin.
83  const int adjustedDragHandleWidth = 14;
84  // The hotspot for the cursor isn't at its centre. Adjust for this.
85  const int hotspotOffset = 5;
86 
87  // We are doing an approximate test here - is the mouse in the right or left border?
88  if (!(state.m_x + hotspotOffset < rect.x + adjustedDragHandleWidth ||
89  state.m_x + hotspotOffset >= rect.x + rect.width - adjustedDragHandleWidth))
90  return {};
91 
92  return HitAnywhere( holder, pTrack, true );
93 }
static UIHandlePtr HitAnywhere(std::weak_ptr< TimeShiftHandle > &holder, const std::shared_ptr< Track > &pTrack, bool gripHit)
bool TimeShiftHandle::IsGripHit ( ) const
inline

Definition at line 59 of file TimeShiftHandle.h.

References mGripHit.

Referenced by TrackArtist::DrawWaveform().

59 { return mGripHit; }
TimeShiftHandle& TimeShiftHandle::operator= ( const TimeShiftHandle )
default
HitTestPreview TimeShiftHandle::Preview ( const TrackPanelMouseState state,
const AudacityProject pProject 
)
overridevirtual

Implements UIHandle.

Definition at line 772 of file TimeShiftHandle.cpp.

References AudacityProject::IsAudioActive().

773 {
774  // After all that, it still may be unsafe to drag.
775  // Even if so, make an informative cursor change from default to "banned."
776  const bool unsafe = pProject->IsAudioActive();
777  return HitPreview(pProject, unsafe);
778 }
static HitTestPreview HitPreview(const AudacityProject *pProject, bool unsafe)
bool IsAudioActive() const
Definition: Project.cpp:1462
UIHandle::Result TimeShiftHandle::Release ( const TrackPanelMouseEvent event,
AudacityProject pProject,
wxWindow *  pParent 
)
overridevirtual

Implements UIHandle.

Definition at line 781 of file TimeShiftHandle.cpp.

References _(), AUTOSAVE, CONSOLIDATE, RefreshCode::FixScrollbars, AudacityProject::IsAudioActive(), WaveClip::MarkChanged(), AudacityProject::PushState(), RefreshCode::RefreshAll, RefreshCode::RefreshNone, and WaveClip::Resample().

783 {
784  using namespace RefreshCode;
785  const bool unsafe = pProject->IsAudioActive();
786  if (unsafe)
787  return this->Cancel(pProject);
788 
789  Result result = RefreshNone;
790 
791  // Do not draw yellow lines
792  if ( mClipMoveState.snapLeft != -1 || mClipMoveState.snapRight != -1) {
794  result |= RefreshAll;
795  }
796 
798  return result;
799 
800  for ( auto &trackClip : mClipMoveState.capturedClipArray )
801  {
802  WaveClip* pWaveClip = trackClip.clip;
803  // Note that per AddClipsToCaptured(Track *t, double t0, double t1),
804  // in the non-WaveTrack case, the code adds a NULL clip to capturedClipArray,
805  // so we have to check for that any time we're going to deref it.
806  // Previous code did not check it here, and that caused bug 367 crash.
807  if (pWaveClip &&
808  trackClip.track != trackClip.origTrack)
809  {
810  // Now that user has dropped the clip into a different track,
811  // make sure the sample rate matches the destination track.
812  // Assume the clip was dropped in a wave track
813  pWaveClip->Resample
814  (static_cast<WaveTrack*>(trackClip.track)->GetRate());
815  pWaveClip->MarkChanged();
816  }
817  }
818 
819  wxString msg;
820  bool consolidate;
821  if (mDidSlideVertically) {
822  msg = _("Moved clips to another track");
823  consolidate = false;
824  }
825  else {
826  msg.Printf(
828  ? _("Time shifted tracks/clips right %.02f seconds")
829  : _("Time shifted tracks/clips left %.02f seconds") ),
830  fabs( mClipMoveState.hSlideAmount ) );
831  consolidate = true;
832  }
833  pProject->PushState(msg, _("Time-Shift"),
834  consolidate ? (UndoPush::CONSOLIDATE) : (UndoPush::AUTOSAVE));
835 
836  return result | FixScrollbars;
837 }
void MarkChanged()
Definition: WaveClip.h:255
void Resample(int rate, ProgressDialog *progress=NULL)
Definition: WaveClip.cpp:1898
unsigned Result
Definition: UIHandle.h:37
ClipMoveState mClipMoveState
This allows multiple clips to be a part of one WaveTrack.
Definition: WaveClip.h:176
TrackClipArray capturedClipArray
Result Cancel(AudacityProject *pProject) override
bool IsAudioActive() const
Definition: Project.cpp:1462
_("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
void PushState(const wxString &desc, const wxString &shortDesc)
Definition: Project.cpp:4617
bool TimeShiftHandle::StopsOnKeystroke ( )
inlineoverridevirtual

Reimplemented from UIHandle.

Definition at line 111 of file TimeShiftHandle.h.

111 { return true; }

Member Data Documentation

std::shared_ptr<Track> TimeShiftHandle::mCapturedTrack
private

Definition at line 114 of file TimeShiftHandle.h.

Referenced by GetTrack().

ClipMoveState TimeShiftHandle::mClipMoveState {}
private

Definition at line 128 of file TimeShiftHandle.h.

bool TimeShiftHandle::mDidSlideVertically {}
private

Definition at line 117 of file TimeShiftHandle.h.

bool TimeShiftHandle::mGripHit {}
private

Definition at line 129 of file TimeShiftHandle.h.

Referenced by IsGripHit().

wxRect TimeShiftHandle::mRect {}
private

Definition at line 115 of file TimeShiftHandle.h.

bool TimeShiftHandle::mSlideUpDownOnly {}
private

Definition at line 118 of file TimeShiftHandle.h.

std::shared_ptr<SnapManager> TimeShiftHandle::mSnapManager {}
private

Definition at line 126 of file TimeShiftHandle.h.

bool TimeShiftHandle::mSnapPreferRightEdge {}
private

Definition at line 120 of file TimeShiftHandle.h.


The documentation for this class was generated from the following files: