diff options
author | Miikka Heikkinen <miikka.heikkinen@qt.io> | 2024-02-09 16:31:30 +0200 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@qt.io> | 2024-02-12 14:32:37 +0000 |
commit | 93993c322e7f8b832e63cb131813d567a5352fdd (patch) | |
tree | 380c4365c07258579b5594b461f1416619a25f4f | |
parent | c90970afed8254aeda20b6496ca09366dd701237 (diff) |
EffectComposer: Fix effect preview zoom
Zoom must scale the component showing the preview, not the source
image. This way the effect stays consistent regardless of the zoom
level.
Fixes: QDS-11899
Change-Id: I550eb9ff693c24a853f5c25d9d79fa146448663f
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
-rw-r--r-- | share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposerPreview.qml | 235 | ||||
-rw-r--r-- | src/plugins/effectcomposer/effectcomposermodel.h | 2 |
2 files changed, 128 insertions, 109 deletions
diff --git a/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposerPreview.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposerPreview.qml index 50c8e32c71..c832b2f370 100644 --- a/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposerPreview.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposerPreview.qml @@ -22,11 +22,13 @@ Column { readonly property int previewMargin: 5 + property real previewScale: 1 + // Create a dummy parent to host the effect qml object function createNewComponent() { // If we have a working effect, do not show preview image as it shows through // transparent parts of the final image - source.visible = false; + placeHolder.visible = false; var oldComponent = componentParent.children[0]; if (oldComponent) @@ -48,7 +50,7 @@ Column { errorLine = e.lineNumber; } effectComposerModel.setEffectError(errorString, 0, errorLine); - source.visible = true; + placeHolder.visible = true; } } @@ -84,42 +86,42 @@ Column { anchors.verticalCenter: parent.verticalCenter HelperWidgets.AbstractButton { - enabled: sourceImage.scale < 3 + enabled: root.previewScale < 3 style: StudioTheme.Values.viewBarButtonStyle buttonIcon: StudioTheme.Constants.zoomIn_medium tooltip: qsTr("Zoom In") onClicked: { - sourceImage.enableAnim(true) - sourceImage.scale += .2 - sourceImage.enableAnim(false) + imageScaler.enableAnim(true) + root.previewScale += .2 + imageScaler.enableAnim(false) zoomIndicator.show() } } HelperWidgets.AbstractButton { - enabled: sourceImage.scale > .4 + enabled: root.previewScale > .4 style: StudioTheme.Values.viewBarButtonStyle buttonIcon: StudioTheme.Constants.zoomOut_medium tooltip: qsTr("Zoom out") onClicked: { - sourceImage.enableAnim(true) - sourceImage.scale -= .2 - sourceImage.enableAnim(false) + imageScaler.enableAnim(true) + root.previewScale -= .2 + imageScaler.enableAnim(false) zoomIndicator.show() } } HelperWidgets.AbstractButton { - enabled: sourceImage.scale !== 1 || sourceImage.x !== root.previewMargin - || sourceImage.y !== root.previewMargin + enabled: root.previewScale !== 1 || imageScaler.x !== root.previewMargin + || imageScaler.y !== root.previewMargin style: StudioTheme.Values.viewBarButtonStyle buttonIcon: StudioTheme.Constants.fitAll_medium tooltip: qsTr("Reset View") onClicked: { - sourceImage.resetTransforms() + imageScaler.resetTransforms() } } } @@ -187,8 +189,8 @@ Column { property bool panning: false onPressed: { - pressX = mouseX - sourceImage.x - pressY = mouseY - sourceImage.y + pressX = mouseX - imageScaler.x + pressY = mouseY - imageScaler.y panning = true } @@ -197,22 +199,21 @@ Column { } onWheel: (wheel) => { - let prevScale = sourceImage.scale + let oldPoint = imageScaler.mapFromItem(mouseArea, Qt.point(wheel.x, wheel.y)) if (wheel.angleDelta.y > 0) { - if (sourceImage.scale < 3) - sourceImage.scale += .2 + if (root.previewScale < 3) + root.previewScale += .2 } else { - if (sourceImage.scale > .4) - sourceImage.scale -= .2 + if (root.previewScale > .4) + root.previewScale -= .2 } - let dScale = sourceImage.scale - prevScale - - sourceImage.x += (sourceImage.x + sourceImage.width * .5 - wheel.x) * dScale; - sourceImage.y += (sourceImage.y + sourceImage.height * .5 - wheel.y) * dScale; + let newPoint = imageScaler.mapFromItem(mouseArea, Qt.point(wheel.x, wheel.y)) + imageScaler.x -= (oldPoint.x - newPoint.x) * imageScaler.scale + imageScaler.y -= (oldPoint.y - newPoint.y) * imageScaler.scale - sourceImage.checkBounds() + imageScaler.checkBounds() zoomIndicator.show() } @@ -222,117 +223,135 @@ Column { repeat: true onTriggered: { - sourceImage.x = mouseArea.mouseX - mouseArea.pressX - sourceImage.y = mouseArea.mouseY - mouseArea.pressY - sourceImage.checkBounds() + imageScaler.x = mouseArea.mouseX - mouseArea.pressX + imageScaler.y = mouseArea.mouseY - mouseArea.pressY + imageScaler.checkBounds() } } } + Image { + id: placeHolder + anchors.fill: parent + anchors.margins: root.previewMargin + fillMode: Image.PreserveAspectFit + source: imagesComboBox.selectedImage + smooth: true + } + Item { // Source item as a canvas (render target) for effect id: source - anchors.fill: parent + width: sourceImage.sourceSize.width + height: sourceImage.sourceSize.height layer.enabled: true layer.mipmap: true layer.smooth: true + visible: false Image { id: sourceImage - function checkBounds() { - let edgeMargin = 10 - // correction factor to account for an observation that edgeMargin decreases - // with increased zoom - let corrFactor = 10 * sourceImage.scale - let imgW2 = sourceImage.paintedWidth * sourceImage.scale * .5 - let imgH2 = sourceImage.paintedHeight * sourceImage.scale * .5 - let srcW2 = source.width * .5 - let srcH2 = source.height * .5 - - if (sourceImage.x < -srcW2 - imgW2 + edgeMargin + corrFactor) - sourceImage.x = -srcW2 - imgW2 + edgeMargin + corrFactor - else if (x > srcW2 + imgW2 - edgeMargin - corrFactor) - sourceImage.x = srcW2 + imgW2 - edgeMargin - corrFactor - - if (sourceImage.y < -srcH2 - imgH2 + edgeMargin + corrFactor) - sourceImage.y = -srcH2 - imgH2 + edgeMargin + corrFactor - else if (y > srcH2 + imgH2 - edgeMargin - corrFactor) - sourceImage.y = srcH2 + imgH2 - edgeMargin - corrFactor - } + onSourceChanged: imageScaler.resetTransforms() - function resetTransforms() { - sourceImage.enableAnim(true) - sourceImage.scale = 1 - sourceImage.x = root.previewMargin - sourceImage.y = root.previewMargin - sourceImage.enableAnim(false) - } - - function enableAnim(flag) { - xBehavior.enabled = flag - yBehavior.enabled = flag - scaleBehavior.enabled = flag - } + fillMode: Image.Pad - onSourceChanged: sourceImage.resetTransforms() - - fillMode: Image.PreserveAspectFit - - x: root.previewMargin - y: root.previewMargin - width: parent.width - root.previewMargin * 2 - height: parent.height - root.previewMargin * 2 source: imagesComboBox.selectedImage smooth: true + } + } - Behavior on x { - id: xBehavior + BlurHelper { + id: blurHelper + source: source + property int blurMax: g_propertyData.blur_helper_max_level ? g_propertyData.blur_helper_max_level : 64 + property real blurMultiplier: g_propertyData.blurMultiplier ? g_propertyData.blurMultiplier : 0 + } - enabled: false - NumberAnimation { - duration: 200 - easing.type: Easing.OutQuad - } + Item { + id: imageScaler + x: root.previewMargin + y: root.previewMargin + width: parent.width - root.previewMargin * 2 + height: parent.height - root.previewMargin * 2 + + scale: root.previewScale * (width > height ? height / sourceImage.sourceSize.height + : width / sourceImage.sourceSize.width) + + Behavior on x { + id: xBehavior + + enabled: false + NumberAnimation { + duration: 200 + easing.type: Easing.OutQuad } + } - Behavior on y { - id: yBehavior + Behavior on y { + id: yBehavior - enabled: false - NumberAnimation { - duration: 200 - easing.type: Easing.OutQuad - } + enabled: false + NumberAnimation { + duration: 200 + easing.type: Easing.OutQuad } + } - Behavior on scale { - id: scaleBehavior + Behavior on scale { + id: scaleBehavior - enabled: false - NumberAnimation { - duration: 200 - easing.type: Easing.OutQuad - } + enabled: false + NumberAnimation { + duration: 200 + easing.type: Easing.OutQuad } } - } - BlurHelper { - id: blurHelper - source: source - property int blurMax: g_propertyData.blur_helper_max_level ? g_propertyData.blur_helper_max_level : 64 - property real blurMultiplier: g_propertyData.blurMultiplier ? g_propertyData.blurMultiplier : 0 - } + function checkBounds() { + let edgeMargin = 10 + // correction factor to account for an observation that edgeMargin decreases + // with increased zoom + let corrFactor = 10 * imageScaler.scale + let imgW2 = sourceImage.paintedWidth * imageScaler.scale * .5 + let imgH2 = sourceImage.paintedHeight * imageScaler.scale * .5 + let srcW2 = width * .5 + let srcH2 = height * .5 + + if (imageScaler.x < -srcW2 - imgW2 + edgeMargin + corrFactor) + imageScaler.x = -srcW2 - imgW2 + edgeMargin + corrFactor + else if (x > srcW2 + imgW2 - edgeMargin - corrFactor) + imageScaler.x = srcW2 + imgW2 - edgeMargin - corrFactor + + if (imageScaler.y < -srcH2 - imgH2 + edgeMargin + corrFactor) + imageScaler.y = -srcH2 - imgH2 + edgeMargin + corrFactor + else if (y > srcH2 + imgH2 - edgeMargin - corrFactor) + imageScaler.y = srcH2 + imgH2 - edgeMargin - corrFactor + } - Item { - id: componentParent - width: source.width - height: source.height - anchors.centerIn: parent - // Cache the layer. This way heavy shaders rendering doesn't - // slow down code editing & rest of the UI. - layer.enabled: true - layer.smooth: true + function resetTransforms() { + imageScaler.enableAnim(true) + root.previewScale = 1 + imageScaler.x = root.previewMargin + imageScaler.y = root.previewMargin + imageScaler.enableAnim(false) + } + + function enableAnim(flag) { + xBehavior.enabled = flag + yBehavior.enabled = flag + scaleBehavior.enabled = flag + } + + Item { + id: componentParent + width: source.width + height: source.height + anchors.centerIn: parent + // Cache the layer. This way heavy shaders rendering doesn't + // slow down code editing & rest of the UI. + layer.enabled: true + layer.smooth: true + } } Rectangle { @@ -349,7 +368,7 @@ Column { } Text { - text: Math.round(sourceImage.scale * 100) + "%" + text: Math.round(root.previewScale * 100) + "%" color: StudioTheme.Values.themeTextColor anchors.centerIn: parent } diff --git a/src/plugins/effectcomposer/effectcomposermodel.h b/src/plugins/effectcomposer/effectcomposermodel.h index c0eb76f0b9..871d0c7298 100644 --- a/src/plugins/effectcomposer/effectcomposermodel.h +++ b/src/plugins/effectcomposer/effectcomposermodel.h @@ -178,7 +178,7 @@ private: QList<CompositionNode *> m_nodes; int m_selectedIndex = -1; - bool m_isEmpty = true; + bool m_isEmpty = false; // Init to false to force initial bake after setup bool m_hasUnsavedChanges = false; // True when shaders haven't changed since last baking bool m_shadersUpToDate = true; |