1 /**********************************************************************
2 
3 Audacity: A Digital Audio Editor
4 
5 StretchHandle.h
6 
7 Paul Licameli split from TrackPanel.cpp
8 
9 **********************************************************************/
10 
11 #ifndef __AUDACITY_STRETCH_HANDLE__
12 #define __AUDACITY_STRETCH_HANDLE__
13 
14 #include "../../../../UIHandle.h"
15 
16 class Alg_seq;
17 class NoteTrack;
18 class Track;
19 class ViewInfo;
20 
21 class StretchHandle : public UIHandle
22 {
23 public:
24    enum StretchEnum {
25       stretchNone = 0, // false value!
26       stretchLeft,
27       stretchCenter,
28       stretchRight
29    };
30 
31    // Stretching applies to a selected region after quantizing the
32    // region to beat boundaries (subbeat stretching is not supported,
33    // but maybe it should be enabled with shift or ctrl or something)
34    // Stretching can drag the left boundary (the right stays fixed),
35    // the right boundary (the left stays fixed), or the center (splits
36    // the selection into two parts: when left part grows, the right
37    // part shrinks, keeping the leftmost and rightmost boundaries
38    // fixed.
39    struct StretchState {
40       StretchEnum mMode { stretchCenter }; // remembers what to drag
41 
42       using QuantizedTimeAndBeat = std::pair< double, double >;
43 
44       QuantizedTimeAndBeat mBeatCenter { 0, 0 };
45       QuantizedTimeAndBeat mBeat0 { 0, 0 };
46       QuantizedTimeAndBeat mBeat1 { 0, 0 };
47       double mLeftBeats {}; // how many beats from left to cursor
48       double mRightBeats {}; // how many beats from cursor to right
49 
50       double mOrigSel0Quantized { -1 }, mOrigSel1Quantized { -1 };
51    };
52 
53 private:
54    StretchHandle(const StretchHandle&);
55    static HitTestPreview HitPreview(StretchEnum stretchMode, bool unsafe);
56 
57 public:
58    explicit StretchHandle
59       ( const std::shared_ptr<NoteTrack> &pTrack,
60         const StretchState &stretchState );
61 
62    StretchHandle &operator=(const StretchHandle&) = default;
63 
64    static UIHandlePtr HitTest
65       (std::weak_ptr<StretchHandle> &holder,
66        const TrackPanelMouseState &state, const AudacityProject *pProject,
67        const std::shared_ptr<NoteTrack> &pTrack );
68 
69    virtual ~StretchHandle();
70 
71    Result Click
72       (const TrackPanelMouseEvent &event, AudacityProject *pProject) override;
73 
74    Result Drag
75       (const TrackPanelMouseEvent &event, AudacityProject *pProject) override;
76 
77    HitTestPreview Preview
78       (const TrackPanelMouseState &state, AudacityProject *pProject)
79       override;
80 
81    Result Release
82       (const TrackPanelMouseEvent &event, AudacityProject *pProject,
83       wxWindow *pParent) override;
84 
85    Result Cancel(AudacityProject *pProject) override;
86 
StopsOnKeystroke()87    bool StopsOnKeystroke() override { return true; }
88 
89 private:
90    static double GetT0(const Track &track, const ViewInfo &viewInfo);
91    static double GetT1(const Track &track, const ViewInfo &viewInfo);
92 
93    void Stretch
94       (AudacityProject *pProject, int mouseXCoordinate, int trackLeftEdge, Track *pTrack);
95 
96    std::shared_ptr<NoteTrack> mpTrack{};
97    int mLeftEdge{ -1 };
98 
99    StretchState mStretchState{};
100 };
101 
102 #endif
103