File indexing completed on 2024-05-12 16:58:28
0001 /* 0002 * SPDX-FileCopyrightText: 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef breeze_helper_h 0008 #define breeze_helper_h 0009 0010 #include "breeze.h" 0011 #include "breezeanimationdata.h" 0012 #include "breezemetrics.h" 0013 #include "breezesettings.h" 0014 #include "config-breeze.h" 0015 0016 #include <KConfigWatcher> 0017 #include <KSharedConfig> 0018 #include <KStatefulBrush> 0019 0020 #include <QIcon> 0021 #include <QPainterPath> 0022 #include <QToolBar> 0023 #include <QWidget> 0024 0025 namespace Breeze 0026 { 0027 //* breeze style helper class. 0028 /** contains utility functions used at multiple places in both breeze style and breeze window decoration */ 0029 class Helper : public QObject 0030 { 0031 Q_OBJECT 0032 0033 public: 0034 //* constructor 0035 explicit Helper(KSharedConfig::Ptr, QObject *parent = nullptr); 0036 0037 //* destructor 0038 virtual ~Helper() 0039 { 0040 } 0041 0042 //* load configuration 0043 virtual void loadConfig(); 0044 0045 //* pointer to shared config 0046 KSharedConfig::Ptr config() const; 0047 0048 //* pointer to kdecoration config 0049 QSharedPointer<InternalSettings> decorationConfig() const; 0050 0051 //*@name color utilities 0052 //@{ 0053 0054 //* add alpha channel multiplier to color 0055 QColor alphaColor(QColor color, qreal alpha) const; 0056 0057 //* mouse over color 0058 QColor hoverColor(const QPalette &palette) const 0059 { 0060 return _viewHoverBrush.brush(palette).color(); 0061 } 0062 0063 //* focus color 0064 QColor focusColor(const QPalette &palette) const 0065 { 0066 return _viewFocusBrush.brush(palette).color(); 0067 } 0068 0069 //* mouse over color for buttons 0070 QColor buttonHoverColor(const QPalette &palette) const 0071 { 0072 return _buttonHoverBrush.brush(palette).color(); 0073 } 0074 0075 //* focus color for buttons 0076 QColor buttonFocusColor(const QPalette &palette) const 0077 { 0078 return _buttonFocusBrush.brush(palette).color(); 0079 } 0080 0081 //* negative text color (used for close button) 0082 QColor negativeText(const QPalette &palette) const 0083 { 0084 return _viewNegativeTextBrush.brush(palette).color(); 0085 } 0086 0087 //* neutral text color 0088 QColor neutralText(const QPalette &palette) const 0089 { 0090 return _viewNeutralTextBrush.brush(palette).color(); 0091 } 0092 0093 //* shadow 0094 QColor shadowColor(const QPalette &palette, qreal opacity = 0.125) const 0095 { 0096 return QColor::fromRgbF(0, 0, 0, opacity); 0097 } 0098 0099 //* titlebar color 0100 const QColor &titleBarColor(bool active) const 0101 { 0102 return active ? _activeTitleBarColor : _inactiveTitleBarColor; 0103 } 0104 0105 //* titlebar text color 0106 const QColor &titleBarTextColor(bool active) const 0107 { 0108 return active ? _activeTitleBarTextColor : _inactiveTitleBarTextColor; 0109 } 0110 0111 //* frame outline color, using animations 0112 QColor frameOutlineColor(const QPalette &, 0113 bool mouseOver = false, 0114 bool hasFocus = false, 0115 qreal opacity = AnimationData::OpacityInvalid, 0116 AnimationMode = AnimationNone) const; 0117 0118 //* focus outline color, using animations 0119 QColor focusOutlineColor(const QPalette &) const; 0120 0121 //* hover outline color, using animations 0122 QColor hoverOutlineColor(const QPalette &) const; 0123 0124 //* focus outline color, using animations 0125 QColor buttonFocusOutlineColor(const QPalette &) const; 0126 0127 //* hover outline color, using animations 0128 QColor buttonHoverOutlineColor(const QPalette &) const; 0129 0130 //* side panel outline color, using animations 0131 QColor sidePanelOutlineColor(const QPalette &, bool hasFocus = false, qreal opacity = AnimationData::OpacityInvalid, AnimationMode = AnimationNone) const; 0132 0133 //* frame background color 0134 QColor frameBackgroundColor(const QPalette &palette) const 0135 { 0136 return frameBackgroundColor(palette, palette.currentColorGroup()); 0137 } 0138 0139 //* frame background color 0140 QColor frameBackgroundColor(const QPalette &, QPalette::ColorGroup) const; 0141 0142 //* arrow outline color 0143 QColor arrowColor(const QPalette &, QPalette::ColorGroup, QPalette::ColorRole) const; 0144 0145 //* arrow outline color 0146 QColor arrowColor(const QPalette &palette, QPalette::ColorRole role) const 0147 { 0148 return arrowColor(palette, palette.currentColorGroup(), role); 0149 } 0150 0151 //* arrow outline color, using animations 0152 QColor arrowColor(const QPalette &, bool mouseOver, bool hasFocus, qreal opacity = AnimationData::OpacityInvalid, AnimationMode = AnimationNone) const; 0153 0154 //* slider outline color, using animations 0155 QColor 0156 sliderOutlineColor(const QPalette &, bool mouseOver, bool hasFocus, qreal opacity = AnimationData::OpacityInvalid, AnimationMode = AnimationNone) const; 0157 0158 //* scrollbar handle color, using animations 0159 QColor 0160 scrollBarHandleColor(const QPalette &, bool mouseOver, bool hasFocus, qreal opacity = AnimationData::OpacityInvalid, AnimationMode = AnimationNone) const; 0161 0162 //* checkbox indicator, using animations 0163 QColor 0164 checkBoxIndicatorColor(const QPalette &, bool mouseOver, bool active, qreal opacity = AnimationData::OpacityInvalid, AnimationMode = AnimationNone) const; 0165 0166 //* separator color 0167 QColor separatorColor(const QPalette &) const; 0168 0169 //* merge active and inactive palettes based on ratio, for smooth enable state change transition 0170 QPalette disabledPalette(const QPalette &, qreal ratio) const; 0171 0172 //@} 0173 0174 //*@name rendering utilities 0175 //@{ 0176 0177 //* debug frame 0178 void renderDebugFrame(QPainter *, const QRect &) const; 0179 0180 //* focus rect 0181 void renderFocusRect(QPainter *, const QRect &, const QColor &, const QColor &outline = QColor(), Sides = {}) const; 0182 0183 //* focus line 0184 void renderFocusLine(QPainter *, const QRect &, const QColor &) const; 0185 0186 //* generic frame 0187 void renderFrame(QPainter *, const QRect &, const QColor &color, const QColor &outline = QColor()) const; 0188 0189 //* generic frame, with separators only on the side 0190 void renderFrameWithSides(QPainter *, const QRect &, const QColor &color, Qt::Edges edges, const QColor &outline = QColor()) const; 0191 0192 //* side panel frame 0193 void renderSidePanelFrame(QPainter *, const QRect &, const QColor &outline, Side) const; 0194 0195 //* menu frame 0196 void renderMenuFrame(QPainter *, const QRect &, const QColor &color, const QColor &outline, bool roundCorners = true, bool isTopMenu = false) const; 0197 0198 //* button frame 0199 void renderButtonFrame(QPainter *painter, 0200 const QRect &rect, 0201 const QPalette &palette, 0202 const QHash<QByteArray, bool> &stateProperties, 0203 qreal bgAnimation = AnimationData::OpacityInvalid, 0204 qreal penAnimation = AnimationData::OpacityInvalid) const; 0205 0206 //* toolbutton frame 0207 void renderToolBoxFrame(QPainter *, const QRect &, int tabWidth, const QColor &color) const; 0208 0209 //* tab widget frame 0210 void renderTabWidgetFrame(QPainter *, const QRect &, const QColor &color, const QColor &outline, Corners) const; 0211 0212 //* selection frame 0213 void renderSelection(QPainter *, const QRect &, const QColor &) const; 0214 0215 //* separator 0216 void renderSeparator(QPainter *, const QRect &, const QColor &, bool vertical = false) const; 0217 0218 //* checkbox 0219 void renderCheckBoxBackground(QPainter *, 0220 const QRect &, 0221 const QPalette &palette, 0222 CheckBoxState state, 0223 bool neutalHighlight, 0224 bool sunken, 0225 qreal animation = AnimationData::OpacityInvalid) const; 0226 0227 //* checkbox 0228 void renderCheckBox(QPainter *, 0229 const QRect &, 0230 const QPalette &palette, 0231 bool mouseOver, 0232 CheckBoxState state, 0233 CheckBoxState target, 0234 bool neutalHighlight, 0235 bool sunken, 0236 qreal animation = AnimationData::OpacityInvalid, 0237 qreal hoverAnimation = AnimationData::OpacityInvalid) const; 0238 0239 //* radio button 0240 void renderRadioButtonBackground(QPainter *, 0241 const QRect &, 0242 const QPalette &palette, 0243 RadioButtonState state, 0244 bool neutalHighlight, 0245 bool sunken, 0246 qreal animation = AnimationData::OpacityInvalid) const; 0247 0248 //* radio button 0249 void renderRadioButton(QPainter *, 0250 const QRect &, 0251 const QPalette &palette, 0252 bool mouseOver, 0253 RadioButtonState state, 0254 bool neutalHighlight, 0255 bool sunken, 0256 qreal animation = AnimationData::OpacityInvalid, 0257 qreal hoverAnimation = AnimationData::OpacityInvalid) const; 0258 0259 //* slider groove 0260 void renderSliderGroove(QPainter *, const QRect &, const QColor &) const; 0261 0262 //* slider handle 0263 void renderSliderHandle(QPainter *, const QRect &, const QColor &, const QColor &outline, const QColor &shadow, bool sunken) const; 0264 0265 //* dial groove 0266 void renderDialGroove(QPainter *, const QRect &, const QColor &fg, const QColor &bg, qreal first, qreal last) const; 0267 0268 //* progress bar groove 0269 void renderProgressBarGroove(QPainter *, const QRect &, const QColor &fg, const QColor &bg) const; 0270 0271 //* progress bar contents (animated) 0272 void renderProgressBarBusyContents(QPainter *painter, 0273 const QRect &rect, 0274 const QColor &first, 0275 const QColor &second, 0276 bool horizontal, 0277 bool reverse, 0278 int progress) const; 0279 0280 //* scrollbar groove 0281 void renderScrollBarGroove(QPainter *painter, const QRect &rect, const QColor &color) const; 0282 0283 //* scrollbar handle 0284 void renderScrollBarHandle(QPainter *, const QRect &, const QColor &fg, const QColor &bg) const; 0285 0286 //* separator between scrollbar and contents 0287 void renderScrollBarBorder(QPainter *, const QRect &, const QColor &) const; 0288 0289 //* tabbar tab 0290 void 0291 renderTabBarTab(QPainter *, const QRect &, const QPalette &palette, const QHash<QByteArray, bool> &stateProperties, Corners corners, qreal animation) const; 0292 // TODO(janet): document should be set based on whether or not we consider the 0293 // tab user-editable, but Qt apps often misuse or don't use documentMode property 0294 // so we're currently just always setting it to true for now 0295 0296 //* generic arrow 0297 void renderArrow(QPainter *, const QRect &, const QColor &, ArrowOrientation) const; 0298 0299 //* generic button (for mdi decorations, tabs and dock widgets) 0300 void renderDecorationButton(QPainter *, const QRect &, const QColor &, ButtonType, bool inverted) const; 0301 0302 //* generic shadow for rounded rectangles 0303 void renderRoundedRectShadow(QPainter *, const QRectF &, const QColor &, qreal radius = Metrics::Frame_FrameRadius - PenWidth::Shadow / 2) const; 0304 0305 //* generic shadow for ellipses 0306 void renderEllipseShadow(QPainter *, const QRectF &, const QColor &) const; 0307 0308 //@} 0309 0310 //*@name compositing utilities 0311 //@{ 0312 0313 //* true if style was compiled for and is running on X11 0314 static bool isX11(); 0315 0316 //* true if running on platform Wayland 0317 static bool isWayland(); 0318 0319 //* returns true if compositing is active 0320 bool compositingActive() const; 0321 0322 //* returns true if a given widget supports alpha channel 0323 bool hasAlphaChannel(const QWidget *) const; 0324 0325 //* returns true if the tools area should be drawn 0326 bool shouldDrawToolsArea(const QWidget *) const; 0327 0328 //@} 0329 0330 //* frame radius 0331 constexpr qreal frameRadius(const int penWidth = PenWidth::NoPen, const qreal bias = 0) const 0332 { 0333 return qMax(Metrics::Frame_FrameRadius - (0.5 * penWidth) + bias, 0.0); 0334 } 0335 0336 //* frame radius with new pen width 0337 constexpr qreal frameRadiusForNewPenWidth(const qreal oldRadius, const int penWidth) const 0338 { 0339 return qMax(oldRadius - (0.5 * penWidth), 0.0); 0340 } 0341 0342 //* return a QRectF with the appropriate size for a rectangle with a pen stroke 0343 QRectF strokedRect(const QRectF &rect, const qreal penWidth = PenWidth::Frame) const; 0344 0345 //* return a QRectF with the appropriate size for a rectangle with a shadow around it 0346 QRectF shadowedRect(const QRectF &rect, const qreal shadowSize = PenWidth::Shadow) const 0347 { 0348 return rect.adjusted(shadowSize, shadowSize, -shadowSize, -shadowSize); 0349 } 0350 0351 QPixmap coloredIcon(const QIcon &icon, const QPalette &palette, const QSize &size, QIcon::Mode mode = QIcon::Normal, QIcon::State state = QIcon::Off); 0352 0353 protected: 0354 //* return rounded path in a given rect, with only selected corners rounded, and for a given radius 0355 QPainterPath roundedPath(const QRectF &, Corners, qreal) const; 0356 0357 private: 0358 //* configuration 0359 KSharedConfig::Ptr _config; 0360 0361 //* KWin configuration 0362 KSharedConfig::Ptr _kwinConfig; 0363 0364 //* decoration configuration 0365 QSharedPointer<InternalSettings> _decorationConfig; 0366 0367 //*@name brushes 0368 //@{ 0369 KStatefulBrush _viewFocusBrush; 0370 KStatefulBrush _viewHoverBrush; 0371 KStatefulBrush _buttonFocusBrush; 0372 KStatefulBrush _buttonHoverBrush; 0373 KStatefulBrush _viewNegativeTextBrush; 0374 KStatefulBrush _viewNeutralTextBrush; 0375 //@} 0376 0377 //*@name windeco colors 0378 //@{ 0379 QColor _activeTitleBarColor; 0380 QColor _activeTitleBarTextColor; 0381 QColor _inactiveTitleBarColor; 0382 QColor _inactiveTitleBarTextColor; 0383 //@} 0384 0385 mutable bool _cachedAutoValid = false; 0386 0387 friend class ToolsAreaManager; 0388 }; 0389 0390 } 0391 0392 #endif