forked from qt-creator/qt-creator
QmlDesigner: Add 3D edit camera speed configuration dialog
Edit camera speed configuration consists of a slider and a multiplier, which combine into the total camera speed. Speed and multiplier are stored per scene. Fixes: QDS-12187 Change-Id: I587c04cf80d1ca95b5a38c406158e46cdb91d06f Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
// Copyright (C) 2024 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import HelperWidgets as HelperWidgets
|
||||
import StudioControls as StudioControls
|
||||
import StudioTheme as StudioTheme
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
property int toolTipDelay: 1000
|
||||
|
||||
width: 260
|
||||
height: 150
|
||||
color: StudioTheme.Values.themePanelBackground
|
||||
border.color: StudioTheme.Values.themeControlOutline
|
||||
border.width: StudioTheme.Values.border
|
||||
|
||||
function handleSpeedChanged() {
|
||||
speedSlider.value = Math.round(speed)
|
||||
}
|
||||
|
||||
function handleMultiplierChanged() {
|
||||
multiplierSpin.value = multiplier
|
||||
}
|
||||
|
||||
// Connect context object signals to our handler functions
|
||||
// Controls lose the initial binding if the value changes so we need these handlers
|
||||
Component.onCompleted: {
|
||||
onSpeedChanged.connect(handleSpeedChanged);
|
||||
onMultiplierChanged.connect(handleMultiplierChanged);
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
spacing: 0
|
||||
|
||||
RowLayout {
|
||||
height: 32
|
||||
Layout.topMargin: 8
|
||||
Layout.rightMargin: 8
|
||||
Layout.leftMargin: 8
|
||||
Layout.fillWidth: true
|
||||
spacing: 16
|
||||
|
||||
Rectangle {
|
||||
width: 40
|
||||
height: 40
|
||||
radius: 5
|
||||
Layout.fillHeight: false
|
||||
color: StudioTheme.Values.themePanelBackground
|
||||
border.color: StudioTheme.Values.themeControlOutline
|
||||
border.width: StudioTheme.Values.border
|
||||
|
||||
HelperWidgets.IconIndicator {
|
||||
anchors.fill: parent
|
||||
icon: StudioTheme.Constants.snapping_conf_medium // TODO update icon
|
||||
pixelSize: StudioTheme.Values.myIconFontSize * 1.4
|
||||
iconColor: StudioTheme.Values.themeLinkIndicatorColorHover
|
||||
enabled: false
|
||||
states: [] // Disable normal state based coloring
|
||||
}
|
||||
}
|
||||
Text {
|
||||
text: qsTr("Camera Speed Configuration")
|
||||
font.pixelSize: 12
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
Layout.fillWidth: true
|
||||
font.bold: true
|
||||
color: StudioTheme.Values.themeTextColor
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.margins: 10
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 5
|
||||
|
||||
StudioControls.Slider {
|
||||
id: speedSlider
|
||||
Layout.fillWidth: true
|
||||
labels: false
|
||||
actionIndicatorVisible: false
|
||||
handleLabelVisible: false
|
||||
from: 1
|
||||
to: 100
|
||||
value: Math.round(speed)
|
||||
onMoved: speed = Math.round(value)
|
||||
|
||||
hoverEnabled: true
|
||||
ToolTip.visible: hovered
|
||||
ToolTip.text: qsTr("The speed camera moves when controlled by keyboard.")
|
||||
ToolTip.delay: root.toolTipDelay
|
||||
}
|
||||
|
||||
Text {
|
||||
Layout.preferredWidth: 80
|
||||
text: {
|
||||
const decimals = -Math.floor(Math.log10(multiplier))
|
||||
return totalSpeed.toLocaleString(Qt.locale(), 'f', decimals > 0 ? decimals : 0)
|
||||
}
|
||||
|
||||
font.pixelSize: 12
|
||||
font.bold: true
|
||||
horizontalAlignment: Qt.AlignRight
|
||||
color: StudioTheme.Values.themeTextColor
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 5
|
||||
|
||||
Text {
|
||||
text: qsTr("Multiplier")
|
||||
font.pixelSize: 12
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
Layout.fillWidth: true
|
||||
font.bold: true
|
||||
color: StudioTheme.Values.themeTextColor
|
||||
}
|
||||
|
||||
HelperWidgets.DoubleSpinBox {
|
||||
id: multiplierSpin
|
||||
Layout.fillWidth: true
|
||||
minimumValue: 0.01
|
||||
maximumValue: 100000
|
||||
value: multiplier
|
||||
stepSize: 0.01
|
||||
decimals: 2
|
||||
|
||||
ToolTip.visible: hover
|
||||
ToolTip.text: qsTr("The value multiplier for the speed slider.")
|
||||
ToolTip.delay: root.toolTipDelay
|
||||
|
||||
onValueChanged: multiplier = value
|
||||
}
|
||||
|
||||
HelperWidgets.Button {
|
||||
text: qsTr("Reset")
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
Layout.preferredWidth: 70
|
||||
Layout.preferredHeight: multiplierSpin.height
|
||||
onClicked: resetDefaults()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -652,6 +652,7 @@ extend_qtc_plugin(QmlDesigner
|
||||
backgroundcolorselection.cpp backgroundcolorselection.h
|
||||
bakelights.cpp bakelights.h
|
||||
snapconfiguration.cpp snapconfiguration.h
|
||||
cameraspeedconfiguration.cpp cameraspeedconfiguration.h
|
||||
bakelightsdatamodel.cpp bakelightsdatamodel.h
|
||||
bakelightsconnectionmanager.cpp bakelightsconnectionmanager.h
|
||||
edit3d.qrc
|
||||
|
@@ -121,5 +121,37 @@ ModelNode getTextureDefaultInstance(const QString &source, AbstractView *view)
|
||||
return {};
|
||||
}
|
||||
|
||||
ModelNode activeView3dNode(AbstractView *view)
|
||||
{
|
||||
if (!view || !view->model())
|
||||
return {};
|
||||
|
||||
ModelNode activeView3D;
|
||||
ModelNode activeScene = Utils3D::active3DSceneNode(view);
|
||||
|
||||
if (activeScene.isValid()) {
|
||||
if (activeScene.metaInfo().isQtQuick3DView3D()) {
|
||||
activeView3D = activeScene;
|
||||
} else {
|
||||
ModelNode sceneParent = activeScene.parentProperty().parentModelNode();
|
||||
if (sceneParent.metaInfo().isQtQuick3DView3D())
|
||||
activeView3D = sceneParent;
|
||||
}
|
||||
return activeView3D;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
QString activeView3dId(AbstractView *view)
|
||||
{
|
||||
ModelNode activeView3D = activeView3dNode(view);
|
||||
|
||||
if (activeView3D.isValid())
|
||||
return activeView3D.id();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace Utils3D
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -21,5 +21,8 @@ void ensureMaterialLibraryNode(AbstractView *view);
|
||||
bool isPartOfMaterialLibrary(const ModelNode &node);
|
||||
ModelNode getTextureDefaultInstance(const QString &source, AbstractView *view);
|
||||
|
||||
ModelNode activeView3dNode(AbstractView *view);
|
||||
QString activeView3dId(AbstractView *view);
|
||||
|
||||
} // namespace Utils3D
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -62,7 +62,7 @@ BakeLights::BakeLights(AbstractView *view)
|
||||
: QObject(view)
|
||||
, m_view(view)
|
||||
{
|
||||
m_view3dId = resolveView3dId(view);
|
||||
m_view3dId = Utils3D::activeView3dId(view);
|
||||
|
||||
if (m_view3dId.isEmpty()) {
|
||||
// It should never get here, baking controls should be disabled in this case
|
||||
@@ -79,38 +79,6 @@ BakeLights::~BakeLights()
|
||||
cleanup();
|
||||
}
|
||||
|
||||
ModelNode BakeLights::resolveView3dNode(AbstractView *view)
|
||||
{
|
||||
if (!view || !view->model())
|
||||
return {};
|
||||
|
||||
ModelNode activeView3D;
|
||||
ModelNode activeScene = Utils3D::active3DSceneNode(view);
|
||||
|
||||
if (activeScene.isValid()) {
|
||||
if (activeScene.metaInfo().isQtQuick3DView3D()) {
|
||||
activeView3D = activeScene;
|
||||
} else {
|
||||
ModelNode sceneParent = activeScene.parentProperty().parentModelNode();
|
||||
if (sceneParent.metaInfo().isQtQuick3DView3D())
|
||||
activeView3D = sceneParent;
|
||||
}
|
||||
return activeView3D;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
QString BakeLights::resolveView3dId(AbstractView *view)
|
||||
{
|
||||
ModelNode activeView3D = resolveView3dNode(view);
|
||||
|
||||
if (activeView3D.isValid())
|
||||
return activeView3D.id();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void BakeLights::raiseDialog()
|
||||
{
|
||||
if (m_progressDialog)
|
||||
|
@@ -41,9 +41,6 @@ public:
|
||||
bool manualMode() const;
|
||||
void setManualMode(bool enabled);
|
||||
|
||||
static ModelNode resolveView3dNode(AbstractView *view);
|
||||
static QString resolveView3dId(AbstractView *view);
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
void progress(const QString &msg);
|
||||
|
@@ -15,6 +15,8 @@
|
||||
#include "qmlobjectnode.h"
|
||||
#include "variantproperty.h"
|
||||
|
||||
#include <utils3d.h>
|
||||
|
||||
#include <utils/expected.h>
|
||||
#include <utils/filepath.h>
|
||||
#include <utils/qtcassert.h>
|
||||
@@ -140,7 +142,7 @@ bool BakeLightsDataModel::reset()
|
||||
beginResetModel();
|
||||
m_dataList.clear();
|
||||
|
||||
m_view3dNode = BakeLights::resolveView3dNode(m_view);
|
||||
m_view3dNode = Utils3D::activeView3dNode(m_view);
|
||||
|
||||
// Find all models and lights in active View3D
|
||||
QList<ModelNode> nodes = m_view3dNode.allSubModelNodes();
|
||||
|
@@ -0,0 +1,192 @@
|
||||
// Copyright (C) 2024 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "cameraspeedconfiguration.h"
|
||||
|
||||
#include "designersettings.h"
|
||||
#include "edit3dview.h"
|
||||
#include "edit3dviewconfig.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <utils/environment.h>
|
||||
|
||||
#include <QCursor>
|
||||
#include <QGuiApplication>
|
||||
#include <QQmlContext>
|
||||
#include <QQmlEngine>
|
||||
#include <QQuickView>
|
||||
#include <QTimer>
|
||||
#include <QVariant>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
static QString propertyEditorResourcesPath()
|
||||
{
|
||||
#ifdef SHARE_QML_PATH
|
||||
if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
|
||||
return QLatin1String(SHARE_QML_PATH) + "/propertyEditorQmlSources";
|
||||
#endif
|
||||
return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString();
|
||||
}
|
||||
|
||||
static QString qmlSourcesPath()
|
||||
{
|
||||
#ifdef SHARE_QML_PATH
|
||||
if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
|
||||
return QLatin1String(SHARE_QML_PATH) + "/edit3dQmlSource";
|
||||
#endif
|
||||
return Core::ICore::resourcePath("qmldesigner/edit3dQmlSource").toString();
|
||||
}
|
||||
|
||||
CameraSpeedConfiguration::CameraSpeedConfiguration(Edit3DView *view)
|
||||
: QObject(view)
|
||||
, m_view(view)
|
||||
{
|
||||
}
|
||||
|
||||
CameraSpeedConfiguration::~CameraSpeedConfiguration()
|
||||
{
|
||||
delete m_configDialog;
|
||||
restoreCursor();
|
||||
}
|
||||
|
||||
void CameraSpeedConfiguration::apply()
|
||||
{
|
||||
if (m_changes && !m_view.isNull())
|
||||
m_view->setCameraSpeedAuxData(speed(), multiplier());
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
void CameraSpeedConfiguration::resetDefaults()
|
||||
{
|
||||
setSpeed(defaultSpeed);
|
||||
setMultiplier(defaultMultiplier);
|
||||
}
|
||||
|
||||
void CameraSpeedConfiguration::hideCursor()
|
||||
{
|
||||
if (QGuiApplication::overrideCursor())
|
||||
return;
|
||||
|
||||
QGuiApplication::setOverrideCursor(QCursor(Qt::BlankCursor));
|
||||
|
||||
if (QWindow *w = QGuiApplication::focusWindow())
|
||||
m_lastPos = QCursor::pos(w->screen());
|
||||
}
|
||||
|
||||
void CameraSpeedConfiguration::restoreCursor()
|
||||
{
|
||||
if (!QGuiApplication::overrideCursor())
|
||||
return;
|
||||
|
||||
QGuiApplication::restoreOverrideCursor();
|
||||
|
||||
if (QWindow *w = QGuiApplication::focusWindow())
|
||||
QCursor::setPos(w->screen(), m_lastPos);
|
||||
}
|
||||
|
||||
void CameraSpeedConfiguration::holdCursorInPlace()
|
||||
{
|
||||
if (!QGuiApplication::overrideCursor())
|
||||
return;
|
||||
|
||||
if (QWindow *w = QGuiApplication::focusWindow())
|
||||
QCursor::setPos(w->screen(), m_lastPos);
|
||||
}
|
||||
|
||||
int CameraSpeedConfiguration::devicePixelRatio()
|
||||
{
|
||||
if (QWindow *w = QGuiApplication::focusWindow())
|
||||
return w->devicePixelRatio();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CameraSpeedConfiguration::showConfigDialog(const QPoint &pos)
|
||||
{
|
||||
double speed, multiplier;
|
||||
m_view->getCameraSpeedAuxData(speed, multiplier);
|
||||
|
||||
setSpeed(speed);
|
||||
setMultiplier(multiplier);
|
||||
|
||||
m_changes = false;
|
||||
|
||||
if (!m_configDialog) {
|
||||
// Show non-modal progress dialog with cancel button
|
||||
QString path = qmlSourcesPath() + "/CameraSpeedConfigurationDialog.qml";
|
||||
|
||||
m_configDialog = new QQuickView;
|
||||
m_configDialog->setResizeMode(QQuickView::SizeViewToRootObject);
|
||||
m_configDialog->setFlags(Qt::Dialog | Qt::FramelessWindowHint);
|
||||
m_configDialog->setModality(Qt::NonModal);
|
||||
m_configDialog->engine()->addImportPath(propertyEditorResourcesPath() + "/imports");
|
||||
|
||||
m_configDialog->rootContext()->setContextObject(this);
|
||||
m_configDialog->setSource(QUrl::fromLocalFile(path));
|
||||
m_configDialog->installEventFilter(this);
|
||||
|
||||
QPoint finalPos = pos;
|
||||
finalPos.setX(pos.x() - m_configDialog->size().width() / 2);
|
||||
finalPos.setY(pos.y());
|
||||
m_configDialog->setPosition(finalPos);
|
||||
}
|
||||
|
||||
m_configDialog->show();
|
||||
}
|
||||
|
||||
void CameraSpeedConfiguration::setSpeed(double value)
|
||||
{
|
||||
if (value != m_speed) {
|
||||
m_speed = value;
|
||||
m_changes = true;
|
||||
emit speedChanged();
|
||||
emit totalSpeedChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void CameraSpeedConfiguration::setMultiplier(double value)
|
||||
{
|
||||
if (value != m_multiplier) {
|
||||
m_multiplier = value;
|
||||
m_changes = true;
|
||||
emit multiplierChanged();
|
||||
emit totalSpeedChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void CameraSpeedConfiguration::asyncClose()
|
||||
{
|
||||
QTimer::singleShot(0, this, [this] {
|
||||
if (!m_configDialog.isNull() && m_configDialog->isVisible())
|
||||
m_configDialog->close();
|
||||
});
|
||||
}
|
||||
|
||||
void CameraSpeedConfiguration::cancel()
|
||||
{
|
||||
if (!m_configDialog.isNull() && m_configDialog->isVisible())
|
||||
m_configDialog->close();
|
||||
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
bool CameraSpeedConfiguration::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
if (obj == m_configDialog) {
|
||||
if (event->type() == QEvent::FocusOut) {
|
||||
asyncClose();
|
||||
} else if (event->type() == QEvent::KeyPress) {
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||
if (keyEvent->key() == Qt::Key_Escape)
|
||||
asyncClose();
|
||||
} else if (event->type() == QEvent::Close) {
|
||||
apply();
|
||||
}
|
||||
}
|
||||
|
||||
return QObject::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
@@ -0,0 +1,76 @@
|
||||
// Copyright (C) 2024 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
#pragma once
|
||||
|
||||
#include <auxiliarydata.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QPoint>
|
||||
#include <QPointer>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QQuickView;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class Edit3DView;
|
||||
|
||||
inline constexpr AuxiliaryDataKeyView edit3dCameraSpeedDocProperty{AuxiliaryDataType::Document,
|
||||
"cameraSpeed3d"};
|
||||
inline constexpr AuxiliaryDataKeyView edit3dCameraSpeedMultiplierDocProperty{AuxiliaryDataType::Document,
|
||||
"cameraSpeed3dMultiplier"};
|
||||
inline constexpr AuxiliaryDataKeyView edit3dCameraTotalSpeedProperty{AuxiliaryDataType::NodeInstanceAuxiliary,
|
||||
"cameraTotalSpeed3d"};
|
||||
|
||||
class CameraSpeedConfiguration : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(double speed READ speed WRITE setSpeed NOTIFY speedChanged)
|
||||
Q_PROPERTY(double multiplier READ multiplier WRITE setMultiplier NOTIFY multiplierChanged)
|
||||
Q_PROPERTY(double totalSpeed READ totalSpeed NOTIFY totalSpeedChanged)
|
||||
|
||||
public:
|
||||
CameraSpeedConfiguration(Edit3DView *view);
|
||||
~CameraSpeedConfiguration();
|
||||
|
||||
Q_INVOKABLE void resetDefaults();
|
||||
Q_INVOKABLE void hideCursor();
|
||||
Q_INVOKABLE void restoreCursor();
|
||||
Q_INVOKABLE void holdCursorInPlace();
|
||||
Q_INVOKABLE int devicePixelRatio();
|
||||
|
||||
void cancel();
|
||||
void apply();
|
||||
|
||||
void showConfigDialog(const QPoint &pos);
|
||||
|
||||
void setSpeed(double value);
|
||||
double speed() const { return m_speed; }
|
||||
void setMultiplier(double value);
|
||||
double multiplier() const { return m_multiplier; }
|
||||
double totalSpeed() const { return m_speed * m_multiplier; }
|
||||
|
||||
constexpr static double defaultSpeed = 25.;
|
||||
constexpr static double defaultMultiplier = 1.;
|
||||
|
||||
signals:
|
||||
void speedChanged();
|
||||
void multiplierChanged();
|
||||
void totalSpeedChanged();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
|
||||
private:
|
||||
void asyncClose();
|
||||
|
||||
QPointer<QQuickView> m_configDialog;
|
||||
QPointer<Edit3DView> m_view;
|
||||
double m_speed = 0.;
|
||||
double m_multiplier = 0.;
|
||||
bool m_changes = false;
|
||||
QPoint m_lastPos;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
@@ -9,6 +9,8 @@
|
||||
#include "qmldesignerconstants.h"
|
||||
#include "seekerslider.h"
|
||||
|
||||
#include <utils3d.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
@@ -149,7 +151,7 @@ bool Edit3DBakeLightsAction::isVisible(const SelectionContext &) const
|
||||
bool Edit3DBakeLightsAction::isEnabled(const SelectionContext &) const
|
||||
{
|
||||
return m_view->isBakingLightsSupported()
|
||||
&& !BakeLights::resolveView3dId(m_view).isEmpty();
|
||||
&& !Utils3D::activeView3dId(m_view).isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "backgroundcolorselection.h"
|
||||
#include "bakelights.h"
|
||||
#include "cameraspeedconfiguration.h"
|
||||
#include "designeractionmanager.h"
|
||||
#include "designericons.h"
|
||||
#include "designersettings.h"
|
||||
@@ -270,6 +271,8 @@ void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState)
|
||||
selectionContext.setUpdateMode(SelectionContext::UpdateMode::Fast);
|
||||
if (m_bakeLightsAction)
|
||||
m_bakeLightsAction->currentContextChanged(selectionContext);
|
||||
|
||||
syncCameraSpeedToNewView();
|
||||
}
|
||||
|
||||
void Edit3DView::modelAttached(Model *model)
|
||||
@@ -764,6 +767,48 @@ void Edit3DView::syncSnapAuxPropsToSettings()
|
||||
Edit3DViewConfig::load(DesignerSettingsKey::EDIT3DVIEW_SNAP_SCALE_INTERVAL));
|
||||
}
|
||||
|
||||
void Edit3DView::setCameraSpeedAuxData(double speed, double multiplier)
|
||||
{
|
||||
ModelNode node = Utils3D::active3DSceneNode(this);
|
||||
node.setAuxiliaryData(edit3dCameraSpeedDocProperty, speed);
|
||||
node.setAuxiliaryData(edit3dCameraSpeedMultiplierDocProperty, multiplier);
|
||||
rootModelNode().setAuxiliaryData(edit3dCameraTotalSpeedProperty, (speed * multiplier));
|
||||
m_previousCameraSpeed = speed;
|
||||
m_previousCameraMultiplier = multiplier;
|
||||
}
|
||||
|
||||
void Edit3DView::getCameraSpeedAuxData(double &speed, double &multiplier)
|
||||
{
|
||||
ModelNode node = Utils3D::active3DSceneNode(this);
|
||||
auto speedProp = node.auxiliaryData(edit3dCameraSpeedDocProperty);
|
||||
auto multProp = node.auxiliaryData(edit3dCameraSpeedMultiplierDocProperty);
|
||||
speed = speedProp ? speedProp->toDouble() : CameraSpeedConfiguration::defaultSpeed;
|
||||
multiplier = multProp ? multProp->toDouble() : CameraSpeedConfiguration::defaultMultiplier;
|
||||
}
|
||||
|
||||
void Edit3DView::syncCameraSpeedToNewView()
|
||||
{
|
||||
// Camera speed is inherited from previous active view if explicit values have not been
|
||||
// stored for the currently active view
|
||||
ModelNode node = Utils3D::active3DSceneNode(this);
|
||||
auto speedProp = node.auxiliaryData(edit3dCameraSpeedDocProperty);
|
||||
auto multProp = node.auxiliaryData(edit3dCameraSpeedMultiplierDocProperty);
|
||||
double speed = CameraSpeedConfiguration::defaultSpeed;
|
||||
double multiplier = CameraSpeedConfiguration::defaultMultiplier;
|
||||
|
||||
if (!speedProp || !multProp) {
|
||||
if (m_previousCameraSpeed > 0 && m_previousCameraMultiplier > 0) {
|
||||
speed = m_previousCameraSpeed;
|
||||
multiplier = m_previousCameraMultiplier;
|
||||
}
|
||||
} else {
|
||||
speed = speedProp->toDouble();
|
||||
multiplier = multProp->toDouble();
|
||||
}
|
||||
|
||||
setCameraSpeedAuxData(speed, multiplier);
|
||||
}
|
||||
|
||||
const QList<Edit3DView::SplitToolState> &Edit3DView::splitToolStates() const
|
||||
{
|
||||
return m_splitToolStates;
|
||||
@@ -1156,6 +1201,30 @@ void Edit3DView::createEdit3DActions()
|
||||
toolbarIcon(DesignerIcons::SplitViewIcon),
|
||||
this);
|
||||
|
||||
SelectionContextOperation cameraSpeedConfigTrigger = [this](const SelectionContext &) {
|
||||
if (!m_cameraSpeedConfiguration) {
|
||||
m_cameraSpeedConfiguration = new CameraSpeedConfiguration(this);
|
||||
connect(m_cameraSpeedConfiguration.data(), &CameraSpeedConfiguration::totalSpeedChanged,
|
||||
this, [this] {
|
||||
setCameraSpeedAuxData(m_cameraSpeedConfiguration->speed(),
|
||||
m_cameraSpeedConfiguration->multiplier());
|
||||
});
|
||||
}
|
||||
m_cameraSpeedConfiguration->showConfigDialog(resolveToolbarPopupPos(m_cameraSpeedConfigAction.get()));
|
||||
};
|
||||
|
||||
m_cameraSpeedConfigAction = std::make_unique<Edit3DAction>(
|
||||
QmlDesigner::Constants::EDIT3D_CAMERA_SPEED_CONFIG,
|
||||
View3DActionType::Empty,
|
||||
QCoreApplication::translate("CameraSpeedConfigAction", "Open camera speed configuration dialog"),
|
||||
QKeySequence(),
|
||||
false,
|
||||
false,
|
||||
toolbarIcon(DesignerIcons::SnappingConfIcon), // TODO proper icon
|
||||
this,
|
||||
cameraSpeedConfigTrigger);
|
||||
|
||||
|
||||
m_leftActions << m_selectionModeAction.get();
|
||||
m_leftActions << nullptr; // Null indicates separator
|
||||
m_leftActions << nullptr; // Second null after separator indicates an exclusive group
|
||||
@@ -1174,6 +1243,7 @@ void Edit3DView::createEdit3DActions()
|
||||
m_leftActions << nullptr;
|
||||
m_leftActions << m_alignCamerasAction.get();
|
||||
m_leftActions << m_alignViewAction.get();
|
||||
m_leftActions << m_cameraSpeedConfigAction.get();
|
||||
m_leftActions << nullptr;
|
||||
m_leftActions << m_visibilityTogglesAction.get();
|
||||
m_leftActions << m_backgroundColorMenuAction.get();
|
||||
|
@@ -25,6 +25,7 @@ QT_END_NAMESPACE
|
||||
namespace QmlDesigner {
|
||||
|
||||
class BakeLights;
|
||||
class CameraSpeedConfiguration;
|
||||
class Edit3DWidget;
|
||||
class SnapConfiguration;
|
||||
|
||||
@@ -85,6 +86,8 @@ public:
|
||||
bool isBakingLightsSupported() const;
|
||||
|
||||
void syncSnapAuxPropsToSettings();
|
||||
void setCameraSpeedAuxData(double speed, double multiplier);
|
||||
void getCameraSpeedAuxData(double &speed, double &multiplier);
|
||||
|
||||
const QList<SplitToolState> &splitToolStates() const;
|
||||
void setSplitToolState(int splitIndex, const SplitToolState &state);
|
||||
@@ -123,6 +126,7 @@ private:
|
||||
void createResetColorAction(QAction *syncEnvBackgroundAction);
|
||||
void createSyncEnvBackgroundAction();
|
||||
void createSeekerSliderAction();
|
||||
void syncCameraSpeedToNewView();
|
||||
|
||||
QPoint resolveToolbarPopupPos(Edit3DAction *action) const;
|
||||
|
||||
@@ -164,6 +168,7 @@ private:
|
||||
std::unique_ptr<Edit3DAction> m_backgroundColorMenuAction;
|
||||
std::unique_ptr<Edit3DAction> m_snapToggleAction;
|
||||
std::unique_ptr<Edit3DAction> m_snapConfigAction;
|
||||
std::unique_ptr<Edit3DAction> m_cameraSpeedConfigAction;
|
||||
std::unique_ptr<Edit3DBakeLightsAction> m_bakeLightsAction;
|
||||
|
||||
int particlemode;
|
||||
@@ -178,12 +183,16 @@ private:
|
||||
QPointer<BakeLights> m_bakeLights;
|
||||
bool m_isBakingLightsSupported = false;
|
||||
QPointer<SnapConfiguration> m_snapConfiguration;
|
||||
QPointer<CameraSpeedConfiguration> m_cameraSpeedConfiguration;
|
||||
int m_activeSplit = 0;
|
||||
|
||||
QList<SplitToolState> m_splitToolStates;
|
||||
QList<Edit3DAction *> m_flyModeDisabledActions;
|
||||
ModelNode m_contextMenuPendingNode;
|
||||
|
||||
double m_previousCameraSpeed = -1.;
|
||||
double m_previousCameraMultiplier = -1.;
|
||||
|
||||
friend class Edit3DAction;
|
||||
};
|
||||
|
||||
|
@@ -75,6 +75,7 @@ inline constexpr char EDIT3D_BACKGROUND_COLOR_ACTIONS[]
|
||||
inline constexpr char EDIT3D_BAKE_LIGHTS[] = "QmlDesigner.Editor3D.BakeLights";
|
||||
inline constexpr char EDIT3D_SNAP_TOGGLE[] = "QmlDesigner.Editor3D.SnapToggle";
|
||||
inline constexpr char EDIT3D_SNAP_CONFIG[] = "QmlDesigner.Editor3D.SnapConfig";
|
||||
inline constexpr char EDIT3D_CAMERA_SPEED_CONFIG[] = "QmlDesigner.Editor3D.CameraSpeedConfig";
|
||||
|
||||
inline constexpr char QML_DESIGNER_SUBFOLDER[] = "/designer/";
|
||||
inline constexpr char COMPONENT_BUNDLES_FOLDER[] = "/ComponentBundles";
|
||||
|
@@ -26,7 +26,7 @@ Item {
|
||||
readonly property vector3d _defaultCameraPosition: Qt.vector3d(0, 600, 600)
|
||||
readonly property vector3d _defaultCameraRotation: Qt.vector3d(-45, 0, 0)
|
||||
readonly property real _defaultCameraLookAtDistance: _defaultCameraPosition.length()
|
||||
readonly property real _keyPanAmount: 10
|
||||
readonly property real _keyPanAmount: _generalHelper.cameraSpeed
|
||||
property bool ignoreToolState: false
|
||||
property bool flyMode: viewRoot.flyMode
|
||||
|
||||
|
@@ -1116,6 +1116,14 @@ void GeneralHelper::setSnapPositionInterval(double interval)
|
||||
}
|
||||
}
|
||||
|
||||
void GeneralHelper::setCameraSpeed(double speed)
|
||||
{
|
||||
if (m_cameraSpeed != speed) {
|
||||
m_cameraSpeed = speed;
|
||||
emit cameraSpeedChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QString GeneralHelper::formatVectorDragTooltip(const QVector3D &vec, const QString &suffix) const
|
||||
{
|
||||
return QObject::tr("x:%L1 y:%L2 z:%L3%L4")
|
||||
|
@@ -38,6 +38,7 @@ class GeneralHelper : public QObject
|
||||
Q_PROPERTY(bool isMacOS READ isMacOS CONSTANT)
|
||||
Q_PROPERTY(QVariant bgColor READ bgColor NOTIFY bgColorChanged FINAL)
|
||||
Q_PROPERTY(double minGridStep READ minGridStep NOTIFY minGridStepChanged FINAL)
|
||||
Q_PROPERTY(double cameraSpeed READ cameraSpeed NOTIFY cameraSpeedChanged FINAL)
|
||||
|
||||
public:
|
||||
GeneralHelper();
|
||||
@@ -135,12 +136,14 @@ public:
|
||||
void setSnapPositionInterval(double interval);
|
||||
void setSnapRotationInterval(double interval) { m_snapRotationInterval = interval; }
|
||||
void setSnapScaleInterval(double interval) { m_snapScaleInterval = interval / 100.; }
|
||||
void setCameraSpeed(double speed);
|
||||
|
||||
Q_INVOKABLE QString snapPositionDragTooltip(const QVector3D &pos) const;
|
||||
Q_INVOKABLE QString snapRotationDragTooltip(double angle) const;
|
||||
Q_INVOKABLE QString snapScaleDragTooltip(const QVector3D &scale) const;
|
||||
|
||||
double minGridStep() const;
|
||||
double cameraSpeed() const { return m_cameraSpeed; }
|
||||
|
||||
void setBgColor(const QVariant &colors);
|
||||
QVariant bgColor() const { return m_bgColor; }
|
||||
@@ -161,6 +164,7 @@ signals:
|
||||
void sceneEnvDataChanged();
|
||||
void requestCameraMove(QQuick3DCamera *camera, const QVector3D &moveVector);
|
||||
void requestRender();
|
||||
void cameraSpeedChanged();
|
||||
|
||||
private:
|
||||
void handlePendingToolStateUpdate();
|
||||
@@ -214,6 +218,7 @@ private:
|
||||
double m_snapPositionInterval = 50.;
|
||||
double m_snapRotationInterval = 5.;
|
||||
double m_snapScaleInterval = .1;
|
||||
double m_cameraSpeed = 10.;
|
||||
|
||||
QVariant m_bgColor;
|
||||
};
|
||||
|
@@ -343,7 +343,7 @@ void Qt5InformationNodeInstanceServer::updateRotationBlocks(
|
||||
#endif
|
||||
}
|
||||
|
||||
void Qt5InformationNodeInstanceServer::updateSnapSettings(
|
||||
void Qt5InformationNodeInstanceServer::updateSnapAndCameraSettings(
|
||||
[[maybe_unused]] const QVector<PropertyValueContainer> &valueChanges)
|
||||
{
|
||||
#ifdef QUICK3D_MODULE
|
||||
@@ -372,6 +372,8 @@ void Qt5InformationNodeInstanceServer::updateSnapSettings(
|
||||
} else if (container.name() == "snapAbs3d") {
|
||||
helper->setSnapAbsolute(container.value().toBool());
|
||||
changed = true;
|
||||
} else if (container.name() == "cameraTotalSpeed3d") {
|
||||
helper->setCameraSpeed(container.value().toDouble());
|
||||
}
|
||||
}
|
||||
if (changed)
|
||||
@@ -2103,7 +2105,7 @@ void Qt5InformationNodeInstanceServer::createScene(const CreateSceneCommand &com
|
||||
setup3DEditView(instanceList, command);
|
||||
updateRotationBlocks(command.auxiliaryChanges);
|
||||
updateMaterialPreviewData(command.auxiliaryChanges);
|
||||
updateSnapSettings(command.auxiliaryChanges);
|
||||
updateSnapAndCameraSettings(command.auxiliaryChanges);
|
||||
updateColorSettings(command.auxiliaryChanges);
|
||||
}
|
||||
|
||||
@@ -2613,7 +2615,7 @@ void Qt5InformationNodeInstanceServer::changeAuxiliaryValues(const ChangeAuxilia
|
||||
{
|
||||
updateRotationBlocks(command.auxiliaryChanges);
|
||||
updateMaterialPreviewData(command.auxiliaryChanges);
|
||||
updateSnapSettings(command.auxiliaryChanges);
|
||||
updateSnapAndCameraSettings(command.auxiliaryChanges);
|
||||
updateColorSettings(command.auxiliaryChanges);
|
||||
Qt5NodeInstanceServer::changeAuxiliaryValues(command);
|
||||
render3DEditView();
|
||||
|
@@ -124,7 +124,7 @@ private:
|
||||
void resolveImportSupport();
|
||||
void updateMaterialPreviewData(const QVector<PropertyValueContainer> &valueChanges);
|
||||
void updateRotationBlocks(const QVector<PropertyValueContainer> &valueChanges);
|
||||
void updateSnapSettings(const QVector<PropertyValueContainer> &valueChanges);
|
||||
void updateSnapAndCameraSettings(const QVector<PropertyValueContainer> &valueChanges);
|
||||
void updateColorSettings(const QVector<PropertyValueContainer> &valueChanges);
|
||||
void removeRotationBlocks(const QVector<qint32> &instanceIds);
|
||||
void getNodeAtPos(const QPointF &pos);
|
||||
|
Reference in New Issue
Block a user