diff --git a/src/Printing.cpp b/src/Printing.cpp index 1c067e74a..5e41de77a 100644 --- a/src/Printing.cpp +++ b/src/Printing.cpp @@ -102,6 +102,9 @@ bool AudacityPrintout::OnPrintPage(int WXUNUSED(page)) r.x = 0; r.y = 0; r.width = width; + // Note that the views as printed might not have the same proportional + // heights as displayed on the screen, because the fixed-sized separators + // are counted in those heights but not printed auto trackHeight = (int)(view.GetHeight() * scale); r.height = trackHeight; diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 9d63172ca..8c71b9217 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -751,23 +751,30 @@ void TrackPanel::RefreshTrack(Track *trk, bool refreshbacking) if (!trk) return; + // Always move to the first channel of the group, and use only + // the sum of channel heights, not the height of any channel alone! trk = *GetTracks()->FindLeader(trk); auto &view = TrackView::Get( *trk ); auto height = - TrackList::Channels(trk).sum( TrackView::GetTrackHeight ) - - kTopInset - kShadowThickness; + TrackList::Channels(trk).sum( TrackView::GetTrackHeight ); - // subtract insets and shadows from the rectangle, but not border + // Set rectangle top according to the scrolling position, `vpos` + // Subtract the inset (above) and shadow (below) from the height of the + // rectangle, but not the border // This matters because some separators do paint over the border - wxRect rect(kLeftInset, - -mViewInfo->vpos + view.GetY() + kTopInset, - GetRect().GetWidth() - kLeftInset - kRightInset - kShadowThickness, - height); + const auto top = + -mViewInfo->vpos + view.GetCumulativeHeightBefore() + kTopInset; + height -= (kTopInset + kShadowThickness); + + // Width also subtracts insets (left and right) plus shadow (right) + const auto left = kLeftInset; + const auto width = GetRect().GetWidth() + - (kLeftInset + kRightInset + kShadowThickness); + + wxRect rect(left, top, width, height); if( refreshbacking ) - { mRefreshBacking = true; - } Refresh( false, &rect ); } diff --git a/src/tracks/ui/TrackView.cpp b/src/tracks/ui/TrackView.cpp index 13a024c08..627a364f5 100644 --- a/src/tracks/ui/TrackView.cpp +++ b/src/tracks/ui/TrackView.cpp @@ -41,7 +41,7 @@ int TrackView::GetCumulativeHeight( const Track *pTrack ) if ( !pTrack ) return 0; auto &view = Get( *pTrack ); - return view.GetY() + view.GetHeight(); + return view.GetCumulativeHeightBefore() + view.GetHeight(); } int TrackView::GetTotalHeight( const TrackList &list ) @@ -179,8 +179,10 @@ std::shared_ptr TrackView::DoGetAffordanceControls() namespace { -// Attach an object to each project. It receives track list events and updates -// track Y coordinates +/*! + Attached to each project, it receives track list events and maintains the + cache of cumulative track view heights for use by TrackPanel. + */ struct TrackPositioner final : ClientData::Base, wxEvtHandler { AudacityProject &mProject; @@ -214,7 +216,7 @@ struct TrackPositioner final : ClientData::Base, wxEvtHandler while( auto pTrack = *iter ) { auto &view = TrackView::Get( *pTrack ); - view.SetY( yy ); + view.SetCumulativeHeightBefore( yy ); yy += view.GetHeight(); ++iter; } diff --git a/src/tracks/ui/TrackView.h b/src/tracks/ui/TrackView.h index 7620d3b19..2e550ff8d 100644 --- a/src/tracks/ui/TrackView.h +++ b/src/tracks/ui/TrackView.h @@ -49,16 +49,24 @@ public: bool GetMinimized() const { return mMinimized; } void SetMinimized( bool minimized ); - int GetY() const { return mY; } + //! @return cached sum of `GetHeight()` of all preceding tracks + int GetCumulativeHeightBefore() const { return mY; } //! @return height of the track when expanded int GetExpandedHeight() const { return mHeight; } //! @return height of the track when collapsed virtual int GetMinimizedHeight() const = 0; + + //! @return height of the track as it now appears, expanded or collapsed + /*! + Total "height" of channels of a track includes padding areas above and + below it. + */ int GetHeight() const; - void SetY(int y) { DoSetY( y ); } + //! Set cached value dependent on position within the track list + void SetCumulativeHeightBefore(int y) { DoSetY( y ); } /*! Sets height for expanded state. Does not expand a track if it is now collapsed.