From 8e448279800471b32a38b9452a959ef1885d7815 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Thu, 29 Jun 2017 10:34:57 -0400 Subject: [PATCH] TrackPanelCell hit tests can return multiple results... .. though only the first is used yet --- src/LabelTrack.h | 2 +- src/NoteTrack.h | 2 +- src/TimeTrack.h | 2 +- src/Track.h | 4 +- src/TrackPanel.cpp | 5 +- src/TrackPanelCell.h | 8 ++- src/TrackPanelResizerCell.cpp | 7 ++- src/TrackPanelResizerCell.h | 2 +- src/WaveTrack.h | 2 +- .../labeltrack/ui/LabelTrackControls.cpp | 2 +- src/tracks/labeltrack/ui/LabelTrackControls.h | 2 +- src/tracks/labeltrack/ui/LabelTrackUI.cpp | 18 +++--- .../notetrack/ui/NoteTrackControls.cpp | 10 ++- .../notetrack/ui/NoteTrackControls.h | 2 +- .../notetrack/ui/NoteTrackUI.cpp | 7 ++- .../notetrack/ui/NoteTrackVRulerControls.cpp | 12 +++- .../notetrack/ui/NoteTrackVRulerControls.h | 2 +- .../wavetrack/ui/WaveTrackControls.cpp | 10 ++- .../wavetrack/ui/WaveTrackControls.h | 2 +- .../wavetrack/ui/WaveTrackUI.cpp | 61 +++++++++++-------- .../wavetrack/ui/WaveTrackVRulerControls.cpp | 13 ++-- .../wavetrack/ui/WaveTrackVRulerControls.h | 2 +- src/tracks/timetrack/ui/TimeTrackControls.cpp | 2 +- src/tracks/timetrack/ui/TimeTrackControls.h | 2 +- src/tracks/timetrack/ui/TimeTrackUI.cpp | 8 ++- src/tracks/ui/BackgroundCell.cpp | 6 +- src/tracks/ui/BackgroundCell.h | 2 +- src/tracks/ui/TrackControls.cpp | 20 ++++-- src/tracks/ui/TrackControls.h | 2 +- src/tracks/ui/TrackUI.cpp | 33 +++++++--- src/tracks/ui/TrackVRulerControls.cpp | 4 +- src/tracks/ui/TrackVRulerControls.h | 2 +- 32 files changed, 165 insertions(+), 93 deletions(-) diff --git a/src/LabelTrack.h b/src/LabelTrack.h index 581547d83..99660af30 100644 --- a/src/LabelTrack.h +++ b/src/LabelTrack.h @@ -125,7 +125,7 @@ class AUDACITY_DLL_API LabelTrack final : public Track virtual ~ LabelTrack(); - UIHandlePtr DetailedHitTest + std::vector DetailedHitTest (const TrackPanelMouseState &state, const AudacityProject *pProject, int currentTool, bool bMultiTool) override; diff --git a/src/NoteTrack.h b/src/NoteTrack.h index 72c0d6435..7c705e56c 100644 --- a/src/NoteTrack.h +++ b/src/NoteTrack.h @@ -70,7 +70,7 @@ class AUDACITY_DLL_API NoteTrack final NoteTrack(const std::shared_ptr &projDirManager); virtual ~NoteTrack(); - UIHandlePtr DetailedHitTest + std::vector DetailedHitTest (const TrackPanelMouseState &state, const AudacityProject *pProject, int currentTool, bool bMultiTool) override; diff --git a/src/TimeTrack.h b/src/TimeTrack.h index 2e02e1499..81b8ba8b4 100644 --- a/src/TimeTrack.h +++ b/src/TimeTrack.h @@ -51,7 +51,7 @@ class TimeTrack final : public Track { void Silence(double t0, double t1) override; void InsertSilence(double t, double len) override; - UIHandlePtr DetailedHitTest + std::vector DetailedHitTest (const TrackPanelMouseState &state, const AudacityProject *pProject, int currentTool, bool bMultiTool) override; diff --git a/src/Track.h b/src/Track.h index 208d532a0..e44e2ea1f 100644 --- a/src/Track.h +++ b/src/Track.h @@ -136,14 +136,14 @@ class AUDACITY_DLL_API Track /* not final */ // Cause certain overriding tool modes (Zoom; future ones?) to behave // uniformly in all tracks, disregarding track contents. // Do not further override this... - UIHandlePtr HitTest + std::vector HitTest (const TrackPanelMouseState &, const AudacityProject *pProject) final; public: // Rather override this for subclasses: - virtual UIHandlePtr DetailedHitTest + virtual std::vector DetailedHitTest (const TrackPanelMouseState &, const AudacityProject *pProject, int currentTool, bool bMultiTool) = 0; diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index e316eef08..729865dc1 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -904,7 +904,10 @@ void TrackPanel::HandleMotion( const TrackPanelMouseState &tpmState ) // Now do the // UIHANDLE HIT TEST ! - handle = newCell->HitTest(tpmState, GetProject()); + auto targets = newCell->HitTest(tpmState, GetProject()); + + // No use, yet, of any but the first target + handle = targets.empty() ? UIHandlePtr{} : targets[0]; mLastCell = newCell; mLastHitTest = handle; diff --git a/src/TrackPanelCell.h b/src/TrackPanelCell.h index 3ed50eef0..74b96e78d 100644 --- a/src/TrackPanelCell.h +++ b/src/TrackPanelCell.h @@ -25,6 +25,8 @@ class wxWindow; class UIHandle; using UIHandlePtr = std::shared_ptr; +#include + // Abstract base class defining TrackPanel's access to specialist classes that // implement drawing and user interactions class AUDACITY_DLL_API TrackPanelCell /* not final */ @@ -32,12 +34,12 @@ class AUDACITY_DLL_API TrackPanelCell /* not final */ public: virtual ~TrackPanelCell () = 0; - // Return null, or a pointer to an object that can be queried for a status - // bar message and cursor appropriate to the point, and that dispatches + // Return pointers to objects that can be queried for a status + // bar message and cursor appropriate to the point, and that dispatch // mouse button events. // The button-down state passed to the function is as it will be at click // time -- not necessarily as it is now. - virtual UIHandlePtr HitTest + virtual std::vector HitTest (const TrackPanelMouseState &state, const AudacityProject *pProject) = 0; diff --git a/src/TrackPanelResizerCell.cpp b/src/TrackPanelResizerCell.cpp index 5f3e5ea36..65db0b55e 100644 --- a/src/TrackPanelResizerCell.cpp +++ b/src/TrackPanelResizerCell.cpp @@ -21,15 +21,16 @@ TrackPanelResizerCell::TrackPanelResizerCell( std::shared_ptr pTrack ) : mpTrack{ pTrack } {} -UIHandlePtr TrackPanelResizerCell::HitTest +std::vector TrackPanelResizerCell::HitTest (const TrackPanelMouseState &st, const AudacityProject *pProject) { + std::vector results; auto pTrack = mpTrack.lock(); if (pTrack) { auto result = std::make_shared( pTrack, st.state.m_y, pProject ); result = AssignUIHandlePtr(mResizeHandle, result); - return result; + results.push_back(result); } - return {}; + return results; } diff --git a/src/TrackPanelResizerCell.h b/src/TrackPanelResizerCell.h index 038810204..d32573dc7 100644 --- a/src/TrackPanelResizerCell.h +++ b/src/TrackPanelResizerCell.h @@ -24,7 +24,7 @@ public: explicit TrackPanelResizerCell( std::shared_ptr pTrack ); - UIHandlePtr HitTest + std::vector HitTest (const TrackPanelMouseState &, const AudacityProject *) override; std::shared_ptr FindTrack() override { return mpTrack.lock(); }; diff --git a/src/WaveTrack.h b/src/WaveTrack.h index 006be6291..d2854823f 100644 --- a/src/WaveTrack.h +++ b/src/WaveTrack.h @@ -107,7 +107,7 @@ class AUDACITY_DLL_API WaveTrack final : public PlayableTrack { virtual ~WaveTrack(); - UIHandlePtr DetailedHitTest + std::vector DetailedHitTest (const TrackPanelMouseState &state, const AudacityProject *pProject, int currentTool, bool bMultiTool) override; diff --git a/src/tracks/labeltrack/ui/LabelTrackControls.cpp b/src/tracks/labeltrack/ui/LabelTrackControls.cpp index df1f3f57a..bfe14fd3a 100644 --- a/src/tracks/labeltrack/ui/LabelTrackControls.cpp +++ b/src/tracks/labeltrack/ui/LabelTrackControls.cpp @@ -26,7 +26,7 @@ LabelTrackControls::~LabelTrackControls() { } -UIHandlePtr LabelTrackControls::HitTest +std::vector LabelTrackControls::HitTest (const TrackPanelMouseState & state, const AudacityProject *pProject) { diff --git a/src/tracks/labeltrack/ui/LabelTrackControls.h b/src/tracks/labeltrack/ui/LabelTrackControls.h index 7966102d7..f2c6b86e3 100644 --- a/src/tracks/labeltrack/ui/LabelTrackControls.h +++ b/src/tracks/labeltrack/ui/LabelTrackControls.h @@ -24,7 +24,7 @@ public: : TrackControls( pTrack ) {} ~LabelTrackControls(); - UIHandlePtr HitTest + std::vector HitTest (const TrackPanelMouseState &state, const AudacityProject *pProject) override; diff --git a/src/tracks/labeltrack/ui/LabelTrackUI.cpp b/src/tracks/labeltrack/ui/LabelTrackUI.cpp index d0e4ea6ed..d5a69cf2c 100644 --- a/src/tracks/labeltrack/ui/LabelTrackUI.cpp +++ b/src/tracks/labeltrack/ui/LabelTrackUI.cpp @@ -21,23 +21,25 @@ Paul Licameli split from TrackPanel.cpp #include "../../../Project.h" #include "../../../TrackPanelMouseEvent.h" -UIHandlePtr LabelTrack::DetailedHitTest +std::vector LabelTrack::DetailedHitTest (const TrackPanelMouseState &st, const AudacityProject *pProject, int, bool) { + UIHandlePtr result; + std::vector results; const wxMouseState &state = st.state; - // Try label movement handles first - UIHandlePtr result; result = LabelGlyphHandle::HitTest( mGlyphHandle, state, Pointer(this), st.rect); + if (result) + results.push_back(result); - if ( !result ) - // Missed glyph, try text box - result = LabelTextHandle::HitTest( - mTextHandle, state, Pointer(this)); + result = LabelTextHandle::HitTest( + mTextHandle, state, Pointer(this)); + if (result) + results.push_back(result); - return result; + return results; } std::shared_ptr LabelTrack::GetControls() diff --git a/src/tracks/playabletrack/notetrack/ui/NoteTrackControls.cpp b/src/tracks/playabletrack/notetrack/ui/NoteTrackControls.cpp index 22dfe27d2..9b3535616 100644 --- a/src/tracks/playabletrack/notetrack/ui/NoteTrackControls.cpp +++ b/src/tracks/playabletrack/notetrack/ui/NoteTrackControls.cpp @@ -30,15 +30,17 @@ NoteTrackControls::~NoteTrackControls() { } -UIHandlePtr NoteTrackControls::HitTest +std::vector NoteTrackControls::HitTest (const TrackPanelMouseState & st, const AudacityProject *pProject) { + // Hits are mutually exclusive, results single + std::vector results; const wxMouseState &state = st.state; const wxRect &rect = st.rect; if (state.ButtonIsDown(wxMOUSE_BTN_ANY)) { auto track = std::static_pointer_cast(FindTrack()); - if (track && track->GetKind() == Track::Note) { + auto result = [&]{ UIHandlePtr result; if (NULL != (result = MuteButtonHandle::HitTest( mMuteHandle, state, rect, pProject, track))) @@ -55,6 +57,10 @@ UIHandlePtr NoteTrackControls::HitTest mClickHandle, state, rect, track))) return result; #endif + }(); + if (result) { + results.push_back(result); + return results; } } diff --git a/src/tracks/playabletrack/notetrack/ui/NoteTrackControls.h b/src/tracks/playabletrack/notetrack/ui/NoteTrackControls.h index 24aed2114..84a378c9b 100644 --- a/src/tracks/playabletrack/notetrack/ui/NoteTrackControls.h +++ b/src/tracks/playabletrack/notetrack/ui/NoteTrackControls.h @@ -35,7 +35,7 @@ public: : TrackControls( pTrack ) {} ~NoteTrackControls(); - UIHandlePtr HitTest + std::vector HitTest (const TrackPanelMouseState &state, const AudacityProject *pProject) override; diff --git a/src/tracks/playabletrack/notetrack/ui/NoteTrackUI.cpp b/src/tracks/playabletrack/notetrack/ui/NoteTrackUI.cpp index c6ad26c89..1902efe3e 100644 --- a/src/tracks/playabletrack/notetrack/ui/NoteTrackUI.cpp +++ b/src/tracks/playabletrack/notetrack/ui/NoteTrackUI.cpp @@ -22,18 +22,21 @@ Paul Licameli split from TrackPanel.cpp #include "../../../ui/SelectHandle.h" #include "StretchHandle.h" -UIHandlePtr NoteTrack::DetailedHitTest +std::vector NoteTrack::DetailedHitTest (const TrackPanelMouseState &state, const AudacityProject *pProject, int, bool ) { // Eligible for stretch? UIHandlePtr result; + std::vector results; #ifdef USE_MIDI result = StretchHandle::HitTest( mStretchHandle, state, pProject, Pointer(this) ); + if (result) + results.push_back(result); #endif - return result; + return results; } std::shared_ptr NoteTrack::GetControls() diff --git a/src/tracks/playabletrack/notetrack/ui/NoteTrackVRulerControls.cpp b/src/tracks/playabletrack/notetrack/ui/NoteTrackVRulerControls.cpp index f686aec1c..168bc2178 100644 --- a/src/tracks/playabletrack/notetrack/ui/NoteTrackVRulerControls.cpp +++ b/src/tracks/playabletrack/notetrack/ui/NoteTrackVRulerControls.cpp @@ -27,14 +27,22 @@ NoteTrackVRulerControls::~NoteTrackVRulerControls() { } -UIHandlePtr NoteTrackVRulerControls::HitTest +std::vector NoteTrackVRulerControls::HitTest (const TrackPanelMouseState &st, const AudacityProject *pProject) { + std::vector results; UIHandlePtr result; auto track = std::static_pointer_cast(FindTrack()); - return NoteTrackVZoomHandle::HitTest( + result = NoteTrackVZoomHandle::HitTest( mVZoomHandle, st.state, track, st.rect); + if (result) + results.push_back(result); + + auto more = TrackVRulerControls::HitTest(st, pProject); + std::copy(more.begin(), more.end(), std::back_inserter(results)); + + return results; } unsigned NoteTrackVRulerControls::HandleWheelRotation diff --git a/src/tracks/playabletrack/notetrack/ui/NoteTrackVRulerControls.h b/src/tracks/playabletrack/notetrack/ui/NoteTrackVRulerControls.h index 2c0c0c2b8..322e09927 100644 --- a/src/tracks/playabletrack/notetrack/ui/NoteTrackVRulerControls.h +++ b/src/tracks/playabletrack/notetrack/ui/NoteTrackVRulerControls.h @@ -26,7 +26,7 @@ public: : TrackVRulerControls( pTrack ) {} ~NoteTrackVRulerControls(); - UIHandlePtr HitTest + std::vector HitTest (const TrackPanelMouseState &state, const AudacityProject *pProject) override; diff --git a/src/tracks/playabletrack/wavetrack/ui/WaveTrackControls.cpp b/src/tracks/playabletrack/wavetrack/ui/WaveTrackControls.cpp index 28229d06f..340301ece 100644 --- a/src/tracks/playabletrack/wavetrack/ui/WaveTrackControls.cpp +++ b/src/tracks/playabletrack/wavetrack/ui/WaveTrackControls.cpp @@ -53,15 +53,17 @@ WaveTrackControls::~WaveTrackControls() } -UIHandlePtr WaveTrackControls::HitTest +std::vector WaveTrackControls::HitTest (const TrackPanelMouseState & st, const AudacityProject *pProject) { + // Hits are mutually exclusive, results single const wxMouseState &state = st.state; const wxRect &rect = st.rect; if (state.ButtonIsDown(wxMOUSE_BTN_LEFT)) { auto track = FindTrack(); - if (track && track->GetKind() == Track::Wave) { + std::vector results; + auto result = [&]{ UIHandlePtr result; if (NULL != (result = MuteButtonHandle::HitTest( mMuteHandle, state, rect, pProject, track))) @@ -78,6 +80,10 @@ UIHandlePtr WaveTrackControls::HitTest if (NULL != (result = PanSliderHandle::HitTest( mPanHandle, state, rect, track))) return result; + }(); + if (result) { + results.push_back(result); + return results; } } diff --git a/src/tracks/playabletrack/wavetrack/ui/WaveTrackControls.h b/src/tracks/playabletrack/wavetrack/ui/WaveTrackControls.h index 6a6292af2..ed8a06d29 100644 --- a/src/tracks/playabletrack/wavetrack/ui/WaveTrackControls.h +++ b/src/tracks/playabletrack/wavetrack/ui/WaveTrackControls.h @@ -29,7 +29,7 @@ public: : TrackControls( pTrack ) {} ~WaveTrackControls(); - UIHandlePtr HitTest + std::vector HitTest (const TrackPanelMouseState &state, const AudacityProject *pProject) override; diff --git a/src/tracks/playabletrack/wavetrack/ui/WaveTrackUI.cpp b/src/tracks/playabletrack/wavetrack/ui/WaveTrackUI.cpp index e0402933f..2cabc93ed 100644 --- a/src/tracks/playabletrack/wavetrack/ui/WaveTrackUI.cpp +++ b/src/tracks/playabletrack/wavetrack/ui/WaveTrackUI.cpp @@ -23,7 +23,7 @@ Paul Licameli split from TrackPanel.cpp #include "SampleHandle.h" #include "../../../ui/TimeShiftHandle.h" -UIHandlePtr WaveTrack::DetailedHitTest +std::vector WaveTrack::DetailedHitTest (const TrackPanelMouseState &st, const AudacityProject *pProject, int currentTool, bool bMultiTool) { @@ -32,15 +32,20 @@ UIHandlePtr WaveTrack::DetailedHitTest // If that toolbar were eliminated, this could simplify to a sequence of // hit test routines describable by a table. - const auto wavetrack = static_cast(st.pCell.get()); - bool isWaveform = (wavetrack->GetDisplay() == WaveTrack::Waveform); + UIHandlePtr result; + std::vector results; + bool isWaveform = (GetDisplay() == WaveTrack::Waveform); - if (bMultiTool && st.state.CmdDown()) + 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) - return TimeShiftHandle::HitAnywhere( + result = TimeShiftHandle::HitAnywhere( mTimeShiftHandle, Pointer(this), false); + if (result) + results.push_back(result); + return results; + } // Some special targets are not drawn in spectrogram, // so don't hit them in such views. @@ -50,8 +55,8 @@ UIHandlePtr WaveTrack::DetailedHitTest mCutlineHandle, st.state, st.rect, pProject, Pointer(this)))) // This overriding test applies in all tools - return result; - else if (bMultiTool) { + results.push_back(result); + if (bMultiTool) { // Conditional hit tests // If Tools toolbar were eliminated, we would keep these // The priority of these, in case more than one might apply at one @@ -59,35 +64,39 @@ UIHandlePtr WaveTrack::DetailedHitTest if (NULL != (result = EnvelopeHandle::WaveTrackHitTest( mEnvelopeHandle, st.state, st.rect, pProject, Pointer(this)))) - ; - else if (NULL != (result = TimeShiftHandle::HitTest( + results.push_back(result); + if (NULL != (result = TimeShiftHandle::HitTest( mTimeShiftHandle, st.state, st.rect, Pointer(this)))) // This is the hit test on the "grips" drawn left and // right in Multi only - ; - else if (NULL != (result = SampleHandle::HitTest( + results.push_back(result); + if (NULL != (result = SampleHandle::HitTest( mSampleHandle, st.state, st.rect, pProject, Pointer(this)))) - ; - return result; + results.push_back(result); } - else switch ( currentTool ) { - // Unconditional hits appropriate to the tool - // If tools toolbar were eliminated, we would eliminate these - case envelopeTool: { - auto envelope = GetEnvelopeAtX( st.state.m_x ); - return EnvelopeHandle::HitAnywhere( - mEnvelopeHandle, envelope); + else { + switch ( currentTool ) { + // Unconditional hits appropriate to the tool + // If tools toolbar were eliminated, we would eliminate these + case envelopeTool: { + auto envelope = GetEnvelopeAtX( st.state.m_x ); + result = EnvelopeHandle::HitAnywhere( + mEnvelopeHandle, envelope); + break; + } + case drawTool: + result = SampleHandle::HitAnywhere( + mSampleHandle, st.state, Pointer(this)); + default: + break; } - case drawTool: - return SampleHandle::HitAnywhere( - mSampleHandle, st.state, Pointer(this)); - default: - break; + if (result) + results.push_back(result); } } - return {}; + return results; } std::shared_ptr WaveTrack::GetControls() diff --git a/src/tracks/playabletrack/wavetrack/ui/WaveTrackVRulerControls.cpp b/src/tracks/playabletrack/wavetrack/ui/WaveTrackVRulerControls.cpp index b458bf03a..b8f8d1d07 100644 --- a/src/tracks/playabletrack/wavetrack/ui/WaveTrackVRulerControls.cpp +++ b/src/tracks/playabletrack/wavetrack/ui/WaveTrackVRulerControls.cpp @@ -26,18 +26,23 @@ WaveTrackVRulerControls::~WaveTrackVRulerControls() { } -UIHandlePtr WaveTrackVRulerControls::HitTest +std::vector WaveTrackVRulerControls::HitTest (const TrackPanelMouseState &st, - const AudacityProject *) + const AudacityProject *pProject) { + std::vector results; auto pTrack = Track::Pointer( FindTrack().get() ); if (pTrack) { auto result = std::make_shared( pTrack, st.rect, st.state.m_y ); result = AssignUIHandlePtr(mVZoomHandle, result); - return result; + results.push_back(result); } - return {}; + + auto more = TrackVRulerControls::HitTest(st, pProject); + std::copy(more.begin(), more.end(), std::back_inserter(results)); + + return results; } unsigned WaveTrackVRulerControls::HandleWheelRotation diff --git a/src/tracks/playabletrack/wavetrack/ui/WaveTrackVRulerControls.h b/src/tracks/playabletrack/wavetrack/ui/WaveTrackVRulerControls.h index 188b4f1a7..ea02cd280 100644 --- a/src/tracks/playabletrack/wavetrack/ui/WaveTrackVRulerControls.h +++ b/src/tracks/playabletrack/wavetrack/ui/WaveTrackVRulerControls.h @@ -26,7 +26,7 @@ public: : TrackVRulerControls( pTrack ) {} ~WaveTrackVRulerControls(); - UIHandlePtr HitTest + std::vector HitTest (const TrackPanelMouseState &state, const AudacityProject *) override; diff --git a/src/tracks/timetrack/ui/TimeTrackControls.cpp b/src/tracks/timetrack/ui/TimeTrackControls.cpp index 17d4fb5ed..18016804b 100644 --- a/src/tracks/timetrack/ui/TimeTrackControls.cpp +++ b/src/tracks/timetrack/ui/TimeTrackControls.cpp @@ -21,7 +21,7 @@ TimeTrackControls::~TimeTrackControls() { } -UIHandlePtr TimeTrackControls::HitTest +std::vector TimeTrackControls::HitTest (const TrackPanelMouseState & state, const AudacityProject *pProject) { diff --git a/src/tracks/timetrack/ui/TimeTrackControls.h b/src/tracks/timetrack/ui/TimeTrackControls.h index ba738d2d7..1e4231a97 100644 --- a/src/tracks/timetrack/ui/TimeTrackControls.h +++ b/src/tracks/timetrack/ui/TimeTrackControls.h @@ -24,7 +24,7 @@ public: : TrackControls( pTrack ) {} ~TimeTrackControls(); - UIHandlePtr HitTest + std::vector HitTest (const TrackPanelMouseState &state, const AudacityProject *pProject) override; diff --git a/src/tracks/timetrack/ui/TimeTrackUI.cpp b/src/tracks/timetrack/ui/TimeTrackUI.cpp index bb5230e9a..10ad047a2 100644 --- a/src/tracks/timetrack/ui/TimeTrackUI.cpp +++ b/src/tracks/timetrack/ui/TimeTrackUI.cpp @@ -18,12 +18,16 @@ Paul Licameli split from TrackPanel.cpp #include "../../ui/EnvelopeHandle.h" -UIHandlePtr TimeTrack::DetailedHitTest +std::vector TimeTrack::DetailedHitTest (const TrackPanelMouseState &st, const AudacityProject *pProject, int, bool) { - return EnvelopeHandle::TimeTrackHitTest + std::vector results; + auto result = EnvelopeHandle::TimeTrackHitTest ( mEnvelopeHandle, st.state, st.rect, pProject, Pointer(this) ); + if (result) + results.push_back(result); + return results; } std::shared_ptr TimeTrack::GetControls() diff --git a/src/tracks/ui/BackgroundCell.cpp b/src/tracks/ui/BackgroundCell.cpp index b63f8b058..e5d7aa364 100644 --- a/src/tracks/ui/BackgroundCell.cpp +++ b/src/tracks/ui/BackgroundCell.cpp @@ -79,14 +79,16 @@ BackgroundCell::~BackgroundCell() { } -UIHandlePtr BackgroundCell::HitTest +std::vector BackgroundCell::HitTest (const TrackPanelMouseState &, const AudacityProject *) { + std::vector results; auto result = mHandle.lock(); if (!result) result = std::make_shared(); - return result; + results.push_back(result); + return results; } std::shared_ptr BackgroundCell::FindTrack() diff --git a/src/tracks/ui/BackgroundCell.h b/src/tracks/ui/BackgroundCell.h index d39ea04ad..cdd3bf028 100644 --- a/src/tracks/ui/BackgroundCell.h +++ b/src/tracks/ui/BackgroundCell.h @@ -29,7 +29,7 @@ public: virtual ~BackgroundCell(); protected: - UIHandlePtr HitTest + std::vector HitTest (const TrackPanelMouseState &state, const AudacityProject *) override; diff --git a/src/tracks/ui/TrackControls.cpp b/src/tracks/ui/TrackControls.cpp index 7fb64140e..576cefa6a 100644 --- a/src/tracks/ui/TrackControls.cpp +++ b/src/tracks/ui/TrackControls.cpp @@ -37,13 +37,16 @@ std::shared_ptr TrackControls::FindTrack() return mwTrack.lock(); } -UIHandlePtr TrackControls::HitTest +std::vector TrackControls::HitTest (const TrackPanelMouseState &st, const AudacityProject *project) { + // Hits are mutually exclusive, results single + const wxMouseState &state = st.state; const wxRect &rect = st.rect; UIHandlePtr result; + std::vector results; auto pTrack = FindTrack(); // shared pointer to this: @@ -51,18 +54,23 @@ UIHandlePtr TrackControls::HitTest if (NULL != (result = CloseButtonHandle::HitTest( mCloseHandle, state, rect, this))) - return result; + results.push_back(result); if (NULL != (result = MenuButtonHandle::HitTest( mMenuHandle, state, rect, sThis))) - return result; + results.push_back(result); if (NULL != (result = MinimizeButtonHandle::HitTest( mMinimizeHandle, state, rect, this))) - return result; + results.push_back(result); - return TrackSelectHandle::HitAnywhere( - mSelectHandle, pTrack); + if (results.empty()) { + if (NULL != (result = TrackSelectHandle::HitAnywhere( + mSelectHandle, pTrack))) + results.push_back(result); + } + + return results; } enum diff --git a/src/tracks/ui/TrackControls.h b/src/tracks/ui/TrackControls.h index 99b2cc106..51f8060c9 100644 --- a/src/tracks/ui/TrackControls.h +++ b/src/tracks/ui/TrackControls.h @@ -48,7 +48,7 @@ public: protected: // An override is supplied for derived classes to call through but it is // still marked pure virtual - virtual UIHandlePtr HitTest + virtual std::vector HitTest (const TrackPanelMouseState &state, const AudacityProject *) override = 0; diff --git a/src/tracks/ui/TrackUI.cpp b/src/tracks/ui/TrackUI.cpp index 8f5f58865..037fcfa68 100644 --- a/src/tracks/ui/TrackUI.cpp +++ b/src/tracks/ui/TrackUI.cpp @@ -25,44 +25,57 @@ Paul Licameli split from TrackPanel.cpp #include "../../TrackPanelResizerCell.h" #include "BackgroundCell.h" -UIHandlePtr Track::HitTest +std::vector Track::HitTest (const TrackPanelMouseState &st, const AudacityProject *pProject) { + UIHandlePtr result; + std::vector results; const ToolsToolBar * pTtb = pProject->GetToolsToolBar(); const bool isMultiTool = pTtb->IsDown(multiTool); const auto currentTool = pTtb->GetCurrentTool(); - if ( !isMultiTool && currentTool == zoomTool ) + 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. - return ZoomHandle::HitAnywhere( + result = ZoomHandle::HitAnywhere( pProject->GetBackgroundCell()->mZoomHandle); + results.push_back(result); + return results; + } // In other tools, let subclasses determine detailed hits. - auto result = + results = DetailedHitTest( st, pProject, currentTool, isMultiTool ); - // If there is no detailed hit for the subclass, there are still some - // general cases. + // There are still some general cases. // Sliding applies in more than one track type. - if ( !result && !isMultiTool && currentTool == slideTool ) + if ( !isMultiTool && currentTool == slideTool ) { result = TimeShiftHandle::HitAnywhere( mTimeShiftHandle, Pointer(this), false); + if (result) + results.push_back(result); + } // Let the multi-tool right-click handler apply only in default of all // other detailed hits. - if ( !result && isMultiTool ) + if ( isMultiTool ) { result = ZoomHandle::HitTest( pProject->GetBackgroundCell()->mZoomHandle, st.state); + if (result) + results.push_back(result); + } // Finally, default of all is adjustment of the selection box. - if ( !result && ( isMultiTool || currentTool == selectTool) ) + if ( isMultiTool || currentTool == selectTool ) { result = SelectHandle::HitTest( mSelectHandle, st, pProject, Pointer(this)); + if (result) + results.push_back(result); + } - return result; + return results; } std::shared_ptr Track::GetTrackControl() diff --git a/src/tracks/ui/TrackVRulerControls.cpp b/src/tracks/ui/TrackVRulerControls.cpp index 39e699e53..61e96918f 100644 --- a/src/tracks/ui/TrackVRulerControls.cpp +++ b/src/tracks/ui/TrackVRulerControls.cpp @@ -32,10 +32,10 @@ std::shared_ptr TrackVRulerControls::FindTrack() return mwTrack.lock(); } -UIHandlePtr TrackVRulerControls::HitTest +std::vector TrackVRulerControls::HitTest (const TrackPanelMouseState &, const AudacityProject *) { - return {}; + return std::vector{}; } void TrackVRulerControls::DrawZooming diff --git a/src/tracks/ui/TrackVRulerControls.h b/src/tracks/ui/TrackVRulerControls.h index bf7536b04..c79bdb15a 100644 --- a/src/tracks/ui/TrackVRulerControls.h +++ b/src/tracks/ui/TrackVRulerControls.h @@ -28,7 +28,7 @@ public: std::shared_ptr FindTrack() override; // Define a default hit test method, just for message and cursor - UIHandlePtr HitTest + std::vector HitTest (const TrackPanelMouseState &state, const AudacityProject *pProject) override;