From 5395f253bf34b1ff6d807f6ed199269adb924f6c Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Sat, 3 Jun 2017 23:20:37 -0400 Subject: [PATCH] Reviewed use of Track::GetY; don't use in NoteTrack; fix off-by-1's --- src/NoteTrack.cpp | 14 +++++++------- src/NoteTrack.h | 8 ++++---- src/Project.cpp | 10 ++++++---- src/TrackPanel.cpp | 15 ++++++++++++--- src/tracks/ui/EditCursorOverlay.cpp | 9 +++++---- 5 files changed, 34 insertions(+), 22 deletions(-) diff --git a/src/NoteTrack.cpp b/src/NoteTrack.cpp index 473b3060e..0b461ecd8 100644 --- a/src/NoteTrack.cpp +++ b/src/NoteTrack.cpp @@ -907,26 +907,26 @@ void NoteTrack::VScroll(int start, int end) // Zoom the note track, centering the pitch at centerY, // amount is 1 for zoom in, and -1 for zoom out -void NoteTrack::Zoom(int centerY, int amount) +void NoteTrack::Zoom(const wxRect &rect, int centerY, int amount) { // Construct track rectangle to map pitch to screen coordinates // Only y and height are needed: - wxRect trackRect(0, GetY(), 1, GetHeight()); + wxRect trackRect(0, rect.GetY(), 1, rect.GetHeight()); PrepareIPitchToY(trackRect); int centerPitch = YToIPitch(centerY); // zoom out by changing the pitch height -- a small integer mPitchHeight += amount; if (mPitchHeight <= 0) mPitchHeight = 1; PrepareIPitchToY(trackRect); // update because mPitchHeight changed - int newCenterPitch = YToIPitch(GetY() + GetHeight() / 2); + int newCenterPitch = YToIPitch(rect.GetY() + rect.GetHeight() / 2); // center the pitch that the user clicked on SetBottomNote(mBottomNote + (centerPitch - newCenterPitch)); } -void NoteTrack::ZoomTo(int start, int end) +void NoteTrack::ZoomTo(const wxRect &rect, int start, int end) { - wxRect trackRect(0, GetY(), 1, GetHeight()); + wxRect trackRect(0, rect.GetY(), 1, rect.GetHeight()); PrepareIPitchToY(trackRect); int topPitch = YToIPitch(start); int botPitch = YToIPitch(end); @@ -934,7 +934,7 @@ void NoteTrack::ZoomTo(int start, int end) int temp = topPitch; topPitch = botPitch; botPitch = temp; } if (topPitch == botPitch) { // can't divide by zero, do something else - Zoom(start, 1); + Zoom(rect, start, 1); return; } int trialPitchHeight = trackRect.height / (topPitch - botPitch); @@ -943,7 +943,7 @@ void NoteTrack::ZoomTo(int start, int end) } else if (trialPitchHeight == 0) { trialPitchHeight = 1; } - Zoom((start + end) / 2, trialPitchHeight - mPitchHeight); + Zoom(rect, (start + end) / 2, trialPitchHeight - mPitchHeight); } int NoteTrack::YToIPitch(int y) diff --git a/src/NoteTrack.h b/src/NoteTrack.h index b149a85d7..c0c11ab34 100644 --- a/src/NoteTrack.h +++ b/src/NoteTrack.h @@ -121,10 +121,10 @@ class AUDACITY_DLL_API NoteTrack final int GetBottomNote() const { return mBottomNote; } int GetPitchHeight() const { return mPitchHeight; } void SetPitchHeight(int h) { mPitchHeight = h; } - void ZoomOut(int y) { Zoom(y, -1); } - void ZoomIn(int y) { Zoom(y, 1); } - void Zoom(int centerY, int amount); - void ZoomTo(int start, int end); + void ZoomOut(const wxRect &rect, int y) { Zoom(rect, y, -1); } + void ZoomIn(const wxRect &rect, int y) { Zoom(rect, y, 1); } + void Zoom(const wxRect &rect, int centerY, int amount); + void ZoomTo(const wxRect &rect, int start, int end); int GetNoteMargin() const { return (mPitchHeight + 1) / 2; } int GetOctaveHeight() const { return mPitchHeight * 12 + 2; } // call this once before a series of calls to IPitchToY(). It diff --git a/src/Project.cpp b/src/Project.cpp index 48f60ff7c..d64dc623d 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -2009,7 +2009,8 @@ Track *AudacityProject::GetFirstVisible() for (Track *t = iter.First(); t; t = iter.Next()) { int y = t->GetY(); int h = t->GetHeight(); - if (y >= mViewInfo.vpos || y + h >= mViewInfo.vpos) { + if (y + h - 1 >= mViewInfo.vpos) { + // At least the bottom row of pixels is not scrolled away above mViewInfo.track = t; break; } @@ -2028,8 +2029,8 @@ void AudacityProject::UpdateFirstVisible() Track *t = mViewInfo.track; mViewInfo.track = NULL; - if (t->GetY() > mViewInfo.vpos) { - while (t && t->GetY() > mViewInfo.vpos) { + if (t->GetY() >= mViewInfo.vpos) { + while (t && t->GetY() >= mViewInfo.vpos) { t = mTracks->GetPrev(t); } } @@ -2037,7 +2038,8 @@ void AudacityProject::UpdateFirstVisible() while (t) { int y = t->GetY(); int h = t->GetHeight(); - if (y >= mViewInfo.vpos || y + h >= mViewInfo.vpos) { + if (y + h - 1 >= mViewInfo.vpos) { + // At least the bottom row of pixels is not scrolled away above mViewInfo.track = t; return; } diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 0239997e4..55669fdf9 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -4289,12 +4289,18 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event ) // which we then return if (mCapturedTrack->GetKind() == Track::Note) { NoteTrack *nt = (NoteTrack *) mCapturedTrack; + const wxRect rect{ + GetLeftOffset(), + mCapturedTrack->GetY() + kTopMargin, + GetSize().GetWidth() - GetLeftOffset(), + mCapturedTrack->GetHeight() - (kTopMargin + kBottomMargin) + }; if (IsDragZooming()) { - nt->ZoomTo(mZoomStart, mZoomEnd); + nt->ZoomTo(rect, mZoomStart, mZoomEnd); } else if (event.ShiftDown() || event.RightUp()) { - nt->ZoomOut(mZoomEnd); + nt->ZoomOut(rect, mZoomEnd); } else { - nt->ZoomIn(mZoomEnd); + nt->ZoomIn(rect, mZoomEnd); } mZoomEnd = mZoomStart = 0; Refresh(false); @@ -9611,6 +9617,7 @@ void TrackInfo::DrawVelocitySlider(wxDC *dc, NoteTrack *t, wxRect rect, bool cap LWSlider * TrackInfo::GainSlider(WaveTrack *t, bool captured) const { + // PRL: Add the inset, but why not also the border? wxRect rect(kLeftInset, t->GetY() - pParent->GetViewInfo()->vpos + kTopInset, 1, t->GetHeight()); wxRect sliderRect; GetGainRect(rect, sliderRect); @@ -9628,6 +9635,7 @@ LWSlider * TrackInfo::GainSlider(WaveTrack *t, bool captured) const LWSlider * TrackInfo::PanSlider(WaveTrack *t, bool captured) const { + // PRL: Add the inset, but why not also the border? wxRect rect(kLeftInset, t->GetY() - pParent->GetViewInfo()->vpos + kTopInset, 1, t->GetHeight()); wxRect sliderRect; GetPanRect(rect, sliderRect); @@ -9646,6 +9654,7 @@ LWSlider * TrackInfo::PanSlider(WaveTrack *t, bool captured) const #ifdef EXPERIMENTAL_MIDI_OUT LWSlider * TrackInfo::VelocitySlider(NoteTrack *t, bool captured) const { + // PRL: Add the inset, but why not also the border? wxRect rect(kLeftInset, t->GetY() - pParent->GetViewInfo()->vpos + kTopInset, 1, t->GetHeight()); wxRect sliderRect; GetVelocityRect(rect, sliderRect); diff --git a/src/tracks/ui/EditCursorOverlay.cpp b/src/tracks/ui/EditCursorOverlay.cpp index a9a1db32b..585c865f1 100644 --- a/src/tracks/ui/EditCursorOverlay.cpp +++ b/src/tracks/ui/EditCursorOverlay.cpp @@ -122,10 +122,11 @@ void EditCursorOverlay::Draw(OverlayPanel &panel, wxDC &dc) #ifdef EXPERIMENTAL_OUTPUT_DISPLAY if (MONO_WAVE_PAN(pTrack)){ - auto y = pTrack->GetY(true) - viewInfo.vpos + 1; - auto top = y + kTopInset; - auto bottom = y + pTrack->GetHeight(true) - kTopInset; - AColor::Line(dc, mLastCursorX, top, mLastCursorX, bottom); + auto y = pTrack->GetY(true) - viewInfo.vpos; + auto top = y + kTopMargin; + auto height = pTrack->GetHeight(true) - (kTopMargin + kBottomMargin); + // - 1 because AColor::Line is inclusive of endpoint + AColor::Line(dc, mLastCursorX, top, mLastCursorX, top + height - 1); } #endif