1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-10 17:37:45 +02:00

Rewrite TrackPanel::FindTrack as FindCell ...

... which reports disjoint rectangles for the track control panel, the vertical
ruler, and the proper track area.
This commit is contained in:
Paul Licameli 2017-01-10 15:53:19 -05:00
parent 8ddbc1d3d3
commit 54aea4bccf
2 changed files with 162 additions and 155 deletions

@ -227,10 +227,10 @@ but that width may be adjusted when tracks change their vertical scales.
GetLabelWidth() counts columns up to and including the VRuler. GetLabelWidth() counts columns up to and including the VRuler.
GetLeftOffset() is yet one more -- it counts the "one pixel" column. GetLeftOffset() is yet one more -- it counts the "one pixel" column.
FindTrack() for label returns a rectangle up to and including the One Pixel column, FindCell() for label or vruler returns a rectangle up to and including the One Pixel column,
but OMITS left and top insets but OMITS left and top insets
FindTrack() for !label returns a rectangle with x == GetLeftOffset(), and INCLUDES FindCell() for track returns a rectangle with x == GetLeftOffset(), and INCLUDES
right and top insets right and top insets
+--------------- ... ------ ... --------------------- ... ... -------------+ +--------------- ... ------ ... --------------------- ... ... -------------+
@ -1723,10 +1723,9 @@ void TrackPanel::HandleCursor(const wxMouseEvent & event)
// (2) If we are not over a track at all, set the cursor to Arrow and // (2) If we are not over a track at all, set the cursor to Arrow and
// clear the StatusBar, // clear the StatusBar,
wxRect labelRect, trackRect; const auto foundCell = FindCell( event.m_x, event.m_y );
Track *const label = FindTrack(event.m_x, event.m_y, true, true, &labelRect); auto &track = foundCell.pTrack;
Track *const nonlabel = FindTrack(event.m_x, event.m_y, false, false, &trackRect); auto &trackRect = foundCell.rect;
Track *const track = label ? label : nonlabel;
if (!track) { if (!track) {
SetCursor(*mArrowCursor); SetCursor(*mArrowCursor);
@ -1745,16 +1744,17 @@ void TrackPanel::HandleCursor(const wxMouseEvent & event)
wxString tip; wxString tip;
// Are we within the vertical resize area? // Are we within the vertical resize area?
if (nonlabel if (within(event.m_y, trackRect.GetBottom(), TRACK_RESIZE_REGION))
? within(event.m_y, trackRect.y + trackRect.height, TRACK_RESIZE_REGION)
: within(event.m_y, labelRect.y + labelRect.height, TRACK_RESIZE_REGION))
{ {
SetCursorAndTipWhenInVResizeArea(nonlabel && track->GetLinked(), tip); SetCursorAndTipWhenInVResizeArea(
track->GetLinked() && foundCell.type != CellType::Label, tip);
// tip may still be NULL at this point, in which case we go on looking. // tip may still be NULL at this point, in which case we go on looking.
} }
if ((tip == wxString()) && label) { if ((tip == wxString()) &&
SetCursorAndTipWhenInLabel( label, event, tip ); (foundCell.type == CellType::Label ||
foundCell.type == CellType::VRuler)) {
SetCursorAndTipWhenInLabel( track, event, tip );
} }
// Otherwise, we must be over a track of some kind // Otherwise, we must be over a track of some kind
@ -1768,9 +1768,8 @@ void TrackPanel::HandleCursor(const wxMouseEvent & event)
} }
if ((tip == wxString()) && if ((tip == wxString()) &&
nonlabel && track->GetKind() == Track::Wave &&
nonlabel->GetKind() == Track::Wave && SetCursorForCutline(static_cast<WaveTrack*>(track), trackRect, event))
SetCursorForCutline(static_cast<WaveTrack*>(nonlabel), trackRect, event))
return; return;
if( tip == wxString() ) if( tip == wxString() )
@ -1818,8 +1817,9 @@ void TrackPanel::HandleCursor(const wxMouseEvent & event)
/// dragging over a waveform. /// dragging over a waveform.
void TrackPanel::HandleSelect(wxMouseEvent & event) void TrackPanel::HandleSelect(wxMouseEvent & event)
{ {
wxRect rect; const auto foundCell = FindCell(event.m_x, event.m_y);
Track *t = FindTrack(event.m_x, event.m_y, false, false, &rect); auto &t = foundCell.pTrack;
auto &rect = foundCell.rect;
// AS: Ok, did the user just click the mouse, release the mouse, // AS: Ok, did the user just click the mouse, release the mouse,
// or drag? // or drag?
@ -1849,9 +1849,7 @@ void TrackPanel::HandleSelect(wxMouseEvent & event)
} else if (event.LeftDClick() && !event.ShiftDown()) { } else if (event.LeftDClick() && !event.ShiftDown()) {
if (!mCapturedTrack) { if (!mCapturedTrack) {
wxRect rect; mCapturedTrack = t;
mCapturedTrack =
FindTrack(event.m_x, event.m_y, false, false, &rect);
if (!mCapturedTrack) if (!mCapturedTrack)
return; return;
} }
@ -2894,12 +2892,6 @@ void TrackPanel::SelectionHandleDrag(wxMouseEvent & event, Track *clickedTrack)
wxRect rect = mCapturedRect; wxRect rect = mCapturedRect;
Track *pTrack = mCapturedTrack; Track *pTrack = mCapturedTrack;
if (!pTrack) {
pTrack = FindTrack(event.m_x, event.m_y, false, false, &rect);
rect.y += kTopMargin;
rect.height -= kTopMargin + kBottomMargin;
}
// Also fuhggeddaboudit if not in a track. // Also fuhggeddaboudit if not in a track.
if (!pTrack) if (!pTrack)
return; return;
@ -2928,7 +2920,7 @@ void TrackPanel::SelectionHandleDrag(wxMouseEvent & event, Track *clickedTrack)
// Handle which tracks are selected // Handle which tracks are selected
Track *sTrack = pTrack; Track *sTrack = pTrack;
Track *eTrack = FindTrack(x, y, false, false, NULL); Track *eTrack = FindCell(x, y).pTrack;
if( !event.ControlDown() ) if( !event.ControlDown() )
SelectRangeOfTracks(sTrack, eTrack); SelectRangeOfTracks(sTrack, eTrack);
@ -3165,10 +3157,11 @@ bool mayDragWidth, bool onlyWithinSnapDistance,
void TrackPanel::HandleEnvelope(wxMouseEvent & event) void TrackPanel::HandleEnvelope(wxMouseEvent & event)
{ {
if (event.LeftDown()) { if (event.LeftDown()) {
wxRect rect; const auto foundCell = FindCell(event.m_x, event.m_y);
Track *pTrack = FindTrack(event.m_x, event.m_y, false, false, &rect); auto &pTrack = foundCell.pTrack;
auto &rect = foundCell.rect;
if (!pTrack) if (!pTrack || foundCell.type != CellType::Track)
return; return;
SetCapturedTrack(pTrack, IsEnveloping); SetCapturedTrack(pTrack, IsEnveloping);
@ -3437,16 +3430,16 @@ namespace {
/// Prepare for sliding. /// Prepare for sliding.
void TrackPanel::StartSlide(wxMouseEvent & event) void TrackPanel::StartSlide(wxMouseEvent & event)
{ {
wxRect rect;
mHSlideAmount = 0.0; mHSlideAmount = 0.0;
mDidSlideVertically = false; mDidSlideVertically = false;
mTrackExclusions.clear(); mTrackExclusions.clear();
Track *vt = FindTrack(event.m_x, event.m_y, false, false, &rect); const auto foundCell = FindCell(event.m_x, event.m_y);
if (!vt) auto &vt = foundCell.pTrack;
if (!vt || foundCell.type != CellType::Track)
return; return;
auto &rect = foundCell.rect;
ToolsToolBar * ttb = mListener->TP_GetToolsToolBar(); ToolsToolBar * ttb = mListener->TP_GetToolsToolBar();
bool multiToolModeActive = (ttb && ttb->IsDown(multiTool)); bool multiToolModeActive = (ttb && ttb->IsDown(multiTool));
@ -3657,16 +3650,17 @@ void TrackPanel::DoSlide(wxMouseEvent & event)
// find which track the mouse is currently in (mouseTrack) - // find which track the mouse is currently in (mouseTrack) -
// this may not be the same as the one we started in... // this may not be the same as the one we started in...
Track *mouseTrack = FindTrack(event.m_x, event.m_y, false, false, NULL);
if (mouseTrack == NULL) { const auto foundCell = FindCell(event.m_x, event.m_y);
// Allow sliding if the pointer is not over any track, but only if x is if (foundCell.type != CellType::Track)
// Allow sliding only if x is
// within the bounds of the tracks area. // within the bounds of the tracks area.
int width; return;
GetTracksUsableArea(&width, NULL);
if (event.m_x >= GetLeftOffset() && event.m_x < GetLeftOffset() + width) auto mouseTrack = foundCell.pTrack;
mouseTrack = mCapturedTrack; if (mouseTrack == nullptr) {
else // Allow sliding if the pointer is not over any track.
return; mouseTrack = mCapturedTrack;
} }
// Start by undoing the current slide amount; everything // Start by undoing the current slide amount; everything
@ -3987,9 +3981,10 @@ void TrackPanel::HandleZoomClick(wxMouseEvent & event)
if (mCapturedTrack) if (mCapturedTrack)
return; return;
mCapturedTrack = FindTrack(event.m_x, event.m_y, false, false, const auto foundCell = FindCell(event.m_x, event.m_y);
&mCapturedRect); mCapturedTrack = foundCell.pTrack;
if (!mCapturedTrack) mCapturedRect = foundCell.rect;
if (foundCell.type != CellType::Track || !(mCapturedTrack = foundCell.pTrack))
return; return;
SetCapturedTrack(mCapturedTrack, IsZooming); SetCapturedTrack(mCapturedTrack, IsZooming);
@ -4106,9 +4101,10 @@ void TrackPanel::HandleVZoomClick( wxMouseEvent & event )
{ {
if (mCapturedTrack) if (mCapturedTrack)
return; return;
mCapturedTrack = FindTrack(event.m_x, event.m_y, true, false, const auto foundCell = FindCell(event.m_x, event.m_y);
&mCapturedRect); mCapturedTrack = foundCell.pTrack;
if (!mCapturedTrack) mCapturedRect = foundCell.rect;
if (foundCell.type != CellType::VRuler || !(mCapturedTrack = foundCell.pTrack))
return; return;
if (mCapturedTrack->GetKind() == Track::Wave if (mCapturedTrack->GetKind() == Track::Wave
@ -4458,10 +4454,11 @@ bool TrackPanel::IsSampleEditingPossible( wxMouseEvent &event, const WaveTrack *
bool showPoints; bool showPoints;
{ {
wxRect rect; const auto foundCell = FindCell(event.m_x, event.m_y);
FindTrack(event.m_x, event.m_y, false, false, &rect); if ( foundCell.type != CellType::Track )
return false;
const double rate = wt->GetRate(); const double rate = wt->GetRate();
const double time = mViewInfo->PositionToTime(event.m_x, rect.x); const double time = mViewInfo->PositionToTime(event.m_x, foundCell.rect.x);
int width; int width;
GetTracksUsableArea(&width, NULL); GetTracksUsableArea(&width, NULL);
showPoints = SampleResolutionTest(*mViewInfo, wt, time, rate, width); showPoints = SampleResolutionTest(*mViewInfo, wt, time, rate, width);
@ -4509,14 +4506,14 @@ float TrackPanel::FindSampleEditingLevel(wxMouseEvent &event, double dBRange, do
/// Someone has just clicked the mouse. What do we do? /// Someone has just clicked the mouse. What do we do?
void TrackPanel::HandleSampleEditingClick( wxMouseEvent & event ) void TrackPanel::HandleSampleEditingClick( wxMouseEvent & event )
{ {
//declare a rectangle to determine clicking position
wxRect rect;
//Get the track the mouse is over, and save it away for future events //Get the track the mouse is over, and save it away for future events
mDrawingTrack = NULL; mDrawingTrack = NULL;
Track *const t = FindTrack(event.m_x, event.m_y, false, false, &rect); const auto foundCell = FindCell(event.m_x, event.m_y);
auto &t = foundCell.pTrack;
auto &rect = foundCell.rect;
if (!t || (t->GetKind() != Track::Wave)) if (!t || (t->GetKind() != Track::Wave)
|| foundCell.type != CellType::Track)
return; return;
const auto wt = static_cast<WaveTrack *>(t); const auto wt = static_cast<WaveTrack *>(t);
if( !IsSampleEditingPossible( event, wt ) ) if( !IsSampleEditingPossible( event, wt ) )
@ -5062,9 +5059,9 @@ void TrackPanel::HandleLabelClick(wxMouseEvent & event)
bool unsafe = IsUnsafe(); bool unsafe = IsUnsafe();
wxRect rect; const auto foundCell = FindCell(event.m_x, event.m_y);
auto &t = foundCell.pTrack;
Track *t = FindTrack(event.m_x, event.m_y, true, true, &rect); auto &rect = foundCell.rect;
// LL: Check close box // LL: Check close box
if (isleft && CloseFunc(t, rect, event.m_x, event.m_y)) if (isleft && CloseFunc(t, rect, event.m_x, event.m_y))
@ -5384,20 +5381,14 @@ bool TrackPanel::PopupFunc(Track * t, wxRect rect, int x, int y)
/// update the track size. /// update the track size.
void TrackPanel::HandleResizeClick( wxMouseEvent & event ) void TrackPanel::HandleResizeClick( wxMouseEvent & event )
{ {
wxRect rTrack; // Get here only if the click was near the bottom of the cell rectangle.
wxRect rLabel;
// DM: Figure out what track is about to be resized // DM: Figure out what track is about to be resized
Track *track = FindTrack(event.m_x, event.m_y, false, false, &rTrack); const auto foundCell = FindCell(event.m_x, event.m_y);
auto track = foundCell.pTrack;
if (!track) { if (foundCell.type == CellType::Label && track && track->GetLinked())
// This will only return unlinked tracks or left channels of stereo tracks // Click was at the bottom of a stereo track.
// or NULL: track = track->GetLink();
track = FindTrack(event.m_x, event.m_y, true, true, &rLabel);
// If stereo, get the right channel.
if (track && track->GetLinked())
track = track->GetLink();
}
if (!track) { if (!track) {
return; return;
@ -5695,9 +5686,10 @@ void TrackPanel::HandleWheelRotation(wxMouseEvent & event)
// Special case of pointer in the vertical ruler // Special case of pointer in the vertical ruler
if (event.ShiftDown() || event.CmdDown()) { if (event.ShiftDown() || event.CmdDown()) {
wxRect rect; const auto foundCell = FindCell(event.m_x, event.m_y);
Track *const pTrack = FindTrack(event.m_x, event.m_y, true, false, &rect); auto &pTrack = foundCell.pTrack;
if (pTrack && event.m_x >= GetVRulerOffset()) { auto &rect = foundCell.rect;
if (pTrack && foundCell.type == CellType::VRuler) {
HandleWheelRotationInVRuler(event, steps, pTrack, rect); HandleWheelRotationInVRuler(event, steps, pTrack, rect);
// Always stop propagation even if the ruler didn't change. The ruler // Always stop propagation even if the ruler didn't change. The ruler
// is a narrow enough target. // is a narrow enough target.
@ -6213,8 +6205,11 @@ void TrackPanel::OnMouseEvent(wxMouseEvent & event)
if (event.ButtonUp()) { if (event.ButtonUp()) {
wxRect rect; wxRect rect;
Track *t = FindTrack(event.m_x, event.m_y, false, false, &rect); const auto foundCell = FindCell(event.m_x, event.m_y);
if (t) auto t = foundCell.pTrack;
if (t
&& foundCell.type == CellType::Track
)
EnsureVisible(t); EnsureVisible(t);
} }
} }
@ -6544,21 +6539,16 @@ void TrackPanel::HandleTextDragRelease(LabelTrack * lTrack, wxMouseEvent & event
// from the other OnMouseEvent code. // from the other OnMouseEvent code.
void TrackPanel::HandleTrackSpecificMouseEvent(wxMouseEvent & event) void TrackPanel::HandleTrackSpecificMouseEvent(wxMouseEvent & event)
{ {
Track * pTrack; const auto foundCell = FindCell( event.m_x, event.m_y );
Track * pControlTrack; auto &pTrack = foundCell.pTrack;
wxRect rTrack; auto &rect = foundCell.rect;
wxRect rLabel;
bool unsafe = IsUnsafe(); bool unsafe = IsUnsafe();
pControlTrack = FindTrack(event.m_x, event.m_y, true, true, &rLabel);
pTrack = FindTrack(event.m_x, event.m_y, false, false, &rTrack);
//call HandleResize if I'm over the border area //call HandleResize if I'm over the border area
if (event.LeftDown() && if (event.LeftDown() &&
(within(event.m_y, rTrack.y + rTrack.height, TRACK_RESIZE_REGION) pTrack &&
|| within(event.m_y, rLabel.y + rLabel.height, (within(event.m_y, rect.GetBottom(), TRACK_RESIZE_REGION))) {
TRACK_RESIZE_REGION))) {
HandleResize(event); HandleResize(event);
HandleCursor(event); HandleCursor(event);
return; return;
@ -6566,43 +6556,45 @@ void TrackPanel::HandleTrackSpecificMouseEvent(wxMouseEvent & event)
// AS: If the user clicked outside all tracks, make nothing // AS: If the user clicked outside all tracks, make nothing
// selected. // selected.
if ((event.ButtonDown() || event.ButtonDClick()) && if ((event.ButtonDown() || event.ButtonDClick()) && !pTrack) {
!(pTrack || pControlTrack)) {
SelectNone(); SelectNone();
Refresh(false); Refresh(false);
return; return;
} }
//Determine if user clicked on the track's left-hand label //Determine if user clicked on the track's left-hand label or ruler
if (!mCapturedTrack && event.m_x < GetLeftOffset()) { if (!mCapturedTrack) {
if (event.m_x >= GetVRulerOffset()) { if (foundCell.type == CellType::VRuler) {
if( !event.Dragging() ) // JKC: Only want the mouse down event. if( !event.Dragging() ) // JKC: Only want the mouse down event.
HandleVZoom(event); HandleVZoom(event);
HandleCursor(event); HandleCursor(event);
return;
} }
else { else if (foundCell.type == CellType::Label) {
HandleLabelClick(event); HandleLabelClick(event);
HandleCursor(event); HandleCursor(event);
return;
} }
return;
} }
//Determine if user clicked on a label track. //Determine if user clicked on a label track.
//If so, use MouseDown handler for the label track. //If so, use MouseDown handler for the label track.
if (pTrack && (pTrack->GetKind() == Track::Label)) if (pTrack && foundCell.type == CellType::Track &&
(pTrack->GetKind() == Track::Label))
{ {
if (HandleLabelTrackClick((LabelTrack *)pTrack, rTrack, event)) if (HandleLabelTrackClick((LabelTrack *)pTrack, rect, event))
return; return;
} }
bool handled = false; bool handled = false;
if (pTrack && (pTrack->GetKind() == Track::Wave) && if (pTrack && foundCell.type == CellType::Track &&
(pTrack->GetKind() == Track::Wave) &&
(mMouseCapture == IsUncaptured || mMouseCapture == WasOverCutLine)) (mMouseCapture == IsUncaptured || mMouseCapture == WasOverCutLine))
handled = HandleTrackLocationMouseEvent((WaveTrack *)pTrack, rTrack, event); handled = HandleTrackLocationMouseEvent((WaveTrack *)pTrack, rect, event);
ToolsToolBar * pTtb = mListener->TP_GetToolsToolBar(); ToolsToolBar * pTtb = mListener->TP_GetToolsToolBar();
if( !handled && pTtb != NULL ) if( !handled && pTtb != NULL && foundCell.type == CellType::Track )
{ {
int toolToUse = DetermineToolToUse(pTtb, event); int toolToUse = DetermineToolToUse(pTtb, event);
@ -6665,10 +6657,10 @@ int TrackPanel::DetermineToolToUse( ToolsToolBar * pTtb, const wxMouseEvent & ev
return currentTool; return currentTool;
// So now we have to find out what we are near to.. // So now we have to find out what we are near to..
wxRect rect; const auto foundCell = FindCell(event.m_x, event.m_y);
auto &pTrack = foundCell.pTrack;
Track *pTrack = FindTrack(event.m_x, event.m_y, false, false, &rect); auto &rect = foundCell.rect;
if( !pTrack ) if( !pTrack|| foundCell.type != CellType::Track )
return currentTool; return currentTool;
int trackKind = pTrack->GetKind(); int trackKind = pTrack->GetKind();
@ -8790,91 +8782,101 @@ void TrackPanel::OnSetFont(wxCommandEvent & WXUNUSED(event))
/// Determines which track is under the mouse /// Determines which track is under the mouse
/// @param mouseX - mouse X position. /// @param mouseX - mouse X position.
/// @param mouseY - mouse Y position. /// @param mouseY - mouse Y position.
/// @param label - true iff the X Y position is relative to side-panel with the labels in it. TrackPanel::FoundCell TrackPanel::FindCell(int mouseX, int mouseY)
/// @param link - true iff we should consider a hit in any linked track as a hit.
/// @param *trackRect - returns track rectangle.
Track *TrackPanel::FindTrack(int mouseX, int mouseY, bool label, bool link,
wxRect * trackRect)
{ {
// If label is true, resulting rectangle OMITS left and top insets.
// If label is false, resulting rectangle INCLUDES right and top insets.
wxRect rect; wxRect rect;
rect.x = 0; rect.x = 0;
rect.y = -mViewInfo->vpos; rect.y = -mViewInfo->vpos;
rect.y += kTopInset; rect.y += kTopInset;
GetSize(&rect.width, &rect.height); GetSize(&rect.width, &rect.height);
if (label) { // The type of cell that may be found is determined by the x coordinate.
rect.width = GetLeftOffset(); CellType type = CellType::Track;
} else { if (mouseX >= 0 && mouseX < rect.width) {
rect.x = GetLeftOffset(); if (mouseX < GetVRulerOffset())
rect.width -= GetLeftOffset(); type = CellType::Label,
rect.width = GetVRulerOffset();
else if (mouseX < GetLeftOffset())
type = CellType::VRuler,
rect.x = GetVRulerOffset(),
rect.width = GetLeftOffset() - GetVRulerOffset();
else
type = CellType::Track,
rect.x = GetLeftOffset(),
rect.width -= GetLeftOffset();
} }
auto output = [&](Track *pTrack) -> FoundCell {
// If label or vruler, resulting rectangle OMITS left and top insets.
// If track, resulting rectangle INCLUDES right and top insets.
if (pTrack) {
rect.y -= kTopInset;
switch (type) {
case CellType::Label:
rect.x += kLeftInset;
rect.width -= kLeftInset;
rect.y += kTopInset;
rect.height -= kTopInset;
break;
case CellType::VRuler:
rect.y += kTopInset;
rect.height -= kTopInset;
break;
case CellType::Track:
default:
break;
}
return { pTrack, type, rect };
}
else
return { nullptr, type, {} };
};
VisibleTrackIterator iter(GetProject()); VisibleTrackIterator iter(GetProject());
for (Track * t = iter.First(); t; t = iter.Next()) { for (Track * t = iter.First(); t; t = iter.Next()) {
rect.y = t->GetY() - mViewInfo->vpos + kTopInset; rect.y = t->GetY() - mViewInfo->vpos + kTopInset;
rect.height = t->GetHeight(); rect.height = t->GetHeight();
if (link && t->GetLink()) { if (type == CellType::Label) {
Track *l = t->GetLink(); if (t->GetLink()) {
int h = l->GetHeight(); Track *l = t->GetLink();
if (!t->GetLinked()) { int h = l->GetHeight();
t = l; if (!t->GetLinked()) {
rect.y = t->GetY() - mViewInfo->vpos + kTopInset; t = l;
rect.y = t->GetY() - mViewInfo->vpos + kTopInset;
}
rect.height += h;
} }
rect.height += h;
}
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY #ifdef EXPERIMENTAL_OUTPUT_DISPLAY
else if(link && MONO_WAVE_PAN(t)) else if( MONO_WAVE_PAN(t) )
{ rect.height += t->GetHeight(true);
rect.height += t->GetHeight(true);
}
#endif #endif
}
//Determine whether the mouse is inside //Determine whether the mouse is inside
//the current rectangle. If so, recalculate //the current rectangle. If so, recalculate
//the proper dimensions and return. //the proper dimensions and return.
if (rect.Contains(mouseX, mouseY)) { if (rect.Contains(mouseX, mouseY)) {
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY #ifdef EXPERIMENTAL_OUTPUT_DISPLAY
// PRL: Is it good to have a side effect in a hit-testing routine?
t->SetVirtualStereo(false); t->SetVirtualStereo(false);
#endif #endif
if (trackRect) { return output(t);
rect.y -= kTopInset;
if (label) {
rect.x += kLeftInset;
rect.width -= kLeftInset;
rect.y += kTopInset;
rect.height -= kTopInset;
}
*trackRect = rect;
}
return t;
} }
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY #ifdef EXPERIMENTAL_OUTPUT_DISPLAY
if(!link && MONO_WAVE_PAN(t)){ if(type != CellType::Label && MONO_WAVE_PAN(t)){
rect.y = t->GetY(true) - mViewInfo->vpos + kTopInset; rect.y = t->GetY(true) - mViewInfo->vpos + kTopInset;
rect.height = t->GetHeight(true); rect.height = t->GetHeight(true);
if (rect.Contains(mouseX, mouseY)) { if (rect.Contains(mouseX, mouseY)) {
// PRL: Is it good to have a side effect in a hit-testing routine?
t->SetVirtualStereo(true); t->SetVirtualStereo(true);
if (trackRect) { return output(t);
rect.y -= kTopInset;
if (label) {
rect.x += kLeftInset;
rect.width -= kLeftInset;
rect.y += kTopInset;
rect.height -= kTopInset;
}
*trackRect = rect;
}
return t;
} }
} }
#endif // EXPERIMENTAL_OUTPUT_DISPLAY #endif // EXPERIMENTAL_OUTPUT_DISPLAY
} }
return NULL; return { nullptr, type, {} };
} }
/// This finds the rectangle of a given track, either the /// This finds the rectangle of a given track, either the

@ -479,8 +479,13 @@ protected:
virtual void OnMergeStereo(wxCommandEvent &event); virtual void OnMergeStereo(wxCommandEvent &event);
// Find track info by coordinate // Find track info by coordinate
virtual Track *FindTrack(int mouseX, int mouseY, bool label, bool link, enum class CellType { Label, Track, VRuler };
wxRect * trackRect = NULL); struct FoundCell {
Track *pTrack;
CellType type;
wxRect rect;
};
virtual FoundCell FindCell(int mouseX, int mouseY);
virtual wxRect FindTrackRect(Track * target, bool label); virtual wxRect FindTrackRect(Track * target, bool label);