1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-22 15:20:15 +02:00

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)
This commit is contained in:
Paul Licameli 2019-12-29 15:24:12 -05:00
parent 4b2f78fd0d
commit c882564994
3 changed files with 142 additions and 143 deletions

View File

@ -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<Track> &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 ) {

View File

@ -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<UIHandlePtr> 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<TrackPanelCell> CommonTrackView::ContextMenuDelegate()
{
return TrackControls::Get( *FindTrack() ).shared_from_this();

View File

@ -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: