forked from qt-creator/qt-creator
QmlDesigner: Add ScaleGizmo to 3D edit view
ScaleGizmo allows scaling in the direction of local or global axes, as well as uniform scaling. Any scale component cannot be made negative with ScaleGizmo. Change-Id: I9b98d9593e07ded340178b07b73fa1b72421ba20 Fixes: QDS-1195 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io> Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
@@ -27,104 +27,29 @@ import QtQuick 2.0
|
|||||||
import QtQuick3D 1.0
|
import QtQuick3D 1.0
|
||||||
import MouseArea3D 1.0
|
import MouseArea3D 1.0
|
||||||
|
|
||||||
Model {
|
DirectionalDraggable {
|
||||||
id: arrow
|
id: arrow
|
||||||
rotationOrder: Node.XYZr
|
|
||||||
source: "meshes/arrow.mesh"
|
source: "meshes/arrow.mesh"
|
||||||
|
|
||||||
property View3D view3D
|
|
||||||
property alias color: material.emissiveColor
|
|
||||||
property Node targetNode: null
|
|
||||||
property bool dragging: false
|
|
||||||
|
|
||||||
readonly property bool hovering: mouseAreaYZ.hovering || mouseAreaXZ.hovering
|
|
||||||
|
|
||||||
property var _pointerPosPressed
|
|
||||||
property var _targetStartPos
|
|
||||||
|
|
||||||
signal positionCommit()
|
signal positionCommit()
|
||||||
signal positionMove()
|
signal positionMove()
|
||||||
|
|
||||||
materials: DefaultMaterial {
|
function localPos(sceneRelativeDistance)
|
||||||
id: material
|
|
||||||
emissiveColor: "white"
|
|
||||||
lighting: DefaultMaterial.NoLighting
|
|
||||||
}
|
|
||||||
|
|
||||||
function handlePressed(mouseArea, pointerPosition)
|
|
||||||
{
|
{
|
||||||
if (!targetNode)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var maskedPosition = Qt.vector3d(pointerPosition.x, 0, 0);
|
|
||||||
_pointerPosPressed = mouseArea.mapPositionToScene(maskedPosition);
|
|
||||||
var sp = targetNode.scenePosition;
|
|
||||||
_targetStartPos = Qt.vector3d(sp.x, sp.y, sp.z);
|
|
||||||
dragging = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function posInParent(mouseArea, pointerPosition)
|
|
||||||
{
|
|
||||||
var maskedPosition = Qt.vector3d(pointerPosition.x, 0, 0);
|
|
||||||
var scenePointerPos = mouseArea.mapPositionToScene(maskedPosition);
|
|
||||||
var sceneRelativeDistance = Qt.vector3d(
|
|
||||||
scenePointerPos.x - _pointerPosPressed.x,
|
|
||||||
scenePointerPos.y - _pointerPosPressed.y,
|
|
||||||
scenePointerPos.z - _pointerPosPressed.z);
|
|
||||||
|
|
||||||
var newScenePos = Qt.vector3d(
|
var newScenePos = Qt.vector3d(
|
||||||
_targetStartPos.x + sceneRelativeDistance.x,
|
_targetStartPos.x + sceneRelativeDistance.x,
|
||||||
_targetStartPos.y + sceneRelativeDistance.y,
|
_targetStartPos.y + sceneRelativeDistance.y,
|
||||||
_targetStartPos.z + sceneRelativeDistance.z);
|
_targetStartPos.z + sceneRelativeDistance.z);
|
||||||
|
|
||||||
return targetNode.parent.mapPositionFromScene(newScenePos);
|
return targetNode.parent.mapPositionFromScene(newScenePos);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleDragged(mouseArea, pointerPosition)
|
onDragged: {
|
||||||
{
|
targetNode.position = localPos(sceneRelativeDistance);
|
||||||
if (!targetNode)
|
positionMove();
|
||||||
return;
|
|
||||||
|
|
||||||
targetNode.position = posInParent(mouseArea, pointerPosition);
|
|
||||||
arrow.positionMove();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleReleased(mouseArea, pointerPosition)
|
onReleased: {
|
||||||
{
|
targetNode.position = localPos(sceneRelativeDistance);
|
||||||
if (!targetNode)
|
positionCommit();
|
||||||
return;
|
|
||||||
|
|
||||||
targetNode.position = posInParent(mouseArea, pointerPosition);
|
|
||||||
dragging = false;
|
|
||||||
arrow.positionCommit();
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea3D {
|
|
||||||
id: mouseAreaYZ
|
|
||||||
view3D: arrow.view3D
|
|
||||||
x: 0
|
|
||||||
y: -1.5
|
|
||||||
width: 12
|
|
||||||
height: 3
|
|
||||||
rotation: Qt.vector3d(0, 0, 90)
|
|
||||||
grabsMouse: targetNode
|
|
||||||
onPressed: arrow.handlePressed(mouseAreaYZ, pointerPosition)
|
|
||||||
onDragged: arrow.handleDragged(mouseAreaYZ, pointerPosition)
|
|
||||||
onReleased: arrow.handleReleased(mouseAreaYZ, pointerPosition)
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea3D {
|
|
||||||
id: mouseAreaXZ
|
|
||||||
view3D: arrow.view3D
|
|
||||||
x: 0
|
|
||||||
y: -1.5
|
|
||||||
width: 12
|
|
||||||
height: 3
|
|
||||||
rotation: Qt.vector3d(0, 90, 90)
|
|
||||||
grabsMouse: targetNode
|
|
||||||
onPressed: arrow.handlePressed(mouseAreaXZ, pointerPosition)
|
|
||||||
onDragged: arrow.handleDragged(mouseAreaXZ, pointerPosition)
|
|
||||||
onReleased: arrow.handleReleased(mouseAreaXZ, pointerPosition)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
124
share/qtcreator/qml/qmlpuppet/mockfiles/DirectionalDraggable.qml
Normal file
124
share/qtcreator/qml/qmlpuppet/mockfiles/DirectionalDraggable.qml
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtQuick3D 1.0
|
||||||
|
import MouseArea3D 1.0
|
||||||
|
|
||||||
|
Model {
|
||||||
|
id: rootModel
|
||||||
|
rotationOrder: Node.XYZr
|
||||||
|
|
||||||
|
property View3D view3D
|
||||||
|
property alias color: material.emissiveColor
|
||||||
|
property Node targetNode: null
|
||||||
|
property bool dragging: false
|
||||||
|
property bool active: false
|
||||||
|
|
||||||
|
readonly property bool hovering: mouseAreaYZ.hovering || mouseAreaXZ.hovering
|
||||||
|
|
||||||
|
property var _pointerPosPressed
|
||||||
|
property var _targetStartPos
|
||||||
|
|
||||||
|
signal pressed(var mouseArea)
|
||||||
|
signal dragged(var mouseArea, vector3d sceneRelativeDistance)
|
||||||
|
signal released(var mouseArea, vector3d sceneRelativeDistance)
|
||||||
|
|
||||||
|
materials: DefaultMaterial {
|
||||||
|
id: material
|
||||||
|
emissiveColor: "white"
|
||||||
|
lighting: DefaultMaterial.NoLighting
|
||||||
|
}
|
||||||
|
|
||||||
|
function handlePressed(mouseArea, scenePos)
|
||||||
|
{
|
||||||
|
if (!targetNode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var maskedPosition = Qt.vector3d(scenePos.x, 0, 0);
|
||||||
|
_pointerPosPressed = mouseArea.mapPositionToScene(maskedPosition);
|
||||||
|
var sp = targetNode.scenePosition;
|
||||||
|
_targetStartPos = Qt.vector3d(sp.x, sp.y, sp.z);
|
||||||
|
dragging = true;
|
||||||
|
pressed(mouseArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
function calcRelativeDistance(mouseArea, scenePos)
|
||||||
|
{
|
||||||
|
var maskedPosition = Qt.vector3d(scenePos.x, 0, 0);
|
||||||
|
var scenePointerPos = mouseArea.mapPositionToScene(maskedPosition);
|
||||||
|
return Qt.vector3d(scenePointerPos.x - _pointerPosPressed.x,
|
||||||
|
scenePointerPos.y - _pointerPosPressed.y,
|
||||||
|
scenePointerPos.z - _pointerPosPressed.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDragged(mouseArea, scenePos)
|
||||||
|
{
|
||||||
|
if (!targetNode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dragged(mouseArea, calcRelativeDistance(mouseArea, scenePos));
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleReleased(mouseArea, scenePos)
|
||||||
|
{
|
||||||
|
if (!targetNode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
released(mouseArea, calcRelativeDistance(mouseArea, scenePos));
|
||||||
|
dragging = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea3D {
|
||||||
|
id: mouseAreaYZ
|
||||||
|
view3D: rootModel.view3D
|
||||||
|
x: 0
|
||||||
|
y: -1.5
|
||||||
|
width: 12
|
||||||
|
height: 3
|
||||||
|
rotation: Qt.vector3d(0, 0, 90)
|
||||||
|
grabsMouse: targetNode
|
||||||
|
active: rootModel.active
|
||||||
|
onPressed: rootModel.handlePressed(mouseAreaYZ, scenePos)
|
||||||
|
onDragged: rootModel.handleDragged(mouseAreaYZ, scenePos)
|
||||||
|
onReleased: rootModel.handleReleased(mouseAreaYZ, scenePos)
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea3D {
|
||||||
|
id: mouseAreaXZ
|
||||||
|
view3D: rootModel.view3D
|
||||||
|
x: 0
|
||||||
|
y: -1.5
|
||||||
|
width: 12
|
||||||
|
height: 3
|
||||||
|
rotation: Qt.vector3d(0, 90, 90)
|
||||||
|
grabsMouse: targetNode
|
||||||
|
active: rootModel.active
|
||||||
|
onPressed: rootModel.handlePressed(mouseAreaXZ, scenePos)
|
||||||
|
onDragged: rootModel.handleDragged(mouseAreaXZ, scenePos)
|
||||||
|
onReleased: rootModel.handleReleased(mouseAreaXZ, scenePos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -48,8 +48,8 @@ Window {
|
|||||||
property var cameraGizmos: []
|
property var cameraGizmos: []
|
||||||
|
|
||||||
signal objectClicked(var object)
|
signal objectClicked(var object)
|
||||||
signal commitObjectPosition(var object)
|
signal commitObjectProperty(var object, var propName)
|
||||||
signal moveObjectPosition(var object)
|
signal changeObjectProperty(var object, var propName)
|
||||||
|
|
||||||
function selectObject(object) {
|
function selectObject(object) {
|
||||||
selectedNode = object;
|
selectedNode = object;
|
||||||
@@ -113,11 +113,26 @@ Window {
|
|||||||
position: viewWindow.selectedNode ? viewWindow.selectedNode.scenePosition
|
position: viewWindow.selectedNode ? viewWindow.selectedNode.scenePosition
|
||||||
: Qt.vector3d(0, 0, 0)
|
: Qt.vector3d(0, 0, 0)
|
||||||
globalOrientation: globalControl.checked
|
globalOrientation: globalControl.checked
|
||||||
visible: selectedNode
|
visible: selectedNode && moveToolControl.checked
|
||||||
view3D: overlayView
|
view3D: overlayView
|
||||||
|
|
||||||
onPositionCommit: viewWindow.commitObjectPosition(selectedNode)
|
onPositionCommit: viewWindow.commitObjectProperty(selectedNode, "position")
|
||||||
onPositionMove: viewWindow.moveObjectPosition(selectedNode)
|
onPositionMove: viewWindow.changeObjectProperty(selectedNode, "position")
|
||||||
|
}
|
||||||
|
|
||||||
|
ScaleGizmo {
|
||||||
|
id: scaleGizmo
|
||||||
|
scale: autoScale.getScale(Qt.vector3d(5, 5, 5))
|
||||||
|
highlightOnHover: true
|
||||||
|
targetNode: viewWindow.selectedNode
|
||||||
|
position: viewWindow.selectedNode ? viewWindow.selectedNode.scenePosition
|
||||||
|
: Qt.vector3d(0, 0, 0)
|
||||||
|
globalOrientation: globalControl.checked
|
||||||
|
visible: selectedNode && scaleToolControl.checked
|
||||||
|
view3D: overlayView
|
||||||
|
|
||||||
|
onScaleCommit: viewWindow.commitObjectProperty(selectedNode, "scale")
|
||||||
|
onScaleChange: viewWindow.changeObjectProperty(selectedNode, "scale")
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoScaleHelper {
|
AutoScaleHelper {
|
||||||
@@ -186,11 +201,11 @@ Window {
|
|||||||
|
|
||||||
Overlay2D {
|
Overlay2D {
|
||||||
id: gizmoLabel
|
id: gizmoLabel
|
||||||
targetNode: moveGizmo
|
targetNode: moveGizmo.visible ? moveGizmo : scaleGizmo
|
||||||
targetView: overlayView
|
targetView: overlayView
|
||||||
offsetX: 0
|
offsetX: 0
|
||||||
offsetY: 45
|
offsetY: 45
|
||||||
visible: moveGizmo.dragging
|
visible: targetNode.dragging
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
color: "white"
|
color: "white"
|
||||||
@@ -203,11 +218,18 @@ Window {
|
|||||||
id: gizmoLabelText
|
id: gizmoLabelText
|
||||||
text: {
|
text: {
|
||||||
var l = Qt.locale();
|
var l = Qt.locale();
|
||||||
selectedNode
|
var targetProperty;
|
||||||
? qsTr("x:") + Number(selectedNode.position.x).toLocaleString(l, 'f', 1)
|
if (viewWindow.selectedNode) {
|
||||||
+ qsTr(" y:") + Number(selectedNode.position.y).toLocaleString(l, 'f', 1)
|
if (gizmoLabel.targetNode === moveGizmo)
|
||||||
+ qsTr(" z:") + Number(selectedNode.position.z).toLocaleString(l, 'f', 1)
|
targetProperty = viewWindow.selectedNode.position;
|
||||||
: "";
|
else
|
||||||
|
targetProperty = viewWindow.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
|
anchors.centerIn: parent
|
||||||
}
|
}
|
||||||
@@ -252,6 +274,19 @@ Window {
|
|||||||
text: qsTr("Use Global Orientation")
|
text: qsTr("Use Global Orientation")
|
||||||
onCheckedChanged: cameraControl.forceActiveFocus()
|
onCheckedChanged: cameraControl.forceActiveFocus()
|
||||||
}
|
}
|
||||||
|
Column {
|
||||||
|
x: 8
|
||||||
|
RadioButton {
|
||||||
|
id: moveToolControl
|
||||||
|
checked: false
|
||||||
|
text: qsTr("Move Tool")
|
||||||
|
}
|
||||||
|
RadioButton {
|
||||||
|
id: scaleToolControl
|
||||||
|
checked: true
|
||||||
|
text: qsTr("Scale Tool")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
|
@@ -49,8 +49,9 @@ Node {
|
|||||||
rotation: Qt.vector3d(0, 0, -90)
|
rotation: Qt.vector3d(0, 0, -90)
|
||||||
targetNode: moveGizmo.targetNode
|
targetNode: moveGizmo.targetNode
|
||||||
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(1, 0, 0, 1))
|
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(1, 0, 0, 1))
|
||||||
: Qt.rgba(1, 0, 0, 1)
|
: Qt.rgba(1, 0, 0, 1)
|
||||||
view3D: moveGizmo.view3D
|
view3D: moveGizmo.view3D
|
||||||
|
active: moveGizmo.visible
|
||||||
|
|
||||||
onPositionCommit: moveGizmo.positionCommit()
|
onPositionCommit: moveGizmo.positionCommit()
|
||||||
onPositionMove: moveGizmo.positionMove()
|
onPositionMove: moveGizmo.positionMove()
|
||||||
@@ -61,9 +62,10 @@ Node {
|
|||||||
objectName: "Arrow Y"
|
objectName: "Arrow Y"
|
||||||
rotation: Qt.vector3d(0, 0, 0)
|
rotation: Qt.vector3d(0, 0, 0)
|
||||||
targetNode: moveGizmo.targetNode
|
targetNode: moveGizmo.targetNode
|
||||||
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0, 1, 1))
|
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0.6, 0, 1))
|
||||||
: Qt.rgba(0, 0, 1, 1)
|
: Qt.rgba(0, 0.6, 0, 1)
|
||||||
view3D: moveGizmo.view3D
|
view3D: moveGizmo.view3D
|
||||||
|
active: moveGizmo.visible
|
||||||
|
|
||||||
onPositionCommit: moveGizmo.positionCommit()
|
onPositionCommit: moveGizmo.positionCommit()
|
||||||
onPositionMove: moveGizmo.positionMove()
|
onPositionMove: moveGizmo.positionMove()
|
||||||
@@ -74,9 +76,10 @@ Node {
|
|||||||
objectName: "Arrow Z"
|
objectName: "Arrow Z"
|
||||||
rotation: Qt.vector3d(90, 0, 0)
|
rotation: Qt.vector3d(90, 0, 0)
|
||||||
targetNode: moveGizmo.targetNode
|
targetNode: moveGizmo.targetNode
|
||||||
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0.6, 0, 1))
|
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0, 1, 1))
|
||||||
: Qt.rgba(0, 0.6, 0, 1)
|
: Qt.rgba(0, 0, 1, 1)
|
||||||
view3D: moveGizmo.view3D
|
view3D: moveGizmo.view3D
|
||||||
|
active: moveGizmo.visible
|
||||||
|
|
||||||
onPositionCommit: moveGizmo.positionCommit()
|
onPositionCommit: moveGizmo.positionCommit()
|
||||||
onPositionMove: moveGizmo.positionMove()
|
onPositionMove: moveGizmo.positionMove()
|
||||||
@@ -108,13 +111,14 @@ Node {
|
|||||||
rotation: view3D.camera.rotation
|
rotation: view3D.camera.rotation
|
||||||
grabsMouse: moveGizmo.targetNode
|
grabsMouse: moveGizmo.targetNode
|
||||||
priority: 1
|
priority: 1
|
||||||
|
active: moveGizmo.visible
|
||||||
|
|
||||||
property var _pointerPosPressed
|
property var _pointerPosPressed
|
||||||
property var _targetStartPos
|
property var _targetStartPos
|
||||||
|
|
||||||
function posInParent(pointerPosition)
|
function localPos(scenePos)
|
||||||
{
|
{
|
||||||
var scenePointerPos = mapPositionToScene(pointerPosition);
|
var scenePointerPos = mapPositionToScene(scenePos);
|
||||||
var sceneRelativeDistance = Qt.vector3d(
|
var sceneRelativeDistance = Qt.vector3d(
|
||||||
scenePointerPos.x - _pointerPosPressed.x,
|
scenePointerPos.x - _pointerPosPressed.x,
|
||||||
scenePointerPos.y - _pointerPosPressed.y,
|
scenePointerPos.y - _pointerPosPressed.y,
|
||||||
@@ -132,7 +136,7 @@ Node {
|
|||||||
if (!moveGizmo.targetNode)
|
if (!moveGizmo.targetNode)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_pointerPosPressed = mapPositionToScene(pointerPosition);
|
_pointerPosPressed = mapPositionToScene(scenePos);
|
||||||
var sp = moveGizmo.targetNode.scenePosition;
|
var sp = moveGizmo.targetNode.scenePosition;
|
||||||
_targetStartPos = Qt.vector3d(sp.x, sp.y, sp.z);
|
_targetStartPos = Qt.vector3d(sp.x, sp.y, sp.z);
|
||||||
}
|
}
|
||||||
@@ -140,14 +144,14 @@ Node {
|
|||||||
if (!moveGizmo.targetNode)
|
if (!moveGizmo.targetNode)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
moveGizmo.targetNode.position = posInParent(pointerPosition);
|
moveGizmo.targetNode.position = localPos(scenePos);
|
||||||
moveGizmo.positionMove();
|
moveGizmo.positionMove();
|
||||||
}
|
}
|
||||||
onReleased: {
|
onReleased: {
|
||||||
if (!moveGizmo.targetNode)
|
if (!moveGizmo.targetNode)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
moveGizmo.targetNode.position = posInParent(pointerPosition);
|
moveGizmo.targetNode.position = localPos(scenePos);
|
||||||
moveGizmo.positionCommit();
|
moveGizmo.positionCommit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
159
share/qtcreator/qml/qmlpuppet/mockfiles/ScaleGizmo.qml
Normal file
159
share/qtcreator/qml/qmlpuppet/mockfiles/ScaleGizmo.qml
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtQuick3D 1.0
|
||||||
|
import MouseArea3D 1.0
|
||||||
|
|
||||||
|
Node {
|
||||||
|
id: scaleGizmo
|
||||||
|
|
||||||
|
property View3D view3D
|
||||||
|
property bool highlightOnHover: false
|
||||||
|
property Node targetNode: null
|
||||||
|
property bool globalOrientation: true
|
||||||
|
readonly property bool dragging: scaleRodX.dragging || scaleRodY.dragging || scaleRodZ.dragging
|
||||||
|
|| centerMouseArea.dragging
|
||||||
|
|
||||||
|
signal scaleCommit()
|
||||||
|
signal scaleChange()
|
||||||
|
|
||||||
|
Node {
|
||||||
|
rotation: globalOrientation || !targetNode ? Qt.vector3d(0, 0, 0) : targetNode.sceneRotation
|
||||||
|
|
||||||
|
ScaleRod {
|
||||||
|
id: scaleRodX
|
||||||
|
objectName: "scaleRod X"
|
||||||
|
rotation: Qt.vector3d(0, 0, -90)
|
||||||
|
targetNode: scaleGizmo.targetNode
|
||||||
|
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(1, 0, 0, 1))
|
||||||
|
: Qt.rgba(1, 0, 0, 1)
|
||||||
|
view3D: scaleGizmo.view3D
|
||||||
|
active: scaleGizmo.visible
|
||||||
|
|
||||||
|
onScaleCommit: scaleGizmo.scaleCommit()
|
||||||
|
onScaleChange: scaleGizmo.scaleChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
ScaleRod {
|
||||||
|
id: scaleRodY
|
||||||
|
objectName: "scaleRod Y"
|
||||||
|
rotation: Qt.vector3d(0, 0, 0)
|
||||||
|
targetNode: scaleGizmo.targetNode
|
||||||
|
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0.6, 0, 1))
|
||||||
|
: Qt.rgba(0, 0.6, 0, 1)
|
||||||
|
view3D: scaleGizmo.view3D
|
||||||
|
active: scaleGizmo.visible
|
||||||
|
|
||||||
|
onScaleCommit: scaleGizmo.scaleCommit()
|
||||||
|
onScaleChange: scaleGizmo.scaleChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
ScaleRod {
|
||||||
|
id: scaleRodZ
|
||||||
|
objectName: "scaleRod Z"
|
||||||
|
rotation: Qt.vector3d(90, 0, 0)
|
||||||
|
targetNode: scaleGizmo.targetNode
|
||||||
|
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0, 1, 1))
|
||||||
|
: Qt.rgba(0, 0, 1, 1)
|
||||||
|
view3D: scaleGizmo.view3D
|
||||||
|
active: scaleGizmo.visible
|
||||||
|
|
||||||
|
onScaleCommit: scaleGizmo.scaleCommit()
|
||||||
|
onScaleChange: scaleGizmo.scaleChange()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Model {
|
||||||
|
id: centerCube
|
||||||
|
|
||||||
|
source: "#Cube"
|
||||||
|
scale: Qt.vector3d(0.024, 0.024, 0.024)
|
||||||
|
materials: DefaultMaterial {
|
||||||
|
id: material
|
||||||
|
emissiveColor: highlightOnHover
|
||||||
|
&& (centerMouseArea.hovering || centerMouseArea.dragging)
|
||||||
|
? Qt.lighter(Qt.rgba(0.5, 0.5, 0.5, 1))
|
||||||
|
: Qt.rgba(0.5, 0.5, 0.5, 1)
|
||||||
|
lighting: DefaultMaterial.NoLighting
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea3D {
|
||||||
|
id: centerMouseArea
|
||||||
|
view3D: scaleGizmo.view3D
|
||||||
|
x: -60
|
||||||
|
y: -60
|
||||||
|
width: 120
|
||||||
|
height: 120
|
||||||
|
rotation: view3D.camera.rotation
|
||||||
|
grabsMouse: scaleGizmo.targetNode
|
||||||
|
priority: 1
|
||||||
|
active: scaleGizmo.visible
|
||||||
|
|
||||||
|
property var _startScale
|
||||||
|
property var _startScreenPos
|
||||||
|
|
||||||
|
function localScale(screenPos)
|
||||||
|
{
|
||||||
|
var yDelta = screenPos.y - _startScreenPos.y;
|
||||||
|
if (yDelta === 0)
|
||||||
|
return;
|
||||||
|
var scaler = 1.0 + (yDelta * 0.025);
|
||||||
|
if (scaler === 0 )
|
||||||
|
scaler = 0.0001;
|
||||||
|
if (scaler < 0)
|
||||||
|
scaler = -scaler;
|
||||||
|
return Qt.vector3d(scaler * _startScale.x,
|
||||||
|
scaler * _startScale.y,
|
||||||
|
scaler * _startScale.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
if (!scaleGizmo.targetNode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Recreate vector so we don't follow the changes in targetNode.scale
|
||||||
|
_startScale = Qt.vector3d(scaleGizmo.targetNode.scale.x,
|
||||||
|
scaleGizmo.targetNode.scale.y,
|
||||||
|
scaleGizmo.targetNode.scale.z);
|
||||||
|
_startScreenPos = screenPos;
|
||||||
|
}
|
||||||
|
onDragged: {
|
||||||
|
if (!scaleGizmo.targetNode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
scaleGizmo.targetNode.scale = localScale(screenPos);
|
||||||
|
scaleGizmo.scaleChange();
|
||||||
|
}
|
||||||
|
onReleased: {
|
||||||
|
if (!scaleGizmo.targetNode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
scaleGizmo.targetNode.scale = localScale(screenPos);
|
||||||
|
scaleGizmo.scaleCommit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
72
share/qtcreator/qml/qmlpuppet/mockfiles/ScaleRod.qml
Normal file
72
share/qtcreator/qml/qmlpuppet/mockfiles/ScaleRod.qml
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtQuick3D 1.0
|
||||||
|
import MouseArea3D 1.0
|
||||||
|
|
||||||
|
DirectionalDraggable {
|
||||||
|
id: scaleRod
|
||||||
|
source: "meshes/scalerod.mesh"
|
||||||
|
|
||||||
|
signal scaleCommit()
|
||||||
|
signal scaleChange()
|
||||||
|
|
||||||
|
property var _startScale
|
||||||
|
|
||||||
|
Model {
|
||||||
|
source: "#Cube"
|
||||||
|
y: 10
|
||||||
|
scale: Qt.vector3d(0.025, 0.025, 0.025)
|
||||||
|
materials: DefaultMaterial {
|
||||||
|
id: material
|
||||||
|
emissiveColor: scaleRod.color
|
||||||
|
lighting: DefaultMaterial.NoLighting
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function localScale(mouseArea, sceneRelativeDistance)
|
||||||
|
{
|
||||||
|
return mouseArea.getNewScale(targetNode, _startScale, _pointerPosPressed,
|
||||||
|
sceneRelativeDistance, sceneScale.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
// Recreate vector so we don't follow the changes in targetNode.sceneScale
|
||||||
|
_startScale = Qt.vector3d(targetNode.sceneScale.x,
|
||||||
|
targetNode.sceneScale.y,
|
||||||
|
targetNode.sceneScale.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
onDragged: {
|
||||||
|
targetNode.scale = localScale(mouseArea, sceneRelativeDistance);
|
||||||
|
scaleChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
onReleased: {
|
||||||
|
targetNode.scale = localScale(mouseArea, sceneRelativeDistance);
|
||||||
|
scaleCommit();
|
||||||
|
}
|
||||||
|
}
|
BIN
share/qtcreator/qml/qmlpuppet/mockfiles/meshes/scalerod.mesh
Normal file
BIN
share/qtcreator/qml/qmlpuppet/mockfiles/meshes/scalerod.mesh
Normal file
Binary file not shown.
@@ -60,6 +60,11 @@ bool MouseArea3D::grabsMouse() const
|
|||||||
return m_grabsMouse;
|
return m_grabsMouse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MouseArea3D::active() const
|
||||||
|
{
|
||||||
|
return m_active;
|
||||||
|
}
|
||||||
|
|
||||||
qreal MouseArea3D::x() const
|
qreal MouseArea3D::x() const
|
||||||
{
|
{
|
||||||
return m_x;
|
return m_x;
|
||||||
@@ -103,6 +108,15 @@ void MouseArea3D::setGrabsMouse(bool grabsMouse)
|
|||||||
emit grabsMouseChanged(grabsMouse);
|
emit grabsMouseChanged(grabsMouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MouseArea3D::setActive(bool active)
|
||||||
|
{
|
||||||
|
if (m_active == active)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_active = active;
|
||||||
|
emit activeChanged(active);
|
||||||
|
}
|
||||||
|
|
||||||
void MouseArea3D::setX(qreal x)
|
void MouseArea3D::setX(qreal x)
|
||||||
{
|
{
|
||||||
if (qFuzzyCompare(m_x, x))
|
if (qFuzzyCompare(m_x, x))
|
||||||
@@ -190,6 +204,73 @@ QVector3D MouseArea3D::rayIntersectsPlane(const QVector3D &rayPos0,
|
|||||||
return rayPos0 + distanceFromRayPos0ToPlane * rayDirection;
|
return rayPos0 + distanceFromRayPos0ToPlane * rayDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get a new scale based on a relative scene distance along an axis (used to adjust scale via drag)
|
||||||
|
// This function never returns a negative scaling
|
||||||
|
QVector3D MouseArea3D::getNewScale(QQuick3DNode *node, const QVector3D &startScale,
|
||||||
|
const QVector3D &pressPos,
|
||||||
|
const QVector3D &sceneRelativeDistance, float scaler)
|
||||||
|
{
|
||||||
|
if (node) {
|
||||||
|
// Note: This only returns correct scale when scale is positive
|
||||||
|
auto getScale = [&](const QMatrix4x4 &m) -> QVector3D {
|
||||||
|
return QVector3D(m.column(0).length(), m.column(1).length(), m.column(2).length());
|
||||||
|
};
|
||||||
|
const float constantDragScaler = 0.1f;
|
||||||
|
const float nonZeroValue = 0.0001f;
|
||||||
|
|
||||||
|
if (qFuzzyIsNull(scaler))
|
||||||
|
scaler = nonZeroValue;
|
||||||
|
|
||||||
|
const QVector3D scenePos = node->scenePosition();
|
||||||
|
const QMatrix4x4 parentTransform = node->parentNode()->sceneTransform();
|
||||||
|
QMatrix4x4 newTransform = node->sceneTransform();
|
||||||
|
QVector3D normalRelDist = sceneRelativeDistance.normalized();
|
||||||
|
float direction = QVector3D::dotProduct((pressPos - scenePos).normalized(), normalRelDist);
|
||||||
|
float magnitude = constantDragScaler * sceneRelativeDistance.length() / scaler;
|
||||||
|
|
||||||
|
// Reset everything but rotation to ensure translation and scale do not affect rotate below
|
||||||
|
newTransform(0,3) = 0;
|
||||||
|
newTransform(1,3) = 0;
|
||||||
|
newTransform(2,3) = 0;
|
||||||
|
QVector3D curScale = getScale(newTransform);
|
||||||
|
if (qFuzzyIsNull(curScale.x()))
|
||||||
|
curScale.setX(nonZeroValue);
|
||||||
|
if (qFuzzyIsNull(curScale.y()))
|
||||||
|
curScale.setY(nonZeroValue);
|
||||||
|
if (qFuzzyIsNull(curScale.z()))
|
||||||
|
curScale.setZ(nonZeroValue);
|
||||||
|
newTransform.scale({1.f / curScale.x(), 1.f / curScale.y(), 1.f / curScale.z()});
|
||||||
|
|
||||||
|
// Rotate relative distance according to object rotation
|
||||||
|
normalRelDist = newTransform.inverted().map(normalRelDist).normalized();
|
||||||
|
|
||||||
|
// Ensure scaling is always positive/negative according to direction
|
||||||
|
normalRelDist.setX(qAbs(normalRelDist.x()));
|
||||||
|
normalRelDist.setY(qAbs(normalRelDist.y()));
|
||||||
|
normalRelDist.setZ(qAbs(normalRelDist.z()));
|
||||||
|
QVector3D scaleVec = normalRelDist;
|
||||||
|
scaleVec *= magnitude;
|
||||||
|
if (direction > 0) {
|
||||||
|
scaleVec.setX(scaleVec.x() + 1.f);
|
||||||
|
scaleVec.setY(scaleVec.y() + 1.f);
|
||||||
|
scaleVec.setZ(scaleVec.z() + 1.f);
|
||||||
|
} else {
|
||||||
|
scaleVec.setX(1.f - scaleVec.x());
|
||||||
|
scaleVec.setY(1.f - scaleVec.y());
|
||||||
|
scaleVec.setZ(1.f - scaleVec.z());
|
||||||
|
}
|
||||||
|
scaleVec *= startScale;
|
||||||
|
|
||||||
|
newTransform = parentTransform;
|
||||||
|
newTransform.scale(scaleVec);
|
||||||
|
|
||||||
|
const QMatrix4x4 localTransform = parentTransform.inverted() * newTransform;
|
||||||
|
return getScale(localTransform);
|
||||||
|
}
|
||||||
|
|
||||||
|
return startScale;
|
||||||
|
}
|
||||||
|
|
||||||
QVector3D MouseArea3D::getMousePosInPlane(const QPointF &mousePosInView) const
|
QVector3D MouseArea3D::getMousePosInPlane(const QPointF &mousePosInView) const
|
||||||
{
|
{
|
||||||
const QVector3D mousePos1(float(mousePosInView.x()), float(mousePosInView.y()), 0);
|
const QVector3D mousePos1(float(mousePosInView.x()), float(mousePosInView.y()), 0);
|
||||||
@@ -207,8 +288,8 @@ QVector3D MouseArea3D::getMousePosInPlane(const QPointF &mousePosInView) const
|
|||||||
|
|
||||||
bool MouseArea3D::eventFilter(QObject *, QEvent *event)
|
bool MouseArea3D::eventFilter(QObject *, QEvent *event)
|
||||||
{
|
{
|
||||||
if (m_grabsMouse && s_mouseGrab && s_mouseGrab != this
|
if (!m_active || (m_grabsMouse && s_mouseGrab && s_mouseGrab != this
|
||||||
&& (m_priority <= s_mouseGrab->m_priority || s_mouseGrab->m_dragging)) {
|
&& (m_priority <= s_mouseGrab->m_priority || s_mouseGrab->m_dragging))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,7 +308,7 @@ bool MouseArea3D::eventFilter(QObject *, QEvent *event)
|
|||||||
m_mousePosInPlane = getMousePosInPlane(mouseEvent->pos());
|
m_mousePosInPlane = getMousePosInPlane(mouseEvent->pos());
|
||||||
if (mouseOnTopOfMouseArea(m_mousePosInPlane)) {
|
if (mouseOnTopOfMouseArea(m_mousePosInPlane)) {
|
||||||
setDragging(true);
|
setDragging(true);
|
||||||
emit pressed(m_mousePosInPlane);
|
emit pressed(m_mousePosInPlane, mouseEvent->globalPos());
|
||||||
if (m_grabsMouse) {
|
if (m_grabsMouse) {
|
||||||
if (s_mouseGrab && s_mouseGrab != this) {
|
if (s_mouseGrab && s_mouseGrab != this) {
|
||||||
s_mouseGrab->setDragging(false);
|
s_mouseGrab->setDragging(false);
|
||||||
@@ -250,7 +331,7 @@ bool MouseArea3D::eventFilter(QObject *, QEvent *event)
|
|||||||
if (qFuzzyCompare(mousePosInPlane.z(), -1))
|
if (qFuzzyCompare(mousePosInPlane.z(), -1))
|
||||||
mousePosInPlane = m_mousePosInPlane;
|
mousePosInPlane = m_mousePosInPlane;
|
||||||
setDragging(false);
|
setDragging(false);
|
||||||
emit released(mousePosInPlane);
|
emit released(mousePosInPlane, mouseEvent->globalPos());
|
||||||
if (m_grabsMouse) {
|
if (m_grabsMouse) {
|
||||||
if (s_mouseGrab && s_mouseGrab != this) {
|
if (s_mouseGrab && s_mouseGrab != this) {
|
||||||
s_mouseGrab->setDragging(false);
|
s_mouseGrab->setDragging(false);
|
||||||
@@ -290,7 +371,7 @@ bool MouseArea3D::eventFilter(QObject *, QEvent *event)
|
|||||||
|
|
||||||
if (m_dragging && !qFuzzyCompare(mousePosInPlane.z(), -1)) {
|
if (m_dragging && !qFuzzyCompare(mousePosInPlane.z(), -1)) {
|
||||||
m_mousePosInPlane = mousePosInPlane;
|
m_mousePosInPlane = mousePosInPlane;
|
||||||
emit dragged(mousePosInPlane);
|
emit dragged(mousePosInPlane, mouseEvent->globalPos());
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@@ -49,6 +49,7 @@ class MouseArea3D : public QQuick3DNode
|
|||||||
Q_PROPERTY(bool hovering READ hovering NOTIFY hoveringChanged)
|
Q_PROPERTY(bool hovering READ hovering NOTIFY hoveringChanged)
|
||||||
Q_PROPERTY(bool dragging READ dragging NOTIFY draggingChanged)
|
Q_PROPERTY(bool dragging READ dragging NOTIFY draggingChanged)
|
||||||
Q_PROPERTY(int priority READ priority WRITE setPriority NOTIFY priorityChanged)
|
Q_PROPERTY(int priority READ priority WRITE setPriority NOTIFY priorityChanged)
|
||||||
|
Q_PROPERTY(int active READ active WRITE setActive NOTIFY activeChanged)
|
||||||
|
|
||||||
Q_INTERFACES(QQmlParserStatus)
|
Q_INTERFACES(QQmlParserStatus)
|
||||||
|
|
||||||
@@ -66,10 +67,12 @@ public:
|
|||||||
bool hovering() const;
|
bool hovering() const;
|
||||||
bool dragging() const;
|
bool dragging() const;
|
||||||
bool grabsMouse() const;
|
bool grabsMouse() const;
|
||||||
|
bool active() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setView3D(QQuick3DViewport *view3D);
|
void setView3D(QQuick3DViewport *view3D);
|
||||||
void setGrabsMouse(bool grabsMouse);
|
void setGrabsMouse(bool grabsMouse);
|
||||||
|
void setActive(bool active);
|
||||||
|
|
||||||
void setX(qreal x);
|
void setX(qreal x);
|
||||||
void setY(qreal y);
|
void setY(qreal y);
|
||||||
@@ -82,6 +85,10 @@ public slots:
|
|||||||
const QVector3D &planePos,
|
const QVector3D &planePos,
|
||||||
const QVector3D &planeNormal) const;
|
const QVector3D &planeNormal) const;
|
||||||
|
|
||||||
|
Q_INVOKABLE QVector3D getNewScale(QQuick3DNode *node, const QVector3D &startScale,
|
||||||
|
const QVector3D &pressPos,
|
||||||
|
const QVector3D &sceneRelativeDistance, float scaler);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void view3DChanged();
|
void view3DChanged();
|
||||||
|
|
||||||
@@ -93,9 +100,10 @@ signals:
|
|||||||
|
|
||||||
void hoveringChanged();
|
void hoveringChanged();
|
||||||
void draggingChanged();
|
void draggingChanged();
|
||||||
void pressed(const QVector3D &pointerPosition);
|
void activeChanged(bool active);
|
||||||
void released(const QVector3D &pointerPosition);
|
void pressed(const QVector3D &scenePos, const QPoint &screenPos);
|
||||||
void dragged(const QVector3D &pointerPosition);
|
void released(const QVector3D &scenePos, const QPoint &screenPos);
|
||||||
|
void dragged(const QVector3D &scenePos, const QPoint &screenPos);
|
||||||
void grabsMouseChanged(bool grabsMouse);
|
void grabsMouseChanged(bool grabsMouse);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -118,6 +126,7 @@ private:
|
|||||||
|
|
||||||
bool m_hovering = false;
|
bool m_hovering = false;
|
||||||
bool m_dragging = false;
|
bool m_dragging = false;
|
||||||
|
bool m_active = false;
|
||||||
|
|
||||||
QVector3D getMousePosInPlane(const QPointF &mousePosInView) const;
|
QVector3D getMousePosInPlane(const QPointF &mousePosInView) const;
|
||||||
|
|
||||||
|
@@ -97,12 +97,12 @@ QObject *Qt5InformationNodeInstanceServer::createEditView3D(QQmlEngine *engine)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QObject::connect(window, SIGNAL(objectClicked(QVariant)), this, SLOT(objectClicked(QVariant)));
|
QObject::connect(window, SIGNAL(objectClicked(QVariant)), this, SLOT(objectClicked(QVariant)));
|
||||||
QObject::connect(window, SIGNAL(commitObjectPosition(QVariant)),
|
QObject::connect(window, SIGNAL(commitObjectProperty(QVariant, QVariant)),
|
||||||
this, SLOT(handleObjectPositionCommit(QVariant)));
|
this, SLOT(handleObjectPropertyCommit(QVariant, QVariant)));
|
||||||
QObject::connect(window, SIGNAL(moveObjectPosition(QVariant)),
|
QObject::connect(window, SIGNAL(changeObjectProperty(QVariant, QVariant)),
|
||||||
this, SLOT(handleObjectPositionMove(QVariant)));
|
this, SLOT(handleObjectPropertyChange(QVariant, QVariant)));
|
||||||
QObject::connect(&m_moveTimer, &QTimer::timeout,
|
QObject::connect(&m_propertyChangeTimer, &QTimer::timeout,
|
||||||
this, &Qt5InformationNodeInstanceServer::handleObjectPositionMoveTimeout);
|
this, &Qt5InformationNodeInstanceServer::handleObjectPropertyChangeTimeout);
|
||||||
|
|
||||||
//For macOS we have to use the 4.1 core profile
|
//For macOS we have to use the 4.1 core profile
|
||||||
QSurfaceFormat surfaceFormat = window->requestedFormat();
|
QSurfaceFormat surfaceFormat = window->requestedFormat();
|
||||||
@@ -188,28 +188,36 @@ void Qt5InformationNodeInstanceServer::modifyVariantValue(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Qt5InformationNodeInstanceServer::handleObjectPositionCommit(const QVariant &object)
|
void Qt5InformationNodeInstanceServer::handleObjectPropertyCommit(const QVariant &object,
|
||||||
|
const QVariant &propName)
|
||||||
{
|
{
|
||||||
modifyVariantValue(object, "position", ValuesModifiedCommand::TransactionOption::End);
|
modifyVariantValue(object, propName.toByteArray(),
|
||||||
m_movedNode = {};
|
ValuesModifiedCommand::TransactionOption::End);
|
||||||
m_moveTimer.stop();
|
m_changedNode = {};
|
||||||
|
m_changedProperty = {};
|
||||||
|
m_propertyChangeTimer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Qt5InformationNodeInstanceServer::handleObjectPositionMove(const QVariant &object)
|
void Qt5InformationNodeInstanceServer::handleObjectPropertyChange(const QVariant &object,
|
||||||
|
const QVariant &propName)
|
||||||
{
|
{
|
||||||
if (m_movedNode.isNull()) {
|
PropertyName propertyName(propName.toByteArray());
|
||||||
modifyVariantValue(object, "position", ValuesModifiedCommand::TransactionOption::Start);
|
if (m_changedProperty != propertyName || m_changedNode != object) {
|
||||||
} else {
|
if (!m_changedNode.isNull())
|
||||||
if (!m_moveTimer.isActive())
|
handleObjectPropertyCommit(m_changedNode, m_changedProperty);
|
||||||
m_moveTimer.start();
|
modifyVariantValue(object, propertyName,
|
||||||
|
ValuesModifiedCommand::TransactionOption::Start);
|
||||||
|
} else if (!m_propertyChangeTimer.isActive()) {
|
||||||
|
m_propertyChangeTimer.start();
|
||||||
}
|
}
|
||||||
m_movedNode = object;
|
m_changedNode = object;
|
||||||
|
m_changedProperty = propertyName;
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt5InformationNodeInstanceServer::Qt5InformationNodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient) :
|
Qt5InformationNodeInstanceServer::Qt5InformationNodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient) :
|
||||||
Qt5NodeInstanceServer(nodeInstanceClient)
|
Qt5NodeInstanceServer(nodeInstanceClient)
|
||||||
{
|
{
|
||||||
m_moveTimer.setInterval(100);
|
m_propertyChangeTimer.setInterval(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Qt5InformationNodeInstanceServer::sendTokenBack()
|
void Qt5InformationNodeInstanceServer::sendTokenBack()
|
||||||
@@ -282,9 +290,10 @@ void Qt5InformationNodeInstanceServer::modifyProperties(
|
|||||||
nodeInstanceClient()->valuesModified(createValuesModifiedCommand(properties));
|
nodeInstanceClient()->valuesModified(createValuesModifiedCommand(properties));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Qt5InformationNodeInstanceServer::handleObjectPositionMoveTimeout()
|
void Qt5InformationNodeInstanceServer::handleObjectPropertyChangeTimeout()
|
||||||
{
|
{
|
||||||
modifyVariantValue(m_movedNode, "position", ValuesModifiedCommand::TransactionOption::None);
|
modifyVariantValue(m_changedNode, m_changedProperty,
|
||||||
|
ValuesModifiedCommand::TransactionOption::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
QObject *Qt5InformationNodeInstanceServer::findRootNodeOf3DViewport(
|
QObject *Qt5InformationNodeInstanceServer::findRootNodeOf3DViewport(
|
||||||
|
@@ -51,8 +51,8 @@ public:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void objectClicked(const QVariant &object);
|
void objectClicked(const QVariant &object);
|
||||||
void handleObjectPositionCommit(const QVariant &object);
|
void handleObjectPropertyCommit(const QVariant &object, const QVariant &propName);
|
||||||
void handleObjectPositionMove(const QVariant &object);
|
void handleObjectPropertyChange(const QVariant &object, const QVariant &propName);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void collectItemChangesAndSendChangeCommands() override;
|
void collectItemChangesAndSendChangeCommands() override;
|
||||||
@@ -64,7 +64,7 @@ protected:
|
|||||||
void modifyProperties(const QVector<InstancePropertyValueTriple> &properties);
|
void modifyProperties(const QVector<InstancePropertyValueTriple> &properties);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handleObjectPositionMoveTimeout();
|
void handleObjectPropertyChangeTimeout();
|
||||||
QObject *createEditView3D(QQmlEngine *engine);
|
QObject *createEditView3D(QQmlEngine *engine);
|
||||||
void setup3DEditView(const QList<ServerNodeInstance> &instanceList);
|
void setup3DEditView(const QList<ServerNodeInstance> &instanceList);
|
||||||
QObject *findRootNodeOf3DViewport(const QList<ServerNodeInstance> &instanceList) const;
|
QObject *findRootNodeOf3DViewport(const QList<ServerNodeInstance> &instanceList) const;
|
||||||
@@ -81,8 +81,9 @@ private:
|
|||||||
QSet<ServerNodeInstance> m_parentChangedSet;
|
QSet<ServerNodeInstance> m_parentChangedSet;
|
||||||
QList<ServerNodeInstance> m_completedComponentList;
|
QList<ServerNodeInstance> m_completedComponentList;
|
||||||
QList<TokenCommand> m_tokenList;
|
QList<TokenCommand> m_tokenList;
|
||||||
QTimer m_moveTimer;
|
QTimer m_propertyChangeTimer;
|
||||||
QVariant m_movedNode;
|
QVariant m_changedNode;
|
||||||
|
PropertyName m_changedProperty;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -15,7 +15,11 @@
|
|||||||
<file>mockfiles/LightGizmo.qml</file>
|
<file>mockfiles/LightGizmo.qml</file>
|
||||||
<file>mockfiles/IconGizmo.qml</file>
|
<file>mockfiles/IconGizmo.qml</file>
|
||||||
<file>mockfiles/Overlay2D.qml</file>
|
<file>mockfiles/Overlay2D.qml</file>
|
||||||
|
<file>mockfiles/DirectionalDraggable.qml</file>
|
||||||
|
<file>mockfiles/ScaleRod.qml</file>
|
||||||
|
<file>mockfiles/ScaleGizmo.qml</file>
|
||||||
<file>mockfiles/meshes/arrow.mesh</file>
|
<file>mockfiles/meshes/arrow.mesh</file>
|
||||||
|
<file>mockfiles/meshes/scalerod.mesh</file>
|
||||||
<file>mockfiles/images/camera-pick-icon.png</file>
|
<file>mockfiles/images/camera-pick-icon.png</file>
|
||||||
<file>mockfiles/images/camera-pick-icon@2x.png</file>
|
<file>mockfiles/images/camera-pick-icon@2x.png</file>
|
||||||
<file>mockfiles/images/light-pick-icon.png</file>
|
<file>mockfiles/images/light-pick-icon.png</file>
|
||||||
|
Reference in New Issue
Block a user