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 "decorationdefines.h"
0009 #include <kdecoration2/kdecoration2_export.h>
0010 
0011 #include <QObject>
0012 #include <QPointer>
0013 #include <QRect>
0014 
0015 class QHoverEvent;
0016 class QMouseEvent;
0017 class QPainter;
0018 class QWheelEvent;
0019 
0020 namespace KDecoration2
0021 {
0022 class DecorationButtonPrivate;
0023 class Decoration;
0024 #ifndef K_DOXYGEN
0025 uint KDECORATIONS2_EXPORT qHash(const DecorationButtonType &type);
0026 #endif
0027 
0028 /**
0029  * @brief A button to be used in a Decoration.
0030  *
0031  * The DecorationButton is a simple Button which can be used (but doesn't have to) in a Decoration.
0032  * It takes care of the input handling and triggers the correct state change methods on the
0033  * Decoration.
0034  *
0035  * This simplifies the handling of DecorationButtons. A Decoration implementation just needs to
0036  * subclass DecorationButton and implement the paint method. Everything else is handled by the
0037  * DecorationButton.
0038  *
0039  * For positioning the DecorationButtons it's recommended to use a DecorationButtonGroup.
0040  *
0041  * @see Decoration
0042  * @see DecorationButtonGroup
0043  **/
0044 class KDECORATIONS2_EXPORT DecorationButton : public QObject
0045 {
0046     Q_OBJECT
0047     /**
0048      * Whether the DecorationButton is visible. By default this is @c true, OnAllDesktops and
0049      * QuickHelp depend on the DecoratedClient's state.
0050      **/
0051     Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibilityChanged)
0052     /**
0053      * Whether the DecorationButton is currently pressed.
0054      **/
0055     Q_PROPERTY(bool pressed READ isPressed NOTIFY pressedChanged)
0056     /**
0057      * Whether the DecorationButton is currently hovered.
0058      **/
0059     Q_PROPERTY(bool hovered READ isHovered NOTIFY hoveredChanged)
0060     /**
0061      * Whether the DecorationButton is enabled. Only an enabled button accepts hover and mouse
0062      * press events.
0063      **/
0064     Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
0065     /**
0066      * Whether the DecorationButton can be checked. This is used for state aware DecorationButtons
0067      * like Maximize, Shade, KeepAbove, KeepBelow and OnAllDesktops.
0068      **/
0069     Q_PROPERTY(bool checkable READ isCheckable WRITE setCheckable NOTIFY checkableChanged)
0070     /**
0071      * Whether the DecorationButton is checked. A DecorationButton can only be checked if the
0072      * DecorationButton is checkable. Note: the checked state is not changed by clicking the
0073      * DecorationButton. It gets changed if the DecoratedClient changes it's state, though.
0074      **/
0075     Q_PROPERTY(bool checked READ isChecked WRITE setChecked NOTIFY checkedChanged)
0076     /**
0077      * The geometry of the DecorationButton in Decoration-local coordinates.
0078      **/
0079     Q_PROPERTY(QRectF geometry READ geometry NOTIFY geometryChanged)
0080     /**
0081      * The mouse buttons the DecorationButton accepts. By default the Qt::LeftButton gets accepted,
0082      * for some types more buttons are accepted.
0083      **/
0084     Q_PROPERTY(Qt::MouseButtons acceptedButtons READ acceptedButtons WRITE setAcceptedButtons NOTIFY acceptedButtonsChanged)
0085 public:
0086     ~DecorationButton() override;
0087 
0088     QRectF geometry() const;
0089     QSizeF size() const;
0090     void setGeometry(const QRectF &geometry);
0091 
0092     bool isVisible() const;
0093     bool isPressed() const;
0094     bool isHovered() const;
0095     bool isEnabled() const;
0096     bool isChecked() const;
0097     bool isCheckable() const;
0098     DecorationButtonType type() const;
0099 
0100     /**
0101      * Returns @c true if @p pos is inside of the button, otherwise returns @c false.
0102      **/
0103     bool contains(const QPointF &pos) const;
0104 
0105     Qt::MouseButtons acceptedButtons() const;
0106     void setAcceptedButtons(Qt::MouseButtons buttons);
0107 
0108     /**
0109      * Invoked for painting this DecorationButtons. Implementing sub-classes need to implement
0110      * this method. The coordinate system of the QPainter is set to Decoration coordinates.
0111      *
0112      * This method will be invoked from the rendering thread.
0113      *
0114      * @param painter The QPainter to paint this DecorationButton.
0115      * @param repaintArea The area which is going to be repainted in Decoration coordinates
0116      **/
0117     virtual void paint(QPainter *painter, const QRect &repaintArea) = 0;
0118 
0119     QPointer<Decoration> decoration() const;
0120 
0121     bool event(QEvent *event) override;
0122 
0123 public Q_SLOTS:
0124     void setEnabled(bool enabled);
0125     void setCheckable(bool checkable);
0126     void setChecked(bool checked);
0127     void setVisible(bool visible);
0128 
0129     /**
0130      * Schedules a repaint of the DecorationButton.
0131      * Calling update will eventually result in paint being invoked.
0132      *
0133      * @param rect The area to repaint in Decoration local coordinates, a null QRect updates the complete geometry
0134      * @see paint
0135      **/
0136     void update(const QRectF &rect);
0137     /**
0138      * Schedules a repaint of the DecorationButton.
0139      *
0140      * Overloaded method for convenience.
0141      **/
0142     void update();
0143 
0144 Q_SIGNALS:
0145     void clicked(Qt::MouseButton);
0146     void pressed();
0147     void released();
0148     void pointerEntered();
0149     void pointerLeft();
0150     void doubleClicked();
0151 
0152     void pressedChanged(bool);
0153     void hoveredChanged(bool);
0154     void enabledChanged(bool);
0155     void checkableChanged(bool);
0156     void checkedChanged(bool);
0157     void geometryChanged(const QRectF &);
0158     void acceptedButtonsChanged(Qt::MouseButtons);
0159     void visibilityChanged(bool);
0160 
0161 protected:
0162     explicit DecorationButton(DecorationButtonType type, const QPointer<Decoration> &decoration, QObject *parent = nullptr);
0163 
0164     virtual void hoverEnterEvent(QHoverEvent *event);
0165     virtual void hoverLeaveEvent(QHoverEvent *event);
0166     virtual void hoverMoveEvent(QHoverEvent *event);
0167     virtual void mouseMoveEvent(QMouseEvent *event);
0168     virtual void mousePressEvent(QMouseEvent *event);
0169     virtual void mouseReleaseEvent(QMouseEvent *event);
0170     virtual void wheelEvent(QWheelEvent *event);
0171 
0172 private:
0173     class Private;
0174     QScopedPointer<Private> d;
0175 };
0176 
0177 } // namespace
0178 Q_DECLARE_METATYPE(KDecoration2::DecorationButtonType)