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