1 /**********************************************************************
2 
3 Audacity: A Digital Audio Editor
4 
5 SelectHandle.h
6 
7 Paul Licameli split from TrackPanel.cpp
8 
9 **********************************************************************/
10 
11 #ifndef __AUDACITY_SELECT_HANDLE__
12 #define __AUDACITY_SELECT_HANDLE__
13 
14 #include "../../UIHandle.h"
15 #include "SelectedRegion.h"
16 #include "../../Snap.h"
17 
18 #include <vector>
19 
20 class SelectionStateChanger;
21 class SnapManager;
22 class SpectrumAnalyst;
23 class Track;
24 class TrackView;
25 class TrackList;
26 class ViewInfo;
27 class WaveTrack;
28 class wxMouseState;
29 
30 class AUDACITY_DLL_API SelectHandle : public UIHandle
31 {
32    SelectHandle(const SelectHandle&);
33 
34 public:
35    explicit SelectHandle
36       (const std::shared_ptr<TrackView> &pTrackView, bool useSnap,
37        const TrackList &trackList,
38        const TrackPanelMouseState &st, const ViewInfo &viewInfo);
39 
40    // This always hits, but details of the hit vary with mouse position and
41    // key state.
42    static UIHandlePtr HitTest
43       (std::weak_ptr<SelectHandle> &holder,
44        const TrackPanelMouseState &state, const AudacityProject *pProject,
45        const std::shared_ptr<TrackView> &pTrackView);
46 
47    SelectHandle &operator=(const SelectHandle&) = default;
48 
49    virtual ~SelectHandle();
50 
51    bool IsClicked() const;
52 
53    void SetUseSnap(bool use, AudacityProject *pProject);
54    void Enter(bool forward, AudacityProject *pProject) override;
55 
56    bool HasSnap() const;
57    bool HasEscape(AudacityProject *pProject) const override;
58 
59    bool Escape(AudacityProject *pProject) override;
60 
61    Result Click
62       (const TrackPanelMouseEvent &event, AudacityProject *pProject) override;
63 
64    Result Drag
65       (const TrackPanelMouseEvent &event, AudacityProject *pProject) override;
66 
67    HitTestPreview Preview
68       (const TrackPanelMouseState &state, AudacityProject *pProject)
69       override;
70 
71    Result Release
72       (const TrackPanelMouseEvent &event, AudacityProject *pProject,
73        wxWindow *pParent) override;
74 
75    Result Cancel(AudacityProject*) override;
76 
77    static UIHandle::Result NeedChangeHighlight
78       (const SelectHandle &oldState,
79        const SelectHandle &newState);
80 
81 private:
82    std::weak_ptr<Track> FindTrack();
83 
84    void Connect(AudacityProject *pProject);
85 
86    void StartSelection(AudacityProject *pProject);
87    void AdjustSelection
88       (AudacityProject *pProject,
89        ViewInfo &viewInfo, int mouseXCoordinate, int trackLeftEdge,
90        Track *pTrack);
91    void AssignSelection(ViewInfo &viewInfo, double selend, Track *pTrack);
92 
93    void StartFreqSelection
94       (ViewInfo &viewInfo, int mouseYCoordinate, int trackTopEdge,
95       int trackHeight, TrackView *pTrackView);
96    void AdjustFreqSelection
97       (const WaveTrack *wt,
98        ViewInfo &viewInfo, int mouseYCoordinate, int trackTopEdge,
99        int trackHeight);
100 
101    void HandleCenterFrequencyClick
102       (const ViewInfo &viewInfo, bool shiftDown,
103        const WaveTrack *pTrack, double value);
104    static void StartSnappingFreqSelection
105       (SpectrumAnalyst &analyst,
106        const ViewInfo &viewInfo, const WaveTrack *pTrack);
107    void MoveSnappingFreqSelection
108       (AudacityProject *pProject, ViewInfo &viewInfo, int mouseYCoordinate,
109        int trackTopEdge,
110        int trackHeight, TrackView *pTrackView);
111 public:
112    // This is needed to implement a command assignable to keystrokes
113    static void SnapCenterOnce
114       (SpectrumAnalyst &analyst,
115        ViewInfo &viewInfo, const WaveTrack *pTrack, bool up);
116 private:
117 
118    // TrackPanelDrawable implementation
119    void Draw(
120       TrackPanelDrawingContext &context,
121       const wxRect &rect, unsigned iPass ) override;
122 
123    wxRect DrawingArea(
124       TrackPanelDrawingContext &,
125       const wxRect &rect, const wxRect &panelRect, unsigned iPass ) override;
126 
127    //void ResetFreqSelectionPin
128    //   (const ViewInfo &viewInfo, double hintFrequency, bool logF);
129 
130 
131    std::weak_ptr<TrackView> mpView;
132    wxRect mRect{};
133    SelectedRegion mInitialSelection{};
134 
135    std::shared_ptr<SnapManager> mSnapManager;
136    SnapResults mSnapStart, mSnapEnd;
137    bool mUseSnap{ true };
138 
139    bool mSelStartValid{};
140    double mSelStart{ 0.0 };
141 
142    int mSelectionBoundary{ 0 };
143 
144    enum eFreqSelMode {
145       FREQ_SEL_INVALID,
146 
147       FREQ_SEL_SNAPPING_CENTER,
148       FREQ_SEL_PINNED_CENTER,
149       FREQ_SEL_DRAG_CENTER,
150 
151       FREQ_SEL_FREE,
152       FREQ_SEL_TOP_FREE,
153       FREQ_SEL_BOTTOM_FREE,
154    }  mFreqSelMode{ FREQ_SEL_INVALID };
155    std::weak_ptr<const WaveTrack> mFreqSelTrack;
156    // Following holds:
157    // the center for FREQ_SEL_PINNED_CENTER,
158    // the ratio of top to center (== center to bottom) for FREQ_SEL_DRAG_CENTER,
159    // a frequency boundary for FREQ_SEL_FREE, FREQ_SEL_TOP_FREE, or
160    // FREQ_SEL_BOTTOM_FREE,
161    // and is ignored otherwise.
162    double mFreqSelPin{ -1.0 };
163    std::shared_ptr<SpectrumAnalyst> mFrequencySnapper;
164 
165    int mMostRecentX{ -1 }, mMostRecentY{ -1 };
166 
167    bool mAutoScrolling{};
168 
169    std::shared_ptr<SelectionStateChanger> mSelectionStateChanger;
170 
171    class TimerHandler;
172    friend TimerHandler;
173    std::shared_ptr<TimerHandler> mTimerHandler;
174 };
175 #endif
176