File indexing completed on 2024-04-21 03:56:01

0001 /*
0002  *  SPDX-FileCopyrightText: 2017 Marco Martin <mart@kde.org>
0003  *  SPDX-FileCopyrightText: 2023 ivan tkachenko <me@ratijas.tk>
0004  *
0005  *  SPDX-License-Identifier: LGPL-2.0-or-later
0006  */
0007 
0008 #include "scenepositionattached.h"
0009 #include <QDebug>
0010 #include <QQuickItem>
0011 
0012 ScenePositionAttached::ScenePositionAttached(QObject *parent)
0013     : QObject(parent)
0014 {
0015     m_item = qobject_cast<QQuickItem *>(parent);
0016     connectAncestors(m_item);
0017 }
0018 
0019 ScenePositionAttached::~ScenePositionAttached()
0020 {
0021 }
0022 
0023 qreal ScenePositionAttached::x() const
0024 {
0025     qreal x = 0.0;
0026     QQuickItem *item = m_item;
0027 
0028     while (item) {
0029         x += item->x();
0030         item = item->parentItem();
0031     }
0032 
0033     return x;
0034 }
0035 
0036 qreal ScenePositionAttached::y() const
0037 {
0038     qreal y = 0.0;
0039     QQuickItem *item = m_item;
0040 
0041     while (item) {
0042         y += item->y();
0043         item = item->parentItem();
0044     }
0045 
0046     return y;
0047 }
0048 
0049 void ScenePositionAttached::connectAncestors(QQuickItem *item)
0050 {
0051     if (!item) {
0052         return;
0053     }
0054 
0055     QQuickItem *ancestor = item;
0056     while (ancestor) {
0057         m_ancestors << ancestor;
0058 
0059         connect(ancestor, &QQuickItem::xChanged, this, &ScenePositionAttached::xChanged);
0060         connect(ancestor, &QQuickItem::yChanged, this, &ScenePositionAttached::yChanged);
0061         connect(ancestor, &QQuickItem::parentChanged, this, [this, ancestor]() {
0062             while (!m_ancestors.isEmpty()) {
0063                 QQuickItem *last = m_ancestors.takeLast();
0064                 // Disconnect the item which had its parent changed too,
0065                 // because connectAncestors() would reconnect it next.
0066                 disconnect(last, nullptr, this, nullptr);
0067                 if (last == ancestor) {
0068                     break;
0069                 }
0070             }
0071 
0072             connectAncestors(ancestor);
0073 
0074             Q_EMIT xChanged();
0075             Q_EMIT yChanged();
0076         });
0077 
0078         ancestor = ancestor->parentItem();
0079     }
0080 }
0081 
0082 ScenePositionAttached *ScenePositionAttached::qmlAttachedProperties(QObject *object)
0083 {
0084     return new ScenePositionAttached(object);
0085 }
0086 
0087 #include "moc_scenepositionattached.cpp"