aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@qt.io>2024-02-09 16:31:30 +0200
committerMiikka Heikkinen <miikka.heikkinen@qt.io>2024-02-12 14:32:37 +0000
commit93993c322e7f8b832e63cb131813d567a5352fdd (patch)
tree380c4365c07258579b5594b461f1416619a25f4f
parentc90970afed8254aeda20b6496ca09366dd701237 (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.qml235
-rw-r--r--src/plugins/effectcomposer/effectcomposermodel.h2
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;