diff --git a/share/qtcreator/qmldesigner/edit3dQmlSource/CameraSpeedConfigurationDialog.qml b/share/qtcreator/qmldesigner/edit3dQmlSource/CameraSpeedConfigurationDialog.qml new file mode 100644 index 00000000000..219b485ca0d --- /dev/null +++ b/share/qtcreator/qmldesigner/edit3dQmlSource/CameraSpeedConfigurationDialog.qml @@ -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() + } + } + } + } +} diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index 3f503c42311..b5b64bebbc8 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -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 diff --git a/src/plugins/qmldesigner/components/componentcore/utils3d.cpp b/src/plugins/qmldesigner/components/componentcore/utils3d.cpp index 54618604df2..3983dcb13ca 100644 --- a/src/plugins/qmldesigner/components/componentcore/utils3d.cpp +++ b/src/plugins/qmldesigner/components/componentcore/utils3d.cpp @@ -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 diff --git a/src/plugins/qmldesigner/components/componentcore/utils3d.h b/src/plugins/qmldesigner/components/componentcore/utils3d.h index 9891a62b4cd..0e582c0fb4a 100644 --- a/src/plugins/qmldesigner/components/componentcore/utils3d.h +++ b/src/plugins/qmldesigner/components/componentcore/utils3d.h @@ -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 diff --git a/src/plugins/qmldesigner/components/edit3d/bakelights.cpp b/src/plugins/qmldesigner/components/edit3d/bakelights.cpp index 25a27f778bf..ab1eb9b07b1 100644 --- a/src/plugins/qmldesigner/components/edit3d/bakelights.cpp +++ b/src/plugins/qmldesigner/components/edit3d/bakelights.cpp @@ -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) diff --git a/src/plugins/qmldesigner/components/edit3d/bakelights.h b/src/plugins/qmldesigner/components/edit3d/bakelights.h index 65f00acc7b0..2b6848bd482 100644 --- a/src/plugins/qmldesigner/components/edit3d/bakelights.h +++ b/src/plugins/qmldesigner/components/edit3d/bakelights.h @@ -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); diff --git a/src/plugins/qmldesigner/components/edit3d/bakelightsdatamodel.cpp b/src/plugins/qmldesigner/components/edit3d/bakelightsdatamodel.cpp index 9657d564fb2..95a260c26fd 100644 --- a/src/plugins/qmldesigner/components/edit3d/bakelightsdatamodel.cpp +++ b/src/plugins/qmldesigner/components/edit3d/bakelightsdatamodel.cpp @@ -15,6 +15,8 @@ #include "qmlobjectnode.h" #include "variantproperty.h" +#include + #include #include #include @@ -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 nodes = m_view3dNode.allSubModelNodes(); diff --git a/src/plugins/qmldesigner/components/edit3d/cameraspeedconfiguration.cpp b/src/plugins/qmldesigner/components/edit3d/cameraspeedconfiguration.cpp new file mode 100644 index 00000000000..76560ac1926 --- /dev/null +++ b/src/plugins/qmldesigner/components/edit3d/cameraspeedconfiguration.cpp @@ -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 + +#include + +#include +#include +#include +#include +#include +#include +#include + +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(event); + if (keyEvent->key() == Qt::Key_Escape) + asyncClose(); + } else if (event->type() == QEvent::Close) { + apply(); + } + } + + return QObject::eventFilter(obj, event); +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/edit3d/cameraspeedconfiguration.h b/src/plugins/qmldesigner/components/edit3d/cameraspeedconfiguration.h new file mode 100644 index 00000000000..55256890cbb --- /dev/null +++ b/src/plugins/qmldesigner/components/edit3d/cameraspeedconfiguration.h @@ -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 + +#include +#include +#include + +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 m_configDialog; + QPointer m_view; + double m_speed = 0.; + double m_multiplier = 0.; + bool m_changes = false; + QPoint m_lastPos; +}; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dactions.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dactions.cpp index add61d195de..b3d140bc887 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dactions.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dactions.cpp @@ -9,6 +9,8 @@ #include "qmldesignerconstants.h" #include "seekerslider.h" +#include + #include 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(); } } diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp index fafcff86671..e5ff133c69f 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp @@ -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::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( + 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(); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.h b/src/plugins/qmldesigner/components/edit3d/edit3dview.h index 63b815f392b..781b26d8d8d 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.h @@ -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 &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 m_backgroundColorMenuAction; std::unique_ptr m_snapToggleAction; std::unique_ptr m_snapConfigAction; + std::unique_ptr m_cameraSpeedConfigAction; std::unique_ptr m_bakeLightsAction; int particlemode; @@ -178,12 +183,16 @@ private: QPointer m_bakeLights; bool m_isBakingLightsSupported = false; QPointer m_snapConfiguration; + QPointer m_cameraSpeedConfiguration; int m_activeSplit = 0; QList m_splitToolStates; QList m_flyModeDisabledActions; ModelNode m_contextMenuPendingNode; + double m_previousCameraSpeed = -1.; + double m_previousCameraMultiplier = -1.; + friend class Edit3DAction; }; diff --git a/src/plugins/qmldesigner/qmldesignerconstants.h b/src/plugins/qmldesigner/qmldesignerconstants.h index 547d42e6e99..db63d894fec 100644 --- a/src/plugins/qmldesigner/qmldesignerconstants.h +++ b/src/plugins/qmldesigner/qmldesignerconstants.h @@ -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"; diff --git a/src/tools/qml2puppet/mockfiles/qt6/EditCameraController.qml b/src/tools/qml2puppet/mockfiles/qt6/EditCameraController.qml index e2321dbc3ac..446d5756838 100644 --- a/src/tools/qml2puppet/mockfiles/qt6/EditCameraController.qml +++ b/src/tools/qml2puppet/mockfiles/qt6/EditCameraController.qml @@ -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 diff --git a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp index 52070332b46..6886f7e41c5 100644 --- a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp +++ b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp @@ -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") diff --git a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h index 9afaf077c9b..3ba6f8b1d9f 100644 --- a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h +++ b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h @@ -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; }; diff --git a/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp index 1ce4e0364c8..c7cab45ed4d 100644 --- a/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp +++ b/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp @@ -343,7 +343,7 @@ void Qt5InformationNodeInstanceServer::updateRotationBlocks( #endif } -void Qt5InformationNodeInstanceServer::updateSnapSettings( +void Qt5InformationNodeInstanceServer::updateSnapAndCameraSettings( [[maybe_unused]] const QVector &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(); diff --git a/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.h b/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.h index d18266dd589..4f7fcd71774 100644 --- a/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.h +++ b/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.h @@ -124,7 +124,7 @@ private: void resolveImportSupport(); void updateMaterialPreviewData(const QVector &valueChanges); void updateRotationBlocks(const QVector &valueChanges); - void updateSnapSettings(const QVector &valueChanges); + void updateSnapAndCameraSettings(const QVector &valueChanges); void updateColorSettings(const QVector &valueChanges); void removeRotationBlocks(const QVector &instanceIds); void getNodeAtPos(const QPointF &pos);