From c88256499490e7ca57ae079546fc8fc0be88fc60 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Sun, 29 Dec 2019 15:24:12 -0500 Subject: [PATCH] Move drawing of TrackName from the subview to VRulersAndChannels... ... And thus do it only once per channel (i.e. once per set of sub-views) --- src/TrackPanel.cpp | 143 +++++++++++++++++++++++++++++- src/tracks/ui/CommonTrackView.cpp | 133 --------------------------- src/tracks/ui/CommonTrackView.h | 9 -- 3 files changed, 142 insertions(+), 143 deletions(-) diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index c1ab75d6f..45be61163 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -66,6 +66,7 @@ is time to refresh some aspect of the screen. #include "UndoManager.h" #include "AColor.h" +#include "AllThemeResources.h" #include "AudioIO.h" #include "float_cast.h" @@ -1050,6 +1051,112 @@ void TrackPanel::VerticalScroll( float fracPosition){ namespace { + // Drawing constants + // DisplaceX and MarginX are large enough to avoid overwriting <- symbol + // See TrackArt::DrawNegativeOffsetTrackArrows + enum : int { + // Displacement of the rectangle from upper left corner + DisplaceX = 7, DisplaceY = 1, + // Size of margins about the text extent that determine the rectangle size + MarginX = 8, MarginY = 2, + // Derived constants + MarginsX = 2 * MarginX, MarginsY = 2 * MarginY, + }; + +void GetTrackNameExtent( + wxDC &dc, const Track *t, wxCoord *pW, wxCoord *pH ) +{ + wxFont labelFont(12, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL); + dc.SetFont(labelFont); + dc.GetTextExtent( t->GetName(), pW, pH ); +} + +wxRect GetTrackNameRect( + int leftOffset, + const wxRect &trackRect, wxCoord textWidth, wxCoord textHeight ) +{ + return { + leftOffset + DisplaceX, + trackRect.y + DisplaceY, + textWidth + MarginsX, + textHeight + MarginsY + }; +} + +// Draws the track name on the track, if it is needed. +void DrawTrackName( + int leftOffset, + TrackPanelDrawingContext &context, const Track * t, const wxRect & rect ) +{ + if( !TrackArtist::Get( context )->mbShowTrackNameInTrack ) + return; + auto name = t->GetName(); + if( name.IsEmpty()) + return; + if( !t->IsLeader()) + return; + auto &dc = context.dc; + wxBrush Brush; + wxCoord textWidth, textHeight; + GetTrackNameExtent( dc, t, &textWidth, &textHeight ); + + // Logic for name background translucency (aka 'shields') + // Tracks less than kOpaqueHeight high will have opaque shields. + // Tracks more than kTranslucentHeight will have maximum translucency for shields. + const int kOpaqueHeight = 44; + const int kTranslucentHeight = 124; + int h = rect.GetHeight(); + // f codes the opacity as a number between 0.0 and 1.0 + float f = wxClip((h-kOpaqueHeight)/(float)(kTranslucentHeight-kOpaqueHeight),0.0,1.0); + // kOpaque is the shield's alpha for tracks that are not tall + // kTranslucent is the shield's alpha for tracks that are tall. + const int kOpaque = 255; + const int kTranslucent = 140; + // 0.0 maps to full opacity, 1.0 maps to full translucency. + int opacity = 255 - (255-140)*f; + + const auto nameRect = + GetTrackNameRect( leftOffset, rect, textWidth, textHeight ); + +#ifdef __WXMAC__ + // Mac dc is a graphics dc already. + AColor::UseThemeColour( &dc, clrTrackInfoSelected, clrTrackPanelText, opacity ); + dc.DrawRoundedRectangle( nameRect, 8.0 ); +#else + // This little dance with wxImage in order to draw to a graphic dc + // which we can then paste as a translucent bitmap onto the real dc. + enum : int { + SecondMarginX = 1, SecondMarginY = 1, + SecondMarginsX = 2 * SecondMarginX, SecondMarginsY = 2 * SecondMarginY, + }; + wxImage image( + textWidth + MarginsX + SecondMarginsX, + textHeight + MarginsY + SecondMarginsY ); + image.InitAlpha(); + unsigned char *alpha=image.GetAlpha(); + memset(alpha, wxIMAGE_ALPHA_TRANSPARENT, image.GetWidth()*image.GetHeight()); + + { + std::unique_ptr< wxGraphicsContext > + pGc{ wxGraphicsContext::Create(image) }; + auto &gc = *pGc; + // This is to a gc, not a dc. + AColor::UseThemeColour( &gc, clrTrackInfoSelected, clrTrackPanelText, opacity ); + // Draw at 1,1, not at 0,0 to avoid clipping of the antialiasing. + gc.DrawRoundedRectangle( + SecondMarginX, SecondMarginY, + textWidth + MarginsX, textHeight + MarginsY, 8.0 ); + // destructor of gc updates the wxImage. + } + wxBitmap bitmap( image ); + dc.DrawBitmap( bitmap, + nameRect.x - SecondMarginX, nameRect.y - SecondMarginY ); +#endif + dc.SetTextForeground(theTheme.Colour( clrTrackPanelText )); + dc.DrawText(t->GetName(), + nameRect.x + MarginX, + nameRect.y + MarginY); +} /* @@ -1134,8 +1241,10 @@ struct VRulerAndChannel final : TrackPanelGroup { // a vertical ruler and a channel struct VRulersAndChannels final : TrackPanelGroup { VRulersAndChannels( + const std::shared_ptr &pTrack, TrackView::Refinement refinement, wxCoord leftOffset ) - : mRefinement{ std::move( refinement ) } + : mpTrack{ pTrack } + , mRefinement{ std::move( refinement ) } , mLeftOffset{ leftOffset } {} Subdivision Children( const wxRect &rect ) override { @@ -1149,6 +1258,37 @@ struct VRulersAndChannels final : TrackPanelGroup { } return { Axis::Y, std::move( refinement ) }; } + + // TrackPanelDrawable implementation + void Draw( + TrackPanelDrawingContext &context, + const wxRect &rect, unsigned iPass ) override + { + // This overpaints the track area, but sometimes too the stereo channel + // separator, so draw at least later than that + if ( iPass == TrackArtist::PassBorders ) + DrawTrackName( mLeftOffset, + context, mpTrack->SubstitutePendingChangedTrack().get(), rect ); + } + + wxRect DrawingArea( + TrackPanelDrawingContext &context, + const wxRect &rect, const wxRect &panelRect, unsigned iPass ) override + { + auto result = rect; + if ( iPass == TrackArtist::PassBorders ) { + if ( true ) { + wxCoord textWidth, textHeight; + GetTrackNameExtent( context.dc, mpTrack.get(), + &textWidth, &textHeight ); + result = + GetTrackNameRect( mLeftOffset, rect, textWidth, textHeight ); + } + } + return result; + } + + std::shared_ptr< Track > mpTrack; TrackView::Refinement mRefinement; wxCoord mLeftOffset; }; @@ -1173,6 +1313,7 @@ struct ChannelGroup final : TrackPanelGroup { rect.SetHeight( height - kSeparatorThickness ); refinement.emplace_back( yy, std::make_shared< VRulersAndChannels >( + channel->shared_from_this(), TrackView::Get( *channel ).GetSubViews( rect ), mLeftOffset ) ); if ( channel != pLast ) { diff --git a/src/tracks/ui/CommonTrackView.cpp b/src/tracks/ui/CommonTrackView.cpp index 0044db76d..f01cb30ef 100644 --- a/src/tracks/ui/CommonTrackView.cpp +++ b/src/tracks/ui/CommonTrackView.cpp @@ -16,7 +16,6 @@ Paul Licameli split from class TrackView #include "ZoomHandle.h" #include "../ui/SelectHandle.h" #include "../../AColor.h" -#include "../../AllThemeResources.h" #include "../../ProjectSettings.h" #include "../../Track.h" #include "../../TrackArtist.h" @@ -81,138 +80,6 @@ std::vector CommonTrackView::HitTest return results; } -namespace { - // Drawing constants - // DisplaceX and MarginX are large enough to avoid overwriting <- symbol - // See TrackArt::DrawNegativeOffsetTrackArrows - enum : int { - // Displacement of the rectangle from upper left corner - DisplaceX = 7, DisplaceY = 1, - // Size of margins about the text extent that determine the rectangle size - MarginX = 8, MarginY = 2, - // Derived constants - MarginsX = 2 * MarginX, MarginsY = 2 * MarginY, - }; -} - -static void GetTrackNameExtent( - wxDC &dc, const Track *t, wxCoord *pW, wxCoord *pH ) -{ - wxFont labelFont(12, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL); - dc.SetFont(labelFont); - dc.GetTextExtent( t->GetName(), pW, pH ); -} - -static wxRect GetTrackNameRect( - const wxRect &trackRect, wxCoord textWidth, wxCoord textHeight ) -{ - return { - trackRect.x + DisplaceX, - trackRect.y + DisplaceY, - textWidth + MarginsX, - textHeight + MarginsY - }; -} - -// Draws the track name on the track, if it is needed. -static void DrawTrackName( - TrackPanelDrawingContext &context, const Track * t, const wxRect & rect ) -{ - if( !TrackArtist::Get( context )->mbShowTrackNameInTrack ) - return; - auto name = t->GetName(); - if( name.IsEmpty()) - return; - if( !t->IsLeader()) - return; - auto &dc = context.dc; - wxBrush Brush; - wxCoord textWidth, textHeight; - GetTrackNameExtent( dc, t, &textWidth, &textHeight ); - - // Logic for name background translucency (aka 'shields') - // Tracks less than kOpaqueHeight high will have opaque shields. - // Tracks more than kTranslucentHeight will have maximum translucency for shields. - const int kOpaqueHeight = 44; - const int kTranslucentHeight = 124; - int h = rect.GetHeight(); - // f codes the opacity as a number between 0.0 and 1.0 - float f = wxClip((h-kOpaqueHeight)/(float)(kTranslucentHeight-kOpaqueHeight),0.0,1.0); - // kOpaque is the shield's alpha for tracks that are not tall - // kTranslucent is the shield's alpha for tracks that are tall. - const int kOpaque = 255; - const int kTranslucent = 140; - // 0.0 maps to full opacity, 1.0 maps to full translucency. - int opacity = 255 - (255-140)*f; - - const auto nameRect = GetTrackNameRect( rect, textWidth, textHeight ); - -#ifdef __WXMAC__ - // Mac dc is a graphics dc already. - AColor::UseThemeColour( &dc, clrTrackInfoSelected, clrTrackPanelText, opacity ); - dc.DrawRoundedRectangle( nameRect, 8.0 ); -#else - // This little dance with wxImage in order to draw to a graphic dc - // which we can then paste as a translucent bitmap onto the real dc. - enum : int { - SecondMarginX = 1, SecondMarginY = 1, - SecondMarginsX = 2 * SecondMarginX, SecondMarginsY = 2 * SecondMarginY, - }; - wxImage image( - textWidth + MarginsX + SecondMarginsX, - textHeight + MarginsY + SecondMarginsY ); - image.InitAlpha(); - unsigned char *alpha=image.GetAlpha(); - memset(alpha, wxIMAGE_ALPHA_TRANSPARENT, image.GetWidth()*image.GetHeight()); - - { - std::unique_ptr< wxGraphicsContext > - pGc{ wxGraphicsContext::Create(image) }; - auto &gc = *pGc; - // This is to a gc, not a dc. - AColor::UseThemeColour( &gc, clrTrackInfoSelected, clrTrackPanelText, opacity ); - // Draw at 1,1, not at 0,0 to avoid clipping of the antialiasing. - gc.DrawRoundedRectangle( - SecondMarginX, SecondMarginY, - textWidth + MarginsX, textHeight + MarginsY, 8.0 ); - // destructor of gc updates the wxImage. - } - wxBitmap bitmap( image ); - dc.DrawBitmap( bitmap, - nameRect.x - SecondMarginX, nameRect.y - SecondMarginY ); -#endif - dc.SetTextForeground(theTheme.Colour( clrTrackPanelText )); - dc.DrawText(t->GetName(), - nameRect.x + MarginX, - nameRect.y + MarginY); -} - -wxRect CommonTrackView::DrawingArea( - TrackPanelDrawingContext &context, - const wxRect &rect, const wxRect &panelRect, unsigned iPass ) -{ - auto result = rect; - if ( iPass == TrackArtist::PassBorders ) { - if ( true ) { - wxCoord textWidth, textHeight; - GetTrackNameExtent( context.dc, FindTrack().get(), - &textWidth, &textHeight ); - result = GetTrackNameRect( rect, textWidth, textHeight ); - } - } - return rect; -} - -void CommonTrackView::Draw( - TrackPanelDrawingContext &context, const wxRect &rect, unsigned iPass ) -{ - // This overpaints the track area, but sometimes too the stereo channel - // separator, so draw at least later than that - if ( iPass == TrackArtist::PassBorders ) - DrawTrackName( - context, FindTrack()->SubstitutePendingChangedTrack().get(), rect ); -} - std::shared_ptr CommonTrackView::ContextMenuDelegate() { return TrackControls::Get( *FindTrack() ).shared_from_this(); diff --git a/src/tracks/ui/CommonTrackView.h b/src/tracks/ui/CommonTrackView.h index ace7a4d18..f7c0e483a 100644 --- a/src/tracks/ui/CommonTrackView.h +++ b/src/tracks/ui/CommonTrackView.h @@ -33,15 +33,6 @@ public: void TimeShiftHitTest(); - // TrackPanelDrawable implementation - wxRect DrawingArea( - TrackPanelDrawingContext &context, - const wxRect &rect, const wxRect &panelRect, unsigned iPass ) override; - - void Draw( - TrackPanelDrawingContext &context, - const wxRect &rect, unsigned iPass ) override; - virtual int GetMinimizedHeight() const override; protected: