From e581fa60d9328cc4c379f840a0cbd0a85179cad5 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Tue, 18 Jun 2019 00:00:35 -0400 Subject: [PATCH] Move responsibilities from Track to TrackView classes... ... And Track no longer inherits TrackPanelCell, so be careful to rewrite some dynamic_casts too to check instead for TrackView. Those casts won't fail to recompile if not rewritten. --- src/AdornedRulerPanel.cpp | 5 +- src/LabelTrack.cpp | 18 ++--- src/LabelTrack.h | 20 ------ src/NoteTrack.h | 5 -- src/TimeTrack.h | 9 --- src/Track.cpp | 5 -- src/Track.h | 26 +------- src/TrackPanel.cpp | 15 +++-- src/WaveTrack.h | 13 ---- .../labeltrack/ui/LabelDefaultClickHandle.cpp | 3 +- src/tracks/labeltrack/ui/LabelTrackView.cpp | 7 +- src/tracks/labeltrack/ui/LabelTrackView.h | 19 ++++++ .../notetrack/ui/NoteTrackView.cpp | 2 +- .../notetrack/ui/NoteTrackView.h | 6 ++ .../wavetrack/ui/WaveTrackView.cpp | 19 +++--- .../wavetrack/ui/WaveTrackView.h | 14 ++++ src/tracks/timetrack/ui/TimeTrackView.cpp | 7 +- src/tracks/timetrack/ui/TimeTrackView.h | 9 +++ src/tracks/ui/CommonTrackView.cpp | 55 +++++++++++++++- src/tracks/ui/CommonTrackView.h | 21 +++++- src/tracks/ui/EditCursorOverlay.cpp | 8 ++- src/tracks/ui/EnvelopeHandle.cpp | 5 +- src/tracks/ui/PlayIndicatorOverlay.cpp | 5 +- src/tracks/ui/SelectHandle.cpp | 8 ++- src/tracks/ui/TimeShiftHandle.cpp | 7 +- src/tracks/ui/TrackView.cpp | 65 ------------------- 26 files changed, 190 insertions(+), 186 deletions(-) diff --git a/src/AdornedRulerPanel.cpp b/src/AdornedRulerPanel.cpp index 96b27c026..189c98fea 100644 --- a/src/AdornedRulerPanel.cpp +++ b/src/AdornedRulerPanel.cpp @@ -45,6 +45,7 @@ #include "prefs/TracksPrefs.h" #include "toolbars/ControlToolBar.h" #include "tracks/ui/Scrubbing.h" +#include "tracks/ui/TrackView.h" #include "widgets/AButton.h" #include "widgets/Grabber.h" @@ -335,8 +336,8 @@ void AdornedRulerPanel::QuickPlayIndicatorOverlay::Draw( // Draw indicator in all visible tracks static_cast(panel) .VisitCells( [&]( const wxRect &rect, TrackPanelCell &cell ) { - const auto pTrack = dynamic_cast(&cell); - if (!pTrack) + const auto pTrackView = dynamic_cast(&cell); + if (!pTrackView) return; // Draw the NEW indicator in its NEW location diff --git a/src/LabelTrack.cpp b/src/LabelTrack.cpp index 6eff12b1e..df222e4da 100644 --- a/src/LabelTrack.cpp +++ b/src/LabelTrack.cpp @@ -1804,13 +1804,14 @@ bool LabelTrackView::DoCaptureKey(wxKeyEvent & event) return false; } -unsigned LabelTrack::CaptureKey(wxKeyEvent & event, ViewInfo &, wxWindow *) +unsigned LabelTrackView::CaptureKey(wxKeyEvent & event, ViewInfo &, wxWindow *) { - event.Skip(!LabelTrackView::Get( *this ).DoCaptureKey(event)); + event.Skip(!DoCaptureKey(event)); return RefreshCode::RefreshNone; } -unsigned LabelTrack::KeyDown(wxKeyEvent & event, ViewInfo &viewInfo, wxWindow *WXUNUSED(pParent)) +unsigned LabelTrackView::KeyDown( + wxKeyEvent & event, ViewInfo &viewInfo, wxWindow *WXUNUSED(pParent)) { double bkpSel0 = viewInfo.selectedRegion.t0(), bkpSel1 = viewInfo.selectedRegion.t1(); @@ -1819,8 +1820,7 @@ unsigned LabelTrack::KeyDown(wxKeyEvent & event, ViewInfo &viewInfo, wxWindow *W // Pass keystroke to labeltrack's handler and add to history if any // updates were done - auto &view = LabelTrackView::Get( *this ); - if (view.DoKeyDown(viewInfo.selectedRegion, event)) { + if (DoKeyDown(viewInfo.selectedRegion, event)) { ProjectHistory::Get( *pProj ).PushState(_("Modified Label"), _("Label Edit"), UndoPush::CONSOLIDATE); @@ -1828,7 +1828,8 @@ unsigned LabelTrack::KeyDown(wxKeyEvent & event, ViewInfo &viewInfo, wxWindow *W // Make sure caret is in view int x; - if (CalcCursorX(&x)) { + const auto pTrack = FindLabelTrack(); + if (pTrack->CalcCursorX(&x)) { TrackPanel::Get( *pProj ).ScrollIntoView(x); } @@ -1843,7 +1844,8 @@ unsigned LabelTrack::KeyDown(wxKeyEvent & event, ViewInfo &viewInfo, wxWindow *W return RefreshCode::RefreshNone; } -unsigned LabelTrack::Char(wxKeyEvent & event, ViewInfo &viewInfo, wxWindow *) +unsigned LabelTrackView::Char( + wxKeyEvent & event, ViewInfo &viewInfo, wxWindow *) { double bkpSel0 = viewInfo.selectedRegion.t0(), bkpSel1 = viewInfo.selectedRegion.t1(); @@ -1852,7 +1854,7 @@ unsigned LabelTrack::Char(wxKeyEvent & event, ViewInfo &viewInfo, wxWindow *) AudacityProject *const pProj = GetActiveProject(); - if (LabelTrackView::Get( *this ).DoChar(viewInfo.selectedRegion, event)) + if (DoChar(viewInfo.selectedRegion, event)) ProjectHistory::Get( *pProj ).PushState(_("Modified Label"), _("Label Edit"), UndoPush::CONSOLIDATE); diff --git a/src/LabelTrack.h b/src/LabelTrack.h index dd105c999..e8976c6ab 100644 --- a/src/LabelTrack.h +++ b/src/LabelTrack.h @@ -101,9 +101,6 @@ const int NUM_GLYPH_CONFIGS = 3; const int NUM_GLYPH_HIGHLIGHTS = 4; const int MAX_NUM_ROWS =80; -class LabelGlyphHandle; -class LabelTextHandle; - class AUDACITY_DLL_API LabelTrack final : public Track { friend class LabelTrackView; @@ -124,20 +121,6 @@ class AUDACITY_DLL_API LabelTrack final : public Track virtual ~ LabelTrack(); - std::vector DetailedHitTest - (const TrackPanelMouseState &state, - const AudacityProject *pProject, int currentTool, bool bMultiTool) - override; - - unsigned CaptureKey - (wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent) override; - - unsigned KeyDown - (wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent) override; - - unsigned Char - (wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent) override; - void SetOffset(double dOffset) override; static const int DefaultFontSize = 12; @@ -313,9 +296,6 @@ private: static wxFont msFont; - std::weak_ptr mGlyphHandle; - std::weak_ptr mTextHandle; - protected: std::shared_ptr DoGetView() override; std::shared_ptr DoGetControls() override; diff --git a/src/NoteTrack.h b/src/NoteTrack.h index a47f56629..f15734a37 100644 --- a/src/NoteTrack.h +++ b/src/NoteTrack.h @@ -71,11 +71,6 @@ public: NoteTrack(const std::shared_ptr &projDirManager); virtual ~NoteTrack(); - std::vector DetailedHitTest - (const TrackPanelMouseState &state, - const AudacityProject *pProject, int currentTool, bool bMultiTool) - override; - using Holder = std::shared_ptr; private: diff --git a/src/TimeTrack.h b/src/TimeTrack.h index ca0c049a4..6db758b12 100644 --- a/src/TimeTrack.h +++ b/src/TimeTrack.h @@ -21,8 +21,6 @@ class Ruler; class ZoomInfo; struct TrackPanelDrawingContext; -class EnvelopeHandle; - class TimeTrack final : public Track { public: @@ -49,11 +47,6 @@ class TimeTrack final : public Track { void Silence(double t0, double t1) override; void InsertSilence(double t, double len) override; - std::vector DetailedHitTest - (const TrackPanelMouseState &state, - const AudacityProject *pProject, int currentTool, bool bMultiTool) - override; - // TimeTrack parameters double GetOffset() const override { return 0.0; } @@ -108,8 +101,6 @@ class TimeTrack final : public Track { bool mDisplayLog; bool mRescaleXMLValues; // needed for backward-compatibility with older project files - std::weak_ptr mEnvelopeHandle; - /** @brief Copy the metadata from another track but not the points * * Copies the Name, DefaultName, Range and Display data from the source track diff --git a/src/Track.cpp b/src/Track.cpp index f4c8e3494..6f4985d2d 100644 --- a/src/Track.cpp +++ b/src/Track.cpp @@ -387,11 +387,6 @@ void Track::SyncLockAdjust(double oldT1, double newT1) } } -std::shared_ptr Track::DoFindTrack() -{ - return SharedPointer(); -} - void PlayableTrack::Init( const PlayableTrack &orig ) { mMute = orig.mMute; diff --git a/src/Track.h b/src/Track.h index 19f8bf40e..72e960b7a 100644 --- a/src/Track.h +++ b/src/Track.h @@ -43,9 +43,6 @@ class NoteTrack; class AudacityProject; class ZoomInfo; -class SelectHandle; -class TimeShiftHandle; - using TrackArray = std::vector< Track* >; using WaveTrackArray = std::vector < std::shared_ptr< WaveTrack > > ; using WaveTrackConstArray = std::vector < std::shared_ptr < const WaveTrack > >; @@ -186,7 +183,7 @@ private: }; class AUDACITY_DLL_API Track /* not final */ - : public CommonTrackPanelCell, public XMLTagHandler + : public XMLTagHandler , public std::enable_shared_from_this // see SharedPointer() { friend class TrackList; @@ -264,24 +261,7 @@ class AUDACITY_DLL_API Track /* not final */ // original; else return this track std::shared_ptr SubstituteOriginalTrack() const; - // Cause certain overriding tool modes (Zoom; future ones?) to behave - // uniformly in all tracks, disregarding track contents. - // Do not further override this... - std::vector HitTest - (const TrackPanelMouseState &, const AudacityProject *pProject) - final override; - - // Delegates the handling to the related TCP cell - std::shared_ptr ContextMenuDelegate() override; - public: - - // Rather override this for subclasses: - virtual std::vector DetailedHitTest - (const TrackPanelMouseState &, - const AudacityProject *pProject, int currentTool, bool bMultiTool) - = 0; - mutable wxSize vrulerSize; // Return another, associated TrackPanelCell object that implements @@ -751,7 +731,6 @@ public: bool HandleCommonXMLAttribute(const wxChar *attr, const wxChar *value); protected: - std::shared_ptr DoFindTrack() override; // These are called to create controls on demand: virtual std::shared_ptr DoGetView() = 0; @@ -760,9 +739,6 @@ protected: // These hold the controls: std::shared_ptr mpView; std::shared_ptr mpControls; - - std::weak_ptr mSelectHandle; - std::weak_ptr mTimeShiftHandle; }; class AUDACITY_DLL_API AudioTrack /* not final */ : public Track diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 16c1d44d7..7a9817a17 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -2023,7 +2023,7 @@ void TrackPanel::ScrollIntoView(int x) void TrackPanel::OnTrackMenu(Track *t) { - CellularPanel::DoContextMenu( t ); + CellularPanel::DoContextMenu( &TrackView::Get( *t ) ); } Track * TrackPanel::GetFirstSelectedTrack() @@ -2198,7 +2198,8 @@ struct VRulerAndChannel final : TrackPanelGroup { return { Axis::X, Refinement{ { rect.GetLeft(), TrackVRulerControls::Get( *mpChannel ).shared_from_this() }, - { mLeftOffset, mpChannel } + { mLeftOffset, + TrackView::Get( *mpChannel ).shared_from_this() } } }; } std::shared_ptr< Track > mpChannel; @@ -2368,12 +2369,18 @@ void TrackPanel::DisplaySelection() TrackPanelCell *TrackPanel::GetFocusedCell() { - return mAx->GetFocus().get(); + auto pTrack = mAx->GetFocus().get(); + if (pTrack) + return &TrackView::Get( *pTrack ); + return nullptr; } Track *TrackPanel::GetFocusedTrack() { - return static_cast( GetFocusedCell() ); + auto pView = dynamic_cast( GetFocusedCell() ); + if (pView) + return pView->FindTrack().get(); + return nullptr; } void TrackPanel::SetFocusedCell() diff --git a/src/WaveTrack.h b/src/WaveTrack.h index 4a4fa0b44..34d2adba9 100644 --- a/src/WaveTrack.h +++ b/src/WaveTrack.h @@ -24,10 +24,6 @@ class SpectrogramSettings; class WaveformSettings; class TimeWarper; -class CutlineHandle; -class SampleHandle; -class EnvelopeHandle; - class Sequence; class WaveClip; @@ -106,11 +102,6 @@ private: virtual ~WaveTrack(); - std::vector DetailedHitTest - (const TrackPanelMouseState &state, - const AudacityProject *pProject, int currentTool, bool bMultiTool) - override; - double GetOffset() const override; void SetOffset(double o) override; virtual ChannelType GetChannelIgnoringPan() const; @@ -694,10 +685,6 @@ private: std::unique_ptr mpSpectrumSettings; std::unique_ptr mpWaveformSettings; - std::weak_ptr mCutlineHandle; - std::weak_ptr mSampleHandle; - std::weak_ptr mEnvelopeHandle; - protected: std::shared_ptr DoGetView() override; std::shared_ptr DoGetControls() override; diff --git a/src/tracks/labeltrack/ui/LabelDefaultClickHandle.cpp b/src/tracks/labeltrack/ui/LabelDefaultClickHandle.cpp index 08266f872..68f55f185 100644 --- a/src/tracks/labeltrack/ui/LabelDefaultClickHandle.cpp +++ b/src/tracks/labeltrack/ui/LabelDefaultClickHandle.cpp @@ -11,6 +11,7 @@ Paul Licameli split from TrackPanel.cpp #include "../../../Audacity.h" #include "LabelDefaultClickHandle.h" +#include "../../ui/TrackView.h" #include "../../../HitTestResult.h" #include "../../../LabelTrack.h" #include "../../../RefreshCode.h" @@ -62,7 +63,7 @@ UIHandle::Result LabelDefaultClickHandle::Click const auto pLT = evt.pCell.get(); for (auto lt : TrackList::Get( *pProject ).Any()) { - if (pLT != lt) { + if (pLT != &TrackView::Get( *lt )) { lt->ResetFlags(); lt->Unselect(); } diff --git a/src/tracks/labeltrack/ui/LabelTrackView.cpp b/src/tracks/labeltrack/ui/LabelTrackView.cpp index 9889ae650..f41faef2f 100644 --- a/src/tracks/labeltrack/ui/LabelTrackView.cpp +++ b/src/tracks/labeltrack/ui/LabelTrackView.cpp @@ -44,7 +44,7 @@ std::shared_ptr LabelTrackView::FindLabelTrack() const return const_cast(this)->FindLabelTrack(); } -std::vector LabelTrack::DetailedHitTest +std::vector LabelTrackView::DetailedHitTest (const TrackPanelMouseState &st, const AudacityProject *WXUNUSED(pProject), int, bool) { @@ -52,13 +52,14 @@ std::vector LabelTrack::DetailedHitTest std::vector results; const wxMouseState &state = st.state; + const auto pTrack = FindLabelTrack(); result = LabelGlyphHandle::HitTest( - mGlyphHandle, state, SharedPointer(), st.rect); + mGlyphHandle, state, pTrack, st.rect); if (result) results.push_back(result); result = LabelTextHandle::HitTest( - mTextHandle, state, SharedPointer()); + mTextHandle, state, pTrack); if (result) results.push_back(result); diff --git a/src/tracks/labeltrack/ui/LabelTrackView.h b/src/tracks/labeltrack/ui/LabelTrackView.h index 80b8dcd62..371ca7bea 100644 --- a/src/tracks/labeltrack/ui/LabelTrackView.h +++ b/src/tracks/labeltrack/ui/LabelTrackView.h @@ -13,6 +13,8 @@ Paul Licameli split from class LabelTrack #include "../../ui/CommonTrackView.h" +class LabelGlyphHandle; +class LabelTextHandle; class LabelTrack; class SelectedRegion; @@ -37,10 +39,27 @@ public: bool DoChar(SelectedRegion &sel, wxKeyEvent & event); private: + std::vector DetailedHitTest + (const TrackPanelMouseState &state, + const AudacityProject *pProject, int currentTool, bool bMultiTool) + override; + + unsigned CaptureKey + (wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent) override; + + unsigned KeyDown + (wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent) override; + + unsigned Char + (wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent) override; + std::shared_ptr DoGetVRulerControls() override; std::shared_ptr FindLabelTrack(); std::shared_ptr FindLabelTrack() const; + + std::weak_ptr mGlyphHandle; + std::weak_ptr mTextHandle; }; #endif diff --git a/src/tracks/playabletrack/notetrack/ui/NoteTrackView.cpp b/src/tracks/playabletrack/notetrack/ui/NoteTrackView.cpp index 936da0bad..bfbc39859 100644 --- a/src/tracks/playabletrack/notetrack/ui/NoteTrackView.cpp +++ b/src/tracks/playabletrack/notetrack/ui/NoteTrackView.cpp @@ -28,7 +28,7 @@ NoteTrackView::~NoteTrackView() { } -std::vector NoteTrack::DetailedHitTest +std::vector NoteTrackView::DetailedHitTest (const TrackPanelMouseState &WXUNUSED(state), const AudacityProject *WXUNUSED(pProject), int, bool ) { diff --git a/src/tracks/playabletrack/notetrack/ui/NoteTrackView.h b/src/tracks/playabletrack/notetrack/ui/NoteTrackView.h index 6b21da0c4..a2c5b15e8 100644 --- a/src/tracks/playabletrack/notetrack/ui/NoteTrackView.h +++ b/src/tracks/playabletrack/notetrack/ui/NoteTrackView.h @@ -25,6 +25,12 @@ public: ~NoteTrackView() override; std::shared_ptr DoGetVRulerControls() override; + +private: + std::vector DetailedHitTest + (const TrackPanelMouseState &state, + const AudacityProject *pProject, int currentTool, bool bMultiTool) + override; }; #endif diff --git a/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.cpp b/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.cpp index f8f3441a9..cdf766ee2 100644 --- a/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.cpp +++ b/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.cpp @@ -29,7 +29,7 @@ WaveTrackView::~WaveTrackView() { } -std::vector WaveTrack::DetailedHitTest +std::vector WaveTrackView::DetailedHitTest (const TrackPanelMouseState &st, const AudacityProject *pProject, int currentTool, bool bMultiTool) { @@ -40,14 +40,15 @@ std::vector WaveTrack::DetailedHitTest UIHandlePtr result; std::vector results; - bool isWaveform = (GetDisplay() == WaveTrack::Waveform); + const auto pTrack = std::static_pointer_cast< WaveTrack >( FindTrack() ); + bool isWaveform = (pTrack->GetDisplay() == WaveTrack::Waveform); if (bMultiTool && st.state.CmdDown()) { // Ctrl modifier key in multi-tool overrides everything else // (But this does not do the time shift constrained to the vertical only, // which is what happens when you hold Ctrl in the Time Shift tool mode) result = TimeShiftHandle::HitAnywhere( - mTimeShiftHandle, SharedPointer(), false); + mTimeShiftHandle, pTrack, false); if (result) results.push_back(result); return results; @@ -59,7 +60,7 @@ std::vector WaveTrack::DetailedHitTest if (NULL != (result = CutlineHandle::HitTest( mCutlineHandle, st.state, st.rect, - pProject, SharedPointer()))) + pProject, pTrack ))) // This overriding test applies in all tools results.push_back(result); if (bMultiTool) { @@ -69,16 +70,16 @@ std::vector WaveTrack::DetailedHitTest // point, seems arbitrary if (NULL != (result = EnvelopeHandle::WaveTrackHitTest( mEnvelopeHandle, st.state, st.rect, - pProject, SharedPointer()))) + pProject, pTrack ))) results.push_back(result); if (NULL != (result = TimeShiftHandle::HitTest( - mTimeShiftHandle, st.state, st.rect, SharedPointer()))) + mTimeShiftHandle, st.state, st.rect, pTrack ))) // This is the hit test on the "grips" drawn left and // right in Multi only results.push_back(result); if (NULL != (result = SampleHandle::HitTest( mSampleHandle, st.state, st.rect, - pProject, SharedPointer()))) + pProject, pTrack ))) results.push_back(result); } else { @@ -86,14 +87,14 @@ std::vector WaveTrack::DetailedHitTest // Unconditional hits appropriate to the tool // If tools toolbar were eliminated, we would eliminate these case ToolCodes::envelopeTool: { - auto envelope = GetEnvelopeAtX( st.state.m_x ); + auto envelope = pTrack->GetEnvelopeAtX( st.state.m_x ); result = EnvelopeHandle::HitAnywhere( mEnvelopeHandle, envelope, false); break; } case ToolCodes::drawTool: result = SampleHandle::HitAnywhere( - mSampleHandle, st.state, SharedPointer()); + mSampleHandle, st.state, pTrack ); break; default: result = {}; diff --git a/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.h b/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.h index 2942eec23..165554605 100644 --- a/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.h +++ b/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.h @@ -13,6 +13,10 @@ Paul Licameli split from class WaveTrack #include "../../../ui/CommonTrackView.h" +class CutlineHandle; +class SampleHandle; +class EnvelopeHandle; + class WaveTrackView final : public CommonTrackView { WaveTrackView( const WaveTrackView& ) = delete; @@ -25,6 +29,16 @@ public: ~WaveTrackView() override; std::shared_ptr DoGetVRulerControls() override; + +private: + std::vector DetailedHitTest + (const TrackPanelMouseState &state, + const AudacityProject *pProject, int currentTool, bool bMultiTool) + override; + + std::weak_ptr mCutlineHandle; + std::weak_ptr mSampleHandle; + std::weak_ptr mEnvelopeHandle; }; #endif diff --git a/src/tracks/timetrack/ui/TimeTrackView.cpp b/src/tracks/timetrack/ui/TimeTrackView.cpp index 73ff534d9..fd2265421 100644 --- a/src/tracks/timetrack/ui/TimeTrackView.cpp +++ b/src/tracks/timetrack/ui/TimeTrackView.cpp @@ -24,13 +24,14 @@ TimeTrackView::~TimeTrackView() { } -std::vector TimeTrack::DetailedHitTest +std::vector TimeTrackView::DetailedHitTest (const TrackPanelMouseState &st, const AudacityProject *pProject, int, bool) { std::vector results; - auto result = EnvelopeHandle::TimeTrackHitTest( - mEnvelopeHandle, st.state, st.rect, pProject, SharedPointer() ); + auto result = EnvelopeHandle::TimeTrackHitTest + ( mEnvelopeHandle, st.state, st.rect, pProject, + std::static_pointer_cast< TimeTrack >( FindTrack() ) ); if (result) results.push_back(result); return results; diff --git a/src/tracks/timetrack/ui/TimeTrackView.h b/src/tracks/timetrack/ui/TimeTrackView.h index a9f767132..75e48dbeb 100644 --- a/src/tracks/timetrack/ui/TimeTrackView.h +++ b/src/tracks/timetrack/ui/TimeTrackView.h @@ -13,6 +13,8 @@ Paul Licameli split from class TimeTrack #include "../../ui/CommonTrackView.h" +class EnvelopeHandle; + class TimeTrackView final : public CommonTrackView { TimeTrackView( const TimeTrackView& ) = delete; @@ -26,6 +28,13 @@ public: std::shared_ptr DoGetVRulerControls() override; +private: + std::vector DetailedHitTest + (const TrackPanelMouseState &state, + const AudacityProject *pProject, int currentTool, bool bMultiTool) + override; + + std::weak_ptr mEnvelopeHandle; }; #endif diff --git a/src/tracks/ui/CommonTrackView.cpp b/src/tracks/ui/CommonTrackView.cpp index 49211a213..20a2e6be4 100644 --- a/src/tracks/ui/CommonTrackView.cpp +++ b/src/tracks/ui/CommonTrackView.cpp @@ -10,13 +10,66 @@ Paul Licameli split from class TrackView #include "CommonTrackView.h" +#include "BackgroundCell.h" +#include "TimeShiftHandle.h" #include "TrackControls.h" +#include "ZoomHandle.h" +#include "../ui/SelectHandle.h" +#include "../../ProjectSettings.h" +#include "../../TrackPanelMouseEvent.h" std::vector CommonTrackView::HitTest (const TrackPanelMouseState &st, const AudacityProject *pProject) { - return {}; + UIHandlePtr result; + using namespace ToolCodes; + std::vector results; + const auto &settings = ProjectSettings::Get( *pProject ); + const auto currentTool = settings.GetTool(); + const bool isMultiTool = ( currentTool == multiTool ); + + if ( !isMultiTool && currentTool == zoomTool ) { + // Zoom tool is a non-selecting tool that takes precedence in all tracks + // over all other tools, no matter what detail you point at. + result = ZoomHandle::HitAnywhere( + BackgroundCell::Get( *pProject ).mZoomHandle ); + results.push_back(result); + return results; + } + + // In other tools, let subclasses determine detailed hits. + results = + DetailedHitTest( st, pProject, currentTool, isMultiTool ); + + // There are still some general cases. + + // Sliding applies in more than one track type. + if ( !isMultiTool && currentTool == slideTool ) { + result = TimeShiftHandle::HitAnywhere( + mTimeShiftHandle, FindTrack(), false); + if (result) + results.push_back(result); + } + + // Let the multi-tool right-click handler apply only in default of all + // other detailed hits. + if ( isMultiTool ) { + result = ZoomHandle::HitTest( + BackgroundCell::Get( *pProject ).mZoomHandle, st.state); + if (result) + results.push_back(result); + } + + // Finally, default of all is adjustment of the selection box. + if ( isMultiTool || currentTool == selectTool ) { + result = SelectHandle::HitTest( + mSelectHandle, st, pProject, FindTrack() ); + if (result) + results.push_back(result); + } + + return results; } std::shared_ptr CommonTrackView::ContextMenuDelegate() diff --git a/src/tracks/ui/CommonTrackView.h b/src/tracks/ui/CommonTrackView.h index 195bca688..9884d4714 100644 --- a/src/tracks/ui/CommonTrackView.h +++ b/src/tracks/ui/CommonTrackView.h @@ -13,20 +13,35 @@ Paul Licameli split from class TrackView #include "TrackView.h" // to inherit +class SelectHandle; +class TimeShiftHandle; + class CommonTrackView /* not final */ : public TrackView { public: using TrackView::TrackView; + + // Delegates the handling to the related TCP cell + std::shared_ptr ContextMenuDelegate() override; + // Cause certain overriding tool modes (Zoom; future ones?) to behave + // uniformly in all tracks, disregarding track contents. + // Do not further override this... std::vector HitTest (const TrackPanelMouseState &, const AudacityProject *pProject) final override; - // Delegates the handling to the related TCP cell - std::shared_ptr ContextMenuDelegate() override; - protected: + // Rather override this for subclasses: + virtual std::vector DetailedHitTest + (const TrackPanelMouseState &, + const AudacityProject *pProject, int currentTool, bool bMultiTool) + = 0; + Track *GetTrack() const; + + std::weak_ptr mSelectHandle; + std::weak_ptr mTimeShiftHandle; }; #endif diff --git a/src/tracks/ui/EditCursorOverlay.cpp b/src/tracks/ui/EditCursorOverlay.cpp index baeccb956..570a74baf 100644 --- a/src/tracks/ui/EditCursorOverlay.cpp +++ b/src/tracks/ui/EditCursorOverlay.cpp @@ -11,6 +11,7 @@ Paul Licameli split from TrackPanel.cpp #include "../../Audacity.h" #include "EditCursorOverlay.h" +#include "TrackView.h" #include "../../AColor.h" #include "../../AdornedRulerPanel.h" #include "../../Project.h" @@ -103,11 +104,12 @@ void EditCursorOverlay::Draw(OverlayPanel &panel, wxDC &dc) // Draw cursor in all selected tracks tp->VisitCells( [&]( const wxRect &rect, TrackPanelCell &cell ) { - const auto pTrack = dynamic_cast(&cell); - if (!pTrack) + const auto pTrackView = dynamic_cast(&cell); + if (!pTrackView) return; + const auto pTrack = pTrackView->FindTrack(); if (pTrack->GetSelected() || - trackPanel.GetAx().IsFocused(pTrack)) + trackPanel.GetAx().IsFocused(pTrack.get())) { // AColor::Line includes both endpoints so use GetBottom() AColor::Line(dc, mLastCursorX, rect.GetTop(), mLastCursorX, rect.GetBottom()); diff --git a/src/tracks/ui/EnvelopeHandle.cpp b/src/tracks/ui/EnvelopeHandle.cpp index 8d94a59d5..bf605c06c 100644 --- a/src/tracks/ui/EnvelopeHandle.cpp +++ b/src/tracks/ui/EnvelopeHandle.cpp @@ -13,6 +13,8 @@ Paul Licameli split from TrackPanel.cpp #include "../../Experimental.h" +#include "TrackView.h" + #include "../../Envelope.h" #include "../../EnvelopeEditor.h" #include "../../HitTestResult.h" @@ -177,7 +179,8 @@ UIHandle::Result EnvelopeHandle::Click const wxMouseEvent &event = evt.event; const auto &viewInfo = ViewInfo::Get( *pProject ); - const auto pTrack = static_cast(evt.pCell.get()); + const auto pView = std::static_pointer_cast(evt.pCell); + const auto pTrack = pView ? pView->FindTrack().get() : nullptr; mEnvelopeEditors.clear(); diff --git a/src/tracks/ui/PlayIndicatorOverlay.cpp b/src/tracks/ui/PlayIndicatorOverlay.cpp index cb6aa060f..f965b9e3d 100644 --- a/src/tracks/ui/PlayIndicatorOverlay.cpp +++ b/src/tracks/ui/PlayIndicatorOverlay.cpp @@ -22,6 +22,7 @@ Paul Licameli split from TrackPanel.cpp #include "../../ViewInfo.h" #include "Scrubbing.h" #include "../../toolbars/ControlToolBar.h" +#include "TrackView.h" #include @@ -92,8 +93,8 @@ void PlayIndicatorOverlayBase::Draw(OverlayPanel &panel, wxDC &dc) // Draw indicator in all visible tracks tp->VisitCells( [&]( const wxRect &rect, TrackPanelCell &cell ) { - const auto pTrack = dynamic_cast(&cell); - if (pTrack) pTrack->TypeSwitch( + const auto pTrackView = dynamic_cast(&cell); + if (pTrackView) pTrackView->FindTrack()->TypeSwitch( [](LabelTrack *) { // Don't draw the indicator in label tracks }, diff --git a/src/tracks/ui/SelectHandle.cpp b/src/tracks/ui/SelectHandle.cpp index 394f67c42..5ff2a3e62 100644 --- a/src/tracks/ui/SelectHandle.cpp +++ b/src/tracks/ui/SelectHandle.cpp @@ -14,6 +14,7 @@ Paul Licameli split from TrackPanel.cpp #include "../../Experimental.h" #include "Scrubbing.h" +#include "TrackView.h" #include "../../AColor.h" #include "../../FreqWindow.h" @@ -1109,7 +1110,12 @@ void SelectHandle::TimerHandler::OnTimer(wxCommandEvent &event) // AS: For some reason, GCC won't let us pass this directly. wxMouseEvent evt(wxEVT_MOTION); const auto size = trackPanel.GetSize(); - mParent->Drag(TrackPanelMouseEvent{ evt, mParent->mRect, size, pTrack }, project); + mParent->Drag( + TrackPanelMouseEvent{ + evt, mParent->mRect, size, + TrackView::Get( *pTrack ).shared_from_this() }, + project + ); mParent->mAutoScrolling = false; TrackPanel::Get( *mConnectedProject ).Refresh(false); } diff --git a/src/tracks/ui/TimeShiftHandle.cpp b/src/tracks/ui/TimeShiftHandle.cpp index bf7e46e63..0e52b1339 100644 --- a/src/tracks/ui/TimeShiftHandle.cpp +++ b/src/tracks/ui/TimeShiftHandle.cpp @@ -13,6 +13,7 @@ Paul Licameli split from TrackPanel.cpp #include "../../Experimental.h" +#include "TrackView.h" #include "../../AColor.h" #include "../../HitTestResult.h" #include "../../NoteTrack.h" @@ -361,7 +362,8 @@ UIHandle::Result TimeShiftHandle::Click const wxRect &rect = evt.rect; auto &viewInfo = ViewInfo::Get( *pProject ); - const auto pTrack = std::static_pointer_cast(evt.pCell); + const auto pView = std::static_pointer_cast(evt.pCell); + const auto pTrack = pView ? pView->FindTrack().get() : nullptr; if (!pTrack) return RefreshCode::Cancelled; @@ -680,7 +682,8 @@ UIHandle::Result TimeShiftHandle::Drag const wxMouseEvent &event = evt.event; auto &viewInfo = ViewInfo::Get( *pProject ); - Track *track = dynamic_cast(evt.pCell.get()); + TrackView *trackView = dynamic_cast(evt.pCell.get()); + Track *track = trackView ? trackView->FindTrack().get() : nullptr; // Uncommenting this permits drag to continue to work even over the controls area /* diff --git a/src/tracks/ui/TrackView.cpp b/src/tracks/ui/TrackView.cpp index ee88808d3..b26c03350 100644 --- a/src/tracks/ui/TrackView.cpp +++ b/src/tracks/ui/TrackView.cpp @@ -11,14 +11,8 @@ Paul Licameli split from TrackPanel.cpp #include "TrackView.h" #include "../../Track.h" -#include "../../TrackPanelMouseEvent.h" #include "TrackControls.h" -#include "../ui/SelectHandle.h" -#include "ZoomHandle.h" -#include "TimeShiftHandle.h" #include "../../TrackPanelResizerCell.h" -#include "BackgroundCell.h" -#include "../../ProjectSettings.h" TrackView::~TrackView() { @@ -38,65 +32,6 @@ const TrackView &TrackView::Get( const Track &track ) return *track.GetTrackView(); } -std::vector Track::HitTest -(const TrackPanelMouseState &st, - const AudacityProject *pProject) -{ - UIHandlePtr result; - using namespace ToolCodes; - std::vector results; - const auto &settings = ProjectSettings::Get( *pProject ); - const auto currentTool = settings.GetTool(); - const bool isMultiTool = ( currentTool == multiTool ); - - if ( !isMultiTool && currentTool == zoomTool ) { - // Zoom tool is a non-selecting tool that takes precedence in all tracks - // over all other tools, no matter what detail you point at. - result = ZoomHandle::HitAnywhere( - BackgroundCell::Get( *pProject ).mZoomHandle ); - results.push_back(result); - return results; - } - - // In other tools, let subclasses determine detailed hits. - results = - DetailedHitTest( st, pProject, currentTool, isMultiTool ); - - // There are still some general cases. - - // Sliding applies in more than one track type. - if ( !isMultiTool && currentTool == slideTool ) { - result = TimeShiftHandle::HitAnywhere( - mTimeShiftHandle, SharedPointer(), false); - if (result) - results.push_back(result); - } - - // Let the multi-tool right-click handler apply only in default of all - // other detailed hits. - if ( isMultiTool ) { - result = ZoomHandle::HitTest( - BackgroundCell::Get( *pProject ).mZoomHandle, st.state); - if (result) - results.push_back(result); - } - - // Finally, default of all is adjustment of the selection box. - if ( isMultiTool || currentTool == selectTool ) { - result = SelectHandle::HitTest( - mSelectHandle, st, pProject, SharedPointer()); - if (result) - results.push_back(result); - } - - return results; -} - -std::shared_ptr Track::ContextMenuDelegate() -{ - return TrackControls::Get( *this ).shared_from_this(); -} - std::shared_ptr Track::GetTrackView() { if (!mpView)