forked from qt-creator/qt-creator
QmlDesigner: Add "Create" submenu to the 3D Editor's context menu
Allow adding Quick3D Node-based items to the 3D scene using the contxt menu. Fixes: QDS-7397 Fixes: QDS-7399 Fixes: QDS-7400 Change-Id: Ib0a9b1c0243e3e945b4925262f68d80d2460f516 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Samuel Ghinet <samuel.ghinet@qt.io> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
@@ -23,13 +23,13 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "designmodewidget.h"
|
|
||||||
#include "edit3dactions.h"
|
#include "edit3dactions.h"
|
||||||
#include "edit3dcanvas.h"
|
#include "edit3dcanvas.h"
|
||||||
#include "edit3dview.h"
|
#include "edit3dview.h"
|
||||||
#include "edit3dwidget.h"
|
#include "edit3dwidget.h"
|
||||||
#include "edit3dviewconfig.h"
|
#include "edit3dviewconfig.h"
|
||||||
#include "backgroundcolorselection.h"
|
#include "backgroundcolorselection.h"
|
||||||
|
#include "metainfo.h"
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/messagebox.h>
|
#include <coreplugin/messagebox.h>
|
||||||
@@ -52,11 +52,13 @@ namespace QmlDesigner {
|
|||||||
Edit3DView::Edit3DView(QObject *parent)
|
Edit3DView::Edit3DView(QObject *parent)
|
||||||
: AbstractView(parent)
|
: AbstractView(parent)
|
||||||
{
|
{
|
||||||
|
m_compressionTimer.setInterval(1000);
|
||||||
|
m_compressionTimer.setSingleShot(true);
|
||||||
|
connect(&m_compressionTimer, &QTimer::timeout, this, &Edit3DView::handleEntriesChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
Edit3DView::~Edit3DView()
|
Edit3DView::~Edit3DView()
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
void Edit3DView::createEdit3DWidget()
|
void Edit3DView::createEdit3DWidget()
|
||||||
{
|
{
|
||||||
@@ -206,6 +208,31 @@ void Edit3DView::modelAttached(Model *model)
|
|||||||
}
|
}
|
||||||
|
|
||||||
edit3DWidget()->canvas()->busyIndicator()->show();
|
edit3DWidget()->canvas()->busyIndicator()->show();
|
||||||
|
|
||||||
|
connect(model->metaInfo().itemLibraryInfo(), &ItemLibraryInfo::entriesChanged, this,
|
||||||
|
&Edit3DView::onEntriesChanged, Qt::UniqueConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Edit3DView::onEntriesChanged()
|
||||||
|
{
|
||||||
|
m_compressionTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Edit3DView::handleEntriesChanged()
|
||||||
|
{
|
||||||
|
QMap<QString, QList<ItemLibraryEntry>> entriesMap {
|
||||||
|
{"Camera", {}},
|
||||||
|
{"Lights", {}},
|
||||||
|
{"Models", {}}
|
||||||
|
};
|
||||||
|
|
||||||
|
const QList<ItemLibraryEntry> itemLibEntries = model()->metaInfo().itemLibraryInfo()->entries();
|
||||||
|
for (const ItemLibraryEntry &entry : itemLibEntries) {
|
||||||
|
if (entry.typeName().startsWith("QtQuick3D.") && entriesMap.contains(entry.category()))
|
||||||
|
entriesMap[entry.category()].append(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_edit3DWidget->updateCreateSubMenu(entriesMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Edit3DView::modelAboutToBeDetached(Model *model)
|
void Edit3DView::modelAboutToBeDetached(Model *model)
|
||||||
|
@@ -35,6 +35,7 @@
|
|||||||
#include <QtCore/qvector.h>
|
#include <QtCore/qvector.h>
|
||||||
#include <QtCore/qvariant.h>
|
#include <QtCore/qvariant.h>
|
||||||
#include <QtCore/qsize.h>
|
#include <QtCore/qsize.h>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
@@ -82,6 +83,9 @@ 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);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onEntriesChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class ModelAtPosReqType {
|
enum class ModelAtPosReqType {
|
||||||
MaterialDrop,
|
MaterialDrop,
|
||||||
@@ -91,6 +95,7 @@ private:
|
|||||||
|
|
||||||
void createEdit3DWidget();
|
void createEdit3DWidget();
|
||||||
void checkImports();
|
void checkImports();
|
||||||
|
void handleEntriesChanged();
|
||||||
|
|
||||||
Edit3DAction *createSelectBackgrounColorAction();
|
Edit3DAction *createSelectBackgrounColorAction();
|
||||||
Edit3DAction *createGridColorSelectionAction();
|
Edit3DAction *createGridColorSelectionAction();
|
||||||
@@ -129,6 +134,7 @@ private:
|
|||||||
ModelNode m_droppedMaterial;
|
ModelNode m_droppedMaterial;
|
||||||
ModelAtPosReqType m_modelAtPosReqType;
|
ModelAtPosReqType m_modelAtPosReqType;
|
||||||
QPoint m_contextMenuPos;
|
QPoint m_contextMenuPos;
|
||||||
|
QTimer m_compressionTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -23,7 +23,6 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "designersettings.h"
|
|
||||||
#include "edit3dactions.h"
|
#include "edit3dactions.h"
|
||||||
#include "edit3dcanvas.h"
|
#include "edit3dcanvas.h"
|
||||||
#include "edit3dview.h"
|
#include "edit3dview.h"
|
||||||
@@ -42,6 +41,7 @@
|
|||||||
#include <coreplugin/actionmanager/command.h>
|
#include <coreplugin/actionmanager/command.h>
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <toolbox.h>
|
#include <toolbox.h>
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/utilsicons.h>
|
#include <utils/utilsicons.h>
|
||||||
|
|
||||||
#include <QActionGroup>
|
#include <QActionGroup>
|
||||||
@@ -193,6 +193,57 @@ void Edit3DWidget::createContextMenu()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called by the view to update the "create" sub-menu when the Quick3D entries are ready
|
||||||
|
void Edit3DWidget::updateCreateSubMenu(const QMap<QString, QList<ItemLibraryEntry>> &entriesMap)
|
||||||
|
{
|
||||||
|
if (!m_contextMenu)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_createSubMenu) {
|
||||||
|
m_contextMenu->removeAction(m_createSubMenu->menuAction());
|
||||||
|
m_createSubMenu.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_nameToEntry.clear();
|
||||||
|
m_createSubMenu = m_contextMenu->addMenu(tr("Create"));
|
||||||
|
|
||||||
|
const QStringList categories = entriesMap.keys();
|
||||||
|
for (const QString &cat : categories) {
|
||||||
|
QMenu *catMenu = m_createSubMenu->addMenu(cat);
|
||||||
|
|
||||||
|
QList<ItemLibraryEntry> entries = entriesMap.value(cat);
|
||||||
|
std::sort(entries.begin(), entries.end(), [](const ItemLibraryEntry &a, const ItemLibraryEntry &b) {
|
||||||
|
return a.name() < b.name();
|
||||||
|
});
|
||||||
|
for (const ItemLibraryEntry &entry : std::as_const(entries)) {
|
||||||
|
QAction *action = catMenu->addAction(entry.name(), this, &Edit3DWidget::onCreateAction);
|
||||||
|
action->setData(entry.name());
|
||||||
|
m_nameToEntry.insert(entry.name(), entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Action triggered from the "create" sub-menu
|
||||||
|
void Edit3DWidget::onCreateAction()
|
||||||
|
{
|
||||||
|
QAction *action = qobject_cast<QAction *>(sender());
|
||||||
|
if (!action)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_view->executeInTransaction(__FUNCTION__, [&] {
|
||||||
|
int activeScene = m_view->rootModelNode().auxiliaryData("active3dScene@Internal").toInt();
|
||||||
|
|
||||||
|
auto modelNode = QmlVisualNode::createQml3DNode(m_view, m_nameToEntry.value(action->data().toString()),
|
||||||
|
activeScene).modelNode();
|
||||||
|
QTC_ASSERT(modelNode.isValid(), return);
|
||||||
|
m_view->setSelectedModelNode(modelNode);
|
||||||
|
|
||||||
|
// if added node is a Model, assign it a material
|
||||||
|
if (modelNode.isSubclassOf("QtQuick3D.Model"))
|
||||||
|
m_view->assignMaterialTo3dModel(modelNode);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void Edit3DWidget::contextHelp(const Core::IContext::HelpCallback &callback) const
|
void Edit3DWidget::contextHelp(const Core::IContext::HelpCallback &callback) const
|
||||||
{
|
{
|
||||||
if (m_view)
|
if (m_view)
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
#include <coreplugin/icontext.h>
|
#include <coreplugin/icontext.h>
|
||||||
|
#include "itemlibraryinfo.h"
|
||||||
#include <modelnode.h>
|
#include <modelnode.h>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
@@ -57,6 +58,10 @@ public:
|
|||||||
void showBackgroundColorMenu(bool show, const QPoint &pos);
|
void showBackgroundColorMenu(bool show, const QPoint &pos);
|
||||||
|
|
||||||
void showContextMenu(const QPoint &pos, const ModelNode &modelNode);
|
void showContextMenu(const QPoint &pos, const ModelNode &modelNode);
|
||||||
|
void updateCreateSubMenu(const QMap<QString, QList<ItemLibraryEntry>> &entriesMap);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onCreateAction();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void dragEnterEvent(QDragEnterEvent *dragEnterEvent) override;
|
void dragEnterEvent(QDragEnterEvent *dragEnterEvent) override;
|
||||||
@@ -77,7 +82,9 @@ private:
|
|||||||
QPointer<QMenu> m_contextMenu;
|
QPointer<QMenu> m_contextMenu;
|
||||||
QPointer<QAction> m_editMaterialAction;
|
QPointer<QAction> m_editMaterialAction;
|
||||||
QPointer<QAction> m_deleteAction;
|
QPointer<QAction> m_deleteAction;
|
||||||
|
QPointer<QMenu> m_createSubMenu;
|
||||||
ModelNode m_contextMenuTarget;
|
ModelNode m_contextMenuTarget;
|
||||||
|
QHash<QString, ItemLibraryEntry> m_nameToEntry;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
Reference in New Issue
Block a user