Files
RedBear-OS/local/recipes/kde/kirigami/source/src/overlayzstackingattached.h
T
2026-04-14 10:51:06 +01:00

109 lines
3.1 KiB
C++

/*
* SPDX-FileCopyrightText: 2023 ivan tkachenko <me@ratijas.tk>
*
* SPDX-License-Identifier: LGPL-2.0-or-later
*/
#ifndef OVERLAYZSTACKINGATTACHED_H
#define OVERLAYZSTACKINGATTACHED_H
#include <QObject>
#include <QQmlEngine>
#include <qqmlregistration.h>
class QQuickItem;
/**
* This attached property manages z-index for stacking overlays relative to each other.
*
* When a popup is about to show, OverlayZStacking object kicks in, searches for the
* next nearest popup in the QtQuick hierarchy of items, and sets its z value to the
* biggest of two: current stacking value for its layer, or parent's z index + 1.
* This way OverlayZStacking algorithm ensures that a popup is always stacked higher
* than its logical parent popup, but also no lower than its siblings on the same
* logical layer.
*
* @code
* import QtQuick.Controls as QQC2
* import org.kde.kirigami as Kirigami
*
* QQC2.Popup {
* Kirigami.OverlayZStacking.layer: Kirigami.OverlayZStacking.ToolTip
* z: Kirigami.OverlayZStacking.z
* }
* @endcode
*
* @since 6.0
*/
class OverlayZStackingAttached : public QObject
{
Q_OBJECT
QML_ELEMENT_OFF_OFF_OFF_OFF_OFF_OFF
QML_NAMED_ELEMENT_OFF_OFF_OFF_OFF_OFF_OFF(OverlayZStacking)
QML_UNCREATABLE_OFF_OFF_OFF_OFF_OFF_OFF("Cannot create objects of type OverlayZStacking, use it as an attached property")
QML_ATTACHED_OFF_OFF_OFF_OFF_OFF_OFF(OverlayZStackingAttached)
/**
* An optimal z-index that attachee popup should bind to.
*/
Q_PROPERTY(qreal z READ z NOTIFY zChanged FINAL)
/**
* The logical stacking layer of attachee popup, akin to window manager's layers.
*/
Q_PROPERTY(Layer layer READ layer WRITE setLayer NOTIFY layerChanged FINAL)
public:
enum Layer {
DefaultLowest = 0,
Drawer,
FullScreen,
Dialog,
Menu,
Notification,
ToolTip,
};
Q_ENUM(Layer)
explicit OverlayZStackingAttached(QObject *parent = nullptr);
~OverlayZStackingAttached() override;
qreal z() const;
Layer layer() const;
void setLayer(Layer layer);
// QML attached property
static OverlayZStackingAttached *qmlAttachedProperties(QObject *object);
Q_SIGNALS:
void zChanged();
void layerChanged();
private Q_SLOTS:
// Popup shall not change z index while being open, so if changes arrive, we defer it until closed.
void enqueueSignal();
void dispatchPendingSignal();
void updateParentPopup();
private:
void updateParentPopupSilent();
void setParentPopup(QObject *popup);
qreal parentPopupZ() const;
static bool isVisible(const QObject *popup);
static bool isPopup(const QObject *object);
static QObject *findParentPopup(const QObject *popup);
static QQuickItem *findParentPopupItem(const QObject *popup);
static Layer defaultLayerForPopupType(const QObject *popup);
static qreal defaultZForLayer(Layer layer);
Layer m_layer = Layer::DefaultLowest;
QPointer<QObject> m_parentPopup;
bool m_pending;
};
QML_DECLARE_TYPEINFO(OverlayZStackingAttached, QML_HAS_ATTACHED_PROPERTIES)
#endif // OVERLAYZSTACKINGATTACHED_H