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

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 "decorationshadow.h"
0009 #include <kdecoration2/kdecoration2_export.h>
0010 
0011 #include <QMargins>
0012 #include <QObject>
0013 #include <QPointer>
0014 #include <QRect>
0015 
0016 class QHoverEvent;
0017 class QMouseEvent;
0018 class QPainter;
0019 class QWheelEvent;
0020 
0021 /**
0022  * @brief Framework for creating window decorations.
0023  *
0024  **/
0025 namespace KDecoration2
0026 {
0027 class DecorationPrivate;
0028 class DecoratedClient;
0029 class DecorationButton;
0030 class DecorationSettings;
0031 
0032 /**
0033  * @brief Base class for the Decoration.
0034  *
0035  * To provide a Decoration one needs to inherit from this class. The framework will instantiate
0036  * an instance of the inherited class for each DecoratedClient.
0037  *
0038  * The main tasks of the Decoration is to provide borders around the DecoratedClient. For this
0039  * the Deocration provides border sizes: those should be adjusted depending on the state of the
0040  * DecoratedClient. E.g. commonly a maximized DecoratedClient does not have borders on the side,
0041  * only the title bar.
0042  *
0043  * Whenever the visual representation of the Decoration changes the slot @link Decoration::update @endlink
0044  * should be invoked to request a repaint. The framework will in return invoke the
0045  * @link Decoration::paint @endlink method. This method needs to be implemented by inheriting
0046  * classes.
0047  *
0048  * A Decoration commonly provides buttons for interaction. E.g. a close button to close the
0049  * DecoratedClient. For such actions the Decoration provides slots which should be connected to
0050  * the clicked signals of the buttons. For convenience the framework provides the @link DecorationButton @endlink
0051  * and the @link DecorationButtonGroup @endlink for easier layout. It is not required to use those,
0052  * if one uses different ways to represent the actions one needs to filter the events accordingly.
0053  *
0054  * @see DecoratedClient
0055  * @see DecorationButton
0056  * @see DecorationButtonGroup
0057  **/
0058 class KDECORATIONS2_EXPORT Decoration : public QObject
0059 {
0060     Q_OBJECT
0061     Q_PROPERTY(QMargins borders READ borders NOTIFY bordersChanged)
0062     Q_PROPERTY(int borderLeft READ borderLeft NOTIFY bordersChanged)
0063     Q_PROPERTY(int borderRight READ borderRight NOTIFY bordersChanged)
0064     Q_PROPERTY(int borderTop READ borderTop NOTIFY bordersChanged)
0065     Q_PROPERTY(int borderBottom READ borderBottom NOTIFY bordersChanged)
0066     Q_PROPERTY(QMargins resizeOnlyBorders READ resizeOnlyBorders NOTIFY resizeOnlyBordersChanged)
0067     Q_PROPERTY(int resizeOnlyBorderLeft READ resizeOnlyBorderLeft NOTIFY resizeOnlyBordersChanged)
0068     Q_PROPERTY(int resizeOnlyBorderRight READ resizeOnlyBorderRight NOTIFY resizeOnlyBordersChanged)
0069     Q_PROPERTY(int resizeOnlyBorderTop READ resizeOnlyBorderTop NOTIFY resizeOnlyBordersChanged)
0070     Q_PROPERTY(int resizeOnlyBorderBottom READ resizeOnlyBorderBottom NOTIFY resizeOnlyBordersChanged)
0071     /**
0072      * This property denotes the part of the Decoration which is currently under the mouse pointer.
0073      * It gets automatically updated whenever a QMouseEvent or QHoverEvent gets processed.
0074      **/
0075     Q_PROPERTY(Qt::WindowFrameSection sectionUnderMouse READ sectionUnderMouse NOTIFY sectionUnderMouseChanged)
0076     /**
0077      * The titleBar is the area inside the Decoration containing all controls (e.g. Buttons)
0078      * and the caption. The titleBar is the main interaction area, while all other areas of the
0079      * Decoration are normally used as resize areas.
0080      **/
0081     Q_PROPERTY(QRect titleBar READ titleBar NOTIFY titleBarChanged)
0082     /**
0083      * Whether the Decoration is fully opaque. By default a Decoration is considered to
0084      * use the alpha channel and this property has the value @c false. But for e.g. a maximized
0085      * DecoratedClient it is possible that the Decoration is fully opaque. In this case the
0086      * Decoration should set this property to @c true.
0087      **/
0088     Q_PROPERTY(bool opaque READ isOpaque NOTIFY opaqueChanged)
0089 public:
0090     ~Decoration() override;
0091 
0092     /**
0093      * The DecoratedClient for this Decoration.
0094      * As long as the Decoration is alive it is guaranteed that the object is not
0095      * deleted. Thus it is save to access using QWeakPointer::data in e.g. a sublcass
0096      * of Decoration without promoting to QSharedPointer.
0097      **/
0098     QWeakPointer<DecoratedClient> client() const;
0099 
0100     QMargins borders() const;
0101     int borderLeft() const;
0102     int borderRight() const;
0103     int borderTop() const;
0104     int borderBottom() const;
0105     QMargins resizeOnlyBorders() const;
0106     int resizeOnlyBorderLeft() const;
0107     int resizeOnlyBorderRight() const;
0108     int resizeOnlyBorderTop() const;
0109     int resizeOnlyBorderBottom() const;
0110     Qt::WindowFrameSection sectionUnderMouse() const;
0111     QRect titleBar() const;
0112     bool isOpaque() const;
0113 
0114     /**
0115      * DecorationShadow for this Decoration. It is recommended that multiple Decorations share
0116      * the same DecorationShadow. E.g one DecorationShadow for all inactive Decorations and one
0117      * for the active Decoration.
0118      **/
0119     QSharedPointer<DecorationShadow> shadow() const;
0120 
0121     /**
0122      * The decoration's geometry in local coordinates.
0123      *
0124      * Basically the size of the DecoratedClient combined with the borders.
0125      **/
0126     QRect rect() const;
0127     QSize size() const;
0128 
0129     /**
0130      * The decoration's blur region in local coordinates
0131      */
0132     QRegion blurRegion() const;
0133 
0134     /**
0135      * Invoked by the framework to set the Settings for this Decoration before
0136      * init is invoked.
0137      * @internal
0138      **/
0139     void setSettings(const QSharedPointer<DecorationSettings> &settings);
0140     /**
0141      * @returns The DecorationSettings used for this Decoration.
0142      **/
0143     QSharedPointer<DecorationSettings> settings() const;
0144 
0145     /**
0146      * Implement this method in inheriting classes to provide the rendering.
0147      *
0148      * The @p painter is set up to paint on an internal QPaintDevice. The painting is
0149      * implicitly double buffered.
0150      *
0151      * @param painter The painter which needs to be used for rendering
0152      * @param repaintArea The region which needs to be repainted.
0153      **/
0154     virtual void paint(QPainter *painter, const QRect &repaintArea) = 0;
0155 
0156     bool event(QEvent *event) override;
0157 
0158 public Q_SLOTS:
0159     void requestClose();
0160     void requestToggleMaximization(Qt::MouseButtons buttons);
0161     void requestMinimize();
0162     void requestContextHelp();
0163     void requestToggleOnAllDesktops();
0164     void requestToggleShade();
0165     void requestToggleKeepAbove();
0166     void requestToggleKeepBelow();
0167 
0168 #if KDECORATIONS2_ENABLE_DEPRECATED_SINCE(5, 21)
0169     /**
0170      * @deprecated
0171      * @see requestShowWindowMenu(const QRect &rect)
0172      */
0173     KDECORATIONS2_DEPRECATED_VERSION(5, 21, "Use Decoration::requestShowWindowMenu(QRect)")
0174     void requestShowWindowMenu();
0175 #endif
0176 
0177     /**
0178      * @param rect the location at which to show the window menu
0179      */
0180     void requestShowWindowMenu(const QRect &rect);
0181     void requestShowToolTip(const QString &text);
0182     void requestHideToolTip();
0183 
0184     void showApplicationMenu(int actionId);
0185     void requestShowApplicationMenu(const QRect &rect, int actionId);
0186 
0187     void update(const QRect &rect);
0188     void update();
0189 
0190     /**
0191      * This method gets invoked from the framework once the Decoration is created and
0192      * completely setup.
0193      *
0194      * An inheriting class should override this method and perform all initialization in
0195      * this method instead of the constructor.
0196      **/
0197     virtual void init();
0198 
0199 Q_SIGNALS:
0200     void blurRegionChanged();
0201     void bordersChanged();
0202     void resizeOnlyBordersChanged();
0203     void sectionUnderMouseChanged(Qt::WindowFrameSection);
0204     void titleBarChanged();
0205     void opaqueChanged(bool);
0206     void shadowChanged(const QSharedPointer<DecorationShadow> &shadow);
0207     void damaged(const QRegion &region);
0208 
0209 protected:
0210     /**
0211      * Constructor for the Decoration.
0212      *
0213      * The @p args are used by the decoration framework to pass meta information
0214      * to the Decoration. An inheriting class is supposed to pass the args to the
0215      * parent class.
0216      *
0217      * @param parent The parent of the Decoration
0218      * @param args Additional arguments passed in from the framework
0219      **/
0220     explicit Decoration(QObject *parent, const QVariantList &args);
0221     void setBorders(const QMargins &borders);
0222     void setResizeOnlyBorders(const QMargins &borders);
0223     void setBlurRegion(const QRegion &region);
0224     /**
0225      * An implementation has to invoke this method whenever the area
0226      * containing the controls and caption changes.
0227      * @param rect The new geometry of the titleBar in Decoration coordinates
0228      **/
0229     void setTitleBar(const QRect &rect);
0230     void setOpaque(bool opaque);
0231     void setShadow(const QSharedPointer<DecorationShadow> &shadow);
0232 
0233     virtual void hoverEnterEvent(QHoverEvent *event);
0234     virtual void hoverLeaveEvent(QHoverEvent *event);
0235     virtual void hoverMoveEvent(QHoverEvent *event);
0236     virtual void mouseMoveEvent(QMouseEvent *event);
0237     virtual void mousePressEvent(QMouseEvent *event);
0238     virtual void mouseReleaseEvent(QMouseEvent *event);
0239     virtual void wheelEvent(QWheelEvent *event);
0240 
0241 private:
0242     friend class DecorationButton;
0243     class Private;
0244     QScopedPointer<Private> d;
0245 };
0246 
0247 } // namespace
0248 
0249 Q_DECLARE_METATYPE(KDecoration2::Decoration *)