From f725e937a45c2f06a762141e51d3a5b5de4cca3f Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Wed, 19 Jul 2017 15:16:47 -0400 Subject: [PATCH] Still better redrawing of resized Note tracks, still not perfect... ... The uses of GetPitchHeight(1) should be reexamined --- src/NoteTrack.cpp | 9 ++++++--- src/NoteTrack.h | 13 +++++++------ src/TrackArtist.cpp | 12 ++++++------ 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/NoteTrack.cpp b/src/NoteTrack.cpp index 8e2d1052b..7b3eb4849 100644 --- a/src/NoteTrack.cpp +++ b/src/NoteTrack.cpp @@ -213,11 +213,14 @@ double NoteTrack::GetEndTime() const void NoteTrack::SetHeight(int h) { auto oldHeight = GetHeight(); + auto oldMargin = GetNoteMargin(oldHeight); Track::SetHeight(h); + auto margin = GetNoteMargin(h); Zoom( wxRect{ 0, 0, 1, h }, // only height matters - h - 1, // preserve bottom note - (float)h / std::max(1, oldHeight), + h - margin - 1, // preserve bottom note + (float)(h - 2 * margin) / + std::max(1, oldHeight - 2 * oldMargin), false ); } @@ -984,7 +987,7 @@ int NoteTrack::YToIPitch(int y) y -= octave * GetOctaveHeight(); // result is approximate because C and G are one pixel taller than // mPitchHeight. - return (y / GetPitchHeight()) + octave * 12; + return (y / GetPitchHeight(1)) + octave * 12; } const float NoteTrack::ZoomStep = powf( 2.0f, 0.25f ); diff --git a/src/NoteTrack.h b/src/NoteTrack.h index 090a71f14..74570196c 100644 --- a/src/NoteTrack.h +++ b/src/NoteTrack.h @@ -124,7 +124,8 @@ class AUDACITY_DLL_API NoteTrack final ( QuantizedTimeAndBeat t0, QuantizedTimeAndBeat t1, double newDur ); int GetBottomNote() const { return mBottomNote; } - int GetPitchHeight() const { return std::max(1, (int)mPitchHeight); } + int GetPitchHeight(int factor) const + { return std::max(1, (int)(factor * mPitchHeight)); } void SetPitchHeight(int rectHeight, float h) { // Impose certain zoom limits @@ -146,14 +147,14 @@ class AUDACITY_DLL_API NoteTrack final void Zoom(const wxRect &rect, int y, float multiplier, bool center); void ZoomTo(const wxRect &rect, int start, int end); int GetNoteMargin(int height) const - { return std::min(height / 4, (GetPitchHeight() + 1) / 2); } - int GetOctaveHeight() const { return GetPitchHeight() * 12 + 2; } + { return std::min(height / 4, (GetPitchHeight(1) + 1) / 2); } + int GetOctaveHeight() const { return GetPitchHeight(12) + 2; } // call this once before a series of calls to IPitchToY(). It // sets mBottom to offset of octave 0 so that mBottomNote // is located at r.y + r.height - (GetNoteMargin() + 1 + GetPitchHeight()) void PrepareIPitchToY(const wxRect &r) const { mBottom = - r.y + r.height - GetNoteMargin(r.height) - 1 - GetPitchHeight() + + r.y + r.height - GetNoteMargin(r.height) - 1 - GetPitchHeight(1) + (mBottomNote / 12) * GetOctaveHeight() + GetNotePos(mBottomNote % 12); } @@ -164,7 +165,7 @@ class AUDACITY_DLL_API NoteTrack final // compute the window coordinate of the bottom of an octave: This is // the bottom of the line separating B and C. int GetOctaveBottom(int oct) const { - return IPitchToY(oct * 12) + GetPitchHeight() + 1; + return IPitchToY(oct * 12) + GetPitchHeight(1) + 1; } // Y coordinate for given floating point pitch (rounded to int) int PitchToY(double p) const { @@ -176,7 +177,7 @@ class AUDACITY_DLL_API NoteTrack final // (the bottom of the black line between B and C) to the top of the // note. Note extra pixel separates B(11)/C(0) and E(4)/F(5). int GetNotePos(int p) const - { return 1 + GetPitchHeight() * (p + 1) + (p > 4); } + { return 1 + GetPitchHeight(p + 1) + (p > 4); } // get pixel offset to top of ith black key note int GetBlackPos(int i) const { return GetNotePos(i * 2 + 1 + (i > 1)); } // GetWhitePos tells where to draw lines between keys as an offset from diff --git a/src/TrackArtist.cpp b/src/TrackArtist.cpp index 7fa83a2ff..21803d34a 100644 --- a/src/TrackArtist.cpp +++ b/src/TrackArtist.cpp @@ -632,7 +632,7 @@ void TrackArtist::DrawVRuler rect.x + rect.width, obottom - pos); } wxRect br = rect; - br.height = track->GetPitchHeight(); + br.height = track->GetPitchHeight(1); br.x++; br.width = 17; for (int black = 0; black < 5; black++) { @@ -2825,7 +2825,7 @@ void TrackArtist::DrawNoteBackground(const NoteTrack *track, wxDC &dc, int obottom = track->GetOctaveBottom(octave); // eOffset is for the line between E and F; there's another line // between B and C, hence the offset of 2 for two line thicknesses - int eOffset = track->GetPitchHeight() * 5 + 2; + int eOffset = track->GetPitchHeight(5) + 2; while (obottom > rect.y + track->GetNoteMargin(rect.height) + 3) { // draw a black line separating octaves if this octave botton is visible if (obottom < rect.y + rect.height - track->GetNoteMargin(rect.height)) { @@ -2844,7 +2844,7 @@ void TrackArtist::DrawNoteBackground(const NoteTrack *track, wxDC &dc, wxRect br; br.x = left; br.width = right - left; - br.height = track->GetPitchHeight(); + br.height = track->GetPitchHeight(1); for (int black = 0; black < 5; black++) { br.y = obottom - track->GetBlackPos(black); if (br.y > rect.y && br.y + br.height < rect.y + rect.height) { @@ -2914,7 +2914,7 @@ void TrackArtist::DrawNoteTrack(const NoteTrack *track, // reserve 1/2 note height at top and bottom of track for // out-of-bounds notes - int numPitches = (rect.height) / track->GetPitchHeight(); + int numPitches = (rect.height) / track->GetPitchHeight(1); if (numPitches < 0) numPitches = 0; // cannot be negative // bottom is the hypothetical location of the bottom of pitch 0 relative to @@ -3017,7 +3017,7 @@ void TrackArtist::DrawNoteTrack(const NoteTrack *track, if (note->loud > 0.0 || 0 == (shape = IsShape(note))) { wxRect nr; // "note rectangle" nr.y = track->PitchToY(note->pitch); - nr.height = track->GetPitchHeight(); + nr.height = track->GetPitchHeight(1); nr.x = TIME_TO_X(xx); nr.width = TIME_TO_X(x1) - nr.x; @@ -3058,7 +3058,7 @@ void TrackArtist::DrawNoteTrack(const NoteTrack *track, else AColor::MIDIChannel(&dc, note->chan + 1); dc.DrawRectangle(nr); - if (track->GetPitchHeight() > 2) { + if (track->GetPitchHeight(1) > 2) { AColor::LightMIDIChannel(&dc, note->chan + 1); AColor::Line(dc, nr.x, nr.y, nr.x + nr.width-2, nr.y); AColor::Line(dc, nr.x, nr.y, nr.x, nr.y + nr.height-2);