1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-09 00:21:16 +02:00

TrackPanelCell hit tests can return multiple results...

.. though only the first is used yet
This commit is contained in:
Paul Licameli 2017-06-29 10:34:57 -04:00
parent b3d62e2ab6
commit 8e44827980
32 changed files with 165 additions and 93 deletions

View File

@ -125,7 +125,7 @@ class AUDACITY_DLL_API LabelTrack final : public Track
virtual ~ LabelTrack(); virtual ~ LabelTrack();
UIHandlePtr DetailedHitTest std::vector<UIHandlePtr> DetailedHitTest
(const TrackPanelMouseState &state, (const TrackPanelMouseState &state,
const AudacityProject *pProject, int currentTool, bool bMultiTool) const AudacityProject *pProject, int currentTool, bool bMultiTool)
override; override;

View File

@ -70,7 +70,7 @@ class AUDACITY_DLL_API NoteTrack final
NoteTrack(const std::shared_ptr<DirManager> &projDirManager); NoteTrack(const std::shared_ptr<DirManager> &projDirManager);
virtual ~NoteTrack(); virtual ~NoteTrack();
UIHandlePtr DetailedHitTest std::vector<UIHandlePtr> DetailedHitTest
(const TrackPanelMouseState &state, (const TrackPanelMouseState &state,
const AudacityProject *pProject, int currentTool, bool bMultiTool) const AudacityProject *pProject, int currentTool, bool bMultiTool)
override; override;

View File

@ -51,7 +51,7 @@ class TimeTrack final : public Track {
void Silence(double t0, double t1) override; void Silence(double t0, double t1) override;
void InsertSilence(double t, double len) override; void InsertSilence(double t, double len) override;
UIHandlePtr DetailedHitTest std::vector<UIHandlePtr> DetailedHitTest
(const TrackPanelMouseState &state, (const TrackPanelMouseState &state,
const AudacityProject *pProject, int currentTool, bool bMultiTool) const AudacityProject *pProject, int currentTool, bool bMultiTool)
override; override;

View File

@ -136,14 +136,14 @@ class AUDACITY_DLL_API Track /* not final */
// Cause certain overriding tool modes (Zoom; future ones?) to behave // Cause certain overriding tool modes (Zoom; future ones?) to behave
// uniformly in all tracks, disregarding track contents. // uniformly in all tracks, disregarding track contents.
// Do not further override this... // Do not further override this...
UIHandlePtr HitTest std::vector<UIHandlePtr> HitTest
(const TrackPanelMouseState &, const AudacityProject *pProject) (const TrackPanelMouseState &, const AudacityProject *pProject)
final; final;
public: public:
// Rather override this for subclasses: // Rather override this for subclasses:
virtual UIHandlePtr DetailedHitTest virtual std::vector<UIHandlePtr> DetailedHitTest
(const TrackPanelMouseState &, (const TrackPanelMouseState &,
const AudacityProject *pProject, int currentTool, bool bMultiTool) const AudacityProject *pProject, int currentTool, bool bMultiTool)
= 0; = 0;

View File

@ -904,7 +904,10 @@ void TrackPanel::HandleMotion( const TrackPanelMouseState &tpmState )
// Now do the // Now do the
// UIHANDLE HIT TEST ! // 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; mLastCell = newCell;
mLastHitTest = handle; mLastHitTest = handle;

View File

@ -25,6 +25,8 @@ class wxWindow;
class UIHandle; class UIHandle;
using UIHandlePtr = std::shared_ptr<UIHandle>; using UIHandlePtr = std::shared_ptr<UIHandle>;
#include <vector>
// Abstract base class defining TrackPanel's access to specialist classes that // Abstract base class defining TrackPanel's access to specialist classes that
// implement drawing and user interactions // implement drawing and user interactions
class AUDACITY_DLL_API TrackPanelCell /* not final */ class AUDACITY_DLL_API TrackPanelCell /* not final */
@ -32,12 +34,12 @@ class AUDACITY_DLL_API TrackPanelCell /* not final */
public: public:
virtual ~TrackPanelCell () = 0; virtual ~TrackPanelCell () = 0;
// Return null, or a pointer to an object that can be queried for a status // Return pointers to objects that can be queried for a status
// bar message and cursor appropriate to the point, and that dispatches // bar message and cursor appropriate to the point, and that dispatch
// mouse button events. // mouse button events.
// The button-down state passed to the function is as it will be at click // The button-down state passed to the function is as it will be at click
// time -- not necessarily as it is now. // time -- not necessarily as it is now.
virtual UIHandlePtr HitTest virtual std::vector<UIHandlePtr> HitTest
(const TrackPanelMouseState &state, (const TrackPanelMouseState &state,
const AudacityProject *pProject) = 0; const AudacityProject *pProject) = 0;

View File

@ -21,15 +21,16 @@ TrackPanelResizerCell::TrackPanelResizerCell( std::shared_ptr<Track> pTrack )
: mpTrack{ pTrack } : mpTrack{ pTrack }
{} {}
UIHandlePtr TrackPanelResizerCell::HitTest std::vector<UIHandlePtr> TrackPanelResizerCell::HitTest
(const TrackPanelMouseState &st, const AudacityProject *pProject) (const TrackPanelMouseState &st, const AudacityProject *pProject)
{ {
std::vector<UIHandlePtr> results;
auto pTrack = mpTrack.lock(); auto pTrack = mpTrack.lock();
if (pTrack) { if (pTrack) {
auto result = std::make_shared<TrackPanelResizeHandle>( auto result = std::make_shared<TrackPanelResizeHandle>(
pTrack, st.state.m_y, pProject ); pTrack, st.state.m_y, pProject );
result = AssignUIHandlePtr(mResizeHandle, result); result = AssignUIHandlePtr(mResizeHandle, result);
return result; results.push_back(result);
} }
return {}; return results;
} }

View File

@ -24,7 +24,7 @@ public:
explicit explicit
TrackPanelResizerCell( std::shared_ptr<Track> pTrack ); TrackPanelResizerCell( std::shared_ptr<Track> pTrack );
UIHandlePtr HitTest std::vector<UIHandlePtr> HitTest
(const TrackPanelMouseState &, const AudacityProject *) override; (const TrackPanelMouseState &, const AudacityProject *) override;
std::shared_ptr<Track> FindTrack() override { return mpTrack.lock(); }; std::shared_ptr<Track> FindTrack() override { return mpTrack.lock(); };

View File

@ -107,7 +107,7 @@ class AUDACITY_DLL_API WaveTrack final : public PlayableTrack {
virtual ~WaveTrack(); virtual ~WaveTrack();
UIHandlePtr DetailedHitTest std::vector<UIHandlePtr> DetailedHitTest
(const TrackPanelMouseState &state, (const TrackPanelMouseState &state,
const AudacityProject *pProject, int currentTool, bool bMultiTool) const AudacityProject *pProject, int currentTool, bool bMultiTool)
override; override;

View File

@ -26,7 +26,7 @@ LabelTrackControls::~LabelTrackControls()
{ {
} }
UIHandlePtr LabelTrackControls::HitTest std::vector<UIHandlePtr> LabelTrackControls::HitTest
(const TrackPanelMouseState & state, (const TrackPanelMouseState & state,
const AudacityProject *pProject) const AudacityProject *pProject)
{ {

View File

@ -24,7 +24,7 @@ public:
: TrackControls( pTrack ) {} : TrackControls( pTrack ) {}
~LabelTrackControls(); ~LabelTrackControls();
UIHandlePtr HitTest std::vector<UIHandlePtr> HitTest
(const TrackPanelMouseState &state, (const TrackPanelMouseState &state,
const AudacityProject *pProject) override; const AudacityProject *pProject) override;

View File

@ -21,23 +21,25 @@ Paul Licameli split from TrackPanel.cpp
#include "../../../Project.h" #include "../../../Project.h"
#include "../../../TrackPanelMouseEvent.h" #include "../../../TrackPanelMouseEvent.h"
UIHandlePtr LabelTrack::DetailedHitTest std::vector<UIHandlePtr> LabelTrack::DetailedHitTest
(const TrackPanelMouseState &st, (const TrackPanelMouseState &st,
const AudacityProject *pProject, int, bool) const AudacityProject *pProject, int, bool)
{ {
UIHandlePtr result;
std::vector<UIHandlePtr> results;
const wxMouseState &state = st.state; const wxMouseState &state = st.state;
// Try label movement handles first
UIHandlePtr result;
result = LabelGlyphHandle::HitTest( result = LabelGlyphHandle::HitTest(
mGlyphHandle, state, Pointer<LabelTrack>(this), st.rect); mGlyphHandle, state, Pointer<LabelTrack>(this), st.rect);
if (result)
results.push_back(result);
if ( !result )
// Missed glyph, try text box
result = LabelTextHandle::HitTest( result = LabelTextHandle::HitTest(
mTextHandle, state, Pointer<LabelTrack>(this)); mTextHandle, state, Pointer<LabelTrack>(this));
if (result)
results.push_back(result);
return result; return results;
} }
std::shared_ptr<TrackControls> LabelTrack::GetControls() std::shared_ptr<TrackControls> LabelTrack::GetControls()

View File

@ -30,15 +30,17 @@ NoteTrackControls::~NoteTrackControls()
{ {
} }
UIHandlePtr NoteTrackControls::HitTest std::vector<UIHandlePtr> NoteTrackControls::HitTest
(const TrackPanelMouseState & st, (const TrackPanelMouseState & st,
const AudacityProject *pProject) const AudacityProject *pProject)
{ {
// Hits are mutually exclusive, results single
std::vector<UIHandlePtr> results;
const wxMouseState &state = st.state; const wxMouseState &state = st.state;
const wxRect &rect = st.rect; const wxRect &rect = st.rect;
if (state.ButtonIsDown(wxMOUSE_BTN_ANY)) { if (state.ButtonIsDown(wxMOUSE_BTN_ANY)) {
auto track = std::static_pointer_cast<NoteTrack>(FindTrack()); auto track = std::static_pointer_cast<NoteTrack>(FindTrack());
if (track && track->GetKind() == Track::Note) { auto result = [&]{
UIHandlePtr result; UIHandlePtr result;
if (NULL != (result = MuteButtonHandle::HitTest( if (NULL != (result = MuteButtonHandle::HitTest(
mMuteHandle, state, rect, pProject, track))) mMuteHandle, state, rect, pProject, track)))
@ -55,6 +57,10 @@ UIHandlePtr NoteTrackControls::HitTest
mClickHandle, state, rect, track))) mClickHandle, state, rect, track)))
return result; return result;
#endif #endif
}();
if (result) {
results.push_back(result);
return results;
} }
} }

View File

@ -35,7 +35,7 @@ public:
: TrackControls( pTrack ) {} : TrackControls( pTrack ) {}
~NoteTrackControls(); ~NoteTrackControls();
UIHandlePtr HitTest std::vector<UIHandlePtr> HitTest
(const TrackPanelMouseState &state, (const TrackPanelMouseState &state,
const AudacityProject *pProject) override; const AudacityProject *pProject) override;

View File

@ -22,18 +22,21 @@ Paul Licameli split from TrackPanel.cpp
#include "../../../ui/SelectHandle.h" #include "../../../ui/SelectHandle.h"
#include "StretchHandle.h" #include "StretchHandle.h"
UIHandlePtr NoteTrack::DetailedHitTest std::vector<UIHandlePtr> NoteTrack::DetailedHitTest
(const TrackPanelMouseState &state, (const TrackPanelMouseState &state,
const AudacityProject *pProject, int, bool ) const AudacityProject *pProject, int, bool )
{ {
// Eligible for stretch? // Eligible for stretch?
UIHandlePtr result; UIHandlePtr result;
std::vector<UIHandlePtr> results;
#ifdef USE_MIDI #ifdef USE_MIDI
result = StretchHandle::HitTest( result = StretchHandle::HitTest(
mStretchHandle, state, pProject, Pointer<NoteTrack>(this) ); mStretchHandle, state, pProject, Pointer<NoteTrack>(this) );
if (result)
results.push_back(result);
#endif #endif
return result; return results;
} }
std::shared_ptr<TrackControls> NoteTrack::GetControls() std::shared_ptr<TrackControls> NoteTrack::GetControls()

View File

@ -27,14 +27,22 @@ NoteTrackVRulerControls::~NoteTrackVRulerControls()
{ {
} }
UIHandlePtr NoteTrackVRulerControls::HitTest std::vector<UIHandlePtr> NoteTrackVRulerControls::HitTest
(const TrackPanelMouseState &st, (const TrackPanelMouseState &st,
const AudacityProject *pProject) const AudacityProject *pProject)
{ {
std::vector<UIHandlePtr> results;
UIHandlePtr result; UIHandlePtr result;
auto track = std::static_pointer_cast<NoteTrack>(FindTrack()); auto track = std::static_pointer_cast<NoteTrack>(FindTrack());
return NoteTrackVZoomHandle::HitTest( result = NoteTrackVZoomHandle::HitTest(
mVZoomHandle, st.state, track, st.rect); 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 unsigned NoteTrackVRulerControls::HandleWheelRotation

View File

@ -26,7 +26,7 @@ public:
: TrackVRulerControls( pTrack ) {} : TrackVRulerControls( pTrack ) {}
~NoteTrackVRulerControls(); ~NoteTrackVRulerControls();
UIHandlePtr HitTest std::vector<UIHandlePtr> HitTest
(const TrackPanelMouseState &state, (const TrackPanelMouseState &state,
const AudacityProject *pProject) override; const AudacityProject *pProject) override;

View File

@ -53,15 +53,17 @@ WaveTrackControls::~WaveTrackControls()
} }
UIHandlePtr WaveTrackControls::HitTest std::vector<UIHandlePtr> WaveTrackControls::HitTest
(const TrackPanelMouseState & st, (const TrackPanelMouseState & st,
const AudacityProject *pProject) const AudacityProject *pProject)
{ {
// Hits are mutually exclusive, results single
const wxMouseState &state = st.state; const wxMouseState &state = st.state;
const wxRect &rect = st.rect; const wxRect &rect = st.rect;
if (state.ButtonIsDown(wxMOUSE_BTN_LEFT)) { if (state.ButtonIsDown(wxMOUSE_BTN_LEFT)) {
auto track = FindTrack(); auto track = FindTrack();
if (track && track->GetKind() == Track::Wave) { std::vector<UIHandlePtr> results;
auto result = [&]{
UIHandlePtr result; UIHandlePtr result;
if (NULL != (result = MuteButtonHandle::HitTest( if (NULL != (result = MuteButtonHandle::HitTest(
mMuteHandle, state, rect, pProject, track))) mMuteHandle, state, rect, pProject, track)))
@ -78,6 +80,10 @@ UIHandlePtr WaveTrackControls::HitTest
if (NULL != (result = PanSliderHandle::HitTest( if (NULL != (result = PanSliderHandle::HitTest(
mPanHandle, state, rect, track))) mPanHandle, state, rect, track)))
return result; return result;
}();
if (result) {
results.push_back(result);
return results;
} }
} }

View File

@ -29,7 +29,7 @@ public:
: TrackControls( pTrack ) {} : TrackControls( pTrack ) {}
~WaveTrackControls(); ~WaveTrackControls();
UIHandlePtr HitTest std::vector<UIHandlePtr> HitTest
(const TrackPanelMouseState &state, (const TrackPanelMouseState &state,
const AudacityProject *pProject) override; const AudacityProject *pProject) override;

View File

@ -23,7 +23,7 @@ Paul Licameli split from TrackPanel.cpp
#include "SampleHandle.h" #include "SampleHandle.h"
#include "../../../ui/TimeShiftHandle.h" #include "../../../ui/TimeShiftHandle.h"
UIHandlePtr WaveTrack::DetailedHitTest std::vector<UIHandlePtr> WaveTrack::DetailedHitTest
(const TrackPanelMouseState &st, (const TrackPanelMouseState &st,
const AudacityProject *pProject, int currentTool, bool bMultiTool) 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 // If that toolbar were eliminated, this could simplify to a sequence of
// hit test routines describable by a table. // hit test routines describable by a table.
const auto wavetrack = static_cast<WaveTrack*>(st.pCell.get()); UIHandlePtr result;
bool isWaveform = (wavetrack->GetDisplay() == WaveTrack::Waveform); std::vector<UIHandlePtr> 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 // Ctrl modifier key in multi-tool overrides everything else
// (But this does not do the time shift constrained to the vertical only, // (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) // which is what happens when you hold Ctrl in the Time Shift tool mode)
return TimeShiftHandle::HitAnywhere( result = TimeShiftHandle::HitAnywhere(
mTimeShiftHandle, Pointer(this), false); mTimeShiftHandle, Pointer(this), false);
if (result)
results.push_back(result);
return results;
}
// Some special targets are not drawn in spectrogram, // Some special targets are not drawn in spectrogram,
// so don't hit them in such views. // so don't hit them in such views.
@ -50,8 +55,8 @@ UIHandlePtr WaveTrack::DetailedHitTest
mCutlineHandle, st.state, st.rect, mCutlineHandle, st.state, st.rect,
pProject, Pointer<WaveTrack>(this)))) pProject, Pointer<WaveTrack>(this))))
// This overriding test applies in all tools // This overriding test applies in all tools
return result; results.push_back(result);
else if (bMultiTool) { if (bMultiTool) {
// Conditional hit tests // Conditional hit tests
// If Tools toolbar were eliminated, we would keep these // If Tools toolbar were eliminated, we would keep these
// The priority of these, in case more than one might apply at one // 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( if (NULL != (result = EnvelopeHandle::WaveTrackHitTest(
mEnvelopeHandle, st.state, st.rect, mEnvelopeHandle, st.state, st.rect,
pProject, Pointer<WaveTrack>(this)))) pProject, Pointer<WaveTrack>(this))))
; results.push_back(result);
else if (NULL != (result = TimeShiftHandle::HitTest( if (NULL != (result = TimeShiftHandle::HitTest(
mTimeShiftHandle, st.state, st.rect, Pointer(this)))) mTimeShiftHandle, st.state, st.rect, Pointer(this))))
// This is the hit test on the "grips" drawn left and // This is the hit test on the "grips" drawn left and
// right in Multi only // right in Multi only
; results.push_back(result);
else if (NULL != (result = SampleHandle::HitTest( if (NULL != (result = SampleHandle::HitTest(
mSampleHandle, st.state, st.rect, mSampleHandle, st.state, st.rect,
pProject, Pointer<WaveTrack>(this)))) pProject, Pointer<WaveTrack>(this))))
; results.push_back(result);
return result;
} }
else switch ( currentTool ) { else {
switch ( currentTool ) {
// Unconditional hits appropriate to the tool // Unconditional hits appropriate to the tool
// If tools toolbar were eliminated, we would eliminate these // If tools toolbar were eliminated, we would eliminate these
case envelopeTool: { case envelopeTool: {
auto envelope = GetEnvelopeAtX( st.state.m_x ); auto envelope = GetEnvelopeAtX( st.state.m_x );
return EnvelopeHandle::HitAnywhere( result = EnvelopeHandle::HitAnywhere(
mEnvelopeHandle, envelope); mEnvelopeHandle, envelope);
break;
} }
case drawTool: case drawTool:
return SampleHandle::HitAnywhere( result = SampleHandle::HitAnywhere(
mSampleHandle, st.state, Pointer<WaveTrack>(this)); mSampleHandle, st.state, Pointer<WaveTrack>(this));
default: default:
break; break;
} }
if (result)
results.push_back(result);
}
} }
return {}; return results;
} }
std::shared_ptr<TrackControls> WaveTrack::GetControls() std::shared_ptr<TrackControls> WaveTrack::GetControls()

View File

@ -26,18 +26,23 @@ WaveTrackVRulerControls::~WaveTrackVRulerControls()
{ {
} }
UIHandlePtr WaveTrackVRulerControls::HitTest std::vector<UIHandlePtr> WaveTrackVRulerControls::HitTest
(const TrackPanelMouseState &st, (const TrackPanelMouseState &st,
const AudacityProject *) const AudacityProject *pProject)
{ {
std::vector<UIHandlePtr> results;
auto pTrack = Track::Pointer<WaveTrack>( FindTrack().get() ); auto pTrack = Track::Pointer<WaveTrack>( FindTrack().get() );
if (pTrack) { if (pTrack) {
auto result = std::make_shared<WaveTrackVZoomHandle>( auto result = std::make_shared<WaveTrackVZoomHandle>(
pTrack, st.rect, st.state.m_y ); pTrack, st.rect, st.state.m_y );
result = AssignUIHandlePtr(mVZoomHandle, result); 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 unsigned WaveTrackVRulerControls::HandleWheelRotation

View File

@ -26,7 +26,7 @@ public:
: TrackVRulerControls( pTrack ) {} : TrackVRulerControls( pTrack ) {}
~WaveTrackVRulerControls(); ~WaveTrackVRulerControls();
UIHandlePtr HitTest std::vector<UIHandlePtr> HitTest
(const TrackPanelMouseState &state, (const TrackPanelMouseState &state,
const AudacityProject *) override; const AudacityProject *) override;

View File

@ -21,7 +21,7 @@ TimeTrackControls::~TimeTrackControls()
{ {
} }
UIHandlePtr TimeTrackControls::HitTest std::vector<UIHandlePtr> TimeTrackControls::HitTest
(const TrackPanelMouseState & state, (const TrackPanelMouseState & state,
const AudacityProject *pProject) const AudacityProject *pProject)
{ {

View File

@ -24,7 +24,7 @@ public:
: TrackControls( pTrack ) {} : TrackControls( pTrack ) {}
~TimeTrackControls(); ~TimeTrackControls();
UIHandlePtr HitTest std::vector<UIHandlePtr> HitTest
(const TrackPanelMouseState &state, (const TrackPanelMouseState &state,
const AudacityProject *pProject) override; const AudacityProject *pProject) override;

View File

@ -18,12 +18,16 @@ Paul Licameli split from TrackPanel.cpp
#include "../../ui/EnvelopeHandle.h" #include "../../ui/EnvelopeHandle.h"
UIHandlePtr TimeTrack::DetailedHitTest std::vector<UIHandlePtr> TimeTrack::DetailedHitTest
(const TrackPanelMouseState &st, (const TrackPanelMouseState &st,
const AudacityProject *pProject, int, bool) const AudacityProject *pProject, int, bool)
{ {
return EnvelopeHandle::TimeTrackHitTest std::vector<UIHandlePtr> results;
auto result = EnvelopeHandle::TimeTrackHitTest
( mEnvelopeHandle, st.state, st.rect, pProject, Pointer<TimeTrack>(this) ); ( mEnvelopeHandle, st.state, st.rect, pProject, Pointer<TimeTrack>(this) );
if (result)
results.push_back(result);
return results;
} }
std::shared_ptr<TrackControls> TimeTrack::GetControls() std::shared_ptr<TrackControls> TimeTrack::GetControls()

View File

@ -79,14 +79,16 @@ BackgroundCell::~BackgroundCell()
{ {
} }
UIHandlePtr BackgroundCell::HitTest std::vector<UIHandlePtr> BackgroundCell::HitTest
(const TrackPanelMouseState &, (const TrackPanelMouseState &,
const AudacityProject *) const AudacityProject *)
{ {
std::vector<UIHandlePtr> results;
auto result = mHandle.lock(); auto result = mHandle.lock();
if (!result) if (!result)
result = std::make_shared<BackgroundHandle>(); result = std::make_shared<BackgroundHandle>();
return result; results.push_back(result);
return results;
} }
std::shared_ptr<Track> BackgroundCell::FindTrack() std::shared_ptr<Track> BackgroundCell::FindTrack()

View File

@ -29,7 +29,7 @@ public:
virtual ~BackgroundCell(); virtual ~BackgroundCell();
protected: protected:
UIHandlePtr HitTest std::vector<UIHandlePtr> HitTest
(const TrackPanelMouseState &state, (const TrackPanelMouseState &state,
const AudacityProject *) override; const AudacityProject *) override;

View File

@ -37,13 +37,16 @@ std::shared_ptr<Track> TrackControls::FindTrack()
return mwTrack.lock(); return mwTrack.lock();
} }
UIHandlePtr TrackControls::HitTest std::vector<UIHandlePtr> TrackControls::HitTest
(const TrackPanelMouseState &st, (const TrackPanelMouseState &st,
const AudacityProject *project) const AudacityProject *project)
{ {
// Hits are mutually exclusive, results single
const wxMouseState &state = st.state; const wxMouseState &state = st.state;
const wxRect &rect = st.rect; const wxRect &rect = st.rect;
UIHandlePtr result; UIHandlePtr result;
std::vector<UIHandlePtr> results;
auto pTrack = FindTrack(); auto pTrack = FindTrack();
// shared pointer to this: // shared pointer to this:
@ -51,18 +54,23 @@ UIHandlePtr TrackControls::HitTest
if (NULL != (result = CloseButtonHandle::HitTest( if (NULL != (result = CloseButtonHandle::HitTest(
mCloseHandle, state, rect, this))) mCloseHandle, state, rect, this)))
return result; results.push_back(result);
if (NULL != (result = MenuButtonHandle::HitTest( if (NULL != (result = MenuButtonHandle::HitTest(
mMenuHandle, state, rect, sThis))) mMenuHandle, state, rect, sThis)))
return result; results.push_back(result);
if (NULL != (result = MinimizeButtonHandle::HitTest( if (NULL != (result = MinimizeButtonHandle::HitTest(
mMinimizeHandle, state, rect, this))) mMinimizeHandle, state, rect, this)))
return result; results.push_back(result);
return TrackSelectHandle::HitAnywhere( if (results.empty()) {
mSelectHandle, pTrack); if (NULL != (result = TrackSelectHandle::HitAnywhere(
mSelectHandle, pTrack)))
results.push_back(result);
}
return results;
} }
enum enum

View File

@ -48,7 +48,7 @@ public:
protected: protected:
// An override is supplied for derived classes to call through but it is // An override is supplied for derived classes to call through but it is
// still marked pure virtual // still marked pure virtual
virtual UIHandlePtr HitTest virtual std::vector<UIHandlePtr> HitTest
(const TrackPanelMouseState &state, (const TrackPanelMouseState &state,
const AudacityProject *) override = 0; const AudacityProject *) override = 0;

View File

@ -25,44 +25,57 @@ Paul Licameli split from TrackPanel.cpp
#include "../../TrackPanelResizerCell.h" #include "../../TrackPanelResizerCell.h"
#include "BackgroundCell.h" #include "BackgroundCell.h"
UIHandlePtr Track::HitTest std::vector<UIHandlePtr> Track::HitTest
(const TrackPanelMouseState &st, (const TrackPanelMouseState &st,
const AudacityProject *pProject) const AudacityProject *pProject)
{ {
UIHandlePtr result;
std::vector<UIHandlePtr> results;
const ToolsToolBar * pTtb = pProject->GetToolsToolBar(); const ToolsToolBar * pTtb = pProject->GetToolsToolBar();
const bool isMultiTool = pTtb->IsDown(multiTool); const bool isMultiTool = pTtb->IsDown(multiTool);
const auto currentTool = pTtb->GetCurrentTool(); 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 // Zoom tool is a non-selecting tool that takes precedence in all tracks
// over all other tools, no matter what detail you point at. // over all other tools, no matter what detail you point at.
return ZoomHandle::HitAnywhere( result = ZoomHandle::HitAnywhere(
pProject->GetBackgroundCell()->mZoomHandle); pProject->GetBackgroundCell()->mZoomHandle);
results.push_back(result);
return results;
}
// In other tools, let subclasses determine detailed hits. // In other tools, let subclasses determine detailed hits.
auto result = results =
DetailedHitTest( st, pProject, currentTool, isMultiTool ); DetailedHitTest( st, pProject, currentTool, isMultiTool );
// If there is no detailed hit for the subclass, there are still some // There are still some general cases.
// general cases.
// Sliding applies in more than one track type. // Sliding applies in more than one track type.
if ( !result && !isMultiTool && currentTool == slideTool ) if ( !isMultiTool && currentTool == slideTool ) {
result = TimeShiftHandle::HitAnywhere( result = TimeShiftHandle::HitAnywhere(
mTimeShiftHandle, Pointer(this), false); mTimeShiftHandle, Pointer(this), false);
if (result)
results.push_back(result);
}
// Let the multi-tool right-click handler apply only in default of all // Let the multi-tool right-click handler apply only in default of all
// other detailed hits. // other detailed hits.
if ( !result && isMultiTool ) if ( isMultiTool ) {
result = ZoomHandle::HitTest( result = ZoomHandle::HitTest(
pProject->GetBackgroundCell()->mZoomHandle, st.state); pProject->GetBackgroundCell()->mZoomHandle, st.state);
if (result)
results.push_back(result);
}
// Finally, default of all is adjustment of the selection box. // Finally, default of all is adjustment of the selection box.
if ( !result && ( isMultiTool || currentTool == selectTool) ) if ( isMultiTool || currentTool == selectTool ) {
result = SelectHandle::HitTest( result = SelectHandle::HitTest(
mSelectHandle, st, pProject, Pointer(this)); mSelectHandle, st, pProject, Pointer(this));
if (result)
results.push_back(result);
}
return result; return results;
} }
std::shared_ptr<TrackPanelCell> Track::GetTrackControl() std::shared_ptr<TrackPanelCell> Track::GetTrackControl()

View File

@ -32,10 +32,10 @@ std::shared_ptr<Track> TrackVRulerControls::FindTrack()
return mwTrack.lock(); return mwTrack.lock();
} }
UIHandlePtr TrackVRulerControls::HitTest std::vector<UIHandlePtr> TrackVRulerControls::HitTest
(const TrackPanelMouseState &, const AudacityProject *) (const TrackPanelMouseState &, const AudacityProject *)
{ {
return {}; return std::vector<UIHandlePtr>{};
} }
void TrackVRulerControls::DrawZooming void TrackVRulerControls::DrawZooming

View File

@ -28,7 +28,7 @@ public:
std::shared_ptr<Track> FindTrack() override; std::shared_ptr<Track> FindTrack() override;
// Define a default hit test method, just for message and cursor // Define a default hit test method, just for message and cursor
UIHandlePtr HitTest std::vector<UIHandlePtr> HitTest
(const TrackPanelMouseState &state, (const TrackPanelMouseState &state,
const AudacityProject *pProject) override; const AudacityProject *pProject) override;