QML PhotoShop like Transform Control
-
I am trying to create a PhotoShop like transform control as a QML Component. I am doing this by creating a series of circles and line, and then parenting them to a draggable image. Moving the different circles around the the image scale and rotate the image just like in PS. The problem is that since the transform control is a child of the image, the circle are getting scaled also. How would I go about keep this from happening the child of a component from scaling with the parent?
-
Tranform Control
@import QtQuick 1.0Rectangle {
id: transControl
width: parent.width
height: parent.height
color: "#00000000"
anchors.fill: parentproperty int gripSize: 10 property int gripZ: 25 property double originalWidth: width Rectangle { id: border width: parent.width height: parent.height color: "#00000000" border.color: "#000000" z: 0 ResizeGrip { id: topLeftGrip type: "topLeft" width: transControl.gripSize height: transControl.gripSize anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenterOffset: 0 - parent.width / 2 anchors.verticalCenter: parent.verticalCenter anchors.verticalCenterOffset: 0 - parent.height / 2 z: gripZ } ResizeGrip { id: topMiddleGrip type: "topMiddle" width: transControl.gripSize height: transControl.gripSize anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter anchors.verticalCenterOffset: 0 - parent.height / 2 z: gripZ } ResizeGrip { id: topRightGrip type: "topRight" width: transControl.gripSize height: transControl.gripSize anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenterOffset: 0 + parent.width / 2 anchors.verticalCenter: parent.verticalCenter anchors.verticalCenterOffset: 0 - parent.height / 2 z: gripZ } ResizeGrip { id: midLeftGrip type: "middleLeft" width: transControl.gripSize height: transControl.gripSize anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenterOffset: 0 - parent.width / 2 anchors.verticalCenter: parent.verticalCenter z: gripZ } ResizeGrip { id: midRightGrip type: "middleRight" width: transControl.gripSize height: transControl.gripSize anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenterOffset: 0 + parent.width / 2 anchors.verticalCenter: parent.verticalCenter z: gripZ Scale{ id: mrScale origin.x: midLeftGrip.x origin.y: midLeftGrip.y xScale: .5 } MouseArea{ id: ma anchors.fill: parent drag.axis: Drag.XAxis drag.target: midRightGrip onPressed: { console.log(midRightGrip.type + " was pressed"); midRightGrip.anchors.horizontalCenter = undefined; } onReleased: { console.log(midRightGrip.type + " was released"); midRightGrip.anchors.horizontalCenter = midRightGrip.parent.horizontalCenter; } } onXChanged: { var parent = transControl.parent if (ma.drag.active){ var distance = Math.abs(midRightGrip.x - midLeftGrip.x) mrScale.xScale = distance mrScale.xScale = distance / transControl.originalWidth parent.transform = mrScale console.log(transControl.originalWidth) console.log("Distance is " + distance) console.log("Scale is " + mrScale.xScale) console.log(midRightGrip.type + " moved to " + midRightGrip.x) } } } ResizeGrip { id: rgtLeftGrip type: "rightLeft" width: transControl.gripSize height: transControl.gripSize anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenterOffset: 0 - parent.width / 2 anchors.verticalCenter: parent.verticalCenter anchors.verticalCenterOffset: parent.height / 2 z: gripZ } ResizeGrip { id: rgtMiddleGrip type: "rightMiddle" width: transControl.gripSize height: transControl.gripSize anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter anchors.verticalCenterOffset: parent.height / 2 z: gripZ } ResizeGrip { id: rgtRightGrip type: "rightRight" width: transControl.gripSize height: transControl.gripSize anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenterOffset: 0 + parent.width / 2 anchors.verticalCenter: parent.verticalCenter anchors.verticalCenterOffset: parent.height / 2 z: gripZ } }
}
@ -
Code that instantiates it onto the draggable image
@ var component = Qt.createComponent("Transform.qml");
console.log("creating transform control");
if (component.status == Component.Ready){
var transform = component.createObject(di);
transform.x = di.x - transform.width / 2
transform.y = di.y - transform.height / 2
}@ -
Hi,
Rather than making your control a child of the Image you want to manipulate, can you make it a sibling? You could e.g. add a target property to transControl:
@property Item target@
which would be used internally where transControl.parent is currently used. Externally, you would then assign the target wherever the control is used:
@Rectangle {
Image { id: myImage }
TransformControl { target: myImage }
}@Regards,
Michael -
I have updated the transControl as you have said with
@property Item target@Then, on the javascript side when I create the control with
@var component = Qt.createComponent("Transform.qml");
component.target = target;@I get this error:
Error: Cannot assign to non-existent property "target"Do you know what I am doing wrong?
-
Hi,
The target property is defined for the instances of the component, rather than the component itself, so it needs to be set on the objects returned from createObject:
@var obj = component.createObject(parent)
obj.target = targetItem
@If you are using QtQuick 1.1 you can also do something like the following (which is faster and should potentially generate fewer warnings):
@var obj = component.createObject(parent, { target: targetItem })
Regards,
Michael