forked from qt-creator/qt-creator
QmlDesigner: Implement drag-n-drop materials to the 3D Editor
Fixes: QDS-7011 Change-Id: Id6e4aea2c19561ea861507480636ae2358ece067 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -40,6 +40,7 @@ public:
|
|||||||
ActiveSceneChanged,
|
ActiveSceneChanged,
|
||||||
RenderModelNodePreviewImage,
|
RenderModelNodePreviewImage,
|
||||||
Import3DSupport,
|
Import3DSupport,
|
||||||
|
ModelAtPos,
|
||||||
None };
|
None };
|
||||||
|
|
||||||
PuppetToCreatorCommand(Type type, const QVariant &data);
|
PuppetToCreatorCommand(Type type, const QVariant &data);
|
||||||
|
|||||||
@@ -59,9 +59,10 @@ public:
|
|||||||
SelectBackgroundColor,
|
SelectBackgroundColor,
|
||||||
SelectGridColor,
|
SelectGridColor,
|
||||||
ResetBackgroundColor,
|
ResetBackgroundColor,
|
||||||
|
GetModelAtPos
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit View3DActionCommand(Type type, const QVariant &value);
|
View3DActionCommand(Type type, const QVariant &value);
|
||||||
|
|
||||||
View3DActionCommand() = default;
|
View3DActionCommand() = default;
|
||||||
|
|
||||||
|
|||||||
@@ -2319,6 +2319,32 @@ void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &c
|
|||||||
m_particleAnimationDriver->setSeekerPosition(static_cast<const View3DSeekActionCommand &>(command).position());
|
m_particleAnimationDriver->setSeekerPosition(static_cast<const View3DSeekActionCommand &>(command).position());
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef QUICK3D_MODULE
|
||||||
|
case View3DActionCommand::GetModelAtPos: {
|
||||||
|
// pick a Quick3DModel at view position
|
||||||
|
auto helper = qobject_cast<QmlDesigner::Internal::GeneralHelper *>(m_3dHelper);
|
||||||
|
if (!helper)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QQmlProperty editViewProp(m_editView3DData.rootItem, "editView", context());
|
||||||
|
QObject *obj = qvariant_cast<QObject *>(editViewProp.read());
|
||||||
|
QQuick3DViewport *editView = qobject_cast<QQuick3DViewport *>(obj);
|
||||||
|
|
||||||
|
QPointF pos = command.value().toPointF();
|
||||||
|
QQuick3DModel *hitModel = helper->pickViewAt(editView, pos.x(), pos.y()).objectHit();
|
||||||
|
|
||||||
|
// filter out picks of models created dynamically or inside components
|
||||||
|
QQuick3DModel *resolvedPick = qobject_cast<QQuick3DModel *>(helper->resolvePick(hitModel));
|
||||||
|
|
||||||
|
if (resolvedPick) {
|
||||||
|
ServerNodeInstance instance = instanceForObject(resolvedPick);
|
||||||
|
nodeInstanceClient()->handlePuppetToCreatorCommand(
|
||||||
|
{PuppetToCreatorCommand::ModelAtPos, QVariant(instance.instanceId())});
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -239,6 +239,16 @@ void Edit3DView::customNotification(const AbstractView *view, const QString &ide
|
|||||||
resetPuppet();
|
resetPuppet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Edit3DView::modelAtPosReady(const ModelNode &modelNode)
|
||||||
|
{
|
||||||
|
if (!m_droppedMaterial.isValid() || !modelNode.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
executeInTransaction(__FUNCTION__, [&] {
|
||||||
|
assignMaterialTo3dModel(modelNode, m_droppedMaterial);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void Edit3DView::sendInputEvent(QInputEvent *e) const
|
void Edit3DView::sendInputEvent(QInputEvent *e) const
|
||||||
{
|
{
|
||||||
if (nodeInstanceView())
|
if (nodeInstanceView())
|
||||||
@@ -605,5 +615,10 @@ void Edit3DView::addQuick3DImport()
|
|||||||
tr("Could not add QtQuick3D import to project."));
|
tr("Could not add QtQuick3D import to project."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Edit3DView::dropMaterial(const ModelNode &matNode, const QPointF &pos)
|
||||||
|
{
|
||||||
|
m_droppedMaterial = matNode;
|
||||||
|
QmlDesignerPlugin::instance()->viewManager().nodeInstanceView()->view3DAction({View3DActionCommand::GetModelAtPos, pos});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ public:
|
|||||||
void modelAboutToBeDetached(Model *model) override;
|
void modelAboutToBeDetached(Model *model) override;
|
||||||
void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override;
|
void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override;
|
||||||
void customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data) override;
|
void customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data) override;
|
||||||
|
void modelAtPosReady(const ModelNode &modelNode) override;
|
||||||
|
|
||||||
void sendInputEvent(QInputEvent *e) const;
|
void sendInputEvent(QInputEvent *e) const;
|
||||||
void edit3DViewResized(const QSize &size) const;
|
void edit3DViewResized(const QSize &size) const;
|
||||||
@@ -78,8 +79,7 @@ public:
|
|||||||
void setSeeker(SeekerSlider *slider);
|
void setSeeker(SeekerSlider *slider);
|
||||||
|
|
||||||
void addQuick3DImport();
|
void addQuick3DImport();
|
||||||
|
void dropMaterial(const ModelNode &matNode, const QPointF &pos);
|
||||||
protected:
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createEdit3DWidget();
|
void createEdit3DWidget();
|
||||||
@@ -118,6 +118,7 @@ private:
|
|||||||
SeekerSlider *m_seeker = nullptr;
|
SeekerSlider *m_seeker = nullptr;
|
||||||
int particlemode;
|
int particlemode;
|
||||||
ModelCache<QImage> m_canvasCache;
|
ModelCache<QImage> m_canvasCache;
|
||||||
|
ModelNode m_droppedMaterial;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
|||||||
@@ -242,12 +242,28 @@ void Edit3DWidget::dragEnterEvent(QDragEnterEvent *dragEnterEvent)
|
|||||||
{
|
{
|
||||||
const DesignerActionManager &actionManager = QmlDesignerPlugin::instance()
|
const DesignerActionManager &actionManager = QmlDesignerPlugin::instance()
|
||||||
->viewManager().designerActionManager();
|
->viewManager().designerActionManager();
|
||||||
if (actionManager.externalDragHasSupportedAssets(dragEnterEvent->mimeData()))
|
if (actionManager.externalDragHasSupportedAssets(dragEnterEvent->mimeData())
|
||||||
|
|| dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_MATERIAL)) {
|
||||||
dragEnterEvent->acceptProposedAction();
|
dragEnterEvent->acceptProposedAction();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Edit3DWidget::dropEvent(QDropEvent *dropEvent)
|
void Edit3DWidget::dropEvent(QDropEvent *dropEvent)
|
||||||
{
|
{
|
||||||
|
// handle dropping materials
|
||||||
|
if (dropEvent->mimeData()->hasFormat(Constants::MIME_TYPE_MATERIAL)) {
|
||||||
|
QByteArray data = dropEvent->mimeData()->data(Constants::MIME_TYPE_MATERIAL);
|
||||||
|
QDataStream stream(data);
|
||||||
|
qint32 internalId;
|
||||||
|
stream >> internalId;
|
||||||
|
ModelNode matNode = m_view->modelNodeForInternalId(internalId);
|
||||||
|
|
||||||
|
if (matNode.isValid())
|
||||||
|
m_view->dropMaterial(matNode, dropEvent->position());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle dropping external assets
|
||||||
const DesignerActionManager &actionManager = QmlDesignerPlugin::instance()
|
const DesignerActionManager &actionManager = QmlDesignerPlugin::instance()
|
||||||
->viewManager().designerActionManager();
|
->viewManager().designerActionManager();
|
||||||
QHash<QString, QStringList> addedAssets = actionManager.handleExternalAssetsDrop(dropEvent->mimeData());
|
QHash<QString, QStringList> addedAssets = actionManager.handleExternalAssetsDrop(dropEvent->mimeData());
|
||||||
|
|||||||
@@ -165,6 +165,7 @@ public:
|
|||||||
void emitUpdateActiveScene3D(const QVariantMap &sceneState);
|
void emitUpdateActiveScene3D(const QVariantMap &sceneState);
|
||||||
void emitModelNodelPreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap);
|
void emitModelNodelPreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap);
|
||||||
void emitImport3DSupportChanged(const QVariantMap &supportMap);
|
void emitImport3DSupportChanged(const QVariantMap &supportMap);
|
||||||
|
void emitModelAtPosResult(const ModelNode &modelNode);
|
||||||
|
|
||||||
void sendTokenToInstances(const QString &token, int number, const QVector<ModelNode> &nodeVector);
|
void sendTokenToInstances(const QString &token, int number, const QVector<ModelNode> &nodeVector);
|
||||||
|
|
||||||
@@ -229,6 +230,7 @@ public:
|
|||||||
virtual void renderImage3DChanged(const QImage &image);
|
virtual void renderImage3DChanged(const QImage &image);
|
||||||
virtual void updateActiveScene3D(const QVariantMap &sceneState);
|
virtual void updateActiveScene3D(const QVariantMap &sceneState);
|
||||||
virtual void updateImport3DSupport(const QVariantMap &supportMap);
|
virtual void updateImport3DSupport(const QVariantMap &supportMap);
|
||||||
|
virtual void modelAtPosReady(const ModelNode &modelNode);
|
||||||
virtual void modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap);
|
virtual void modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap);
|
||||||
|
|
||||||
virtual void dragStarted(QMimeData *mimeData);
|
virtual void dragStarted(QMimeData *mimeData);
|
||||||
|
|||||||
@@ -1691,6 +1691,10 @@ void NodeInstanceView::handlePuppetToCreatorCommand(const PuppetToCreatorCommand
|
|||||||
} else if (command.type() == PuppetToCreatorCommand::Import3DSupport) {
|
} else if (command.type() == PuppetToCreatorCommand::Import3DSupport) {
|
||||||
const QVariantMap supportMap = qvariant_cast<QVariantMap>(command.data());
|
const QVariantMap supportMap = qvariant_cast<QVariantMap>(command.data());
|
||||||
emitImport3DSupportChanged(supportMap);
|
emitImport3DSupportChanged(supportMap);
|
||||||
|
} else if (command.type() == PuppetToCreatorCommand::ModelAtPos) {
|
||||||
|
ModelNode modelNode = modelNodeForInternalId(command.data().toUInt());
|
||||||
|
if (modelNode.isValid())
|
||||||
|
emitModelAtPosResult(modelNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -403,6 +403,9 @@ void AbstractView::updateImport3DSupport(const QVariantMap & /*supportMap*/)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// a Quick3DModel that is picked at the requested position in the 3D Editor
|
||||||
|
void AbstractView::modelAtPosReady(const ModelNode & /*modelNode*/) {}
|
||||||
|
|
||||||
void AbstractView::modelNodePreviewPixmapChanged(const ModelNode & /*node*/, const QPixmap & /*pixmap*/)
|
void AbstractView::modelNodePreviewPixmapChanged(const ModelNode & /*node*/, const QPixmap & /*pixmap*/)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -794,6 +797,12 @@ void AbstractView::emitImport3DSupportChanged(const QVariantMap &supportMap)
|
|||||||
model()->d->notifyImport3DSupportChanged(supportMap);
|
model()->d->notifyImport3DSupportChanged(supportMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AbstractView::emitModelAtPosResult(const ModelNode &modelNode)
|
||||||
|
{
|
||||||
|
if (model())
|
||||||
|
model()->d->notifyModelAtPosResult(modelNode);
|
||||||
|
}
|
||||||
|
|
||||||
void AbstractView::emitRewriterEndTransaction()
|
void AbstractView::emitRewriterEndTransaction()
|
||||||
{
|
{
|
||||||
if (model())
|
if (model())
|
||||||
|
|||||||
@@ -589,6 +589,11 @@ void ModelPrivate::notifyImport3DSupportChanged(const QVariantMap &supportMap)
|
|||||||
notifyInstanceChanges([&](AbstractView *view) { view->updateImport3DSupport(supportMap); });
|
notifyInstanceChanges([&](AbstractView *view) { view->updateImport3DSupport(supportMap); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModelPrivate::notifyModelAtPosResult(const ModelNode &modelNode)
|
||||||
|
{
|
||||||
|
notifyInstanceChanges([&](AbstractView *view) { view->modelAtPosReady(modelNode); });
|
||||||
|
}
|
||||||
|
|
||||||
void ModelPrivate::notifyDragStarted(QMimeData *mimeData)
|
void ModelPrivate::notifyDragStarted(QMimeData *mimeData)
|
||||||
{
|
{
|
||||||
notifyInstanceChanges([&](AbstractView *view) { view->dragStarted(mimeData); });
|
notifyInstanceChanges([&](AbstractView *view) { view->dragStarted(mimeData); });
|
||||||
|
|||||||
@@ -182,6 +182,7 @@ public:
|
|||||||
void notifyUpdateActiveScene3D(const QVariantMap &sceneState);
|
void notifyUpdateActiveScene3D(const QVariantMap &sceneState);
|
||||||
void notifyModelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap);
|
void notifyModelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap);
|
||||||
void notifyImport3DSupportChanged(const QVariantMap &supportMap);
|
void notifyImport3DSupportChanged(const QVariantMap &supportMap);
|
||||||
|
void notifyModelAtPosResult(const ModelNode &modelNode);
|
||||||
|
|
||||||
void notifyDragStarted(QMimeData *mimeData);
|
void notifyDragStarted(QMimeData *mimeData);
|
||||||
void notifyDragEnded();
|
void notifyDragEnded();
|
||||||
|
|||||||
Reference in New Issue
Block a user