1 /**********************************************************************
2 
3   Audacity: A Digital Audio Editor
4 
5   TrackPanel.h
6 
7   Dominic Mazzoni
8 
9 **********************************************************************/
10 
11 #ifndef __AUDACITY_TRACK_PANEL__
12 #define __AUDACITY_TRACK_PANEL__
13 
14 
15 
16 
17 #include <vector>
18 
19 #include <wx/setup.h> // for wxUSE_* macros
20 #include <wx/timer.h> // to inherit
21 
22 #include "HitTestResult.h"
23 #include "Prefs.h"
24 
25 #include "SelectedRegion.h"
26 
27 #include "CellularPanel.h"
28 
29 #include "commands/CommandManagerWindowClasses.h"
30 
31 
32 class wxRect;
33 
34 // All cells of the TrackPanel are subclasses of this
35 class CommonTrackPanelCell;
36 
37 class SpectrumAnalyst;
38 class Track;
39 class TrackList;
40 struct TrackListEvent;
41 class TrackPanel;
42 class TrackArtist;
43 class Ruler;
44 class AdornedRulerPanel;
45 class LWSlider;
46 
47 class TrackPanelAx;
48 
49 // Declared elsewhere, to reduce compilation dependencies
50 class TrackPanelListener;
51 
52 struct TrackPanelDrawingContext;
53 
54 enum class UndoPush : unsigned char;
55 
56 enum {
57    kTimerInterval = 50, // milliseconds
58 };
59 
60 const int DragThreshold = 3;// Anything over 3 pixels is a drag, else a click.
61 
62 class AUDACITY_DLL_API TrackPanel final
63    : public CellularPanel
64    , public NonKeystrokeInterceptingWindow
65    , private PrefsListener
66 {
67  public:
68    static TrackPanel &Get( AudacityProject &project );
69    static const TrackPanel &Get( const AudacityProject &project );
70    static void Destroy( AudacityProject &project );
71 
72    TrackPanel(wxWindow * parent,
73               wxWindowID id,
74               const wxPoint & pos,
75               const wxSize & size,
76               const std::shared_ptr<TrackList> &tracks,
77               ViewInfo * viewInfo,
78               AudacityProject * project,
79               AdornedRulerPanel * ruler );
80 
81    virtual ~ TrackPanel();
82 
83    void UpdatePrefs() override;
84 
85    void OnAudioIO(wxCommandEvent & evt);
86 
87    void OnPaint(wxPaintEvent & event);
88    void OnMouseEvent(wxMouseEvent & event);
89    void OnKeyDown(wxKeyEvent & event);
90 
91    void OnTrackListResizing(TrackListEvent & event);
92    void OnTrackListDeletion(wxEvent & event);
93    void OnEnsureVisible(TrackListEvent & event);
94    void UpdateViewIfNoTracks(); // Call this to update mViewInfo, etc, after track(s) removal, before Refresh().
95 
96    double GetMostRecentXPos();
97 
98    void OnSize( wxSizeEvent & );
99    void OnIdle(wxIdleEvent & event);
100    void OnTimer(wxTimerEvent& event);
101    void OnProjectSettingsChange(wxCommandEvent &event);
102    void OnTrackFocusChange( wxCommandEvent &event );
103 
104    void OnUndoReset( wxCommandEvent &event );
105 
106    void Refresh
107       (bool eraseBackground = true, const wxRect *rect = (const wxRect *) NULL)
108       override;
109 
110    void RefreshTrack(Track *trk, bool refreshbacking = true);
111 
112    void HandlePageUpKey();
113    void HandlePageDownKey();
114    AudacityProject * GetProject() const override;
115 
116    void OnTrackMenu(Track *t = NULL);
117 
118    void VerticalScroll( float fracPosition);
119 
120    TrackPanelCell *GetFocusedCell() override;
121    void SetFocusedCell() override;
122 
123    void UpdateVRulers();
124    void UpdateVRuler(Track *t);
125    void UpdateTrackVRuler(Track *t);
126    void UpdateVRulerSize();
127 
128  protected:
129    bool IsAudioActive();
130 
131 public:
132    size_t GetSelectedTrackCount() const;
133 
134 protected:
135    void UpdateSelectionDisplay();
136 
137 public:
138    void MakeParentRedrawScrollbars();
139 
140    /*!
141     @return includes track control panel, and the vertical ruler, and
142     the proper track area of all channels, and the separators between them.
143     If target is nullptr, returns empty rectangle.
144    */
145    wxRect FindTrackRect( const Track * target );
146 
147    /*!
148     @return includes what's in `FindTrackRect(target)` and the focus ring
149     area around it.
150     If target is nullptr, returns empty rectangle.
151    */
152    wxRect FindFocusedTrackRect( const Track * target );
153 
154    /*!
155     @return extents of the vertical rulers of one channel, top to bottom.
156     (There may be multiple sub-views, each with a ruler.)
157     If target is nullptr, returns an empty vector.
158     */
159    std::vector<wxRect> FindRulerRects( const Track * target );
160 
161 protected:
162    // Get the root object defining a recursive subdivision of the panel's
163    // area into cells
164    std::shared_ptr<TrackPanelNode> Root() override;
165 
166 public:
167 // JKC Nov-2011: These four functions only used from within a dll
168 // They work around some messy problems with constructors.
GetTracks()169    const TrackList * GetTracks() const { return mTracks.get(); }
GetTracks()170    TrackList * GetTracks() { return mTracks.get(); }
GetViewInfo()171    ViewInfo * GetViewInfo(){ return mViewInfo;}
GetListener()172    TrackPanelListener * GetListener(){ return mListener;}
GetRuler()173    AdornedRulerPanel * GetRuler(){ return mRuler;}
174 
175 protected:
176    void DrawTracks(wxDC * dc);
177 
178 public:
179    // Set the object that performs catch-all event handling when the pointer
180    // is not in any track or ruler or control panel.
181    void SetBackgroundCell
182       (const std::shared_ptr< CommonTrackPanelCell > &pCell);
183    std::shared_ptr< CommonTrackPanelCell > GetBackgroundCell();
184 
185 public:
186 
187 protected:
188    TrackPanelListener *mListener;
189 
190    std::shared_ptr<TrackList> mTracks;
191 
192    AdornedRulerPanel *mRuler;
193 
194    std::unique_ptr<TrackArtist> mTrackArtist;
195 
196    class AUDACITY_DLL_API AudacityTimer final : public wxTimer {
197    public:
Notify()198      void Notify() override{
199        // (From Debian)
200        //
201        // Don't call parent->OnTimer(..) directly here, but instead post
202        // an event. This ensures that this is a pure wxWidgets event
203        // (no GDK event behind it) and that it therefore isn't processed
204        // within the YieldFor(..) of the clipboard operations (workaround
205        // for Debian bug #765341).
206        // QueueEvent() will take ownership of the event
207        parent->GetEventHandler()->QueueEvent(safenew wxTimerEvent(*this));
208      }
209      TrackPanel *parent;
210    } mTimer;
211 
212    int mTimeCount;
213 
214    bool mRefreshBacking;
215 
216 
217 protected:
218 
219    SelectedRegion mLastDrawnSelectedRegion {};
220 
221  protected:
222 
223    std::shared_ptr<CommonTrackPanelCell> mpBackground;
224 
225    DECLARE_EVENT_TABLE()
226 
227    void ProcessUIHandleResult
228       (TrackPanelCell *pClickedTrack, TrackPanelCell *pLatestCell,
229        unsigned refreshResult) override;
230 
231    void UpdateStatusMessage( const TranslatableString &status ) override;
232 };
233 
234 #endif
235