forked from qt-creator/qt-creator
QmlDesigner: Allow drag-n-drop a texture to the 3D Editor
Task-number: QDS-8207 Change-Id: I58bf2857e2ae1830b1dc48f352088c424d4e7c0d Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
@@ -0,0 +1,153 @@
|
|||||||
|
// Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuickDesignerTheme
|
||||||
|
import HelperWidgets
|
||||||
|
import StudioControls as StudioControls
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
color: StudioTheme.Values.themePanelBackground
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: col
|
||||||
|
padding: 5
|
||||||
|
spacing: 5
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: 5
|
||||||
|
|
||||||
|
Column {
|
||||||
|
spacing: 5
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("Select material:")
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: StudioTheme.Values.myFontSize
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: materialsListView
|
||||||
|
|
||||||
|
width: root.width * .5 - 5
|
||||||
|
height: root.height - 60
|
||||||
|
focus: true
|
||||||
|
clip: true
|
||||||
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
ScrollBar.vertical: StudioControls.ScrollBar {
|
||||||
|
visible: materialsListView.height < materialsListView.contentHeight
|
||||||
|
}
|
||||||
|
model: materialsModel
|
||||||
|
delegate: Rectangle {
|
||||||
|
width: materialsListView.width
|
||||||
|
height: 20
|
||||||
|
color: ListView.isCurrentItem ? StudioTheme.Values.themeTextSelectionColor
|
||||||
|
: "transparent"
|
||||||
|
|
||||||
|
function id() {
|
||||||
|
return modelData.match(/\((.*)\)/).pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: modelData
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
font.pixelSize: StudioTheme.Values.myFontSize
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
leftPadding: 5
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
materialsListView.currentIndex = index
|
||||||
|
rootView.updatePropsModel(id())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
spacing: 5
|
||||||
|
Text {
|
||||||
|
text: qsTr("Select property:")
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: StudioTheme.Values.myFontSize
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: propertiesListView
|
||||||
|
|
||||||
|
width: root.width * .5 - 5
|
||||||
|
height: root.height - 60
|
||||||
|
focus: true
|
||||||
|
clip: true
|
||||||
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
ScrollBar.vertical: StudioControls.ScrollBar {
|
||||||
|
visible: propertiesListView.height < propertiesListView.contentHeight
|
||||||
|
}
|
||||||
|
model: propertiesModel
|
||||||
|
delegate: Rectangle {
|
||||||
|
width: propertiesListView.width
|
||||||
|
height: 20
|
||||||
|
color: ListView.isCurrentItem ? StudioTheme.Values.themeTextSelectionColor
|
||||||
|
: "transparent"
|
||||||
|
|
||||||
|
function propName() {
|
||||||
|
return modelData
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: modelData
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
font.pixelSize: StudioTheme.Values.myFontSize
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
leftPadding: 5
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
propertiesListView.currentIndex = index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: 5
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 10
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: qsTr("Cancel")
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
rootView.closeChooseMatPropsView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: qsTr("Apply")
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
let matId = materialsListView.currentItem.id()
|
||||||
|
let prop = propertiesListView.currentItem.propName()
|
||||||
|
|
||||||
|
rootView.applyTextureToMaterial(matId, prop)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,33 +2,48 @@
|
|||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
#include "edit3dview.h"
|
#include "edit3dview.h"
|
||||||
|
|
||||||
#include "backgroundcolorselection.h"
|
#include "backgroundcolorselection.h"
|
||||||
|
#include "bindingproperty.h"
|
||||||
|
#include "designersettings.h"
|
||||||
|
#include "designmodecontext.h"
|
||||||
#include "edit3dactions.h"
|
#include "edit3dactions.h"
|
||||||
#include "edit3dcanvas.h"
|
#include "edit3dcanvas.h"
|
||||||
#include "edit3dviewconfig.h"
|
#include "edit3dviewconfig.h"
|
||||||
#include "edit3dwidget.h"
|
#include "edit3dwidget.h"
|
||||||
|
#include "materialbrowserwidget.h"
|
||||||
#include "metainfo.h"
|
#include "metainfo.h"
|
||||||
#include "nodehints.h"
|
#include "nodehints.h"
|
||||||
|
#include "nodeinstanceview.h"
|
||||||
|
#include "qmldesignerconstants.h"
|
||||||
|
#include "qmldesignericons.h"
|
||||||
|
#include "qmldesignerplugin.h"
|
||||||
#include "seekerslider.h"
|
#include "seekerslider.h"
|
||||||
|
#include "variantproperty.h"
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/messagebox.h>
|
#include <coreplugin/messagebox.h>
|
||||||
#include <designeractionmanager.h>
|
|
||||||
#include <designersettings.h>
|
|
||||||
#include <designmodecontext.h>
|
|
||||||
#include <nodeinstanceview.h>
|
|
||||||
#include <viewmanager.h>
|
|
||||||
#include <qmldesignerconstants.h>
|
|
||||||
#include <qmldesignericons.h>
|
|
||||||
#include <qmldesignerplugin.h>
|
|
||||||
|
|
||||||
|
#include <utils/algorithm.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/utilsicons.h>
|
#include <utils/utilsicons.h>
|
||||||
|
|
||||||
|
#include <QQmlContext>
|
||||||
|
#include <QQmlEngine>
|
||||||
|
#include <QQuickView>
|
||||||
#include <QToolButton>
|
#include <QToolButton>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
static QString propertyEditorResourcesPath()
|
||||||
|
{
|
||||||
|
#ifdef SHARE_QML_PATH
|
||||||
|
if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
|
||||||
|
return QLatin1String(SHARE_QML_PATH) + "/propertyEditorQmlSources";
|
||||||
|
#endif
|
||||||
|
return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString();
|
||||||
|
}
|
||||||
|
|
||||||
Edit3DView::Edit3DView(ExternalDependenciesInterface &externalDependencies)
|
Edit3DView::Edit3DView(ExternalDependenciesInterface &externalDependencies)
|
||||||
: AbstractView{externalDependencies}
|
: AbstractView{externalDependencies}
|
||||||
{
|
{
|
||||||
@@ -261,6 +276,24 @@ void Edit3DView::customNotification([[maybe_unused]] const AbstractView *view,
|
|||||||
resetPuppet();
|
resetPuppet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Edit3DView::eventFilter(QObject *obj, QEvent *event)
|
||||||
|
{
|
||||||
|
if (event->type() == QEvent::KeyPress) {
|
||||||
|
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||||
|
if (keyEvent->key() == Qt::Key_Escape) {
|
||||||
|
if (obj == m_chooseMatPropsView)
|
||||||
|
m_chooseMatPropsView->close();
|
||||||
|
}
|
||||||
|
} else if (event->type() == QEvent::Close) {
|
||||||
|
if (obj == m_chooseMatPropsView) {
|
||||||
|
m_droppedModelNode = {};
|
||||||
|
m_chooseMatPropsView->deleteLater();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return AbstractView::eventFilter(obj, event);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get node at position from puppet process
|
* @brief Get node at position from puppet process
|
||||||
*
|
*
|
||||||
@@ -278,15 +311,64 @@ void Edit3DView::nodeAtPosReady(const ModelNode &modelNode, const QVector3D &pos
|
|||||||
setSelectedModelNode(modelNode);
|
setSelectedModelNode(modelNode);
|
||||||
m_edit3DWidget->showContextMenu(m_contextMenuPos, modelNode, pos3d);
|
m_edit3DWidget->showContextMenu(m_contextMenuPos, modelNode, pos3d);
|
||||||
} else if (m_nodeAtPosReqType == NodeAtPosReqType::MaterialDrop) {
|
} else if (m_nodeAtPosReqType == NodeAtPosReqType::MaterialDrop) {
|
||||||
const bool isModel = modelNode.metaInfo().isQtQuick3DModel();
|
bool isModel = modelNode.metaInfo().isQtQuick3DModel();
|
||||||
if (m_droppedMaterial.isValid() && modelNode.isValid() && isModel) {
|
if (m_droppedModelNode.isValid() && modelNode.isValid() && isModel) {
|
||||||
executeInTransaction(__FUNCTION__, [&] {
|
executeInTransaction(__FUNCTION__, [&] {
|
||||||
assignMaterialTo3dModel(modelNode, m_droppedMaterial);
|
assignMaterialTo3dModel(modelNode, m_droppedModelNode);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (m_nodeAtPosReqType == NodeAtPosReqType::BundleMaterialDrop) {
|
} else if (m_nodeAtPosReqType == NodeAtPosReqType::BundleMaterialDrop) {
|
||||||
emitCustomNotification("drop_bundle_material", {modelNode}); // To ContentLibraryView
|
emitCustomNotification("drop_bundle_material", {modelNode}); // To ContentLibraryView
|
||||||
|
} else if (m_nodeAtPosReqType == NodeAtPosReqType::TextureDrop) {
|
||||||
|
if (m_droppedModelNode.isValid() && modelNode.isValid() && modelNode.metaInfo().isQtQuick3DModel()) {
|
||||||
|
// get model's material list
|
||||||
|
BindingProperty matsProp = modelNode.bindingProperty("materials");
|
||||||
|
QList<ModelNode> materials;
|
||||||
|
if (hasId(matsProp.expression()))
|
||||||
|
materials.append(modelNodeForId(matsProp.expression()));
|
||||||
|
else
|
||||||
|
materials = matsProp.resolveToModelNodeList();
|
||||||
|
|
||||||
|
if (materials.size() > 0) {
|
||||||
|
m_textureModels.clear();
|
||||||
|
QStringList materialsModel;
|
||||||
|
for (const ModelNode &mat : std::as_const(materials)) {
|
||||||
|
QString matName = mat.variantProperty("objectName").value().toString();
|
||||||
|
materialsModel.append(QLatin1String("%1 (%2)").arg(matName, mat.id()));
|
||||||
|
QList<PropertyName> texProps;
|
||||||
|
for (const PropertyMetaInfo &p : mat.metaInfo().properties()) {
|
||||||
|
if (p.propertyType().isQtQuick3DTexture())
|
||||||
|
texProps.append(p.name());
|
||||||
}
|
}
|
||||||
|
m_textureModels.insert(mat.id(), texProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString path = MaterialBrowserWidget::qmlSourcesPath() + "/ChooseMaterialProperty.qml";
|
||||||
|
|
||||||
|
m_chooseMatPropsView = new QQuickView;
|
||||||
|
m_chooseMatPropsView->setTitle(tr("Select a material property"));
|
||||||
|
m_chooseMatPropsView->setResizeMode(QQuickView::SizeRootObjectToView);
|
||||||
|
m_chooseMatPropsView->setMinimumSize({150, 100});
|
||||||
|
m_chooseMatPropsView->setMaximumSize({600, 400});
|
||||||
|
m_chooseMatPropsView->setWidth(450);
|
||||||
|
m_chooseMatPropsView->setHeight(300);
|
||||||
|
m_chooseMatPropsView->setFlags(Qt::Widget);
|
||||||
|
m_chooseMatPropsView->setModality(Qt::ApplicationModal);
|
||||||
|
m_chooseMatPropsView->engine()->addImportPath(propertyEditorResourcesPath() + "/imports");
|
||||||
|
m_chooseMatPropsView->rootContext()->setContextProperties({
|
||||||
|
{"rootView", QVariant::fromValue(this)},
|
||||||
|
{"materialsModel", QVariant::fromValue(materialsModel)},
|
||||||
|
{"propertiesModel", QVariant::fromValue(m_textureModels.value(materials.at(0).id()))},
|
||||||
|
});
|
||||||
|
m_chooseMatPropsView->setSource(QUrl::fromLocalFile(path));
|
||||||
|
m_chooseMatPropsView->installEventFilter(this);
|
||||||
|
m_chooseMatPropsView->show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_nodeAtPosReqType != NodeAtPosReqType::TextureDrop)
|
||||||
|
m_droppedModelNode = {};
|
||||||
m_nodeAtPosReqType = NodeAtPosReqType::None;
|
m_nodeAtPosReqType = NodeAtPosReqType::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -842,7 +924,7 @@ void Edit3DView::startContextMenu(const QPoint &pos)
|
|||||||
void Edit3DView::dropMaterial(const ModelNode &matNode, const QPointF &pos)
|
void Edit3DView::dropMaterial(const ModelNode &matNode, const QPointF &pos)
|
||||||
{
|
{
|
||||||
m_nodeAtPosReqType = NodeAtPosReqType::MaterialDrop;
|
m_nodeAtPosReqType = NodeAtPosReqType::MaterialDrop;
|
||||||
m_droppedMaterial = matNode;
|
m_droppedModelNode = matNode;
|
||||||
emitView3DAction(View3DActionType::GetNodeAtPos, pos);
|
emitView3DAction(View3DActionType::GetNodeAtPos, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -852,4 +934,37 @@ void Edit3DView::dropBundleMaterial(const QPointF &pos)
|
|||||||
emitView3DAction(View3DActionType::GetNodeAtPos, pos);
|
emitView3DAction(View3DActionType::GetNodeAtPos, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Edit3DView::dropTexture(const ModelNode &textureNode, const QPointF &pos)
|
||||||
|
{
|
||||||
|
m_nodeAtPosReqType = NodeAtPosReqType::TextureDrop;
|
||||||
|
m_droppedModelNode = textureNode;
|
||||||
|
emitView3DAction(View3DActionType::GetNodeAtPos, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Edit3DView::updatePropsModel(const QString &matId)
|
||||||
|
{
|
||||||
|
m_chooseMatPropsView->rootContext()->setContextProperty("propertiesModel",
|
||||||
|
QVariant::fromValue(m_textureModels.value(matId)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Edit3DView::applyTextureToMaterial(const QString &matId, const QString &propName)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_droppedModelNode.isValid(), return);
|
||||||
|
|
||||||
|
ModelNode mat = modelNodeForId(matId);
|
||||||
|
QTC_ASSERT(mat.isValid(), return);
|
||||||
|
|
||||||
|
BindingProperty texProp = mat.bindingProperty(propName.toLatin1());
|
||||||
|
QTC_ASSERT(texProp.isValid(), return);
|
||||||
|
|
||||||
|
texProp.setExpression(m_droppedModelNode.id());
|
||||||
|
|
||||||
|
closeChooseMatPropsView();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Edit3DView::closeChooseMatPropsView()
|
||||||
|
{
|
||||||
|
m_chooseMatPropsView->close();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
|||||||
@@ -8,14 +8,16 @@
|
|||||||
#include <modelcache.h>
|
#include <modelcache.h>
|
||||||
|
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
|
#include <QPointer>
|
||||||
#include <QSize>
|
#include <QSize>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QInputEvent;
|
|
||||||
class QAction;
|
class QAction;
|
||||||
|
class QInputEvent;
|
||||||
|
class QQuickView;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
@@ -62,6 +64,14 @@ public:
|
|||||||
void startContextMenu(const QPoint &pos);
|
void startContextMenu(const QPoint &pos);
|
||||||
void dropMaterial(const ModelNode &matNode, const QPointF &pos);
|
void dropMaterial(const ModelNode &matNode, const QPointF &pos);
|
||||||
void dropBundleMaterial(const QPointF &pos);
|
void dropBundleMaterial(const QPointF &pos);
|
||||||
|
void dropTexture(const ModelNode &textureNode, const QPointF &pos);
|
||||||
|
|
||||||
|
Q_INVOKABLE void updatePropsModel(const QString &matId);
|
||||||
|
Q_INVOKABLE void applyTextureToMaterial(const QString &matId, const QString &propName);
|
||||||
|
Q_INVOKABLE void closeChooseMatPropsView();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onEntriesChanged();
|
void onEntriesChanged();
|
||||||
@@ -70,6 +80,7 @@ private:
|
|||||||
enum class NodeAtPosReqType {
|
enum class NodeAtPosReqType {
|
||||||
BundleMaterialDrop,
|
BundleMaterialDrop,
|
||||||
MaterialDrop,
|
MaterialDrop,
|
||||||
|
TextureDrop,
|
||||||
ContextMenu,
|
ContextMenu,
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
@@ -112,10 +123,12 @@ private:
|
|||||||
SeekerSlider *m_seeker = nullptr;
|
SeekerSlider *m_seeker = nullptr;
|
||||||
int particlemode;
|
int particlemode;
|
||||||
ModelCache<QImage> m_canvasCache;
|
ModelCache<QImage> m_canvasCache;
|
||||||
ModelNode m_droppedMaterial;
|
ModelNode m_droppedModelNode;
|
||||||
NodeAtPosReqType m_nodeAtPosReqType;
|
NodeAtPosReqType m_nodeAtPosReqType;
|
||||||
QPoint m_contextMenuPos;
|
QPoint m_contextMenuPos;
|
||||||
QTimer m_compressionTimer;
|
QTimer m_compressionTimer;
|
||||||
|
QPointer<QQuickView> m_chooseMatPropsView;
|
||||||
|
QHash<QString, QList<PropertyName>> m_textureModels;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
|||||||
@@ -427,7 +427,8 @@ void Edit3DWidget::dragEnterEvent(QDragEnterEvent *dragEnterEvent)
|
|||||||
->viewManager().designerActionManager();
|
->viewManager().designerActionManager();
|
||||||
if (actionManager.externalDragHasSupportedAssets(dragEnterEvent->mimeData())
|
if (actionManager.externalDragHasSupportedAssets(dragEnterEvent->mimeData())
|
||||||
|| dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_MATERIAL)
|
|| dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_MATERIAL)
|
||||||
|| dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_BUNDLE_MATERIAL)) {
|
|| dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_BUNDLE_MATERIAL)
|
||||||
|
|| dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_TEXTURE)) {
|
||||||
dragEnterEvent->acceptProposedAction();
|
dragEnterEvent->acceptProposedAction();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -436,15 +437,23 @@ void Edit3DWidget::dropEvent(QDropEvent *dropEvent)
|
|||||||
{
|
{
|
||||||
const QPointF pos = m_canvas->mapFrom(this, dropEvent->position());
|
const QPointF pos = m_canvas->mapFrom(this, dropEvent->position());
|
||||||
|
|
||||||
// handle dropping materials
|
// handle dropping materials and textures
|
||||||
if (dropEvent->mimeData()->hasFormat(Constants::MIME_TYPE_MATERIAL)) {
|
if (dropEvent->mimeData()->hasFormat(Constants::MIME_TYPE_MATERIAL)
|
||||||
QByteArray data = dropEvent->mimeData()->data(Constants::MIME_TYPE_MATERIAL);
|
|| dropEvent->mimeData()->hasFormat(Constants::MIME_TYPE_TEXTURE)) {
|
||||||
|
bool isMaterial = dropEvent->mimeData()->hasFormat(Constants::MIME_TYPE_MATERIAL);
|
||||||
|
QByteArray data = dropEvent->mimeData()->data(isMaterial
|
||||||
|
? QString::fromLatin1(Constants::MIME_TYPE_MATERIAL)
|
||||||
|
: QString::fromLatin1(Constants::MIME_TYPE_TEXTURE));
|
||||||
QDataStream stream(data);
|
QDataStream stream(data);
|
||||||
qint32 internalId;
|
qint32 internalId;
|
||||||
stream >> internalId;
|
stream >> internalId;
|
||||||
|
|
||||||
if (ModelNode matNode = m_view->modelNodeForInternalId(internalId))
|
if (ModelNode dropNode = m_view->modelNodeForInternalId(internalId)) {
|
||||||
m_view->dropMaterial(matNode, pos);
|
if (isMaterial)
|
||||||
|
m_view->dropMaterial(dropNode, pos);
|
||||||
|
else
|
||||||
|
m_view->dropTexture(dropNode, pos);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ bool MaterialBrowserWidget::eventFilter(QObject *obj, QEvent *event)
|
|||||||
QByteArray data;
|
QByteArray data;
|
||||||
QMimeData *mimeData = new QMimeData;
|
QMimeData *mimeData = new QMimeData;
|
||||||
QDataStream stream(&data, QIODevice::WriteOnly);
|
QDataStream stream(&data, QIODevice::WriteOnly);
|
||||||
stream << m_materialToDrag.internalId();
|
stream << (isMaterial ? m_materialToDrag.internalId() : m_textureToDrag.internalId());
|
||||||
mimeData->setData(isMaterial ? QString::fromLatin1(Constants::MIME_TYPE_MATERIAL)
|
mimeData->setData(isMaterial ? QString::fromLatin1(Constants::MIME_TYPE_MATERIAL)
|
||||||
: QString::fromLatin1(Constants::MIME_TYPE_TEXTURE),
|
: QString::fromLatin1(Constants::MIME_TYPE_TEXTURE),
|
||||||
data);
|
data);
|
||||||
|
|||||||
@@ -1149,7 +1149,7 @@ bool MaterialEditorView::eventFilter(QObject *obj, QEvent *event)
|
|||||||
if (m_qmlBackEnd && m_qmlBackEnd->widget() == obj)
|
if (m_qmlBackEnd && m_qmlBackEnd->widget() == obj)
|
||||||
QMetaObject::invokeMethod(m_qmlBackEnd->widget()->rootObject(), "closeContextMenu");
|
QMetaObject::invokeMethod(m_qmlBackEnd->widget()->rootObject(), "closeContextMenu");
|
||||||
}
|
}
|
||||||
return QObject::eventFilter(obj, event);
|
return AbstractView::eventFilter(obj, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialEditorView::reloadQml()
|
void MaterialEditorView::reloadQml()
|
||||||
|
|||||||
Reference in New Issue
Block a user