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