QmlDesigner: Show snap interval on drag tooltip in 3D view

Fixes: QDS-10751
Change-Id: I7c13075ae726c1f33992ec52c554491a21f7e5c1
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
This commit is contained in:
Miikka Heikkinen
2023-09-26 15:27:11 +03:00
parent 8f69e5c0f2
commit 8da35ac06d
4 changed files with 125 additions and 39 deletions

View File

@@ -727,6 +727,11 @@ Item {
}
}
}
function onUpdateDragTooltip()
{
gizmoLabel.updateLabel();
rotateGizmoLabel.updateLabel();
}
}
Node {
@@ -834,6 +839,7 @@ Item {
else
viewRoot.changeObjectProperty([viewRoot.selectedNode], propertyNames);
}
onCurrentAngleChanged: rotateGizmoLabel.updateLabel()
}
LightGizmo {
@@ -1012,6 +1018,27 @@ Item {
visible: targetNode.dragging
z: 3
function updateLabel()
{
// This is skipped during application shutdown, as calling QQuickText::setText()
// during application shutdown can crash the application.
if (!gizmoLabel.visible || !viewRoot.selectedNode || shuttingDown)
return;
var targetProperty;
if (gizmoLabel.targetNode === moveGizmo)
gizmoLabelText.text = _generalHelper.snapPositionDragTooltip(viewRoot.selectedNode.position);
else
gizmoLabelText.text = _generalHelper.snapScaleDragTooltip(viewRoot.selectedNode.scale);
}
Connections {
target: viewRoot.selectedNode
function onPositionChanged() { gizmoLabel.updateLabel() }
function onScaleChanged() { gizmoLabel.updateLabel() }
}
onVisibleChanged: gizmoLabel.updateLabel()
Rectangle {
color: "white"
x: -width / 2
@@ -1021,25 +1048,6 @@ Item {
border.width: 1
Text {
id: gizmoLabelText
text: {
// This is skipped during application shutdown, as calling QQuickText::setText()
// during application shutdown can crash the application.
if (shuttingDown)
return text;
var l = Qt.locale();
var targetProperty;
if (viewRoot.selectedNode) {
if (gizmoLabel.targetNode === moveGizmo)
targetProperty = viewRoot.selectedNode.position;
else
targetProperty = viewRoot.selectedNode.scale;
return qsTr("x:") + Number(targetProperty.x).toLocaleString(l, 'f', 1)
+ qsTr(" y:") + Number(targetProperty.y).toLocaleString(l, 'f', 1)
+ qsTr(" z:") + Number(targetProperty.z).toLocaleString(l, 'f', 1);
} else {
return "";
}
}
anchors.centerIn: parent
}
}
@@ -1057,21 +1065,19 @@ Item {
parent: rotateGizmo.view3D
z: 3
function updateLabel() {
// This is skipped during application shutdown, as calling QQuickText::setText()
// during application shutdown can crash the application.
if (!rotateGizmoLabel.visible || !rotateGizmo.targetNode || shuttingDown)
return;
var degrees = rotateGizmo.currentAngle * (180 / Math.PI);
rotateGizmoLabelText.text = _generalHelper.snapRotationDragTooltip(degrees);
}
onVisibleChanged: rotateGizmoLabel.updateLabel()
Text {
id: rotateGizmoLabelText
text: {
// This is skipped during application shutdown, as calling QQuickText::setText()
// during application shutdown can crash the application.
if (shuttingDown)
return text;
var l = Qt.locale();
if (rotateGizmo.targetNode) {
var degrees = rotateGizmo.currentAngle * (180 / Math.PI);
return Number(degrees).toLocaleString(l, 'f', 1);
} else {
return "";
}
}
anchors.centerIn: parent
}
}
@@ -1135,4 +1141,30 @@ Item {
visible: viewRoot.fps > 0
}
}
Keys.onPressed: (event) => {
switch (event.key) {
case Qt.Key_Control:
case Qt.Key_Shift:
gizmoLabel.updateLabel();
rotateGizmoLabel.updateLabel();
break;
default:
break;
}
event.accepted = false;
}
Keys.onReleased: (event) => {
switch (event.key) {
case Qt.Key_Control:
case Qt.Key_Shift:
gizmoLabel.updateLabel();
rotateGizmoLabel.updateLabel();
break;
default:
break;
}
event.accepted = false;
}
}

View File

@@ -962,6 +962,42 @@ void GeneralHelper::setSnapPositionInterval(double interval)
}
}
QString GeneralHelper::formatVectorDragTooltip(const QVector3D &vec, const QString &suffix) const
{
return QObject::tr("x:%L1 y:%L2 z:%L3%L4")
.arg(vec.x(), 0, 'f', 1).arg(vec.y(), 0, 'f', 1)
.arg(vec.z(), 0, 'f', 1).arg(suffix);
}
QString GeneralHelper::formatSnapStr(bool snapEnabled, double increment, const QString &suffix) const
{
double inc = increment;
QString snapStr;
if (queryKeyboardForSnapping(snapEnabled, inc)) {
int precision = 0;
// We can have fractional snap if shift is pressed, so adjust precision in those cases
if (qRound(inc * 10.) != qRound(inc) * 10)
precision = 1;
snapStr = QObject::tr(" (Snap: %1%2)").arg(inc, 0, 'f', precision).arg(suffix);
}
return snapStr;
}
QString GeneralHelper::snapPositionDragTooltip(const QVector3D &pos) const
{
return formatVectorDragTooltip(pos, formatSnapStr(m_snapPosition, m_snapPositionInterval, {}));
}
QString GeneralHelper::snapRotationDragTooltip(double angle) const
{
return tr("%L1%L2").arg(angle, 0, 'f', 1).arg(formatSnapStr(m_snapRotation, m_snapRotationInterval, {}));
}
QString GeneralHelper::snapScaleDragTooltip(const QVector3D &scale) const
{
return formatVectorDragTooltip(scale, formatSnapStr(m_snapScale, m_snapScaleInterval * 100., tr("%")));
}
double GeneralHelper::minGridStep() const
{
// Minimum grid step is a multiple of snap interval, as the last step is divided to subgrid

View File

@@ -119,6 +119,10 @@ public:
void setSnapRotationInterval(double interval) { m_snapRotationInterval = interval; }
void setSnapScaleInterval(double interval) { m_snapScaleInterval = interval / 100.; }
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;
void setBgColor(const QVariant &colors);
@@ -132,12 +136,15 @@ signals:
void rotationBlocksChanged();
void bgColorChanged();
void minGridStepChanged();
void updateDragTooltip();
private:
void handlePendingToolStateUpdate();
QVector3D pivotScenePosition(QQuick3DNode *node) const;
bool getBounds(QQuick3DViewport *view3D, QQuick3DNode *node, QVector3D &minBounds,
QVector3D &maxBounds);
QString formatVectorDragTooltip(const QVector3D &vec, const QString &suffix) const;
QString formatSnapStr(bool snapEnabled, double increment, const QString &suffix) const;
QTimer m_overlayUpdateTimer;
QTimer m_toolStateUpdateTimer;

View File

@@ -344,22 +344,33 @@ void Qt5InformationNodeInstanceServer::updateSnapSettings(
#ifdef QUICK3D_MODULE
auto helper = qobject_cast<QmlDesigner::Internal::GeneralHelper *>(m_3dHelper);
if (helper) {
bool changed = false;
for (const auto &container : valueChanges) {
if (container.name() == "snapPos3d")
if (container.name() == "snapPos3d") {
helper->setSnapPosition(container.value().toBool());
else if (container.name() == "snapPosInt3d")
changed = true;
} else if (container.name() == "snapPosInt3d") {
helper->setSnapPositionInterval(container.value().toDouble());
else if (container.name() == "snapRot3d")
changed = true;
} else if (container.name() == "snapRot3d") {
helper->setSnapRotation(container.value().toBool());
else if (container.name() == "snapRotInt3d")
changed = true;
} else if (container.name() == "snapRotInt3d") {
helper->setSnapRotationInterval(container.value().toDouble());
else if (container.name() == "snapScale3d")
changed = true;
} else if (container.name() == "snapScale3d") {
helper->setSnapScale(container.value().toBool());
else if (container.name() == "snapScaleInt3d")
changed = true;
} else if (container.name() == "snapScaleInt3d") {
helper->setSnapScaleInterval(container.value().toDouble());
else if (container.name() == "snapAbs3d")
changed = true;
} else if (container.name() == "snapAbs3d") {
helper->setSnapAbsolute(container.value().toBool());
changed = true;
}
}
if (changed)
emit helper->updateDragTooltip();
}
#endif
}