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