forked from qt-creator/qt-creator
QmlDesigner: Don't display the camera, if it has no scene
Fixes: QDS-13490 Change-Id: I82bf07866f667dd39773f7e5e172ebd36c36e46e Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
@@ -24,6 +24,7 @@
|
|||||||
<file>mockfiles/qt6/AdjustableArrow.qml</file>
|
<file>mockfiles/qt6/AdjustableArrow.qml</file>
|
||||||
<file>mockfiles/qt6/Arrow.qml</file>
|
<file>mockfiles/qt6/Arrow.qml</file>
|
||||||
<file>mockfiles/qt6/AutoScaleHelper.qml</file>
|
<file>mockfiles/qt6/AutoScaleHelper.qml</file>
|
||||||
|
<file>mockfiles/qt6/CameraDisplay.qml</file>
|
||||||
<file>mockfiles/qt6/CameraFrustum.qml</file>
|
<file>mockfiles/qt6/CameraFrustum.qml</file>
|
||||||
<file>mockfiles/qt6/CameraGizmo.qml</file>
|
<file>mockfiles/qt6/CameraGizmo.qml</file>
|
||||||
<file>mockfiles/qt6/CameraView.qml</file>
|
<file>mockfiles/qt6/CameraView.qml</file>
|
||||||
|
82
src/tools/qml2puppet/mockfiles/qt6/CameraDisplay.qml
Normal file
82
src/tools/qml2puppet/mockfiles/qt6/CameraDisplay.qml
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
// Copyright (C) 2024 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick3D
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: cameraDisplay
|
||||||
|
|
||||||
|
required property Camera camera
|
||||||
|
required property size preferredSize
|
||||||
|
required property size viewPortSize
|
||||||
|
required property var activeScene
|
||||||
|
required property var activeSceneEnvironment
|
||||||
|
|
||||||
|
implicitWidth: view3D.dispSize.width
|
||||||
|
implicitHeight: view3D.dispSize.height
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
View3D {
|
||||||
|
id: view3D
|
||||||
|
|
||||||
|
readonly property bool isOrthographicCamera: _generalHelper.isOrthographicCamera(view3D.camera)
|
||||||
|
property size dispSize: calculateSize(cameraDisplay.viewPortSize, cameraDisplay.preferredSize)
|
||||||
|
readonly property real magnificationFactor: cameraDisplay.viewPortSize.width === 0
|
||||||
|
? 1.0
|
||||||
|
: (view3D.dispSize.width / cameraDisplay.viewPortSize.width)
|
||||||
|
|
||||||
|
transformOrigin: Item.Center
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
camera: cameraDisplay.camera
|
||||||
|
importScene: cameraDisplay.activeScene
|
||||||
|
environment: cameraDisplay.activeSceneEnvironment ?? defaultSceneEnvironment
|
||||||
|
|
||||||
|
function calculateSize(viewPortSize: size, preferredSize : size) {
|
||||||
|
if (_generalHelper.fuzzyCompare(viewPortSize.width, 0)
|
||||||
|
|| _generalHelper.fuzzyCompare(viewPortSize.height, 0)) {
|
||||||
|
return Qt.size(0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
let aspectRatio = viewPortSize.height / viewPortSize.width
|
||||||
|
var calculatedHeight = preferredSize.width * aspectRatio
|
||||||
|
if (calculatedHeight <= preferredSize.height)
|
||||||
|
return Qt.size(preferredSize.width, calculatedHeight)
|
||||||
|
|
||||||
|
var calculatedWidth = preferredSize.height / aspectRatio;
|
||||||
|
return Qt.size(calculatedWidth, preferredSize.height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneEnvironment {
|
||||||
|
id: defaultSceneEnvironment
|
||||||
|
|
||||||
|
antialiasingMode: SceneEnvironment.MSAA
|
||||||
|
antialiasingQuality: SceneEnvironment.High
|
||||||
|
}
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "orthoCamera"
|
||||||
|
when: view3D.isOrthographicCamera
|
||||||
|
PropertyChanges {
|
||||||
|
target: view3D
|
||||||
|
|
||||||
|
width: cameraDisplay.viewPortSize.width
|
||||||
|
height: cameraDisplay.viewPortSize.height
|
||||||
|
scale: view3D.magnificationFactor
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "nonOrthoCamera"
|
||||||
|
when: !view3D.isOrthographicCamera
|
||||||
|
PropertyChanges {
|
||||||
|
target: view3D
|
||||||
|
|
||||||
|
width: view3D.dispSize.width
|
||||||
|
height: view3D.dispSize.height
|
||||||
|
scale: 1.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@@ -3,7 +3,7 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick3D
|
import QtQuick3D
|
||||||
|
|
||||||
Item {
|
Rectangle {
|
||||||
id: cameraView
|
id: cameraView
|
||||||
|
|
||||||
required property bool showCameraView
|
required property bool showCameraView
|
||||||
@@ -16,44 +16,57 @@ Item {
|
|||||||
property var activeSceneEnvironment
|
property var activeSceneEnvironment
|
||||||
property var preferredCamera
|
property var preferredCamera
|
||||||
|
|
||||||
width: loader.width
|
width: priv.loaderSize.width + 2
|
||||||
height: loader.height
|
height: priv.loaderSize.height + 2
|
||||||
|
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.margins: 10
|
anchors.margins: 10
|
||||||
visible: loader.active
|
|
||||||
|
|
||||||
onTargetNodeChanged: loader.updateCamera()
|
visible: priv.cameraViewIsOn
|
||||||
onAlwaysOnChanged: loader.updateCamera()
|
|
||||||
onPreferredCameraChanged: loader.updateCamera()
|
onTargetNodeChanged: priv.updateCamera()
|
||||||
|
onAlwaysOnChanged: priv.updateCamera()
|
||||||
|
onPreferredCameraChanged: priv.updateCamera()
|
||||||
onActiveSceneChanged: forceReload()
|
onActiveSceneChanged: forceReload()
|
||||||
Component.onCompleted: loader.updateCamera()
|
Component.onCompleted: priv.updateCamera()
|
||||||
|
|
||||||
|
border.width: 1
|
||||||
|
border.color: "lightslategray"
|
||||||
|
color: "black"
|
||||||
|
|
||||||
function forceReload() {
|
function forceReload() {
|
||||||
loader.forceDeactive = true
|
priv.forceDeactive = true
|
||||||
loader.oldCamera = null
|
priv.oldCamera = null
|
||||||
loader.updateCamera()
|
priv.updateCamera()
|
||||||
loader.forceDeactive = false
|
priv.forceDeactive = false
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
QtObject {
|
||||||
id: loader
|
id: priv
|
||||||
|
|
||||||
property Camera camera
|
property Camera camera
|
||||||
property Camera oldCamera
|
property Camera oldCamera
|
||||||
|
property bool view3dRootNodeExists
|
||||||
property bool forceDeactive: false
|
property bool forceDeactive: false
|
||||||
|
readonly property bool cameraViewIsOn: !forceDeactive && (cameraView.alwaysOn || cameraView.showCameraView) && priv.camera
|
||||||
active: !forceDeactive && (cameraView.alwaysOn || cameraView.showCameraView) && loader.camera
|
readonly property bool cameraHasValidScene: priv.cameraViewIsOn && priv.view3dRootNodeExists
|
||||||
|
property Loader activeLoader
|
||||||
|
readonly property size loaderSize: activeLoader && activeLoader.active
|
||||||
|
? Qt.size(activeLoader.width, activeLoader.height)
|
||||||
|
: Qt.size(-2, -2)
|
||||||
|
|
||||||
function updateCamera() {
|
function updateCamera() {
|
||||||
loader.camera = activeCamera()
|
let activeCam = activeCamera()
|
||||||
|
priv.camera = activeCam
|
||||||
|
priv.view3dRootNodeExists = _generalHelper.view3dRootNode(activeCam)
|
||||||
}
|
}
|
||||||
|
|
||||||
function activeCamera() {
|
function activeCamera() {
|
||||||
if (cameraView.alwaysOn) {
|
if (cameraView.alwaysOn) {
|
||||||
if (_generalHelper.isCamera(cameraView.targetNode))
|
if (_generalHelper.isCamera(cameraView.targetNode))
|
||||||
return cameraView.targetNode
|
return cameraView.targetNode
|
||||||
else if (loader.oldCamera)
|
else if (priv.oldCamera)
|
||||||
return loader.oldCamera
|
return priv.oldCamera
|
||||||
else
|
else
|
||||||
return cameraView.preferredCamera
|
return cameraView.preferredCamera
|
||||||
} else if (_generalHelper.isCamera(cameraView.targetNode)) {
|
} else if (_generalHelper.isCamera(cameraView.targetNode)) {
|
||||||
@@ -63,82 +76,36 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onCameraChanged: {
|
onCameraChanged: {
|
||||||
if (loader.camera)
|
if (priv.camera)
|
||||||
loader.oldCamera = loader.camera
|
priv.oldCamera = priv.camera
|
||||||
}
|
|
||||||
|
|
||||||
sourceComponent: Rectangle {
|
|
||||||
id: cameraRect
|
|
||||||
|
|
||||||
implicitWidth: view3D.dispSize.width + 2
|
|
||||||
implicitHeight: view3D.dispSize.height + 2
|
|
||||||
border.width: 1
|
|
||||||
border.color: "lightslategray"
|
|
||||||
color: "black"
|
|
||||||
|
|
||||||
View3D {
|
|
||||||
id: view3D
|
|
||||||
|
|
||||||
readonly property bool isOrthographicCamera: _generalHelper.isOrthographicCamera(view3D.camera)
|
|
||||||
property size dispSize: calculateSize(cameraView.viewPortSize, cameraView.preferredSize)
|
|
||||||
readonly property real magnificationFactor: cameraView.viewPortSize.width === 0
|
|
||||||
? 1.0
|
|
||||||
: (view3D.dispSize.width / cameraView.viewPortSize.width)
|
|
||||||
|
|
||||||
transformOrigin: Item.Center
|
|
||||||
anchors.centerIn: parent
|
|
||||||
|
|
||||||
camera: loader.camera
|
|
||||||
importScene: cameraView.activeScene
|
|
||||||
environment: cameraView.activeSceneEnvironment ?? defaultSceneEnvironment
|
|
||||||
|
|
||||||
function calculateSize(viewPortSize: size, preferredSize : size){
|
|
||||||
if (_generalHelper.fuzzyCompare(viewPortSize.width, 0)
|
|
||||||
|| _generalHelper.fuzzyCompare(viewPortSize.height, 0))
|
|
||||||
return Qt.size(0, 0)
|
|
||||||
|
|
||||||
let aspectRatio = viewPortSize.height / viewPortSize.width
|
|
||||||
var calculatedHeight = preferredSize.width * aspectRatio
|
|
||||||
if (calculatedHeight <= preferredSize.height)
|
|
||||||
return Qt.size(preferredSize.width, calculatedHeight)
|
|
||||||
|
|
||||||
var calculatedWidth = preferredSize.height / aspectRatio;
|
|
||||||
return Qt.size(calculatedWidth, preferredSize.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: "orthoCamera"
|
|
||||||
when: view3D.isOrthographicCamera
|
|
||||||
PropertyChanges {
|
|
||||||
target: view3D
|
|
||||||
|
|
||||||
width: cameraView.viewPortSize.width
|
|
||||||
height: cameraView.viewPortSize.height
|
|
||||||
scale: view3D.magnificationFactor
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "nonOrthoCamera"
|
|
||||||
when: !view3D.isOrthographicCamera
|
|
||||||
PropertyChanges {
|
|
||||||
target: view3D
|
|
||||||
|
|
||||||
width: view3D.dispSize.width
|
|
||||||
height: view3D.dispSize.height
|
|
||||||
scale: 1.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneEnvironment {
|
Loader {
|
||||||
id: defaultSceneEnvironment
|
id: cameraLoader
|
||||||
|
|
||||||
antialiasingMode: SceneEnvironment.MSAA
|
active: priv.cameraViewIsOn && priv.cameraHasValidScene
|
||||||
antialiasingQuality: SceneEnvironment.High
|
onLoaded: priv.activeLoader = this
|
||||||
|
sourceComponent: CameraDisplay {
|
||||||
|
camera: priv.camera
|
||||||
|
preferredSize: cameraView.preferredSize
|
||||||
|
viewPortSize: cameraView.viewPortSize
|
||||||
|
activeScene: cameraView.activeScene
|
||||||
|
activeSceneEnvironment: cameraView.activeSceneEnvironment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: errorLoader
|
||||||
|
|
||||||
|
active: priv.cameraViewIsOn && !priv.cameraHasValidScene
|
||||||
|
onLoaded: priv.activeLoader = this
|
||||||
|
sourceComponent: Text {
|
||||||
|
font.pixelSize: 14
|
||||||
|
color: "yellow"
|
||||||
|
text: qsTr("Camera does not have a valid view")
|
||||||
|
padding: 10
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
states: [
|
states: [
|
||||||
|
@@ -692,6 +692,20 @@ bool GeneralHelper::isOrthographicCamera(QQuick3DNode *node) const
|
|||||||
return node && qobject_cast<QQuick3DOrthographicCamera *>(node);
|
return node && qobject_cast<QQuick3DOrthographicCamera *>(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QQuick3DNode *GeneralHelper::view3dRootNode(QQuick3DNode *node) const
|
||||||
|
{
|
||||||
|
if (!node)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
QQuick3DNode *parentNode = node->parentNode();
|
||||||
|
while (parentNode) {
|
||||||
|
if (parentNode->inherits("QQuick3DSceneRootNode"))
|
||||||
|
return parentNode;
|
||||||
|
parentNode = parentNode->parentNode();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// Emitter gizmo model creation is done in C++ as creating dynamic properties and
|
// Emitter gizmo model creation is done in C++ as creating dynamic properties and
|
||||||
// assigning materials to dynamically created models is lot simpler in C++
|
// assigning materials to dynamically created models is lot simpler in C++
|
||||||
QQuick3DNode *GeneralHelper::createParticleEmitterGizmoModel(QQuick3DNode *emitter,
|
QQuick3DNode *GeneralHelper::createParticleEmitterGizmoModel(QQuick3DNode *emitter,
|
||||||
|
@@ -97,6 +97,7 @@ public:
|
|||||||
Q_INVOKABLE bool isPickable(QQuick3DNode *node) const;
|
Q_INVOKABLE bool isPickable(QQuick3DNode *node) const;
|
||||||
Q_INVOKABLE bool isCamera(QQuick3DNode *node) const;
|
Q_INVOKABLE bool isCamera(QQuick3DNode *node) const;
|
||||||
Q_INVOKABLE bool isOrthographicCamera(QQuick3DNode *node) const;
|
Q_INVOKABLE bool isOrthographicCamera(QQuick3DNode *node) const;
|
||||||
|
Q_INVOKABLE QQuick3DNode *view3dRootNode(QQuick3DNode *node) const;
|
||||||
Q_INVOKABLE QQuick3DNode *createParticleEmitterGizmoModel(QQuick3DNode *emitter,
|
Q_INVOKABLE QQuick3DNode *createParticleEmitterGizmoModel(QQuick3DNode *emitter,
|
||||||
QQuick3DMaterial *material) const;
|
QQuick3DMaterial *material) const;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user