From 880ab11e76478f4702edcd1f27d789c44743b130 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 13 Nov 2019 11:16:55 +0100 Subject: [PATCH] QmlDesigner: Use proxy dialog for 3D edit view To integrate the 3D edit view in the qml2puppet process, we create a dialog in the Qt Creator process. This dialog acts as a proxy that manages the actual window. For this I introduced a new command that allows showing, hiding, resizing and moving of the 3D edit view. The 3D edit view always follows the proxy dialog. During moving and resizing we hide the window to avoid artefacts. At this point in time the proxy widget is a dialog, but it could also be a dockwidget or any other QWidget in the future. Task-number: QDS-1179 Change-Id: I67ccab49eb2de9ba23098a67b2f9577f6c7fd3ac Reviewed-by: Miikka Heikkinen --- .../commands/change3dviewcommand.cpp | 63 +++++++ .../qmlpuppet/commands/change3dviewcommand.h | 57 ++++++ .../qml/qmlpuppet/commands/commands.pri | 2 + .../instances/nodeinstanceclientproxy.cpp | 9 + .../instances/nodeinstanceclientproxy.h | 2 + .../qml/qmlpuppet/interfaces/commondefines.h | 6 +- .../nodeinstanceserverinterface.cpp | 4 + .../interfaces/nodeinstanceserverinterface.h | 2 + .../qml/qmlpuppet/mockfiles/EditView3D.qml | 11 +- .../instances/nodeinstanceserver.cpp | 4 + .../qml2puppet/instances/nodeinstanceserver.h | 1 + .../qt5informationnodeinstanceserver.cpp | 84 +++++++++ .../qt5informationnodeinstanceserver.h | 10 ++ src/plugins/qmldesigner/CMakeLists.txt | 2 + .../formeditor/editview3dproxydialog.cpp | 168 ++++++++++++++++++ .../formeditor/editview3dproxydialog.h | 67 +++++++ .../components/formeditor/formeditor.pri | 2 + .../components/formeditor/formeditorview.cpp | 4 + .../components/formeditor/formeditorview.h | 2 +- .../formeditor/formeditorwidget.cpp | 14 ++ .../components/formeditor/formeditorwidget.h | 6 +- .../designercore/include/nodeinstanceview.h | 7 + .../instances/nodeinstanceserverproxy.cpp | 6 + .../instances/nodeinstanceserverproxy.h | 1 + .../instances/nodeinstanceview.cpp | 32 ++++ src/plugins/qmldesigner/qmldesignerplugin.qbs | 2 + src/tools/qml2puppet/CMakeLists.txt | 1 + src/tools/qml2puppet/qml2puppet.qbs | 2 + 28 files changed, 565 insertions(+), 6 deletions(-) create mode 100644 share/qtcreator/qml/qmlpuppet/commands/change3dviewcommand.cpp create mode 100644 share/qtcreator/qml/qmlpuppet/commands/change3dviewcommand.h create mode 100644 src/plugins/qmldesigner/components/formeditor/editview3dproxydialog.cpp create mode 100644 src/plugins/qmldesigner/components/formeditor/editview3dproxydialog.h diff --git a/share/qtcreator/qml/qmlpuppet/commands/change3dviewcommand.cpp b/share/qtcreator/qml/qmlpuppet/commands/change3dviewcommand.cpp new file mode 100644 index 00000000000..ad4832d86b8 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/commands/change3dviewcommand.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2019 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 "change3dviewcommand.h" + +#include + +namespace QmlDesigner { + +Change3DViewCommand::Change3DViewCommand() = default; + +Change3DViewCommand::Change3DViewCommand(const QVector &informationVector) + : m_informationVector(informationVector) +{ +} + +QVector Change3DViewCommand::informationVector() const +{ + return m_informationVector; +} + +QDataStream &operator<<(QDataStream &out, const Change3DViewCommand &command) +{ + out << command.informationVector(); + + return out; +} + +QDataStream &operator>>(QDataStream &in, Change3DViewCommand &command) +{ + in >> command.m_informationVector; + + return in; +} + +QDebug operator <<(QDebug debug, const Change3DViewCommand &command) +{ + return debug.nospace() << "Change3DViewCommand(auxiliaryChanges: " << command.m_informationVector << ")"; +} + +} // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/commands/change3dviewcommand.h b/share/qtcreator/qml/qmlpuppet/commands/change3dviewcommand.h new file mode 100644 index 00000000000..6b1b062da07 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/commands/change3dviewcommand.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2019 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 +#include + +#include "informationcontainer.h" + +namespace QmlDesigner { + +class Change3DViewCommand +{ + friend QDataStream &operator>>(QDataStream &in, Change3DViewCommand &command); + friend QDebug operator <<(QDebug debug, const Change3DViewCommand &command); + +public: + Change3DViewCommand(); + explicit Change3DViewCommand(const QVector &auxiliaryChangeVector); + + QVector informationVector() const; + +private: + QVector m_informationVector; +}; + +QDataStream &operator<<(QDataStream &out, const Change3DViewCommand &command); +QDataStream &operator>>(QDataStream &in, Change3DViewCommand &command); + +QDebug operator <<(QDebug debug, const Change3DViewCommand &command); + +} // namespace QmlDesigner + +Q_DECLARE_METATYPE(QmlDesigner::Change3DViewCommand) diff --git a/share/qtcreator/qml/qmlpuppet/commands/commands.pri b/share/qtcreator/qml/qmlpuppet/commands/commands.pri index 8bca5ce88a9..ffd1ce6dea5 100644 --- a/share/qtcreator/qml/qmlpuppet/commands/commands.pri +++ b/share/qtcreator/qml/qmlpuppet/commands/commands.pri @@ -28,6 +28,7 @@ HEADERS += $$PWD/removesharedmemorycommand.h HEADERS += $$PWD/puppetalivecommand.h HEADERS += $$PWD/changeselectioncommand.h HEADERS += $$PWD/drop3dlibraryitemcommand.h +HEADERS += $$PWD/change3dviewcommand.h SOURCES += $$PWD/synchronizecommand.cpp SOURCES += $$PWD/debugoutputcommand.cpp @@ -57,3 +58,4 @@ SOURCES += $$PWD/removesharedmemorycommand.cpp SOURCES += $$PWD/puppetalivecommand.cpp SOURCES += $$PWD/changeselectioncommand.cpp SOURCES += $$PWD/drop3dlibraryitemcommand.cpp +SOURCES += $$PWD/change3dviewcommand.cpp diff --git a/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.cpp b/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.cpp index 7d46fcbfc19..93520c2f7de 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.cpp +++ b/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.cpp @@ -41,6 +41,7 @@ #include "instancecontainer.h" #include "createinstancescommand.h" #include "createscenecommand.h" +#include "change3dviewcommand.h" #include "changevaluescommand.h" #include "changebindingscommand.h" #include "changeauxiliarycommand.h" @@ -360,6 +361,11 @@ void NodeInstanceClientProxy::createScene(const CreateSceneCommand &command) nodeInstanceServer()->createScene(command); } +void NodeInstanceClientProxy::change3DView(const Change3DViewCommand &command) +{ + nodeInstanceServer()->change3DView(command); +} + void NodeInstanceClientProxy::clearScene(const ClearSceneCommand &command) { nodeInstanceServer()->clearScene(command); @@ -447,6 +453,7 @@ void NodeInstanceClientProxy::changeSelection(const ChangeSelectionCommand &comm void NodeInstanceClientProxy::dispatchCommand(const QVariant &command) { static const int createInstancesCommandType = QMetaType::type("CreateInstancesCommand"); + static const int change3DViewCommandType = QMetaType::type("Change3DViewCommand"); static const int changeFileUrlCommandType = QMetaType::type("ChangeFileUrlCommand"); static const int createSceneCommandType = QMetaType::type("CreateSceneCommand"); static const int clearSceneCommandType = QMetaType::type("ClearSceneCommand"); @@ -470,6 +477,8 @@ void NodeInstanceClientProxy::dispatchCommand(const QVariant &command) if (commandType == createInstancesCommandType) createInstances(command.value()); + else if (commandType == change3DViewCommandType) + change3DView(command.value()); else if (commandType == changeFileUrlCommandType) changeFileUrl(command.value()); else if (commandType == createSceneCommandType) diff --git a/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.h b/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.h index 2b41bf83cba..e9044b63efd 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.h +++ b/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.h @@ -45,6 +45,7 @@ class CreateSceneCommand; class CreateInstancesCommand; class ClearSceneCommand; class ReparentInstancesCommand; +class Change3DViewCommand; class ChangeFileUrlCommand; class ChangeValuesCommand; class ChangeAuxiliaryCommand; @@ -95,6 +96,7 @@ protected: void changeFileUrl(const ChangeFileUrlCommand &command); void createScene(const CreateSceneCommand &command); void clearScene(const ClearSceneCommand &command); + void change3DView(const Change3DViewCommand &command); void removeInstances(const RemoveInstancesCommand &command); void removeProperties(const RemovePropertiesCommand &command); void changePropertyBindings(const ChangeBindingsCommand &command); diff --git a/share/qtcreator/qml/qmlpuppet/interfaces/commondefines.h b/share/qtcreator/qml/qmlpuppet/interfaces/commondefines.h index 51010c9a536..eb1bd41051b 100644 --- a/share/qtcreator/qml/qmlpuppet/interfaces/commondefines.h +++ b/share/qtcreator/qml/qmlpuppet/interfaces/commondefines.h @@ -52,7 +52,11 @@ enum InformationName HasBindingForProperty, ContentTransform, ContentItemTransform, - ContentItemBoundingRect + ContentItemBoundingRect, + MoveView, + ShowView, + ResizeView, + HideView }; } diff --git a/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.cpp b/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.cpp index e58ef1011e3..83c8c67ef72 100644 --- a/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.cpp +++ b/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.cpp @@ -32,6 +32,7 @@ #include "instancecontainer.h" #include "createinstancescommand.h" #include "createscenecommand.h" +#include "change3dviewcommand.h" #include "changevaluescommand.h" #include "changebindingscommand.h" #include "changeauxiliarycommand.h" @@ -90,6 +91,9 @@ void NodeInstanceServerInterface::registerCommands() qRegisterMetaType("CreateSceneCommand"); qRegisterMetaTypeStreamOperators("CreateSceneCommand"); + qRegisterMetaType("Change3DViewCommand"); + qRegisterMetaTypeStreamOperators("Change3DViewCommand"); + qRegisterMetaType("ChangeBindingsCommand"); qRegisterMetaTypeStreamOperators("ChangeBindingsCommand"); diff --git a/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.h b/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.h index b452c802be4..3dc651ef2f3 100644 --- a/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.h +++ b/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.h @@ -33,6 +33,7 @@ class PropertyAbstractContainer; class PropertyBindingContainer; class PropertyValueContainer; +class Change3DViewCommand; class ChangeFileUrlCommand; class ChangeValuesCommand; class ChangeBindingsCommand; @@ -66,6 +67,7 @@ public: virtual void changeFileUrl(const ChangeFileUrlCommand &command) = 0; virtual void createScene(const CreateSceneCommand &command) = 0; virtual void clearScene(const ClearSceneCommand &command) = 0; + virtual void change3DView(const Change3DViewCommand &command) = 0; virtual void removeInstances(const RemoveInstancesCommand &command) = 0; virtual void removeProperties(const RemovePropertiesCommand &command) = 0; virtual void changePropertyBindings(const ChangeBindingsCommand &command) = 0; diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml index 2200048fa5f..e97aeec19a7 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml @@ -24,7 +24,7 @@ ****************************************************************************/ import QtQuick 2.12 -import QtQuick.Window 2.0 +import QtQuick.Window 2.12 import QtQuick3D 1.0 import QtQuick.Controls 2.0 import QtGraphicalEffects 1.0 @@ -33,9 +33,14 @@ Window { id: viewWindow width: 1024 height: 768 - visible: true + visible: false title: "3D" - flags: Qt.WindowStaysOnTopHint | Qt.Window | Qt.WindowTitleHint | Qt.WindowCloseButtonHint + flags: Qt.Widget | Qt.SplashScreen + + onActiveChanged: { + if (viewWindow.active) + cameraControl.forceActiveFocus() + } property alias scene: editView.importScene property alias showEditLight: btnEditViewLight.toggled diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp index e2e6564c893..d19c0faea46 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp @@ -332,6 +332,10 @@ void NodeInstanceServer::clearScene(const ClearSceneCommand &/*command*/) m_fileUrl.clear(); } +void NodeInstanceServer::change3DView(const Change3DViewCommand &/*command*/) +{ +} + void NodeInstanceServer::changeSelection(const ChangeSelectionCommand & /*command*/) { } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.h index 9eab649af71..c369882b419 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.h @@ -101,6 +101,7 @@ public: void changeIds(const ChangeIdsCommand &command) override; void createScene(const CreateSceneCommand &command) override; void clearScene(const ClearSceneCommand &command) override; + void change3DView(const Change3DViewCommand &command) override; void removeInstances(const RemoveInstancesCommand &command) override; void removeProperties(const RemovePropertiesCommand &command) override; void reparentInstances(const ReparentInstancesCommand &command) override; diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp index 95360eaa4fc..54012f7e4a5 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp @@ -40,6 +40,7 @@ #include "changefileurlcommand.h" #include "clearscenecommand.h" #include "reparentinstancescommand.h" +#include "change3dviewcommand.h" #include "changevaluescommand.h" #include "changebindingscommand.h" #include "changeidscommand.h" @@ -129,6 +130,8 @@ QObject *Qt5InformationNodeInstanceServer::createEditView3D(QQmlEngine *engine) this, SLOT(handleObjectPropertyCommit(QVariant, QVariant))); QObject::connect(window, SIGNAL(changeObjectProperty(QVariant, QVariant)), this, SLOT(handleObjectPropertyChange(QVariant, QVariant))); + QObject::connect(window, SIGNAL(activeChanged()), + this, SLOT(handleActiveChanged())); QObject::connect(&m_propertyChangeTimer, &QTimer::timeout, this, &Qt5InformationNodeInstanceServer::handleObjectPropertyChangeTimeout); @@ -219,6 +222,65 @@ void Qt5InformationNodeInstanceServer::modifyVariantValue( } } +void Qt5InformationNodeInstanceServer::showEditView(const QPoint &pos, const QSize &size) +{ + m_blockViewActivate = false; + auto window = qobject_cast(m_editView3D); + if (window) { + activateEditView(); + window->setPosition(pos); + window->resize(size); + } +} + +void Qt5InformationNodeInstanceServer::hideEditView() +{ + m_blockViewActivate = true; + auto window = qobject_cast(m_editView3D); + if (window) + window->hide(); +} + +void Qt5InformationNodeInstanceServer::activateEditView() +{ + auto window = qobject_cast(m_editView3D); + if (window) { + Qt::WindowFlags flags = window->flags(); + +#ifdef Q_OS_MACOS + window->setFlags(Qt::Popup); + window->show(); + window->setFlags(flags); +#else + window->raise(); + window->setFlags(flags | Qt::WindowStaysOnTopHint); + window->show(); + + window->requestActivate(); + window->raise(); + window->setFlags(flags); +#endif + } +} + +void Qt5InformationNodeInstanceServer::moveEditView(const QPoint &pos) +{ + auto window = qobject_cast(m_editView3D); + if (window) { + activateEditView(); + window->setPosition(pos); + } +} + +void Qt5InformationNodeInstanceServer::resizeEditView(const QSize &size) +{ + auto window = qobject_cast(m_editView3D); + if (window) { + activateEditView(); + window->resize(size); + } +} + void Qt5InformationNodeInstanceServer::handleObjectPropertyCommit(const QVariant &object, const QVariant &propName) { @@ -253,6 +315,14 @@ void Qt5InformationNodeInstanceServer::updateViewPortRect() viewPortProperty.write(viewPortrect); } +void Qt5InformationNodeInstanceServer::handleActiveChanged() +{ + if (m_blockViewActivate) + return; + + activateEditView(); +} + Qt5InformationNodeInstanceServer::Qt5InformationNodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient) : Qt5NodeInstanceServer(nodeInstanceClient) { @@ -641,4 +711,18 @@ void Qt5InformationNodeInstanceServer::changePropertyValues(const ChangeValuesCo startRenderTimer(); } +void Qt5InformationNodeInstanceServer::change3DView(const Change3DViewCommand &command) +{ + for (const InformationContainer &container : command.informationVector()) { + if (container.name() == InformationName::ShowView) + showEditView(container.information().toPoint(), container.secondInformation().toSize()); + else if (container.name() == InformationName::HideView) + hideEditView(); + else if (container.name() == InformationName::MoveView) + moveEditView(container.information().toPoint()); + else if (container.name() == InformationName::ResizeView) + resizeEditView(container.secondInformation().toSize()); + } +} + } // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h index 0597947024d..439e4da0c74 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h @@ -42,6 +42,7 @@ public: void reparentInstances(const ReparentInstancesCommand &command) override; void clearScene(const ClearSceneCommand &command) override; + void change3DView(const Change3DViewCommand &command) override; void createScene(const CreateSceneCommand &command) override; void completeComponent(const CompleteComponentCommand &command) override; void token(const TokenCommand &command) override; @@ -54,6 +55,7 @@ private slots: void handleObjectPropertyCommit(const QVariant &object, const QVariant &propName); void handleObjectPropertyChange(const QVariant &object, const QVariant &propName); void updateViewPortRect(); + void handleActiveChanged(); protected: void collectItemChangesAndSendChangeCommands() override; @@ -80,6 +82,12 @@ private: const PropertyName &propertyName, ValuesModifiedCommand::TransactionOption option); + void showEditView(const QPoint &pos, const QSize &size); + void hideEditView(); + void activateEditView(); + void moveEditView(const QPoint &pos); + void resizeEditView(const QSize &size); + QObject *m_editView3D = nullptr; QSet m_parentChangedSet; QList m_completedComponentList; @@ -88,6 +96,8 @@ private: QVariant m_changedNode; PropertyName m_changedProperty; ServerNodeInstance m_viewPortInstance; + + bool m_blockViewActivate = false; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index 5689455b63b..4967f757e78 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -140,6 +140,7 @@ extend_qtc_plugin(QmlDesigner valueschangedcommand.cpp valueschangedcommand.h changeselectioncommand.cpp changeselectioncommand.h drop3dlibraryitemcommand.cpp drop3dlibraryitemcommand.h + change3dviewcommand.cpp change3dviewcommand.h ) extend_qtc_plugin(QmlDesigner @@ -234,6 +235,7 @@ extend_qtc_plugin(QmlDesigner snappinglinecreator.cpp snappinglinecreator.h toolbox.cpp toolbox.h option3daction.cpp option3daction.h + editview3dproxydialog.cpp editview3dproxydialog.h ) extend_qtc_plugin(QmlDesigner diff --git a/src/plugins/qmldesigner/components/formeditor/editview3dproxydialog.cpp b/src/plugins/qmldesigner/components/formeditor/editview3dproxydialog.cpp new file mode 100644 index 00000000000..505eeacd1ff --- /dev/null +++ b/src/plugins/qmldesigner/components/formeditor/editview3dproxydialog.cpp @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2019 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 "editview3dproxydialog.h" +#include "formeditorview.h" + +#include + +#include + +#include + +#include +#include +#include +#include + +namespace QmlDesigner { + +const int borderOffset = 8; + +static int titleBarHeight() { + return QApplication::style()->pixelMetric(QStyle::PM_TitleBarHeight); +} + +EditView3DProxyDialog::EditView3DProxyDialog(FormEditorView *view) : + QDialog(Core::ICore::dialogParent()) + ,m_formEditorView(view) +{ + setFocusPolicy(Qt::ClickFocus); + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + + if (Utils::HostOsInfo::isMacHost()) { + setWindowFlag(Qt::Tool); + setAttribute(Qt::WA_MacAlwaysShowToolWindow); + } + + resize(1024, 768); +} + +void EditView3DProxyDialog::invalidate() +{ + if (nodeInstanceView() && isVisible()) + nodeInstanceView()->show3DView(adjustedRect()); +} + +void EditView3DProxyDialog::moveEvent(QMoveEvent *event) +{ + if (nodeInstanceView()) + nodeInstanceView()->move3DView(pos() + QPoint(borderOffset, titleBarHeight() + 2 * borderOffset)); + + QDialog::moveEvent(event); +} + +void EditView3DProxyDialog::closeEvent(QCloseEvent *event) +{ + if (m_formEditorView) { + m_formEditorView->toggle3DViewEnabled(false); + m_formEditorView->setupOption3DAction(); + } + + nodeInstanceView()->hide3DView(); + + QDialog::closeEvent(event); +} + +void EditView3DProxyDialog::hideEvent(QHideEvent *event) +{ + if (m_formEditorView) { + m_formEditorView->toggle3DViewEnabled(false); + m_formEditorView->setupOption3DAction(); + } + + nodeInstanceView()->hide3DView(); + + QDialog::hideEvent(event); +} + +void EditView3DProxyDialog::focusOutEvent(QFocusEvent *event) +{ + if (isVisible()) + showView(); + + QDialog::focusOutEvent(event); +} + +void EditView3DProxyDialog::focusInEvent(QFocusEvent *event) +{ + showView(); + + QDialog::focusInEvent(event); +} + +void EditView3DProxyDialog::resizeEvent(QResizeEvent *event) +{ + if (nodeInstanceView()) + nodeInstanceView()->show3DView(adjustedRect()); + + QDialog::resizeEvent(event); +} + +bool EditView3DProxyDialog::event(QEvent *event) +{ + if (event->type() == QEvent::WindowActivate) { + showView(); + } else if (event->type() == QEvent::NonClientAreaMouseButtonPress) { + auto mouseMoveEvent = static_cast(event); + if (mouseMoveEvent->buttons() & Qt::LeftButton) + hideView(); + } else if (event->type() == QEvent::NonClientAreaMouseButtonRelease) { + auto mouseMoveEvent = static_cast(event); + if (mouseMoveEvent->buttons() & Qt::LeftButton) + showView(); + } + + return QDialog::event(event); +} + +QRect EditView3DProxyDialog::adjustedRect() const +{ + return QRect(pos(), size()).adjusted(borderOffset, + titleBarHeight() + 2 * borderOffset, + -borderOffset, titleBarHeight()); +} + +NodeInstanceView *EditView3DProxyDialog::nodeInstanceView() const +{ + if (m_formEditorView) + return m_formEditorView->nodeInstanceView(); + + return nullptr; +} + +void EditView3DProxyDialog::showView() +{ + if (nodeInstanceView()) + nodeInstanceView()->show3DView(adjustedRect()); +} + +void EditView3DProxyDialog::hideView() +{ + if (nodeInstanceView()) + nodeInstanceView()->hide3DView(); +} + +} //QmlDesigner diff --git a/src/plugins/qmldesigner/components/formeditor/editview3dproxydialog.h b/src/plugins/qmldesigner/components/formeditor/editview3dproxydialog.h new file mode 100644 index 00000000000..717deca7f9e --- /dev/null +++ b/src/plugins/qmldesigner/components/formeditor/editview3dproxydialog.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2019 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 "abstractcustomtool.h" + +#include +#include + +namespace QmlDesigner { + +class FormEditorView; +class NodeInstanceView; + +class EditView3DProxyDialog : public QDialog +{ + Q_OBJECT + +public: + explicit EditView3DProxyDialog(FormEditorView *view); + + void invalidate(); + +protected: + void moveEvent(QMoveEvent *event) override; + void closeEvent(QCloseEvent *event) override; + void hideEvent(QHideEvent *event) override; + void focusOutEvent(QFocusEvent *event) override; + void focusInEvent(QFocusEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + bool event(QEvent *event) override; + +private: + QRect adjustedRect() const; + NodeInstanceView *nodeInstanceView() const; + void showView(); + void hideView(); + + QPointer m_formEditorView; + +}; + +} //QmlDesigner + diff --git a/src/plugins/qmldesigner/components/formeditor/formeditor.pri b/src/plugins/qmldesigner/components/formeditor/formeditor.pri index 5bff19e664c..15de28f5041 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditor.pri +++ b/src/plugins/qmldesigner/components/formeditor/formeditor.pri @@ -1,5 +1,6 @@ VPATH += $$PWD SOURCES += formeditoritem.cpp \ + editview3dproxydialog.cpp \ formeditorview.cpp \ formeditorscene.cpp \ formeditorwidget.cpp \ @@ -40,6 +41,7 @@ SOURCES += formeditoritem.cpp \ option3daction.cpp HEADERS += formeditorscene.h \ + editview3dproxydialog.h \ formeditorwidget.h \ formeditoritem.h \ formeditorview.h \ diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp index 10fcbdc1b75..eb7fbba4a32 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp @@ -474,6 +474,8 @@ void FormEditorView::instancesCompleted(const QVector &completedNodeL itemNodeList.append(item); } } + if (node.isRootNode()) + formEditorWidget()->invalidate3DEditor(); } currentTool()->instancesCompleted(itemNodeList); } @@ -594,6 +596,8 @@ void FormEditorView::toggle3DViewEnabled(bool enabled) rootModelNode().removeAuxiliaryData("3d-view"); else rootModelNode().setAuxiliaryData("3d-view", false); + + formEditorWidget()->set3dEditorVisibility(enabled); } QmlItemNode findRecursiveQmlItemNode(const QmlObjectNode &firstQmlObjectNode) diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.h b/src/plugins/qmldesigner/components/formeditor/formeditorview.h index c607aa0b69e..2319da48828 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorview.h +++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.h @@ -119,6 +119,7 @@ public: void exportAsImage(); void toggle3DViewEnabled(bool enabled); + void setupOption3DAction(); protected: void reset(); @@ -131,7 +132,6 @@ private: //functions void hideNodeFromScene(const QmlItemNode &qmlItemNode); void createFormEditorWidget(); void temporaryBlockView(); - void setupOption3DAction(); private: //variables QPointer m_formEditorWidget; diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp index 045fe964398..fdad23a8802 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp @@ -24,6 +24,7 @@ ****************************************************************************/ #include "designeractionmanager.h" +#include "editview3dproxydialog.h" #include "formeditorwidget.h" #include "formeditorscene.h" #include "qmldesignerplugin.h" @@ -173,6 +174,8 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view) : fillLayout->addWidget(m_graphicsView.data()); m_graphicsView.data()->setStyleSheet(Theme::replaceCssColors(QString::fromUtf8(Utils::FileReader::fetchQrc(QLatin1String(":/qmldesigner/scrollbar.css"))))); + + m_editView3DProxyDialog = new EditView3DProxyDialog(view); } void FormEditorWidget::changeTransformTool(bool checked) @@ -394,6 +397,17 @@ FormEditorGraphicsView *FormEditorWidget::graphicsView() const return m_graphicsView; } +void FormEditorWidget::set3dEditorVisibility(bool b) +{ + m_editView3DProxyDialog->setVisible(b); +} + +void FormEditorWidget::invalidate3DEditor() +{ + if (m_editView3DProxyDialog) + m_editView3DProxyDialog->invalidate(); +} + DocumentWarningWidget *FormEditorWidget::errorWidget() { if (m_documentErrorWidget.isNull()) { diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.h b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.h index ef0ae3615e4..d1c55885288 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.h +++ b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.h @@ -37,6 +37,7 @@ QT_END_NAMESPACE namespace QmlDesigner { +class EditView3DProxyDialog; class ZoomAction; class LineEditAction; class BackgroundAction; @@ -47,7 +48,6 @@ class FormEditorGraphicsView; class ToolBox; class QmlItemNode; - class FormEditorWidget : public QWidget { Q_OBJECT @@ -87,6 +87,9 @@ public: FormEditorGraphicsView *graphicsView() const; + void set3dEditorVisibility(bool b); + void invalidate3DEditor(); + protected: void wheelEvent(QWheelEvent *event) override; QActionGroup *toolActionGroup() const; @@ -117,6 +120,7 @@ private: QPointer m_option3DAction; QPointer m_resetAction; QPointer m_documentErrorWidget; + QPointer m_editView3DProxyDialog; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h index 61ee71e3002..a6de5fd6c66 100644 --- a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h +++ b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h @@ -59,6 +59,7 @@ class CreateSceneCommand; class CreateInstancesCommand; class ClearSceneCommand; class ReparentInstancesCommand; +class Change3DViewCommand; class ChangeFileUrlCommand; class ChangeValuesCommand; class ChangeBindingsCommand; @@ -142,10 +143,15 @@ public: void selectedNodesChanged(const QList &selectedNodeList, const QList &lastSelectedNodeList) override; + void show3DView(const QRect &rect); + void move3DView(const QPoint &position); + void hide3DView(); + protected: void timerEvent(QTimerEvent *event) override; private: // functions + enum ViewAction { Show, Move, Hide }; void activateState(const NodeInstance &instance); void activateBaseState(); @@ -170,6 +176,7 @@ private: // functions CreateSceneCommand createCreateSceneCommand(); + Change3DViewCommand createChange3DViewCommand(ViewAction action, const QPoint &pos = {}, const QSize &size = {}) const; ClearSceneCommand createClearSceneCommand() const; CreateInstancesCommand createCreateInstancesCommand(const QList &instanceList) const; CompleteComponentCommand createComponentCompleteCommand(const QList &instanceList) const; diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp index 408dd2a7e46..39de64f9ae7 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -651,6 +652,11 @@ void NodeInstanceServerProxy::clearScene(const ClearSceneCommand &command) writeCommand(QVariant::fromValue(command)); } +void NodeInstanceServerProxy::change3DView(const Change3DViewCommand &command) +{ + writeCommand(QVariant::fromValue(command)); +} + void NodeInstanceServerProxy::removeInstances(const RemoveInstancesCommand &command) { writeCommand(QVariant::fromValue(command)); diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.h b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.h index a6a7f6ce99b..62c361dbd1a 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.h +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.h @@ -69,6 +69,7 @@ public: void createInstances(const CreateInstancesCommand &command) override; void changeFileUrl(const ChangeFileUrlCommand &command) override; void createScene(const CreateSceneCommand &command) override; + void change3DView(const Change3DViewCommand &command) override; void clearScene(const ClearSceneCommand &command) override; void removeInstances(const RemoveInstancesCommand &command) override; void changeSelection(const ChangeSelectionCommand &command) override; diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp index a65d52d8887..9aa8d2f41ca 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp @@ -48,6 +48,7 @@ #include "clearscenecommand.h" #include "changefileurlcommand.h" #include "reparentinstancescommand.h" +#include "change3dviewcommand.h" #include "changevaluescommand.h" #include "changeauxiliarycommand.h" #include "changebindingscommand.h" @@ -978,6 +979,20 @@ ClearSceneCommand NodeInstanceView::createClearSceneCommand() const return {}; } +Change3DViewCommand NodeInstanceView::createChange3DViewCommand(ViewAction action, const QPoint &pos, const QSize &size) const +{ + InformationName informationName = InformationName::ShowView; + + if (action == ViewAction::Move) + informationName = InformationName::MoveView; + else if (action == ViewAction::Hide) + informationName = InformationName::HideView; + + const qint32 instanceId = 0; + + return Change3DViewCommand({ InformationContainer(instanceId, informationName, pos, size) }); +} + CompleteComponentCommand NodeInstanceView::createComponentCompleteCommand(const QList &instanceList) const { QVector containerList; @@ -1458,6 +1473,23 @@ void NodeInstanceView::selectedNodesChanged(const QList &selectedNode nodeInstanceServer()->changeSelection(createChangeSelectionCommand(selectedNodeList)); } +void NodeInstanceView::move3DView(const QPoint &position) +{ + nodeInstanceServer()->change3DView(createChange3DViewCommand(ViewAction::Move, position)); +} + +void NodeInstanceView::hide3DView() +{ + nodeInstanceServer()->change3DView(createChange3DViewCommand(ViewAction::Hide)); +} + +void NodeInstanceView::show3DView(const QRect &rect) +{ + nodeInstanceServer()->change3DView(createChange3DViewCommand(ViewAction::Show, + rect.topLeft(), + rect.size())); +} + void NodeInstanceView::timerEvent(QTimerEvent *event) { if (m_restartProcessTimerId == event->timerId()) diff --git a/src/plugins/qmldesigner/qmldesignerplugin.qbs b/src/plugins/qmldesigner/qmldesignerplugin.qbs index 736d4ed52c2..ec861438b08 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.qbs +++ b/src/plugins/qmldesigner/qmldesignerplugin.qbs @@ -171,6 +171,8 @@ Project { "commands/changeselectioncommand.h", "commands/drop3dlibraryitemcommand.cpp", "commands/drop3dlibraryitemcommand.h", + "commands/change3dviewcommand.cpp", + "commands/change3dviewcommand.h", "container/addimportcontainer.cpp", "container/addimportcontainer.h", "container/idcontainer.cpp", diff --git a/src/tools/qml2puppet/CMakeLists.txt b/src/tools/qml2puppet/CMakeLists.txt index 1859bebe98f..ea449b4010a 100644 --- a/src/tools/qml2puppet/CMakeLists.txt +++ b/src/tools/qml2puppet/CMakeLists.txt @@ -46,6 +46,7 @@ extend_qtc_executable(qml2puppet tokencommand.cpp tokencommand.h changeselectioncommand.cpp changeselectioncommand.h drop3dlibraryitemcommand.cpp drop3dlibraryitemcommand.h + change3dviewcommand.cpp change3dviewcommand.h valueschangedcommand.cpp ) diff --git a/src/tools/qml2puppet/qml2puppet.qbs b/src/tools/qml2puppet/qml2puppet.qbs index fe42083d6e2..40719787498 100644 --- a/src/tools/qml2puppet/qml2puppet.qbs +++ b/src/tools/qml2puppet/qml2puppet.qbs @@ -97,6 +97,8 @@ QtcTool { "commands/changeselectioncommand.h", "commands/drop3dlibraryitemcommand.cpp", "commands/drop3dlibraryitemcommand.h", + "commands/change3dviewcommand.cpp", + "commands/change3dviewcommand.h", "container/addimportcontainer.cpp", "container/addimportcontainer.h", "container/idcontainer.cpp",