2020-02-11 11:33:25 +02:00
|
|
|
/****************************************************************************
|
|
|
|
|
**
|
|
|
|
|
** Copyright (C) 2020 The Qt Company Ltd.
|
|
|
|
|
** Contact: https://www.qt.io/licensing/
|
|
|
|
|
**
|
|
|
|
|
** This file is part of Qt Creator.
|
|
|
|
|
**
|
|
|
|
|
** Commercial License Usage
|
|
|
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
|
|
|
** accordance with the commercial license agreement provided with the
|
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
|
|
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
|
|
|
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
|
|
|
** information use the contact form at https://www.qt.io/contact-us.
|
|
|
|
|
**
|
|
|
|
|
** GNU General Public License Usage
|
|
|
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
|
|
|
** General Public License version 3 as published by the Free Software
|
|
|
|
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
|
|
|
** included in the packaging of this file. Please review the following
|
|
|
|
|
** information to ensure the GNU General Public License requirements will
|
|
|
|
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
|
|
|
|
**
|
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
|
|
#include "edit3dview.h"
|
|
|
|
|
#include "edit3dwidget.h"
|
|
|
|
|
#include "edit3dcanvas.h"
|
|
|
|
|
#include "edit3dactions.h"
|
|
|
|
|
#include "designmodewidget.h"
|
|
|
|
|
|
|
|
|
|
#include <nodeinstanceview.h>
|
|
|
|
|
#include <designeractionmanager.h>
|
|
|
|
|
#include <qmldesignerplugin.h>
|
|
|
|
|
#include <designersettings.h>
|
|
|
|
|
#include <qmldesignerconstants.h>
|
|
|
|
|
#include <viewmanager.h>
|
|
|
|
|
#include <qmldesignericons.h>
|
2020-03-19 13:05:36 +02:00
|
|
|
#include <designmodecontext.h>
|
2020-02-11 11:33:25 +02:00
|
|
|
#include <utils/utilsicons.h>
|
2020-03-12 15:55:30 +02:00
|
|
|
#include <coreplugin/icore.h>
|
2020-03-19 13:05:36 +02:00
|
|
|
#include <coreplugin/messagebox.h>
|
2020-02-11 11:33:25 +02:00
|
|
|
|
|
|
|
|
#include <QDebug>
|
|
|
|
|
|
|
|
|
|
namespace QmlDesigner {
|
|
|
|
|
|
|
|
|
|
Edit3DView::Edit3DView(QObject *parent)
|
|
|
|
|
: AbstractView(parent)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Edit3DView::~Edit3DView()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Edit3DView::createEdit3DWidget()
|
|
|
|
|
{
|
|
|
|
|
createEdit3DActions();
|
|
|
|
|
m_edit3DWidget = new Edit3DWidget(this);
|
2020-03-12 15:55:30 +02:00
|
|
|
|
|
|
|
|
auto editor3DContext = new Internal::Editor3DContext(m_edit3DWidget.data());
|
|
|
|
|
Core::ICore::addContextObject(editor3DContext);
|
2020-02-11 11:33:25 +02:00
|
|
|
}
|
|
|
|
|
|
2020-03-19 13:05:36 +02:00
|
|
|
void Edit3DView::checkImports()
|
|
|
|
|
{
|
|
|
|
|
bool has3dImport = false;
|
|
|
|
|
const QList<Import> imports = model()->imports();
|
|
|
|
|
for (const auto &import : imports) {
|
|
|
|
|
if (import.url() == "QtQuick3D") {
|
|
|
|
|
has3dImport = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
edit3DWidget()->showCanvas(has3dImport);
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-11 11:33:25 +02:00
|
|
|
WidgetInfo Edit3DView::widgetInfo()
|
|
|
|
|
{
|
|
|
|
|
if (!m_edit3DWidget)
|
|
|
|
|
createEdit3DWidget();
|
|
|
|
|
|
|
|
|
|
return createWidgetInfo(m_edit3DWidget.data(), nullptr, "Editor3D", WidgetInfo::CentralPane, 0, tr("3D Editor"), DesignerWidgetFlags::IgnoreErrors);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Edit3DWidget *Edit3DView::edit3DWidget() const
|
|
|
|
|
{
|
|
|
|
|
return m_edit3DWidget.data();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Edit3DView::renderImage3DChanged(const QImage &img)
|
|
|
|
|
{
|
|
|
|
|
edit3DWidget()->canvas()->updateRenderImage(img);
|
2020-03-06 16:14:12 +02:00
|
|
|
|
|
|
|
|
// Notify puppet to resize if received image wasn't correct size
|
|
|
|
|
if (img.size() != canvasSize())
|
|
|
|
|
edit3DViewResized(canvasSize());
|
2020-02-11 11:33:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState)
|
|
|
|
|
{
|
2020-03-27 20:16:29 +02:00
|
|
|
const QString sceneKey = QStringLiteral("sceneInstanceId");
|
|
|
|
|
const QString selectKey = QStringLiteral("selectionMode");
|
|
|
|
|
const QString transformKey = QStringLiteral("transformMode");
|
2020-02-11 11:33:25 +02:00
|
|
|
const QString perspectiveKey = QStringLiteral("usePerspective");
|
|
|
|
|
const QString orientationKey = QStringLiteral("globalOrientation");
|
2020-03-27 20:16:29 +02:00
|
|
|
const QString editLightKey = QStringLiteral("showEditLight");
|
|
|
|
|
const QString gridKey = QStringLiteral("showGrid");
|
2020-02-11 11:33:25 +02:00
|
|
|
|
2020-03-12 15:55:30 +02:00
|
|
|
if (sceneState.contains(sceneKey)) {
|
|
|
|
|
qint32 newActiveScene = sceneState[sceneKey].value<qint32>();
|
|
|
|
|
edit3DWidget()->canvas()->updateActiveScene(newActiveScene);
|
2020-06-11 19:10:19 +02:00
|
|
|
rootModelNode().setAuxiliaryData("active3dScene", newActiveScene);
|
2020-03-12 15:55:30 +02:00
|
|
|
}
|
2020-02-11 11:33:25 +02:00
|
|
|
|
|
|
|
|
if (sceneState.contains(selectKey))
|
2020-03-27 20:16:29 +02:00
|
|
|
m_selectionModeAction->action()->setChecked(sceneState[selectKey].toInt() == 1);
|
2020-02-11 11:33:25 +02:00
|
|
|
else
|
|
|
|
|
m_selectionModeAction->action()->setChecked(false);
|
|
|
|
|
|
|
|
|
|
if (sceneState.contains(transformKey)) {
|
|
|
|
|
const int tool = sceneState[transformKey].toInt();
|
|
|
|
|
if (tool == 0)
|
|
|
|
|
m_moveToolAction->action()->setChecked(true);
|
|
|
|
|
else if (tool == 1)
|
|
|
|
|
m_rotateToolAction->action()->setChecked(true);
|
|
|
|
|
else
|
|
|
|
|
m_scaleToolAction->action()->setChecked(true);
|
|
|
|
|
} else {
|
|
|
|
|
m_moveToolAction->action()->setChecked(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sceneState.contains(perspectiveKey))
|
|
|
|
|
m_cameraModeAction->action()->setChecked(sceneState[perspectiveKey].toBool());
|
|
|
|
|
else
|
|
|
|
|
m_cameraModeAction->action()->setChecked(false);
|
2020-03-27 20:16:29 +02:00
|
|
|
|
2020-02-11 11:33:25 +02:00
|
|
|
if (sceneState.contains(orientationKey))
|
|
|
|
|
m_orientationModeAction->action()->setChecked(sceneState[orientationKey].toBool());
|
|
|
|
|
else
|
|
|
|
|
m_orientationModeAction->action()->setChecked(false);
|
2020-03-27 20:16:29 +02:00
|
|
|
|
2020-02-11 11:33:25 +02:00
|
|
|
if (sceneState.contains(editLightKey))
|
|
|
|
|
m_editLightAction->action()->setChecked(sceneState[editLightKey].toBool());
|
|
|
|
|
else
|
|
|
|
|
m_editLightAction->action()->setChecked(false);
|
2020-03-27 20:16:29 +02:00
|
|
|
|
|
|
|
|
if (sceneState.contains(gridKey))
|
|
|
|
|
m_showGridAction->action()->setChecked(sceneState[gridKey].toBool());
|
|
|
|
|
else
|
|
|
|
|
m_showGridAction->action()->setChecked(false);
|
2020-02-11 11:33:25 +02:00
|
|
|
}
|
|
|
|
|
|
2020-03-19 13:05:36 +02:00
|
|
|
void Edit3DView::modelAttached(Model *model)
|
|
|
|
|
{
|
|
|
|
|
AbstractView::modelAttached(model);
|
|
|
|
|
|
|
|
|
|
checkImports();
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-06 16:14:12 +02:00
|
|
|
void Edit3DView::modelAboutToBeDetached(Model *model)
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(model)
|
|
|
|
|
|
2020-03-19 13:05:36 +02:00
|
|
|
// Hide the canvas when model is detached (i.e. changing documents)
|
|
|
|
|
edit3DWidget()->showCanvas(false);
|
|
|
|
|
|
|
|
|
|
AbstractView::modelAboutToBeDetached(model);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Edit3DView::importsChanged(const QList<Import> &addedImports,
|
|
|
|
|
const QList<Import> &removedImports)
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(addedImports)
|
|
|
|
|
Q_UNUSED(removedImports)
|
|
|
|
|
|
|
|
|
|
checkImports();
|
2020-03-06 16:14:12 +02:00
|
|
|
}
|
|
|
|
|
|
2020-04-21 13:30:44 +03:00
|
|
|
void Edit3DView::customNotification(const AbstractView *view, const QString &identifier,
|
|
|
|
|
const QList<ModelNode> &nodeList, const QList<QVariant> &data)
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(view)
|
|
|
|
|
Q_UNUSED(nodeList)
|
|
|
|
|
Q_UNUSED(data)
|
|
|
|
|
|
|
|
|
|
if (identifier == "asset_import_update")
|
|
|
|
|
resetPuppet();
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-11 11:33:25 +02:00
|
|
|
void Edit3DView::sendInputEvent(QInputEvent *e) const
|
|
|
|
|
{
|
2020-03-13 12:09:02 +02:00
|
|
|
if (nodeInstanceView())
|
|
|
|
|
nodeInstanceView()->sendInputEvent(e);
|
2020-02-11 11:33:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Edit3DView::edit3DViewResized(const QSize &size) const
|
|
|
|
|
{
|
2020-03-13 12:09:02 +02:00
|
|
|
if (nodeInstanceView())
|
|
|
|
|
nodeInstanceView()->edit3DViewResized(size);
|
2020-02-11 11:33:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QSize Edit3DView::canvasSize() const
|
|
|
|
|
{
|
|
|
|
|
if (!m_edit3DWidget.isNull() && m_edit3DWidget->canvas())
|
|
|
|
|
return m_edit3DWidget->canvas()->size();
|
|
|
|
|
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Edit3DView::createEdit3DActions()
|
|
|
|
|
{
|
|
|
|
|
m_selectionModeAction
|
|
|
|
|
= new Edit3DAction(
|
2020-03-20 16:27:55 +02:00
|
|
|
QmlDesigner::Constants::EDIT3D_SELECTION_MODE, View3DActionCommand::SelectionModeToggle,
|
2020-03-10 16:45:52 +01:00
|
|
|
QCoreApplication::translate("SelectionModeToggleAction", "Toggle Group/Single Selection Mode"),
|
2020-02-11 11:33:25 +02:00
|
|
|
QKeySequence(Qt::Key_Q), true, false, Icons::EDIT3D_SELECTION_MODE_OFF.icon(),
|
|
|
|
|
Icons::EDIT3D_SELECTION_MODE_ON.icon());
|
|
|
|
|
|
|
|
|
|
m_moveToolAction
|
|
|
|
|
= new Edit3DAction(
|
2020-03-20 16:27:55 +02:00
|
|
|
QmlDesigner::Constants::EDIT3D_MOVE_TOOL, View3DActionCommand::MoveTool,
|
2020-02-11 11:33:25 +02:00
|
|
|
QCoreApplication::translate("MoveToolAction", "Activate Move Tool"),
|
|
|
|
|
QKeySequence(Qt::Key_W), true, true, Icons::EDIT3D_MOVE_TOOL_OFF.icon(),
|
|
|
|
|
Icons::EDIT3D_MOVE_TOOL_ON.icon());
|
|
|
|
|
|
|
|
|
|
m_rotateToolAction
|
|
|
|
|
= new Edit3DAction(
|
2020-03-20 16:27:55 +02:00
|
|
|
QmlDesigner::Constants::EDIT3D_ROTATE_TOOL, View3DActionCommand::RotateTool,
|
2020-02-11 11:33:25 +02:00
|
|
|
QCoreApplication::translate("RotateToolAction", "Activate Rotate Tool"),
|
|
|
|
|
QKeySequence(Qt::Key_E), true, false, Icons::EDIT3D_ROTATE_TOOL_OFF.icon(),
|
|
|
|
|
Icons::EDIT3D_ROTATE_TOOL_ON.icon());
|
|
|
|
|
|
|
|
|
|
m_scaleToolAction
|
|
|
|
|
= new Edit3DAction(
|
2020-03-20 16:27:55 +02:00
|
|
|
QmlDesigner::Constants::EDIT3D_SCALE_TOOL, View3DActionCommand::ScaleTool,
|
2020-02-11 11:33:25 +02:00
|
|
|
QCoreApplication::translate("ScaleToolAction", "Activate Scale Tool"),
|
|
|
|
|
QKeySequence(Qt::Key_R), true, false, Icons::EDIT3D_SCALE_TOOL_OFF.icon(),
|
|
|
|
|
Icons::EDIT3D_SCALE_TOOL_ON.icon());
|
|
|
|
|
|
|
|
|
|
m_fitAction = new Edit3DAction(
|
2020-03-20 16:27:55 +02:00
|
|
|
QmlDesigner::Constants::EDIT3D_FIT_SELECTED, View3DActionCommand::FitToView,
|
2020-03-10 16:45:52 +01:00
|
|
|
QCoreApplication::translate("FitToViewAction", "Fit Selected Object to View"),
|
2020-02-11 11:33:25 +02:00
|
|
|
QKeySequence(Qt::Key_F), false, false, Icons::EDIT3D_FIT_SELECTED_OFF.icon(), {});
|
|
|
|
|
|
|
|
|
|
m_cameraModeAction
|
|
|
|
|
= new Edit3DAction(
|
2020-03-20 16:27:55 +02:00
|
|
|
QmlDesigner::Constants::EDIT3D_EDIT_CAMERA, View3DActionCommand::CameraToggle,
|
2020-03-10 16:45:52 +01:00
|
|
|
QCoreApplication::translate("CameraToggleAction", "Toggle Perspective/Orthographic Edit Camera"),
|
2020-02-11 11:33:25 +02:00
|
|
|
QKeySequence(Qt::Key_T), true, false, Icons::EDIT3D_EDIT_CAMERA_OFF.icon(),
|
|
|
|
|
Icons::EDIT3D_EDIT_CAMERA_ON.icon());
|
|
|
|
|
|
|
|
|
|
m_orientationModeAction
|
|
|
|
|
= new Edit3DAction(
|
2020-03-20 16:27:55 +02:00
|
|
|
QmlDesigner::Constants::EDIT3D_ORIENTATION, View3DActionCommand::OrientationToggle,
|
2020-03-10 16:45:52 +01:00
|
|
|
QCoreApplication::translate("OrientationToggleAction", "Toggle Global/Local Orientation"),
|
2020-02-11 11:33:25 +02:00
|
|
|
QKeySequence(Qt::Key_Y), true, false, Icons::EDIT3D_ORIENTATION_OFF.icon(),
|
|
|
|
|
Icons::EDIT3D_ORIENTATION_ON.icon());
|
|
|
|
|
|
|
|
|
|
m_editLightAction
|
|
|
|
|
= new Edit3DAction(
|
2020-03-20 16:27:55 +02:00
|
|
|
QmlDesigner::Constants::EDIT3D_EDIT_LIGHT, View3DActionCommand::EditLightToggle,
|
2020-03-10 16:45:52 +01:00
|
|
|
QCoreApplication::translate("EditLightToggleAction", "Toggle Edit Light On/Off"),
|
2020-02-11 11:33:25 +02:00
|
|
|
QKeySequence(Qt::Key_U), true, false, Icons::EDIT3D_LIGHT_OFF.icon(),
|
|
|
|
|
Icons::EDIT3D_LIGHT_ON.icon());
|
|
|
|
|
|
2020-03-27 20:16:29 +02:00
|
|
|
m_showGridAction = new Edit3DAction(
|
|
|
|
|
QmlDesigner::Constants::EDIT3D_EDIT_SHOW_GRID, View3DActionCommand::ShowGrid,
|
2020-07-01 17:09:11 +02:00
|
|
|
QCoreApplication::translate("ShowGridAction", "Toggle Grid Visibility"),
|
2020-03-27 20:16:29 +02:00
|
|
|
QKeySequence(Qt::Key_G), true, true, Icons::EDIT3D_GRID_OFF.icon(),
|
|
|
|
|
Icons::EDIT3D_GRID_ON.icon());
|
|
|
|
|
|
2020-02-11 11:33:25 +02:00
|
|
|
SelectionContextOperation resetTrigger = [this](const SelectionContext &) {
|
|
|
|
|
setCurrentStateNode(rootModelNode());
|
|
|
|
|
resetPuppet();
|
|
|
|
|
};
|
|
|
|
|
m_resetAction
|
|
|
|
|
= new Edit3DAction(
|
2020-03-20 16:27:55 +02:00
|
|
|
QmlDesigner::Constants::EDIT3D_RESET_VIEW, View3DActionCommand::Empty,
|
2020-02-11 11:33:25 +02:00
|
|
|
QCoreApplication::translate("ResetView", "Reset View"),
|
|
|
|
|
QKeySequence(Qt::Key_P), false, false, Utils::Icons::RESET_TOOLBAR.icon(), {},
|
|
|
|
|
resetTrigger);
|
|
|
|
|
|
|
|
|
|
m_leftActions << m_selectionModeAction;
|
|
|
|
|
m_leftActions << nullptr; // Null indicates separator
|
|
|
|
|
m_leftActions << nullptr; // Second null after separator indicates an exclusive group
|
|
|
|
|
m_leftActions << m_moveToolAction;
|
|
|
|
|
m_leftActions << m_rotateToolAction;
|
|
|
|
|
m_leftActions << m_scaleToolAction;
|
|
|
|
|
m_leftActions << nullptr;
|
|
|
|
|
m_leftActions << m_fitAction;
|
|
|
|
|
m_leftActions << nullptr;
|
|
|
|
|
m_leftActions << m_cameraModeAction;
|
|
|
|
|
m_leftActions << m_orientationModeAction;
|
|
|
|
|
m_leftActions << m_editLightAction;
|
2020-03-27 20:16:29 +02:00
|
|
|
m_leftActions << m_showGridAction;
|
2020-02-11 11:33:25 +02:00
|
|
|
|
|
|
|
|
m_rightActions << m_resetAction;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QVector<Edit3DAction *> Edit3DView::leftActions() const
|
|
|
|
|
{
|
|
|
|
|
return m_leftActions;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QVector<Edit3DAction *> Edit3DView::rightActions() const
|
|
|
|
|
{
|
|
|
|
|
return m_rightActions;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-19 13:05:36 +02:00
|
|
|
void Edit3DView::addQuick3DImport()
|
|
|
|
|
{
|
2020-04-24 12:21:35 +03:00
|
|
|
if (model()) {
|
|
|
|
|
const QList<Import> imports = model()->possibleImports();
|
|
|
|
|
for (const auto &import : imports) {
|
|
|
|
|
if (import.url() == "QtQuick3D") {
|
|
|
|
|
model()->changeImports({import}, {});
|
|
|
|
|
|
|
|
|
|
// Subcomponent manager update needed to make item library entries appear
|
|
|
|
|
QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManager();
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-03-19 13:05:36 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Core::AsynchronousMessageBox::warning(tr("Failed to Add Import"),
|
|
|
|
|
tr("Could not add QtQuick3D import to project."));
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-11 11:33:25 +02:00
|
|
|
}
|
|
|
|
|
|