forked from qt-creator/qt-creator
QmlPuppet: Hide 3D edit view render window
Rendering is now done using QRhi private API and QQuickRenderControl. In addition, input event handling was changed to use sendEvent instead of postEvent for our fake mouse events, as mouse event position gets corrupted somehow if event is handled asynchronously when the window is hidden. Change-Id: Ia2466622cd4b60e3f73e0ad3e7e4da7c7c335451 Fixes: QDS-3125 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
@@ -50,11 +50,8 @@ Item {
|
|||||||
view.destroy();
|
view.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
function createViewForObject(obj, w, h)
|
function createViewForObject(obj)
|
||||||
{
|
{
|
||||||
width = w;
|
|
||||||
height = h;
|
|
||||||
|
|
||||||
if (obj instanceof Material)
|
if (obj instanceof Material)
|
||||||
createViewForMaterial(obj);
|
createViewForMaterial(obj);
|
||||||
else if (obj instanceof Model)
|
else if (obj instanceof Model)
|
||||||
|
@@ -45,6 +45,12 @@
|
|||||||
#include <QtQuick3D/private/qquick3dviewport_p.h>
|
#include <QtQuick3D/private/qquick3dviewport_p.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
#include <QtGui/private/qrhi_p.h>
|
||||||
|
#include <QtQuick/private/qquickrendercontrol_p.h>
|
||||||
|
#include <QtQuick/private/qquickrendertarget_p.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <private/qquickdesignersupportitems_p.h>
|
#include <private/qquickdesignersupportitems_p.h>
|
||||||
|
|
||||||
IconRenderer::IconRenderer(int size, const QString &filePath, const QString &source)
|
IconRenderer::IconRenderer(int size, const QString &filePath, const QString &source)
|
||||||
@@ -62,23 +68,26 @@ void IconRenderer::setupRender()
|
|||||||
DesignerSupport::activateDesignerWindowManager();
|
DesignerSupport::activateDesignerWindowManager();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_quickView = new QQuickView;
|
QQmlEngine *engine = nullptr;
|
||||||
|
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||||
QSurfaceFormat surfaceFormat = m_quickView->requestedFormat();
|
auto view = new QQuickView;
|
||||||
|
engine = view->engine();
|
||||||
|
m_window = view;
|
||||||
|
QSurfaceFormat surfaceFormat = view->requestedFormat();
|
||||||
surfaceFormat.setVersion(4, 1);
|
surfaceFormat.setVersion(4, 1);
|
||||||
surfaceFormat.setProfile(QSurfaceFormat::CoreProfile);
|
surfaceFormat.setProfile(QSurfaceFormat::CoreProfile);
|
||||||
m_quickView->setFormat(surfaceFormat);
|
view->setFormat(surfaceFormat);
|
||||||
|
DesignerSupport::createOpenGLContext(view);
|
||||||
DesignerSupport::createOpenGLContext(m_quickView);
|
|
||||||
#else
|
#else
|
||||||
m_quickView->setDefaultAlphaBuffer(true);
|
engine = new QQmlEngine;
|
||||||
m_quickView->setColor(Qt::transparent);
|
m_renderControl = new QQuickRenderControl;
|
||||||
m_ratio = m_quickView->devicePixelRatio();
|
m_window = new QQuickWindow(m_renderControl);
|
||||||
m_quickView->installEventFilter(this);
|
m_window->setDefaultAlphaBuffer(true);
|
||||||
|
m_window->setColor(Qt::transparent);
|
||||||
|
m_renderControl->initialize();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QQmlComponent component(m_quickView->engine());
|
QQmlComponent component(engine);
|
||||||
component.loadUrl(QUrl::fromLocalFile(m_source));
|
component.loadUrl(QUrl::fromLocalFile(m_source));
|
||||||
QObject *iconItem = component.create();
|
QObject *iconItem = component.create();
|
||||||
|
|
||||||
@@ -86,13 +95,19 @@ void IconRenderer::setupRender()
|
|||||||
#ifdef QUICK3D_MODULE
|
#ifdef QUICK3D_MODULE
|
||||||
if (auto scene = qobject_cast<QQuick3DNode *>(iconItem)) {
|
if (auto scene = qobject_cast<QQuick3DNode *>(iconItem)) {
|
||||||
qmlRegisterType<QmlDesigner::Internal::SelectionBoxGeometry>("SelectionBoxGeometry", 1, 0, "SelectionBoxGeometry");
|
qmlRegisterType<QmlDesigner::Internal::SelectionBoxGeometry>("SelectionBoxGeometry", 1, 0, "SelectionBoxGeometry");
|
||||||
QQmlComponent component(m_quickView->engine());
|
QQmlComponent component(engine);
|
||||||
component.loadUrl(QUrl("qrc:/qtquickplugin/mockfiles/IconRenderer3D.qml"));
|
component.loadUrl(QUrl("qrc:/qtquickplugin/mockfiles/IconRenderer3D.qml"));
|
||||||
m_containerItem = qobject_cast<QQuickItem *>(component.create());
|
m_containerItem = qobject_cast<QQuickItem *>(component.create());
|
||||||
DesignerSupport::setRootItem(m_quickView, m_containerItem);
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
DesignerSupport::setRootItem(view, m_containerItem);
|
||||||
|
#else
|
||||||
|
m_window->contentItem()->setSize(m_containerItem->size());
|
||||||
|
m_window->setGeometry(0, 0, m_containerItem->width(), m_containerItem->height());
|
||||||
|
m_containerItem->setParentItem(m_window->contentItem());
|
||||||
|
#endif
|
||||||
|
|
||||||
auto helper = new QmlDesigner::Internal::GeneralHelper();
|
auto helper = new QmlDesigner::Internal::GeneralHelper();
|
||||||
m_quickView->engine()->rootContext()->setContextProperty("_generalHelper", helper);
|
engine->rootContext()->setContextProperty("_generalHelper", helper);
|
||||||
|
|
||||||
m_contentItem = QQmlProperty::read(m_containerItem, "view3D").value<QQuickItem *>();
|
m_contentItem = QQmlProperty::read(m_containerItem, "view3D").value<QQuickItem *>();
|
||||||
auto view3D = qobject_cast<QQuick3DViewport *>(m_contentItem);
|
auto view3D = qobject_cast<QQuick3DViewport *>(m_contentItem);
|
||||||
@@ -104,21 +119,21 @@ void IconRenderer::setupRender()
|
|||||||
m_contentItem = scene;
|
m_contentItem = scene;
|
||||||
m_containerItem = new QQuickItem();
|
m_containerItem = new QQuickItem();
|
||||||
m_containerItem->setSize(QSizeF(1024, 1024));
|
m_containerItem->setSize(QSizeF(1024, 1024));
|
||||||
DesignerSupport::setRootItem(m_quickView, m_containerItem);
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
DesignerSupport::setRootItem(view, m_containerItem);
|
||||||
|
#else
|
||||||
|
m_window->contentItem()->setSize(m_containerItem->size());
|
||||||
|
m_window->setGeometry(0, 0, m_containerItem->width(), m_containerItem->height());
|
||||||
|
m_containerItem->setParentItem(m_window->contentItem());
|
||||||
|
#endif
|
||||||
m_contentItem->setParentItem(m_containerItem);
|
m_contentItem->setParentItem(m_containerItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_containerItem && m_contentItem) {
|
if (m_containerItem && m_contentItem) {
|
||||||
resizeContent(m_size);
|
resizeContent(m_size);
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
if (!initRhi())
|
||||||
|
QTimer::singleShot(0, qGuiApp, &QGuiApplication::quit);
|
||||||
QTimer::singleShot(0, this, &IconRenderer::createIcon);
|
QTimer::singleShot(0, this, &IconRenderer::createIcon);
|
||||||
#else
|
|
||||||
m_quickView->show();
|
|
||||||
m_quickView->lower();
|
|
||||||
|
|
||||||
// Failsafe to exit eventually if window fails to expose
|
|
||||||
QTimer::singleShot(10000, qGuiApp, &QGuiApplication::quit);
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
QTimer::singleShot(0, qGuiApp, &QGuiApplication::quit);
|
QTimer::singleShot(0, qGuiApp, &QGuiApplication::quit);
|
||||||
}
|
}
|
||||||
@@ -127,25 +142,12 @@ void IconRenderer::setupRender()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IconRenderer::eventFilter(QObject *watched, QEvent *event)
|
|
||||||
{
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
|
||||||
if (watched == m_quickView && event->type() == QEvent::Expose)
|
|
||||||
QTimer::singleShot(0, this, &IconRenderer::createIcon);
|
|
||||||
#else
|
|
||||||
Q_UNUSED(watched)
|
|
||||||
Q_UNUSED(event)
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IconRenderer::createIcon()
|
void IconRenderer::createIcon()
|
||||||
{
|
{
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||||
m_designerSupport.refFromEffectItem(m_quickView->rootObject(), false);
|
m_designerSupport.refFromEffectItem(m_containerItem, false);
|
||||||
#endif
|
#endif
|
||||||
QQuickDesignerSupportItems::disableNativeTextRendering(m_quickView->rootObject());
|
QQuickDesignerSupportItems::disableNativeTextRendering(m_containerItem);
|
||||||
|
|
||||||
#ifdef QUICK3D_MODULE
|
#ifdef QUICK3D_MODULE
|
||||||
if (m_is3D) {
|
if (m_is3D) {
|
||||||
// Render once to make sure scene is up to date before we set up the selection box
|
// Render once to make sure scene is up to date before we set up the selection box
|
||||||
@@ -166,6 +168,8 @@ void IconRenderer::createIcon()
|
|||||||
|
|
||||||
// Render @2x image
|
// Render @2x image
|
||||||
resizeContent(m_size * 2);
|
resizeContent(m_size * 2);
|
||||||
|
if (!initRhi())
|
||||||
|
QTimer::singleShot(1000, qGuiApp, &QGuiApplication::quit);
|
||||||
|
|
||||||
QString saveFile;
|
QString saveFile;
|
||||||
saveFile = fi.absolutePath() + '/' + fi.completeBaseName() + "@2x";
|
saveFile = fi.absolutePath() + '/' + fi.completeBaseName() + "@2x";
|
||||||
@@ -194,23 +198,39 @@ void IconRenderer::render(const QString &fileName)
|
|||||||
item->update();
|
item->update();
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
updateNodesRecursive(m_quickView->rootObject());
|
updateNodesRecursive(m_containerItem);
|
||||||
|
|
||||||
QRect rect(QPoint(), m_contentItem->size().toSize());
|
QRect rect(QPoint(), m_contentItem->size().toSize());
|
||||||
|
QImage renderImage;
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||||
QImage renderImage = m_designerSupport.renderImageForItem(m_quickView->rootObject(),
|
renderImage = m_designerSupport.renderImageForItem(m_containerItem, rect, rect.size());
|
||||||
rect, rect.size());
|
|
||||||
#else
|
#else
|
||||||
QImage renderImage = m_quickView->grabWindow();
|
m_renderControl->polishItems();
|
||||||
|
m_renderControl->beginFrame();
|
||||||
|
m_renderControl->sync();
|
||||||
|
m_renderControl->render();
|
||||||
|
|
||||||
|
bool readCompleted = false;
|
||||||
|
QRhiReadbackResult readResult;
|
||||||
|
readResult.completed = [&] {
|
||||||
|
readCompleted = true;
|
||||||
|
QImage wrapperImage(reinterpret_cast<const uchar *>(readResult.data.constData()),
|
||||||
|
readResult.pixelSize.width(), readResult.pixelSize.height(),
|
||||||
|
QImage::Format_RGBA8888_Premultiplied);
|
||||||
|
if (m_rhi->isYUpInFramebuffer())
|
||||||
|
renderImage = wrapperImage.mirrored().copy(0, 0, rect.width(), rect.height());
|
||||||
|
else
|
||||||
|
renderImage = wrapperImage.copy(0, 0, rect.width(), rect.height());
|
||||||
|
};
|
||||||
|
QRhiResourceUpdateBatch *readbackBatch = m_rhi->nextResourceUpdateBatch();
|
||||||
|
readbackBatch->readBackTexture(m_texture, &readResult);
|
||||||
|
|
||||||
|
QQuickRenderControlPrivate *rd = QQuickRenderControlPrivate::get(m_renderControl);
|
||||||
|
rd->cb->resourceUpdate(readbackBatch);
|
||||||
|
|
||||||
|
m_renderControl->endFrame();
|
||||||
#endif
|
#endif
|
||||||
if (!fileName.isEmpty()) {
|
if (!fileName.isEmpty()) {
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
|
||||||
if (m_ratio != 1.) {
|
|
||||||
rect.setWidth(qRound(rect.size().width() * m_ratio));
|
|
||||||
rect.setHeight(qRound(rect.size().height() * m_ratio));
|
|
||||||
}
|
|
||||||
renderImage = renderImage.copy(rect);
|
|
||||||
#endif
|
|
||||||
QFileInfo fi(fileName);
|
QFileInfo fi(fileName);
|
||||||
if (fi.suffix().isEmpty())
|
if (fi.suffix().isEmpty())
|
||||||
renderImage.save(fileName, "PNG");
|
renderImage.save(fileName, "PNG");
|
||||||
@@ -219,16 +239,60 @@ void IconRenderer::render(const QString &fileName)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IconRenderer::resizeContent(int size)
|
void IconRenderer::resizeContent(int dimensions)
|
||||||
{
|
{
|
||||||
int theSize = size;
|
QSizeF size(dimensions, dimensions);
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
m_contentItem->setSize(size);
|
||||||
if (m_ratio != 1.)
|
|
||||||
theSize = qRound(qreal(size) / m_quickView->devicePixelRatio());
|
|
||||||
#endif
|
|
||||||
m_contentItem->setSize(QSizeF(theSize, theSize));
|
|
||||||
if (m_contentItem->width() > m_containerItem->width())
|
if (m_contentItem->width() > m_containerItem->width())
|
||||||
m_containerItem->setWidth(m_contentItem->width());
|
m_containerItem->setWidth(m_contentItem->width());
|
||||||
if (m_contentItem->height() > m_containerItem->height())
|
if (m_contentItem->height() > m_containerItem->height())
|
||||||
m_containerItem->setHeight(m_contentItem->height());
|
m_containerItem->setHeight(m_contentItem->height());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IconRenderer::initRhi()
|
||||||
|
{
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
if (!m_rhi) {
|
||||||
|
QQuickRenderControlPrivate *rd = QQuickRenderControlPrivate::get(m_renderControl);
|
||||||
|
m_rhi = rd->rhi;
|
||||||
|
if (!m_rhi) {
|
||||||
|
qWarning() << __FUNCTION__ << "Rhi is null";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't bother deleting old ones as iconrender is a single shot executable
|
||||||
|
m_texTarget = nullptr;
|
||||||
|
m_rpDesc = nullptr;
|
||||||
|
m_buffer = nullptr;
|
||||||
|
m_texture = nullptr;
|
||||||
|
|
||||||
|
const QSize size = m_containerItem->size().toSize();
|
||||||
|
m_texture = m_rhi->newTexture(QRhiTexture::RGBA8, size, 1,
|
||||||
|
QRhiTexture::RenderTarget | QRhiTexture::UsedAsTransferSource);
|
||||||
|
if (!m_texture->create()) {
|
||||||
|
qWarning() << __FUNCTION__ << "QRhiTexture creation failed";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_buffer = m_rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, size, 1);
|
||||||
|
if (!m_buffer->create()) {
|
||||||
|
qWarning() << __FUNCTION__ << "Depth/stencil buffer creation failed";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRhiTextureRenderTargetDescription rtDesc {QRhiColorAttachment(m_texture)};
|
||||||
|
rtDesc.setDepthStencilBuffer(m_buffer);
|
||||||
|
m_texTarget = m_rhi->newTextureRenderTarget(rtDesc);
|
||||||
|
m_rpDesc = m_texTarget->newCompatibleRenderPassDescriptor();
|
||||||
|
m_texTarget->setRenderPassDescriptor(m_rpDesc);
|
||||||
|
if (!m_texTarget->create()) {
|
||||||
|
qWarning() << __FUNCTION__ << "Texture render target creation failed";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// redirect Qt Quick rendering into our texture
|
||||||
|
m_window->setRenderTarget(QQuickRenderTarget::fromRhiRenderTarget(m_texTarget));
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@@ -31,8 +31,16 @@
|
|||||||
#include <designersupportdelegate.h>
|
#include <designersupportdelegate.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QQuickView;
|
class QQuickWindow;
|
||||||
class QQuickItem;
|
class QQuickItem;
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
class QQuickRenderControl;
|
||||||
|
class QRhi;
|
||||||
|
class QRhiTexture;
|
||||||
|
class QRhiRenderBuffer;
|
||||||
|
class QRhiTextureRenderTarget;
|
||||||
|
class QRhiRenderPassDescriptor;
|
||||||
|
#endif
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
class IconRenderer : public QObject
|
class IconRenderer : public QObject
|
||||||
@@ -44,21 +52,26 @@ public:
|
|||||||
|
|
||||||
void setupRender();
|
void setupRender();
|
||||||
|
|
||||||
protected:
|
|
||||||
bool eventFilter(QObject *watched, QEvent *event) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createIcon();
|
void createIcon();
|
||||||
void render(const QString &fileName);
|
void render(const QString &fileName);
|
||||||
void resizeContent(int size);
|
void resizeContent(int dimensions);
|
||||||
|
bool initRhi();
|
||||||
|
|
||||||
int m_size = 16;
|
int m_size = 16;
|
||||||
double m_ratio = 1.;
|
|
||||||
QString m_filePath;
|
QString m_filePath;
|
||||||
QString m_source;
|
QString m_source;
|
||||||
QQuickView *m_quickView = nullptr;
|
QQuickWindow *m_window = nullptr;
|
||||||
QQuickItem *m_contentItem = nullptr;
|
QQuickItem *m_contentItem = nullptr;
|
||||||
QQuickItem *m_containerItem = nullptr;
|
QQuickItem *m_containerItem = nullptr;
|
||||||
DesignerSupport m_designerSupport;
|
DesignerSupport m_designerSupport;
|
||||||
bool m_is3D = false;
|
bool m_is3D = false;
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
QQuickRenderControl *m_renderControl = nullptr;
|
||||||
|
QRhi *m_rhi = nullptr;
|
||||||
|
QRhiTexture *m_texture = nullptr;
|
||||||
|
QRhiRenderBuffer *m_buffer = nullptr;
|
||||||
|
QRhiTextureRenderTarget *m_texTarget = nullptr;
|
||||||
|
QRhiRenderPassDescriptor *m_rpDesc = nullptr;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
@@ -87,6 +87,14 @@
|
|||||||
#include <QtGui/qevent.h>
|
#include <QtGui/qevent.h>
|
||||||
#include <QtGui/qguiapplication.h>
|
#include <QtGui/qguiapplication.h>
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
#include <QtGui/private/qrhi_p.h>
|
||||||
|
#include <QtQuick/private/qquickwindow_p.h>
|
||||||
|
#include <QtQuick/private/qsgrenderer_p.h>
|
||||||
|
#include <QtQuick/private/qquickrendercontrol_p.h>
|
||||||
|
#include <QtQuick/private/qquickrendertarget_p.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef QUICK3D_MODULE
|
#ifdef QUICK3D_MODULE
|
||||||
#include <QtQuick3D/private/qquick3dnode_p.h>
|
#include <QtQuick3D/private/qquick3dnode_p.h>
|
||||||
#include <QtQuick3D/private/qquick3dcamera_p.h>
|
#include <QtQuick3D/private/qquick3dcamera_p.h>
|
||||||
@@ -135,29 +143,34 @@ static bool isQuick3DMode()
|
|||||||
return mode3D;
|
return mode3D;
|
||||||
}
|
}
|
||||||
|
|
||||||
QQuickView *Qt5InformationNodeInstanceServer::createAuxiliaryQuickView(const QUrl &url,
|
void Qt5InformationNodeInstanceServer::createAuxiliaryQuickView(const QUrl &url,
|
||||||
QQuickItem *&rootItem)
|
RenderViewData &viewData)
|
||||||
{
|
{
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||||
auto view = new QQuickView(quickView()->engine(), quickView());
|
viewData.window = new QQuickView(quickView()->engine(), quickView());
|
||||||
view->setFormat(quickView()->format());
|
viewData.window->setFormat(quickView()->format());
|
||||||
DesignerSupport::createOpenGLContext(view);
|
DesignerSupport::createOpenGLContext(static_cast<QQuickView *>(viewData.window));
|
||||||
#else
|
#else
|
||||||
auto view = new QQuickView(quickView()->engine(), nullptr);
|
viewData.renderControl = new QQuickRenderControl;
|
||||||
view->setFormat(quickView()->format());
|
viewData.window = new QQuickWindow(viewData.renderControl);
|
||||||
|
viewData.renderControl->initialize();
|
||||||
#endif
|
#endif
|
||||||
QQmlComponent component(engine());
|
QQmlComponent component(engine());
|
||||||
component.loadUrl(url);
|
component.loadUrl(url);
|
||||||
rootItem = qobject_cast<QQuickItem *>(component.create());
|
viewData.rootItem = qobject_cast<QQuickItem *>(component.create());
|
||||||
|
|
||||||
if (!rootItem) {
|
if (!viewData.rootItem) {
|
||||||
qWarning() << "Could not create view for: " << url.toString() << component.errors();
|
qWarning() << "Could not create view for: " << url.toString() << component.errors();
|
||||||
return nullptr;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DesignerSupport::setRootItem(view, rootItem);
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
DesignerSupport::setRootItem(static_cast<QQuickView *>(viewData.window), viewData.rootItem);
|
||||||
return view;
|
#else
|
||||||
|
viewData.window->contentItem()->setSize(viewData.rootItem->size());
|
||||||
|
viewData.window->setGeometry(0, 0, viewData.rootItem->width(), viewData.rootItem->height());
|
||||||
|
viewData.rootItem->setParentItem(viewData.window->contentItem());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Qt5InformationNodeInstanceServer::updateLockedAndHiddenStates(const QSet<ServerNodeInstance> &instances)
|
void Qt5InformationNodeInstanceServer::updateLockedAndHiddenStates(const QSet<ServerNodeInstance> &instances)
|
||||||
@@ -177,6 +190,179 @@ void Qt5InformationNodeInstanceServer::updateLockedAndHiddenStates(const QSet<Se
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Qt5InformationNodeInstanceServer::handleInputEvents()
|
||||||
|
{
|
||||||
|
if (m_editView3DData.window) {
|
||||||
|
int angleDelta = 0;
|
||||||
|
for (int i = 0; i < m_pendingInputEventCommands.size(); ++i) {
|
||||||
|
const InputEventCommand &command = m_pendingInputEventCommands[i];
|
||||||
|
if (command.type() == QEvent::Wheel) {
|
||||||
|
if (i < m_pendingInputEventCommands.size() - 1) {
|
||||||
|
// Peek at next command. If that is also a wheel with same button/modifiers
|
||||||
|
// state, skip this event and add the angle delta to the next one.
|
||||||
|
auto nextCommand = m_pendingInputEventCommands[i + 1];
|
||||||
|
if (nextCommand.type() == QEvent::MouseMove
|
||||||
|
&& nextCommand.button() == command.button()
|
||||||
|
&& nextCommand.buttons() == command.buttons()
|
||||||
|
&& nextCommand.modifiers() == command.modifiers()) {
|
||||||
|
angleDelta += command.angleDelta();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QWheelEvent *we
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
||||||
|
= new QWheelEvent(command.pos(), command.pos(), {0, 0},
|
||||||
|
{0, angleDelta + command.angleDelta()},
|
||||||
|
command.buttons(), command.modifiers(), Qt::NoScrollPhase,
|
||||||
|
false);
|
||||||
|
#else
|
||||||
|
= new QWheelEvent(command.pos(), command.pos(), {0, 0}, {0, command.angleDelta()},
|
||||||
|
0, Qt::Horizontal, command.buttons(), command.modifiers(),
|
||||||
|
Qt::NoScrollPhase, Qt::MouseEventNotSynthesized);
|
||||||
|
#endif
|
||||||
|
angleDelta = 0;
|
||||||
|
QGuiApplication::sendEvent(m_editView3DData.window, we);
|
||||||
|
} else {
|
||||||
|
if (command.type() == QEvent::MouseMove && i < m_pendingInputEventCommands.size() - 1) {
|
||||||
|
// Peek at next command. If that is also a move with only difference being
|
||||||
|
// the position, skip this event as it is pointless
|
||||||
|
auto nextCommand = m_pendingInputEventCommands[i + 1];
|
||||||
|
if (nextCommand.type() == QEvent::MouseMove
|
||||||
|
&& nextCommand.button() == command.button()
|
||||||
|
&& nextCommand.buttons() == command.buttons()
|
||||||
|
&& nextCommand.modifiers() == command.modifiers()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto me = new QMouseEvent(command.type(), command.pos(), command.button(),
|
||||||
|
command.buttons(), command.modifiers());
|
||||||
|
// We must use sendEvent in Qt 6, as using postEvent allows the associated position
|
||||||
|
// data stored internally in QMutableEventPoint to potentially be updated by system
|
||||||
|
// before the event is delivered.
|
||||||
|
QGuiApplication::sendEvent(m_editView3DData.window, me);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pendingInputEventCommands.clear();
|
||||||
|
|
||||||
|
render3DEditView();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Qt5InformationNodeInstanceServer::initRhi(RenderViewData &viewData)
|
||||||
|
{
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
if (!viewData.renderControl) {
|
||||||
|
qWarning() << __FUNCTION__ << "Render control not created";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!viewData.rhi) {
|
||||||
|
QQuickRenderControlPrivate *rd = QQuickRenderControlPrivate::get(viewData.renderControl);
|
||||||
|
viewData.rhi = rd->rhi;
|
||||||
|
|
||||||
|
if (!viewData.rhi) {
|
||||||
|
qWarning() << __FUNCTION__ << "Rhi is null";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto cleanRhiResources = [&viewData]() {
|
||||||
|
// Releasing cached resources is a workaround for bug QTBUG-88761
|
||||||
|
auto renderer = QQuickWindowPrivate::get(viewData.window)->renderer;
|
||||||
|
if (renderer)
|
||||||
|
renderer->releaseCachedResources();
|
||||||
|
|
||||||
|
if (viewData.rpDesc) {
|
||||||
|
viewData.rpDesc->deleteLater();
|
||||||
|
viewData.rpDesc = nullptr;
|
||||||
|
}
|
||||||
|
if (viewData.texTarget) {
|
||||||
|
viewData.texTarget->deleteLater();
|
||||||
|
viewData.texTarget = nullptr;
|
||||||
|
}
|
||||||
|
if (viewData.buffer) {
|
||||||
|
viewData.buffer->deleteLater();
|
||||||
|
viewData.buffer = nullptr;
|
||||||
|
}
|
||||||
|
if (viewData.texture) {
|
||||||
|
viewData.texture->deleteLater();
|
||||||
|
viewData.texture = nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (viewData.bufferDirty) {
|
||||||
|
cleanRhiResources();
|
||||||
|
viewData.bufferDirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QSize size = viewData.rootItem->size().toSize();
|
||||||
|
viewData.texture = viewData.rhi->newTexture(QRhiTexture::RGBA8, size, 1,
|
||||||
|
QRhiTexture::RenderTarget | QRhiTexture::UsedAsTransferSource);
|
||||||
|
if (!viewData.texture->create()) {
|
||||||
|
qWarning() << __FUNCTION__ << "QRhiTexture creation failed";
|
||||||
|
cleanRhiResources();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
viewData.buffer = viewData.rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, size, 1);
|
||||||
|
if (!viewData.buffer->create()) {
|
||||||
|
qWarning() << __FUNCTION__ << "Depth/stencil buffer creation failed";
|
||||||
|
cleanRhiResources();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRhiTextureRenderTargetDescription rtDesc(QRhiColorAttachment(viewData.texture));
|
||||||
|
rtDesc.setDepthStencilBuffer(viewData.buffer);
|
||||||
|
viewData.texTarget = viewData.rhi->newTextureRenderTarget(rtDesc);
|
||||||
|
viewData.rpDesc = viewData.texTarget->newCompatibleRenderPassDescriptor();
|
||||||
|
viewData.texTarget->setRenderPassDescriptor(viewData.rpDesc);
|
||||||
|
if (!viewData.texTarget->create()) {
|
||||||
|
qWarning() << __FUNCTION__ << "Texture render target creation failed";
|
||||||
|
cleanRhiResources();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// redirect Qt Quick rendering into our texture
|
||||||
|
viewData.window->setRenderTarget(QQuickRenderTarget::fromRhiRenderTarget(viewData.texTarget));
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage Qt5InformationNodeInstanceServer::grabRenderControl(RenderViewData &viewData)
|
||||||
|
{
|
||||||
|
QImage renderImage;
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
if (viewData.bufferDirty && !initRhi(viewData))
|
||||||
|
return renderImage;
|
||||||
|
|
||||||
|
viewData.renderControl->polishItems();
|
||||||
|
viewData.renderControl->beginFrame();
|
||||||
|
viewData.renderControl->sync();
|
||||||
|
viewData.renderControl->render();
|
||||||
|
|
||||||
|
bool readCompleted = false;
|
||||||
|
QRhiReadbackResult readResult;
|
||||||
|
readResult.completed = [&] {
|
||||||
|
readCompleted = true;
|
||||||
|
QImage wrapperImage(reinterpret_cast<const uchar *>(readResult.data.constData()),
|
||||||
|
readResult.pixelSize.width(), readResult.pixelSize.height(),
|
||||||
|
QImage::Format_RGBA8888_Premultiplied);
|
||||||
|
if (viewData.rhi->isYUpInFramebuffer())
|
||||||
|
renderImage = wrapperImage.mirrored();
|
||||||
|
else
|
||||||
|
renderImage = wrapperImage.copy();
|
||||||
|
};
|
||||||
|
QRhiResourceUpdateBatch *readbackBatch = viewData.rhi->nextResourceUpdateBatch();
|
||||||
|
readbackBatch->readBackTexture(viewData.texture, &readResult);
|
||||||
|
|
||||||
|
QQuickRenderControlPrivate *rd = QQuickRenderControlPrivate::get(viewData.renderControl);
|
||||||
|
rd->cb->resourceUpdate(readbackBatch);
|
||||||
|
|
||||||
|
viewData.renderControl->endFrame();
|
||||||
|
#endif
|
||||||
|
return renderImage;
|
||||||
|
}
|
||||||
|
|
||||||
void Qt5InformationNodeInstanceServer::createEditView3D()
|
void Qt5InformationNodeInstanceServer::createEditView3D()
|
||||||
{
|
{
|
||||||
#ifdef QUICK3D_MODULE
|
#ifdef QUICK3D_MODULE
|
||||||
@@ -199,10 +385,10 @@ void Qt5InformationNodeInstanceServer::createEditView3D()
|
|||||||
new QmlDesigner::Internal::IconGizmoImageProvider);
|
new QmlDesigner::Internal::IconGizmoImageProvider);
|
||||||
m_3dHelper = helper;
|
m_3dHelper = helper;
|
||||||
|
|
||||||
m_editView3D = createAuxiliaryQuickView(QUrl("qrc:/qtquickplugin/mockfiles/EditView3D.qml"), m_editView3DRootItem);
|
createAuxiliaryQuickView(QUrl("qrc:/qtquickplugin/mockfiles/EditView3D.qml"), m_editView3DData);
|
||||||
|
|
||||||
if (m_editView3DRootItem)
|
if (m_editView3DData.rootItem)
|
||||||
helper->setParent(m_editView3DRootItem);
|
helper->setParent(m_editView3DData.rootItem);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -373,10 +559,10 @@ void Qt5InformationNodeInstanceServer::handleNode3DDestroyed(QObject *obj)
|
|||||||
{
|
{
|
||||||
#ifdef QUICK3D_MODULE
|
#ifdef QUICK3D_MODULE
|
||||||
if (qobject_cast<QQuick3DCamera *>(obj)) {
|
if (qobject_cast<QQuick3DCamera *>(obj)) {
|
||||||
QMetaObject::invokeMethod(m_editView3DRootItem, "releaseCameraGizmo",
|
QMetaObject::invokeMethod(m_editView3DData.rootItem, "releaseCameraGizmo",
|
||||||
Q_ARG(QVariant, objectToVariant(obj)));
|
Q_ARG(QVariant, objectToVariant(obj)));
|
||||||
} else if (qobject_cast<QQuick3DAbstractLight *>(obj)) {
|
} else if (qobject_cast<QQuick3DAbstractLight *>(obj)) {
|
||||||
QMetaObject::invokeMethod(m_editView3DRootItem, "releaseLightGizmo",
|
QMetaObject::invokeMethod(m_editView3DData.rootItem, "releaseLightGizmo",
|
||||||
Q_ARG(QVariant, objectToVariant(obj)));
|
Q_ARG(QVariant, objectToVariant(obj)));
|
||||||
}
|
}
|
||||||
removeNode3D(obj);
|
removeNode3D(obj);
|
||||||
@@ -392,7 +578,7 @@ void Qt5InformationNodeInstanceServer::updateView3DRect(QObject *view3D)
|
|||||||
viewPortrect = QRectF(0., 0., view3D->property("width").toDouble(),
|
viewPortrect = QRectF(0., 0., view3D->property("width").toDouble(),
|
||||||
view3D->property("height").toDouble());
|
view3D->property("height").toDouble());
|
||||||
}
|
}
|
||||||
QQmlProperty viewPortProperty(m_editView3DRootItem, "viewPortRect", context());
|
QQmlProperty viewPortProperty(m_editView3DData.rootItem, "viewPortRect", context());
|
||||||
viewPortProperty.write(viewPortrect);
|
viewPortProperty.write(viewPortrect);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,7 +591,7 @@ void Qt5InformationNodeInstanceServer::updateActiveSceneToEditView3D()
|
|||||||
// Active scene change handling on qml side is async, so a deleted importScene would crash
|
// Active scene change handling on qml side is async, so a deleted importScene would crash
|
||||||
// editView when it updates next. Disable/enable edit view update synchronously to avoid this.
|
// editView when it updates next. Disable/enable edit view update synchronously to avoid this.
|
||||||
QVariant activeSceneVar = objectToVariant(m_active3DScene);
|
QVariant activeSceneVar = objectToVariant(m_active3DScene);
|
||||||
QMetaObject::invokeMethod(m_editView3DRootItem, "enableEditViewUpdate",
|
QMetaObject::invokeMethod(m_editView3DData.rootItem, "enableEditViewUpdate",
|
||||||
Q_ARG(QVariant, activeSceneVar));
|
Q_ARG(QVariant, activeSceneVar));
|
||||||
|
|
||||||
ServerNodeInstance sceneInstance = active3DSceneInstance();
|
ServerNodeInstance sceneInstance = active3DSceneInstance();
|
||||||
@@ -419,7 +605,7 @@ void Qt5InformationNodeInstanceServer::updateActiveSceneToEditView3D()
|
|||||||
m_active3DSceneUpdatePending = false;
|
m_active3DSceneUpdatePending = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMetaObject::invokeMethod(m_editView3DRootItem, "setActiveScene", Qt::QueuedConnection,
|
QMetaObject::invokeMethod(m_editView3DData.rootItem, "setActiveScene", Qt::QueuedConnection,
|
||||||
Q_ARG(QVariant, activeSceneVar),
|
Q_ARG(QVariant, activeSceneVar),
|
||||||
Q_ARG(QVariant, QVariant::fromValue(sceneId)));
|
Q_ARG(QVariant, QVariant::fromValue(sceneId)));
|
||||||
|
|
||||||
@@ -472,11 +658,11 @@ void Qt5InformationNodeInstanceServer::resolveSceneRoots()
|
|||||||
|
|
||||||
if (newRoot != oldRoot) {
|
if (newRoot != oldRoot) {
|
||||||
if (qobject_cast<QQuick3DCamera *>(node)) {
|
if (qobject_cast<QQuick3DCamera *>(node)) {
|
||||||
QMetaObject::invokeMethod(m_editView3DRootItem, "updateCameraGizmoScene",
|
QMetaObject::invokeMethod(m_editView3DData.rootItem, "updateCameraGizmoScene",
|
||||||
Q_ARG(QVariant, objectToVariant(newRoot)),
|
Q_ARG(QVariant, objectToVariant(newRoot)),
|
||||||
Q_ARG(QVariant, objectToVariant(node)));
|
Q_ARG(QVariant, objectToVariant(node)));
|
||||||
} else if (qobject_cast<QQuick3DAbstractLight *>(node)) {
|
} else if (qobject_cast<QQuick3DAbstractLight *>(node)) {
|
||||||
QMetaObject::invokeMethod(m_editView3DRootItem, "updateLightGizmoScene",
|
QMetaObject::invokeMethod(m_editView3DData.rootItem, "updateLightGizmoScene",
|
||||||
Q_ARG(QVariant, objectToVariant(newRoot)),
|
Q_ARG(QVariant, objectToVariant(newRoot)),
|
||||||
Q_ARG(QVariant, objectToVariant(node)));
|
Q_ARG(QVariant, objectToVariant(node)));
|
||||||
}
|
}
|
||||||
@@ -535,30 +721,30 @@ void Qt5InformationNodeInstanceServer::render3DEditView(int count)
|
|||||||
void Qt5InformationNodeInstanceServer::doRender3DEditView()
|
void Qt5InformationNodeInstanceServer::doRender3DEditView()
|
||||||
{
|
{
|
||||||
if (m_editView3DSetupDone) {
|
if (m_editView3DSetupDone) {
|
||||||
if (!m_editView3DContentItem)
|
if (!m_editView3DData.contentItem)
|
||||||
m_editView3DContentItem = getContentItemForRendering(m_editView3DRootItem);
|
m_editView3DData.contentItem = getContentItemForRendering(m_editView3DData.rootItem);
|
||||||
|
|
||||||
QImage renderImage;
|
QImage renderImage;
|
||||||
|
|
||||||
updateNodesRecursive(m_editView3DContentItem);
|
updateNodesRecursive(m_editView3DData.contentItem);
|
||||||
|
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||||
if (Internal::QuickItemNodeInstance::unifiedRenderPath()) {
|
if (Internal::QuickItemNodeInstance::unifiedRenderPath()) {
|
||||||
renderImage = m_editView3D->grabWindow();
|
renderImage = m_editView3DData.window->grabWindow();
|
||||||
} else {
|
} else {
|
||||||
// Fake render loop signaling to update things like QML items as 3D textures
|
// Fake render loop signaling to update things like QML items as 3D textures
|
||||||
m_editView3D->beforeSynchronizing();
|
m_editView3DData.window->beforeSynchronizing();
|
||||||
m_editView3D->beforeRendering();
|
m_editView3DData.window->beforeRendering();
|
||||||
|
|
||||||
QSizeF size = qobject_cast<QQuickItem *>(m_editView3DContentItem)->size();
|
QSizeF size = qobject_cast<QQuickItem *>(m_editView3DData.contentItem)->size();
|
||||||
QRectF renderRect(QPointF(0., 0.), size);
|
QRectF renderRect(QPointF(0., 0.), size);
|
||||||
renderImage = designerSupport()->renderImageForItem(m_editView3DContentItem,
|
renderImage = designerSupport()->renderImageForItem(m_editView3DData.contentItem,
|
||||||
renderRect, size.toSize());
|
renderRect, size.toSize());
|
||||||
|
|
||||||
m_editView3D->afterRendering();
|
m_editView3DData.window->afterRendering();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
renderImage = m_editView3D->grabWindow();
|
renderImage = grabRenderControl(m_editView3DData);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// There's no instance related to image, so instance id is -1.
|
// There's no instance related to image, so instance id is -1.
|
||||||
@@ -601,9 +787,9 @@ void Qt5InformationNodeInstanceServer::doRenderModelNodeImageView()
|
|||||||
void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView()
|
void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView()
|
||||||
{
|
{
|
||||||
#ifdef QUICK3D_MODULE
|
#ifdef QUICK3D_MODULE
|
||||||
if (m_ModelNode3DImageViewRootItem) {
|
if (m_modelNode3DImageViewData.rootItem) {
|
||||||
if (!m_ModelNode3DImageViewContentItem)
|
if (!m_modelNode3DImageViewData.contentItem)
|
||||||
m_ModelNode3DImageViewContentItem = getContentItemForRendering(m_ModelNode3DImageViewRootItem);
|
m_modelNode3DImageViewData.contentItem = getContentItemForRendering(m_modelNode3DImageViewData.rootItem);
|
||||||
|
|
||||||
// Key number is selected so that it is unlikely to conflict other ImageContainer use.
|
// Key number is selected so that it is unlikely to conflict other ImageContainer use.
|
||||||
auto imgContainer = ImageContainer(m_modelNodePreviewImageCommand.instanceId(), {}, 2100000001);
|
auto imgContainer = ImageContainer(m_modelNodePreviewImageCommand.instanceId(), {}, 2100000001);
|
||||||
@@ -628,43 +814,48 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView()
|
|||||||
if (Internal::QuickItemNodeInstance::unifiedRenderPath()) {
|
if (Internal::QuickItemNodeInstance::unifiedRenderPath()) {
|
||||||
// Requested size is already adjusted for target pixel ratio, so we have to adjust
|
// Requested size is already adjusted for target pixel ratio, so we have to adjust
|
||||||
// back if ratio is not default for our window.
|
// back if ratio is not default for our window.
|
||||||
double ratio = m_ModelNode3DImageView->devicePixelRatio();
|
double ratio = m_modelNode3DImageViewData.window->devicePixelRatio();
|
||||||
renderSize.setWidth(qRound(qreal(renderSize.width()) / ratio));
|
renderSize.setWidth(qRound(qreal(renderSize.width()) / ratio));
|
||||||
renderSize.setHeight(qRound(qreal(renderSize.height()) / ratio));
|
renderSize.setHeight(qRound(qreal(renderSize.height()) / ratio));
|
||||||
}
|
}
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
m_modelNode3DImageViewData.bufferDirty = m_modelNode3DImageViewData.bufferDirty
|
||||||
|
|| m_modelNode3DImageViewData.rootItem->width() != renderSize.width()
|
||||||
|
|| m_modelNode3DImageViewData.rootItem->height() != renderSize.height();
|
||||||
|
#endif
|
||||||
|
|
||||||
QMetaObject::invokeMethod(m_ModelNode3DImageViewRootItem, "createViewForObject",
|
m_modelNode3DImageViewData.window->resize(renderSize);
|
||||||
Q_ARG(QVariant, objectToVariant(instanceObj)),
|
m_modelNode3DImageViewData.rootItem->setSize(renderSize);
|
||||||
Q_ARG(QVariant, QVariant::fromValue(renderSize.width())),
|
|
||||||
Q_ARG(QVariant, QVariant::fromValue(renderSize.height())));
|
|
||||||
|
|
||||||
|
QMetaObject::invokeMethod(m_modelNode3DImageViewData.rootItem, "createViewForObject",
|
||||||
|
Q_ARG(QVariant, objectToVariant(instanceObj)));
|
||||||
|
|
||||||
bool ready = false;
|
bool ready = false;
|
||||||
int count = 0; // Ensure we don't ever get stuck in an infinite loop
|
int count = 0; // Ensure we don't ever get stuck in an infinite loop
|
||||||
while (!ready && ++count < 10) {
|
while (!ready && ++count < 10) {
|
||||||
updateNodesRecursive(m_ModelNode3DImageViewContentItem);
|
updateNodesRecursive(m_modelNode3DImageViewData.contentItem);
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||||
if (Internal::QuickItemNodeInstance::unifiedRenderPath()) {
|
if (Internal::QuickItemNodeInstance::unifiedRenderPath()) {
|
||||||
renderImage = m_ModelNode3DImageView->grabWindow();
|
renderImage = m_modelNode3DImageViewData.window->grabWindow();
|
||||||
} else {
|
} else {
|
||||||
// Fake render loop signaling to update things like QML items as 3D textures
|
// Fake render loop signaling to update things like QML items as 3D textures
|
||||||
m_ModelNode3DImageView->beforeSynchronizing();
|
m_modelNode3DImageViewData.window->beforeSynchronizing();
|
||||||
m_ModelNode3DImageView->beforeRendering();
|
m_modelNode3DImageViewData.window->beforeRendering();
|
||||||
|
|
||||||
QSizeF size = qobject_cast<QQuickItem *>(m_ModelNode3DImageViewContentItem)->size();
|
QSizeF size = qobject_cast<QQuickItem *>(m_modelNode3DImageViewData.contentItem)->size();
|
||||||
QRectF renderRect(QPointF(0., 0.), size);
|
QRectF renderRect(QPointF(0., 0.), size);
|
||||||
renderImage = designerSupport()->renderImageForItem(m_ModelNode3DImageViewContentItem,
|
renderImage = designerSupport()->renderImageForItem(m_modelNode3DImageViewData.contentItem,
|
||||||
renderRect, size.toSize());
|
renderRect, size.toSize());
|
||||||
|
|
||||||
m_ModelNode3DImageView->afterRendering();
|
m_modelNode3DImageViewData.window->afterRendering();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
renderImage = m_ModelNode3DImageView->grabWindow();
|
renderImage = grabRenderControl(m_modelNode3DImageViewData);
|
||||||
#endif
|
#endif
|
||||||
QMetaObject::invokeMethod(m_ModelNode3DImageViewRootItem, "afterRender");
|
QMetaObject::invokeMethod(m_modelNode3DImageViewData.rootItem, "afterRender");
|
||||||
ready = QQmlProperty::read(m_ModelNode3DImageViewRootItem, "ready").value<bool>();
|
ready = QQmlProperty::read(m_modelNode3DImageViewData.rootItem, "ready").value<bool>();
|
||||||
}
|
}
|
||||||
QMetaObject::invokeMethod(m_ModelNode3DImageViewRootItem, "destroyView");
|
QMetaObject::invokeMethod(m_modelNode3DImageViewData.rootItem, "destroyView");
|
||||||
if (!m_modelNodePreviewImageCommand.componentPath().isEmpty()) {
|
if (!m_modelNodePreviewImageCommand.componentPath().isEmpty()) {
|
||||||
// If component changes, puppet will need a reset anyway, so we can cache the image
|
// If component changes, puppet will need a reset anyway, so we can cache the image
|
||||||
m_modelNodePreviewImageCache.insert(m_modelNodePreviewImageCommand.componentPath(), renderImage);
|
m_modelNodePreviewImageCache.insert(m_modelNodePreviewImageCommand.componentPath(), renderImage);
|
||||||
@@ -705,9 +896,9 @@ static QRectF itemBoundingRect(QQuickItem *item)
|
|||||||
|
|
||||||
void Qt5InformationNodeInstanceServer::doRenderModelNode2DImageView()
|
void Qt5InformationNodeInstanceServer::doRenderModelNode2DImageView()
|
||||||
{
|
{
|
||||||
if (m_ModelNode2DImageViewRootItem) {
|
if (m_modelNode2DImageViewData.rootItem) {
|
||||||
if (!m_ModelNode2DImageViewContentItem)
|
if (!m_modelNode2DImageViewData.contentItem)
|
||||||
m_ModelNode2DImageViewContentItem = getContentItemForRendering(m_ModelNode2DImageViewRootItem);
|
m_modelNode2DImageViewData.contentItem = getContentItemForRendering(m_modelNode2DImageViewData.rootItem);
|
||||||
|
|
||||||
// Key number is the same as in 3D case as they produce image for same purpose
|
// Key number is the same as in 3D case as they produce image for same purpose
|
||||||
auto imgContainer = ImageContainer(m_modelNodePreviewImageCommand.instanceId(), {}, 2100000001);
|
auto imgContainer = ImageContainer(m_modelNodePreviewImageCommand.instanceId(), {}, 2100000001);
|
||||||
@@ -730,7 +921,7 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode2DImageView()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
instanceItem->setParentItem(m_ModelNode2DImageViewContentItem);
|
instanceItem->setParentItem(m_modelNode2DImageViewData.contentItem);
|
||||||
|
|
||||||
// Some component may expect to always be shown at certain size, so their layouts may
|
// Some component may expect to always be shown at certain size, so their layouts may
|
||||||
// not support scaling, so let's always render at the default size if item has one and
|
// not support scaling, so let's always render at the default size if item has one and
|
||||||
@@ -742,21 +933,28 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode2DImageView()
|
|||||||
renderSize = finalSize;
|
renderSize = finalSize;
|
||||||
renderRect = QRectF(QPointF(0., 0.), QSizeF(renderSize));
|
renderRect = QRectF(QPointF(0., 0.), QSizeF(renderSize));
|
||||||
}
|
}
|
||||||
m_ModelNode2DImageView->resize(renderSize);
|
|
||||||
m_ModelNode2DImageViewRootItem->setSize(renderSize);
|
|
||||||
m_ModelNode2DImageViewContentItem->setPosition(QPointF(-renderRect.x(), -renderRect.y()));
|
|
||||||
|
|
||||||
updateNodesRecursive(m_ModelNode2DImageViewContentItem);
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
m_modelNode2DImageViewData.bufferDirty = m_modelNode2DImageViewData.bufferDirty
|
||||||
|
|| m_modelNode2DImageViewData.rootItem->width() != renderSize.width()
|
||||||
|
|| m_modelNode2DImageViewData.rootItem->height() != renderSize.height();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_modelNode2DImageViewData.window->resize(renderSize);
|
||||||
|
m_modelNode2DImageViewData.rootItem->setSize(renderSize);
|
||||||
|
m_modelNode2DImageViewData.contentItem->setPosition(QPointF(-renderRect.x(), -renderRect.y()));
|
||||||
|
|
||||||
|
updateNodesRecursive(m_modelNode2DImageViewData.contentItem);
|
||||||
|
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||||
if (Internal::QuickItemNodeInstance::unifiedRenderPath()) {
|
if (Internal::QuickItemNodeInstance::unifiedRenderPath()) {
|
||||||
renderImage = m_ModelNode2DImageView->grabWindow();
|
renderImage = m_modelNode2DImageViewData.window->grabWindow();
|
||||||
} else {
|
} else {
|
||||||
renderImage = designerSupport()->renderImageForItem(m_ModelNode2DImageViewContentItem,
|
renderImage = designerSupport()->renderImageForItem(m_modelNode2DImageViewData.contentItem,
|
||||||
renderRect, renderSize);
|
renderRect, renderSize);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
renderImage = m_ModelNode2DImageView->grabWindow();
|
renderImage = grabRenderControl(m_modelNode2DImageViewData);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!imageHasContent(renderImage))
|
if (!imageHasContent(renderImage))
|
||||||
@@ -788,13 +986,31 @@ Qt5InformationNodeInstanceServer::Qt5InformationNodeInstanceServer(NodeInstanceC
|
|||||||
m_propertyChangeTimer.setSingleShot(true);
|
m_propertyChangeTimer.setSingleShot(true);
|
||||||
m_selectionChangeTimer.setSingleShot(true);
|
m_selectionChangeTimer.setSingleShot(true);
|
||||||
m_render3DEditViewTimer.setSingleShot(true);
|
m_render3DEditViewTimer.setSingleShot(true);
|
||||||
|
m_inputEventTimer.setSingleShot(true);
|
||||||
m_renderModelNodeImageViewTimer.setSingleShot(true);
|
m_renderModelNodeImageViewTimer.setSingleShot(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt5InformationNodeInstanceServer::~Qt5InformationNodeInstanceServer()
|
Qt5InformationNodeInstanceServer::~Qt5InformationNodeInstanceServer()
|
||||||
{
|
{
|
||||||
|
m_editView3DSetupDone = false;
|
||||||
|
|
||||||
|
m_propertyChangeTimer.stop();
|
||||||
|
m_propertyChangeTimer.stop();
|
||||||
|
m_selectionChangeTimer.stop();
|
||||||
|
m_render3DEditViewTimer.stop();
|
||||||
|
m_inputEventTimer.stop();
|
||||||
|
|
||||||
|
delete m_editView3DData.rootItem;
|
||||||
|
delete m_editView3DData.window;
|
||||||
|
delete m_modelNode3DImageViewData.rootItem;
|
||||||
|
delete m_modelNode3DImageViewData.window;
|
||||||
|
delete m_modelNode2DImageViewData.rootItem;
|
||||||
|
delete m_modelNode2DImageViewData.window;
|
||||||
|
|
||||||
for (auto view : qAsConst(m_view3Ds))
|
for (auto view : qAsConst(m_view3Ds))
|
||||||
QObject::disconnect(view, nullptr, this, nullptr);
|
view->disconnect();
|
||||||
|
for (auto scene : qAsConst(m_3DSceneMap))
|
||||||
|
scene->disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Qt5InformationNodeInstanceServer::sendTokenBack()
|
void Qt5InformationNodeInstanceServer::sendTokenBack()
|
||||||
@@ -887,29 +1103,14 @@ void Qt5InformationNodeInstanceServer::initializeAuxiliaryViews()
|
|||||||
#ifdef QUICK3D_MODULE
|
#ifdef QUICK3D_MODULE
|
||||||
if (isQuick3DMode())
|
if (isQuick3DMode())
|
||||||
createEditView3D();
|
createEditView3D();
|
||||||
m_ModelNode3DImageView = createAuxiliaryQuickView(QUrl("qrc:/qtquickplugin/mockfiles/ModelNode3DImageView.qml"),
|
createAuxiliaryQuickView(QUrl("qrc:/qtquickplugin/mockfiles/ModelNode3DImageView.qml"),
|
||||||
m_ModelNode3DImageViewRootItem);
|
m_modelNode3DImageViewData);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_ModelNode2DImageView = createAuxiliaryQuickView(QUrl("qrc:/qtquickplugin/mockfiles/ModelNode2DImageView.qml"),
|
createAuxiliaryQuickView(QUrl("qrc:/qtquickplugin/mockfiles/ModelNode2DImageView.qml"),
|
||||||
m_ModelNode2DImageViewRootItem);
|
m_modelNode2DImageViewData);
|
||||||
m_ModelNode2DImageView->setDefaultAlphaBuffer(true);
|
m_modelNode2DImageViewData.window->setDefaultAlphaBuffer(true);
|
||||||
m_ModelNode2DImageView->setColor(Qt::transparent);
|
m_modelNode2DImageViewData.window->setColor(Qt::transparent);
|
||||||
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
|
||||||
if (!m_editView3D.isNull()) {
|
|
||||||
m_editView3D->show();
|
|
||||||
m_editView3D->lower();
|
|
||||||
}
|
|
||||||
if (!m_ModelNode3DImageView.isNull()) {
|
|
||||||
m_ModelNode3DImageView->show();
|
|
||||||
m_ModelNode3DImageView->lower();
|
|
||||||
}
|
|
||||||
if (!m_ModelNode2DImageView.isNull()) {
|
|
||||||
m_ModelNode2DImageView->show();
|
|
||||||
m_ModelNode2DImageView->lower();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Qt5InformationNodeInstanceServer::handleObjectPropertyChangeTimeout()
|
void Qt5InformationNodeInstanceServer::handleObjectPropertyChangeTimeout()
|
||||||
@@ -940,7 +1141,7 @@ void Qt5InformationNodeInstanceServer::createCameraAndLightGizmos(
|
|||||||
while (cameraIt != cameras.constEnd()) {
|
while (cameraIt != cameras.constEnd()) {
|
||||||
const auto cameraObjs = cameraIt.value();
|
const auto cameraObjs = cameraIt.value();
|
||||||
for (auto &obj : cameraObjs) {
|
for (auto &obj : cameraObjs) {
|
||||||
QMetaObject::invokeMethod(m_editView3DRootItem, "addCameraGizmo",
|
QMetaObject::invokeMethod(m_editView3DData.rootItem, "addCameraGizmo",
|
||||||
Q_ARG(QVariant, objectToVariant(cameraIt.key())),
|
Q_ARG(QVariant, objectToVariant(cameraIt.key())),
|
||||||
Q_ARG(QVariant, objectToVariant(obj)));
|
Q_ARG(QVariant, objectToVariant(obj)));
|
||||||
}
|
}
|
||||||
@@ -950,7 +1151,7 @@ void Qt5InformationNodeInstanceServer::createCameraAndLightGizmos(
|
|||||||
while (lightIt != lights.constEnd()) {
|
while (lightIt != lights.constEnd()) {
|
||||||
const auto lightObjs = lightIt.value();
|
const auto lightObjs = lightIt.value();
|
||||||
for (auto &obj : lightObjs) {
|
for (auto &obj : lightObjs) {
|
||||||
QMetaObject::invokeMethod(m_editView3DRootItem, "addLightGizmo",
|
QMetaObject::invokeMethod(m_editView3DData.rootItem, "addLightGizmo",
|
||||||
Q_ARG(QVariant, objectToVariant(lightIt.key())),
|
Q_ARG(QVariant, objectToVariant(lightIt.key())),
|
||||||
Q_ARG(QVariant, objectToVariant(obj)));
|
Q_ARG(QVariant, objectToVariant(obj)));
|
||||||
}
|
}
|
||||||
@@ -1134,7 +1335,7 @@ void Qt5InformationNodeInstanceServer::setup3DEditView(const QList<ServerNodeIns
|
|||||||
const QHash<QString, QVariantMap> &toolStates)
|
const QHash<QString, QVariantMap> &toolStates)
|
||||||
{
|
{
|
||||||
#ifdef QUICK3D_MODULE
|
#ifdef QUICK3D_MODULE
|
||||||
if (!m_editView3DRootItem)
|
if (!m_editView3DData.rootItem)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ServerNodeInstance root = rootNodeInstance();
|
ServerNodeInstance root = rootNodeInstance();
|
||||||
@@ -1142,13 +1343,13 @@ void Qt5InformationNodeInstanceServer::setup3DEditView(const QList<ServerNodeIns
|
|||||||
add3DViewPorts(instanceList);
|
add3DViewPorts(instanceList);
|
||||||
add3DScenes(instanceList);
|
add3DScenes(instanceList);
|
||||||
|
|
||||||
QObject::connect(m_editView3DRootItem, SIGNAL(selectionChanged(QVariant)),
|
QObject::connect(m_editView3DData.rootItem, SIGNAL(selectionChanged(QVariant)),
|
||||||
this, SLOT(handleSelectionChanged(QVariant)));
|
this, SLOT(handleSelectionChanged(QVariant)));
|
||||||
QObject::connect(m_editView3DRootItem, SIGNAL(commitObjectProperty(QVariant, QVariant)),
|
QObject::connect(m_editView3DData.rootItem, SIGNAL(commitObjectProperty(QVariant, QVariant)),
|
||||||
this, SLOT(handleObjectPropertyCommit(QVariant, QVariant)));
|
this, SLOT(handleObjectPropertyCommit(QVariant, QVariant)));
|
||||||
QObject::connect(m_editView3DRootItem, SIGNAL(changeObjectProperty(QVariant, QVariant)),
|
QObject::connect(m_editView3DData.rootItem, SIGNAL(changeObjectProperty(QVariant, QVariant)),
|
||||||
this, SLOT(handleObjectPropertyChange(QVariant, QVariant)));
|
this, SLOT(handleObjectPropertyChange(QVariant, QVariant)));
|
||||||
QObject::connect(m_editView3DRootItem, SIGNAL(notifyActiveSceneChange()),
|
QObject::connect(m_editView3DData.rootItem, SIGNAL(notifyActiveSceneChange()),
|
||||||
this, SLOT(handleActiveSceneChange()));
|
this, SLOT(handleActiveSceneChange()));
|
||||||
QObject::connect(&m_propertyChangeTimer, &QTimer::timeout,
|
QObject::connect(&m_propertyChangeTimer, &QTimer::timeout,
|
||||||
this, &Qt5InformationNodeInstanceServer::handleObjectPropertyChangeTimeout);
|
this, &Qt5InformationNodeInstanceServer::handleObjectPropertyChangeTimeout);
|
||||||
@@ -1156,6 +1357,8 @@ void Qt5InformationNodeInstanceServer::setup3DEditView(const QList<ServerNodeIns
|
|||||||
this, &Qt5InformationNodeInstanceServer::handleSelectionChangeTimeout);
|
this, &Qt5InformationNodeInstanceServer::handleSelectionChangeTimeout);
|
||||||
QObject::connect(&m_render3DEditViewTimer, &QTimer::timeout,
|
QObject::connect(&m_render3DEditViewTimer, &QTimer::timeout,
|
||||||
this, &Qt5InformationNodeInstanceServer::doRender3DEditView);
|
this, &Qt5InformationNodeInstanceServer::doRender3DEditView);
|
||||||
|
QObject::connect(&m_inputEventTimer, &QTimer::timeout,
|
||||||
|
this, &Qt5InformationNodeInstanceServer::handleInputEvents);
|
||||||
|
|
||||||
QString lastSceneId;
|
QString lastSceneId;
|
||||||
auto helper = qobject_cast<QmlDesigner::Internal::GeneralHelper *>(m_3dHelper);
|
auto helper = qobject_cast<QmlDesigner::Internal::GeneralHelper *>(m_3dHelper);
|
||||||
@@ -1167,7 +1370,7 @@ void Qt5InformationNodeInstanceServer::setup3DEditView(const QList<ServerNodeIns
|
|||||||
}
|
}
|
||||||
if (toolStates.contains(helper->globalStateId())) {
|
if (toolStates.contains(helper->globalStateId())) {
|
||||||
if (toolStates[helper->globalStateId()].contains(helper->rootSizeKey()))
|
if (toolStates[helper->globalStateId()].contains(helper->rootSizeKey()))
|
||||||
m_editView3DRootItem->setSize(toolStates[helper->globalStateId()][helper->rootSizeKey()].value<QSize>());
|
m_editView3DData.rootItem->setSize(toolStates[helper->globalStateId()][helper->rootSizeKey()].value<QSize>());
|
||||||
if (toolStates[helper->globalStateId()].contains(helper->lastSceneIdKey()))
|
if (toolStates[helper->globalStateId()].contains(helper->lastSceneIdKey()))
|
||||||
lastSceneId = toolStates[helper->globalStateId()][helper->lastSceneIdKey()].toString();
|
lastSceneId = toolStates[helper->globalStateId()][helper->lastSceneIdKey()].toString();
|
||||||
}
|
}
|
||||||
@@ -1198,7 +1401,7 @@ void Qt5InformationNodeInstanceServer::setup3DEditView(const QList<ServerNodeIns
|
|||||||
if (toolStates.contains({})) {
|
if (toolStates.contains({})) {
|
||||||
// Update tool state to an existing no-scene state before updating the active scene to
|
// Update tool state to an existing no-scene state before updating the active scene to
|
||||||
// ensure the previous state is inherited properly in all cases.
|
// ensure the previous state is inherited properly in all cases.
|
||||||
QMetaObject::invokeMethod(m_editView3DRootItem, "updateToolStates", Qt::QueuedConnection,
|
QMetaObject::invokeMethod(m_editView3DData.rootItem, "updateToolStates", Qt::QueuedConnection,
|
||||||
Q_ARG(QVariant, toolStates[{}]),
|
Q_ARG(QVariant, toolStates[{}]),
|
||||||
Q_ARG(QVariant, QVariant::fromValue(false)));
|
Q_ARG(QVariant, QVariant::fromValue(false)));
|
||||||
}
|
}
|
||||||
@@ -1456,13 +1659,13 @@ void Qt5InformationNodeInstanceServer::changeSelection(const ChangeSelectionComm
|
|||||||
// Ensure the UI has enough selection box items. If it doesn't yet have them, which can be the
|
// Ensure the UI has enough selection box items. If it doesn't yet have them, which can be the
|
||||||
// case when the first selection processed is a multiselection, we wait a bit as
|
// case when the first selection processed is a multiselection, we wait a bit as
|
||||||
// using the new boxes immediately leads to visual glitches.
|
// using the new boxes immediately leads to visual glitches.
|
||||||
int boxCount = m_editView3DRootItem->property("selectionBoxes").value<QVariantList>().size();
|
int boxCount = m_editView3DData.rootItem->property("selectionBoxes").value<QVariantList>().size();
|
||||||
if (boxCount < selectedObjs.size()) {
|
if (boxCount < selectedObjs.size()) {
|
||||||
QMetaObject::invokeMethod(m_editView3DRootItem, "ensureSelectionBoxes",
|
QMetaObject::invokeMethod(m_editView3DData.rootItem, "ensureSelectionBoxes",
|
||||||
Q_ARG(QVariant, QVariant::fromValue(selectedObjs.size())));
|
Q_ARG(QVariant, QVariant::fromValue(selectedObjs.size())));
|
||||||
m_selectionChangeTimer.start(0);
|
m_selectionChangeTimer.start(0);
|
||||||
} else {
|
} else {
|
||||||
QMetaObject::invokeMethod(m_editView3DRootItem, "selectObjects",
|
QMetaObject::invokeMethod(m_editView3DData.rootItem, "selectObjects",
|
||||||
Q_ARG(QVariant, QVariant::fromValue(selectedObjs)));
|
Q_ARG(QVariant, QVariant::fromValue(selectedObjs)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1511,27 +1714,10 @@ void Qt5InformationNodeInstanceServer::removeInstances(const RemoveInstancesComm
|
|||||||
|
|
||||||
void Qt5InformationNodeInstanceServer::inputEvent(const InputEventCommand &command)
|
void Qt5InformationNodeInstanceServer::inputEvent(const InputEventCommand &command)
|
||||||
{
|
{
|
||||||
if (m_editView3D) {
|
if (m_editView3DData.window) {
|
||||||
if (command.type() == QEvent::Wheel) {
|
m_pendingInputEventCommands.append(command);
|
||||||
QWheelEvent *we
|
if (!m_inputEventTimer.isActive())
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
m_inputEventTimer.start(0);
|
||||||
= new QWheelEvent(command.pos(), command.pos(), {0, 0}, {0, command.angleDelta()},
|
|
||||||
command.buttons(), command.modifiers(), Qt::NoScrollPhase,
|
|
||||||
false);
|
|
||||||
#else
|
|
||||||
= new QWheelEvent(command.pos(), command.pos(), {0, 0}, {0, command.angleDelta()},
|
|
||||||
0, Qt::Horizontal, command.buttons(), command.modifiers(),
|
|
||||||
Qt::NoScrollPhase, Qt::MouseEventNotSynthesized);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QGuiApplication::postEvent(m_editView3D, we);
|
|
||||||
} else {
|
|
||||||
auto me = new QMouseEvent(command.type(), command.pos(), command.button(),
|
|
||||||
command.buttons(), command.modifiers());
|
|
||||||
QGuiApplication::postEvent(m_editView3D, me);
|
|
||||||
}
|
|
||||||
|
|
||||||
render3DEditView();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1554,7 +1740,7 @@ void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &c
|
|||||||
updatedState.insert("transformMode", 2);
|
updatedState.insert("transformMode", 2);
|
||||||
break;
|
break;
|
||||||
case View3DActionCommand::FitToView:
|
case View3DActionCommand::FitToView:
|
||||||
QMetaObject::invokeMethod(m_editView3DRootItem, "fitToView");
|
QMetaObject::invokeMethod(m_editView3DData.rootItem, "fitToView");
|
||||||
break;
|
break;
|
||||||
case View3DActionCommand::SelectionModeToggle:
|
case View3DActionCommand::SelectionModeToggle:
|
||||||
updatedState.insert("selectionMode", command.isEnabled() ? 1 : 0);
|
updatedState.insert("selectionMode", command.isEnabled() ? 1 : 0);
|
||||||
@@ -1578,7 +1764,7 @@ void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &c
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!updatedState.isEmpty()) {
|
if (!updatedState.isEmpty()) {
|
||||||
QMetaObject::invokeMethod(m_editView3DRootItem, "updateToolStates",
|
QMetaObject::invokeMethod(m_editView3DData.rootItem, "updateToolStates",
|
||||||
Q_ARG(QVariant, updatedState),
|
Q_ARG(QVariant, updatedState),
|
||||||
Q_ARG(QVariant, QVariant::fromValue(false)));
|
Q_ARG(QVariant, QVariant::fromValue(false)));
|
||||||
}
|
}
|
||||||
@@ -1619,7 +1805,7 @@ void Qt5InformationNodeInstanceServer::changeIds(const ChangeIdsCommand &command
|
|||||||
qint32 sceneInstanceId = sceneInstance.instanceId();
|
qint32 sceneInstanceId = sceneInstance.instanceId();
|
||||||
for (const auto &id : command.ids) {
|
for (const auto &id : command.ids) {
|
||||||
if (sceneInstanceId == id.instanceId()) {
|
if (sceneInstanceId == id.instanceId()) {
|
||||||
QMetaObject::invokeMethod(m_editView3DRootItem, "handleActiveSceneIdChange",
|
QMetaObject::invokeMethod(m_editView3DData.rootItem, "handleActiveSceneIdChange",
|
||||||
Qt::QueuedConnection,
|
Qt::QueuedConnection,
|
||||||
Q_ARG(QVariant, QVariant(sceneInstance.id())));
|
Q_ARG(QVariant, QVariant(sceneInstance.id())));
|
||||||
render3DEditView();
|
render3DEditView();
|
||||||
@@ -1763,12 +1949,18 @@ void Qt5InformationNodeInstanceServer::update3DViewState(const Update3dViewState
|
|||||||
#ifdef QUICK3D_MODULE
|
#ifdef QUICK3D_MODULE
|
||||||
if (command.type() == Update3dViewStateCommand::SizeChange) {
|
if (command.type() == Update3dViewStateCommand::SizeChange) {
|
||||||
if (m_editView3DSetupDone) {
|
if (m_editView3DSetupDone) {
|
||||||
m_editView3DRootItem->setSize(command.size());
|
m_editView3DData.rootItem->setSize(command.size());
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
m_editView3DData.window->contentItem()->setSize(m_editView3DData.rootItem->size());
|
||||||
|
m_editView3DData.window->setGeometry(0, 0, m_editView3DData.rootItem->width(),
|
||||||
|
m_editView3DData.rootItem->height());
|
||||||
|
m_editView3DData.bufferDirty = true;
|
||||||
|
#endif
|
||||||
auto helper = qobject_cast<QmlDesigner::Internal::GeneralHelper *>(m_3dHelper);
|
auto helper = qobject_cast<QmlDesigner::Internal::GeneralHelper *>(m_3dHelper);
|
||||||
if (helper)
|
if (helper)
|
||||||
helper->storeToolState(helper->globalStateId(), helper->rootSizeKey(), QVariant(command.size()), 0);
|
helper->storeToolState(helper->globalStateId(), helper->rootSizeKey(), QVariant(command.size()), 0);
|
||||||
// Queue two renders to make sure icon gizmos update properly
|
// Queue three renders to make sure icon gizmos update properly
|
||||||
render3DEditView(2);
|
render3DEditView(3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@@ -39,6 +39,15 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QDragMoveEvent;
|
class QDragMoveEvent;
|
||||||
|
class QQuickWindow;
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
class QQuickRenderControl;
|
||||||
|
class QRhi;
|
||||||
|
class QRhiTexture;
|
||||||
|
class QRhiRenderBuffer;
|
||||||
|
class QRhiTextureRenderTarget;
|
||||||
|
class QRhiRenderPassDescriptor;
|
||||||
|
#endif
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
@@ -129,19 +138,33 @@ private:
|
|||||||
void doRenderModelNodeImageView();
|
void doRenderModelNodeImageView();
|
||||||
void doRenderModelNode3DImageView();
|
void doRenderModelNode3DImageView();
|
||||||
void doRenderModelNode2DImageView();
|
void doRenderModelNode2DImageView();
|
||||||
QQuickView *createAuxiliaryQuickView(const QUrl &url, QQuickItem *&rootItem);
|
|
||||||
void updateLockedAndHiddenStates(const QSet<ServerNodeInstance> &instances);
|
void updateLockedAndHiddenStates(const QSet<ServerNodeInstance> &instances);
|
||||||
|
void handleInputEvents();
|
||||||
|
|
||||||
|
struct RenderViewData {
|
||||||
|
QQuickWindow *window = nullptr;
|
||||||
|
QQuickItem *rootItem = nullptr;
|
||||||
|
QQuickItem *contentItem = nullptr;
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
bool bufferDirty = true;
|
||||||
|
QQuickRenderControl *renderControl = nullptr;
|
||||||
|
QRhi *rhi = nullptr;
|
||||||
|
QRhiTexture *texture = nullptr;
|
||||||
|
QRhiRenderBuffer *buffer = nullptr;
|
||||||
|
QRhiTextureRenderTarget *texTarget = nullptr;
|
||||||
|
QRhiRenderPassDescriptor *rpDesc = nullptr;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
bool initRhi(RenderViewData &viewData);
|
||||||
|
QImage grabRenderControl(RenderViewData &viewData);
|
||||||
|
void createAuxiliaryQuickView(const QUrl &url, RenderViewData &viewData);
|
||||||
|
|
||||||
|
RenderViewData m_editView3DData;
|
||||||
|
RenderViewData m_modelNode3DImageViewData;
|
||||||
|
RenderViewData m_modelNode2DImageViewData;
|
||||||
|
|
||||||
QPointer<QQuickView> m_editView3D;
|
|
||||||
QQuickItem *m_editView3DRootItem = nullptr;
|
|
||||||
QQuickItem *m_editView3DContentItem = nullptr;
|
|
||||||
bool m_editView3DSetupDone = false;
|
bool m_editView3DSetupDone = false;
|
||||||
QPointer<QQuickView> m_ModelNode3DImageView;
|
|
||||||
QQuickItem *m_ModelNode3DImageViewRootItem = nullptr;
|
|
||||||
QQuickItem *m_ModelNode3DImageViewContentItem = nullptr;
|
|
||||||
QPointer<QQuickView> m_ModelNode2DImageView;
|
|
||||||
QQuickItem *m_ModelNode2DImageViewRootItem = nullptr;
|
|
||||||
QQuickItem *m_ModelNode2DImageViewContentItem = nullptr;
|
|
||||||
RequestModelNodePreviewImageCommand m_modelNodePreviewImageCommand;
|
RequestModelNodePreviewImageCommand m_modelNodePreviewImageCommand;
|
||||||
QHash<QString, QImage> m_modelNodePreviewImageCache;
|
QHash<QString, QImage> m_modelNodePreviewImageCache;
|
||||||
QSet<QObject *> m_view3Ds;
|
QSet<QObject *> m_view3Ds;
|
||||||
@@ -156,9 +179,11 @@ private:
|
|||||||
QTimer m_selectionChangeTimer;
|
QTimer m_selectionChangeTimer;
|
||||||
QTimer m_render3DEditViewTimer;
|
QTimer m_render3DEditViewTimer;
|
||||||
QTimer m_renderModelNodeImageViewTimer;
|
QTimer m_renderModelNodeImageViewTimer;
|
||||||
|
QTimer m_inputEventTimer;
|
||||||
QVariant m_changedNode;
|
QVariant m_changedNode;
|
||||||
PropertyName m_changedProperty;
|
PropertyName m_changedProperty;
|
||||||
ChangeSelectionCommand m_lastSelectionChangeCommand;
|
ChangeSelectionCommand m_lastSelectionChangeCommand;
|
||||||
|
QList<InputEventCommand> m_pendingInputEventCommands;
|
||||||
QObject *m_3dHelper = nullptr;
|
QObject *m_3dHelper = nullptr;
|
||||||
int m_need3DEditViewRender = 0;
|
int m_need3DEditViewRender = 0;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user