cf12defd28
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
109 lines
3.1 KiB
C++
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
|