Audacity 3.2.0
TimeShiftHandle.h
Go to the documentation of this file.
1/**********************************************************************
2
3Audacity: A Digital Audio Editor
4
5TimeShiftHandle.h
6
7Paul 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
21class SnapManager;
22class Track;
23using TrackArray = std::vector<Track*>;
24class TrackList;
25
26class Track;
27class TrackInterval;
28
29class ViewInfo;
30class wxMouseState;
31
33class AUDACITY_DLL_API TrackShifter {
34public:
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
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
157protected:
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
177private:
178 bool mAllFixed = true;
180};
181
183class CoarseTrackShifter final : public TrackShifter {
184public:
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
194private:
195 std::shared_ptr<Track> mpTrack;
196};
197
198struct MakeTrackShifterTag;
200 MakeTrackShifterTag, std::unique_ptr<TrackShifter>, Track, AudacityProject&>;
202
203class ViewInfo;
204
205struct 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
261class AUDACITY_DLL_API TimeShiftHandle : public UIHandle
262{
265 (const AudacityProject *pProject, bool unsafe);
266
267public:
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
301 HitTestPreview Preview
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
315protected:
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;
319private:
320 // TrackPanelDrawable implementation
321 void Draw(
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
Utility for non-intrusive definition of a new method on a base class.
std::shared_ptr< UIHandle > UIHandlePtr
Definition: CellularPanel.h:28
std::vector< Track * > TrackArray
DECLARE_EXPORTED_ATTACHED_VIRTUAL(AUDACITY_DLL_API, MakeTrackShifter)
Class template generates single-dispatch, open method registry tables.
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:89
Used in default of other reimplementations to shift any track as a whole, invoking Track::Offset()
CoarseTrackShifter(Track &track)
bool SyncLocks() override
Returns false.
std::shared_ptr< Track > mpTrack
Track & GetTrack() const override
There is always an associated track.
~CoarseTrackShifter() override
HitTestResult HitTest(double, const ViewInfo &, HitTestParams *) override
Decide how shift behaves, based on the track that is clicked in.
TimeShiftHandle(const TimeShiftHandle &)=delete
bool StopsOnKeystroke() override
bool IsGripHit() const
TimeShiftHandle & operator=(TimeShiftHandle &&)=default
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:225
A start and an end time, and mutative access to optional extra information.
Definition: Track.h:205
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
Definition: Track.h:1336
Abstract base class for policies to manipulate a track type with the Time Shift tool.
Intervals mFixed
std::vector< TrackInterval > Intervals
virtual Track & GetTrack() const =0
There is always an associated track.
virtual HitTestResult HitTest(double time, const ViewInfo &viewInfo, HitTestParams *pParams=nullptr)=0
Decide how shift behaves, based on the track that is clicked in.
bool AllFixed() const
const Intervals & MovingIntervals() const
Return special intervals of the track that may move.
virtual ~TrackShifter()=0
TrackShifter & operator=(const TrackShifter &) PROHIBITED
HitTestResult
Possibilities for HitTest on the clicked track.
TrackShifter(const TrackShifter &) PROHIBITED
virtual bool SyncLocks()=0
Whether unfixing of an interval should propagate to all overlapping intervals in the sync lock group.
const Intervals & FixedIntervals() const
Return special intervals of the track that will not move.
Intervals mMoving
Short-lived drawing and event-handling object associated with a TrackPanelCell.
Definition: UIHandle.h:35
void Release(wxWindow *handler)
AUDACITY_DLL_API HitTestPreview HitPreview(const wxMouseState &state)
ClipMoveState(ClipMoveState &&)=default
ClipMoveState(const ClipMoveState &) PROHIBITED
ClipMoveState()=default
ShifterMap shifters
std::unordered_map< Track *, std::unique_ptr< TrackShifter > > ShifterMap
std::shared_ptr< Track > mCapturedTrack
Optional, more complete information for hit testing.