File indexing completed on 2024-05-12 16:58:23
0001 #ifndef BREEZE_DECORATION_H 0002 #define BREEZE_DECORATION_H 0003 0004 /* 0005 * SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org> 0006 * SPDX-FileCopyrightText: 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr> 0007 * 0008 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0009 */ 0010 0011 #include "breeze.h" 0012 #include "breezesettings.h" 0013 0014 #include <KDecoration2/DecoratedClient> 0015 #include <KDecoration2/Decoration> 0016 #include <KDecoration2/DecorationSettings> 0017 0018 #include <QPalette> 0019 #include <QVariant> 0020 #include <QVariantAnimation> 0021 0022 namespace KDecoration2 0023 { 0024 class DecorationButton; 0025 class DecorationButtonGroup; 0026 } 0027 0028 namespace Breeze 0029 { 0030 class Decoration : public KDecoration2::Decoration 0031 { 0032 Q_OBJECT 0033 0034 public: 0035 //* constructor 0036 explicit Decoration(QObject *parent = nullptr, const QVariantList &args = QVariantList()); 0037 0038 //* destructor 0039 virtual ~Decoration(); 0040 0041 //* paint 0042 void paint(QPainter *painter, const QRect &repaintRegion) override; 0043 0044 //* internal settings 0045 InternalSettingsPtr internalSettings() const 0046 { 0047 return m_internalSettings; 0048 } 0049 0050 qreal animationsDuration() const 0051 { 0052 return m_animation->duration(); 0053 } 0054 0055 //* caption height 0056 int captionHeight() const; 0057 0058 //* button height 0059 int buttonHeight() const; 0060 0061 //*@name active state change animation 0062 //@{ 0063 void setOpacity(qreal); 0064 0065 qreal opacity() const 0066 { 0067 return m_opacity; 0068 } 0069 0070 //@} 0071 0072 //*@name colors 0073 //@{ 0074 QColor titleBarColor() const; 0075 QColor fontColor() const; 0076 //@} 0077 0078 //*@name maximization modes 0079 //@{ 0080 inline bool isMaximized() const; 0081 inline bool isMaximizedHorizontally() const; 0082 inline bool isMaximizedVertically() const; 0083 0084 inline bool isLeftEdge() const; 0085 inline bool isRightEdge() const; 0086 inline bool isTopEdge() const; 0087 inline bool isBottomEdge() const; 0088 0089 inline bool hideTitleBar() const; 0090 //@} 0091 0092 public Q_SLOTS: 0093 void init() override; 0094 0095 private Q_SLOTS: 0096 void reconfigure(); 0097 void recalculateBorders(); 0098 void updateButtonsGeometry(); 0099 void updateButtonsGeometryDelayed(); 0100 void updateTitleBar(); 0101 void updateAnimationState(); 0102 void onTabletModeChanged(bool mode); 0103 0104 private: 0105 //* return the rect in which caption will be drawn 0106 QPair<QRect, Qt::Alignment> captionRect() const; 0107 0108 void createButtons(); 0109 void paintTitleBar(QPainter *painter, const QRect &repaintRegion); 0110 void updateShadow(); 0111 QSharedPointer<KDecoration2::DecorationShadow> createShadowObject(const float strengthScale, const QColor &outlineColor); 0112 void setScaledCornerRadius(); 0113 0114 //*@name border size 0115 //@{ 0116 int borderSize(bool bottom = false) const; 0117 inline bool hasBorders() const; 0118 inline bool hasNoBorders() const; 0119 inline bool hasNoSideBorders() const; 0120 //@} 0121 0122 InternalSettingsPtr m_internalSettings; 0123 KDecoration2::DecorationButtonGroup *m_leftButtons = nullptr; 0124 KDecoration2::DecorationButtonGroup *m_rightButtons = nullptr; 0125 0126 //* active state change animation 0127 QVariantAnimation *m_animation; 0128 QVariantAnimation *m_shadowAnimation; 0129 0130 //* active state change opacity 0131 qreal m_opacity = 0; 0132 qreal m_shadowOpacity = 0; 0133 0134 //*frame corner radius, scaled according to DPI 0135 qreal m_scaledCornerRadius = 3; 0136 0137 bool m_tabletMode = false; 0138 }; 0139 0140 bool Decoration::hasBorders() const 0141 { 0142 if (m_internalSettings && m_internalSettings->mask() & BorderSize) { 0143 return m_internalSettings->borderSize() > InternalSettings::BorderNoSides; 0144 } else { 0145 return settings()->borderSize() > KDecoration2::BorderSize::NoSides; 0146 } 0147 } 0148 0149 bool Decoration::hasNoBorders() const 0150 { 0151 if (m_internalSettings && m_internalSettings->mask() & BorderSize) { 0152 return m_internalSettings->borderSize() == InternalSettings::BorderNone; 0153 } else { 0154 return settings()->borderSize() == KDecoration2::BorderSize::None; 0155 } 0156 } 0157 0158 bool Decoration::hasNoSideBorders() const 0159 { 0160 if (m_internalSettings && m_internalSettings->mask() & BorderSize) { 0161 return m_internalSettings->borderSize() == InternalSettings::BorderNoSides; 0162 } else { 0163 return settings()->borderSize() == KDecoration2::BorderSize::NoSides; 0164 } 0165 } 0166 0167 bool Decoration::isMaximized() const 0168 { 0169 return client().toStrongRef()->isMaximized() && !m_internalSettings->drawBorderOnMaximizedWindows(); 0170 } 0171 0172 bool Decoration::isMaximizedHorizontally() const 0173 { 0174 return client().toStrongRef()->isMaximizedHorizontally() && !m_internalSettings->drawBorderOnMaximizedWindows(); 0175 } 0176 0177 bool Decoration::isMaximizedVertically() const 0178 { 0179 return client().toStrongRef()->isMaximizedVertically() && !m_internalSettings->drawBorderOnMaximizedWindows(); 0180 } 0181 0182 bool Decoration::isLeftEdge() const 0183 { 0184 const auto c = client().toStrongRef(); 0185 return (c->isMaximizedHorizontally() || c->adjacentScreenEdges().testFlag(Qt::LeftEdge)) && !m_internalSettings->drawBorderOnMaximizedWindows(); 0186 } 0187 0188 bool Decoration::isRightEdge() const 0189 { 0190 const auto c = client().toStrongRef(); 0191 return (c->isMaximizedHorizontally() || c->adjacentScreenEdges().testFlag(Qt::RightEdge)) && !m_internalSettings->drawBorderOnMaximizedWindows(); 0192 } 0193 0194 bool Decoration::isTopEdge() const 0195 { 0196 const auto c = client().toStrongRef(); 0197 return (c->isMaximizedVertically() || c->adjacentScreenEdges().testFlag(Qt::TopEdge)) && !m_internalSettings->drawBorderOnMaximizedWindows(); 0198 } 0199 0200 bool Decoration::isBottomEdge() const 0201 { 0202 const auto c = client().toStrongRef(); 0203 return (c->isMaximizedVertically() || c->adjacentScreenEdges().testFlag(Qt::BottomEdge)) && !m_internalSettings->drawBorderOnMaximizedWindows(); 0204 } 0205 0206 bool Decoration::hideTitleBar() const 0207 { 0208 return m_internalSettings->hideTitleBar() && !client().toStrongRef()->isShaded(); 0209 } 0210 0211 } 0212 0213 #endif