mirror of
https://github.com/cookiengineer/audacity
synced 2025-08-16 08:34:10 +02:00
Bug2225: Don't duplicate display of track name when view is split
This commit is contained in:
commit
1c7fd66b6e
@ -66,6 +66,7 @@ is time to refresh some aspect of the screen.
|
|||||||
#include "UndoManager.h"
|
#include "UndoManager.h"
|
||||||
|
|
||||||
#include "AColor.h"
|
#include "AColor.h"
|
||||||
|
#include "AllThemeResources.h"
|
||||||
#include "AudioIO.h"
|
#include "AudioIO.h"
|
||||||
#include "float_cast.h"
|
#include "float_cast.h"
|
||||||
|
|
||||||
@ -1050,6 +1051,112 @@ void TrackPanel::VerticalScroll( float fracPosition){
|
|||||||
|
|
||||||
|
|
||||||
namespace {
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
@ -1079,8 +1186,10 @@ namespace {
|
|||||||
Fifthly, divide what remains into the vertically stacked channels, if there
|
Fifthly, divide what remains into the vertically stacked channels, if there
|
||||||
are more than one, alternating with separators, which can be clicked to
|
are more than one, alternating with separators, which can be clicked to
|
||||||
resize the channel views.
|
resize the channel views.
|
||||||
|
|
||||||
|
Sixthly, divide each channel into one or more vertically stacked sub-views.
|
||||||
|
|
||||||
Lastly, split the area for each channel into a vertical ruler, and an area
|
Lastly, split the area for each sub-view into a vertical ruler, and an area
|
||||||
that displays the channel's own contents.
|
that displays the channel's own contents.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
@ -1128,6 +1237,62 @@ struct VRulerAndChannel final : TrackPanelGroup {
|
|||||||
wxCoord mLeftOffset;
|
wxCoord mLeftOffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// One or more sub-views of one channel, stacked vertically, each contianing
|
||||||
|
// a vertical ruler and a channel
|
||||||
|
struct VRulersAndChannels final : TrackPanelGroup {
|
||||||
|
VRulersAndChannels(
|
||||||
|
const std::shared_ptr<Track> &pTrack,
|
||||||
|
TrackView::Refinement refinement, wxCoord leftOffset )
|
||||||
|
: mpTrack{ pTrack }
|
||||||
|
, mRefinement{ std::move( refinement ) }
|
||||||
|
, mLeftOffset{ leftOffset } {}
|
||||||
|
Subdivision Children( const wxRect &rect ) override
|
||||||
|
{
|
||||||
|
Refinement refinement;
|
||||||
|
auto y1 = rect.GetTop();
|
||||||
|
for ( const auto &subView : mRefinement ) {
|
||||||
|
y1 = std::max( y1, subView.first );
|
||||||
|
refinement.emplace_back( y1,
|
||||||
|
std::make_shared< VRulerAndChannel >(
|
||||||
|
subView.second, mLeftOffset ) );
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
// n channels with vertical rulers, alternating with n - 1 resizers;
|
// n channels with vertical rulers, alternating with n - 1 resizers;
|
||||||
// each channel-ruler pair might be divided into multiple views
|
// each channel-ruler pair might be divided into multiple views
|
||||||
struct ChannelGroup final : TrackPanelGroup {
|
struct ChannelGroup final : TrackPanelGroup {
|
||||||
@ -1146,14 +1311,11 @@ struct ChannelGroup final : TrackPanelGroup {
|
|||||||
auto height = view.GetHeight();
|
auto height = view.GetHeight();
|
||||||
rect.SetTop( yy );
|
rect.SetTop( yy );
|
||||||
rect.SetHeight( height - kSeparatorThickness );
|
rect.SetHeight( height - kSeparatorThickness );
|
||||||
const auto subViews = TrackView::Get( *channel ).GetSubViews( rect );
|
refinement.emplace_back( yy,
|
||||||
auto y1 = yy;
|
std::make_shared< VRulersAndChannels >(
|
||||||
for ( const auto &subView : subViews ) {
|
channel->shared_from_this(),
|
||||||
y1 = std::max( y1, subView.first );
|
TrackView::Get( *channel ).GetSubViews( rect ),
|
||||||
refinement.emplace_back( y1,
|
mLeftOffset ) );
|
||||||
std::make_shared< VRulerAndChannel >(
|
|
||||||
subView.second, mLeftOffset ) );
|
|
||||||
}
|
|
||||||
if ( channel != pLast ) {
|
if ( channel != pLast ) {
|
||||||
yy += height;
|
yy += height;
|
||||||
refinement.emplace_back(
|
refinement.emplace_back(
|
||||||
|
@ -16,7 +16,6 @@ Paul Licameli split from class TrackView
|
|||||||
#include "ZoomHandle.h"
|
#include "ZoomHandle.h"
|
||||||
#include "../ui/SelectHandle.h"
|
#include "../ui/SelectHandle.h"
|
||||||
#include "../../AColor.h"
|
#include "../../AColor.h"
|
||||||
#include "../../AllThemeResources.h"
|
|
||||||
#include "../../ProjectSettings.h"
|
#include "../../ProjectSettings.h"
|
||||||
#include "../../Track.h"
|
#include "../../Track.h"
|
||||||
#include "../../TrackArtist.h"
|
#include "../../TrackArtist.h"
|
||||||
@ -81,138 +80,6 @@ std::vector<UIHandlePtr> CommonTrackView::HitTest
|
|||||||
return results;
|
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()
|
std::shared_ptr<TrackPanelCell> CommonTrackView::ContextMenuDelegate()
|
||||||
{
|
{
|
||||||
return TrackControls::Get( *FindTrack() ).shared_from_this();
|
return TrackControls::Get( *FindTrack() ).shared_from_this();
|
||||||
|
@ -33,15 +33,6 @@ public:
|
|||||||
|
|
||||||
void TimeShiftHitTest();
|
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;
|
virtual int GetMinimizedHeight() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user