1 /**********************************************************************
2 
3 Audacity: A Digital Audio Editor
4 
5 WaveTrackView.h
6 
7 Paul Licameli split from class WaveTrack
8 
9 **********************************************************************/
10 
11 #ifndef __AUDACITY_WAVE_TRACK_VIEW__
12 #define __AUDACITY_WAVE_TRACK_VIEW__
13 
14 #include "../../../ui/CommonTrackView.h"
15 #include "ClientData.h"
16 #include "SampleCount.h"
17 namespace WaveTrackViewConstants{ enum Display : int; }
18 struct WaveTrackSubViewType;
19 
20 class CutlineHandle;
21 class TranslatableString;
22 class WaveTrack;
23 class WaveTrackView;
24 class WaveClip;
25 class WaveClipTrimHandle;
26 class ZoomInfo;
27 
28 
29 class TrackPanelResizeHandle;
30 class WaveTrackAffordanceHandle;
31 
32 namespace {
33    class SubViewCloseHandle;
34    class SubViewAdjustHandle;
35    class SubViewRearrangeHandle;
36 }
37 
38 class wxDC;
39 
40 class AUDACITY_DLL_API WaveTrackSubView : public CommonTrackView
41 {
42 public:
43 
44    using Display = WaveTrackViewConstants::Display;
45    using Type = WaveTrackSubViewType;
46 
47    explicit
48    WaveTrackSubView( WaveTrackView &waveTrackView );
49 
50    virtual const Type &SubViewType() const = 0;
51 
52    // For undo and redo purpose
53    // Empty abstract method to be inherited, for copying the spectral data in SpectrumSubView
54    virtual void CopyToSubView(WaveTrackSubView *destSubView) const;
55 
56    std::pair<
57       bool, // if true, hit-testing is finished
58       std::vector<UIHandlePtr>
59    > DoDetailedHitTest(
60       const TrackPanelMouseState &state,
61       const AudacityProject *pProject, int currentTool, bool bMultiTool,
62       const std::shared_ptr<WaveTrack> &wt );
63 
64 protected:
65    static void DrawBoldBoundaries(
66       TrackPanelDrawingContext &context, const WaveTrack *track,
67       const wxRect &rect );
68 
69    std::weak_ptr<WaveTrackView> GetWaveTrackView() const;
70 
71    std::vector<MenuItem> GetMenuItems(
72       const wxRect &rect, const wxPoint *pPosition, AudacityProject *pProject )
73    override;
74 
75 private:
76    std::weak_ptr<SubViewCloseHandle> mCloseHandle;
77    std::weak_ptr<TrackPanelResizeHandle> mResizeHandle;
78    std::weak_ptr<SubViewAdjustHandle> mAdjustHandle;
79    std::weak_ptr<SubViewRearrangeHandle> mRearrangeHandle;
80    std::weak_ptr<WaveClipTrimHandle> mClipTrimHandle;
81    std::weak_ptr<CutlineHandle> mCutlineHandle;
82    std::weak_ptr<WaveTrackView> mwWaveTrackView;
83 };
84 
85 struct WaveTrackSubViewPlacement {
86    int index;
87    float fraction;
88 };
89 using WaveTrackSubViewPlacements = std::vector< WaveTrackSubViewPlacement >;
90 
91 class WaveTrackView;
92 using WaveTrackSubViews = ClientData::Site<
93    WaveTrackView, WaveTrackSubView, ClientData::SkipCopying, std::shared_ptr
94 >;
95 
96 class AUDACITY_DLL_API WaveTrackView final
97    : public CommonTrackView
98    , public WaveTrackSubViews
99 {
100    WaveTrackView( const WaveTrackView& ) = delete;
101    WaveTrackView &operator=( const WaveTrackView& ) = delete;
102 
103 public:
104    static constexpr int kChannelSeparatorThickness{ 8 };
105 
106    using Display = WaveTrackViewConstants::Display;
107 
108    static WaveTrackView &Get( WaveTrack &track );
109    static const WaveTrackView &Get( const WaveTrack &track );
110 
111    explicit
112    WaveTrackView( const std::shared_ptr<Track> &pTrack );
113    ~WaveTrackView() override;
114 
115    // Preserve some view state too for undo/redo purposes
116    void CopyTo( Track &track ) const override;
117 
118    std::shared_ptr<TrackVRulerControls> DoGetVRulerControls() override;
119 
120    // CommonTrackView implementation
121    void Reparent( const std::shared_ptr<Track> &parent ) override;
122 
123    static std::pair<
124       bool, // if true, hit-testing is finished
125       std::vector<UIHandlePtr>
126    > DoDetailedHitTest(
127       const TrackPanelMouseState &state,
128       const AudacityProject *pProject, int currentTool, bool bMultiTool,
129       const std::shared_ptr<WaveTrack> &wt,
130       CommonTrackView &view);
131 
132    std::vector< WaveTrackSubView::Type > GetDisplays() const;
133    void SetDisplay(Display display, bool exclusive = true);
134 
SavePlacements()135    const WaveTrackSubViewPlacements &SavePlacements() const
136       { return mPlacements; }
RestorePlacements(const WaveTrackSubViewPlacements & placements)137    void RestorePlacements( const WaveTrackSubViewPlacements &placements )
138       { mPlacements = placements; }
139 
140    // Return true if successful.  Fails if you try to toggle off the only
141    // sub-view.
142    bool ToggleSubView( Display id );
143 
144    // Get all the sub-views, in a sequence that is unspecified but in
145    // correspondence with the result of SavePlacements
146    std::vector< std::shared_ptr< WaveTrackSubView > > GetAllSubViews();
147 
148    // Return cached height of rect in last call of GetSubViews
GetLastHeight()149    wxCoord GetLastHeight() const { return mLastHeight; }
150 
GetMultiView()151    bool GetMultiView() const { return mMultiView; }
SetMultiView(bool value)152    void SetMultiView( bool value ) { mMultiView = value; }
153 
154 
155    std::weak_ptr<WaveClip> GetSelectedClip();
156 
157    // Returns a visible subset of subviews, sorted in the same
158    // order as they are supposed to be displayed
159 
160 
161    // Get the visible sub-views,
162    // if rect is provided then result will contain
163    // y coordinate for each subview within this rect
164    Refinement GetSubViews(const wxRect* rect = nullptr);
165 
166    unsigned CaptureKey
167    (wxKeyEvent& event, ViewInfo& viewInfo, wxWindow* pParent,
168        AudacityProject* project) override;
169 
170    unsigned KeyDown(wxKeyEvent& event, ViewInfo& viewInfo, wxWindow* pParent,
171        AudacityProject* project) override;
172 
173    unsigned Char
174    (wxKeyEvent& event, ViewInfo& viewInfo, wxWindow* pParent,
175        AudacityProject* project) override;
176 
177    unsigned LoseFocus(AudacityProject *project) override;
178 
179    static bool ClipDetailsVisible(const WaveClip& clip, const ZoomInfo& zoomInfo, const wxRect& viewRect);
180    static wxRect ClipHitTestArea(const WaveClip& clip, const ZoomInfo& zoomInfo, const wxRect& viewRect);
181    static bool HitTest(const WaveClip& clip, const ZoomInfo& zoomInfo, const wxRect& rect, const wxPoint& pos);
182 
183    //FIXME: These functions do not push state to undo history
184    //because attempt to do so leads to a focus lose which, in
185    //turn finilizes text editing (state is saved after text
186    //editing was intentionally finished instead)
187 
188    bool CutSelectedText(AudacityProject& project);
189    bool CopySelectedText(AudacityProject& project);
190    bool PasteText(AudacityProject& project);
191    bool SelectAllText(AudacityProject& project);
192 
193 private:
194    void BuildSubViews() const;
195    void DoSetDisplay(Display display, bool exclusive = true);
196    bool SelectNextClip(ViewInfo& viewInfo, AudacityProject* project, bool forward);
197 
198    // TrackPanelDrawable implementation
199    void Draw(
200       TrackPanelDrawingContext &context,
201       const wxRect &rect, unsigned iPass ) override;
202 
203    std::vector<UIHandlePtr> DetailedHitTest
204       (const TrackPanelMouseState &state,
205        const AudacityProject *pProject, int currentTool, bool bMultiTool)
206       override;
207 
208    // TrackView implementation
209    Refinement GetSubViews(const wxRect& rect) override;
210 
211 protected:
212    std::shared_ptr<CommonTrackCell> GetAffordanceControls() override;
213 
214    void DoSetMinimized( bool minimized ) override;
215 
216    // Placements are in correspondence with the array of sub-views
217    // in the WaveTrackSubViews base class, though their sequence is
218    // unspecified and maybe different in different platforms.
219    WaveTrackSubViewPlacements mPlacements;
220    mutable wxCoord mLastHeight{};
221 
222    bool mMultiView{ false };
223 
224 private:
225    std::shared_ptr<CommonTrackCell> DoGetAffordance(const std::shared_ptr<Track>& track);
226 
227    std::shared_ptr<CommonTrackCell> mpAffordanceCellControl;
228 
229    std::weak_ptr<TrackPanelCell> mKeyEventDelegate;
230 
231    std::weak_ptr<WaveTrackAffordanceHandle> mAffordanceHandle;
232 };
233 
234 // Helper for drawing routines
235 class SelectedRegion;
236 class WaveClip;
237 class ZoomInfo;
238 
239 struct AUDACITY_DLL_API ClipParameters
240 {
241    // Do a bunch of calculations common to waveform and spectrum drawing.
242    ClipParameters
243       (bool spectrum, const WaveTrack *track, const WaveClip *clip, const wxRect &rect,
244       const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo);
245 
246    double tOffset;
247    double rate;
248    double h; // absolute time of left edge of display
249    double tpre; // offset corrected time of left edge of display
250    double h1;
251    double tpost; // offset corrected time of right edge of display
252 
253    // Calculate actual selection bounds so that t0 > 0 and t1 < the
254    // end of the track
255    double t0;
256    double t1;
257 
258    double averagePixelsPerSample;
259    bool showIndividualSamples;
260 
261    sampleCount ssel0;
262    sampleCount ssel1;
263 
264    wxRect hiddenMid;
265    int hiddenLeftOffset;
266 
267    wxRect mid;
268    int leftOffset;
269 
270    // returns a clip rectangle restricted by viewRect,
271    // and with clipOffsetX - clip horizontal origin offset within view rect
272    static wxRect GetClipRect(const WaveClip& clip, const ZoomInfo& zoomInfo, const wxRect& viewRect, bool* outShowSamples = nullptr);
273 };
274 
275 #endif
276