1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Quick Controls module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qquicksceneposlistener_p.h"
41#include <QtQuick/private/qquickitem_p.h>
42
43QT_BEGIN_NAMESPACE
44
45static const QQuickItemPrivate::ChangeTypes AncestorChangeTypes = QQuickItemPrivate::Geometry
46 | QQuickItemPrivate::Parent
47 | QQuickItemPrivate::Children;
48
49static const QQuickItemPrivate::ChangeTypes ItemChangeTypes = QQuickItemPrivate::Geometry
50 | QQuickItemPrivate::Parent
51 | QQuickItemPrivate::Destroyed;
52
53QQuickScenePosListener1::QQuickScenePosListener1(QObject *parent)
54 : QObject(parent)
55 , m_enabled(false)
56 , m_item(0)
57{
58}
59
60QQuickScenePosListener1::~QQuickScenePosListener1()
61{
62 if (m_item == 0)
63 return;
64
65 QQuickItemPrivate::get(item: m_item)->removeItemChangeListener(this, types: ItemChangeTypes);
66 removeAncestorListeners(item: m_item->parentItem());
67}
68
69QQuickItem *QQuickScenePosListener1::item() const
70{
71 return m_item;
72}
73
74void QQuickScenePosListener1::setItem(QQuickItem *item)
75{
76 if (m_item == item)
77 return;
78
79 if (m_item != 0) {
80 QQuickItemPrivate::get(item: m_item)->removeItemChangeListener(this, types: ItemChangeTypes);
81 removeAncestorListeners(item: m_item->parentItem());
82 }
83
84 m_item = item;
85
86 if (m_item == 0)
87 return;
88
89 if (m_enabled) {
90 QQuickItemPrivate::get(item: m_item)->addItemChangeListener(listener: this, types: ItemChangeTypes);
91 addAncestorListeners(item: m_item->parentItem());
92 }
93
94 updateScenePos();
95}
96
97QPointF QQuickScenePosListener1::scenePos() const
98{
99 return m_scenePos;
100}
101
102bool QQuickScenePosListener1::isEnabled() const
103{
104 return m_enabled;
105}
106
107void QQuickScenePosListener1::setEnabled(bool enabled)
108{
109 if (m_enabled == enabled)
110 return;
111
112 m_enabled = enabled;
113
114 if (m_item != 0) {
115 if (enabled) {
116 QQuickItemPrivate::get(item: m_item)->addItemChangeListener(listener: this, types: ItemChangeTypes);
117 addAncestorListeners(item: m_item->parentItem());
118 } else {
119 QQuickItemPrivate::get(item: m_item)->removeItemChangeListener(this, types: ItemChangeTypes);
120 removeAncestorListeners(item: m_item->parentItem());
121 }
122 }
123
124 emit enabledChanged();
125}
126
127void QQuickScenePosListener1::itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &)
128{
129 updateScenePos();
130}
131
132void QQuickScenePosListener1::itemParentChanged(QQuickItem *, QQuickItem *parent)
133{
134 addAncestorListeners(item: parent);
135}
136
137void QQuickScenePosListener1::itemChildRemoved(QQuickItem *, QQuickItem *child)
138{
139 if (isAncestor(item: child))
140 removeAncestorListeners(item: child);
141}
142
143void QQuickScenePosListener1::itemDestroyed(QQuickItem *item)
144{
145 Q_ASSERT(m_item == item);
146
147 // Remove all injected listeners.
148 m_item = 0;
149 QQuickItemPrivate::get(item)->removeItemChangeListener(this, types: ItemChangeTypes);
150 removeAncestorListeners(item: item->parentItem());
151}
152
153void QQuickScenePosListener1::updateScenePos()
154{
155 const QPointF &scenePos = m_item->mapToScene(point: QPointF(0, 0));
156 if (m_scenePos != scenePos) {
157 m_scenePos = scenePos;
158 emit scenePosChanged();
159 }
160}
161
162/*!
163 \internal
164
165 Remove this listener from \a item and all its ancestors.
166 */
167void QQuickScenePosListener1::removeAncestorListeners(QQuickItem *item)
168{
169 if (item == m_item)
170 return;
171
172 QQuickItem *p = item;
173 while (p != 0) {
174 QQuickItemPrivate::get(item: p)->removeItemChangeListener(this, types: AncestorChangeTypes);
175 p = p->parentItem();
176 }
177}
178
179/*!
180 \internal
181
182 Injects this as a listener to \a item and all its ancestors.
183 */
184void QQuickScenePosListener1::addAncestorListeners(QQuickItem *item)
185{
186 if (item == m_item)
187 return;
188
189 QQuickItem *p = item;
190 while (p != 0) {
191 QQuickItemPrivate::get(item: p)->addItemChangeListener(listener: this, types: AncestorChangeTypes);
192 p = p->parentItem();
193 }
194}
195
196bool QQuickScenePosListener1::isAncestor(QQuickItem *item) const
197{
198 if (!m_item)
199 return false;
200
201 QQuickItem *parent = m_item->parentItem();
202 while (parent) {
203 if (parent == item)
204 return true;
205 parent = parent->parentItem();
206 }
207 return false;
208}
209
210QT_END_NAMESPACE
211

source code of qtquickcontrols/src/controls/Private/qquicksceneposlistener.cpp