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.
 
 
 
 

321 lines
13 KiB

/*
* SPDX-FileCopyrightText: 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef breeze_helper_h
#define breeze_helper_h
#include "breeze.h"
#include "breezemetrics.h"
#include "breezeanimationdata.h"
#include "breezesettings.h"
#include "config-breeze.h"
#include <KColorScheme>
#include <KSharedConfig>
#include <KConfigWatcher>
#include <QToolBar>
#include <QPainterPath>
#include <QIcon>
#include <QWidget>
namespace Breeze
{
//* breeze style helper class.
/** contains utility functions used at multiple places in both breeze style and breeze window decoration */
class Helper : public QObject
{
Q_OBJECT
public:
//* constructor
explicit Helper( KSharedConfig::Ptr, QObject *parent = nullptr );
//* destructor
virtual ~Helper()
{}
//* load configuration
virtual void loadConfig();
//* pointer to shared config
KSharedConfig::Ptr config() const;
//* pointer to kdecoration config
QSharedPointer<InternalSettings> decorationConfig() const;
//*@name color utilities
//@{
//* add alpha channel multiplier to color
QColor alphaColor( QColor color, qreal alpha ) const;
//* mouse over color
QColor hoverColor( const QPalette& palette ) const
{ return _viewHoverBrush.brush( palette ).color(); }
//* focus color
QColor focusColor( const QPalette& palette ) const
{ return _viewFocusBrush.brush( palette ).color(); }
//* mouse over color for buttons
QColor buttonHoverColor( const QPalette& palette ) const
{ return _buttonHoverBrush.brush( palette ).color(); }
//* focus color for buttons
QColor buttonFocusColor( const QPalette& palette ) const
{ return _buttonFocusBrush.brush( palette ).color(); }
//* negative text color (used for close button)
QColor negativeText( const QPalette& palette ) const
{ return _viewNegativeTextBrush.brush( palette ).color(); }
//* neutral text color
QColor neutralText( const QPalette& palette ) const
{ return _viewNeutralTextBrush.brush( palette ).color(); }
//* shadow
QColor shadowColor( const QPalette& palette, qreal opacity = 0.125 ) const
{ return QColor::fromRgbF(0, 0, 0, opacity); }
//* titlebar color
const QColor& titleBarColor( bool active ) const
{ return active ? _activeTitleBarColor:_inactiveTitleBarColor; }
//* titlebar text color
const QColor& titleBarTextColor( bool active ) const
{ return active ? _activeTitleBarTextColor : _inactiveTitleBarTextColor; }
//* frame outline color, using animations
QColor frameOutlineColor( const QPalette&, bool mouseOver = false, bool hasFocus = false, qreal opacity = AnimationData::OpacityInvalid, AnimationMode = AnimationNone ) const;
//* focus outline color, using animations
QColor focusOutlineColor( const QPalette& ) const;
//* hover outline color, using animations
QColor hoverOutlineColor( const QPalette& ) const;
//* focus outline color, using animations
QColor buttonFocusOutlineColor( const QPalette& ) const;
//* hover outline color, using animations
QColor buttonHoverOutlineColor( const QPalette& ) const;
//* side panel outline color, using animations
QColor sidePanelOutlineColor( const QPalette&, bool hasFocus = false, qreal opacity = AnimationData::OpacityInvalid, AnimationMode = AnimationNone ) const;
//* frame background color
QColor frameBackgroundColor( const QPalette& palette ) const
{ return frameBackgroundColor( palette, palette.currentColorGroup() ); }
//* frame background color
QColor frameBackgroundColor( const QPalette&, QPalette::ColorGroup ) const;
//* arrow outline color
QColor arrowColor( const QPalette&, QPalette::ColorGroup, QPalette::ColorRole ) const;
//* arrow outline color
QColor arrowColor( const QPalette& palette, QPalette::ColorRole role ) const
{ return arrowColor( palette, palette.currentColorGroup(), role ); }
//* arrow outline color, using animations
QColor arrowColor( const QPalette&, bool mouseOver, bool hasFocus, qreal opacity = AnimationData::OpacityInvalid, AnimationMode = AnimationNone ) const;
//* slider outline color, using animations
QColor sliderOutlineColor( const QPalette&, bool mouseOver, bool hasFocus, qreal opacity = AnimationData::OpacityInvalid, AnimationMode = AnimationNone ) const;
//* scrollbar handle color, using animations
QColor scrollBarHandleColor( const QPalette&, bool mouseOver, bool hasFocus, qreal opacity = AnimationData::OpacityInvalid, AnimationMode = AnimationNone ) const;
//* checkbox indicator, using animations
QColor checkBoxIndicatorColor( const QPalette&, bool mouseOver, bool active, qreal opacity = AnimationData::OpacityInvalid, AnimationMode = AnimationNone ) const;
//* separator color
QColor separatorColor( const QPalette& ) const;
//* merge active and inactive palettes based on ratio, for smooth enable state change transition
QPalette disabledPalette( const QPalette&, qreal ratio ) const;
//@}
//*@name rendering utilities
//@{
//* debug frame
void renderDebugFrame( QPainter*, const QRect& ) const;
//* focus rect
void renderFocusRect( QPainter*, const QRect&, const QColor&, const QColor& outline = QColor(), Sides = {} ) const;
//* focus line
void renderFocusLine( QPainter*, const QRect&, const QColor& ) const;
//* generic frame
void renderFrame( QPainter*, const QRect&, const QColor& color, const QColor& outline = QColor() ) const;
//* generic frame, with separators only on the side
void renderFrameWithSides( QPainter*, const QRect&, const QColor& color, Qt::Edges edges, const QColor& outline = QColor() ) const;
//* side panel frame
void renderSidePanelFrame( QPainter*, const QRect&, const QColor& outline, Side ) const;
//* menu frame
void renderMenuFrame( QPainter*, const QRect&, const QColor& color, const QColor& outline, bool roundCorners = true, bool isTopMenu = false ) const;
//* button frame
void renderButtonFrame(QPainter* painter, const QRect& rect, const QPalette& palette, const QHash<QByteArray, bool>& stateProperties, qreal bgAnimation = AnimationData::OpacityInvalid, qreal penAnimation = AnimationData::OpacityInvalid) const;
//* toolbutton frame
void renderToolBoxFrame( QPainter*, const QRect&, int tabWidth, const QColor& color ) const;
//* tab widget frame
void renderTabWidgetFrame( QPainter*, const QRect&, const QColor& color, const QColor& outline, Corners ) const;
//* selection frame
void renderSelection( QPainter*, const QRect&, const QColor& ) const;
//* separator
void renderSeparator( QPainter*, const QRect&, const QColor&, bool vertical = false ) const;
//* checkbox
void renderCheckBoxBackground( QPainter*, const QRect&, const QPalette& palette, CheckBoxState state, bool neutalHighlight, bool sunken, qreal animation = AnimationData::OpacityInvalid ) const;
//* checkbox
void renderCheckBox( QPainter*, const QRect&, const QPalette& palette, bool mouseOver, CheckBoxState state, CheckBoxState target, bool neutalHighlight, bool sunken, qreal animation = AnimationData::OpacityInvalid, qreal hoverAnimation = AnimationData::OpacityInvalid ) const;
//* radio button
void renderRadioButtonBackground( QPainter*, const QRect&, const QPalette& palette, RadioButtonState state, bool neutalHighlight, bool sunken, qreal animation = AnimationData::OpacityInvalid ) const;
//* radio button
void renderRadioButton( QPainter*, const QRect&, const QPalette& palette, bool mouseOver, RadioButtonState state, bool neutalHighlight, bool sunken, qreal animation = AnimationData::OpacityInvalid, qreal hoverAnimation = AnimationData::OpacityInvalid ) const;
//* slider groove
void renderSliderGroove( QPainter*, const QRect&, const QColor& ) const;
//* slider handle
void renderSliderHandle( QPainter*, const QRect&, const QColor&, const QColor& outline, const QColor& shadow, bool sunken ) const;
//* dial groove
void renderDialGroove( QPainter*, const QRect&, const QColor& fg, const QColor& bg, qreal first, qreal last ) const;
//* progress bar groove
void renderProgressBarGroove( QPainter*, const QRect&, const QColor& fg, const QColor& bg) const;
//* progress bar contents (animated)
void renderProgressBarBusyContents( QPainter* painter, const QRect& rect, const QColor& first, const QColor& second, bool horizontal, bool reverse, int progress ) const;
//* scrollbar groove
void renderScrollBarGroove( QPainter* painter, const QRect& rect, const QColor& color ) const;
//* scrollbar handle
void renderScrollBarHandle( QPainter*, const QRect&, const QColor& fg, const QColor& bg ) const;
//* separator between scrollbar and contents
void renderScrollBarBorder( QPainter*, const QRect&, const QColor& ) const;
//* tabbar tab
void renderTabBarTab( QPainter*, const QRect&, const QPalette& palette, const QHash<QByteArray, bool>& stateProperties, Corners corners, qreal animation ) const;
// TODO(janet): document should be set based on whether or not we consider the
// tab user-editable, but Qt apps often misuse or don't use documentMode property
// so we're currently just always setting it to true for now
//* generic arrow
void renderArrow( QPainter*, const QRect&, const QColor&, ArrowOrientation ) const;
//* generic button (for mdi decorations, tabs and dock widgets)
void renderDecorationButton( QPainter*, const QRect&, const QColor&, ButtonType, bool inverted ) const;
//* generic shadow for rounded rectangles
void renderRoundedRectShadow( QPainter*, const QRectF&, const QColor&, qreal radius = Metrics::Frame_FrameRadius - PenWidth::Shadow / 2 ) const;
//* generic shadow for ellipses
void renderEllipseShadow( QPainter*, const QRectF&, const QColor& ) const;
//@}
//*@name compositing utilities
//@{
//* true if style was compiled for and is running on X11
static bool isX11();
//* true if running on platform Wayland
static bool isWayland();
//* returns true if compositing is active
bool compositingActive() const;
//* returns true if a given widget supports alpha channel
bool hasAlphaChannel( const QWidget* ) const;
//* returns true if the tools area should be drawn
bool shouldDrawToolsArea ( const QWidget* ) const;
//@}
//* frame radius
constexpr qreal frameRadius( const int penWidth = PenWidth::NoPen, const qreal bias = 0 ) const
{ return qMax( Metrics::Frame_FrameRadius - (0.5 * penWidth) + bias, 0.0 ); }
//* frame radius with new pen width
constexpr qreal frameRadiusForNewPenWidth( const qreal oldRadius, const int penWidth ) const
{ return qMax( oldRadius - (0.5 * penWidth), 0.0 ); }
//* return a QRectF with the appropriate size for a rectangle with a pen stroke
QRectF strokedRect( const QRectF &rect, const qreal penWidth = PenWidth::Frame ) const;
//* return a QRectF with the appropriate size for a rectangle with a shadow around it
QRectF shadowedRect( const QRectF &rect, const qreal shadowSize = PenWidth::Shadow ) const
{ return rect.adjusted(shadowSize, shadowSize, -shadowSize, -shadowSize); }
QPixmap coloredIcon(const QIcon &icon, const QPalette& palette, const QSize &size,
QIcon::Mode mode = QIcon::Normal, QIcon::State state = QIcon::Off);
protected:
//* return rounded path in a given rect, with only selected corners rounded, and for a given radius
QPainterPath roundedPath( const QRectF&, Corners, qreal ) const;
private:
//* configuration
KSharedConfig::Ptr _config;
//* KWin configuration
KSharedConfig::Ptr _kwinConfig;
//* decoration configuration
QSharedPointer<InternalSettings> _decorationConfig;
//*@name brushes
//@{
KStatefulBrush _viewFocusBrush;
KStatefulBrush _viewHoverBrush;
KStatefulBrush _buttonFocusBrush;
KStatefulBrush _buttonHoverBrush;
KStatefulBrush _viewNegativeTextBrush;
KStatefulBrush _viewNeutralTextBrush;
//@}
//*@name windeco colors
//@{
QColor _activeTitleBarColor;
QColor _activeTitleBarTextColor;
QColor _inactiveTitleBarColor;
QColor _inactiveTitleBarTextColor;
//@}
mutable bool _cachedAutoValid = false;
friend class ToolsAreaManager;
};
}
#endif