File indexing completed on 2024-05-05 05:28:59

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