| 1 | /* |
| 2 | * SPDX-FileCopyrightText: 2023 ivan tkachenko <me@ratijas.tk> |
| 3 | * |
| 4 | * SPDX-License-Identifier: LGPL-2.0-or-later |
| 5 | */ |
| 6 | |
| 7 | #ifndef OVERLAYZSTACKINGATTACHED_H |
| 8 | #define OVERLAYZSTACKINGATTACHED_H |
| 9 | |
| 10 | #include <QObject> |
| 11 | #include <QQmlEngine> |
| 12 | |
| 13 | #include <qqmlregistration.h> |
| 14 | |
| 15 | class QQuickItem; |
| 16 | |
| 17 | /*! |
| 18 | * \qmltype OverlayZStacking |
| 19 | * \inqmlmodule org.kde.kirigami |
| 20 | * |
| 21 | * \brief An attached property that manages z-index for stacking overlays relative to each other. |
| 22 | * |
| 23 | * When a popup is about to show, OverlayZStacking object kicks in, searches for the |
| 24 | * next nearest popup in the QtQuick hierarchy of items, and sets its z value to the |
| 25 | * biggest of two: current stacking value for its layer, or parent's z index + 1. |
| 26 | * |
| 27 | * This way OverlayZStacking algorithm ensures that a popup is always stacked higher |
| 28 | * than its logical parent popup, but also no lower than its siblings on the same |
| 29 | * logical layer. |
| 30 | * |
| 31 | * \code |
| 32 | * import QtQuick.Controls as QQC2 |
| 33 | * import org.kde.kirigami as Kirigami |
| 34 | * |
| 35 | * QQC2.Popup { |
| 36 | * Kirigami.OverlayZStacking.layer: Kirigami.OverlayZStacking.ToolTip |
| 37 | * z: Kirigami.OverlayZStacking.z |
| 38 | * } |
| 39 | * \endcode |
| 40 | * |
| 41 | * \since 6.0 |
| 42 | */ |
| 43 | class OverlayZStackingAttached : public QObject |
| 44 | { |
| 45 | Q_OBJECT |
| 46 | QML_ELEMENT |
| 47 | QML_NAMED_ELEMENT(OverlayZStacking) |
| 48 | QML_UNCREATABLE("Cannot create objects of type OverlayZStacking, use it as an attached property" ) |
| 49 | QML_ATTACHED(OverlayZStackingAttached) |
| 50 | /*! |
| 51 | * \qmlattachedproperty real OverlayZStacking::z |
| 52 | * |
| 53 | * An optimal z-index that attachee popup should bind to. |
| 54 | */ |
| 55 | Q_PROPERTY(qreal z READ z NOTIFY zChanged FINAL) |
| 56 | |
| 57 | /*! |
| 58 | * \qmlattachedproperty enumeration OverlayZStacking::layer |
| 59 | * |
| 60 | * \qmlenumeratorsfrom OverlayZStackingAttached::Layer |
| 61 | * |
| 62 | * The logical stacking layer of attachee popup, akin to window manager's layers. |
| 63 | */ |
| 64 | Q_PROPERTY(Layer layer READ layer WRITE setLayer NOTIFY layerChanged FINAL) |
| 65 | |
| 66 | public: |
| 67 | /*! |
| 68 | * \value DefaultLowest |
| 69 | * \value Drawer |
| 70 | * \value FullScreen |
| 71 | * \value Dialog |
| 72 | * \value Menu |
| 73 | * \value Notification |
| 74 | * \value ToolTip |
| 75 | */ |
| 76 | enum Layer { |
| 77 | DefaultLowest = 0, |
| 78 | Drawer, |
| 79 | FullScreen, |
| 80 | Dialog, |
| 81 | , |
| 82 | Notification, |
| 83 | ToolTip, |
| 84 | }; |
| 85 | Q_ENUM(Layer) |
| 86 | |
| 87 | explicit OverlayZStackingAttached(QObject *parent = nullptr); |
| 88 | ~OverlayZStackingAttached() override; |
| 89 | |
| 90 | qreal z() const; |
| 91 | |
| 92 | Layer layer() const; |
| 93 | void setLayer(Layer layer); |
| 94 | |
| 95 | // QML attached property |
| 96 | static OverlayZStackingAttached *qmlAttachedProperties(QObject *object); |
| 97 | |
| 98 | Q_SIGNALS: |
| 99 | void zChanged(); |
| 100 | void layerChanged(); |
| 101 | |
| 102 | private Q_SLOTS: |
| 103 | // Popup shall not change z index while being open, so if changes arrive, we defer it until closed. |
| 104 | void enqueueSignal(); |
| 105 | void dispatchPendingSignal(); |
| 106 | |
| 107 | void (); |
| 108 | |
| 109 | private: |
| 110 | void (); |
| 111 | void (QObject *); |
| 112 | qreal () const; |
| 113 | static bool isVisible(const QObject *); |
| 114 | static bool (const QObject *object); |
| 115 | static QObject *(const QObject *); |
| 116 | static QQuickItem *(const QObject *); |
| 117 | static Layer (const QObject *); |
| 118 | static qreal defaultZForLayer(Layer layer); |
| 119 | |
| 120 | Layer m_layer = Layer::DefaultLowest; |
| 121 | QPointer<QObject> ; |
| 122 | bool m_pending; |
| 123 | }; |
| 124 | |
| 125 | QML_DECLARE_TYPEINFO(OverlayZStackingAttached, QML_HAS_ATTACHED_PROPERTIES) |
| 126 | |
| 127 | #endif // OVERLAYZSTACKINGATTACHED_H |
| 128 | |