File indexing completed on 2024-05-05 05:29:54

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