Integrate Edit3D view into Creator

Edit3D view is now a tab alongside Form Editor.
Buttons were moved to a Creator side task bar on Edit 3D view.

Change-Id: Ia06107e4f855ba512ffea3e628a61558894e800e
Fixes: QDS-1570
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Miikka Heikkinen
2020-02-11 11:33:25 +02:00
parent 7eda08f600
commit 4908055937
93 changed files with 2037 additions and 509 deletions

View File

@@ -29,9 +29,10 @@ HEADERS += $$PWD/puppetalivecommand.h
HEADERS += $$PWD/changeselectioncommand.h HEADERS += $$PWD/changeselectioncommand.h
HEADERS += $$PWD/drop3dlibraryitemcommand.h HEADERS += $$PWD/drop3dlibraryitemcommand.h
HEADERS += $$PWD/update3dviewstatecommand.h HEADERS += $$PWD/update3dviewstatecommand.h
HEADERS += $$PWD/enable3dviewcommand.h
HEADERS += $$PWD/view3dclosedcommand.h HEADERS += $$PWD/view3dclosedcommand.h
HEADERS += $$PWD/puppettocreatorcommand.h HEADERS += $$PWD/puppettocreatorcommand.h
HEADERS += $$PWD/inputeventcommand.h
HEADERS += $$PWD/view3dactioncommand.h
SOURCES += $$PWD/synchronizecommand.cpp SOURCES += $$PWD/synchronizecommand.cpp
SOURCES += $$PWD/debugoutputcommand.cpp SOURCES += $$PWD/debugoutputcommand.cpp
@@ -62,6 +63,7 @@ SOURCES += $$PWD/puppetalivecommand.cpp
SOURCES += $$PWD/changeselectioncommand.cpp SOURCES += $$PWD/changeselectioncommand.cpp
SOURCES += $$PWD/drop3dlibraryitemcommand.cpp SOURCES += $$PWD/drop3dlibraryitemcommand.cpp
SOURCES += $$PWD/update3dviewstatecommand.cpp SOURCES += $$PWD/update3dviewstatecommand.cpp
SOURCES += $$PWD/enable3dviewcommand.cpp
SOURCES += $$PWD/view3dclosedcommand.cpp SOURCES += $$PWD/view3dclosedcommand.cpp
SOURCES += $$PWD/puppettocreatorcommand.cpp SOURCES += $$PWD/puppettocreatorcommand.cpp
SOURCES += $$PWD/inputeventcommand.cpp
SOURCES += $$PWD/view3dactioncommand.cpp

View File

@@ -0,0 +1,96 @@
/****************************************************************************
**
** 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 "inputeventcommand.h"
#include <QDataStream>
#include <QDebug>
namespace QmlDesigner {
InputEventCommand::InputEventCommand() = default;
InputEventCommand::InputEventCommand(QInputEvent *e)
: m_type(e->type()),
m_modifiers(e->modifiers())
{
if (m_type == QEvent::Wheel) {
auto we = static_cast<QWheelEvent *>(e);
#if QT_VERSION <= QT_VERSION_CHECK(5, 15, 0)
m_pos = we->pos();
#else
m_pos = we->position().toPoint();
#endif
m_buttons = we->buttons();
m_angleDelta = we->angleDelta().y();
} else {
auto me = static_cast<QMouseEvent *>(e);
m_pos = me->pos();
m_button = me->button();
m_buttons = me->buttons();
}
}
QDataStream &operator<<(QDataStream &out, const InputEventCommand &command)
{
out << command.type();
out << command.pos();
out << command.button();
out << command.buttons();
out << command.modifiers();
out << command.angleDelta();
return out;
}
QDataStream &operator>>(QDataStream &in, InputEventCommand &command)
{
int type;
int button;
in >> type;
command.m_type = (QEvent::Type)type;
in >> command.m_pos;
in >> button;
command.m_button = (Qt::MouseButton)button;
in >> command.m_buttons;
in >> command.m_modifiers;
in >> command.m_angleDelta;
return in;
}
QDebug operator <<(QDebug debug, const InputEventCommand &command)
{
return debug.nospace() << "InputEventCommand("
<< "type: " << command.type() << ", "
<< "pos: " << command.pos() << ", "
<< "button: " << command.button() << ", "
<< "buttons: " << command.buttons() << ", "
<< "modifiers: " << command.modifiers() << ", "
<< "angleDelta: " << command.angleDelta() << ")";
}
} // namespace QmlDesigner

View File

@@ -0,0 +1,68 @@
/****************************************************************************
**
** 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.
**
****************************************************************************/
#pragma once
#include <QtCore/qmetatype.h>
#include <QtCore/qdatastream.h>
#include <QtGui/qevent.h>
#include "instancecontainer.h"
namespace QmlDesigner {
class InputEventCommand
{
friend QDataStream &operator>>(QDataStream &in, InputEventCommand &command);
friend QDebug operator <<(QDebug debug, const InputEventCommand &command);
public:
InputEventCommand();
explicit InputEventCommand(QInputEvent *e);
QEvent::Type type() const { return m_type; }
QPoint pos() const { return m_pos; }
Qt::MouseButton button() const { return m_button; }
Qt::MouseButtons buttons() const { return m_buttons; }
Qt::KeyboardModifiers modifiers() const { return m_modifiers; }
int angleDelta() const { return m_angleDelta; }
private:
QEvent::Type m_type;
QPoint m_pos;
Qt::MouseButton m_button = Qt::NoButton;
Qt::MouseButtons m_buttons = Qt::NoButton;
Qt::KeyboardModifiers m_modifiers = Qt::NoModifier;
int m_angleDelta = 0;
};
QDataStream &operator<<(QDataStream &out, const InputEventCommand &command);
QDataStream &operator>>(QDataStream &in, InputEventCommand &command);
QDebug operator <<(QDebug debug, const InputEventCommand &command);
} // namespace QmlDesigner
Q_DECLARE_METATYPE(QmlDesigner::InputEventCommand)

View File

@@ -34,7 +34,7 @@ namespace QmlDesigner {
class PuppetToCreatorCommand class PuppetToCreatorCommand
{ {
public: public:
enum Type { KeyPressed, Edit3DToolState, None }; enum Type { KeyPressed, Edit3DToolState, Render3DView, ActiveSceneChanged, None };
PuppetToCreatorCommand(Type type, const QVariant &data); PuppetToCreatorCommand(Type type, const QVariant &data);
PuppetToCreatorCommand() = default; PuppetToCreatorCommand() = default;

View File

@@ -45,6 +45,12 @@ Update3dViewStateCommand::Update3dViewStateCommand(bool active, bool hasPopup)
{ {
} }
Update3dViewStateCommand::Update3dViewStateCommand(const QSize &size)
: m_size(size)
, m_type(Update3dViewStateCommand::SizeChange)
{
}
Qt::WindowStates Update3dViewStateCommand::previousStates() const Qt::WindowStates Update3dViewStateCommand::previousStates() const
{ {
return m_previousStates; return m_previousStates;
@@ -65,6 +71,11 @@ bool Update3dViewStateCommand::hasPopup() const
return m_hasPopup; return m_hasPopup;
} }
QSize Update3dViewStateCommand::size() const
{
return m_size;
}
Update3dViewStateCommand::Type Update3dViewStateCommand::type() const Update3dViewStateCommand::Type Update3dViewStateCommand::type() const
{ {
return m_type; return m_type;
@@ -77,6 +88,7 @@ QDataStream &operator<<(QDataStream &out, const Update3dViewStateCommand &comman
out << qint32(command.isActive()); out << qint32(command.isActive());
out << qint32(command.hasPopup()); out << qint32(command.hasPopup());
out << qint32(command.type()); out << qint32(command.type());
out << command.size();
return out; return out;
} }
@@ -94,13 +106,16 @@ QDataStream &operator>>(QDataStream &in, Update3dViewStateCommand &command)
command.m_active = active; command.m_active = active;
command.m_hasPopup = hasPopup; command.m_hasPopup = hasPopup;
command.m_type = Update3dViewStateCommand::Type(type); command.m_type = Update3dViewStateCommand::Type(type);
in >> command.m_size;
return in; return in;
} }
QDebug operator<<(QDebug debug, const Update3dViewStateCommand &command) QDebug operator<<(QDebug debug, const Update3dViewStateCommand &command)
{ {
return debug.nospace() << "Update3dViewStateCommand(type: " << command.m_type << ")"; return debug.nospace() << "Update3dViewStateCommand(type: "
<< command.m_type << ","
<< command.m_size << ")";
} }
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -26,6 +26,7 @@
#pragma once #pragma once
#include <QMetaType> #include <QMetaType>
#include <QtCore/qsize.h>
namespace QmlDesigner { namespace QmlDesigner {
@@ -35,10 +36,11 @@ class Update3dViewStateCommand
friend QDebug operator<<(QDebug debug, const Update3dViewStateCommand &command); friend QDebug operator<<(QDebug debug, const Update3dViewStateCommand &command);
public: public:
enum Type { StateChange, ActiveChange, Empty }; enum Type { StateChange, ActiveChange, SizeChange, Empty };
explicit Update3dViewStateCommand(Qt::WindowStates previousStates, Qt::WindowStates currentStates); explicit Update3dViewStateCommand(Qt::WindowStates previousStates, Qt::WindowStates currentStates);
explicit Update3dViewStateCommand(bool active, bool hasPopup); explicit Update3dViewStateCommand(bool active, bool hasPopup);
explicit Update3dViewStateCommand(const QSize &size);
Update3dViewStateCommand() = default; Update3dViewStateCommand() = default;
Qt::WindowStates previousStates() const; Qt::WindowStates previousStates() const;
@@ -46,6 +48,7 @@ public:
bool isActive() const; bool isActive() const;
bool hasPopup() const; bool hasPopup() const;
QSize size() const;
Type type() const; Type type() const;
@@ -55,6 +58,7 @@ private:
bool m_active = false; bool m_active = false;
bool m_hasPopup = false; bool m_hasPopup = false;
QSize m_size;
Type m_type = Empty; Type m_type = Empty;
}; };

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2019 The Qt Company Ltd. ** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of Qt Creator. ** This file is part of Qt Creator.
@@ -23,43 +23,54 @@
** **
****************************************************************************/ ****************************************************************************/
#include "enable3dviewcommand.h" #include "view3dactioncommand.h"
#include <QDebug> #include <QDebug>
#include <QDataStream> #include <QDataStream>
namespace QmlDesigner { namespace QmlDesigner {
// open / close edit view 3D command View3DActionCommand::View3DActionCommand(Type type, bool enable)
Enable3DViewCommand::Enable3DViewCommand(bool enable) : m_type(type)
: m_enable(enable) , m_enabled(enable)
{ {
} }
bool Enable3DViewCommand::isEnable() const bool View3DActionCommand::isEnabled() const
{ {
return m_enable; return m_enabled;
} }
QDataStream &operator<<(QDataStream &out, const Enable3DViewCommand &command) View3DActionCommand::Type View3DActionCommand::type() const
{ {
out << qint32(command.isEnable()); return m_type;
}
QDataStream &operator<<(QDataStream &out, const View3DActionCommand &command)
{
out << qint32(command.isEnabled());
out << qint32(command.type());
return out; return out;
} }
QDataStream &operator>>(QDataStream &in, Enable3DViewCommand &command) QDataStream &operator>>(QDataStream &in, View3DActionCommand &command)
{ {
qint32 enable; qint32 enabled;
in >> enable; qint32 type;
command.m_enable = enable; in >> enabled;
in >> type;
command.m_enabled = bool(enabled);
command.m_type = View3DActionCommand::Type(type);
return in; return in;
} }
QDebug operator<<(QDebug debug, const Enable3DViewCommand &command) QDebug operator<<(QDebug debug, const View3DActionCommand &command)
{ {
return debug.nospace() << "Enable3DViewCommand(enable: " << command.m_enable << ")"; return debug.nospace() << "View3DActionCommand(type: "
<< command.m_type << ","
<< command.m_enabled << ")";
} }
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -0,0 +1,67 @@
/****************************************************************************
**
** 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.
**
****************************************************************************/
#pragma once
#include <QMetaType>
namespace QmlDesigner {
class View3DActionCommand
{
friend QDataStream &operator>>(QDataStream &in, View3DActionCommand &command);
friend QDebug operator<<(QDebug debug, const View3DActionCommand &command);
public:
enum Type { Empty,
MoveTool,
ScaleTool,
RotateTool,
FitToView,
SelectionModeToggle,
CameraToggle,
OrientationToggle,
EditLightToggle
};
explicit View3DActionCommand(Type type, bool enable);
View3DActionCommand() = default;
bool isEnabled() const;
Type type() const;
private:
Type m_type = Empty;
bool m_enabled = false;
};
QDataStream &operator<<(QDataStream &out, const View3DActionCommand &command);
QDataStream &operator>>(QDataStream &in, View3DActionCommand &command);
QDebug operator<<(QDebug debug, const View3DActionCommand &command);
} // namespace QmlDesigner
Q_DECLARE_METATYPE(QmlDesigner::View3DActionCommand)

View File

@@ -42,7 +42,6 @@
#include "createinstancescommand.h" #include "createinstancescommand.h"
#include "createscenecommand.h" #include "createscenecommand.h"
#include "update3dviewstatecommand.h" #include "update3dviewstatecommand.h"
#include "enable3dviewcommand.h"
#include "changevaluescommand.h" #include "changevaluescommand.h"
#include "changebindingscommand.h" #include "changebindingscommand.h"
#include "changeauxiliarycommand.h" #include "changeauxiliarycommand.h"
@@ -57,6 +56,8 @@
#include "synchronizecommand.h" #include "synchronizecommand.h"
#include "removesharedmemorycommand.h" #include "removesharedmemorycommand.h"
#include "tokencommand.h" #include "tokencommand.h"
#include "inputeventcommand.h"
#include "view3dactioncommand.h"
#include "informationchangedcommand.h" #include "informationchangedcommand.h"
#include "pixmapchangedcommand.h" #include "pixmapchangedcommand.h"
@@ -328,6 +329,16 @@ QVariant NodeInstanceClientProxy::readCommandFromIOStream(QIODevice *ioDevice, q
return command; return command;
} }
void NodeInstanceClientProxy::inputEvent(const InputEventCommand &command)
{
nodeInstanceServer()->inputEvent(command);
}
void NodeInstanceClientProxy::view3DAction(const View3DActionCommand &command)
{
nodeInstanceServer()->view3DAction(command);
}
void NodeInstanceClientProxy::readDataStream() void NodeInstanceClientProxy::readDataStream()
{ {
QList<QVariant> commandList; QList<QVariant> commandList;
@@ -386,11 +397,6 @@ void NodeInstanceClientProxy::update3DViewState(const Update3dViewStateCommand &
nodeInstanceServer()->update3DViewState(command); nodeInstanceServer()->update3DViewState(command);
} }
void NodeInstanceClientProxy::enable3DView(const Enable3DViewCommand &command)
{
nodeInstanceServer()->enable3DView(command);
}
void NodeInstanceClientProxy::clearScene(const ClearSceneCommand &command) void NodeInstanceClientProxy::clearScene(const ClearSceneCommand &command)
{ {
nodeInstanceServer()->clearScene(command); nodeInstanceServer()->clearScene(command);
@@ -479,7 +485,6 @@ void NodeInstanceClientProxy::dispatchCommand(const QVariant &command)
{ {
static const int createInstancesCommandType = QMetaType::type("CreateInstancesCommand"); static const int createInstancesCommandType = QMetaType::type("CreateInstancesCommand");
static const int update3dViewStateCommand = QMetaType::type("Update3dViewStateCommand"); static const int update3dViewStateCommand = QMetaType::type("Update3dViewStateCommand");
static const int enable3DViewCommandType = QMetaType::type("Enable3DViewCommand");
static const int changeFileUrlCommandType = QMetaType::type("ChangeFileUrlCommand"); static const int changeFileUrlCommandType = QMetaType::type("ChangeFileUrlCommand");
static const int createSceneCommandType = QMetaType::type("CreateSceneCommand"); static const int createSceneCommandType = QMetaType::type("CreateSceneCommand");
static const int clearSceneCommandType = QMetaType::type("ClearSceneCommand"); static const int clearSceneCommandType = QMetaType::type("ClearSceneCommand");
@@ -498,15 +503,17 @@ void NodeInstanceClientProxy::dispatchCommand(const QVariant &command)
static const int tokenCommandType = QMetaType::type("TokenCommand"); static const int tokenCommandType = QMetaType::type("TokenCommand");
static const int endPuppetCommandType = QMetaType::type("EndPuppetCommand"); static const int endPuppetCommandType = QMetaType::type("EndPuppetCommand");
static const int changeSelectionCommandType = QMetaType::type("ChangeSelectionCommand"); static const int changeSelectionCommandType = QMetaType::type("ChangeSelectionCommand");
static const int inputEventCommandType = QMetaType::type("InputEventCommand");
static const int view3DActionCommandType = QMetaType::type("View3DActionCommand");
const int commandType = command.userType(); const int commandType = command.userType();
if (commandType == createInstancesCommandType) if (commandType == inputEventCommandType)
inputEvent(command.value<InputEventCommand>());
else if (commandType == createInstancesCommandType)
createInstances(command.value<CreateInstancesCommand>()); createInstances(command.value<CreateInstancesCommand>());
else if (commandType == update3dViewStateCommand) else if (commandType == update3dViewStateCommand)
update3DViewState(command.value<Update3dViewStateCommand>()); update3DViewState(command.value<Update3dViewStateCommand>());
else if (commandType == enable3DViewCommandType)
enable3DView(command.value<Enable3DViewCommand>());
else if (commandType == changeFileUrlCommandType) else if (commandType == changeFileUrlCommandType)
changeFileUrl(command.value<ChangeFileUrlCommand>()); changeFileUrl(command.value<ChangeFileUrlCommand>());
else if (commandType == createSceneCommandType) else if (commandType == createSceneCommandType)
@@ -539,6 +546,8 @@ void NodeInstanceClientProxy::dispatchCommand(const QVariant &command)
redirectToken(command.value<TokenCommand>()); redirectToken(command.value<TokenCommand>());
else if (commandType == endPuppetCommandType) else if (commandType == endPuppetCommandType)
redirectToken(command.value<EndPuppetCommand>()); redirectToken(command.value<EndPuppetCommand>());
else if (commandType == view3DActionCommandType)
view3DAction(command.value<View3DActionCommand>());
else if (commandType == synchronizeCommandType) { else if (commandType == synchronizeCommandType) {
SynchronizeCommand synchronizeCommand = command.value<SynchronizeCommand>(); SynchronizeCommand synchronizeCommand = command.value<SynchronizeCommand>();
m_synchronizeId = synchronizeCommand.synchronizeId(); m_synchronizeId = synchronizeCommand.synchronizeId();

View File

@@ -46,7 +46,6 @@ class CreateInstancesCommand;
class ClearSceneCommand; class ClearSceneCommand;
class ReparentInstancesCommand; class ReparentInstancesCommand;
class Update3dViewStateCommand; class Update3dViewStateCommand;
class Enable3DViewCommand;
class ChangeFileUrlCommand; class ChangeFileUrlCommand;
class ChangeValuesCommand; class ChangeValuesCommand;
class ChangeAuxiliaryCommand; class ChangeAuxiliaryCommand;
@@ -62,6 +61,8 @@ class ChangeSelectionCommand;
class Drop3DLibraryItemCommand; class Drop3DLibraryItemCommand;
class PuppetToCreatorCommand; class PuppetToCreatorCommand;
class View3DClosedCommand; class View3DClosedCommand;
class InputEventCommand;
class View3DActionCommand;
class NodeInstanceClientProxy : public QObject, public NodeInstanceClientInterface class NodeInstanceClientProxy : public QObject, public NodeInstanceClientInterface
{ {
@@ -102,7 +103,6 @@ protected:
void createScene(const CreateSceneCommand &command); void createScene(const CreateSceneCommand &command);
void clearScene(const ClearSceneCommand &command); void clearScene(const ClearSceneCommand &command);
void update3DViewState(const Update3dViewStateCommand &command); void update3DViewState(const Update3dViewStateCommand &command);
void enable3DView(const Enable3DViewCommand &command);
void removeInstances(const RemoveInstancesCommand &command); void removeInstances(const RemoveInstancesCommand &command);
void removeProperties(const RemovePropertiesCommand &command); void removeProperties(const RemovePropertiesCommand &command);
void changePropertyBindings(const ChangeBindingsCommand &command); void changePropertyBindings(const ChangeBindingsCommand &command);
@@ -118,6 +118,8 @@ protected:
void redirectToken(const EndPuppetCommand &command); void redirectToken(const EndPuppetCommand &command);
void changeSelection(const ChangeSelectionCommand &command); void changeSelection(const ChangeSelectionCommand &command);
static QVariant readCommandFromIOStream(QIODevice *ioDevice, quint32 *readCommandCounter, quint32 *blockSize); static QVariant readCommandFromIOStream(QIODevice *ioDevice, quint32 *readCommandCounter, quint32 *blockSize);
void inputEvent(const InputEventCommand &command);
void view3DAction(const View3DActionCommand &command);
protected slots: protected slots:
void readDataStream(); void readDataStream();

View File

@@ -33,7 +33,6 @@
#include "createinstancescommand.h" #include "createinstancescommand.h"
#include "createscenecommand.h" #include "createscenecommand.h"
#include "update3dviewstatecommand.h" #include "update3dviewstatecommand.h"
#include "enable3dviewcommand.h"
#include "changevaluescommand.h" #include "changevaluescommand.h"
#include "changebindingscommand.h" #include "changebindingscommand.h"
#include "changeauxiliarycommand.h" #include "changeauxiliarycommand.h"
@@ -49,6 +48,8 @@
#include "changenodesourcecommand.h" #include "changenodesourcecommand.h"
#include "changeselectioncommand.h" #include "changeselectioncommand.h"
#include "drop3dlibraryitemcommand.h" #include "drop3dlibraryitemcommand.h"
#include "inputeventcommand.h"
#include "view3dactioncommand.h"
#include "informationchangedcommand.h" #include "informationchangedcommand.h"
#include "pixmapchangedcommand.h" #include "pixmapchangedcommand.h"
@@ -97,9 +98,6 @@ void NodeInstanceServerInterface::registerCommands()
qRegisterMetaType<Update3dViewStateCommand>("Update3dViewStateCommand"); qRegisterMetaType<Update3dViewStateCommand>("Update3dViewStateCommand");
qRegisterMetaTypeStreamOperators<Update3dViewStateCommand>("Update3dViewStateCommand"); qRegisterMetaTypeStreamOperators<Update3dViewStateCommand>("Update3dViewStateCommand");
qRegisterMetaType<Enable3DViewCommand>("Enable3DViewCommand");
qRegisterMetaTypeStreamOperators<Enable3DViewCommand>("Enable3DViewCommand");
qRegisterMetaType<ChangeBindingsCommand>("ChangeBindingsCommand"); qRegisterMetaType<ChangeBindingsCommand>("ChangeBindingsCommand");
qRegisterMetaTypeStreamOperators<ChangeBindingsCommand>("ChangeBindingsCommand"); qRegisterMetaTypeStreamOperators<ChangeBindingsCommand>("ChangeBindingsCommand");
@@ -214,6 +212,12 @@ void NodeInstanceServerInterface::registerCommands()
qRegisterMetaType<PuppetToCreatorCommand>("PuppetToCreatorCommand"); qRegisterMetaType<PuppetToCreatorCommand>("PuppetToCreatorCommand");
qRegisterMetaTypeStreamOperators<PuppetToCreatorCommand>("PuppetToCreatorCommand"); qRegisterMetaTypeStreamOperators<PuppetToCreatorCommand>("PuppetToCreatorCommand");
qRegisterMetaType<InputEventCommand>("InputEventCommand");
qRegisterMetaTypeStreamOperators<InputEventCommand>("InputEventCommand");
qRegisterMetaType<View3DActionCommand>("View3DActionCommand");
qRegisterMetaTypeStreamOperators<View3DActionCommand>("View3DActionCommand");
qRegisterMetaType<QPair<int, int>>("QPairIntInt"); qRegisterMetaType<QPair<int, int>>("QPairIntInt");
qRegisterMetaTypeStreamOperators<QPair<int, int>>("QPairIntInt"); qRegisterMetaTypeStreamOperators<QPair<int, int>>("QPairIntInt");
} }

View File

@@ -34,7 +34,6 @@ class PropertyBindingContainer;
class PropertyValueContainer; class PropertyValueContainer;
class Update3dViewStateCommand; class Update3dViewStateCommand;
class Enable3DViewCommand;
class ChangeFileUrlCommand; class ChangeFileUrlCommand;
class ChangeValuesCommand; class ChangeValuesCommand;
class ChangeBindingsCommand; class ChangeBindingsCommand;
@@ -52,6 +51,8 @@ class ChangeNodeSourceCommand;
class TokenCommand; class TokenCommand;
class RemoveSharedMemoryCommand; class RemoveSharedMemoryCommand;
class ChangeSelectionCommand; class ChangeSelectionCommand;
class InputEventCommand;
class View3DActionCommand;
class NodeInstanceServerInterface : public QObject class NodeInstanceServerInterface : public QObject
{ {
@@ -69,7 +70,6 @@ public:
virtual void createScene(const CreateSceneCommand &command) = 0; virtual void createScene(const CreateSceneCommand &command) = 0;
virtual void clearScene(const ClearSceneCommand &command) = 0; virtual void clearScene(const ClearSceneCommand &command) = 0;
virtual void update3DViewState(const Update3dViewStateCommand &command) = 0; virtual void update3DViewState(const Update3dViewStateCommand &command) = 0;
virtual void enable3DView(const Enable3DViewCommand &command) = 0;
virtual void removeInstances(const RemoveInstancesCommand &command) = 0; virtual void removeInstances(const RemoveInstancesCommand &command) = 0;
virtual void removeProperties(const RemovePropertiesCommand &command) = 0; virtual void removeProperties(const RemovePropertiesCommand &command) = 0;
virtual void changePropertyBindings(const ChangeBindingsCommand &command) = 0; virtual void changePropertyBindings(const ChangeBindingsCommand &command) = 0;
@@ -83,6 +83,8 @@ public:
virtual void token(const TokenCommand &command) = 0; virtual void token(const TokenCommand &command) = 0;
virtual void removeSharedMemory(const RemoveSharedMemoryCommand &command) = 0; virtual void removeSharedMemory(const RemoveSharedMemoryCommand &command) = 0;
virtual void changeSelection(const ChangeSelectionCommand &command) = 0; virtual void changeSelection(const ChangeSelectionCommand &command) = 0;
virtual void inputEvent(const InputEventCommand &command) = 0;
virtual void view3DAction(const View3DActionCommand &command) = 0;
virtual void benchmark(const QString &) virtual void benchmark(const QString &)
{} {}

View File

@@ -30,16 +30,11 @@ import QtQuick.Controls 2.0
import QtGraphicalEffects 1.0 import QtGraphicalEffects 1.0
import MouseArea3D 1.0 import MouseArea3D 1.0
Window { Item {
id: viewWindow id: viewRoot
width: 1024 width: 1024
height: 768 height: 768
minimumHeight: 200
minimumWidth: 200
visible: true visible: true
title: qsTr("3D Edit View [") + sceneId + qsTr("]")
// need all those flags otherwise the title bar disappears after setting WindowStaysOnTopHint flag later
flags: Qt.Window | Qt.WindowTitleHint | Qt.WindowSystemMenuHint | Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint
property Node activeScene: null property Node activeScene: null
property View3D editView: null property View3D editView: null
@@ -48,6 +43,7 @@ Window {
property alias showEditLight: btnEditViewLight.toggled property alias showEditLight: btnEditViewLight.toggled
property alias usePerspective: btnPerspective.toggled property alias usePerspective: btnPerspective.toggled
property alias globalOrientation: btnLocalGlobal.toggled property alias globalOrientation: btnLocalGlobal.toggled
property alias contentItem: contentItem
property Node selectedNode: null // This is non-null only in single selection case property Node selectedNode: null // This is non-null only in single selection case
property var selectedNodes: [] // All selected nodes property var selectedNodes: [] // All selected nodes
@@ -57,6 +53,8 @@ Window {
property var selectionBoxes: [] property var selectionBoxes: []
property rect viewPortRect: Qt.rect(0, 0, 1000, 1000) property rect viewPortRect: Qt.rect(0, 0, 1000, 1000)
property bool showButtons: false
signal selectionChanged(var selectedNodes) signal selectionChanged(var selectedNodes)
signal commitObjectProperty(var object, var propName) signal commitObjectProperty(var object, var propName)
signal changeObjectProperty(var object, var propName) signal changeObjectProperty(var object, var propName)
@@ -86,7 +84,7 @@ Window {
editView.cameraZoomFactor = Qt.binding(function() {return cameraControl._zoomFactor;}); editView.cameraZoomFactor = Qt.binding(function() {return cameraControl._zoomFactor;});
selectionBoxes.length = 0; selectionBoxes.length = 0;
updateToolStates(); updateToolStates(_generalHelper.getToolStates(sceneId), true);
} }
} }
} }
@@ -99,54 +97,62 @@ Window {
_generalHelper.enableItemUpdate(editView, (scene && scene === activeScene)); _generalHelper.enableItemUpdate(editView, (scene && scene === activeScene));
} }
function fitToView()
function restoreWindowState()
{ {
// It is expected that tool states have been initialized before calling this if (editView) {
_generalHelper.restoreWindowState(viewWindow); var targetNode = selectedNodes.length > 0
? selectionBoxes[0].model : null;
cameraControl.focusObject(targetNode, editView.camera.rotation, true);
}
} }
function updateToolStates() // If resetToDefault is true, tool states not specifically set to anything will be reset to
// their default state.
function updateToolStates(toolStates, resetToDefault)
{ {
var toolStates = _generalHelper.getToolStates(sceneId);
if ("showEditLight" in toolStates) if ("showEditLight" in toolStates)
showEditLight = toolStates.showEditLight; showEditLight = toolStates.showEditLight;
else else if (resetToDefault)
showEditLight = false; showEditLight = false;
if ("usePerspective" in toolStates) if ("usePerspective" in toolStates)
usePerspective = toolStates.usePerspective; usePerspective = toolStates.usePerspective;
else else if (resetToDefault)
usePerspective = false; usePerspective = false;
if ("globalOrientation" in toolStates) if ("globalOrientation" in toolStates)
globalOrientation = toolStates.globalOrientation; globalOrientation = toolStates.globalOrientation;
else else if (resetToDefault)
globalOrientation = false; globalOrientation = false;
var groupIndex; var groupIndex;
var group; var group;
var i; var i;
btnSelectItem.selected = false;
btnSelectGroup.selected = true;
if ("groupSelect" in toolStates) { if ("groupSelect" in toolStates) {
groupIndex = toolStates.groupSelect; groupIndex = toolStates.groupSelect;
group = toolbarButtons.buttonGroups["groupSelect"]; group = toolbarButtons.buttonGroups["groupSelect"];
for (i = 0; i < group.length; ++i) for (i = 0; i < group.length; ++i)
group[i].selected = (i === groupIndex); group[i].selected = (i === groupIndex);
_generalHelper.storeToolState(sceneId, "groupSelect", groupIndex)
} else if (resetToDefault) {
btnSelectItem.selected = true;
btnSelectGroup.selected = false;
} }
btnRotate.selected = false;
btnScale.selected = false;
btnMove.selected = true;
if ("groupTransform" in toolStates) { if ("groupTransform" in toolStates) {
groupIndex = toolStates.groupTransform; groupIndex = toolStates.groupTransform;
group = toolbarButtons.buttonGroups["groupTransform"]; group = toolbarButtons.buttonGroups["groupTransform"];
for (i = 0; i < group.length; ++i) for (i = 0; i < group.length; ++i)
group[i].selected = (i === groupIndex); group[i].selected = (i === groupIndex);
_generalHelper.storeToolState(sceneId, "groupTransform", groupIndex)
} else if (resetToDefault) {
btnRotate.selected = false;
btnScale.selected = false;
btnMove.selected = true;
} }
if ("editCamState" in toolStates) if ("editCamState" in toolStates)
cameraControl.restoreCameraState(toolStates.editCamState); cameraControl.restoreCameraState(toolStates.editCamState);
else else if (resetToDefault)
cameraControl.restoreDefaultState(); cameraControl.restoreDefaultState();
} }
@@ -324,37 +330,27 @@ Window {
_generalHelper.requestOverlayUpdate(); _generalHelper.requestOverlayUpdate();
} }
onWidthChanged: { onWidthChanged: _generalHelper.requestOverlayUpdate()
_generalHelper.requestOverlayUpdate(); onHeightChanged: _generalHelper.requestOverlayUpdate()
_generalHelper.storeWindowState(viewWindow);
}
onHeightChanged: {
_generalHelper.requestOverlayUpdate();
_generalHelper.storeWindowState(viewWindow);
}
onXChanged: _generalHelper.storeWindowState(viewWindow);
onYChanged: _generalHelper.storeWindowState(viewWindow);
onWindowStateChanged: _generalHelper.storeWindowState(viewWindow);
Node { Node {
id: overlayScene id: overlayScene
PerspectiveCamera { PerspectiveCamera {
id: overlayPerspectiveCamera id: overlayPerspectiveCamera
clipFar: viewWindow.editView ? viewWindow.editView.perpectiveCamera.clipFar : 1000 clipFar: viewRoot.editView ? viewRoot.editView.perpectiveCamera.clipFar : 1000
clipNear: viewWindow.editView ? viewWindow.editView.perpectiveCamera.clipNear : 1 clipNear: viewRoot.editView ? viewRoot.editView.perpectiveCamera.clipNear : 1
position: viewWindow.editView ? viewWindow.editView.perpectiveCamera.position : Qt.vector3d(0, 0, 0) position: viewRoot.editView ? viewRoot.editView.perpectiveCamera.position : Qt.vector3d(0, 0, 0)
rotation: viewWindow.editView ? viewWindow.editView.perpectiveCamera.rotation : Qt.vector3d(0, 0, 0) rotation: viewRoot.editView ? viewRoot.editView.perpectiveCamera.rotation : Qt.vector3d(0, 0, 0)
} }
OrthographicCamera { OrthographicCamera {
id: overlayOrthoCamera id: overlayOrthoCamera
clipFar: viewWindow.editView ? viewWindow.editView.orthoCamera.clipFar : 1000 clipFar: viewRoot.editView ? viewRoot.editView.orthoCamera.clipFar : 1000
clipNear: viewWindow.editView ? viewWindow.editView.orthoCamera.clipNear : 1 clipNear: viewRoot.editView ? viewRoot.editView.orthoCamera.clipNear : 1
position: viewWindow.editView ? viewWindow.editView.orthoCamera.position : Qt.vector3d(0, 0, 0) position: viewRoot.editView ? viewRoot.editView.orthoCamera.position : Qt.vector3d(0, 0, 0)
rotation: viewWindow.editView ? viewWindow.editView.orthoCamera.rotation : Qt.vector3d(0, 0, 0) rotation: viewRoot.editView ? viewRoot.editView.orthoCamera.rotation : Qt.vector3d(0, 0, 0)
scale: viewWindow.editView ? viewWindow.editView.orthoCamera.scale : Qt.vector3d(0, 0, 0) scale: viewRoot.editView ? viewRoot.editView.orthoCamera.scale : Qt.vector3d(0, 0, 0)
} }
MouseArea3D { MouseArea3D {
@@ -366,41 +362,41 @@ Window {
id: moveGizmo id: moveGizmo
scale: autoScale.getScale(Qt.vector3d(5, 5, 5)) scale: autoScale.getScale(Qt.vector3d(5, 5, 5))
highlightOnHover: true highlightOnHover: true
targetNode: viewWindow.selectedNode targetNode: viewRoot.selectedNode
globalOrientation: viewWindow.globalOrientation globalOrientation: viewRoot.globalOrientation
visible: viewWindow.selectedNode && btnMove.selected visible: viewRoot.selectedNode && btnMove.selected
view3D: overlayView view3D: overlayView
dragHelper: gizmoDragHelper dragHelper: gizmoDragHelper
onPositionCommit: viewWindow.commitObjectProperty(viewWindow.selectedNode, "position") onPositionCommit: viewRoot.commitObjectProperty(viewRoot.selectedNode, "position")
onPositionMove: viewWindow.changeObjectProperty(viewWindow.selectedNode, "position") onPositionMove: viewRoot.changeObjectProperty(viewRoot.selectedNode, "position")
} }
ScaleGizmo { ScaleGizmo {
id: scaleGizmo id: scaleGizmo
scale: autoScale.getScale(Qt.vector3d(5, 5, 5)) scale: autoScale.getScale(Qt.vector3d(5, 5, 5))
highlightOnHover: true highlightOnHover: true
targetNode: viewWindow.selectedNode targetNode: viewRoot.selectedNode
visible: viewWindow.selectedNode && btnScale.selected visible: viewRoot.selectedNode && btnScale.selected
view3D: overlayView view3D: overlayView
dragHelper: gizmoDragHelper dragHelper: gizmoDragHelper
onScaleCommit: viewWindow.commitObjectProperty(viewWindow.selectedNode, "scale") onScaleCommit: viewRoot.commitObjectProperty(viewRoot.selectedNode, "scale")
onScaleChange: viewWindow.changeObjectProperty(viewWindow.selectedNode, "scale") onScaleChange: viewRoot.changeObjectProperty(viewRoot.selectedNode, "scale")
} }
RotateGizmo { RotateGizmo {
id: rotateGizmo id: rotateGizmo
scale: autoScale.getScale(Qt.vector3d(7, 7, 7)) scale: autoScale.getScale(Qt.vector3d(7, 7, 7))
highlightOnHover: true highlightOnHover: true
targetNode: viewWindow.selectedNode targetNode: viewRoot.selectedNode
globalOrientation: viewWindow.globalOrientation globalOrientation: viewRoot.globalOrientation
visible: viewWindow.selectedNode && btnRotate.selected visible: viewRoot.selectedNode && btnRotate.selected
view3D: overlayView view3D: overlayView
dragHelper: gizmoDragHelper dragHelper: gizmoDragHelper
onRotateCommit: viewWindow.commitObjectProperty(viewWindow.selectedNode, "rotation") onRotateCommit: viewRoot.commitObjectProperty(viewRoot.selectedNode, "rotation")
onRotateChange: viewWindow.changeObjectProperty(viewWindow.selectedNode, "rotation") onRotateChange: viewRoot.changeObjectProperty(viewRoot.selectedNode, "rotation")
} }
AutoScaleHelper { AutoScaleHelper {
@@ -412,31 +408,31 @@ Window {
Line3D { Line3D {
id: pivotLine id: pivotLine
visible: viewWindow.selectedNode visible: viewRoot.selectedNode
name: "3D Edit View Pivot Line" name: "3D Edit View Pivot Line"
color: "#ddd600" color: "#ddd600"
function flipIfNeeded(vec) { function flipIfNeeded(vec) {
if (!viewWindow.selectedNode || viewWindow.selectedNode.orientation === Node.LeftHanded) if (!viewRoot.selectedNode || viewRoot.selectedNode.orientation === Node.LeftHanded)
return vec; return vec;
else else
return Qt.vector3d(vec.x, vec.y, -vec.z); return Qt.vector3d(vec.x, vec.y, -vec.z);
} }
startPos: viewWindow.selectedNode ? flipIfNeeded(viewWindow.selectedNode.scenePosition) startPos: viewRoot.selectedNode ? flipIfNeeded(viewRoot.selectedNode.scenePosition)
: Qt.vector3d(0, 0, 0) : Qt.vector3d(0, 0, 0)
Connections { Connections {
target: viewWindow target: viewRoot
onSelectedNodeChanged: { onSelectedNodeChanged: {
pivotLine.endPos = pivotLine.flipIfNeeded(gizmoDragHelper.pivotScenePosition( pivotLine.endPos = pivotLine.flipIfNeeded(gizmoDragHelper.pivotScenePosition(
viewWindow.selectedNode)); viewRoot.selectedNode));
} }
} }
Connections { Connections {
target: viewWindow.selectedNode target: viewRoot.selectedNode
onSceneTransformChanged: { onSceneTransformChanged: {
pivotLine.endPos = pivotLine.flipIfNeeded(gizmoDragHelper.pivotScenePosition( pivotLine.endPos = pivotLine.flipIfNeeded(gizmoDragHelper.pivotScenePosition(
viewWindow.selectedNode)); viewRoot.selectedNode));
} }
} }
@@ -457,6 +453,10 @@ Window {
} }
} }
Item {
id: contentItem
anchors.fill: parent
Rectangle { Rectangle {
id: viewRect id: viewRect
anchors.fill: parent anchors.fill: parent
@@ -471,8 +471,8 @@ Window {
anchors.fill: parent anchors.fill: parent
acceptedButtons: Qt.LeftButton acceptedButtons: Qt.LeftButton
onClicked: { onClicked: {
if (viewWindow.editView) { if (viewRoot.editView) {
var pickResult = viewWindow.editView.pick(mouse.x, mouse.y); var pickResult = viewRoot.editView.pick(mouse.x, mouse.y);
handleObjectClicked(_generalHelper.resolvePick(pickResult.objectHit), handleObjectClicked(_generalHelper.resolvePick(pickResult.objectHit),
mouse.modifiers & Qt.ControlModifier); mouse.modifiers & Qt.ControlModifier);
if (!pickResult.objectHit) if (!pickResult.objectHit)
@@ -512,11 +512,11 @@ Window {
text: { text: {
var l = Qt.locale(); var l = Qt.locale();
var targetProperty; var targetProperty;
if (viewWindow.selectedNode) { if (viewRoot.selectedNode) {
if (gizmoLabel.targetNode === moveGizmo) if (gizmoLabel.targetNode === moveGizmo)
targetProperty = viewWindow.selectedNode.position; targetProperty = viewRoot.selectedNode.position;
else else
targetProperty = viewWindow.selectedNode.scale; targetProperty = viewRoot.selectedNode.scale;
return qsTr("x:") + Number(targetProperty.x).toLocaleString(l, 'f', 1) return qsTr("x:") + Number(targetProperty.x).toLocaleString(l, 'f', 1)
+ qsTr(" y:") + Number(targetProperty.y).toLocaleString(l, 'f', 1) + qsTr(" y:") + Number(targetProperty.y).toLocaleString(l, 'f', 1)
+ qsTr(" z:") + Number(targetProperty.z).toLocaleString(l, 'f', 1); + qsTr(" z:") + Number(targetProperty.z).toLocaleString(l, 'f', 1);
@@ -531,10 +531,10 @@ Window {
EditCameraController { EditCameraController {
id: cameraControl id: cameraControl
camera: viewWindow.editView ? viewWindow.editView.camera : null camera: viewRoot.editView ? viewRoot.editView.camera : null
anchors.fill: parent anchors.fill: parent
view3d: viewWindow.editView view3d: viewRoot.editView
sceneId: viewWindow.sceneId sceneId: viewRoot.sceneId
} }
} }
@@ -543,6 +543,7 @@ Window {
color: "#9F000000" color: "#9F000000"
width: 35 width: 35
height: toolbarButtons.height height: toolbarButtons.height
visible: viewRoot.showButtons
Column { Column {
id: toolbarButtons id: toolbarButtons
@@ -564,7 +565,7 @@ Window {
currentShortcut: selected ? "" : shortcut currentShortcut: selected ? "" : shortcut
tool: "item_selection" tool: "item_selection"
buttonGroup: "groupSelect" buttonGroup: "groupSelect"
sceneId: viewWindow.sceneId sceneId: viewRoot.sceneId
} }
ToolBarButton { ToolBarButton {
@@ -574,7 +575,7 @@ Window {
currentShortcut: btnSelectItem.currentShortcut === shortcut ? "" : shortcut currentShortcut: btnSelectItem.currentShortcut === shortcut ? "" : shortcut
tool: "group_selection" tool: "group_selection"
buttonGroup: "groupSelect" buttonGroup: "groupSelect"
sceneId: viewWindow.sceneId sceneId: viewRoot.sceneId
} }
Rectangle { // separator Rectangle { // separator
@@ -592,7 +593,7 @@ Window {
currentShortcut: shortcut currentShortcut: shortcut
tool: "move" tool: "move"
buttonGroup: "groupTransform" buttonGroup: "groupTransform"
sceneId: viewWindow.sceneId sceneId: viewRoot.sceneId
} }
ToolBarButton { ToolBarButton {
@@ -602,7 +603,7 @@ Window {
currentShortcut: shortcut currentShortcut: shortcut
tool: "rotate" tool: "rotate"
buttonGroup: "groupTransform" buttonGroup: "groupTransform"
sceneId: viewWindow.sceneId sceneId: viewRoot.sceneId
} }
ToolBarButton { ToolBarButton {
@@ -612,7 +613,7 @@ Window {
currentShortcut: shortcut currentShortcut: shortcut
tool: "scale" tool: "scale"
buttonGroup: "groupTransform" buttonGroup: "groupTransform"
sceneId: viewWindow.sceneId sceneId: viewRoot.sceneId
} }
Rectangle { // separator Rectangle { // separator
@@ -631,11 +632,8 @@ Window {
togglable: false togglable: false
onSelectedChanged: { onSelectedChanged: {
if (viewWindow.editView && selected) { if (selected)
var targetNode = viewWindow.selectedNodes.length > 0 viewRoot.fitToView();
? selectionBoxes[0].model : null;
cameraControl.focusObject(targetNode, viewWindow.editView.camera.rotation, true);
}
} }
} }
} }
@@ -647,7 +645,7 @@ Window {
width: 100 width: 100
height: width height: width
editCameraCtrl: cameraControl editCameraCtrl: cameraControl
selectedNode : viewWindow.selectedNodes.length ? selectionBoxes[0].model : null selectedNode : viewRoot.selectedNodes.length ? selectionBoxes[0].model : null
} }
Rectangle { // top controls bar Rectangle { // top controls bar
@@ -657,6 +655,7 @@ Window {
anchors.top: parent.top anchors.top: parent.top
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 100 anchors.rightMargin: 100
visible: viewRoot.showButtons
Row { Row {
padding: 5 padding: 5
@@ -683,17 +682,6 @@ Window {
states: [{iconId: "edit_light_off", text: qsTr("Edit Light Off")}, {iconId: "edit_light_on", text: qsTr("Edit Light On")}] states: [{iconId: "edit_light_off", text: qsTr("Edit Light Off")}, {iconId: "edit_light_on", text: qsTr("Edit Light On")}]
} }
} }
} }
Text {
id: helpText
property string modKey: _generalHelper.isMacOS ? qsTr("Option") : qsTr("Alt")
color: "white"
text: qsTr("Camera controls: ") + modKey
+ qsTr(" + mouse press and drag. Left: Rotate, Middle: Pan, Right/Wheel: Zoom.")
anchors.bottom: parent.bottom
} }
} }

View File

@@ -0,0 +1,50 @@
/****************************************************************************
**
** 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.
**
****************************************************************************/
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
id: viewWindow
width: 1024
height: 768
visible: true
title: qsTr("3D Edit View [") + sceneId + qsTr("]")
// need all those flags otherwise the title bar disappears after setting WindowStaysOnTopHint flag later
flags: Qt.Window | Qt.WindowTitleHint | Qt.WindowSystemMenuHint | Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint
property alias editViewRoot: windowContentItem
onWidthChanged: _generalHelper.storeWindowState();
onHeightChanged: _generalHelper.storeWindowState();
onXChanged: _generalHelper.storeWindowState();
onYChanged: _generalHelper.storeWindowState();
onWindowStateChanged: _generalHelper.storeWindowState();
EditView3D {
id: windowContentItem
anchors.fill: parent
}
}

View File

@@ -45,7 +45,7 @@ Node {
} }
property alias iconSource: iconImage.source property alias iconSource: iconImage.source
property alias overlayColor: colorOverlay.color //property alias overlayColor: colorOverlay.color
signal positionCommit() signal positionCommit()
signal clicked(Node node, bool multi) signal clicked(Node node, bool multi)
@@ -94,15 +94,15 @@ Node {
acceptedButtons: Qt.LeftButton acceptedButtons: Qt.LeftButton
} }
} }
ColorOverlay { // ColorOverlay doesn't work correctly with hidden windows so commenting it out for now
id: colorOverlay // ColorOverlay {
anchors.fill: parent // id: colorOverlay
cached: true // anchors.fill: parent
source: iconImage // cached: true
color: "transparent" // source: iconImage
opacity: 0.6 // color: "#00000000"
} // opacity: 0.6
// }
} }
} }
} }

View File

@@ -37,5 +37,6 @@ IconGizmo {
: "qrc:///qtquickplugin/mockfiles/images/point_light_gradient.png" : "qrc:///qtquickplugin/mockfiles/images/point_light_gradient.png"
: "qrc:///qtquickplugin/mockfiles/images/point_light_gradient.png" : "qrc:///qtquickplugin/mockfiles/images/point_light_gradient.png"
overlayColor: targetNode ? targetNode.color : "transparent" // ColorOverlay doesn't work correctly with hidden windows so commenting it out for now
//overlayColor: targetNode ? targetNode.color : "transparent"
} }

View File

@@ -48,7 +48,7 @@
namespace QmlDesigner { namespace QmlDesigner {
namespace Internal { namespace Internal {
const QString globalStateId = QStringLiteral("@GTS"); // global tool state const QString _globalStateId = QStringLiteral("@GTS"); // global tool state
GeneralHelper::GeneralHelper() GeneralHelper::GeneralHelper()
: QObject() : QObject()
@@ -260,37 +260,42 @@ void GeneralHelper::initToolStates(const QString &sceneId, const QVariantMap &to
m_toolStates[sceneId] = toolStates; m_toolStates[sceneId] = toolStates;
} }
void GeneralHelper::storeWindowState(QQuickWindow *w) void GeneralHelper::storeWindowState()
{ {
if (!m_edit3DWindow)
return;
QVariantMap windowState; QVariantMap windowState;
const QRect geometry = w->geometry(); const QRect geometry = m_edit3DWindow->geometry();
const bool maximized = w->windowState() == Qt::WindowMaximized; const bool maximized = m_edit3DWindow->windowState() == Qt::WindowMaximized;
windowState.insert("maximized", maximized); windowState.insert("maximized", maximized);
windowState.insert("geometry", geometry); windowState.insert("geometry", geometry);
storeToolState(globalStateId, "windowState", windowState, 500); storeToolState(globalStateId(), "windowState", windowState, 500);
} }
void GeneralHelper::restoreWindowState(QQuickWindow *w) void GeneralHelper::restoreWindowState()
{ {
if (m_toolStates.contains(globalStateId)) { if (!m_edit3DWindow)
const QVariantMap &globalStateMap = m_toolStates[globalStateId]; return;
if (m_toolStates.contains(globalStateId())) {
const QVariantMap &globalStateMap = m_toolStates[globalStateId()];
const QString stateKey = QStringLiteral("windowState"); const QString stateKey = QStringLiteral("windowState");
if (globalStateMap.contains(stateKey)) { if (globalStateMap.contains(stateKey)) {
QVariantMap windowState = globalStateMap[stateKey].value<QVariantMap>(); QVariantMap windowState = globalStateMap[stateKey].value<QVariantMap>();
doRestoreWindowState(w, windowState); doRestoreWindowState(windowState);
// If the mouse cursor at puppet launch time is in a different screen than the one where the // If the mouse cursor at puppet launch time is in a different screen than the one where the
// view geometry was saved on, the initial position and size can be incorrect, but if // view geometry was saved on, the initial position and size can be incorrect, but if
// we reset the geometry again asynchronously, it should end up with correct geometry. // we reset the geometry again asynchronously, it should end up with correct geometry.
QTimer::singleShot(0, [this, w, windowState]() { QTimer::singleShot(0, [this, windowState]() {
doRestoreWindowState(w, windowState); doRestoreWindowState(windowState);
QTimer::singleShot(0, [this]() {
QTimer::singleShot(0, [w]() {
// Make sure that the window is at least partially visible on the screen // Make sure that the window is at least partially visible on the screen
QRect geo = w->geometry(); QRect geo = m_edit3DWindow->geometry();
QRect sRect = w->screen()->geometry(); QRect sRect = m_edit3DWindow->screen()->geometry();
if (geo.left() > sRect.right() - 150) if (geo.left() > sRect.right() - 150)
geo.moveRight(sRect.right()); geo.moveRight(sRect.right());
if (geo.right() < sRect.left() + 150) if (geo.right() < sRect.left() + 150)
@@ -303,7 +308,7 @@ void GeneralHelper::restoreWindowState(QQuickWindow *w)
geo.setWidth(sRect.width()); geo.setWidth(sRect.width());
if (geo.height() > sRect.height()) if (geo.height() > sRect.height())
geo.setHeight(sRect.height()); geo.setHeight(sRect.height());
w->setGeometry(geo); m_edit3DWindow->setGeometry(geo);
}); });
}); });
} }
@@ -324,7 +329,17 @@ QVariantMap GeneralHelper::getToolStates(const QString &sceneId)
return {}; return {};
} }
void GeneralHelper::doRestoreWindowState(QQuickWindow *w, const QVariantMap &windowState) void GeneralHelper::setEdit3DWindow(QQuickWindow *w)
{
m_edit3DWindow = w;
}
QString GeneralHelper::globalStateId() const
{
return _globalStateId;
}
void GeneralHelper::doRestoreWindowState(const QVariantMap &windowState)
{ {
const QString geoKey = QStringLiteral("geometry"); const QString geoKey = QStringLiteral("geometry");
if (windowState.contains(geoKey)) { if (windowState.contains(geoKey)) {
@@ -335,9 +350,9 @@ void GeneralHelper::doRestoreWindowState(QQuickWindow *w, const QVariantMap &win
QRect rect = windowState[geoKey].value<QRect>(); QRect rect = windowState[geoKey].value<QRect>();
w->setGeometry(rect); m_edit3DWindow->setGeometry(rect);
if (maximized) if (maximized)
w->showMaximized(); m_edit3DWindow->showMaximized();
} }
} }

View File

@@ -30,6 +30,7 @@
#include <QtCore/qobject.h> #include <QtCore/qobject.h>
#include <QtCore/qtimer.h> #include <QtCore/qtimer.h>
#include <QtCore/qhash.h> #include <QtCore/qhash.h>
#include <QtCore/qpointer.h>
#include <QtGui/qvector3d.h> #include <QtGui/qvector3d.h>
#include <QtGui/qmatrix4x4.h> #include <QtGui/qmatrix4x4.h>
@@ -74,10 +75,12 @@ public:
Q_INVOKABLE void storeToolState(const QString &sceneId, const QString &tool, Q_INVOKABLE void storeToolState(const QString &sceneId, const QString &tool,
const QVariant &state, int delayEmit = 0); const QVariant &state, int delayEmit = 0);
void initToolStates(const QString &sceneId, const QVariantMap &toolStates); void initToolStates(const QString &sceneId, const QVariantMap &toolStates);
Q_INVOKABLE void storeWindowState(QQuickWindow *w); Q_INVOKABLE void storeWindowState();
void restoreWindowState(QQuickWindow *w); void restoreWindowState();
Q_INVOKABLE void enableItemUpdate(QQuickItem *item, bool enable); Q_INVOKABLE void enableItemUpdate(QQuickItem *item, bool enable);
Q_INVOKABLE QVariantMap getToolStates(const QString &sceneId); Q_INVOKABLE QVariantMap getToolStates(const QString &sceneId);
void setEdit3DWindow(QQuickWindow *w);
QString globalStateId() const;
bool isMacOS() const; bool isMacOS() const;
@@ -86,7 +89,7 @@ signals:
void toolStateChanged(const QString &sceneId, const QString &tool, const QVariant &toolState); void toolStateChanged(const QString &sceneId, const QString &tool, const QVariant &toolState);
private slots: private slots:
void doRestoreWindowState(QQuickWindow *w, const QVariantMap &windowState); void doRestoreWindowState(const QVariantMap &windowState);
private: private:
void handlePendingToolStateUpdate(); void handlePendingToolStateUpdate();
@@ -95,6 +98,7 @@ private:
QTimer m_toolStateUpdateTimer; QTimer m_toolStateUpdateTimer;
QHash<QString, QVariantMap> m_toolStates; QHash<QString, QVariantMap> m_toolStates;
QHash<QString, QVariantMap> m_toolStatesPending; QHash<QString, QVariantMap> m_toolStatesPending;
QPointer<QQuickWindow> m_edit3DWindow;
}; };
} }

View File

@@ -68,6 +68,8 @@
#include <removesharedmemorycommand.h> #include <removesharedmemorycommand.h>
#include <changeselectioncommand.h> #include <changeselectioncommand.h>
#include <drop3dlibraryitemcommand.h> #include <drop3dlibraryitemcommand.h>
#include <inputeventcommand.h>
#include <view3dactioncommand.h>
#include <QDebug> #include <QDebug>
#include <QQmlEngine> #include <QQmlEngine>
@@ -336,10 +338,6 @@ void NodeInstanceServer::update3DViewState(const Update3dViewStateCommand &/*com
{ {
} }
void NodeInstanceServer::enable3DView(const Enable3DViewCommand &/*command*/)
{
}
void NodeInstanceServer::changeSelection(const ChangeSelectionCommand & /*command*/) void NodeInstanceServer::changeSelection(const ChangeSelectionCommand & /*command*/)
{ {
} }
@@ -1395,6 +1393,16 @@ QStringList NodeInstanceServer::dummyDataDirectories(const QString& directoryPat
} }
} }
void NodeInstanceServer::inputEvent(const InputEventCommand &command)
{
Q_UNUSED(command)
}
void NodeInstanceServer::view3DAction(const View3DActionCommand &command)
{
Q_UNUSED(command)
}
} }

View File

@@ -102,7 +102,6 @@ public:
void createScene(const CreateSceneCommand &command) override; void createScene(const CreateSceneCommand &command) override;
void clearScene(const ClearSceneCommand &command) override; void clearScene(const ClearSceneCommand &command) override;
void update3DViewState(const Update3dViewStateCommand &command) override; void update3DViewState(const Update3dViewStateCommand &command) override;
void enable3DView(const Enable3DViewCommand &command) override;
void removeInstances(const RemoveInstancesCommand &command) override; void removeInstances(const RemoveInstancesCommand &command) override;
void removeProperties(const RemovePropertiesCommand &command) override; void removeProperties(const RemovePropertiesCommand &command) override;
void reparentInstances(const ReparentInstancesCommand &command) override; void reparentInstances(const ReparentInstancesCommand &command) override;
@@ -112,6 +111,8 @@ public:
void token(const TokenCommand &command) override; void token(const TokenCommand &command) override;
void removeSharedMemory(const RemoveSharedMemoryCommand &command) override; void removeSharedMemory(const RemoveSharedMemoryCommand &command) override;
void changeSelection(const ChangeSelectionCommand &command) override; void changeSelection(const ChangeSelectionCommand &command) override;
void inputEvent(const InputEventCommand &command) override;
void view3DAction(const View3DActionCommand &command) override;
ServerNodeInstance instanceForId(qint32 id) const; ServerNodeInstance instanceForId(qint32 id) const;
bool hasInstanceForId(qint32 id) const; bool hasInstanceForId(qint32 id) const;

View File

@@ -41,7 +41,6 @@
#include "clearscenecommand.h" #include "clearscenecommand.h"
#include "reparentinstancescommand.h" #include "reparentinstancescommand.h"
#include "update3dviewstatecommand.h" #include "update3dviewstatecommand.h"
#include "enable3dviewcommand.h"
#include "changevaluescommand.h" #include "changevaluescommand.h"
#include "changebindingscommand.h" #include "changebindingscommand.h"
#include "changeidscommand.h" #include "changeidscommand.h"
@@ -63,6 +62,8 @@
#include "drop3dlibraryitemcommand.h" #include "drop3dlibraryitemcommand.h"
#include "puppettocreatorcommand.h" #include "puppettocreatorcommand.h"
#include "view3dclosedcommand.h" #include "view3dclosedcommand.h"
#include "inputeventcommand.h"
#include "view3dactioncommand.h"
#include "dummycontextobject.h" #include "dummycontextobject.h"
#include "../editor3d/generalhelper.h" #include "../editor3d/generalhelper.h"
@@ -73,6 +74,7 @@
#include "../editor3d/linegeometry.h" #include "../editor3d/linegeometry.h"
#include <designersupportdelegate.h> #include <designersupportdelegate.h>
#include <qmlprivategate.h>
#include <QVector3D> #include <QVector3D>
#include <QQmlProperty> #include <QQmlProperty>
@@ -80,6 +82,8 @@
#include <QQuickView> #include <QQuickView>
#include <QQmlContext> #include <QQmlContext>
#include <QQmlEngine> #include <QQmlEngine>
#include <QtGui/qevent.h>
#include <QtGui/qguiapplication.h>
#ifdef QUICK3D_MODULE #ifdef QUICK3D_MODULE
#include <QtQuick3D/private/qquick3dnode_p.h> #include <QtQuick3D/private/qquick3dnode_p.h>
@@ -165,53 +169,72 @@ bool Qt5InformationNodeInstanceServer::dropAcceptable(QDragMoveEvent *event) con
return canBeDropped == "true" || canBeDropped == "True"; return canBeDropped == "true" || canBeDropped == "True";
} }
QObject *Qt5InformationNodeInstanceServer::createEditView3D(QQmlEngine *engine) void Qt5InformationNodeInstanceServer::createEditView3D()
{ {
#ifdef QUICK3D_MODULE #ifdef QUICK3D_MODULE
auto helper = new QmlDesigner::Internal::GeneralHelper(); static bool showEditView = qEnvironmentVariableIsSet("QMLDESIGNER_QUICK3D_SHOW_EDIT_WINDOW");
QObject::connect(helper, &QmlDesigner::Internal::GeneralHelper::toolStateChanged,
this, &Qt5InformationNodeInstanceServer::handleToolStateChanged);
engine->rootContext()->setContextProperty("_generalHelper", helper);
m_3dHelper = helper;
qmlRegisterType<QmlDesigner::Internal::MouseArea3D>("MouseArea3D", 1, 0, "MouseArea3D"); qmlRegisterType<QmlDesigner::Internal::MouseArea3D>("MouseArea3D", 1, 0, "MouseArea3D");
qmlRegisterType<QmlDesigner::Internal::CameraGeometry>("CameraGeometry", 1, 0, "CameraGeometry"); qmlRegisterType<QmlDesigner::Internal::CameraGeometry>("CameraGeometry", 1, 0, "CameraGeometry");
qmlRegisterType<QmlDesigner::Internal::GridGeometry>("GridGeometry", 1, 0, "GridGeometry"); qmlRegisterType<QmlDesigner::Internal::GridGeometry>("GridGeometry", 1, 0, "GridGeometry");
qmlRegisterType<QmlDesigner::Internal::SelectionBoxGeometry>("SelectionBoxGeometry", 1, 0, "SelectionBoxGeometry"); qmlRegisterType<QmlDesigner::Internal::SelectionBoxGeometry>("SelectionBoxGeometry", 1, 0, "SelectionBoxGeometry");
qmlRegisterType<QmlDesigner::Internal::LineGeometry>("LineGeometry", 1, 0, "LineGeometry"); qmlRegisterType<QmlDesigner::Internal::LineGeometry>("LineGeometry", 1, 0, "LineGeometry");
#endif
QQmlComponent component(engine, QUrl("qrc:/qtquickplugin/mockfiles/EditView3D.qml")); auto helper = new QmlDesigner::Internal::GeneralHelper();
QObject::connect(helper, &QmlDesigner::Internal::GeneralHelper::toolStateChanged,
this, &Qt5InformationNodeInstanceServer::handleToolStateChanged);
engine()->rootContext()->setContextProperty("_generalHelper", helper);
m_3dHelper = helper;
QWindow *window = qobject_cast<QWindow *>(component.create()); QQmlComponent component(engine());
if (showEditView) {
component.loadUrl(QUrl("qrc:/qtquickplugin/mockfiles/EditWindow3D.qml"));
m_editWindow3D = qobject_cast<QQuickWindow *>(component.create());
m_editView3DRootItem = QQmlProperty::read(m_editWindow3D, "editViewRoot").value<QQuickItem *>();
if (!window) { //For macOS we have to use the 4.1 core profile
qWarning() << "Could not create edit view 3D: " << component.errors(); QSurfaceFormat surfaceFormat = m_editWindow3D->requestedFormat();
return nullptr; surfaceFormat.setVersion(4, 1);
surfaceFormat.setProfile(QSurfaceFormat::CoreProfile);
m_editWindow3D->setFormat(surfaceFormat);
} else {
m_editView3D = new QQuickView(quickView()->engine(), quickView());
m_editView3D->setFormat(quickView()->format());
DesignerSupport::createOpenGLContext(m_editView3D.data());
component.loadUrl(QUrl("qrc:/qtquickplugin/mockfiles/EditView3D.qml"));
m_editView3DRootItem = qobject_cast<QQuickItem *>(component.create());
} }
window->installEventFilter(this); if (!m_editView3DRootItem) {
QObject::connect(window, SIGNAL(selectionChanged(QVariant)), qWarning() << "Could not create edit view 3D: " << component.errors();
return;
}
if (!showEditView) {
DesignerSupport::setRootItem(m_editView3D, m_editView3DRootItem);
} else {
m_editView3DRootItem->installEventFilter(this);
QQmlProperty showButtonsProperty(m_editView3DRootItem, "showButtons", context());
showButtonsProperty.write(QVariant(true));
}
QObject::connect(m_editView3DRootItem, SIGNAL(selectionChanged(QVariant)),
this, SLOT(handleSelectionChanged(QVariant))); this, SLOT(handleSelectionChanged(QVariant)));
QObject::connect(window, SIGNAL(commitObjectProperty(QVariant, QVariant)), QObject::connect(m_editView3DRootItem, SIGNAL(commitObjectProperty(QVariant, QVariant)),
this, SLOT(handleObjectPropertyCommit(QVariant, QVariant))); this, SLOT(handleObjectPropertyCommit(QVariant, QVariant)));
QObject::connect(window, SIGNAL(changeObjectProperty(QVariant, QVariant)), QObject::connect(m_editView3DRootItem, SIGNAL(changeObjectProperty(QVariant, QVariant)),
this, SLOT(handleObjectPropertyChange(QVariant, QVariant))); this, SLOT(handleObjectPropertyChange(QVariant, QVariant)));
QObject::connect(&m_propertyChangeTimer, &QTimer::timeout, QObject::connect(&m_propertyChangeTimer, &QTimer::timeout,
this, &Qt5InformationNodeInstanceServer::handleObjectPropertyChangeTimeout); this, &Qt5InformationNodeInstanceServer::handleObjectPropertyChangeTimeout);
QObject::connect(&m_selectionChangeTimer, &QTimer::timeout, QObject::connect(&m_selectionChangeTimer, &QTimer::timeout,
this, &Qt5InformationNodeInstanceServer::handleSelectionChangeTimeout); this, &Qt5InformationNodeInstanceServer::handleSelectionChangeTimeout);
QObject::connect(&m_renderTimer, &QTimer::timeout,
this, &Qt5InformationNodeInstanceServer::doRender3DEditView);
//For macOS we have to use the 4.1 core profile helper->setParent(m_editView3DRootItem);
QSurfaceFormat surfaceFormat = window->requestedFormat(); if (showEditView)
surfaceFormat.setVersion(4, 1); helper->setEdit3DWindow(m_editWindow3D);
surfaceFormat.setProfile(QSurfaceFormat::CoreProfile);
window->setFormat(surfaceFormat);
#ifdef QUICK3D_MODULE
helper->setParent(window);
#endif #endif
return window;
} }
// The selection has changed in the edit view 3D. Empty list indicates selection is cleared. // The selection has changed in the edit view 3D. Empty list indicates selection is cleared.
@@ -357,10 +380,10 @@ void Qt5InformationNodeInstanceServer::handleNode3DDestroyed(QObject *obj)
{ {
#ifdef QUICK3D_MODULE #ifdef QUICK3D_MODULE
if (qobject_cast<QQuick3DCamera *>(obj)) { if (qobject_cast<QQuick3DCamera *>(obj)) {
QMetaObject::invokeMethod(m_editView3D, "releaseCameraGizmo", QMetaObject::invokeMethod(m_editView3DRootItem, "releaseCameraGizmo",
Q_ARG(QVariant, objectToVariant(obj))); Q_ARG(QVariant, objectToVariant(obj)));
} else if (qobject_cast<QQuick3DAbstractLight *>(obj)) { } else if (qobject_cast<QQuick3DAbstractLight *>(obj)) {
QMetaObject::invokeMethod(m_editView3D, "releaseLightGizmo", QMetaObject::invokeMethod(m_editView3DRootItem, "releaseLightGizmo",
Q_ARG(QVariant, objectToVariant(obj))); Q_ARG(QVariant, objectToVariant(obj)));
} }
removeNode3D(obj); removeNode3D(obj);
@@ -376,29 +399,41 @@ void Qt5InformationNodeInstanceServer::updateView3DRect(QObject *view3D)
viewPortrect = QRectF(0., 0., view3D->property("width").toDouble(), viewPortrect = QRectF(0., 0., view3D->property("width").toDouble(),
view3D->property("height").toDouble()); view3D->property("height").toDouble());
} }
QQmlProperty viewPortProperty(m_editView3D, "viewPortRect", context()); QQmlProperty viewPortProperty(m_editView3DRootItem, "viewPortRect", context());
viewPortProperty.write(viewPortrect); viewPortProperty.write(viewPortrect);
} }
void Qt5InformationNodeInstanceServer::updateActiveSceneToEditView3D() void Qt5InformationNodeInstanceServer::updateActiveSceneToEditView3D()
{ {
#ifdef QUICK3D_MODULE
// Active scene change handling on qml side is async, so a deleted importScene would crash // Active scene change handling on qml side is async, so a deleted importScene would crash
// editView when it updates next. Disable/enable edit view update synchronously to avoid this. // editView when it updates next. Disable/enable edit view update synchronously to avoid this.
QVariant activeSceneVar = objectToVariant(m_active3DScene); QVariant activeSceneVar = objectToVariant(m_active3DScene);
QMetaObject::invokeMethod(m_editView3D, "enableEditViewUpdate", QMetaObject::invokeMethod(m_editView3DRootItem, "enableEditViewUpdate",
Q_ARG(QVariant, activeSceneVar)); Q_ARG(QVariant, activeSceneVar));
ServerNodeInstance sceneInstance = active3DSceneInstance(); ServerNodeInstance sceneInstance = active3DSceneInstance();
QVariant sceneInstanceVar; QVariant sceneIdVar;
QQmlProperty sceneIdProperty(m_editView3D, "sceneId", context()); QQmlProperty sceneIdProperty(m_editView3DRootItem, "sceneId", context());
const QString sceneId = sceneInstance.id();
if (sceneInstance.isValid()) if (sceneInstance.isValid())
sceneInstanceVar = QVariant::fromValue(sceneInstance.id()); sceneIdVar = QVariant::fromValue(sceneId);
sceneIdProperty.write(sceneInstanceVar); sceneIdProperty.write(sceneIdVar);
QQmlProperty sceneProperty(m_editView3D, "activeScene", context()); QQmlProperty sceneProperty(m_editView3DRootItem, "activeScene", context());
sceneProperty.write(activeSceneVar); sceneProperty.write(activeSceneVar);
auto helper = qobject_cast<QmlDesigner::Internal::GeneralHelper *>(m_3dHelper);
QVariantMap toolStates;
if (helper)
toolStates = helper->getToolStates(sceneId);
toolStates.insert("sceneInstanceId", QVariant::fromValue(sceneInstance.instanceId()));
nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::ActiveSceneChanged,
toolStates});
updateView3DRect(m_active3DView); updateView3DRect(m_active3DView);
#endif
} }
void Qt5InformationNodeInstanceServer::removeNode3D(QObject *node) void Qt5InformationNodeInstanceServer::removeNode3D(QObject *node)
@@ -439,11 +474,11 @@ void Qt5InformationNodeInstanceServer::resolveSceneRoots()
if (newRoot != oldRoot) { if (newRoot != oldRoot) {
if (qobject_cast<QQuick3DCamera *>(node)) { if (qobject_cast<QQuick3DCamera *>(node)) {
QMetaObject::invokeMethod(m_editView3D, "updateCameraGizmoScene", QMetaObject::invokeMethod(m_editView3DRootItem, "updateCameraGizmoScene",
Q_ARG(QVariant, objectToVariant(newRoot)), Q_ARG(QVariant, objectToVariant(newRoot)),
Q_ARG(QVariant, objectToVariant(node))); Q_ARG(QVariant, objectToVariant(node)));
} else if (qobject_cast<QQuick3DAbstractLight *>(node)) { } else if (qobject_cast<QQuick3DAbstractLight *>(node)) {
QMetaObject::invokeMethod(m_editView3D, "updateLightGizmoScene", QMetaObject::invokeMethod(m_editView3DRootItem, "updateLightGizmoScene",
Q_ARG(QVariant, objectToVariant(newRoot)), Q_ARG(QVariant, objectToVariant(newRoot)),
Q_ARG(QVariant, objectToVariant(node))); Q_ARG(QVariant, objectToVariant(node)));
} }
@@ -467,11 +502,65 @@ ServerNodeInstance Qt5InformationNodeInstanceServer::active3DSceneInstance() con
return sceneInstance; return sceneInstance;
} }
void Qt5InformationNodeInstanceServer::render3DEditView()
{
m_needRender = true;
if (!m_renderTimer.isActive())
m_renderTimer.start(0);
}
// render the 3D edit view and send the result to creator process
void Qt5InformationNodeInstanceServer::doRender3DEditView()
{
static bool showEditView = qEnvironmentVariableIsSet("QMLDESIGNER_QUICK3D_SHOW_EDIT_WINDOW");
if (m_editView3DRootItem && !showEditView) {
auto t = std::chrono::steady_clock::now();
if (!m_editView3DContentItem) {
m_editView3DContentItem = QQmlProperty::read(m_editView3DRootItem, "contentItem").value<QQuickItem *>();
if (m_editView3DContentItem) {
designerSupport()->refFromEffectItem(m_editView3DContentItem, false);
QmlDesigner::Internal::QmlPrivateGate::disableNativeTextRendering(m_editView3DContentItem);
}
}
std::function<void (QQuickItem *)> updateNodesRecursive;
updateNodesRecursive = [&updateNodesRecursive](QQuickItem *item) {
for (QQuickItem *childItem : item->childItems())
updateNodesRecursive(childItem);
DesignerSupport::updateDirtyNode(item);
};
updateNodesRecursive(m_editView3DContentItem);
QSizeF size = qobject_cast<QQuickItem *>(m_editView3DContentItem)->size();
QRectF renderRect(QPointF(0., 0.), size);
QImage renderImage = designerSupport()->renderImageForItem(m_editView3DContentItem,
renderRect, size.toSize());
// There's no instance related to image, so instance id is -1.
// Key number is selected so that it is unlikely to conflict other ImageContainer use.
const qint32 edit3DKey = 2100000000;
auto imgContainer = ImageContainer(-1, renderImage, edit3DKey);
// send the rendered image to creator process
nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::Render3DView,
QVariant::fromValue(imgContainer)});
qDebug() << "\x1b[42m \x1b[1m" << __FUNCTION__
<< ", t=" << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now()-t).count()
<< "\x1b[m";
if (m_needRender) {
m_renderTimer.start(0);
m_needRender = false;
}
}
}
Qt5InformationNodeInstanceServer::Qt5InformationNodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient) : Qt5InformationNodeInstanceServer::Qt5InformationNodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient) :
Qt5NodeInstanceServer(nodeInstanceClient) Qt5NodeInstanceServer(nodeInstanceClient)
{ {
m_propertyChangeTimer.setInterval(100); m_propertyChangeTimer.setInterval(100);
m_selectionChangeTimer.setSingleShot(true); m_selectionChangeTimer.setSingleShot(true);
m_renderTimer.setSingleShot(true);
} }
void Qt5InformationNodeInstanceServer::sendTokenBack() void Qt5InformationNodeInstanceServer::sendTokenBack()
@@ -523,7 +612,6 @@ bool Qt5InformationNodeInstanceServer::isDirtyRecursiveForParentInstances(QQuick
return false; return false;
return isDirtyRecursiveForParentInstances(parentItem); return isDirtyRecursiveForParentInstances(parentItem);
} }
return false; return false;
@@ -549,12 +637,14 @@ QList<ServerNodeInstance> Qt5InformationNodeInstanceServer::createInstances(
{ {
const auto createdInstances = NodeInstanceServer::createInstances(container); const auto createdInstances = NodeInstanceServer::createInstances(container);
if (m_editView3D) { if (m_editView3DRootItem) {
add3DViewPorts(createdInstances); add3DViewPorts(createdInstances);
add3DScenes(createdInstances); add3DScenes(createdInstances);
createCameraAndLightGizmos(createdInstances); createCameraAndLightGizmos(createdInstances);
} }
render3DEditView();
return createdInstances; return createdInstances;
} }
@@ -586,7 +676,7 @@ void Qt5InformationNodeInstanceServer::createCameraAndLightGizmos(
while (cameraIt != cameras.constEnd()) { while (cameraIt != cameras.constEnd()) {
const auto cameraObjs = cameraIt.value(); const auto cameraObjs = cameraIt.value();
for (auto &obj : cameraObjs) { for (auto &obj : cameraObjs) {
QMetaObject::invokeMethod(m_editView3D, "addCameraGizmo", QMetaObject::invokeMethod(m_editView3DRootItem, "addCameraGizmo",
Q_ARG(QVariant, objectToVariant(cameraIt.key())), Q_ARG(QVariant, objectToVariant(cameraIt.key())),
Q_ARG(QVariant, objectToVariant(obj))); Q_ARG(QVariant, objectToVariant(obj)));
} }
@@ -596,7 +686,7 @@ void Qt5InformationNodeInstanceServer::createCameraAndLightGizmos(
while (lightIt != lights.constEnd()) { while (lightIt != lights.constEnd()) {
const auto lightObjs = lightIt.value(); const auto lightObjs = lightIt.value();
for (auto &obj : lightObjs) { for (auto &obj : lightObjs) {
QMetaObject::invokeMethod(m_editView3D, "addLightGizmo", QMetaObject::invokeMethod(m_editView3DRootItem, "addLightGizmo",
Q_ARG(QVariant, objectToVariant(lightIt.key())), Q_ARG(QVariant, objectToVariant(lightIt.key())),
Q_ARG(QVariant, objectToVariant(obj))); Q_ARG(QVariant, objectToVariant(obj)));
} }
@@ -791,8 +881,8 @@ void Qt5InformationNodeInstanceServer::setup3DEditView(const QList<ServerNodeIns
m_active3DView = findView3DForSceneRoot(m_active3DScene); m_active3DView = findView3DForSceneRoot(m_active3DScene);
} }
if (m_active3DScene) { if (m_active3DScene) {
m_editView3D = createEditView3D(engine()); createEditView3D();
if (!m_editView3D) { if (!m_editView3DRootItem) {
m_active3DScene = nullptr; m_active3DScene = nullptr;
m_active3DView = nullptr; m_active3DView = nullptr;
return; return;
@@ -805,7 +895,11 @@ void Qt5InformationNodeInstanceServer::setup3DEditView(const QList<ServerNodeIns
helper->initToolStates(it.key(), it.value()); helper->initToolStates(it.key(), it.value());
++it; ++it;
} }
helper->restoreWindowState(qobject_cast<QQuickWindow *>(m_editView3D)); helper->restoreWindowState();
if (toolStates.contains(helper->globalStateId())
&& toolStates[helper->globalStateId()].contains("rootSize")) {
m_editView3DRootItem->setSize(toolStates[helper->globalStateId()]["rootSize"].value<QSize>());
}
} }
updateActiveSceneToEditView3D(); updateActiveSceneToEditView3D();
@@ -900,7 +994,7 @@ void Qt5InformationNodeInstanceServer::reparentInstances(const ReparentInstances
Qt5NodeInstanceServer::reparentInstances(command); Qt5NodeInstanceServer::reparentInstances(command);
if (m_editView3D) if (m_editView3DRootItem)
resolveSceneRoots(); resolveSceneRoots();
} }
@@ -991,7 +1085,7 @@ void QmlDesigner::Qt5InformationNodeInstanceServer::removeSharedMemory(const Qml
void Qt5InformationNodeInstanceServer::changeSelection(const ChangeSelectionCommand &command) void Qt5InformationNodeInstanceServer::changeSelection(const ChangeSelectionCommand &command)
{ {
if (!m_editView3D) if (!m_editView3DRootItem)
return; return;
if (m_selectionChangeTimer.isActive()) { if (m_selectionChangeTimer.isActive()) {
@@ -1033,16 +1127,18 @@ void Qt5InformationNodeInstanceServer::changeSelection(const ChangeSelectionComm
// Ensure the UI has enough selection box items. If it doesn't yet have them, which can be the // Ensure the UI has enough selection box items. If it doesn't yet have them, which can be the
// case when the first selection processed is a multiselection, we wait a bit as // case when the first selection processed is a multiselection, we wait a bit as
// using the new boxes immediately leads to visual glitches. // using the new boxes immediately leads to visual glitches.
int boxCount = m_editView3D->property("selectionBoxes").value<QVariantList>().size(); int boxCount = m_editView3DRootItem->property("selectionBoxes").value<QVariantList>().size();
if (boxCount < selectedObjs.size()) { if (boxCount < selectedObjs.size()) {
QMetaObject::invokeMethod(m_editView3D, "ensureSelectionBoxes", QMetaObject::invokeMethod(m_editView3DRootItem, "ensureSelectionBoxes",
Q_ARG(QVariant, QVariant::fromValue(selectedObjs.size()))); Q_ARG(QVariant, QVariant::fromValue(selectedObjs.size())));
m_pendingSelectionChangeCommand = command; m_pendingSelectionChangeCommand = command;
m_selectionChangeTimer.start(100); m_selectionChangeTimer.start(100);
} else { } else {
QMetaObject::invokeMethod(m_editView3D, "selectObjects", QMetaObject::invokeMethod(m_editView3DRootItem, "selectObjects",
Q_ARG(QVariant, QVariant::fromValue(selectedObjs))); Q_ARG(QVariant, QVariant::fromValue(selectedObjs)));
} }
render3DEditView();
} }
void Qt5InformationNodeInstanceServer::changePropertyValues(const ChangeValuesCommand &command) void Qt5InformationNodeInstanceServer::changePropertyValues(const ChangeValuesCommand &command)
@@ -1060,6 +1156,8 @@ void Qt5InformationNodeInstanceServer::changePropertyValues(const ChangeValuesCo
refreshBindings(); refreshBindings();
startRenderTimer(); startRenderTimer();
render3DEditView();
} }
void Qt5InformationNodeInstanceServer::removeInstances(const RemoveInstancesCommand &command) void Qt5InformationNodeInstanceServer::removeInstances(const RemoveInstancesCommand &command)
@@ -1074,45 +1172,110 @@ void Qt5InformationNodeInstanceServer::removeInstances(const RemoveInstancesComm
resolveSceneRoots(); resolveSceneRoots();
} }
if (m_editView3D && (!m_active3DScene || !m_active3DView)) { if (m_editView3DRootItem && (!m_active3DScene || !m_active3DView)) {
if (!m_active3DScene && !m_3DSceneMap.isEmpty()) if (!m_active3DScene && !m_3DSceneMap.isEmpty())
m_active3DScene = m_3DSceneMap.begin().key(); m_active3DScene = m_3DSceneMap.begin().key();
m_active3DView = findView3DForSceneRoot(m_active3DScene); m_active3DView = findView3DForSceneRoot(m_active3DScene);
updateActiveSceneToEditView3D(); updateActiveSceneToEditView3D();
} }
render3DEditView();
}
void Qt5InformationNodeInstanceServer::inputEvent(const InputEventCommand &command)
{
if (m_editView3D) {
if (command.type() == QEvent::Wheel) {
auto we = new QWheelEvent(command.pos(), command.pos(), {0, 0}, {0, command.angleDelta()},
command.buttons(), command.modifiers(), Qt::NoScrollPhase,
false);
QGuiApplication::postEvent(m_editView3D, we);
} else {
auto me = new QMouseEvent(command.type(), command.pos(), command.button(),
command.buttons(), command.modifiers());
QGuiApplication::postEvent(m_editView3D, me);
}
render3DEditView();
}
}
void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &command)
{
QVariantMap updatedState;
switch (command.type()) {
case View3DActionCommand::MoveTool:
updatedState.insert("groupTransform", 0);
break;
case View3DActionCommand::RotateTool:
updatedState.insert("groupTransform", 1);
break;
case View3DActionCommand::ScaleTool:
updatedState.insert("groupTransform", 2);
break;
case View3DActionCommand::FitToView:
QMetaObject::invokeMethod(m_editView3DRootItem, "fitToView");
break;
case View3DActionCommand::SelectionModeToggle:
updatedState.insert("groupSelect", command.isEnabled() ? 0 : 1);
break;
case View3DActionCommand::CameraToggle:
updatedState.insert("usePerspective", command.isEnabled());
break;
case View3DActionCommand::OrientationToggle:
updatedState.insert("globalOrientation", command.isEnabled());
break;
case View3DActionCommand::EditLightToggle:
updatedState.insert("showEditLight", command.isEnabled());
break;
default:
break;
}
if (!updatedState.isEmpty()) {
QMetaObject::invokeMethod(m_editView3DRootItem, "updateToolStates",
Q_ARG(QVariant, updatedState),
Q_ARG(QVariant, QVariant::fromValue(false)));
}
render3DEditView();
}
void Qt5InformationNodeInstanceServer::changeAuxiliaryValues(const ChangeAuxiliaryCommand &command)
{
Qt5NodeInstanceServer::changeAuxiliaryValues(command);
render3DEditView();
} }
// update 3D view window state when the main app window state change // update 3D view window state when the main app window state change
void Qt5InformationNodeInstanceServer::update3DViewState(const Update3dViewStateCommand &command) void Qt5InformationNodeInstanceServer::update3DViewState(const Update3dViewStateCommand &command)
{ {
auto window = qobject_cast<QWindow *>(m_editView3D); #ifdef QUICK3D_MODULE
if (window) { if (command.type() == Update3dViewStateCommand::SizeChange) {
if (m_editView3DRootItem) {
m_editView3DRootItem->setSize(command.size());
auto helper = qobject_cast<QmlDesigner::Internal::GeneralHelper *>(m_3dHelper);
if (helper)
helper->storeToolState(helper->globalStateId(), "rootSize", QVariant(command.size()), 0);
render3DEditView();
}
} else if (m_editWindow3D) {
if (command.type() == Update3dViewStateCommand::StateChange) { if (command.type() == Update3dViewStateCommand::StateChange) {
if (command.previousStates() & Qt::WindowMinimized) // main window expanded from minimize state if (command.previousStates() & Qt::WindowMinimized) // main window expanded from minimize state
window->show(); m_editWindow3D->show();
else if (command.currentStates() & Qt::WindowMinimized) // main window minimized else if (command.currentStates() & Qt::WindowMinimized) // main window minimized
window->hide(); m_editWindow3D->hide();
} else if (command.type() == Update3dViewStateCommand::ActiveChange) { } else if (command.type() == Update3dViewStateCommand::ActiveChange) {
window->setFlag(Qt::WindowStaysOnTopHint, command.isActive()); m_editWindow3D->setFlag(Qt::WindowStaysOnTopHint, command.isActive());
// main window has a popup open, lower the edit view 3D so that the pop up is visible // main window has a popup open, lower the edit view 3D so that the pop up is visible
if (command.hasPopup()) if (command.hasPopup())
window->lower(); m_editWindow3D->lower();
} }
} }
} #else
Q_UNUSED(command)
void Qt5InformationNodeInstanceServer::enable3DView(const Enable3DViewCommand &command) #endif
{
// TODO: this method is not currently in use as the 3D view is currently enabled by resetting the puppet.
// It should however be implemented here.
auto window = qobject_cast<QWindow *>(m_editView3D);
if (window && !command.isEnable()) {
// TODO: remove the 3D view
} else if (!window && command.isEnable()) {
// TODO: create the 3D view
}
} }
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -32,6 +32,7 @@
#include <QTimer> #include <QTimer>
#include <QVariant> #include <QVariant>
#include <QPointer>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QDragMoveEvent; class QDragMoveEvent;
@@ -49,7 +50,6 @@ public:
void reparentInstances(const ReparentInstancesCommand &command) override; void reparentInstances(const ReparentInstancesCommand &command) override;
void clearScene(const ClearSceneCommand &command) override; void clearScene(const ClearSceneCommand &command) override;
void update3DViewState(const Update3dViewStateCommand &command) override; void update3DViewState(const Update3dViewStateCommand &command) override;
void enable3DView(const Enable3DViewCommand &command) override;
void createScene(const CreateSceneCommand &command) override; void createScene(const CreateSceneCommand &command) override;
void completeComponent(const CompleteComponentCommand &command) override; void completeComponent(const CompleteComponentCommand &command) override;
void token(const TokenCommand &command) override; void token(const TokenCommand &command) override;
@@ -57,6 +57,9 @@ public:
void changeSelection(const ChangeSelectionCommand &command) override; void changeSelection(const ChangeSelectionCommand &command) override;
void changePropertyValues(const ChangeValuesCommand &command) override; void changePropertyValues(const ChangeValuesCommand &command) override;
void removeInstances(const RemoveInstancesCommand &command) override; void removeInstances(const RemoveInstancesCommand &command) override;
void inputEvent(const InputEventCommand &command) override;
void view3DAction(const View3DActionCommand &command) override;
void changeAuxiliaryValues(const ChangeAuxiliaryCommand &command) override;
private slots: private slots:
void handleSelectionChanged(const QVariant &objs); void handleSelectionChanged(const QVariant &objs);
@@ -82,7 +85,7 @@ protected:
private: private:
void handleObjectPropertyChangeTimeout(); void handleObjectPropertyChangeTimeout();
void handleSelectionChangeTimeout(); void handleSelectionChangeTimeout();
QObject *createEditView3D(QQmlEngine *engine); void createEditView3D();
void setup3DEditView(const QList<ServerNodeInstance> &instanceList, void setup3DEditView(const QList<ServerNodeInstance> &instanceList,
const QHash<QString, QVariantMap> &toolStates); const QHash<QString, QVariantMap> &toolStates);
void createCameraAndLightGizmos(const QList<ServerNodeInstance> &instanceList) const; void createCameraAndLightGizmos(const QList<ServerNodeInstance> &instanceList) const;
@@ -104,8 +107,13 @@ private:
void removeNode3D(QObject *node); void removeNode3D(QObject *node);
void resolveSceneRoots(); void resolveSceneRoots();
ServerNodeInstance active3DSceneInstance() const; ServerNodeInstance active3DSceneInstance() const;
void render3DEditView();
void doRender3DEditView();
QObject *m_editView3D = nullptr; QPointer<QQuickView> m_editView3D;
QPointer<QQuickWindow> m_editWindow3D;
QQuickItem *m_editView3DRootItem = nullptr;
QQuickItem *m_editView3DContentItem = nullptr;
QSet<QObject *> m_view3Ds; QSet<QObject *> m_view3Ds;
QMultiHash<QObject *, QObject *> m_3DSceneMap; // key: scene root, value: node QMultiHash<QObject *, QObject *> m_3DSceneMap; // key: scene root, value: node
QObject *m_active3DView; QObject *m_active3DView;
@@ -115,10 +123,12 @@ private:
QList<TokenCommand> m_tokenList; QList<TokenCommand> m_tokenList;
QTimer m_propertyChangeTimer; QTimer m_propertyChangeTimer;
QTimer m_selectionChangeTimer; QTimer m_selectionChangeTimer;
QTimer m_renderTimer;
QVariant m_changedNode; QVariant m_changedNode;
PropertyName m_changedProperty; PropertyName m_changedProperty;
ChangeSelectionCommand m_pendingSelectionChangeCommand; ChangeSelectionCommand m_pendingSelectionChangeCommand;
QObject *m_3dHelper = nullptr; QObject *m_3dHelper = nullptr;
bool m_needRender = false;
}; };
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -70,8 +70,10 @@ Qt5NodeInstanceClientProxy::Qt5NodeInstanceClientProxy(QObject *parent) :
* because we want to be able to show the 3D Edit View * because we want to be able to show the 3D Edit View
* as a normal QQuickView. * as a normal QQuickView.
* The DesignerWindowManager prevents any window from actually being shown. */ * The DesignerWindowManager prevents any window from actually being shown. */
if (!qEnvironmentVariableIsSet("QMLDESIGNER_QUICK3D_MODE")) if (!qEnvironmentVariableIsSet("QMLDESIGNER_QUICK3D_MODE")
|| !qEnvironmentVariableIsSet("QMLDESIGNER_QUICK3D_SHOW_EDIT_WINDOW")) {
DesignerSupport::activateDesignerWindowManager(); DesignerSupport::activateDesignerWindowManager();
}
setNodeInstanceServer(new Qt5InformationNodeInstanceServer(this)); setNodeInstanceServer(new Qt5InformationNodeInstanceServer(this));
initializeSocket(); initializeSocket();
} else if (QCoreApplication::arguments().at(2) == QLatin1String("rendermode")) { } else if (QCoreApplication::arguments().at(2) == QLatin1String("rendermode")) {

View File

@@ -72,6 +72,7 @@ void Qt5NodeInstanceServer::initializeView()
DesignerSupport::createOpenGLContext(m_quickView.data()); DesignerSupport::createOpenGLContext(m_quickView.data());
if (qEnvironmentVariableIsSet("QMLDESIGNER_QUICK3D_MODE") if (qEnvironmentVariableIsSet("QMLDESIGNER_QUICK3D_MODE")
&& qEnvironmentVariableIsSet("QMLDESIGNER_QUICK3D_SHOW_EDIT_WINDOW")
&& QCoreApplication::arguments().at(2) == "editormode") { && QCoreApplication::arguments().at(2) == "editormode") {
/* In '3d editormode' we do not use the DesignerWindowManager /* In '3d editormode' we do not use the DesignerWindowManager
* and since we do not show the QQuickView we have to manually create the OpenGL context */ * and since we do not show the QQuickView we have to manually create the OpenGL context */

View File

@@ -627,16 +627,18 @@ QList<QQuickItem *> ServerNodeInstance::allItemsRecursive() const
QString ServerNodeInstance::id() const QString ServerNodeInstance::id() const
{ {
if (isValid())
return m_nodeInstance->id(); return m_nodeInstance->id();
return {};
} }
qint32 ServerNodeInstance::instanceId() const qint32 ServerNodeInstance::instanceId() const
{ {
if (isValid()) { if (isValid())
return m_nodeInstance->instanceId(); return m_nodeInstance->instanceId();
} else {
return -1; return -1;
}
} }
QList<ServerNodeInstance> ServerNodeInstance::stateInstances() const QList<ServerNodeInstance> ServerNodeInstance::stateInstances() const

View File

@@ -8,6 +8,7 @@
<file>mockfiles/GenericBackend.qml</file> <file>mockfiles/GenericBackend.qml</file>
<file>mockfiles/Dialog.qml</file> <file>mockfiles/Dialog.qml</file>
<file>mockfiles/EditView3D.qml</file> <file>mockfiles/EditView3D.qml</file>
<file>mockfiles/EditWindow3D.qml</file>
<file>mockfiles/EditCameraController.qml</file> <file>mockfiles/EditCameraController.qml</file>
<file>mockfiles/Arrow.qml</file> <file>mockfiles/Arrow.qml</file>
<file>mockfiles/AutoScaleHelper.qml</file> <file>mockfiles/AutoScaleHelper.qml</file>

View File

@@ -141,9 +141,10 @@ extend_qtc_plugin(QmlDesigner
changeselectioncommand.cpp changeselectioncommand.h changeselectioncommand.cpp changeselectioncommand.h
drop3dlibraryitemcommand.cpp drop3dlibraryitemcommand.h drop3dlibraryitemcommand.cpp drop3dlibraryitemcommand.h
update3dviewstatecommand.cpp update3dviewstatecommand.h update3dviewstatecommand.cpp update3dviewstatecommand.h
enable3dviewcommand.cpp enable3dviewcommand.h
view3dclosedcommand.cpp view3dclosedcommand.h view3dclosedcommand.cpp view3dclosedcommand.h
puppettocreatorcommand.cpp puppettocreatorcommand.h puppettocreatorcommand.cpp puppettocreatorcommand.h
inputeventcommand.cpp inputeventcommand.h
view3dactioncommand.cpp view3dactioncommand.h
) )
extend_qtc_plugin(QmlDesigner extend_qtc_plugin(QmlDesigner
@@ -194,6 +195,16 @@ extend_qtc_plugin(QmlDesigner
debugviewwidget.cpp debugviewwidget.h debugviewwidget.ui debugviewwidget.cpp debugviewwidget.h debugviewwidget.ui
) )
extend_qtc_plugin(QmlDesigner
SOURCES_PREFIX components/edit3d
SOURCES
edit3dview.cpp edit3dview.h
edit3dwidget.cpp edit3dwidget.h
edit3dcanvas.cpp edit3dcanvas.h
edit3dactions.cpp edit3dactions.h
edit3d.qrc
)
extend_qtc_plugin(QmlDesigner extend_qtc_plugin(QmlDesigner
SOURCES_PREFIX components/formeditor SOURCES_PREFIX components/formeditor
SOURCES SOURCES

View File

@@ -42,7 +42,8 @@ public:
ContextMenuAction, ContextMenuAction,
ToolBarAction, ToolBarAction,
Action, Action,
FormEditorAction FormEditorAction,
Edit3DAction
}; };
enum Priorities { enum Priorities {

View File

@@ -0,0 +1,12 @@
VPATH += $$PWD
SOURCES += edit3dwidget.cpp \
edit3dview.cpp \
edit3dcanvas.cpp \
edit3dactions.cpp
HEADERS += edit3dwidget.h \
edit3dview.h \
edit3dcanvas.h \
edit3dactions.h
RESOURCES += edit3d.qrc

View File

@@ -0,0 +1,34 @@
<RCC>
<qresource prefix="/edit3d">
<file>images/edit_light_off.png</file>
<file>images/edit_light_off@2x.png</file>
<file>images/edit_light_on.png</file>
<file>images/edit_light_on@2x.png</file>
<file>images/fit_active.png</file>
<file>images/fit_active@2x.png</file>
<file>images/global.png</file>
<file>images/global@2x.png</file>
<file>images/group_selection_selected.png</file>
<file>images/group_selection_selected@2x.png</file>
<file>images/item_selection_selected.png</file>
<file>images/item_selection_selected@2x.png</file>
<file>images/local.png</file>
<file>images/local@2x.png</file>
<file>images/move_active.png</file>
<file>images/move_active@2x.png</file>
<file>images/move_selected.png</file>
<file>images/move_selected@2x.png</file>
<file>images/ortho.png</file>
<file>images/ortho@2x.png</file>
<file>images/persp.png</file>
<file>images/persp@2x.png</file>
<file>images/rotate_active.png</file>
<file>images/rotate_active@2x.png</file>
<file>images/rotate_selected.png</file>
<file>images/rotate_selected@2x.png</file>
<file>images/scale_active.png</file>
<file>images/scale_active@2x.png</file>
<file>images/scale_selected.png</file>
<file>images/scale_selected@2x.png</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,97 @@
/****************************************************************************
**
** 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 "edit3dactions.h"
#include "edit3dview.h"
#include "edit3dwidget.h"
#include <viewmanager.h>
#include <nodeinstanceview.h>
#include <qmldesignerplugin.h>
#include <QDebug>
namespace QmlDesigner {
Edit3DActionTemplate::Edit3DActionTemplate(const QString &description,
SelectionContextOperation action,
View3DActionCommand::Type type)
: DefaultAction(description),
m_action(action),
m_type(type)
{ }
void Edit3DActionTemplate::actionTriggered(bool b)
{
if (m_type != View3DActionCommand::Empty) {
QmlDesignerPlugin::instance()->viewManager().nodeInstanceView()
->view3DAction(View3DActionCommand(m_type, b));
}
if (m_action)
m_action(m_selectionContext);
}
Edit3DAction::Edit3DAction(const QByteArray &menuId, View3DActionCommand::Type type,
const QString &description, const QKeySequence &key, bool checkable,
bool checked, const QIcon &iconOff, const QIcon &iconOn,
SelectionContextOperation selectionAction)
: AbstractAction(new Edit3DActionTemplate(description, selectionAction, type))
, m_menuId(menuId)
{
action()->setShortcut(key);
action()->setShortcutContext(Qt::WidgetWithChildrenShortcut);
action()->setCheckable(checkable);
action()->setChecked(checked);
if (checkable) {
QIcon onOffIcon;
const auto onAvail = iconOn.availableSizes(); // Assume both icons have same sizes available
for (const auto &size : onAvail) {
onOffIcon.addPixmap(iconOn.pixmap(size), QIcon::Normal, QIcon::On);
onOffIcon.addPixmap(iconOff.pixmap(size), QIcon::Normal, QIcon::Off);
}
action()->setIcon(onOffIcon);
} else {
action()->setIcon(iconOff);
}
}
QByteArray Edit3DAction::category() const
{
return QByteArray();
}
bool Edit3DAction::isVisible(const SelectionContext &selectionContext) const
{
return true;
}
bool Edit3DAction::isEnabled(const SelectionContext &selectionContext) const
{
return isVisible(selectionContext);
}
}

View File

@@ -0,0 +1,84 @@
/****************************************************************************
**
** 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.
**
****************************************************************************/
#pragma once
#include "view3dactioncommand.h"
#include <abstractaction.h>
#include <QtWidgets/qaction.h>
#include <QtGui/qicon.h>
namespace QmlDesigner {
using SelectionContextOperation = std::function<void(const SelectionContext &)>;
class Edit3DActionTemplate : public DefaultAction
{
public:
Edit3DActionTemplate(const QString &description, SelectionContextOperation action,
View3DActionCommand::Type type);
void actionTriggered(bool b) override;
SelectionContextOperation m_action;
View3DActionCommand::Type m_type;
};
class Edit3DAction : public AbstractAction
{
public:
Edit3DAction(const QByteArray &menuId, View3DActionCommand::Type type,
const QString &description, const QKeySequence &key, bool checkable, bool checked,
const QIcon &iconOff, const QIcon &iconOn,
SelectionContextOperation selectionAction = nullptr);
QByteArray category() const override;
int priority() const override
{
return CustomActionsPriority;
}
Type type() const override
{
return ActionInterface::Edit3DAction;
}
QByteArray menuId() const override
{
return m_menuId;
}
protected:
bool isVisible(const SelectionContext &selectionContext) const override;
bool isEnabled(const SelectionContext &selectionContext) const override;
private:
QByteArray m_menuId;
};
} // namespace QmlDesigner

View File

@@ -0,0 +1,125 @@
/****************************************************************************
**
** 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 "edit3dcanvas.h"
#include "edit3dview.h"
#include "edit3dwidget.h"
#include "nodehints.h"
#include "qmlvisualnode.h"
#include <QtCore/qmimedata.h>
#include <QPainter>
namespace QmlDesigner {
Edit3DCanvas::Edit3DCanvas(Edit3DWidget *parent)
: QWidget(parent),
m_parent(parent)
{
setMouseTracking(true);
setAcceptDrops(true);
}
void Edit3DCanvas::updateRenderImage(const QImage &img)
{
m_image = img;
update();
}
void Edit3DCanvas::updateActiveScene(qint32 activeScene)
{
m_activeScene = activeScene;
}
void Edit3DCanvas::mousePressEvent(QMouseEvent *e)
{
m_parent->view()->sendInputEvent(e);
QWidget::mousePressEvent(e);
}
void Edit3DCanvas::mouseReleaseEvent(QMouseEvent *e)
{
m_parent->view()->sendInputEvent(e);
QWidget::mouseReleaseEvent(e);
}
void Edit3DCanvas::mouseDoubleClickEvent(QMouseEvent *e)
{
m_parent->view()->sendInputEvent(e);
QWidget::mouseDoubleClickEvent(e);
}
void Edit3DCanvas::mouseMoveEvent(QMouseEvent *e)
{
m_parent->view()->sendInputEvent(e);
QWidget::mouseMoveEvent(e);
}
void Edit3DCanvas::wheelEvent(QWheelEvent *e)
{
m_parent->view()->sendInputEvent(e);
QWidget::wheelEvent(e);
}
void Edit3DCanvas::paintEvent(QPaintEvent *e)
{
Q_UNUSED(e)
QWidget::paintEvent(e);
QPainter painter(this);
painter.drawImage(rect(), m_image, rect());
}
void Edit3DCanvas::resizeEvent(QResizeEvent *e)
{
m_parent->view()->edit3DViewResized(e->size());
}
void Edit3DCanvas::dragEnterEvent(QDragEnterEvent *e)
{
QByteArray data = e->mimeData()->data(QStringLiteral("application/vnd.bauhaus.itemlibraryinfo"));
if (!data.isEmpty()) {
QDataStream stream(data);
stream >> m_itemLibraryEntry;
bool canDrop = NodeHints::fromItemLibraryEntry(m_itemLibraryEntry).canBeDroppedInView3D();
if (canDrop)
e->accept();
}
}
void Edit3DCanvas::dropEvent(QDropEvent *e)
{
Q_UNUSED(e)
QmlVisualNode::createQmlVisualNode(m_parent->view(), m_itemLibraryEntry, m_activeScene, {});
}
}

View File

@@ -0,0 +1,66 @@
/****************************************************************************
**
** 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.
**
****************************************************************************/
#pragma once
#include "itemlibraryinfo.h"
#include <QtWidgets/qwidget.h>
#include <QtGui/qimage.h>
#include <QtGui/qevent.h>
#include <QtCore/qpointer.h>
namespace QmlDesigner {
class Edit3DWidget;
class Edit3DCanvas : public QWidget
{
Q_OBJECT
public:
Edit3DCanvas(Edit3DWidget *parent);
void updateRenderImage(const QImage &img);
void updateActiveScene(qint32 activeScene);
protected:
void mousePressEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override;
void mouseDoubleClickEvent(QMouseEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override;
void wheelEvent(QWheelEvent *e) override;
void paintEvent(QPaintEvent *e) override;
void resizeEvent(QResizeEvent *e) override;
void dragEnterEvent(QDragEnterEvent *e) override;
void dropEvent(QDropEvent *e) override;
private:
QPointer<Edit3DWidget> m_parent;
QImage m_image;
qint32 m_activeScene;
ItemLibraryEntry m_itemLibraryEntry;
};
} // namespace QmlDesigner

View File

@@ -0,0 +1,247 @@
/****************************************************************************
**
** 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>
#include <utils/utilsicons.h>
#include <QDebug>
namespace QmlDesigner {
Edit3DView::Edit3DView(QObject *parent)
: AbstractView(parent)
{
}
Edit3DView::~Edit3DView()
{
}
void Edit3DView::createEdit3DWidget()
{
createEdit3DActions();
m_edit3DWidget = new Edit3DWidget(this);
}
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);
}
void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState)
{
const QString sceneKey = QStringLiteral("sceneInstanceId");
const QString selectKey = QStringLiteral("groupSelect");
const QString transformKey = QStringLiteral("groupTransform");
const QString perspectiveKey = QStringLiteral("usePerspective");
const QString orientationKey = QStringLiteral("globalOrientation");
const QString editLightKey = QStringLiteral("showEditLight");
if (sceneState.contains(sceneKey))
edit3DWidget()->canvas()->updateActiveScene(sceneState[sceneKey].value<qint32>());
if (sceneState.contains(selectKey))
m_selectionModeAction->action()->setChecked(sceneState[selectKey].toInt() == 0);
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);
if (sceneState.contains(orientationKey))
m_orientationModeAction->action()->setChecked(sceneState[orientationKey].toBool());
else
m_orientationModeAction->action()->setChecked(false);
if (sceneState.contains(editLightKey))
m_editLightAction->action()->setChecked(sceneState[editLightKey].toBool());
else
m_editLightAction->action()->setChecked(false);
}
void Edit3DView::sendInputEvent(QInputEvent *e) const
{
nodeInstanceView()->sendInputEvent(e);
}
void Edit3DView::edit3DViewResized(const QSize &size) const
{
nodeInstanceView()->edit3DViewResized(size);
}
QSize Edit3DView::canvasSize() const
{
if (!m_edit3DWidget.isNull() && m_edit3DWidget->canvas())
return m_edit3DWidget->canvas()->size();
return {};
}
void Edit3DView::createEdit3DActions()
{
m_selectionModeAction
= new Edit3DAction(
"Edit3DSelectionModeToggle", View3DActionCommand::SelectionModeToggle,
QCoreApplication::translate("SelectionModeToggleAction", "Toggle Group / Single Selection Mode"),
QKeySequence(Qt::Key_Q), true, false, Icons::EDIT3D_SELECTION_MODE_OFF.icon(),
Icons::EDIT3D_SELECTION_MODE_ON.icon());
m_moveToolAction
= new Edit3DAction(
"Edit3DMoveTool", View3DActionCommand::MoveTool,
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(
"Edit3DRotateTool", View3DActionCommand::RotateTool,
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(
"Edit3DScaleTool", View3DActionCommand::ScaleTool,
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(
"Edit3DFitToView", View3DActionCommand::FitToView,
QCoreApplication::translate("FitToViewAction", "Fit Selected Object To View"),
QKeySequence(Qt::Key_F), false, false, Icons::EDIT3D_FIT_SELECTED_OFF.icon(), {});
m_cameraModeAction
= new Edit3DAction(
"Edit3DCameraToggle", View3DActionCommand::CameraToggle,
QCoreApplication::translate("CameraToggleAction", "Toggle Perspective / Orthographic Edit Camera"),
QKeySequence(Qt::Key_T), true, false, Icons::EDIT3D_EDIT_CAMERA_OFF.icon(),
Icons::EDIT3D_EDIT_CAMERA_ON.icon());
m_orientationModeAction
= new Edit3DAction(
"Edit3DOrientationToggle", View3DActionCommand::OrientationToggle,
QCoreApplication::translate("OrientationToggleAction", "Toggle Global / Local Orientation"),
QKeySequence(Qt::Key_Y), true, false, Icons::EDIT3D_ORIENTATION_OFF.icon(),
Icons::EDIT3D_ORIENTATION_ON.icon());
m_editLightAction
= new Edit3DAction(
"Edit3DEditLightToggle", View3DActionCommand::EditLightToggle,
QCoreApplication::translate("EditLightToggleAction", "Toggle Edit Light On / Off"),
QKeySequence(Qt::Key_U), true, false, Icons::EDIT3D_LIGHT_OFF.icon(),
Icons::EDIT3D_LIGHT_ON.icon());
SelectionContextOperation resetTrigger = [this](const SelectionContext &) {
setCurrentStateNode(rootModelNode());
resetPuppet();
};
m_resetAction
= new Edit3DAction(
"Edit3DResetView", View3DActionCommand::Empty,
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;
m_rightActions << m_resetAction;
// TODO: Registering actions to action manager causes conflicting shortcuts in form editor.
// Registration commented out until UX defines non-conflicting shortcuts.
// Also, actions creation needs to be somehow triggered before action manager registers
// actions to creator.
// DesignerActionManager &actionManager = QmlDesignerPlugin::instance()->designerActionManager();
// for (auto action : qAsConst(m_leftActions)) {
// if (action)
// actionManager.addDesignerAction(action);
// }
// for (auto action : qAsConst(m_rightActions)) {
// if (action)
// actionManager.addDesignerAction(action);
// }
}
QVector<Edit3DAction *> Edit3DView::leftActions() const
{
return m_leftActions;
}
QVector<Edit3DAction *> Edit3DView::rightActions() const
{
return m_rightActions;
}
}

View File

@@ -0,0 +1,87 @@
/****************************************************************************
**
** 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.
**
****************************************************************************/
#pragma once
#include "view3dactioncommand.h"
#include <abstractview.h>
#include <QtGui/qevent.h>
#include <QtGui/qimage.h>
#include <QtCore/qvector.h>
#include <QtCore/qvariant.h>
#include <QtCore/qsize.h>
QT_BEGIN_NAMESPACE
QT_END_NAMESPACE
namespace QmlDesigner {
class Edit3DWidget;
class Edit3DAction;
class QMLDESIGNERCORE_EXPORT Edit3DView : public AbstractView
{
Q_OBJECT
public:
Edit3DView(QObject *parent = nullptr);
~Edit3DView() override;
WidgetInfo widgetInfo() override;
Edit3DWidget *edit3DWidget() const;
void renderImage3DChanged(const QImage &img) override;
void updateActiveScene3D(const QVariantMap &sceneState) override;
void sendInputEvent(QInputEvent *e) const;
void edit3DViewResized(const QSize &size) const;
QSize canvasSize() const;
void createEdit3DActions();
QVector<Edit3DAction *> leftActions() const;
QVector<Edit3DAction *> rightActions() const;
protected:
private:
void createEdit3DWidget();
QPointer<Edit3DWidget> m_edit3DWidget;
QVector<Edit3DAction *> m_leftActions;
QVector<Edit3DAction *> m_rightActions;
Edit3DAction *m_selectionModeAction;
Edit3DAction *m_moveToolAction;
Edit3DAction *m_rotateToolAction;
Edit3DAction *m_scaleToolAction;
Edit3DAction *m_fitAction;
Edit3DAction *m_cameraModeAction;
Edit3DAction *m_orientationModeAction;
Edit3DAction *m_editLightAction;
Edit3DAction *m_resetAction;
};
} // namespace QmlDesigner

View File

@@ -0,0 +1,106 @@
/****************************************************************************
**
** 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 "edit3dwidget.h"
#include "edit3dview.h"
#include "edit3dcanvas.h"
#include "edit3dactions.h"
#include "qmldesignerplugin.h"
#include "designersettings.h"
#include "qmldesignerconstants.h"
#include "viewmanager.h"
#include <toolbox.h>
#include <utils/utilsicons.h>
#include <QVBoxLayout>
namespace QmlDesigner {
Edit3DWidget::Edit3DWidget(Edit3DView *view) :
m_view(view)
{
setMouseTracking(true);
setFocusPolicy(Qt::WheelFocus);
auto fillLayout = new QVBoxLayout(this);
fillLayout->setContentsMargins(0, 0, 0, 0);
fillLayout->setSpacing(0);
setLayout(fillLayout);
// Initialize toolbar
m_toolBox = new ToolBox(this);
fillLayout->addWidget(m_toolBox.data());
// Iterate through view actions. A null action indicates a separator and a second null action
// after separator indicates an exclusive group.
auto addActionsToToolBox = [this](const QVector<Edit3DAction *> &actions, bool left) {
bool previousWasSeparator = true;
QActionGroup *group = nullptr;
for (auto action : actions) {
if (action) {
if (group)
group->addAction(action->action());
addAction(action->action());
if (left)
m_toolBox->addLeftSideAction(action->action());
else
m_toolBox->addRightSideAction(action->action());
previousWasSeparator = false;
} else {
if (previousWasSeparator) {
group = new QActionGroup(this);
previousWasSeparator = false;
} else {
group = nullptr;
auto separator = new QAction(this);
separator->setSeparator(true);
addAction(separator);
m_toolBox->addLeftSideAction(separator);
previousWasSeparator = true;
}
}
}
};
addActionsToToolBox(view->leftActions(), true);
addActionsToToolBox(view->rightActions(), false);
// Canvas is used to render the actual edit 3d view
m_canvas = new Edit3DCanvas(this);
fillLayout->addWidget(m_canvas.data());
}
Edit3DCanvas *Edit3DWidget::canvas() const
{
return m_canvas.data();
}
Edit3DView *Edit3DWidget::view() const
{
return m_view.data();
}
}

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2019 The Qt Company Ltd. ** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of Qt Creator. ** This file is part of Qt Creator.
@@ -22,33 +22,32 @@
** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
** **
****************************************************************************/ ****************************************************************************/
#pragma once #pragma once
#include <QMetaType> #include <QtWidgets/qwidget.h>
#include <QtCore/qpointer.h>
namespace QmlDesigner { namespace QmlDesigner {
class Enable3DViewCommand class Edit3DView;
class Edit3DCanvas;
class ToolBox;
class Edit3DWidget : public QWidget
{ {
friend QDataStream &operator>>(QDataStream &in, Enable3DViewCommand &command); Q_OBJECT
friend QDebug operator<<(QDebug debug, const Enable3DViewCommand &command);
public: public:
explicit Enable3DViewCommand(bool enable); Edit3DWidget(Edit3DView *view);
Enable3DViewCommand() = default;
bool isEnable() const; Edit3DCanvas *canvas() const;
Edit3DView *view() const;
private: private:
bool m_enable = true; QPointer<Edit3DView> m_edit3DView;
QPointer<Edit3DView> m_view;
QPointer<Edit3DCanvas> m_canvas;
QPointer<ToolBox> m_toolBox;
}; };
QDataStream &operator<<(QDataStream &out, const Enable3DViewCommand &command);
QDataStream &operator>>(QDataStream &in, Enable3DViewCommand &command);
QDebug operator<<(QDebug debug, const Enable3DViewCommand &command);
} // namespace QmlDesigner } // namespace QmlDesigner
Q_DECLARE_METATYPE(QmlDesigner::Enable3DViewCommand)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 561 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 904 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 661 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 869 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 906 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 B

View File

@@ -676,9 +676,6 @@ void FormEditorView::toggle3DViewEnabled(bool enabled)
rootModelNode().removeAuxiliaryData("3d-view"); rootModelNode().removeAuxiliaryData("3d-view");
resetNodeInstanceView(); resetNodeInstanceView();
// TODO: the line below is not in use. It should replace the resetNodeInstanceView(); to have a clean API
// nodeInstanceView()->enable3DView(enabled);
} }
QmlItemNode findRecursiveQmlItemNode(const QmlObjectNode &firstQmlObjectNode) QmlItemNode findRecursiveQmlItemNode(const QmlObjectNode &firstQmlObjectNode)

View File

@@ -72,7 +72,7 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view) :
layoutActionGroup->setExclusive(true); layoutActionGroup->setExclusive(true);
m_noSnappingAction = layoutActionGroup->addAction(tr("No snapping (T).")); m_noSnappingAction = layoutActionGroup->addAction(tr("No snapping (T)."));
m_noSnappingAction->setShortcut(Qt::Key_W); m_noSnappingAction->setShortcut(Qt::Key_T);
m_noSnappingAction->setShortcutContext(Qt::WidgetWithChildrenShortcut); m_noSnappingAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
m_noSnappingAction->setCheckable(true); m_noSnappingAction->setCheckable(true);
m_noSnappingAction->setChecked(true); m_noSnappingAction->setChecked(true);
@@ -133,7 +133,6 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view) :
m_toolBox = new ToolBox(this); m_toolBox = new ToolBox(this);
fillLayout->addWidget(m_toolBox.data()); fillLayout->addWidget(m_toolBox.data());
m_toolBox->setLeftSideActions(upperActions); m_toolBox->setLeftSideActions(upperActions);
m_backgroundAction = new BackgroundAction(m_toolActionGroup.data()); m_backgroundAction = new BackgroundAction(m_toolActionGroup.data());
@@ -143,9 +142,11 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view) :
m_toolBox->addRightSideAction(m_backgroundAction.data()); m_toolBox->addRightSideAction(m_backgroundAction.data());
m_option3DAction = new Option3DAction(m_toolActionGroup.data()); m_option3DAction = new Option3DAction(m_toolActionGroup.data());
if (qEnvironmentVariableIsSet("QMLDESIGNER_QUICK3D_SHOW_EDIT_WINDOW")) {
addAction(m_option3DAction.data()); addAction(m_option3DAction.data());
upperActions.append(m_option3DAction.data()); upperActions.append(m_option3DAction.data());
m_toolBox->addRightSideAction(m_option3DAction.data()); m_toolBox->addRightSideAction(m_option3DAction.data());
}
m_zoomAction = new ZoomAction(m_toolActionGroup.data()); m_zoomAction = new ZoomAction(m_toolActionGroup.data());
connect(m_zoomAction.data(), &ZoomAction::zoomLevelChanged, connect(m_zoomAction.data(), &ZoomAction::zoomLevelChanged,

View File

@@ -28,6 +28,10 @@ QTabBar#centralTabBar::tab:selected {
color: creatorTheme.QmlDesigner_TabDark; color: creatorTheme.QmlDesigner_TabDark;
} }
QTabBar#centralTabBar::tab:disabled {
color: creatorTheme.QmlDesigner_ScrollBarHandleColor;
}
QToolButton#centralTabBar { QToolButton#centralTabBar {
background-color: creatorTheme.QmlDesigner_BackgroundColorDarkAlternate; background-color: creatorTheme.QmlDesigner_BackgroundColorDarkAlternate;
width: 08px; width: 08px;

View File

@@ -16,6 +16,7 @@ QtcProduct {
"..", "..",
"../components/componentcore", "../components/componentcore",
"../components/debugview", "../components/debugview",
"../components/edit3d",
"../components/formeditor", "../components/formeditor",
"../components/importmanager", "../components/importmanager",
"../components/integration", "../components/integration",

View File

@@ -44,6 +44,7 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QStyle; class QStyle;
class QToolButton; class QToolButton;
class QImage;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace QmlDesigner { namespace QmlDesigner {
@@ -182,6 +183,8 @@ public:
void emitRewriterBeginTransaction(); void emitRewriterBeginTransaction();
void emitRewriterEndTransaction(); void emitRewriterEndTransaction();
void emitInstanceToken(const QString &token, int number, const QVector<ModelNode> &nodeVector); void emitInstanceToken(const QString &token, int number, const QVector<ModelNode> &nodeVector);
void emitRenderImage3DChanged(const QImage &image);
void emitUpdateActiveScene3D(const QVariantMap &sceneState);
void sendTokenToInstances(const QString &token, int number, const QVector<ModelNode> &nodeVector); void sendTokenToInstances(const QString &token, int number, const QVector<ModelNode> &nodeVector);
@@ -237,6 +240,9 @@ public:
virtual void currentTimelineChanged(const ModelNode &node); virtual void currentTimelineChanged(const ModelNode &node);
virtual void renderImage3DChanged(const QImage &image);
virtual void updateActiveScene3D(const QVariantMap &sceneState);
void changeRootNodeType(const TypeName &type, int majorVersion, int minorVersion); void changeRootNodeType(const TypeName &type, int majorVersion, int minorVersion);
NodeInstanceView *nodeInstanceView() const; NodeInstanceView *nodeInstanceView() const;

View File

@@ -59,6 +59,7 @@ public:
bool doesLayoutChildren() const; bool doesLayoutChildren() const;
bool canBeDroppedInFormEditor() const; bool canBeDroppedInFormEditor() const;
bool canBeDroppedInNavigator() const; bool canBeDroppedInNavigator() const;
bool canBeDroppedInView3D() const;
bool isMovable() const; bool isMovable() const;
bool isResizable() const; bool isResizable() const;
bool isStackedContainer() const; bool isStackedContainer() const;

View File

@@ -39,6 +39,7 @@
#include <QPointer> #include <QPointer>
#include <QRectF> #include <QRectF>
#include <QTime> #include <QTime>
#include <QtGui/qevent.h>
namespace ProjectExplorer { namespace ProjectExplorer {
class Target; class Target;
@@ -94,7 +95,6 @@ public:
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 nodeSourceChanged(const ModelNode &modelNode, const QString &newNodeSource) override; void nodeSourceChanged(const ModelNode &modelNode, const QString &newNodeSource) override;
void currentStateChanged(const ModelNode &node) override; void currentStateChanged(const ModelNode &node) override;
QList<NodeInstance> instances() const; QList<NodeInstance> instances() const;
@@ -136,7 +136,9 @@ public:
void mainWindowStateChanged(Qt::WindowStates previousStates, Qt::WindowStates currentStates); void mainWindowStateChanged(Qt::WindowStates previousStates, Qt::WindowStates currentStates);
void mainWindowActiveChanged(bool active, bool hasPopup); void mainWindowActiveChanged(bool active, bool hasPopup);
void enable3DView(bool enable); void sendInputEvent(QInputEvent *e) const;
void view3DAction(const View3DActionCommand &command);
void edit3DViewResized(const QSize &size) const;
void handlePuppetToCreatorCommand(const PuppetToCreatorCommand &command) override; void handlePuppetToCreatorCommand(const PuppetToCreatorCommand &command) override;

View File

@@ -42,6 +42,7 @@ class AbstractCustomTool;
class DesignerActionManager; class DesignerActionManager;
class NodeInstanceView; class NodeInstanceView;
class RewriterView; class RewriterView;
class Edit3DView;
namespace Internal { class DesignModeWidget; } namespace Internal { class DesignModeWidget; }

View File

@@ -30,7 +30,6 @@
#include <createinstancescommand.h> #include <createinstancescommand.h>
#include <createscenecommand.h> #include <createscenecommand.h>
#include <update3dviewstatecommand.h> #include <update3dviewstatecommand.h>
#include <enable3dviewcommand.h>
#include <changevaluescommand.h> #include <changevaluescommand.h>
#include <changebindingscommand.h> #include <changebindingscommand.h>
#include <changeauxiliarycommand.h> #include <changeauxiliarycommand.h>
@@ -47,6 +46,8 @@
#include <drop3dlibraryitemcommand.h> #include <drop3dlibraryitemcommand.h>
#include <puppettocreatorcommand.h> #include <puppettocreatorcommand.h>
#include <view3dclosedcommand.h> #include <view3dclosedcommand.h>
#include <inputeventcommand.h>
#include <view3dactioncommand.h>
#include <informationchangedcommand.h> #include <informationchangedcommand.h>
#include <pixmapchangedcommand.h> #include <pixmapchangedcommand.h>
@@ -665,11 +666,6 @@ void NodeInstanceServerProxy::update3DViewState(const Update3dViewStateCommand &
writeCommand(QVariant::fromValue(command)); writeCommand(QVariant::fromValue(command));
} }
void NodeInstanceServerProxy::enable3DView(const Enable3DViewCommand &command)
{
writeCommand(QVariant::fromValue(command));
}
void NodeInstanceServerProxy::removeInstances(const RemoveInstancesCommand &command) void NodeInstanceServerProxy::removeInstances(const RemoveInstancesCommand &command)
{ {
writeCommand(QVariant::fromValue(command)); writeCommand(QVariant::fromValue(command));
@@ -740,4 +736,14 @@ void NodeInstanceServerProxy::benchmark(const QString &message)
qCInfo(instanceViewBenchmark) << message << m_benchmarkTimer.elapsed(); qCInfo(instanceViewBenchmark) << message << m_benchmarkTimer.elapsed();
} }
void NodeInstanceServerProxy::inputEvent(const InputEventCommand &command)
{
writeCommand(QVariant::fromValue(command));
}
void NodeInstanceServerProxy::view3DAction(const View3DActionCommand &command)
{
writeCommand(QVariant::fromValue(command));
}
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -68,7 +68,6 @@ public:
void changeFileUrl(const ChangeFileUrlCommand &command) override; void changeFileUrl(const ChangeFileUrlCommand &command) override;
void createScene(const CreateSceneCommand &command) override; void createScene(const CreateSceneCommand &command) override;
void update3DViewState(const Update3dViewStateCommand &command) override; void update3DViewState(const Update3dViewStateCommand &command) override;
void enable3DView(const Enable3DViewCommand &command) override;
void clearScene(const ClearSceneCommand &command) override; void clearScene(const ClearSceneCommand &command) override;
void removeInstances(const RemoveInstancesCommand &command) override; void removeInstances(const RemoveInstancesCommand &command) override;
void changeSelection(const ChangeSelectionCommand &command) override; void changeSelection(const ChangeSelectionCommand &command) override;
@@ -84,6 +83,8 @@ public:
void token(const TokenCommand &command) override; void token(const TokenCommand &command) override;
void removeSharedMemory(const RemoveSharedMemoryCommand &command) override; void removeSharedMemory(const RemoveSharedMemoryCommand &command) override;
void benchmark(const QString &message) override; void benchmark(const QString &message) override;
void inputEvent(const InputEventCommand &command) override;
void view3DAction(const View3DActionCommand &command) override;
protected: protected:
void writeCommand(const QVariant &command); void writeCommand(const QVariant &command);

View File

@@ -48,7 +48,6 @@
#include "changefileurlcommand.h" #include "changefileurlcommand.h"
#include "reparentinstancescommand.h" #include "reparentinstancescommand.h"
#include "update3dviewstatecommand.h" #include "update3dviewstatecommand.h"
#include "enable3dviewcommand.h"
#include "changevaluescommand.h" #include "changevaluescommand.h"
#include "changeauxiliarycommand.h" #include "changeauxiliarycommand.h"
#include "changebindingscommand.h" #include "changebindingscommand.h"
@@ -71,6 +70,9 @@
#include "debugoutputcommand.h" #include "debugoutputcommand.h"
#include "nodeinstanceserverproxy.h" #include "nodeinstanceserverproxy.h"
#include "puppettocreatorcommand.h" #include "puppettocreatorcommand.h"
#include "inputeventcommand.h"
#include "view3dactioncommand.h"
#include "edit3dview.h"
#ifndef QMLDESIGNER_TEST #ifndef QMLDESIGNER_TEST
#include <qmldesignerplugin.h> #include <qmldesignerplugin.h>
@@ -1470,6 +1472,13 @@ void NodeInstanceView::handlePuppetToCreatorCommand(const PuppetToCreatorCommand
m_edit3DToolStates[qmlId].insert(data[1].toString(), data[2]); m_edit3DToolStates[qmlId].insert(data[1].toString(), data[2]);
} }
} }
} else if (command.type() == PuppetToCreatorCommand::Render3DView) {
ImageContainer container = qvariant_cast<ImageContainer>(command.data());
if (!container.image().isNull())
emitRenderImage3DChanged(container.image());
} else if (command.type() == PuppetToCreatorCommand::ActiveSceneChanged) {
const auto sceneState = qvariant_cast<QVariantMap>(command.data());
emitUpdateActiveScene3D(sceneState);
} }
} }
@@ -1526,10 +1535,19 @@ void NodeInstanceView::mainWindowActiveChanged(bool active, bool hasPopup)
nodeInstanceServer()->update3DViewState(Update3dViewStateCommand(active, hasPopup)); nodeInstanceServer()->update3DViewState(Update3dViewStateCommand(active, hasPopup));
} }
// enable / disable 3D edit View void NodeInstanceView::sendInputEvent(QInputEvent *e) const
void NodeInstanceView::enable3DView(bool enable)
{ {
nodeInstanceServer()->enable3DView(Enable3DViewCommand(enable)); nodeInstanceServer()->inputEvent(InputEventCommand(e));
}
void NodeInstanceView::view3DAction(const View3DActionCommand &command)
{
nodeInstanceServer()->view3DAction(command);
}
void NodeInstanceView::edit3DViewResized(const QSize &size) const
{
nodeInstanceServer()->update3DViewState(Update3dViewStateCommand(size));
} }
void NodeInstanceView::timerEvent(QTimerEvent *event) void NodeInstanceView::timerEvent(QTimerEvent *event)

View File

@@ -165,6 +165,11 @@ bool NodeHints::canBeDroppedInNavigator() const
return evaluateBooleanExpression("canBeDroppedInNavigator", true); return evaluateBooleanExpression("canBeDroppedInNavigator", true);
} }
bool NodeHints::canBeDroppedInView3D() const
{
return evaluateBooleanExpression("canBeDroppedInView3D", false);
}
bool NodeHints::isMovable() const bool NodeHints::isMovable() const
{ {
if (!isValid()) if (!isValid())

View File

@@ -42,6 +42,7 @@
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <QRegExp> #include <QRegExp>
#include <QtGui/qimage.h>
namespace QmlDesigner { namespace QmlDesigner {
@@ -362,7 +363,14 @@ void AbstractView::documentMessagesChanged(const QList<DocumentMessage> &/*error
void AbstractView::currentTimelineChanged(const ModelNode & /*node*/) void AbstractView::currentTimelineChanged(const ModelNode & /*node*/)
{ {
}
void AbstractView::renderImage3DChanged(const QImage &image)
{
}
void AbstractView::updateActiveScene3D(const QVariantMap &sceneState)
{
} }
QList<ModelNode> AbstractView::toModelNodeList(const QList<Internal::InternalNode::Pointer> &nodeList) const QList<ModelNode> AbstractView::toModelNodeList(const QList<Internal::InternalNode::Pointer> &nodeList) const
@@ -729,6 +737,18 @@ void AbstractView::emitInstanceToken(const QString &token, int number, const QVe
model()->d->notifyInstanceToken(token, number, nodeVector); model()->d->notifyInstanceToken(token, number, nodeVector);
} }
void AbstractView::emitRenderImage3DChanged(const QImage &image)
{
if (model())
model()->d->notifyRenderImage3DChanged(image);
}
void AbstractView::emitUpdateActiveScene3D(const QVariantMap &sceneState)
{
if (model())
model()->d->notifyUpdateActiveScene3D(sceneState);
}
void AbstractView::emitRewriterEndTransaction() void AbstractView::emitRewriterEndTransaction()
{ {
if (model()) if (model())

View File

@@ -668,6 +668,22 @@ void ModelPrivate::notifyCurrentTimelineChanged(const ModelNode &node)
resetModelByRewriter(description); resetModelByRewriter(description);
} }
void ModelPrivate::notifyRenderImage3DChanged(const QImage &image)
{
for (const QPointer<AbstractView> &view : qAsConst(m_viewList)) {
Q_ASSERT(view != nullptr);
view->renderImage3DChanged(image);
}
}
void ModelPrivate::notifyUpdateActiveScene3D(const QVariantMap &sceneState)
{
for (const QPointer<AbstractView> &view : qAsConst(m_viewList)) {
Q_ASSERT(view != nullptr);
view->updateActiveScene3D(sceneState);
}
}
void ModelPrivate::notifyRewriterBeginTransaction() void ModelPrivate::notifyRewriterBeginTransaction()
{ {
bool resetModel = false; bool resetModel = false;

View File

@@ -158,6 +158,9 @@ public:
void notifyCurrentStateChanged(const ModelNode &node); void notifyCurrentStateChanged(const ModelNode &node);
void notifyCurrentTimelineChanged(const ModelNode &node); void notifyCurrentTimelineChanged(const ModelNode &node);
void notifyRenderImage3DChanged(const QImage &image);
void notifyUpdateActiveScene3D(const QVariantMap &sceneState);
void setDocumentMessages(const QList<DocumentMessage> &errors, const QList<DocumentMessage> &warnings); void setDocumentMessages(const QList<DocumentMessage> &errors, const QList<DocumentMessage> &warnings);
void notifyRewriterBeginTransaction(); void notifyRewriterBeginTransaction();

View File

@@ -36,6 +36,7 @@
#include <itemlibraryview.h> #include <itemlibraryview.h>
#include <navigatorview.h> #include <navigatorview.h>
#include <stateseditorview.h> #include <stateseditorview.h>
#include <edit3dview.h>
#include <formeditorview.h> #include <formeditorview.h>
#include <texteditorview.h> #include <texteditorview.h>
#include <propertyeditorview.h> #include <propertyeditorview.h>
@@ -63,6 +64,7 @@ public:
DesignerActionManagerView designerActionManagerView; DesignerActionManagerView designerActionManagerView;
NodeInstanceView nodeInstanceView; NodeInstanceView nodeInstanceView;
ComponentView componentView; ComponentView componentView;
Edit3DView edit3DView;
FormEditorView formEditorView; FormEditorView formEditorView;
TextEditorView textEditorView; TextEditorView textEditorView;
ItemLibraryView itemLibraryView; ItemLibraryView itemLibraryView;
@@ -73,7 +75,6 @@ public:
QList<QPointer<AbstractView> > additionalViews; QList<QPointer<AbstractView> > additionalViews;
}; };
static CrumbleBar *crumbleBar() { static CrumbleBar *crumbleBar() {
return QmlDesignerPlugin::instance()->mainWidget()->crumbleBar(); return QmlDesignerPlugin::instance()->mainWidget()->crumbleBar();
} }
@@ -165,6 +166,7 @@ QList<QPointer<AbstractView> > ViewManager::views() const
{ {
auto list = d->additionalViews; auto list = d->additionalViews;
list.append({ list.append({
&d->edit3DView,
&d->formEditorView, &d->formEditorView,
&d->textEditorView, &d->textEditorView,
&d->itemLibraryView, &d->itemLibraryView,
@@ -195,6 +197,7 @@ void ViewManager::detachViewsExceptRewriterAndComponetView()
switchStateEditorViewToBaseState(); switchStateEditorViewToBaseState();
detachAdditionalViews(); detachAdditionalViews();
currentModel()->detachView(&d->designerActionManagerView); currentModel()->detachView(&d->designerActionManagerView);
currentModel()->detachView(&d->edit3DView);
currentModel()->detachView(&d->formEditorView); currentModel()->detachView(&d->formEditorView);
currentModel()->detachView(&d->textEditorView); currentModel()->detachView(&d->textEditorView);
currentModel()->detachView(&d->navigatorView); currentModel()->detachView(&d->navigatorView);
@@ -264,9 +267,15 @@ void ViewManager::attachViewsExceptRewriterAndComponetView()
int last = time.elapsed(); int last = time.elapsed();
qCInfo(viewBenchmark) << "ActionManagerView:" << last << time.elapsed(); qCInfo(viewBenchmark) << "ActionManagerView:" << last << time.elapsed();
currentModel()->attachView(&d->formEditorView); currentModel()->attachView(&d->edit3DView);
int currentTime = time.elapsed(); int currentTime = time.elapsed();
qCInfo(viewBenchmark) << "Edit3DView:" << currentTime - last;
last = currentTime;
currentModel()->attachView(&d->formEditorView);
currentTime = time.elapsed();
qCInfo(viewBenchmark) << "FormEditorView:" << currentTime - last; qCInfo(viewBenchmark) << "FormEditorView:" << currentTime - last;
last = currentTime; last = currentTime;
@@ -337,6 +346,7 @@ QList<WidgetInfo> ViewManager::widgetInfos() const
{ {
QList<WidgetInfo> widgetInfoList; QList<WidgetInfo> widgetInfoList;
widgetInfoList.append(d->edit3DView.widgetInfo());
widgetInfoList.append(d->formEditorView.widgetInfo()); widgetInfoList.append(d->formEditorView.widgetInfo());
widgetInfoList.append(d->textEditorView.widgetInfo()); widgetInfoList.append(d->textEditorView.widgetInfo());
widgetInfoList.append(d->itemLibraryView.widgetInfo()); widgetInfoList.append(d->itemLibraryView.widgetInfo());

View File

@@ -31,6 +31,7 @@
#include "qmldesignerplugin.h" #include "qmldesignerplugin.h"
#include "crumblebar.h" #include "crumblebar.h"
#include "documentwarningwidget.h" #include "documentwarningwidget.h"
#include "edit3dview.h"
#include <texteditor/textdocument.h> #include <texteditor/textdocument.h>
#include <nodeinstanceview.h> #include <nodeinstanceview.h>

View File

@@ -23,6 +23,7 @@ INCLUDEPATH *= \
$$PWD/components/componentcore \ $$PWD/components/componentcore \
$$PWD/components/importmanager \ $$PWD/components/importmanager \
$$PWD/components/itemlibrary \ $$PWD/components/itemlibrary \
$$PWD/components/edit3d \
$$PWD/components/formeditor \ $$PWD/components/formeditor \
$$PWD/components/navigator \ $$PWD/components/navigator \
$$PWD/components/stateseditor \ $$PWD/components/stateseditor \

View File

@@ -47,5 +47,36 @@ const Utils::Icon NO_SNAPPING({
const Utils::Icon NO_SNAPPING_AND_ANCHORING({ const Utils::Icon NO_SNAPPING_AND_ANCHORING({
{QLatin1String(":/icon/layout/snapping_and_anchoring.png"), Utils::Theme::IconsBaseColor}}); {QLatin1String(":/icon/layout/snapping_and_anchoring.png"), Utils::Theme::IconsBaseColor}});
const Utils::Icon EDIT3D_LIGHT_ON({
{QLatin1String(":/edit3d/images/edit_light_on.png"), Utils::Theme::IconsBaseColor}});
const Utils::Icon EDIT3D_LIGHT_OFF({
{QLatin1String(":/edit3d/images/edit_light_off.png"), Utils::Theme::IconsBaseColor}});
const Utils::Icon EDIT3D_SELECTION_MODE_ON({
{QLatin1String(":/edit3d/images/group_selection_selected.png"), Utils::Theme::IconsBaseColor}});
const Utils::Icon EDIT3D_SELECTION_MODE_OFF({
{QLatin1String(":/edit3d/images/item_selection_selected.png"), Utils::Theme::IconsBaseColor}});
const Utils::Icon EDIT3D_MOVE_TOOL_ON({
{QLatin1String(":/edit3d/images/move_selected.png"), Utils::Theme::IconsBaseColor}});
const Utils::Icon EDIT3D_MOVE_TOOL_OFF({
{QLatin1String(":/edit3d/images/move_active.png"), Utils::Theme::IconsBaseColor}});
const Utils::Icon EDIT3D_ROTATE_TOOL_ON({
{QLatin1String(":/edit3d/images/rotate_selected.png"), Utils::Theme::IconsBaseColor}});
const Utils::Icon EDIT3D_ROTATE_TOOL_OFF({
{QLatin1String(":/edit3d/images/rotate_active.png"), Utils::Theme::IconsBaseColor}});
const Utils::Icon EDIT3D_SCALE_TOOL_ON({
{QLatin1String(":/edit3d/images/scale_selected.png"), Utils::Theme::IconsBaseColor}});
const Utils::Icon EDIT3D_SCALE_TOOL_OFF({
{QLatin1String(":/edit3d/images/scale_active.png"), Utils::Theme::IconsBaseColor}});
const Utils::Icon EDIT3D_FIT_SELECTED_OFF({
{QLatin1String(":/edit3d/images/fit_active.png"), Utils::Theme::IconsBaseColor}});
const Utils::Icon EDIT3D_EDIT_CAMERA_ON({
{QLatin1String(":/edit3d/images/persp.png"), Utils::Theme::IconsBaseColor}});
const Utils::Icon EDIT3D_EDIT_CAMERA_OFF({
{QLatin1String(":/edit3d/images/ortho.png"), Utils::Theme::IconsBaseColor}});
const Utils::Icon EDIT3D_ORIENTATION_ON({
{QLatin1String(":/edit3d/images/global.png"), Utils::Theme::IconsBaseColor}});
const Utils::Icon EDIT3D_ORIENTATION_OFF({
{QLatin1String(":/edit3d/images/local.png"), Utils::Theme::IconsBaseColor}});
} // Icons } // Icons
} // QmlDesigner } // QmlDesigner

View File

@@ -13,6 +13,7 @@ include(designercore/designercore-lib.pri)
include(components/componentcore/componentcore.pri) include(components/componentcore/componentcore.pri)
include(components/integration/integration.pri) include(components/integration/integration.pri)
include(components/propertyeditor/propertyeditor.pri) include(components/propertyeditor/propertyeditor.pri)
include(components/edit3d/edit3d.pri)
include(components/formeditor/formeditor.pri) include(components/formeditor/formeditor.pri)
include(components/texteditor/texteditor.pri) include(components/texteditor/texteditor.pri)
include(components/itemlibrary/itemlibrary.pri) include(components/itemlibrary/itemlibrary.pri)

View File

@@ -51,6 +51,7 @@ Project {
"components/importmanager", "components/importmanager",
"components/integration", "components/integration",
"components/propertyeditor", "components/propertyeditor",
"components/edit3d",
"components/formeditor", "components/formeditor",
"components/itemlibrary", "components/itemlibrary",
"components/navigator", "components/navigator",
@@ -70,6 +71,7 @@ Project {
cpp.includePaths: base.concat([ cpp.includePaths: base.concat([
product.sourceDirectory, product.sourceDirectory,
product.sourceDirectory + "/components/componentcore", product.sourceDirectory + "/components/componentcore",
product.sourceDirectory + "/components/edit3d",
product.sourceDirectory + "/components/formeditor", product.sourceDirectory + "/components/formeditor",
product.sourceDirectory + "/components/integration", product.sourceDirectory + "/components/integration",
product.sourceDirectory + "/designercore", product.sourceDirectory + "/designercore",
@@ -175,12 +177,14 @@ Project {
"commands/drop3dlibraryitemcommand.h", "commands/drop3dlibraryitemcommand.h",
"commands/update3dviewstatecommand.cpp", "commands/update3dviewstatecommand.cpp",
"commands/update3dviewstatecommand.h", "commands/update3dviewstatecommand.h",
"commands/enable3dviewcommand.cpp",
"commands/enable3dviewcommand.h",
"commands/view3dclosedcommand.cpp", "commands/view3dclosedcommand.cpp",
"commands/view3dclosedcommand.h", "commands/view3dclosedcommand.h",
"commands/puppettocreatorcommand.cpp", "commands/puppettocreatorcommand.cpp",
"commands/puppettocreatorcommand.h", "commands/puppettocreatorcommand.h",
"commands/inputeventcommand.cpp",
"commands/inputeventcommand.h",
"commands/view3dactioncommand.cpp",
"commands/view3dactioncommand.h",
"container/addimportcontainer.cpp", "container/addimportcontainer.cpp",
"container/addimportcontainer.h", "container/addimportcontainer.h",
"container/idcontainer.cpp", "container/idcontainer.cpp",
@@ -444,6 +448,15 @@ Project {
"debugview/debugviewwidget.cpp", "debugview/debugviewwidget.cpp",
"debugview/debugviewwidget.h", "debugview/debugviewwidget.h",
"debugview/debugviewwidget.ui", "debugview/debugviewwidget.ui",
"edit3d/edit3dview.cpp",
"edit3d/edit3dview.h",
"edit3d/edit3dwidget.cpp",
"edit3d/edit3dwidget.h",
"edit3d/edit3dcanvas.cpp",
"edit3d/edit3dcanvas.h",
"edit3d/edit3dactions.cpp",
"edit3d/edit3dactions.h",
"edit3d/edit3d.qrc",
"formeditor/abstractcustomtool.cpp", "formeditor/abstractcustomtool.cpp",
"formeditor/abstractcustomtool.h", "formeditor/abstractcustomtool.h",
"formeditor/abstractformeditortool.cpp", "formeditor/abstractformeditortool.cpp",

View File

@@ -121,25 +121,32 @@ QWidget *SwitchSplitTabWidget::currentWidget() const
void SwitchSplitTabWidget::updateSplitterSizes(int index) void SwitchSplitTabWidget::updateSplitterSizes(int index)
{ {
if (isHidden()) { QVector<int> splitterSizes(m_splitter->count());
// we cannot get the sizes if the splitter is hidden
m_splittSizesAreDirty = true;
return;
}
QVector<int> splitterSizes = m_splitter->sizes().toVector();
int splitterFullSize = 0; int splitterFullSize = 0;
for (int size : splitterSizes) bool isHorizontal = m_splitter->orientation() == Qt::Horizontal;
splitterFullSize += size; for (int i = 0; i < m_splitter->count(); ++i) {
auto widget = m_splitter->widget(i);
splitterFullSize += isHorizontal ? widget->width() : widget->height();
}
if (index > -1) { if (index > -1) {
// collapse all but not the one at index // collapse all but the one at index
splitterSizes.fill(0); splitterSizes.fill(0);
splitterSizes.replace(index, splitterFullSize); splitterSizes.replace(index, splitterFullSize);
} else { } else {
// distribute full size // distribute full size among enabled tabs
splitterSizes.fill(splitterFullSize / splitterSizes.count()); int divisor = splitterSizes.count();
for (int i = 0; i < m_splitter->count(); ++i) {
if (!m_tabBar->isTabEnabled(i + fakeTab))
--divisor;
} }
int splitSize = splitterFullSize / divisor;
for (int i = 0; i < m_splitter->count(); ++i)
splitterSizes.replace(i, m_tabBar->isTabEnabled(i + fakeTab) ? splitSize : 0);
}
m_splitter->setSizes(splitterSizes.toList()); m_splitter->setSizes(splitterSizes.toList());
m_splittSizesAreDirty = false;
} }
int SwitchSplitTabWidget::addTab(QWidget *w, const QString &label) int SwitchSplitTabWidget::addTab(QWidget *w, const QString &label)
@@ -178,20 +185,10 @@ void SwitchSplitTabWidget::switchTo(QWidget *widget)
updateSplitterSizes(widgetIndex); updateSplitterSizes(widgetIndex);
m_tabBar->setCurrentIndex(widgetIndex + fakeTab); m_tabBar->setCurrentIndex(widgetIndex + fakeTab);
} }
widget->setFocus(); widget->setFocus();
} }
bool SwitchSplitTabWidget::event(QEvent *event)
{
if (event->type() == QEvent::Show && m_splittSizesAreDirty) {
bool returnValue = QWidget::event(event);
updateSplitterSizes(m_tabBar->currentIndex() - fakeTab);
return returnValue;
}
return QWidget::event(event);
}
void SwitchSplitTabWidget::updateSplitButtons() void SwitchSplitTabWidget::updateSplitButtons()
{ {
const bool isTabBarNecessary = count() > 1; const bool isTabBarNecessary = count() > 1;
@@ -203,14 +200,13 @@ void SwitchSplitTabWidget::selectFakeTab()
m_tabBar->setCurrentIndex(0); m_tabBar->setCurrentIndex(0);
} }
SwitchSplitTabWidget::Mode SwitchSplitTabWidget::mode() SwitchSplitTabWidget::Mode SwitchSplitTabWidget::mode() const
{ {
const bool isTabBarNecessary = count() > 1; const bool isTabBarNecessary = count() > 1;
const int fakeTabPosition = 0; const int fakeTabPosition = 0;
const int hasSelectedTab = m_tabBar->currentIndex() > fakeTabPosition; const int hasSelectedTab = m_tabBar->currentIndex() > fakeTabPosition;
if (isTabBarNecessary && !hasSelectedTab) // Note: When splitting the view by dragging from the side of the view, SplitMode is not detected
return SplitMode; return (isTabBarNecessary && !hasSelectedTab) ? SplitMode : TabMode;
return TabMode;
} }
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -37,10 +37,9 @@ namespace QmlDesigner {
class SwitchSplitTabWidget : public QWidget class SwitchSplitTabWidget : public QWidget
{ {
Q_OBJECT Q_OBJECT
enum Mode {
SplitMode, enum Mode { SplitMode, TabMode };
TabMode
};
public: public:
explicit SwitchSplitTabWidget(QWidget *parent = nullptr); explicit SwitchSplitTabWidget(QWidget *parent = nullptr);
int count() const; int count() const;
@@ -50,19 +49,15 @@ public:
QWidget *takeTabWidget(const int index); QWidget *takeTabWidget(const int index);
void switchTo(QWidget *widget); void switchTo(QWidget *widget);
protected:
bool event(QEvent* event) override;
private: private:
void updateSplitterSizes(int index = -1); void updateSplitterSizes(int index = -1);
void updateSplitButtons(); void updateSplitButtons();
void selectFakeTab(); void selectFakeTab();
Mode mode(); Mode mode() const;
QSplitter *m_splitter = nullptr; QSplitter *m_splitter = nullptr;
QTabBar *m_tabBar = nullptr; QTabBar *m_tabBar = nullptr;
QWidget *m_tabBarBackground = nullptr; QWidget *m_tabBarBackground = nullptr;
const int fakeTab = 1; const int fakeTab = 1;
bool m_splittSizesAreDirty = true;
}; };
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -47,9 +47,10 @@ extend_qtc_executable(qml2puppet
changeselectioncommand.cpp changeselectioncommand.h changeselectioncommand.cpp changeselectioncommand.h
drop3dlibraryitemcommand.cpp drop3dlibraryitemcommand.h drop3dlibraryitemcommand.cpp drop3dlibraryitemcommand.h
update3dviewstatecommand.cpp update3dviewstatecommand.h update3dviewstatecommand.cpp update3dviewstatecommand.h
enable3dviewcommand.cpp enable3dviewcommand.h
view3dclosedcommand.cpp view3dclosedcommand.h view3dclosedcommand.cpp view3dclosedcommand.h
puppettocreatorcommand.cpp puppettocreatorcommand.h puppettocreatorcommand.cpp puppettocreatorcommand.h
inputeventcommand.cpp inputeventcommand.h
view3dactioncommand.cpp view3dactioncommand.h
valueschangedcommand.cpp valueschangedcommand.cpp
) )

View File

@@ -99,12 +99,14 @@ QtcTool {
"commands/drop3dlibraryitemcommand.h", "commands/drop3dlibraryitemcommand.h",
"commands/update3dviewstatecommand.cpp", "commands/update3dviewstatecommand.cpp",
"commands/update3dviewstatecommand.h", "commands/update3dviewstatecommand.h",
"commands/enable3dviewcommand.cpp",
"commands/enable3dviewcommand.h",
"commands/view3dclosedcommand.cpp", "commands/view3dclosedcommand.cpp",
"commands/view3dclosedcommand.h", "commands/view3dclosedcommand.h",
"commands/puppettocreatorcommand.cpp", "commands/puppettocreatorcommand.cpp",
"commands/puppettocreatorcommand.h", "commands/puppettocreatorcommand.h",
"commands/inputeventcommand.cpp",
"commands/inputeventcommand.h",
"commands/view3dactioncommand.cpp",
"commands/view3dactioncommand.h",
"container/addimportcontainer.cpp", "container/addimportcontainer.cpp",
"container/addimportcontainer.h", "container/addimportcontainer.h",
"container/idcontainer.cpp", "container/idcontainer.cpp",