1 /********************************************************************** 2 3 Audacity: A Digital Audio Editor 4 5 LabelTrackView.h 6 7 Paul Licameli split from class LabelTrack 8 9 **********************************************************************/ 10 11 #ifndef __AUDACITY_LABEL_TRACK_VIEW__ 12 #define __AUDACITY_LABEL_TRACK_VIEW__ 13 14 #include "../../ui/CommonTrackView.h" 15 16 class LabelGlyphHandle; 17 class LabelTextHandle; 18 class LabelDefaultClickHandle; 19 class LabelStruct; 20 class LabelTrack; 21 struct LabelTrackEvent; 22 struct LabelTrackHit; 23 class NotifyingSelectedRegion; 24 class SelectedRegion; 25 struct TrackPanelDrawingContext; 26 class ZoomInfo; 27 28 class wxBitmap; 29 class wxCommandEvent; 30 class wxDC; 31 class wxMouseEvent; 32 33 constexpr int NUM_GLYPH_CONFIGS = 3; 34 constexpr int NUM_GLYPH_HIGHLIGHTS = 4; 35 constexpr int MAX_NUM_ROWS =80; 36 37 class wxKeyEvent; 38 39 class AUDACITY_DLL_API LabelTrackView final : public CommonTrackView 40 { 41 LabelTrackView( const LabelTrackView& ) = delete; 42 LabelTrackView &operator=( const LabelTrackView& ) = delete; 43 44 void Reparent( const std::shared_ptr<Track> &parent ) override; 45 46 public: 47 enum : int { DefaultFontSize = 0 }; //system preferred 48 static constexpr int TextFramePadding { 2 }; 49 static constexpr int TextFrameYOffset { -1 }; 50 static constexpr int LabelBarHeight { 6 }; 51 52 explicit 53 LabelTrackView( const std::shared_ptr<Track> &pTrack ); 54 ~LabelTrackView() override; 55 56 static LabelTrackView &Get( LabelTrack& ); 57 static const LabelTrackView &Get( const LabelTrack& ); 58 59 bool DoCaptureKey( AudacityProject &project, wxKeyEvent &event ); 60 bool DoKeyDown( 61 AudacityProject &project, NotifyingSelectedRegion &sel, wxKeyEvent & event); 62 bool DoChar( 63 AudacityProject &project, NotifyingSelectedRegion &sel, wxKeyEvent & event); 64 65 //This returns the index of the label we just added. 66 int AddLabel(const SelectedRegion ®ion, 67 const wxString &title = {}, 68 int restoreFocus = -1); 69 70 private: 71 void BindTo( LabelTrack *pParent ); 72 void UnbindFrom( LabelTrack *pParent ); 73 74 std::vector<UIHandlePtr> DetailedHitTest 75 (const TrackPanelMouseState &state, 76 const AudacityProject *pProject, int currentTool, bool bMultiTool) 77 override; 78 79 unsigned CaptureKey 80 (wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent, 81 AudacityProject *project) override; 82 83 unsigned KeyDown 84 (wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent, 85 AudacityProject *project) override; 86 87 unsigned Char 88 (wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent, 89 AudacityProject *project) override; 90 91 std::shared_ptr<TrackVRulerControls> DoGetVRulerControls() override; 92 93 // Preserve some view state too for undo/redo purposes 94 void CopyTo( Track &track ) const override; 95 96 public: 97 static void DoEditLabels( 98 AudacityProject &project, LabelTrack *lt = nullptr, int index = -1); 99 100 static int DialogForLabelName( 101 AudacityProject &project, const SelectedRegion& region, 102 const wxString& initialValue, wxString& value); 103 104 bool IsTextSelected( AudacityProject &project ) const; 105 106 private: 107 void CreateCustomGlyphs(); 108 109 public: 110 static wxFont GetFont(const wxString &faceName, int size = DefaultFontSize); 111 static void ResetFont(); 112 113 void Draw( TrackPanelDrawingContext &context, const wxRect & r ) const; 114 115 bool CutSelectedText( AudacityProject &project ); 116 bool CopySelectedText( AudacityProject &project ); 117 bool SelectAllText(AudacityProject& project); 118 119 bool PasteSelectedText( 120 AudacityProject &project, double sel0, double sel1 ); 121 122 static void OverGlyph( 123 const LabelTrack &track, LabelTrackHit &hit, int x, int y ); 124 125 private: 126 static wxBitmap & GetGlyph( int i); 127 128 struct Index 129 { 130 Index(); 131 Index(int index); 132 operator int() const; 133 Index &operator =(int index); 134 Index &operator ++(); 135 Index &operator --(); 136 137 bool IsModified() const; 138 void SetModified(bool modified); 139 140 private: 141 int mIndex; 142 bool mModified; 143 }; 144 145 public: 146 struct Flags { 147 int mInitialCursorPos, mCurrentCursorPos; 148 Index mNavigationIndex; 149 Index mTextEditIndex; 150 wxString mUndoLabel; 151 }; 152 153 void ResetFlags(); 154 Flags SaveFlags() const; 155 void RestoreFlags( const Flags& flags ); 156 157 static int OverATextBox( const LabelTrack &track, int xx, int yy ); 158 159 static bool OverTextBox( const LabelStruct *pLabel, int x, int y ); 160 161 private: 162 static bool IsTextClipSupported(); 163 164 public: 165 void AddedLabel( const wxString &title, int pos ); 166 void DeletedLabel( int index ); 167 168 private: 169 //And this tells us the index, if there is a label already there. 170 int GetLabelIndex(double t, double t1); 171 172 public: 173 //get current cursor position, 174 // relative to the left edge of the track panel 175 bool CalcCursorX( AudacityProject &project, int * x ) const; 176 177 private: 178 void CalcHighlightXs(int *x1, int *x2) const; 179 180 public: 181 void ShowContextMenu( AudacityProject &project ); 182 183 private: 184 void OnContextMenu( AudacityProject &project, wxCommandEvent & evt); 185 186 /// Keeps track of the currently selected label (not same as selection region) 187 /// used for navigation between labels 188 mutable Index mNavigationIndex{ -1 }; 189 /// Index of the current label text beeing edited 190 mutable Index mTextEditIndex{ -1 }; 191 192 mutable wxString mUndoLabel; 193 194 static int mIconHeight; 195 static int mIconWidth; 196 static int mTextHeight; 197 198 static bool mbGlyphsReady; 199 static wxBitmap mBoundaryGlyphs[NUM_GLYPH_CONFIGS * NUM_GLYPH_HIGHLIGHTS]; 200 201 static int mFontHeight; 202 mutable int mCurrentCursorPos; /// current cursor position 203 mutable int mInitialCursorPos; /// initial cursor position 204 205 206 int mRestoreFocus{-2}; /// Restore focus to this track 207 /// when done editing 208 209 void ComputeTextPosition(const wxRect & r, int index) const; 210 void ComputeLayout(const wxRect & r, const ZoomInfo &zoomInfo) const; 211 static void DrawLines( wxDC & dc, const LabelStruct &ls, const wxRect & r); 212 static void DrawGlyphs( wxDC & dc, const LabelStruct &ls, const wxRect & r, 213 int GlyphLeft, int GlyphRight); 214 static int GetTextFrameHeight(); 215 static void DrawText( wxDC & dc, const LabelStruct &ls, const wxRect & r); 216 static void DrawTextBox( wxDC & dc, const LabelStruct &ls, const wxRect & r); 217 static void DrawBar(wxDC& dc, const LabelStruct& ls, const wxRect& r); 218 static void DrawHighlight( 219 wxDC & dc, const LabelStruct &ls, int xPos1, int xPos2, int charHeight); 220 221 public: 222 /// convert pixel coordinate to character position in text box 223 int FindCursorPosition(int labelIndex, wxCoord xPos); GetCurrentCursorPosition()224 int GetCurrentCursorPosition() const { return mCurrentCursorPos; } 225 void SetCurrentCursorPosition(int pos); GetInitialCursorPosition()226 int GetInitialCursorPosition() const { return mInitialCursorPos; } 227 228 /// Sets the label with specified index for editing, 229 /// optionaly selection may be specified with [start, end] 230 void SetTextSelection(int labelIndex, int start = 1, int end = 1); 231 int GetTextEditIndex(AudacityProject& project) const; 232 void ResetTextSelection(); 233 234 void SetNavigationIndex(int index); 235 int GetNavigationIndex(AudacityProject& project) const; 236 237 private: 238 239 // TrackPanelDrawable implementation 240 void Draw( 241 TrackPanelDrawingContext &context, 242 const wxRect &rect, unsigned iPass ) override; 243 244 static void calculateFontHeight(wxDC & dc); 245 246 bool IsValidIndex(const Index& index, AudacityProject& project) const; 247 248 private: 249 void RemoveSelectedText(); 250 251 void OnLabelAdded( LabelTrackEvent& ); 252 void OnLabelDeleted( LabelTrackEvent& ); 253 void OnLabelPermuted( LabelTrackEvent& ); 254 void OnSelectionChange( LabelTrackEvent& ); 255 256 std::shared_ptr<LabelTrack> FindLabelTrack(); 257 std::shared_ptr<const LabelTrack> FindLabelTrack() const; 258 259 std::weak_ptr<LabelGlyphHandle> mGlyphHandle; 260 std::weak_ptr<LabelTextHandle> mTextHandle; 261 262 static wxFont msFont; 263 264 // Bug #2571: See explanation in ShowContextMenu() 265 int mEditIndex; 266 }; 267 268 #endif 269