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,
|
||||
RenderModelNodePreviewImage,
|
||||
Import3DSupport,
|
||||
ModelAtPos,
|
||||
None };
|
||||
|
||||
PuppetToCreatorCommand(Type type, const QVariant &data);
|
||||
|
||||
@@ -59,9 +59,10 @@ public:
|
||||
SelectBackgroundColor,
|
||||
SelectGridColor,
|
||||
ResetBackgroundColor,
|
||||
GetModelAtPos
|
||||
};
|
||||
|
||||
explicit View3DActionCommand(Type type, const QVariant &value);
|
||||
View3DActionCommand(Type type, const QVariant &value);
|
||||
|
||||
View3DActionCommand() = default;
|
||||
|
||||
|
||||
@@ -2319,6 +2319,32 @@ void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &c
|
||||
m_particleAnimationDriver->setSeekerPosition(static_cast<const View3DSeekActionCommand &>(command).position());
|
||||
break;
|
||||
#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:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -239,6 +239,16 @@ void Edit3DView::customNotification(const AbstractView *view, const QString &ide
|
||||
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
|
||||
{
|
||||
if (nodeInstanceView())
|
||||
@@ -605,5 +615,10 @@ void Edit3DView::addQuick3DImport()
|
||||
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 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 modelAtPosReady(const ModelNode &modelNode) override;
|
||||
|
||||
void sendInputEvent(QInputEvent *e) const;
|
||||
void edit3DViewResized(const QSize &size) const;
|
||||
@@ -78,8 +79,7 @@ public:
|
||||
void setSeeker(SeekerSlider *slider);
|
||||
|
||||
void addQuick3DImport();
|
||||
|
||||
protected:
|
||||
void dropMaterial(const ModelNode &matNode, const QPointF &pos);
|
||||
|
||||
private:
|
||||
void createEdit3DWidget();
|
||||
@@ -118,6 +118,7 @@ private:
|
||||
SeekerSlider *m_seeker = nullptr;
|
||||
int particlemode;
|
||||
ModelCache<QImage> m_canvasCache;
|
||||
ModelNode m_droppedMaterial;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
||||
@@ -242,12 +242,28 @@ void Edit3DWidget::dragEnterEvent(QDragEnterEvent *dragEnterEvent)
|
||||
{
|
||||
const DesignerActionManager &actionManager = QmlDesignerPlugin::instance()
|
||||
->viewManager().designerActionManager();
|
||||
if (actionManager.externalDragHasSupportedAssets(dragEnterEvent->mimeData()))
|
||||
if (actionManager.externalDragHasSupportedAssets(dragEnterEvent->mimeData())
|
||||
|| dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_MATERIAL)) {
|
||||
dragEnterEvent->acceptProposedAction();
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
->viewManager().designerActionManager();
|
||||
QHash<QString, QStringList> addedAssets = actionManager.handleExternalAssetsDrop(dropEvent->mimeData());
|
||||
|
||||
@@ -165,6 +165,7 @@ public:
|
||||
void emitUpdateActiveScene3D(const QVariantMap &sceneState);
|
||||
void emitModelNodelPreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap);
|
||||
void emitImport3DSupportChanged(const QVariantMap &supportMap);
|
||||
void emitModelAtPosResult(const ModelNode &modelNode);
|
||||
|
||||
void sendTokenToInstances(const QString &token, int number, const QVector<ModelNode> &nodeVector);
|
||||
|
||||
@@ -229,6 +230,7 @@ public:
|
||||
virtual void renderImage3DChanged(const QImage &image);
|
||||
virtual void updateActiveScene3D(const QVariantMap &sceneState);
|
||||
virtual void updateImport3DSupport(const QVariantMap &supportMap);
|
||||
virtual void modelAtPosReady(const ModelNode &modelNode);
|
||||
virtual void modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap);
|
||||
|
||||
virtual void dragStarted(QMimeData *mimeData);
|
||||
|
||||
@@ -1691,6 +1691,10 @@ void NodeInstanceView::handlePuppetToCreatorCommand(const PuppetToCreatorCommand
|
||||
} else if (command.type() == PuppetToCreatorCommand::Import3DSupport) {
|
||||
const QVariantMap supportMap = qvariant_cast<QVariantMap>(command.data());
|
||||
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*/)
|
||||
{
|
||||
}
|
||||
@@ -794,6 +797,12 @@ void AbstractView::emitImport3DSupportChanged(const QVariantMap &supportMap)
|
||||
model()->d->notifyImport3DSupportChanged(supportMap);
|
||||
}
|
||||
|
||||
void AbstractView::emitModelAtPosResult(const ModelNode &modelNode)
|
||||
{
|
||||
if (model())
|
||||
model()->d->notifyModelAtPosResult(modelNode);
|
||||
}
|
||||
|
||||
void AbstractView::emitRewriterEndTransaction()
|
||||
{
|
||||
if (model())
|
||||
|
||||
@@ -589,6 +589,11 @@ void ModelPrivate::notifyImport3DSupportChanged(const QVariantMap &supportMap)
|
||||
notifyInstanceChanges([&](AbstractView *view) { view->updateImport3DSupport(supportMap); });
|
||||
}
|
||||
|
||||
void ModelPrivate::notifyModelAtPosResult(const ModelNode &modelNode)
|
||||
{
|
||||
notifyInstanceChanges([&](AbstractView *view) { view->modelAtPosReady(modelNode); });
|
||||
}
|
||||
|
||||
void ModelPrivate::notifyDragStarted(QMimeData *mimeData)
|
||||
{
|
||||
notifyInstanceChanges([&](AbstractView *view) { view->dragStarted(mimeData); });
|
||||
|
||||
@@ -182,6 +182,7 @@ public:
|
||||
void notifyUpdateActiveScene3D(const QVariantMap &sceneState);
|
||||
void notifyModelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap);
|
||||
void notifyImport3DSupportChanged(const QVariantMap &supportMap);
|
||||
void notifyModelAtPosResult(const ModelNode &modelNode);
|
||||
|
||||
void notifyDragStarted(QMimeData *mimeData);
|
||||
void notifyDragEnded();
|
||||
|
||||
Reference in New Issue
Block a user