File indexing completed on 2024-04-28 16:44:34

0001 /*
0002  * SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005  */
0006 #pragma once
0007 
0008 #include <kdecoration2/kdecoration2_export.h>
0009 
0010 #include <QImage>
0011 #include <QMargins>
0012 #include <QObject>
0013 
0014 namespace KDecoration2
0015 {
0016 class DecorationShadowPrivate;
0017 
0018 /**
0019  * @brief A wrapper to define the shadow around the Decoration.
0020  *
0021  * The shadow around the Decoration should not be rendered as part of the Decoration.
0022  * Instead a DecorationShadow should be used. That way a backend can optimize the
0023  * rendering of the shadow in a better way. If the shadow were part of the Decoration
0024  * directly it would need to be updated when the rendering changes. By using a dedicated
0025  * DecorationShadow the same shadow can be shared between multiple DecoratedClients.
0026  *
0027  * The DecorationShadow consists of a shadow QImage which is composed of multiple parts:
0028  * @li topLeft: rendered as it is
0029  * @li top: stretched in x direction
0030  * @li topRight: rendered as it is
0031  * @li right: stretched in y direction
0032  * @li bottomRight: rendered as it is
0033  * @li bottom: stretched in x direction
0034  * @li bottomLeft: rendered as it is
0035  * @li left: stretched in y direction
0036  *
0037  * The sizes of these parts is denoted in the property innerShadowRect and the layout is the
0038  * following:
0039  * #######################################
0040  * # topLeft #     top        # topRight #
0041  * #######################################
0042  * # left #                      # right #
0043  * #######################################
0044  * # bottomLeft #  bottom  # bottomRight #
0045  * #######################################
0046  *
0047  * The innerShadowRect property is a QRect of the geometry of the areas not covered by any of the
0048  * elements. This means that:
0049  * @li x/y of the rect is the same as the size of the topLeft element
0050  * @li width of the rect is the same as the width of the top and bottom element
0051  * @li height of the rect is the same as the height of the left and the right element
0052  * By that the actual sizes of all elements can be derived out of the size of the shadow image
0053  * and the innerShadowRect.
0054  *
0055  * The position of the rendering depends on the values;
0056  * @li paddingTop
0057  * @li paddingRight
0058  * @li paddingBottom
0059  * @li paddingLeft
0060  *
0061  * The top left element is rendered with an offset of paddingLeft and paddingTop.
0062  * The non-stretched elements are rendered in the size as specified, the area
0063  * between two non-stretched elements (e.g. between topLeft and topRight) is filled
0064  * by the element with one direction stretched and the other direction fixed at the
0065  * corresponding padding value. E.g. the top element is stretched in x direction and
0066  * fixed at paddingTop value. If stretching the side elements is not wanted one needs
0067  * to provide a shadow image with those elements at a size that stretching is not
0068  * required.
0069  *
0070  * If the padding values are smaller than the sizes of the shadow elements the shadow
0071  * will overlap with the Decoration and be rendered behind the Decoration.
0072  *
0073  **/
0074 class KDECORATIONS2_EXPORT DecorationShadow : public QObject
0075 {
0076     Q_OBJECT
0077     Q_PROPERTY(QImage shadow READ shadow WRITE setShadow NOTIFY shadowChanged)
0078     Q_PROPERTY(QRect innerShadowRect READ innerShadowRect WRITE setInnerShadowRect NOTIFY innerShadowRectChanged)
0079     Q_PROPERTY(QRect topLeftGeometry READ topLeftGeometry NOTIFY innerShadowRectChanged)
0080     Q_PROPERTY(QRect topGeometry READ topGeometry NOTIFY innerShadowRectChanged)
0081     Q_PROPERTY(QRect topRightGeometry READ topRightGeometry NOTIFY innerShadowRectChanged)
0082     Q_PROPERTY(QRect rightGeometry READ rightGeometry NOTIFY innerShadowRectChanged)
0083     Q_PROPERTY(QRect bottomRightGeometry READ bottomRightGeometry NOTIFY innerShadowRectChanged)
0084     Q_PROPERTY(QRect bottomGeometry READ bottomGeometry NOTIFY innerShadowRectChanged)
0085     Q_PROPERTY(QRect bottomLeftGeometry READ bottomLeftGeometry NOTIFY innerShadowRectChanged)
0086     Q_PROPERTY(QRect leftGeometry READ leftGeometry NOTIFY innerShadowRectChanged)
0087     Q_PROPERTY(int paddingTop READ paddingTop NOTIFY paddingChanged)
0088     Q_PROPERTY(int paddingRight READ paddingRight NOTIFY paddingChanged)
0089     Q_PROPERTY(int paddingBottom READ paddingBottom NOTIFY paddingChanged)
0090     Q_PROPERTY(int paddingLeft READ paddingLeft NOTIFY paddingChanged)
0091     Q_PROPERTY(QMargins padding READ padding WRITE setPadding NOTIFY paddingChanged)
0092 public:
0093     explicit DecorationShadow();
0094     ~DecorationShadow() override;
0095 
0096     QImage shadow() const;
0097     QRect innerShadowRect() const;
0098     QRect topLeftGeometry() const;
0099     QRect topGeometry() const;
0100     QRect topRightGeometry() const;
0101     QRect rightGeometry() const;
0102     QRect bottomRightGeometry() const;
0103     QRect bottomGeometry() const;
0104     QRect bottomLeftGeometry() const;
0105     QRect leftGeometry() const;
0106     int paddingTop() const;
0107     int paddingRight() const;
0108     int paddingBottom() const;
0109     int paddingLeft() const;
0110     QMargins padding() const;
0111 
0112     void setShadow(const QImage &image);
0113     void setInnerShadowRect(const QRect &rect);
0114     void setPadding(const QMargins &margins);
0115 
0116 Q_SIGNALS:
0117     void shadowChanged(const QImage &);
0118     void innerShadowRectChanged();
0119     void paddingChanged();
0120 
0121 private:
0122     class Private;
0123     QScopedPointer<Private> d;
0124 };
0125 
0126 }
0127 
0128 Q_DECLARE_METATYPE(KDecoration2::DecorationShadow *)