Audacity  3.0.3
TimeShiftHandle.h
Go to the documentation of this file.
1 /**********************************************************************
2 
3 Audacity: A Digital Audio Editor
4 
5 TimeShiftHandle.h
6 
7 Paul Licameli
8 
9 **********************************************************************/
10 
11 #ifndef __AUDACITY_TIMESHIFT_HANDLE__
12 #define __AUDACITY_TIMESHIFT_HANDLE__
13 
14 #include <functional>
15 #include <unordered_map>
16 #include <vector>
17 
19 #include "../../UIHandle.h"
20 
21 class SnapManager;
22 class Track;
23 using TrackArray = std::vector<Track*>;
24 class TrackList;
25 
26 class Track;
27 class TrackInterval;
28 
29 class ViewInfo;
30 class wxMouseState;
31 
33 class AUDACITY_DLL_API TrackShifter {
34 public:
36  TrackShifter(const TrackShifter&) PROHIBITED;
37  TrackShifter &operator=(const TrackShifter&) PROHIBITED;
38 
39  virtual ~TrackShifter() = 0;
41  virtual Track &GetTrack() const = 0;
42 
44  enum class HitTestResult {
45  Miss,
46  Selection,
47  Intervals,
48  Track
49  };
50 
52  struct HitTestParams {
53  wxRect rect;
54  wxCoord xx, yy;
55  };
56 
58 
64  double time,
65  const ViewInfo &viewInfo,
66  HitTestParams *pParams = nullptr
67  ) = 0;
68 
69  using Intervals = std::vector<TrackInterval>;
70 
72  const Intervals &FixedIntervals() const { return mFixed; }
73 
75  const Intervals &MovingIntervals() const { return mMoving; }
76 
78  void UnfixIntervals(
79  std::function< bool( const TrackInterval& ) > pred );
80 
82  void UnfixAll();
83 
85 
86  virtual void SelectInterval( const TrackInterval &interval );
87 
89  virtual bool SyncLocks() = 0;
90 
92 
99  virtual double HintOffsetLarger( double desiredOffset );
100 
102 
103  virtual double QuantizeOffset( double desiredOffset );
104 
106 
112  virtual double AdjustOffsetSmaller( double desiredOffset );
113 
115 
116  virtual bool MayMigrateTo( Track &otherTrack );
117 
119 
120  virtual Intervals Detach();
121 
123 
124  virtual bool AdjustFit(
125  const Track &otherTrack,
126  const Intervals &intervals,
128  double &desiredOffset,
129  double tolerance
130  );
131 
133 
138  virtual bool Attach( Intervals intervals );
139 
141 
146  virtual bool FinishMigration();
147 
150  virtual void DoHorizontalOffset( double offset );
151 
152  // This function is used by the keyboard interface for time shifting.
153  // It adjusts t0 after the move to take into account
154  // any rounding errors if this is necessary.
155  virtual double AdjustT0(double t0) const;
156 
157 protected:
159  void CommonSelectInterval( const TrackInterval &interval );
160 
164  bool CommonMayMigrateTo( Track &otherTrack );
165 
167 
168  void InitIntervals();
169 
170  bool AllFixed() const {
171  return mAllFixed && mMoving.empty();
172  }
173 
176 
177 private:
178  bool mAllFixed = true;
180 };
181 
183 class CoarseTrackShifter final : public TrackShifter {
184 public:
185  CoarseTrackShifter( Track &track );
187  Track &GetTrack() const override { return *mpTrack; }
188 
189  HitTestResult HitTest( double, const ViewInfo&, HitTestParams* ) override;
190 
192  bool SyncLocks() override;
193 
194 private:
195  std::shared_ptr<Track> mpTrack;
196 };
197 
198 struct MakeTrackShifterTag;
200  MakeTrackShifterTag, std::unique_ptr<TrackShifter>, Track, AudacityProject&>;
202 
203 class ViewInfo;
204 
205 struct AUDACITY_DLL_API ClipMoveState {
206  ClipMoveState() = default;
207 
208  ClipMoveState(const ClipMoveState&) PROHIBITED;
209  ClipMoveState& operator =(const ClipMoveState&) PROHIBITED;
210 
212  ClipMoveState& operator =(ClipMoveState&&) = default;
213 
214  using ShifterMap = std::unordered_map<Track*, std::unique_ptr<TrackShifter>>;
215 
217  void Init(
218  AudacityProject &project,
219  Track &capturedTrack, //<! pHit if not null associates with this track
220  TrackShifter::HitTestResult hitTestResult,
221  std::unique_ptr<TrackShifter> pHit,
223  double clickTime,
224  const ViewInfo &viewInfo,
225  TrackList &trackList, bool syncLocked );
226 
228 
229  const TrackInterval *CapturedInterval() const;
230 
232 
233  double DoSlideHorizontal( double desiredSlideAmount );
234 
236  void DoHorizontalOffset( double offset );
237 
238  std::shared_ptr<Track> mCapturedTrack;
239 
240  bool initialized{ false };
241  bool movingSelection {};
242  bool wasMoved{ false };
243  double hSlideAmount {};
245  wxInt64 snapLeft { -1 }, snapRight { -1 };
246 
247  int mMouseClickX{};
248 
249  void clear()
250  {
251  initialized = false;
252  wasMoved = false;
253  movingSelection = false;
254  hSlideAmount = 0;
255  shifters.clear();
256  snapLeft = snapRight = -1;
257  mMouseClickX = 0;
258  }
259 };
260 
261 class AUDACITY_DLL_API TimeShiftHandle : public UIHandle
262 {
265  (const AudacityProject *pProject, bool unsafe);
266 
267 public:
268  explicit TimeShiftHandle
269  ( const std::shared_ptr<Track> &pTrack, bool gripHit );
270 
272 
273  bool IsGripHit() const { return mGripHit; }
274 
275  // Try to move clips from one track to another, before also moving
276  // by some horizontal amount, which may be slightly adjusted to fit the
277  // destination tracks.
278  static bool DoSlideVertical(
279  ViewInfo &viewInfo, wxCoord xx,
280  ClipMoveState &state, TrackList &trackList,
281  Track &dstTrack, double &desiredSlideAmount );
282 
283  static UIHandlePtr HitAnywhere
284  (std::weak_ptr<TimeShiftHandle> &holder,
285  const std::shared_ptr<Track> &pTrack, bool gripHit);
286  static UIHandlePtr HitTest
287  (std::weak_ptr<TimeShiftHandle> &holder,
288  const wxMouseState &state, const wxRect &rect,
289  const std::shared_ptr<Track> &pTrack);
290 
291  virtual ~TimeShiftHandle();
292 
293  void Enter(bool forward, AudacityProject *) override;
294 
295  Result Click
296  (const TrackPanelMouseEvent &event, AudacityProject *pProject) override;
297 
298  Result Drag
299  (const TrackPanelMouseEvent &event, AudacityProject *pProject) override;
300 
302  (const TrackPanelMouseState &state, AudacityProject *pProject)
303  override;
304 
306  (const TrackPanelMouseEvent &event, AudacityProject *pProject,
307  wxWindow *pParent) override;
308 
309  Result Cancel(AudacityProject *pProject) override;
310 
311  bool StopsOnKeystroke() override { return true; }
312 
313  bool Clicked() const;
314 
315 protected:
316  std::shared_ptr<Track> GetTrack() const;
317  //There were attempt to move clip/track horizontally, or to move it vertically
318  bool WasMoved() const;
319 private:
320  // TrackPanelDrawable implementation
321  void Draw(
322  TrackPanelDrawingContext &context,
323  const wxRect &rect, unsigned iPass ) override;
324 
325  wxRect DrawingArea(
327  const wxRect &rect, const wxRect &panelRect, unsigned iPass ) override;
328 
329  wxRect mRect{};
330 
331  bool mDidSlideVertically{};
332  bool mSlideUpDownOnly{};
333 
334  bool mSnapPreferRightEdge{};
335 
336  // Handles snapping the selection boundaries or track boundaries to
337  // line up with existing tracks or labels. mSnapLeft and mSnapRight
338  // are the horizontal index of pixels to display user feedback
339  // guidelines so the user knows when such snapping is taking place.
340  std::shared_ptr<SnapManager> mSnapManager{};
341 
342  ClipMoveState mClipMoveState{};
343  bool mGripHit {};
344 };
345 
346 #endif
ClipMoveState::ClipMoveState
ClipMoveState()=default
CoarseTrackShifter::mpTrack
std::shared_ptr< Track > mpTrack
Definition: TimeShiftHandle.h:195
Init
Definition: ModuleManager.h:152
TimeShiftHandle::TimeShiftHandle
TimeShiftHandle(const TimeShiftHandle &)=delete
TrackShifter::SyncLocks
virtual bool SyncLocks()=0
Whether unfixing of an interval should propagate to all overlapping intervals in the sync lock group.
TrackShifter::FixedIntervals
const Intervals & FixedIntervals() const
Return special intervals of the track that will not move.
Definition: TimeShiftHandle.h:72
TrackShifter::HitTestParams::rect
wxRect rect
Definition: TimeShiftHandle.h:53
TrackShifter::mFixed
Intervals mFixed
Definition: TimeShiftHandle.h:174
UIHandle::Preview
virtual HitTestPreview Preview(const TrackPanelMouseState &state, AudacityProject *pProject)=0
DECLARE_EXPORTED_ATTACHED_VIRTUAL
DECLARE_EXPORTED_ATTACHED_VIRTUAL(AUDACITY_DLL_API, MakeTrackShifter)
AttachedVirtualFunction
Class template generates single-dispatch, open method registry tables.
Definition: AttachedVirtualFunction.h:159
TrackShifter::HitTest
virtual HitTestResult HitTest(double time, const ViewInfo &viewInfo, HitTestParams *pParams=nullptr)=0
Decide how shift behaves, based on the track that is clicked in.
TrackPanelDrawingContext
Definition: TrackPanelDrawingContext.h:22
TrackList
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
Definition: Track.h:1280
ViewInfo
Definition: ViewInfo.h:202
ClipMoveState
Definition: TimeShiftHandle.h:205
TimeShiftHandle::StopsOnKeystroke
bool StopsOnKeystroke() override
Definition: TimeShiftHandle.h:311
TrackPanelDrawable::DrawingArea
virtual wxRect DrawingArea(TrackPanelDrawingContext &context, const wxRect &rect, const wxRect &panelRect, unsigned iPass)
Definition: TrackPanelDrawable.cpp:22
TrackShifter::MovingIntervals
const Intervals & MovingIntervals() const
Return special intervals of the track that may move.
Definition: TimeShiftHandle.h:75
CoarseTrackShifter::CoarseTrackShifter
CoarseTrackShifter(Track &track)
Definition: TimeShiftHandle.cpp:256
TrackInterval
A start and an end time, and mutative access to optional extra information.
Definition: Track.h:219
CoarseTrackShifter::GetTrack
Track & GetTrack() const override
There is always an associated track.
Definition: TimeShiftHandle.h:187
WaveTrackVZoomHandle::HitPreview
AUDACITY_DLL_API HitTestPreview HitPreview(const wxMouseState &state)
Definition: WaveTrackVZoomHandle.cpp:61
UIHandle
Short-lived drawing and event-handling object associated with a TrackPanelCell.
Definition: UIHandle.h:35
TrackShifter
Abstract base class for policies to manipulate a track type with the Time Shift tool.
Definition: TimeShiftHandle.h:33
ClipMoveState::mCapturedTrack
std::shared_ptr< Track > mCapturedTrack
Definition: TimeShiftHandle.h:238
TrackShifter::HitTestResult
HitTestResult
Possibilities for HitTest on the clicked track.
Definition: TimeShiftHandle.h:44
TrackShifter::~TrackShifter
virtual ~TrackShifter()=0
TrackShifter::TrackShifter
TrackShifter()
TrackShifter::mMoving
Intervals mMoving
Definition: TimeShiftHandle.h:175
ClipMoveState::shifters
ShifterMap shifters
Definition: TimeShiftHandle.h:244
TimeShiftHandle::IsGripHit
bool IsGripHit() const
Definition: TimeShiftHandle.h:273
CoarseTrackShifter::~CoarseTrackShifter
~CoarseTrackShifter() override
UIHandle::Click
virtual Result Click(const TrackPanelMouseEvent &event, AudacityProject *pProject)=0
TrackShifter::AllFixed
bool AllFixed() const
Definition: TimeShiftHandle.h:170
ClipMoveState::ClipMoveState
ClipMoveState(ClipMoveState &&)=default
UIHandlePtr
std::shared_ptr< UIHandle > UIHandlePtr
Definition: CellularPanel.h:28
UIHandle::Cancel
virtual Result Cancel(AudacityProject *pProject)=0
HitTestPreview
Definition: HitTestResult.h:20
ClipMoveState::ShifterMap
std::unordered_map< Track *, std::unique_ptr< TrackShifter > > ShifterMap
Definition: TimeShiftHandle.h:214
CoarseTrackShifter
Used in default of other reimplementations to shift any track as a whole, invoking Track::Offset()
Definition: TimeShiftHandle.h:183
TimeShiftHandle
Definition: TimeShiftHandle.h:262
TimeShiftHandle::operator=
TimeShiftHandle & operator=(TimeShiftHandle &&)=default
ClipMoveState::ClipMoveState
ClipMoveState(const ClipMoveState &) PROHIBITED
TrackArray
std::vector< Track * > TrackArray
Definition: Track.h:45
Track
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:239
TrackShifter::GetTrack
virtual Track & GetTrack() const =0
There is always an associated track.
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
TrackShifter::HitTestParams::yy
wxCoord yy
Definition: TimeShiftHandle.h:54
TrackPanelMouseEvent
Definition: TrackPanelMouseEvent.h:46
SnapManager
Definition: Snap.h:56
CoarseTrackShifter::SyncLocks
bool SyncLocks() override
Returns false.
Definition: TimeShiftHandle.cpp:270
TrackShifter::operator=
TrackShifter & operator=(const TrackShifter &) PROHIBITED
TrackPanelMouseState
Definition: TrackPanelMouseEvent.h:28
UIHandle::Enter
virtual void Enter(bool forward, AudacityProject *pProject)
Definition: UIHandle.cpp:20
UIHandle::Drag
virtual Result Drag(const TrackPanelMouseEvent &event, AudacityProject *pProject)=0
CoarseTrackShifter::HitTest
HitTestResult HitTest(double, const ViewInfo &, HitTestParams *) override
Decide how shift behaves, based on the track that is clicked in.
Definition: TimeShiftHandle.cpp:264
UIHandle::Release
virtual Result Release(const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *pParent)=0
TrackShifter::TrackShifter
TrackShifter(const TrackShifter &) PROHIBITED
WaveTrackVZoomHandle::Result
unsigned Result
Definition: WaveTrackVZoomHandle.h:24
ClipMoveState::clear
void clear()
Definition: TimeShiftHandle.h:249
TrackShifter::Intervals
std::vector< TrackInterval > Intervals
Definition: TimeShiftHandle.h:69
AttachedVirtualFunction.h
Utility for non-intrusive definition of a new method on a base class.
TrackShifter::HitTestParams
Optional, more complete information for hit testing.
Definition: TimeShiftHandle.h:52
TrackPanelDrawable::Draw
virtual void Draw(TrackPanelDrawingContext &context, const wxRect &rect, unsigned iPass)
Definition: TrackPanelDrawable.cpp:17