Skip to content

Commit

Permalink
Clip button backgrounds with rounded corners
Browse files Browse the repository at this point in the history
  • Loading branch information
paulmcauley committed Mar 30, 2021
1 parent a5b65e9 commit 1b42947
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 21 deletions.
12 changes: 9 additions & 3 deletions kdecoration/breezebutton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ namespace Breeze
if( d->internalSettings()->buttonHighlightStyle() == InternalSettings::EnumButtonHighlightStyle::HighlightSquare )
paintSquareBackground(painter);

// translate from offset -- this is the main offset that applies to all button geometries to space each button correctly
if( m_flag == FlagFirstInList ) painter->translate( m_offset );
// translate from offset
if( m_flag == FlagLeftmostAndAtEdge ) painter->translate( m_offset );
else painter->translate( 0, m_offset.y() );

const QRectF iconRect( geometry().topLeft(), m_iconSize );
Expand Down Expand Up @@ -181,7 +181,7 @@ namespace Breeze
paintSquareBackground(painter);

// translate from offset
if( m_flag == FlagFirstInList ) painter->translate( m_offset );
if( m_flag == FlagLeftmostAndAtEdge ) painter->translate( m_offset );
else painter->translate( 0, m_offset.y() );

/*
Expand Down Expand Up @@ -459,13 +459,19 @@ namespace Breeze
void Button::paintSquareBackground(QPainter* painter) const
{
auto d = qobject_cast<Decoration*>( decoration() );
auto s = d->settings();
QPainterPath* titlebarPath = d->titleBarPath();

if( m_backgroundColor.isValid() )
{
painter->save();
painter->setRenderHints( QPainter::Antialiasing );
painter->setBrush( m_backgroundColor );

//clip the rounded corners using the titlebar path
if( !d->isMaximized() && s->isAlphaChannelSupported() && (m_flag == FlagLeftmostNotAtEdge || m_flag == FlagRightmostNotAtEdge) )
painter->setClipPath(*titlebarPath, Qt::IntersectClip);

if( shouldDrawBackgroundStroke() )
{
QColor strokeColor = d->fontColor();
Expand Down
8 changes: 5 additions & 3 deletions kdecoration/breezebutton.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,18 @@ namespace Breeze
{
FlagNone,
FlagStandalone,
FlagFirstInList,
FlagLastInList,
FlagLeftmostNotAtEdge,
FlagLeftmostAndAtEdge,
FlagRightmostNotAtEdge,
FlagRightmostAndAtEdge,
};

//* flag
void setFlag( Flag value )
{ m_flag = value; }

//* standalone buttons
bool isStandAlone() const { return m_flag == FlagStandalone; }
bool isStandAlone() const { return ( m_flag == FlagStandalone || m_flag == FlagLeftmostNotAtEdge || m_flag == FlagRightmostNotAtEdge); }

//* offset
void setOffset( const QPointF& value )
Expand Down
36 changes: 21 additions & 15 deletions kdecoration/breezedecoration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -590,13 +590,15 @@ namespace Breeze
if( m_internalSettings->buttonHighlightStyle() == InternalSettings::EnumButtonHighlightStyle::HighlightSquare ) vPadding = 0;
else vPadding = isTopEdge() ? 0 : s->smallSpacing()*titleBarTopMargin;
const int hPadding = s->smallSpacing()*m_internalSettings->titlebarSideMargins();

auto firstButton = static_cast<Button*>( m_leftButtons->buttons().front().data() );
firstButton->setFlag( Button::FlagLeftmostNotAtEdge);
if( isLeftEdge() )
{
// add offsets on the side buttons, to preserve padding, but satisfy Fitts law
auto button = static_cast<Button*>( m_leftButtons->buttons().front().data() );
button->setGeometry( QRectF( QPoint( 0, 0 ), QSizeF( button->geometry().width() + hPadding, button->geometry().height() ) ) );
button->setHorizontalOffset( hPadding );
button->setFlag( Button::FlagFirstInList );
firstButton->setGeometry( QRectF( QPoint( 0, 0 ), QSizeF( firstButton->geometry().width() + hPadding, firstButton->geometry().height() ) ) );
firstButton->setHorizontalOffset( hPadding );
firstButton->setFlag( Button::FlagLeftmostAndAtEdge );

m_leftButtons->setPos(QPointF(0, vPadding));

Expand All @@ -619,12 +621,13 @@ namespace Breeze
if( m_internalSettings->buttonHighlightStyle() == InternalSettings::EnumButtonHighlightStyle::HighlightSquare ) vPadding = 0;
else vPadding = isTopEdge() ? 0 : s->smallSpacing()*titleBarTopMargin;
const int hPadding = s->smallSpacing()*m_internalSettings->titlebarSideMargins();

auto lastButton = static_cast<Button*>( m_rightButtons->buttons().back().data() );
lastButton->setFlag( Button::FlagRightmostNotAtEdge );
if( isRightEdge() )
{

auto button = static_cast<Button*>( m_rightButtons->buttons().back().data() );
button->setGeometry( QRectF( QPoint( 0, 0 ), QSizeF( button->geometry().width() + hPadding, button->geometry().height() ) ) );
button->setFlag( Button::FlagLastInList );
lastButton->setGeometry( QRectF( QPoint( 0, 0 ), QSizeF( lastButton->geometry().width() + hPadding, lastButton->geometry().height() ) ) );
lastButton->setFlag( Button::FlagRightmostAndAtEdge );

m_rightButtons->setPos(QPointF(size().width() - m_rightButtons->geometry().width(), vPadding));

Expand Down Expand Up @@ -718,26 +721,29 @@ namespace Breeze

auto s = settings();
double cornerRadiusScaled = m_internalSettings->cornerRadius()*s->smallSpacing();

m_titleBarPath.clear(); //clear the path for subsequent calls to this function
if( isMaximized() || !s->isAlphaChannelSupported() )
{

painter->drawRect(titleRect);
m_titleBarPath.addRect(titleRect);
painter->drawPath(m_titleBarPath);

} else if( c->isShaded() ) {

painter->drawRoundedRect(titleRect, cornerRadiusScaled, cornerRadiusScaled);
m_titleBarPath.addRoundedRect(titleRect, cornerRadiusScaled, cornerRadiusScaled);
painter->drawPath(m_titleBarPath);

} else {

painter->setClipRect(titleRect, Qt::IntersectClip);

// the rect is made a little bit larger to be able to clip away the rounded corners at the bottom and sides
painter->drawRoundedRect(titleRect.adjusted(
m_titleBarPath.addRoundedRect(titleRect.adjusted(
isLeftEdge() ? -cornerRadiusScaled:0,
isTopEdge() ? -cornerRadiusScaled:0,
isRightEdge() ? cornerRadiusScaled:0,
cornerRadiusScaled),
cornerRadiusScaled, cornerRadiusScaled);

painter->drawPath(m_titleBarPath);

}

Expand Down
5 changes: 5 additions & 0 deletions kdecoration/breezedecoration.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <QPalette>
#include <QVariant>
#include <QVariantAnimation>
#include <QPainterPath>

class QVariantAnimation;

Expand Down Expand Up @@ -87,6 +88,8 @@ namespace Breeze

inline bool hideTitleBar() const;
//@}

QPainterPath* titleBarPath(){return &m_titleBarPath;}

public Q_SLOTS:
void init() override;
Expand Down Expand Up @@ -147,6 +150,8 @@ namespace Breeze
//*tilebar main state opacity
int m_titleBarOpacityActive = 255;
int m_titleBarOpacityInactive = 255;

QPainterPath m_titleBarPath;

};

Expand Down

0 comments on commit 1b42947

Please sign in to comment.