You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

1644 lines
57 KiB

/*
* SPDX-FileCopyrightText: 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "breezehelper.h"
#include "breeze.h"
#include "breezestyleconfigdata.h"
#include <KColorUtils>
#include <KIconLoader>
#include <KWindowSystem>
#include <QApplication>
#include <QDBusConnection>
#include <QFileInfo>
#include <QPainter>
#include <QMainWindow>
#include <QMenuBar>
#include <QMdiArea>
#include <QDockWidget>
#include <QWindow>
#if BREEZE_HAVE_QTX11EXTRAS
#include <QX11Info>
#endif
#include <algorithm>
#include <QDialog>
namespace Breeze
{
//* contrast for arrow and treeline rendering
static const qreal arrowShade = 0.15;
static const auto radioCheckSunkenDarkeningFactor = 110;
//____________________________________________________________________
Helper::Helper( KSharedConfig::Ptr config, QObject *parent ) :
QObject ( parent ),
_config( std::move( config ) ),
_kwinConfig( KSharedConfig::openConfig("kwinrc") ),
_decorationConfig( new InternalSettings() )
{
if (qApp) {
connect(qApp, &QApplication::paletteChanged, this, [=]() {
if (qApp->property("KDE_COLOR_SCHEME_PATH").isValid()) {
const auto path = qApp->property("KDE_COLOR_SCHEME_PATH").toString();
KConfig config(path, KConfig::SimpleConfig);
KConfigGroup group( config.group("WM") );
const QPalette palette( QApplication::palette() );
_activeTitleBarColor = group.readEntry( "activeBackground", palette.color( QPalette::Active, QPalette::Highlight ) );
_activeTitleBarTextColor = group.readEntry( "activeForeground", palette.color( QPalette::Active, QPalette::HighlightedText ) );
_inactiveTitleBarColor = group.readEntry( "inactiveBackground", palette.color( QPalette::Disabled, QPalette::Highlight ) );
_inactiveTitleBarTextColor = group.readEntry( "inactiveForeground", palette.color( QPalette::Disabled, QPalette::HighlightedText ) );
}
});
}
}
//____________________________________________________________________
KSharedConfig::Ptr Helper::config() const
{ return _config; }
//____________________________________________________________________
QSharedPointer<InternalSettings> Helper::decorationConfig() const
{ return _decorationConfig; }
//____________________________________________________________________
void Helper::loadConfig()
{
_viewFocusBrush = KStatefulBrush( KColorScheme::View, KColorScheme::FocusColor );
_viewHoverBrush = KStatefulBrush( KColorScheme::View, KColorScheme::HoverColor );
_buttonFocusBrush = KStatefulBrush( KColorScheme::Button, KColorScheme::FocusColor );
_buttonHoverBrush = KStatefulBrush( KColorScheme::Button, KColorScheme::HoverColor );
_viewNegativeTextBrush = KStatefulBrush( KColorScheme::View, KColorScheme::NegativeText );
_viewNeutralTextBrush = KStatefulBrush( KColorScheme::View, KColorScheme::NeutralText );
const QPalette palette( QApplication::palette() );
_config->reparseConfiguration();
_kwinConfig->reparseConfiguration();
_cachedAutoValid = false;
_decorationConfig->load();
KConfig config(qApp->property("KDE_COLOR_SCHEME_PATH").toString(), KConfig::SimpleConfig);
KConfigGroup appGroup( config.group("WM") );
KConfigGroup globalGroup( _config->group("WM") );
_activeTitleBarColor = appGroup.readEntry( "activeBackground", globalGroup.readEntry( "activeBackground", palette.color( QPalette::Active, QPalette::Highlight ) ) );
_activeTitleBarTextColor = appGroup.readEntry( "activeForeground", globalGroup.readEntry( "activeForeground", palette.color( QPalette::Active, QPalette::HighlightedText ) ) );
_inactiveTitleBarColor = appGroup.readEntry( "inactiveBackground", globalGroup.readEntry( "inactiveBackground", palette.color( QPalette::Disabled, QPalette::Highlight ) ) );
_inactiveTitleBarTextColor = appGroup.readEntry( "inactiveForeground", globalGroup.readEntry( "inactiveForeground", palette.color( QPalette::Disabled, QPalette::HighlightedText ) ) );
}
QColor transparentize(const QColor& color, qreal amount)
{
auto clone = color;
clone.setAlphaF(amount);
return clone;
}
//____________________________________________________________________
QColor Helper::frameOutlineColor( const QPalette& palette, bool mouseOver, bool hasFocus, qreal opacity, AnimationMode mode ) const
{
QColor outline( KColorUtils::mix( palette.color( QPalette::Window ), palette.color( QPalette::WindowText ), 0.25 ) );
// focus takes precedence over hover
if( mode == AnimationFocus )
{
const QColor focus( focusColor( palette ) );
const QColor hover( hoverColor( palette ) );
if( mouseOver ) outline = KColorUtils::mix( hover, focus, opacity );
else outline = KColorUtils::mix( outline, focus, opacity );
} else if( hasFocus ) {
outline = focusColor( palette );
} else if( mode == AnimationHover ) {
const QColor hover( hoverColor( palette ) );
outline = KColorUtils::mix( outline, hover, opacity );
} else if( mouseOver ) {
outline = hoverColor( palette );
}
return outline;
}
//____________________________________________________________________
QColor Helper::focusOutlineColor( const QPalette& palette ) const
{ return KColorUtils::mix( focusColor( palette ), palette.color( QPalette::WindowText ), 0.15 ); }
//____________________________________________________________________
QColor Helper::hoverOutlineColor( const QPalette& palette ) const
{ return KColorUtils::mix( hoverColor( palette ), palette.color( QPalette::WindowText ), 0.15 ); }
//____________________________________________________________________
QColor Helper::buttonFocusOutlineColor( const QPalette& palette ) const
{ return KColorUtils::mix( buttonFocusColor( palette ), palette.color( QPalette::ButtonText ), 0.15 ); }
//____________________________________________________________________
QColor Helper::buttonHoverOutlineColor( const QPalette& palette ) const
{ return KColorUtils::mix( buttonHoverColor( palette ), palette.color( QPalette::ButtonText ), 0.15 ); }
//____________________________________________________________________
QColor Helper::sidePanelOutlineColor( const QPalette& palette, bool hasFocus, qreal opacity, AnimationMode mode ) const
{
QColor outline( palette.color( QPalette::Inactive, QPalette::Highlight ) );
const QColor &focus = palette.color( QPalette::Active, QPalette::Highlight );
if( mode == AnimationFocus )
{
outline = KColorUtils::mix( outline, focus, opacity );
} else if( hasFocus ) {
outline = focus;
}
return outline;
}
//____________________________________________________________________
QColor Helper::frameBackgroundColor( const QPalette& palette, QPalette::ColorGroup group ) const
{ return KColorUtils::mix( palette.color( group, QPalette::Window ), palette.color( group, QPalette::Base ), 0.3 ); }
//____________________________________________________________________
QColor Helper::arrowColor( const QPalette& palette, QPalette::ColorGroup group, QPalette::ColorRole role ) const
{
switch( role )
{
case QPalette::Text: return KColorUtils::mix( palette.color( group, QPalette::Text ), palette.color( group, QPalette::Base ), arrowShade );
case QPalette::WindowText: return KColorUtils::mix( palette.color( group, QPalette::WindowText ), palette.color( group, QPalette::Window ), arrowShade );
case QPalette::ButtonText: return KColorUtils::mix( palette.color( group, QPalette::ButtonText ), palette.color( group, QPalette::Button ), arrowShade );
default: return palette.color( group, role );
}
}
//____________________________________________________________________
QColor Helper::arrowColor( const QPalette& palette, bool mouseOver, bool hasFocus, qreal opacity, AnimationMode mode ) const
{
QColor outline( arrowColor( palette, QPalette::WindowText ) );
if( mode == AnimationHover )
{
const QColor focus( focusColor( palette ) );
const QColor hover( hoverColor( palette ) );
if( hasFocus ) outline = KColorUtils::mix( focus, hover, opacity );
else outline = KColorUtils::mix( outline, hover, opacity );
} else if( mouseOver ) {
outline = hoverColor( palette );
} else if( mode == AnimationFocus ) {
const QColor focus( focusColor( palette ) );
outline = KColorUtils::mix( outline, focus, opacity );
} else if( hasFocus ) {
outline = focusColor( palette );
}
return outline;
}
//____________________________________________________________________
QColor Helper::sliderOutlineColor( const QPalette& palette, bool mouseOver, bool hasFocus, qreal opacity, AnimationMode mode ) const
{
QColor outline( KColorUtils::mix( palette.color( QPalette::Window ), palette.color( QPalette::WindowText ), 0.4 ) );
// hover takes precedence over focus
if( mode == AnimationHover )
{
const QColor hover( hoverColor( palette ) );
const QColor focus( focusColor( palette ) );
if( hasFocus ) outline = KColorUtils::mix( focus, hover, opacity );
else outline = KColorUtils::mix( outline, hover, opacity );
} else if( mouseOver ) {
outline = hoverColor( palette );
} else if( mode == AnimationFocus ) {
const QColor focus( focusColor( palette ) );
outline = KColorUtils::mix( outline, focus, opacity );
} else if( hasFocus ) {
outline = focusColor( palette );
}
return outline;
}
//____________________________________________________________________
QColor Helper::scrollBarHandleColor( const QPalette& palette, bool mouseOver, bool hasFocus, qreal opacity, AnimationMode mode ) const
{
QColor color( alphaColor( palette.color( QPalette::WindowText ), 0.5 ) );
// hover takes precedence over focus
if( mode == AnimationHover )
{
const QColor hover( hoverColor( palette ) );
const QColor focus( focusColor( palette ) );
if( hasFocus ) color = KColorUtils::mix( focus, hover, opacity );
else color = KColorUtils::mix( color, hover, opacity );
} else if( mouseOver ) {
color = hoverColor( palette );
} else if( mode == AnimationFocus ) {
const QColor focus( focusColor( palette ) );
color = KColorUtils::mix( color, focus, opacity );
} else if( hasFocus ) {
color = focusColor( palette );
}
return color;
}
//______________________________________________________________________________
QColor Helper::checkBoxIndicatorColor( const QPalette& palette, bool mouseOver, bool active, qreal opacity, AnimationMode mode ) const
{
QColor color( KColorUtils::mix( palette.color( QPalette::Window ), palette.color( QPalette::WindowText ), 0.6 ) );
if( mode == AnimationHover )
{
const QColor focus( focusColor( palette ) );
const QColor hover( hoverColor( palette ) );
if( active ) color = KColorUtils::mix( focus, hover, opacity );
else color = KColorUtils::mix( color, hover, opacity );
} else if( mouseOver ) {
color = hoverColor( palette );
} else if( active ) {
color = focusColor( palette );
}
return color;
}
//______________________________________________________________________________
QColor Helper::separatorColor( const QPalette& palette ) const
{ return KColorUtils::mix( palette.color( QPalette::Window ), palette.color( QPalette::WindowText ), 0.25 ); }
//______________________________________________________________________________
QPalette Helper::disabledPalette( const QPalette& source, qreal ratio ) const
{
QPalette copy( source );
const QList<QPalette::ColorRole> roles = { QPalette::Background, QPalette::Highlight, QPalette::WindowText, QPalette::ButtonText, QPalette::Text, QPalette::Button };
foreach( const QPalette::ColorRole& role, roles )
{ copy.setColor( role, KColorUtils::mix( source.color( QPalette::Active, role ), source.color( QPalette::Disabled, role ), 1.0-ratio ) ); }
return copy;
}
//____________________________________________________________________
QColor Helper::alphaColor( QColor color, qreal alpha ) const
{
if( alpha >= 0 && alpha < 1.0 )
{ color.setAlphaF( alpha*color.alphaF() ); }
return color;
}
//______________________________________________________________________________
void Helper::renderDebugFrame( QPainter* painter, const QRect& rect ) const
{
painter->save();
painter->setRenderHints( QPainter::Antialiasing );
painter->setBrush( Qt::NoBrush );
painter->setPen( Qt::red );
painter->drawRect( strokedRect( rect ) );
painter->restore();
}
//______________________________________________________________________________
void Helper::renderFocusRect( QPainter* painter, const QRect& rect, const QColor& color, const QColor& outline, Sides sides ) const
{
if( !color.isValid() ) return;
painter->save();
painter->setRenderHints( QPainter::Antialiasing );
painter->setBrush( color );
if( !( outline.isValid() && sides ) )
{
painter->setPen( Qt::NoPen );
painter->drawRect( rect );
} else {
painter->setClipRect( rect );
QRectF copy( strokedRect( rect ) );
const qreal radius( frameRadius( PenWidth::Frame ) );
if( !(sides&SideTop) ) copy.adjust( 0, -radius, 0, 0 );
if( !(sides&SideBottom) ) copy.adjust( 0, 0, 0, radius );
if( !(sides&SideLeft) ) copy.adjust( -radius, 0, 0, 0 );
if( !(sides&SideRight) ) copy.adjust( 0, 0, radius, 0 );
painter->setPen( outline );
// painter->setBrush( Qt::NoBrush );
painter->drawRoundedRect( copy, radius, radius );
}
painter->restore();
}
//______________________________________________________________________________
void Helper::renderFocusLine( QPainter* painter, const QRect& rect, const QColor& color ) const
{
if( !color.isValid() ) return;
painter->save();
painter->setRenderHint( QPainter::Antialiasing, false );
painter->setBrush( Qt::NoBrush );
painter->setPen( color );
painter->translate( 0, 2 );
painter->drawLine( rect.bottomLeft(), rect.bottomRight() );
painter->restore();
}
//______________________________________________________________________________
void Helper::renderFrame(
QPainter* painter, const QRect& rect,
const QColor& color, const QColor& outline ) const
{
painter->setRenderHint( QPainter::Antialiasing );
QRectF frameRect( rect.adjusted( 1, 1, -1, -1 ) );
qreal radius( frameRadius( PenWidth::NoPen ) );
// set pen
if( outline.isValid() )
{
painter->setPen( outline );
frameRect = strokedRect( frameRect );
radius = frameRadiusForNewPenWidth( radius, PenWidth::Frame );
} else {
painter->setPen( Qt::NoPen );
}
// set brush
if( color.isValid() ) painter->setBrush( color );
else painter->setBrush( Qt::NoBrush );
// render
painter->drawRoundedRect( frameRect, radius, radius );
}
//______________________________________________________________________________
void Helper::renderSidePanelFrame( QPainter* painter, const QRect& rect, const QColor& outline, Side side ) const
{
// check color
if( !outline.isValid() ) return;
// adjust rect
QRectF frameRect( strokedRect( rect ) );
// setup painter
painter->setRenderHint( QPainter::Antialiasing );
painter->setPen( outline );
// render
switch( side )
{
default:
case SideLeft:
painter->drawLine( frameRect.topRight(), frameRect.bottomRight() );
break;
case SideTop:
painter->drawLine( frameRect.topLeft(), frameRect.topRight() );
break;
case SideRight:
painter->drawLine( frameRect.topLeft(), frameRect.bottomLeft() );
break;
case SideBottom:
painter->drawLine( frameRect.bottomLeft(), frameRect.bottomRight() );
break;
case AllSides:
{
const qreal radius( frameRadius( PenWidth::Frame ) );
painter->drawRoundedRect( frameRect, radius, radius );
break;
}
}
}
//______________________________________________________________________________
void Helper::renderMenuFrame(
QPainter* painter, const QRect& rect,
const QColor& color, const QColor& outline, bool roundCorners, bool isTopMenu ) const
{
painter->save();
// set brush
if( color.isValid() ) painter->setBrush( color );
else painter->setBrush( Qt::NoBrush );
// We simulate being able to independently adjust corner radii by
// setting a clip region and then extending the rectangle beyond it.
if ( isTopMenu ) {
painter->setClipRect( rect );
}
if( roundCorners )
{
painter->setRenderHint( QPainter::Antialiasing );
QRectF frameRect( rect );
qreal radius( frameRadius( PenWidth::NoPen ) );
if( isTopMenu ) frameRect.adjust(0, -radius, 0, 0);
// set pen
if( outline.isValid() )
{
painter->setPen( outline );
frameRect = strokedRect( frameRect );
radius = frameRadiusForNewPenWidth( radius, PenWidth::Frame );
} else painter->setPen( Qt::NoPen );
// render
painter->drawRoundedRect( frameRect, radius, radius );
} else {
painter->setRenderHint( QPainter::Antialiasing, false );
QRect frameRect( rect );
if( isTopMenu ) frameRect.adjust(0, 1, 0, 0);
if( outline.isValid() )
{
painter->setPen( outline );
frameRect.adjust( 0, 0, -1, -1 );
} else painter->setPen( Qt::NoPen );
painter->drawRect( frameRect );
}
painter->restore();
}
//______________________________________________________________________________
void Helper::renderButtonFrame(QPainter* painter, const QRect& rect, const QPalette& palette, const QHash<QByteArray, bool>& stateProperties, qreal bgAnimation, qreal penAnimation) const
{
bool enabled = stateProperties.value("enabled", true);
bool visualFocus = stateProperties.value("visualFocus");
bool hovered = stateProperties.value("hovered");
bool down = stateProperties.value("down");
bool checked = stateProperties.value("checked");
bool flat = stateProperties.value("flat");
bool defaultButton = stateProperties.value("defaultButton");
bool hasNeutralHighlight = stateProperties.value("hasNeutralHighlight");
// don't render background if flat and not hovered, down, checked, or given visual focus
if (flat && !(hovered || down || checked || visualFocus)
&& bgAnimation == AnimationData::OpacityInvalid
&& penAnimation == AnimationData::OpacityInvalid
) {
return;
}
QRectF shadowedRect = this->shadowedRect(rect);
QRectF frameRect = strokedRect(shadowedRect);
qreal radius = frameRadius( PenWidth::Frame );
// setting color group to work around KColorScheme feature
const QColor &highlightColor = palette.color(!enabled ? QPalette::Disabled : QPalette::Active, QPalette::Highlight);
QBrush bgBrush;
QBrush penBrush;
// Colors
if (flat) {
if (down && enabled) {
bgBrush = alphaColor(highlightColor, 0.333);
} else if (checked) {
bgBrush = hasNeutralHighlight ? alphaColor(neutralText(palette), 0.333)
: alphaColor(palette.buttonText().color(), 0.125);
penBrush = hasNeutralHighlight ? neutralText(palette)
: KColorUtils::mix(palette.button().color(), palette.buttonText().color(), 0.3);
} else if (defaultButton) {
bgBrush = alphaColor(highlightColor, 0.125);
penBrush = KColorUtils::mix(
highlightColor,
KColorUtils::mix(palette.button().color(), palette.buttonText().color(), 0.333),
0.5
);
} else {
bgBrush = alphaColor(highlightColor, 0);
penBrush = hasNeutralHighlight ? neutralText(palette) : bgBrush;
}
} else {
if (down && enabled) {
bgBrush = KColorUtils::mix(palette.button().color(), highlightColor, 0.333);
} else if (checked) {
bgBrush = hasNeutralHighlight ? KColorUtils::mix(palette.button().color(), neutralText(palette), 0.333)
: KColorUtils::mix(palette.button().color(), palette.buttonText().color(), 0.125);
penBrush = hasNeutralHighlight ? neutralText(palette)
: KColorUtils::mix(palette.button().color(), palette.buttonText().color(), 0.3);
} else if (defaultButton) {
bgBrush = KColorUtils::mix(palette.button().color(), highlightColor, 0.2);
penBrush = KColorUtils::mix(
highlightColor,
KColorUtils::mix(palette.button().color(), palette.buttonText().color(), 0.333),
0.5
);
} else {
bgBrush = palette.button().color();
penBrush = hasNeutralHighlight ? neutralText(palette)
: KColorUtils::mix(palette.button().color(), palette.buttonText().color(), 0.3);
}
}
if ((hovered || visualFocus || down) && enabled) {
penBrush = highlightColor;
}
// Animations
if (bgAnimation != AnimationData::OpacityInvalid && enabled) {
QColor color1 = bgBrush.color();
QColor color2 = flat ? alphaColor(highlightColor, 0.333)
: KColorUtils::mix(palette.button().color(), highlightColor, 0.333);
bgBrush = KColorUtils::mix(color1, color2, bgAnimation);
}
if (penAnimation != AnimationData::OpacityInvalid && enabled) {
QColor color1 = penBrush.color();
QColor color2 = highlightColor;
penBrush = KColorUtils::mix(color1, color2, penAnimation);
}
// Gradient
if (!(flat || down || hovered || checked) && enabled) {
QLinearGradient bgGradient(frameRect.topLeft(), frameRect.bottomLeft());
bgGradient.setColorAt(0, KColorUtils::mix(bgBrush.color(), Qt::white, 0.03125));
bgGradient.setColorAt(0.5, bgBrush.color());
bgGradient.setColorAt(1, KColorUtils::mix(bgBrush.color(), Qt::black, 0.03125));
QLinearGradient penGradient(frameRect.topLeft(), frameRect.bottomLeft());
penGradient.setColorAt(0, KColorUtils::mix(penBrush.color(), Qt::white, 0.03125));
penGradient.setColorAt(1, KColorUtils::mix(penBrush.color(), Qt::black, 0.0625));
bgBrush = bgGradient;
penBrush = penGradient;
}
// Shadow
if (!(flat || down || checked) && enabled) {
renderRoundedRectShadow(painter, shadowedRect, shadowColor(palette));
}
// Render button
painter->setRenderHint( QPainter::Antialiasing, true );
painter->setBrush(bgBrush);
painter->setPen(QPen(penBrush, PenWidth::Frame));
painter->drawRoundedRect(frameRect, radius, radius);
}
//______________________________________________________________________________
void Helper::renderToolBoxFrame(
QPainter* painter, const QRect& rect, int tabWidth,
const QColor& outline ) const
{
if( !outline.isValid() ) return;
// round radius
const qreal radius( frameRadius( PenWidth::Frame ) );
const QSizeF cornerSize( 2*radius, 2*radius );
// if rect - tabwidth is even, need to increase tabWidth by 1 unit
// for anti aliasing
if( !((rect.width() - tabWidth)%2) ) ++tabWidth;
// adjust rect for antialiasing
QRectF baseRect( strokedRect( rect ) );
// create path
QPainterPath path;
path.moveTo( 0, baseRect.height()-1 );
path.lineTo( ( baseRect.width() - tabWidth )/2 - radius, baseRect.height()-1 );
path.arcTo( QRectF( QPointF( ( baseRect.width() - tabWidth )/2 - 2*radius, baseRect.height()-1 - 2*radius ), cornerSize ), 270, 90 );
path.lineTo( ( baseRect.width() - tabWidth )/2, radius );
path.arcTo( QRectF( QPointF( ( baseRect.width() - tabWidth )/2, 0 ), cornerSize ), 180, -90 );
path.lineTo( ( baseRect.width() + tabWidth )/2 -1 - radius, 0 );
path.arcTo( QRectF( QPointF( ( baseRect.width() + tabWidth )/2 - 1 - 2*radius, 0 ), cornerSize ), 90, -90 );
path.lineTo( ( baseRect.width() + tabWidth )/2 -1, baseRect.height()-1 - radius );
path.arcTo( QRectF( QPointF( ( baseRect.width() + tabWidth )/2 -1, baseRect.height()-1 - 2*radius ), cornerSize ), 180, 90 );
path.lineTo( baseRect.width()-1, baseRect.height()-1 );
// render
painter->setRenderHints( QPainter::Antialiasing );
painter->setBrush( Qt::NoBrush );
painter->setPen( outline );
painter->translate( baseRect.topLeft() );
painter->drawPath( path );
}
//______________________________________________________________________________
void Helper::renderTabWidgetFrame(
QPainter* painter, const QRect& rect,
const QColor& color, const QColor& outline, Corners corners ) const
{
painter->setRenderHint( QPainter::Antialiasing );
QRectF frameRect( rect.adjusted( 1, 1, -1, -1 ) );
qreal radius( frameRadius( PenWidth::NoPen ) );
// set pen
if( outline.isValid() )
{
painter->setPen( outline );
frameRect = strokedRect( frameRect );
radius = frameRadiusForNewPenWidth( radius, PenWidth::Frame );
} else painter->setPen( Qt::NoPen );
// set brush
if( color.isValid() ) painter->setBrush( color );
else painter->setBrush( Qt::NoBrush );
// render
QPainterPath path( roundedPath( frameRect, corners, radius ) );
painter->drawPath( path );
}
//______________________________________________________________________________
void Helper::renderSelection(
QPainter* painter, const QRect& rect,
const QColor& color ) const
{
painter->setRenderHint( QPainter::Antialiasing );
painter->setPen( Qt::NoPen );
painter->setBrush( color );
painter->drawRect( rect );
}
//______________________________________________________________________________
void Helper::renderSeparator(
QPainter* painter, const QRect& rect,
const QColor& color, bool vertical ) const
{
painter->setRenderHint( QPainter::Antialiasing, false );
painter->setBrush( Qt::NoBrush );
painter->setPen( color );
if( vertical )
{
painter->translate( rect.width()/2, 0 );
painter->drawLine( rect.topLeft(), rect.bottomLeft() );
} else {
painter->translate( 0, rect.height()/2 );
painter->drawLine( rect.topLeft(), rect.topRight() );
}
}
//______________________________________________________________________________
void Helper::renderCheckBoxBackground(
QPainter* painter, const QRect& rect,
const QPalette& palette,
CheckBoxState state, bool neutalHighlight,
bool sunken, qreal animation ) const
{
// setup painter
painter->setRenderHint( QPainter::Antialiasing, true );
// copy rect
QRectF frameRect( rect );
frameRect.adjust( 2, 2, -2, -2 );
frameRect = strokedRect(frameRect);
auto transparent = neutalHighlight ? neutralText(palette) : palette.highlight().color();
transparent.setAlphaF(0.50);
painter->setPen( transparentize( palette.text().color(), 0.5 ) );
if (state == CheckOn || state == CheckPartial) {
painter->setPen( neutalHighlight ? neutralText(palette) : palette.highlight().color() );
}
const auto radius = Metrics::CheckBox_Radius;
switch (state) {
case CheckOff:
painter->setBrush( palette.base().color().darker(sunken ? radioCheckSunkenDarkeningFactor : 100) );
painter->drawRoundedRect( frameRect, radius, radius );
break;
case CheckPartial:
case CheckOn:
painter->setBrush( transparent );
painter->drawRoundedRect( frameRect, radius, radius );
break;
case CheckAnimated:
painter->setBrush( palette.base().color().darker(sunken ? radioCheckSunkenDarkeningFactor : 100) );
painter->drawRoundedRect( frameRect, radius, radius );
painter->setBrush( transparent );
painter->setOpacity( animation );
painter->drawRoundedRect( frameRect, radius, radius );
break;
}
}
//______________________________________________________________________________
void Helper::renderCheckBox(
QPainter* painter, const QRect& rect,
const QPalette& palette, bool mouseOver,
CheckBoxState state, CheckBoxState target,
bool neutalHighlight, bool sunken,
qreal animation, qreal hoverAnimation ) const
{
Q_UNUSED(sunken)
// setup painter
painter->setRenderHint( QPainter::Antialiasing, true );
// copy rect and radius
QRectF frameRect( rect );
frameRect.adjust( 2, 2, -2, -2 );
if ( mouseOver ) {
painter->save();
if (hoverAnimation != AnimationData::OpacityInvalid) {
painter->setOpacity(hoverAnimation);
}
painter->setPen( QPen( neutalHighlight ? neutralText(palette).lighter() : focusColor(palette), PenWidth::Frame ) );
painter->setBrush( Qt::NoBrush );
painter->drawRoundedRect( frameRect.adjusted(0.5, 0.5, -0.5, -0.5), Metrics::CheckBox_Radius, Metrics::CheckBox_Radius );
painter->restore();
}
// check
auto leftPoint = frameRect.center();
leftPoint.setX(frameRect.left()+4);
auto bottomPoint = frameRect.center();
bottomPoint.setX(bottomPoint.x() - 1);
bottomPoint.setY(frameRect.bottom() - 5);
auto rightPoint = frameRect.center();
rightPoint.setX(rightPoint.x() + 4.5);
rightPoint.setY(frameRect.top() + 5.5);
QPainterPath path;
path.moveTo(leftPoint);
path.lineTo(bottomPoint);
path.lineTo(rightPoint);
// dots
auto centerDot = QRectF(frameRect.center(), QSize(2, 2));
centerDot.adjust(-1, -1, -1, -1);
auto leftDot = centerDot.adjusted(-4, 0, -4, 0);
auto rightDot = centerDot.adjusted(4, 0, 4, 0);
painter->setPen(Qt::transparent);
painter->setBrush(Qt::transparent);
auto checkPen = QPen( palette.text(), PenWidth::Frame * 2 );
checkPen.setJoinStyle(Qt::MiterJoin);
switch (state) {
case CheckOff:
break;
case CheckOn:
painter->setPen( checkPen );
painter->drawPath( path );
break;
case CheckPartial:
painter->setBrush( palette.text() );
painter->drawRect(leftDot);
painter->drawRect(centerDot);
painter->drawRect(rightDot);
break;
case CheckAnimated:
checkPen.setDashPattern({ path.length() * animation, path.length() });
switch (target) {
case CheckOff:
break;
case CheckOn:
painter->setPen( checkPen );
painter->drawPath( path );
break;
case CheckPartial:
if (animation >= 3/3) painter->drawRect(rightDot);
if (animation >= 2/3) painter->drawRect(centerDot);
if (animation >= 1/3) painter->drawRect(leftDot);
break;
case CheckAnimated:
break;
}
break;
}
}
//______________________________________________________________________________
void Helper::renderRadioButtonBackground( QPainter* painter, const QRect& rect, const QPalette& palette, RadioButtonState state, bool neutalHighlight, bool sunken, qreal animation ) const
{
// setup painter
painter->setRenderHint( QPainter::Antialiasing, true );
// copy rect
QRectF frameRect( rect );
frameRect.adjust( 2, 2, -2, -2 );
frameRect.adjust( 0.5, 0.5, -0.5, -0.5 );
auto transparent = neutalHighlight ? neutralText(palette) : palette.highlight().color();
transparent.setAlphaF(0.50);
painter->setPen( QPen(transparentize( palette.text().color(), 0.5 ), PenWidth::Frame) );
if (state == RadioOn) {
painter->setPen( QPen(neutalHighlight ? neutralText(palette) : palette.highlight().color(), PenWidth::Frame) );
}
switch (state) {
case RadioOff:
painter->setBrush( palette.base().color().darker(sunken ? radioCheckSunkenDarkeningFactor : 100) );
painter->drawEllipse( frameRect );
break;
case RadioOn:
painter->setBrush( transparent );
painter->drawEllipse( frameRect );
break;
case RadioAnimated:
painter->setBrush( palette.base().color().darker(sunken ? radioCheckSunkenDarkeningFactor : 100) );
painter->drawEllipse( frameRect );
painter->setBrush( transparent );
painter->setOpacity( animation );
painter->drawEllipse( frameRect );
break;
}
}
//______________________________________________________________________________
void Helper::renderRadioButton(
QPainter* painter, const QRect& rect,
const QPalette& palette, bool mouseOver,
RadioButtonState state, bool neutralHighlight, bool sunken, qreal animation, qreal animationHover ) const
{
Q_UNUSED(sunken)
// setup painter
painter->setRenderHint( QPainter::Antialiasing, true );
// copy rect
QRectF frameRect( rect );
frameRect.adjust( 1, 1, -1, -1 );
if ( mouseOver ) {
painter->save();
if (animationHover != AnimationData::OpacityInvalid) {
painter->setOpacity(animationHover);
}
painter->setPen( QPen( neutralHighlight ? neutralText(palette).lighter() : focusColor(palette), PenWidth::Frame ) );
painter->setBrush( Qt::NoBrush );
const QRectF contentRect( frameRect.adjusted( 1, 1, -1, -1 ).adjusted( 0.5 , 0.5, -0.5, -0.5 ) );
painter->drawEllipse( contentRect );
painter->restore();
}
painter->setBrush( palette.text() );
painter->setPen( Qt::NoPen );
QRectF markerRect;
markerRect = frameRect.adjusted( 6, 6, -6, -6 );
qreal adjustFactor;
// mark
switch (state) {
case RadioOn:
painter->drawEllipse( markerRect );
break;
case RadioAnimated:
adjustFactor = markerRect.height() * (1 - animation);
markerRect.adjust(adjustFactor, adjustFactor, -adjustFactor, -adjustFactor);
painter->drawEllipse( markerRect );
break;
default:
break;
}
}
//______________________________________________________________________________
void Helper::renderSliderGroove(
QPainter* painter, const QRect& rect,
const QColor& color ) const
{
// setup painter
painter->setRenderHint( QPainter::Antialiasing, true );
QRectF baseRect( rect );
baseRect.adjust(0.5, 0.5, -0.5, -0.5);
const qreal radius( 0.5*Metrics::Slider_GrooveThickness );
// content
if( color.isValid() )
{
painter->setPen( QPen(color, PenWidth::Frame) );
auto bg = color;
bg.setAlphaF(bg.alphaF() / 2);
painter->setBrush( bg );
painter->drawRoundedRect( baseRect, radius, radius );
}
}
//______________________________________________________________________________
void Helper::renderDialGroove(
QPainter* painter, const QRect& rect,
const QColor& fg, const QColor& bg,
qreal first, qreal last ) const
{
// setup painter
painter->setRenderHint( QPainter::Antialiasing, true );
const QRectF baseRect( rect );
// content
if( fg.isValid() )
{
const qreal penWidth( Metrics::Slider_GrooveThickness );
const QRectF grooveRect( rect.adjusted( penWidth/2, penWidth/2, -penWidth/2, -penWidth/2 ) );
// setup angles
const int angleStart( first * 180 * 16 / M_PI );
const int angleSpan( (last - first ) * 180 * 16 / M_PI );
const QPen bgPen( fg, penWidth, Qt::SolidLine, Qt::RoundCap );
const QPen fgPen( KColorUtils::overlayColors( bg, alphaColor( fg, 0.5) ), penWidth - 2, Qt::SolidLine, Qt::RoundCap );
// setup pen
if( angleSpan != 0 )
{
painter->setPen( bgPen );
painter->setBrush( Qt::NoBrush );
painter->drawArc( grooveRect, angleStart, angleSpan );
painter->setPen( fgPen );
painter->drawArc( grooveRect, angleStart, angleSpan );
}
}
}
//______________________________________________________________________________
void Helper::renderSliderHandle(
QPainter* painter, const QRect& rect,
const QColor& color,
const QColor& outline,
const QColor& shadow,
bool sunken ) const
{
// setup painter
painter->setRenderHint( QPainter::Antialiasing, true );
// copy rect
QRectF frameRect( rect );
frameRect.adjust( 1, 1, -1, -1 );
// shadow
if( !sunken )
{
renderEllipseShadow( painter, frameRect, shadow );
}
// set pen
if( outline.isValid() )
{
painter->setPen( QPen(outline, PenWidth::Frame) );
frameRect = strokedRect( frameRect );
} else painter->setPen( Qt::NoPen );
// set brush
if( color.isValid() ) painter->setBrush( color );
else painter->setBrush( Qt::NoBrush );
// render
painter->drawEllipse( frameRect );
}
//______________________________________________________________________________
void Helper::renderProgressBarGroove(
QPainter* painter, const QRect& rect,
const QColor& fg, const QColor& bg ) const
{
// setup painter
painter->setRenderHint( QPainter::Antialiasing, true );
QRectF baseRect( rect );
baseRect.adjust(0.5,0.5,-0.5,-0.5);
const qreal radius( 0.5*Metrics::ProgressBar_Thickness );
// content
if( fg.isValid() )
{
painter->setPen( QPen(fg, PenWidth::Frame) );
painter->setBrush( KColorUtils::overlayColors(bg, alphaColor(fg, 0.5)) );
painter->drawRoundedRect( baseRect, radius, radius );
}
}
//______________________________________________________________________________
void Helper::renderProgressBarBusyContents(
QPainter* painter, const QRect& rect,
const QColor& first,
const QColor& second,
bool horizontal,
bool reverse,
int progress
) const
{
// setup painter
painter->setRenderHint( QPainter::Antialiasing, true );
const QRectF baseRect( rect );
const qreal radius( 0.5*Metrics::ProgressBar_Thickness );
// setup brush
QPixmap pixmap( horizontal ? 2*Metrics::ProgressBar_BusyIndicatorSize : 1, horizontal ? 1:2*Metrics::ProgressBar_BusyIndicatorSize );
pixmap.fill( second );
if( horizontal )
{
QPainter painter( &pixmap );
painter.setBrush( first );
painter.setPen( Qt::NoPen );
progress %= 2*Metrics::ProgressBar_BusyIndicatorSize;
if( reverse ) progress = 2*Metrics::ProgressBar_BusyIndicatorSize - progress - 1;
painter.drawRect( QRect( 0, 0, Metrics::ProgressBar_BusyIndicatorSize, 1 ).translated( progress, 0 ) );
if( progress > Metrics::ProgressBar_BusyIndicatorSize )
{ painter.drawRect( QRect( 0, 0, Metrics::ProgressBar_BusyIndicatorSize, 1 ).translated( progress - 2*Metrics::ProgressBar_BusyIndicatorSize, 0 ) ); }
} else {
QPainter painter( &pixmap );
painter.setBrush( first );
painter.setPen( Qt::NoPen );
progress %= 2*Metrics::ProgressBar_BusyIndicatorSize;
progress = 2*Metrics::ProgressBar_BusyIndicatorSize - progress - 1;
painter.drawRect( QRect( 0, 0, 1, Metrics::ProgressBar_BusyIndicatorSize ).translated( 0, progress ) );
if( progress > Metrics::ProgressBar_BusyIndicatorSize )
{ painter.drawRect( QRect( 0, 0, 1, Metrics::ProgressBar_BusyIndicatorSize ).translated( 0, progress - 2*Metrics::ProgressBar_BusyIndicatorSize ) ); }
}
painter->setPen( Qt::NoPen );
painter->setBrush( pixmap );
painter->drawRoundedRect( baseRect, radius, radius );
}
//______________________________________________________________________________
void Helper::renderScrollBarHandle(
QPainter* painter, const QRect& rect,
const QColor& fg, const QColor& bg ) const
{
// setup painter
painter->setRenderHint( QPainter::Antialiasing, true );
const QRectF baseRect( rect );
const qreal radius( 0.5 * std::min({baseRect.width(), baseRect.height(), (qreal)Metrics::ScrollBar_SliderWidth}) );
painter->setPen( Qt::NoPen );
painter->setPen( QPen(fg, 1.001) );
painter->setBrush( KColorUtils::overlayColors(bg, alphaColor(fg, 0.5)) );
painter->drawRoundedRect( strokedRect(baseRect), radius, radius );
}
void Helper::renderScrollBarGroove(
QPainter* painter, const QRect& rect,
const QColor& color ) const
{
// setup painter
painter->setRenderHint( QPainter::Antialiasing, true );
const QRectF baseRect( rect );
const qreal radius( 0.5 * std::min({baseRect.width(), baseRect.height(), (qreal)Metrics::ScrollBar_SliderWidth}) );
// content
if( color.isValid() )
{
painter->setPen( Qt::NoPen );
auto bg = color;
bg.setAlphaF(bg.alphaF() / 2.0);
painter->setBrush( bg );
painter->setPen( QPen(color, 1.001) );
painter->drawRoundedRect( strokedRect(baseRect), radius, radius );
}
}
//______________________________________________________________________________
void Helper::renderScrollBarBorder(
QPainter* painter, const QRect& rect,
const QColor& color ) const
{
// content
if( color.isValid() )
{
painter->setPen( Qt::NoPen );
painter->setBrush( color );
painter->drawRect( rect );
}
}
//______________________________________________________________________________
void Helper::renderTabBarTab(QPainter *painter, const QRect &rect,
const QColor &color, const QColor &highlight,
const QColor &outline, Corners corners,
bool document, bool bottom) const {
// setup painter
painter->setRenderHint( QPainter::Antialiasing, true );
QRectF frameRect( rect );
qreal radius( frameRadius( PenWidth::NoPen ) );
// pen
if( outline.isValid() )
{
painter->setPen( outline );
frameRect = strokedRect( frameRect );
radius = frameRadiusForNewPenWidth( radius, PenWidth::Frame );
} else painter->setPen( Qt::NoPen );
// brush
if( color.isValid() ) painter->setBrush( color );
else painter->setBrush( Qt::NoBrush );
// render
QPainterPath path( roundedPath( frameRect, corners, radius ) );
painter->drawPath( path );
if (highlight.isValid() && document) {
auto rect = frameRect;
rect.setHeight(2);
if (bottom) {
rect.setTop(frameRect.bottom()-2);
rect.setBottom(frameRect.bottom());
}
QPainterPath rectAsPath;
rectAsPath.addRect(rect);
painter->setClipPath(path.intersected(rectAsPath));
painter->setBrush(highlight);
painter->drawRect(frameRect);
}
}
//______________________________________________________________________________
void Helper::renderArrow( QPainter* painter, const QRect& rect, const QColor& color, ArrowOrientation orientation ) const
{
// define polygon
QPolygonF arrow;
switch( orientation )
{
/* The inner points of the normal arrows are not on half pixels because
* they need to have an even width (up/down) or height (left/right).
* An even width/height makes them easier to align with other UI elements.
*/
case ArrowUp: arrow = QVector<QPointF>{QPointF( -4.5, 1.5 ), QPointF( 0, -3 ), QPointF( 4.5, 1.5 )}; break;
case ArrowDown: arrow = QVector<QPointF>{QPointF( -4.5, -1.5 ), QPointF( 0, 3 ), QPointF( 4.5, -1.5 )}; break;
case ArrowLeft: arrow = QVector<QPointF>{QPointF( 1.5, -4.5 ), QPointF( -3, 0 ), QPointF( 1.5, 4.5 )}; break;
case ArrowRight: arrow = QVector<QPointF>{QPointF( -1.5, -4.5 ), QPointF( 3, 0 ), QPointF( -1.5, 4.5 )}; break;
case ArrowDown_Small: arrow = QVector<QPointF>{QPointF( 1.5, 3.5 ), QPointF( 3.5, 5.5 ), QPointF( 5.5, 3.5 )}; break;
default: break;
}
painter->save();
painter->setRenderHints( QPainter::Antialiasing );
painter->translate( QRectF( rect ).center() );
painter->setBrush( Qt::NoBrush );
QPen pen( color, PenWidth::Symbol );
pen.setCapStyle(Qt::SquareCap);
pen.setJoinStyle(Qt::MiterJoin);
painter->setPen( pen );
painter->drawPolyline( arrow );
painter->restore();
}
//______________________________________________________________________________
void Helper::renderDecorationButton( QPainter* painter, const QRect& rect, const QColor& color, ButtonType buttonType, bool inverted ) const
{
painter->save();
painter->setViewport( rect );
painter->setWindow( 0, 0, 18, 18 );
painter->setRenderHints( QPainter::Antialiasing );
// initialize pen
QPen pen;
pen.setCapStyle( Qt::RoundCap );
pen.setJoinStyle( Qt::MiterJoin );
if( inverted )
{
// render circle
painter->setPen( Qt::NoPen );
painter->setBrush( color );
painter->drawEllipse( QRectF( 0, 0, 18, 18 ) );
// take out the inner part
painter->setCompositionMode( QPainter::CompositionMode_DestinationOut );
painter->setBrush( Qt::NoBrush );
pen.setColor( Qt::black );
} else {
painter->setBrush( Qt::NoBrush );
pen.setColor( color );
}
pen.setCapStyle( Qt::RoundCap );
pen.setJoinStyle( Qt::MiterJoin );
pen.setWidthF( PenWidth::Symbol*qMax(1.0, 18.0/rect.width() ) );
painter->setPen( pen );
switch( buttonType )
{
case ButtonClose:
{
painter->drawLine( QPointF( 5, 5 ), QPointF( 13, 13 ) );
painter->drawLine( 13, 5, 5, 13 );
break;
}
case ButtonMaximize:
{
painter->drawPolyline( QVector<QPointF>{
QPointF( 4, 11 ),
QPointF( 9, 6 ),
QPointF( 14, 11 )});
break;
}
case ButtonMinimize:
{
painter->drawPolyline(QVector<QPointF>{
QPointF( 4, 7 ),
QPointF( 9, 12 ),
QPointF( 14, 7 )} );
break;
}
case ButtonRestore:
{
pen.setJoinStyle( Qt::RoundJoin );
painter->setPen( pen );
painter->drawPolygon( QVector<QPointF>{
QPointF( 4.5, 9 ),
QPointF( 9, 4.5 ),
QPointF( 13.5, 9 ),
QPointF( 9, 13.5 )});
break;
}
default: break;
}
painter->restore();
}
//______________________________________________________________________________
void Helper::renderRoundedRectShadow( QPainter* painter, const QRectF& rect, const QColor& color, qreal radius ) const
{
if( !color.isValid() ) return;
painter->setRenderHint( QPainter::Antialiasing, true );
qreal adjustment = 0.5 * PenWidth::Shadow; // Translate for the pen
QRectF shadowRect = rect.adjusted( adjustment, adjustment, -adjustment, adjustment );
painter->setPen( QPen(color, PenWidth::Shadow) );
painter->setBrush( Qt::NoBrush );
painter->drawRoundedRect( shadowRect, radius, radius );
}
//______________________________________________________________________________
void Helper::renderEllipseShadow( QPainter* painter, const QRectF& rect, const QColor& color ) const
{
if( !color.isValid() ) return;
painter->save();
// Clipping does not improve performance here
qreal adjustment = 0.5 * PenWidth::Shadow; // Adjust for the pen
qreal radius = rect.width() / 2 - adjustment;
/* The right side is offset by +0.5 for the visible part of the shadow.
* The other sides are offset by +0.5 or -0.5 because of the pen.
*/
QRectF shadowRect = rect.adjusted( adjustment, adjustment, adjustment, -adjustment );
painter->translate( rect.center() );
painter->rotate( 45 );
painter->translate( -rect.center() );
painter->setPen( color );
painter->setBrush( Qt::NoBrush );
painter->drawRoundedRect( shadowRect, radius, radius );
painter->restore();
}
//______________________________________________________________________________
bool Helper::isX11()
{
static const bool s_isX11 = KWindowSystem::isPlatformX11();
return s_isX11;
}
//______________________________________________________________________________
bool Helper::isWayland()
{
static const bool s_isWayland = KWindowSystem::isPlatformWayland();
return s_isWayland;
}
//______________________________________________________________________________
QRectF Helper::strokedRect( const QRectF &rect, const qreal penWidth ) const
{
/* With a pen stroke width of 1, the rectangle should have each of its
* sides moved inwards by half a pixel. This allows the stroke to be
* pixel perfect instead of blurry from sitting between pixels and
* prevents the rectangle with a stroke from becoming larger than the
* original size of the rectangle.
*/
qreal adjustment = 0.5 * penWidth;
return rect.adjusted( adjustment, adjustment, -adjustment, -adjustment );
}
//______________________________________________________________________________
QPainterPath Helper::roundedPath( const QRectF& rect, Corners corners, qreal radius ) const
{
QPainterPath path;
// simple cases
if( corners == 0 )
{
path.addRect( rect );
return path;
}
if( corners == AllCorners ) {
path.addRoundedRect( rect, radius, radius );
return path;
}
const QSizeF cornerSize( 2*radius, 2*radius );
// rotate counterclockwise
// top left corner
if( corners & CornerTopLeft )
{
path.moveTo( rect.topLeft() + QPointF( radius, 0 ) );
path.arcTo( QRectF( rect.topLeft(), cornerSize ), 90, 90 );
} else path.moveTo( rect.topLeft() );
// bottom left corner
if( corners & CornerBottomLeft )
{
path.lineTo( rect.bottomLeft() - QPointF( 0, radius ) );
path.arcTo( QRectF( rect.bottomLeft() - QPointF( 0, 2*radius ), cornerSize ), 180, 90 );
} else path.lineTo( rect.bottomLeft() );
// bottom right corner
if( corners & CornerBottomRight )
{
path.lineTo( rect.bottomRight() - QPointF( radius, 0 ) );
path.arcTo( QRectF( rect.bottomRight() - QPointF( 2*radius, 2*radius ), cornerSize ), 270, 90 );
} else path.lineTo( rect.bottomRight() );
// top right corner
if( corners & CornerTopRight )
{
path.lineTo( rect.topRight() + QPointF( 0, radius ) );
path.arcTo( QRectF( rect.topRight() - QPointF( 2*radius, 0 ), cornerSize ), 0, 90 );
} else path.lineTo( rect.topRight() );
path.closeSubpath();
return path;
}
//________________________________________________________________________________________________________
bool Helper::compositingActive() const
{
#if BREEZE_HAVE_QTX11EXTRAS
if( isX11() )
{ return QX11Info::isCompositingManagerRunning( QX11Info::appScreen() ); }
#endif
// use KWindowSystem
return KWindowSystem::compositingActive();
}
//____________________________________________________________________
bool Helper::hasAlphaChannel( const QWidget* widget ) const
{ return compositingActive() && widget && widget->testAttribute( Qt::WA_TranslucentBackground ); }
//______________________________________________________________________________________
qreal Helper::devicePixelRatio( const QPixmap& pixmap ) const
{
return pixmap.devicePixelRatio();
}
QPixmap Helper::coloredIcon(const QIcon& icon, const QPalette& palette, const QSize &size, QIcon::Mode mode, QIcon::State state)
{
const QPalette activePalette = KIconLoader::global()->customPalette();
const bool changePalette = activePalette != palette;
if (changePalette) {
KIconLoader::global()->setCustomPalette(palette);
}
const QPixmap pixmap = icon.pixmap(size, mode, state);
if (changePalette) {
if (activePalette == QPalette()) {
KIconLoader::global()->resetPalette();
} else {
KIconLoader::global()->setCustomPalette(activePalette);
}
}
return pixmap;
}
bool Helper::shouldDrawToolsArea(const QWidget* widget) const {
if (!widget) {
return false;
}
static bool isAuto = false;
static QString borderSize;
if (!_cachedAutoValid) {
KConfigGroup kdecorationGroup(_kwinConfig->group("org.kde.kdecoration2"));
isAuto = kdecorationGroup.readEntry("BorderSizeAuto", true);
borderSize = kdecorationGroup.readEntry("BorderSize", "Normal");
_cachedAutoValid = true;
}
if (isAuto) {
auto window = widget->window();
if (qobject_cast<const QDialog*>(widget)) {
return true;
}
if (window) {
auto handle = window->windowHandle();
if (handle) {
auto toolbar = qobject_cast<const QToolBar*>(widget);
if (toolbar) {
if (toolbar->isFloating()) {
return false;
}
}
return true;
}
} else {
return false;
}
}
if (borderSize != "None" && borderSize != "NoSides") {
return false;
}
return true;
}
}