diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/AutoScaleHelper.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/AutoScaleHelper.qml index c16c47ddd79..41951d8e13f 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/AutoScaleHelper.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/AutoScaleHelper.qml @@ -31,15 +31,14 @@ Node { id: overlayNode property View3D view3D - property Node target: parent - property bool autoScale: true property Camera camera: view3D.camera + property bool active: true // Read-only property real relativeScale: 1 + onActiveChanged: updateScale() onSceneTransformChanged: updateScale() - onAutoScaleChanged: updateScale() // Trigger delayed update on camera change to ensure camera values are correct onCameraChanged: _generalHelper.requestOverlayUpdate(); @@ -61,11 +60,10 @@ Node { function updateScale() { - if (!autoScale) { - target.scale = Qt.vector3d(1, 1, 1); - } else { + if (active) relativeScale = helper.getRelativeScale(overlayNode); - } + else + relativeScale = 1; } MouseArea3D { diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/DirectionalDraggable.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/DirectionalDraggable.qml index f1cf60045ff..1401333627c 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/DirectionalDraggable.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/DirectionalDraggable.qml @@ -38,6 +38,7 @@ Model { property MouseArea3D dragHelper: null property alias material: material property real length: 12 + property real offset: 0 readonly property bool hovering: mouseAreaYZ.hovering || mouseAreaXZ.hovering @@ -95,7 +96,7 @@ Model { MouseArea3D { id: mouseAreaYZ view3D: rootModel.view3D - x: 0 + x: rootModel.offset y: -1.5 width: rootModel.length height: 3 @@ -112,7 +113,7 @@ Model { MouseArea3D { id: mouseAreaXZ view3D: rootModel.view3D - x: 0 + x: rootModel.offset y: -1.5 width: rootModel.length height: 3 diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml index 9e11bd4e777..c9321790c15 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml @@ -457,8 +457,8 @@ Item { view3D: overlayView dragHelper: gizmoDragHelper - onBrightnessCommit: viewRoot.commitObjectProperty(viewRoot.selectedNode, "brightness") - onBrightnessChange: viewRoot.changeObjectProperty(viewRoot.selectedNode, "brightness") + onPropertyValueCommit: viewRoot.commitObjectProperty(targetNode, propName) + onPropertyValueChange: viewRoot.changeObjectProperty(targetNode, propName) } AutoScaleHelper { diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/FadeHandle.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/FadeHandle.qml new file mode 100644 index 00000000000..76e52272c27 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/FadeHandle.qml @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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.15 + +DirectionalDraggable { + id: handleRoot + + property string currentLabel + property point currentMousePos + property real fadeScale + property real baseScale: 5 + + scale: autoScaler.getScale(Qt.vector3d(baseScale, baseScale, baseScale)) + length: 3 + offset: -1.5 + + Model { + id: handle + source: "#Sphere" + materials: [ handleRoot.material ] + scale: Qt.vector3d(0.02, 0.02, 0.02) + } + + AutoScaleHelper { + id: autoScaler + active: handleRoot.active + view3D: handleRoot.view3D + } + + property real _q // quadratic fade + property real _l // linear fade + property real _c // constant fade + property real _d: 20 // Divisor from fadeScale calc in lightGizmo + property real _startScale + property real _startFadeScale + property string _currentProp + + signal valueCommit(string propName) + signal valueChange(string propName) + + function updateFade(relativeDistance, screenPos) + { + // Solved from fadeScale equation in LightGizmo + var newValue = 0; + var _x = Math.max(0, (_startFadeScale - (relativeDistance * _startScale)) / 100); + + // Fades capped to range 0-10 because property editor caps them to that range + if (_currentProp === "quadraticFade") { + if (_x === 0) + newValue = 10; + else + newValue = Math.max(0, Math.min(10, -(_c - _d + (_l * _x)) / (_x * _x))); + if (newValue < 0.01) + newValue = 0; // To avoid having tiny positive value when UI shows 0.00 + targetNode.quadraticFade = newValue; + } else if (_currentProp === "linearFade") { + if (_x === 0) + newValue = 10; + else + newValue = Math.max(0, Math.min(10, -(_c - _d) / _x)); + if (newValue < 0.01) + newValue = 0; // To avoid having tiny positive value when UI shows 0.00 + targetNode.linearFade = newValue; + } else { + // Since pure constant fade equates to infinitely long cone, fadeScale calc assumes + // linear fade of one in this case. + newValue = Math.max(0, Math.min(10, _d - _x)); + targetNode.constantFade = newValue; + } + + var l = Qt.locale(); + handleRoot.currentLabel = _currentProp + qsTr(": ") + Number(newValue).toLocaleString(l, 'f', 2); + handleRoot.currentMousePos = screenPos; + } + + onPressed: { + _startScale = autoScaler.relativeScale * baseScale * 2; + _startFadeScale = fadeScale; + _l = targetNode.linearFade; + _c = targetNode.constantFade; + _q = targetNode.quadraticFade; + if (targetNode.quadraticFade === 0) { + if (targetNode.linearFade === 0) { + _currentProp = "constantFade"; + } else { + _currentProp = "linearFade"; + } + } else { + _currentProp = "quadraticFade"; + } + updateFade(0, screenPos); + } + + onDragged: { + updateFade(relativeDistance, screenPos); + handleRoot.valueChange(_currentProp); + } + + onReleased: { + updateFade(relativeDistance, screenPos); + handleRoot.valueCommit(_currentProp); + } +} diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/LightGizmo.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/LightGizmo.qml index 36c7c2cb38c..8ac93a85762 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/LightGizmo.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/LightGizmo.qml @@ -44,7 +44,7 @@ Node { var c = targetNode.constantFade; var d = 20; // divisor to target intensity value. E.g. 20 = 1/20 = 5% if (l === 0 && q === 0) - l = 1; + l = 1; // For pure constant fade, cone would be infinite, so pretend we have linear fade // Solved from equation in shader: // 1 / d = 1 / (c + (l + q * dist) * dist); if (q === 0) @@ -56,11 +56,14 @@ Node { } } readonly property bool dragging: primaryArrow.dragging + || spotLightHandle.dragging + || spotLightInnerHandle.dragging + || spotLightFadeHandle.dragging property point currentMousePos property string currentLabel - signal brightnessCommit() - signal brightnessChange() + signal propertyValueCommit(string propName) + signal propertyValueChange(string propName) position: targetNode ? targetNode.scenePosition : Qt.vector3d(0, 0, 0) visible: lightGizmo.targetNode instanceof SpotLight @@ -69,7 +72,7 @@ Node { || lightGizmo.targetNode instanceof PointLight AutoScaleHelper { - id: autoScale + id: autoScaler view3D: lightGizmo.view3D } @@ -89,44 +92,111 @@ Node { rotation: !lightGizmo.targetNode ? Qt.quaternion(1, 0, 0, 0) : lightGizmo.targetNode.sceneRotation - LightModel { - id: spotModel - - property real coneScale: visible - ? lightGizmo.fadeScale * Math.tan(Math.PI * targetNode.coneAngle / 180) - : 1 - - geometryName: "Edit 3D SpotLight" - geometryType: LightGeometry.Spot - material: lightMaterial - visible: lightGizmo.targetNode instanceof SpotLight - scale: Qt.vector3d(coneScale, coneScale, lightGizmo.fadeScale) - } Node { + id: spotParts visible: lightGizmo.targetNode instanceof SpotLight - SpotLightHandle { - id: sphereHandle1 - view3D: lightGizmo.view3D + + LightModel { + id: spotModel + + property real coneXYScale: spotParts.visible && lightGizmo.targetNode + ? lightGizmo.fadeScale * Math.tan(Math.PI * lightGizmo.targetNode.coneAngle / 180) + : 1 + + geometryName: "Edit 3D SpotLight Cone" + geometryType: LightGeometry.Spot material: lightMaterial - position: Qt.vector3d(0, spotModel.scale.y, -spotModel.scale.z) + scale: Qt.vector3d(coneXYScale, coneXYScale, + spotParts.visible && lightGizmo.targetNode && lightGizmo.targetNode.coneAngle > 90 + ? -lightGizmo.fadeScale : lightGizmo.fadeScale) } - SpotLightHandle { - id: sphereHandle2 - view3D: lightGizmo.view3D + + LightModel { + id: spotInnerModel + + property real coneXYScale: spotParts.visible && lightGizmo.targetNode + ? lightGizmo.fadeScale * Math.tan(Math.PI * lightGizmo.targetNode.innerConeAngle / 180) + : 1 + + geometryName: "Edit 3D SpotLight Inner Cone" + geometryType: LightGeometry.Spot material: lightMaterial - position: Qt.vector3d(spotModel.scale.x, 0, -spotModel.scale.z) + scale: Qt.vector3d(coneXYScale, coneXYScale, + spotParts.visible && lightGizmo.targetNode && lightGizmo.targetNode.innerConeAngle > 90 + ? -lightGizmo.fadeScale : lightGizmo.fadeScale) } + SpotLightHandle { - id: sphereHandle3 + id: spotLightHandle view3D: lightGizmo.view3D - material: lightMaterial - position: Qt.vector3d(0, -spotModel.scale.y, -spotModel.scale.z) + color: (hovering || dragging) ? Qt.rgba(1, 1, 1, 1) : lightGizmo.color + position: lightGizmo.targetNode instanceof SpotLight ? Qt.vector3d(0, spotModel.scale.y, -spotModel.scale.z) + : Qt.vector3d(0, 0, 0) + targetNode: lightGizmo.targetNode instanceof SpotLight ? lightGizmo.targetNode : null + active: lightGizmo.targetNode instanceof SpotLight + dragHelper: lightGizmo.dragHelper + propName: "coneAngle" + propValue: lightGizmo.targetNode instanceof SpotLight ? targetNode.coneAngle : 0 + + onNewValueChanged: targetNode.coneAngle = newValue + onCurrentMousePosChanged: { + lightGizmo.currentMousePos = currentMousePos; + lightGizmo.currentLabel = currentLabel; + } + onValueChange: lightGizmo.propertyValueChange(propName) + onValueCommit: { + if (targetNode.innerConeAngle > targetNode.coneAngle) + targetNode.innerConeAngle = targetNode.coneAngle; + lightGizmo.propertyValueCommit(propName) + lightGizmo.propertyValueCommit(spotLightInnerHandle.propName); + } } + SpotLightHandle { - id: sphereHandle4 + id: spotLightInnerHandle view3D: lightGizmo.view3D - material: lightMaterial - position: Qt.vector3d(-spotModel.scale.x, 0, -spotModel.scale.z) + color: (hovering || dragging) ? Qt.rgba(1, 1, 1, 1) : lightGizmo.color + position: lightGizmo.targetNode instanceof SpotLight ? Qt.vector3d(0, -spotInnerModel.scale.y, -spotInnerModel.scale.z) + : Qt.vector3d(0, 0, 0) + eulerRotation: Qt.vector3d(180, 0, 0) + targetNode: lightGizmo.targetNode instanceof SpotLight ? lightGizmo.targetNode : null + active: lightGizmo.targetNode instanceof SpotLight + dragHelper: lightGizmo.dragHelper + propName: "innerConeAngle" + propValue: lightGizmo.targetNode instanceof SpotLight ? targetNode.innerConeAngle : 0 + + onNewValueChanged: targetNode.innerConeAngle = newValue + onCurrentMousePosChanged: { + lightGizmo.currentMousePos = currentMousePos; + lightGizmo.currentLabel = currentLabel; + } + onValueChange: lightGizmo.propertyValueChange(propName) + onValueCommit: { + if (targetNode.coneAngle < targetNode.innerConeAngle) + targetNode.coneAngle = targetNode.innerConeAngle; + lightGizmo.propertyValueCommit(propName) + lightGizmo.propertyValueCommit(spotLightHandle.propName); + } + } + + FadeHandle { + id: spotLightFadeHandle + view3D: lightGizmo.view3D + color: (hovering || dragging) ? Qt.rgba(1, 1, 1, 1) : lightGizmo.color + position: lightGizmo.targetNode instanceof SpotLight ? Qt.vector3d(spotModel.scale.x / 2, 0, -spotInnerModel.scale.z / 2) + : Qt.vector3d(0, 0, 0) + eulerRotation: Qt.vector3d(90, 0, 0) + targetNode: lightGizmo.targetNode instanceof SpotLight ? lightGizmo.targetNode : null + active: lightGizmo.targetNode instanceof SpotLight + dragHelper: lightGizmo.dragHelper + fadeScale: lightGizmo.fadeScale + + onCurrentMousePosChanged: { + lightGizmo.currentMousePos = currentMousePos; + lightGizmo.currentLabel = currentLabel; + } + onValueChange: lightGizmo.propertyValueChange(propName) + onValueCommit: lightGizmo.propertyValueCommit(propName) } } @@ -148,7 +218,7 @@ Node { geometryType: LightGeometry.Directional material: lightMaterial visible: lightGizmo.targetNode instanceof DirectionalLight - scale: autoScale.getScale(Qt.vector3d(50, 50, 50)) + scale: autoScaler.getScale(Qt.vector3d(50, 50, 50)) } LightModel { @@ -168,7 +238,7 @@ Node { view3D: lightGizmo.view3D active: lightGizmo.visible dragHelper: lightGizmo.dragHelper - scale: autoScale.getScale(Qt.vector3d(5, 5, 5)) + scale: autoScaler.getScale(Qt.vector3d(5, 5, 5)) length: (lightGizmo.brightnessScale / 10) + 3 property real _startBrightness @@ -177,7 +247,7 @@ Node { { var currentValue = Math.round(Math.max(0, _startBrightness + relativeDistance * 10)); var l = Qt.locale(); - lightGizmo.currentLabel = qsTr("brightness: ") + Number(currentValue).toLocaleString(l, 'f', 0); + lightGizmo.currentLabel = "brightness" + qsTr(": ") + Number(currentValue).toLocaleString(l, 'f', 0); lightGizmo.currentMousePos = screenPos; targetNode.brightness = currentValue; } @@ -189,12 +259,12 @@ Node { onDragged: { updateBrightness(relativeDistance, screenPos); - lightGizmo.brightnessChange(); + lightGizmo.propertyValueChange("brightness"); } onReleased: { updateBrightness(relativeDistance, screenPos); - lightGizmo.brightnessCommit(); + lightGizmo.propertyValueCommit("brightness"); } } diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/SpotLightHandle.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/SpotLightHandle.qml index b50c7555df3..badef266b64 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/SpotLightHandle.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/SpotLightHandle.qml @@ -26,20 +26,57 @@ import QtQuick 2.0 import QtQuick3D 1.15 -Node { +DirectionalDraggable { id: handleRoot - property DefaultMaterial material - property View3D view3D + property string currentLabel + property point currentMousePos + property string propName + property real propValue: 0 + property real newValue: 0 + + scale: autoScaler.getScale(Qt.vector3d(5, 5, 5)) + length: 3 + offset: -1.5 Model { - scale: autoScale.getScale(Qt.vector3d(0.1, 0.1, 0.1)) + id: handle source: "#Sphere" materials: [ handleRoot.material ] + scale: Qt.vector3d(0.02, 0.02, 0.02) } AutoScaleHelper { - id: autoScale + id: autoScaler + active: handleRoot.active view3D: handleRoot.view3D } + + property real _startAngle + + signal valueCommit() + signal valueChange() + + function updateAngle(relativeDistance, screenPos) + { + handleRoot.newValue = Math.round(Math.min(180, Math.max(0, _startAngle + relativeDistance))); + var l = Qt.locale(); + handleRoot.currentLabel = propName + qsTr(": ") + Number(newValue).toLocaleString(l, 'f', 0); + handleRoot.currentMousePos = screenPos; + } + + onPressed: { + _startAngle = propValue; + updateAngle(0, screenPos); + } + + onDragged: { + updateAngle(relativeDistance, screenPos); + handleRoot.valueChange(); + } + + onReleased: { + updateAngle(relativeDistance, screenPos); + handleRoot.valueCommit(); + } } diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc b/share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc index 06883f61220..0519e2e82a0 100644 --- a/share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc @@ -53,5 +53,6 @@ mockfiles/images/point@2x.png mockfiles/images/spot.png mockfiles/images/spot@2x.png + mockfiles/FadeHandle.qml