Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquick3ditem2d.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5
6#include <QtQuick3D/qquick3dobject.h>
7#include <QtQuick3D/private/qquick3ditem2d_p.h>
8
9#include <QtQuick/private/qquickitem_p.h>
10#include <QtQuick/private/qsgrenderer_p.h>
11#include <QtQuick/private/qquickwindow_p.h>
12
13#include <QtQuick3DRuntimeRender/private/qssgrenderitem2d_p.h>
15
16#include <QtGui/rhi/qrhi.h>
17
19
20/*
21internal
22*/
23
24QQuick3DItem2D::QQuick3DItem2D(QQuickItem *item, QQuick3DNode *parent)
25 : QQuick3DNode(*(new QQuick3DNodePrivate(QQuick3DNodePrivate::Type::Item2D)), parent)
26{
27 m_contentItem = new QQuickItem();
28 m_contentItem->setObjectName(QLatin1String("parent of ") + item->objectName()); // for debugging
29 // No size is set for m_contentItem. This is intentional, otherwise item2d anchoring breaks.
30 QQuickItemPrivate::get(m_contentItem)->ensureSubsceneDeliveryAgent();
31 QQmlEngine::setObjectOwnership(m_contentItem, QQmlEngine::CppOwnership);
32
33 connect(m_contentItem, &QQuickItem::childrenChanged, this, &QQuick3DObject::update);
34 addChildItem(item);
35}
36
37QQuick3DItem2D::~QQuick3DItem2D()
38{
39 delete m_contentItem;
40}
41
42void QQuick3DItem2D::addChildItem(QQuickItem *item)
43{
44 item->setParent(m_contentItem);
45 item->setParentItem(m_contentItem);
46 QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::ChangeType::Destroyed);
47 connect(item, &QQuickItem::enabledChanged, this, &QQuick3DItem2D::updatePicking);
48 connect(item, &QQuickItem::visibleChanged, this, &QQuick3DItem2D::updatePicking);
49 m_sourceItems.append(item);
50 update();
51}
52void QQuick3DItem2D::removeChildItem(QQuickItem *item)
53{
54 m_sourceItems.removeOne(item);
55 if (item)
56 QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::ChangeType::Destroyed);
57 if (m_sourceItems.isEmpty())
58 emit allChildrenRemoved();
59 else
60 update();
61}
62
63QQuickItem *QQuick3DItem2D::contentItem() const
64{
65 return m_contentItem;
66}
67
68void QQuick3DItem2D::itemDestroyed(QQuickItem *item)
69{
70 removeChildItem(item);
71}
72
73void QQuick3DItem2D::updatePicking()
74{
75 m_pickingDirty = true;
76 update();
77}
78
79QSSGRenderGraphObject *QQuick3DItem2D::updateSpatialNode(QSSGRenderGraphObject *node)
80{
81 auto *sourceItemPrivate = QQuickItemPrivate::get(m_contentItem);
82 QQuickWindow *window = m_contentItem->window();
83
84 if (!window) {
85 const auto &manager = QQuick3DObjectPrivate::get(this)->sceneManager;
86 window = manager->window();
87 }
88
89 if (!node) {
90 markAllDirty();
91 auto *backEndNode = new QSSGRenderItem2D();
92 backEndNode->m_frontEndObject = this;
93 node = backEndNode;
94 }
95
96 QQuick3DNode::updateSpatialNode(node);
97
98 auto itemNode = static_cast<QSSGRenderItem2D *>(node);
99
100 itemNode->m_rootNode = sourceItemPrivate->rootNode();
101 if (!itemNode->m_rootNode) {
102 QQuickWindowPrivate::get(window)->updateDirtyNode(m_contentItem);
103 itemNode->m_rootNode = sourceItemPrivate->rootNode();
104 if (!itemNode->m_rootNode) {
105 qWarning() << "Item2D is not initialized. It will not be shown.";
106 return nullptr;
107 }
108 }
109
110 if (m_pickingDirty) {
111 m_pickingDirty = false;
112 bool isPickable = false;
113 for (const auto &item : std::as_const(m_sourceItems)) {
114 // Enable picking for Item2D if any of its child is visible and enabled.
115 if (item->isVisible() && item->isEnabled()) {
116 isPickable = true;
117 break;
118 }
119 }
120 itemNode->setState(QSSGRenderNode::LocalState::Pickable, isPickable);
121 }
122
123 return node;
124}
125
126void QQuick3DItem2D::markAllDirty()
127{
128 m_pickingDirty = true;
129
130 QQuick3DNode::markAllDirty();
131}
132
133void QQuick3DItem2D::preSync()
134{
135 const auto &manager = QQuick3DObjectPrivate::get(this)->sceneManager;
136 auto *sourcePrivate = QQuickItemPrivate::get(m_contentItem);
137 auto *window = manager->window();
138 if (m_window != window) {
139 update(); // Just schedule an upate immediately.
140 if (m_window) {
141 disconnect(m_window, SIGNAL(destroyed(QObject*)), this, SLOT(derefWindow(QObject*)));
142 sourcePrivate->derefWindow();
143 }
144 m_window = window;
145 sourcePrivate->refWindow(window);
146 connect(window, SIGNAL(destroyed(QObject*)), this, SLOT(derefWindow(QObject*)));
147 sourcePrivate->refFromEffectItem(true);
148 }
149}
150
151static void detachWindow(QQuickItem *item, QObject *win)
152{
153 auto *itemPriv = QQuickItemPrivate::get(item);
154
155 if (win == itemPriv->window) {
156 itemPriv->window = nullptr;
157 itemPriv->windowRefCount = 0;
158
159 itemPriv->prevDirtyItem = nullptr;
160 itemPriv->nextDirtyItem = nullptr;
161 }
162
163 for (auto *child: itemPriv->childItems)
164 detachWindow(child, win);
165}
166
167void QQuick3DItem2D::derefWindow(QObject *win)
168{
169 detachWindow(m_contentItem, win);
170}
171
172QT_END_NAMESPACE
Combined button and popup list for selecting options.
static void detachWindow(QQuickItem *item, QObject *win)