1 | /* |
2 | * SPDX-FileCopyrightText: 2017 Marco Martin <mart@kde.org> |
3 | * SPDX-FileCopyrightText: 2023 ivan tkachenko <me@ratijas.tk> |
4 | * |
5 | * SPDX-License-Identifier: LGPL-2.0-or-later |
6 | */ |
7 | |
8 | #include "scenepositionattached.h" |
9 | #include <QDebug> |
10 | #include <QQuickItem> |
11 | |
12 | ScenePositionAttached::ScenePositionAttached(QObject *parent) |
13 | : QObject(parent) |
14 | { |
15 | m_item = qobject_cast<QQuickItem *>(o: parent); |
16 | connectAncestors(item: m_item); |
17 | } |
18 | |
19 | ScenePositionAttached::~ScenePositionAttached() |
20 | { |
21 | } |
22 | |
23 | qreal ScenePositionAttached::x() const |
24 | { |
25 | qreal x = 0.0; |
26 | QQuickItem *item = m_item; |
27 | |
28 | while (item) { |
29 | x += item->x(); |
30 | item = item->parentItem(); |
31 | } |
32 | |
33 | return x; |
34 | } |
35 | |
36 | qreal ScenePositionAttached::y() const |
37 | { |
38 | qreal y = 0.0; |
39 | QQuickItem *item = m_item; |
40 | |
41 | while (item) { |
42 | y += item->y(); |
43 | item = item->parentItem(); |
44 | } |
45 | |
46 | return y; |
47 | } |
48 | |
49 | void ScenePositionAttached::connectAncestors(QQuickItem *item) |
50 | { |
51 | if (!item) { |
52 | return; |
53 | } |
54 | |
55 | QQuickItem *ancestor = item; |
56 | while (ancestor) { |
57 | m_ancestors << ancestor; |
58 | |
59 | connect(sender: ancestor, signal: &QQuickItem::xChanged, context: this, slot: &ScenePositionAttached::xChanged); |
60 | connect(sender: ancestor, signal: &QQuickItem::yChanged, context: this, slot: &ScenePositionAttached::yChanged); |
61 | connect(sender: ancestor, signal: &QQuickItem::parentChanged, context: this, slot: [this, ancestor]() { |
62 | while (!m_ancestors.isEmpty()) { |
63 | QQuickItem *last = m_ancestors.takeLast(); |
64 | // Disconnect the item which had its parent changed too, |
65 | // because connectAncestors() would reconnect it next. |
66 | disconnect(sender: last, signal: nullptr, receiver: this, member: nullptr); |
67 | if (last == ancestor) { |
68 | break; |
69 | } |
70 | } |
71 | |
72 | connectAncestors(item: ancestor); |
73 | |
74 | Q_EMIT xChanged(); |
75 | Q_EMIT yChanged(); |
76 | }); |
77 | |
78 | ancestor = ancestor->parentItem(); |
79 | } |
80 | } |
81 | |
82 | ScenePositionAttached *ScenePositionAttached::qmlAttachedProperties(QObject *object) |
83 | { |
84 | return new ScenePositionAttached(object); |
85 | } |
86 | |
87 | #include "moc_scenepositionattached.cpp" |
88 | |