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 #include "decorationbutton.h"
0008 #include <functional>
0009 #include <kdecoration2/kdecoration2_export.h>
0010 
0011 class QPainter;
0012 
0013 namespace KDecoration2
0014 {
0015 class Decoration;
0016 class DecorationButtonGroupPrivate;
0017 
0018 /**
0019  * @brief Helper class to layout DecorationButton.
0020  *
0021  * A Decoration normally has two groups of DecorationButtons: one left of the caption and one
0022  * right of the caption. The DecorationButtonGroup helps in positioning the DecorationButtons in
0023  * these groups and to update the position of each of the DecorationButtons whenever the state
0024  * changes in a way that they should be repositioned.
0025  *
0026  * A DecorationButtonGroup is a visual layout element not accepting input events. As a visual
0027  * element it provides a paint method allowing a sub class to provide custom painting for the
0028  * DecorationButtonGroup.
0029  **/
0030 class KDECORATIONS2_EXPORT DecorationButtonGroup : public QObject
0031 {
0032     Q_OBJECT
0033     /**
0034      * The spacing to use between the DecorationButtons
0035      **/
0036     Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing NOTIFY spacingChanged)
0037     /**
0038      * The geometry of the DecorationButtonGroup in Decoration-local coordinates.
0039      * The size of the DecorationButtonGroup depends on the sizes of the individual
0040      * DecorationButtons and the spacing.
0041      **/
0042     Q_PROPERTY(QRectF geometry READ geometry NOTIFY geometryChanged)
0043     // TODO: pos must consider whether it's left or right
0044     /**
0045      * The top left Position of the DecorationButtonGroup. This property needs to be
0046      * changed to reposition the DecorationButtonGroup. An update should normally be
0047      * triggered after e.g. a state change like maximization.
0048      **/
0049     Q_PROPERTY(QPointF pos READ pos WRITE setPos NOTIFY posChanged)
0050 public:
0051     enum class Position {
0052         Left,
0053         Right,
0054     };
0055     explicit DecorationButtonGroup(Position type,
0056                                    Decoration *parent,
0057                                    std::function<DecorationButton *(DecorationButtonType, Decoration *, QObject *)> buttonCreator);
0058     explicit DecorationButtonGroup(Decoration *parent);
0059     ~DecorationButtonGroup() override;
0060 
0061     /**
0062      * Paints the DecorationButtonGroup. This method should normally be invoked from the
0063      * Decoration's paint method. Base implementation just calls the paint method on each
0064      * of the DecorationButtons. Overwriting sub classes need to either call the base
0065      * implementation or ensure that the DecorationButtons are painted.
0066      *
0067      * @param painter The QPainter which is used to paint this DecorationButtonGroup
0068      * @param repaintArea The area which is going to be repainted in Decoration coordinates
0069      **/
0070     virtual void paint(QPainter *painter, const QRect &repaintArea);
0071 
0072     QPointer<Decoration> decoration() const;
0073 
0074     qreal spacing() const;
0075     void setSpacing(qreal spacing);
0076 
0077     QRectF geometry() const;
0078     QPointF pos() const;
0079     void setPos(const QPointF &pos);
0080 
0081     /**
0082      * Adds @p button to the DecorationButtonGroup and triggers a re-layout of all
0083      * DecorationButtons.
0084      **/
0085     void addButton(const QPointer<DecorationButton> &button);
0086     /**
0087      * Removes @p button from the DecorationButtonGroup and triggers a re-layout of all
0088      * DecorationButtons.
0089      **/
0090     void removeButton(const QPointer<DecorationButton> &button);
0091     /**
0092      * Removes all DecorationButtons with @p type from the DecorationButtonGroup and
0093      * triggers a re-layout of all DecorationButtons.
0094      **/
0095     void removeButton(DecorationButtonType type);
0096     /**
0097      * @returns @c true if the DecorationButtonGroup contains a DecorationButton of @p type
0098      **/
0099     bool hasButton(DecorationButtonType type) const;
0100     /**
0101      * @returns All DecorationButtons in this DecorationButtonGroup
0102      **/
0103     QVector<QPointer<DecorationButton>> buttons() const;
0104 
0105 Q_SIGNALS:
0106     void spacingChanged(qreal);
0107     void geometryChanged(const QRectF &);
0108     void posChanged(const QPointF &);
0109 
0110 private:
0111     class Private;
0112     QScopedPointer<Private> d;
0113 };
0114 
0115 } // namespace