Creating a resizable Qml dialog - qt

I am trying to make a resizable dialog:
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.12
ApplicationWindow {
width: 640
height: 480
visible: true
title: qsTr("Test")
Dialog {
id: dlg
x: 10
y: 10
width: 100
height: 100
visible: true
Rectangle {
anchors.fill: parent
color: "blue"
}
MouseArea {
height: 40
width: 40
anchors.right: parent.right
anchors.bottom: parent.bottom
Rectangle {
anchors.fill: parent
color: "red"
}
property real startX: 0
property real startY: 0
property real startWidth: 0
property real startHeight: 0
onPressed: {
startX = mouseX;
startY = mouseY;
startWidth = dlg.width;
startHeight = dlg.height;
}
function fnc_updatePos() {
if (pressed) {
var deltaX = mouseX-startX;
var deltaY = mouseY-startY;
dlg.width = startWidth + deltaX;
dlg.height = startHeight + deltaY;
}
}
onPositionChanged: fnc_updatePos()
}
}
}
The code resizes the dialog but the dialog flickers during dragging. The problem is that the mouse area is part of the dialog. How can the code be improved for proper scaling of the popup dialog?
Regards

I post the answer instead of deleting the question, just in case someone is stumbling upon the same problem.
mapToItem is the solution:
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.12
ApplicationWindow {
id: mainWindow
width: 640
height: 480
visible: true
title: qsTr("Test")
Dialog {
id: dlg
x: 10
y: 10
width: 100
height: 100
visible: true
Rectangle {
anchors.fill: parent
color: "blue"
}
MouseArea {
height: 40
width: 40
anchors.right: parent.right
anchors.bottom: parent.bottom
Rectangle {
anchors.fill: parent
color: "red"
}
property real startX: 0
property real startY: 0
property real startWidth: 0
property real startHeight: 0
onPressed: {
var pos = mapToItem(mainWindow.contentItem, mouseX, mouseY)
startX = pos.x;
startY = pos.y;
startWidth = dlg.width;
startHeight = dlg.height;
}
function fnc_updatePos() {
if (pressed) {
var pos = mapToItem(mainWindow.contentItem, mouseX, mouseY)
//console.log(pos)
var deltaX = pos.x-startX;
var deltaY = pos.y-startY;
dlg.width = startWidth + deltaX;
dlg.height = startHeight + deltaY;
}
}
onPositionChanged: fnc_updatePos()
}
}
}

Related

Reproducing OS Minimize Behaviour in a Custom Titlle Bar done in QML

I'm being tasked with creating a customized title bar for our application. It needs to have rounded corners and a settings button, amongst other things. It will run exclusively on windows.
Our application uses Qt and QML for the front end.
So the only way I could find how to do this is by making the application window frameless and creating the title bar from scratch.
This is my test code:
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.0
ApplicationWindow {
id: mainWindow
visible: true
visibility: Window.Maximized
title: qsTr("Hello World")
flags: Qt.FramelessWindowHint | Qt.Window | Qt.WA_TranslucentBackground
//flags: Qt.Window | Qt.WA_TranslucentBackground
color: "#00000000"
TitleBar {
id: mainTitleBar
width: mainWindow.width;
height: mainWindow.height*0.018
color: "#aaaaaa"
onCloseApplication: {
Qt.quit();
}
onMinimizeApplication: {
mainWindow.visibility = Window.Minimized
}
}
Component.onCompleted: {
console.log("Size: " + mainWindow.width + "x" + mainWindow.height)
mainTitleBar.width = mainWindow.width
mainTitleBar.height = mainWindow.height*0.023;
}
Rectangle {
id: content
width: mainWindow.width
height: mainWindow.height - mainTitleBar.height
anchors.top: mainTitleBar.bottom
anchors.left: mainTitleBar.left
color: "#00ff00"
}
}
And
Here is the title bar code (TitleBar.js file):
import QtQuick 2.0
import QtQuick.Controls 2.0
Rectangle {
/*
* Requires setting up of
* -> width
* -> height
* -> title text
* -> icon path.
* -> Background color.
*/
id: vmWindowTitleBar
border.width: 0
x: 0
y: 0
radius: 20
signal closeApplication();
signal minimizeApplication();
// The purpose of this rectangle is to erase the bottom rounded corners
Rectangle {
width: parent.width
height: parent.height/2;
anchors.bottom: parent.bottom
anchors.left: parent.left
border.width: 0
color: parent.color
}
Text {
id: titleBarText
text: "This is The Title Bar"
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: parent.width*0.018
}
Button {
id: minimizeButton
width: height
height: vmWindowTitleBar.height*0.8
anchors.right: closeButton.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: parent.width*0.018
background: Rectangle {
id: btnMinimizeRect
color: vmWindowTitleBar.color
anchors.fill: parent
}
onPressed:{
minimizeApplication()
}
scale: pressed? 0.8:1;
contentItem: Canvas {
id: btnMinimizeCanvas
contextType: "2d"
anchors.fill: parent
onPaint: {
var ctx = btnMinimizeCanvas.getContext("2d");
var h = minimizeButton.height;
var w = minimizeButton.width;
ctx.reset();
ctx.strokeStyle = minimizeButton.pressed? "#58595b": "#757575";
ctx.lineWidth = 6;
ctx.lineCap = "round"
ctx.moveTo(0,h);
ctx.lineTo(w,h);
ctx.closePath();
ctx.stroke();
}
}
}
Button {
id: closeButton
//hoverEnabled: false
width: height
height: vmWindowTitleBar.height*0.8
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: parent.width*0.018
background: Rectangle {
id: btnCloseRect
color: vmWindowTitleBar.color
anchors.fill: parent
}
onPressed:{
closeApplication()
}
scale: pressed? 0.8:1;
Behavior on scale{
NumberAnimation {
duration: 10
}
}
contentItem: Canvas {
id: btnCloseCanvas
contextType: "2d"
anchors.fill: parent
onPaint: {
var ctx = btnCloseCanvas.getContext("2d");
var h = closeButton.height;
var w = closeButton.width;
ctx.reset();
ctx.strokeStyle = closeButton.pressed? "#58595b": "#757575";
ctx.lineWidth = 2;
ctx.lineCap = "round"
ctx.moveTo(0,0);
ctx.lineTo(w,h);
ctx.moveTo(w,0);
ctx.lineTo(0,h);
ctx.closePath();
ctx.stroke();
}
}
}
}
Now the problem comes with minimizing the application. The first thing I realize is that when using the Qt.FramelessWindowHint flag, the icon does not appear in the Windows Taskbar. Furthermore if I minimize it this happens:
And If I click on it, it doesn't restore.
So my question is, is there a way to reproduce regular minimize behavior when pressing the minimize button?
Or alternatively, is there a way I can completely customize the title bar of the application so that I can achieve the look and feel set by our UI designer?
NOTE: The current look is just a quick test. I have not set the gradient, font, or the aforementioned settings button.
As for me, playing with frameless windows and transparent background is kind of workaround. As I know, the only way to apply a custom shape to the window is QWindow::setMask. Sinse Window is derived from QWindow you can do that in this way.
For example, in the main.cpp:
QWindow *wnd = qobject_cast<QWindow *>(engine.rootObjects().at(0));
auto f = [wnd]() {
QPainterPath path;
path.addRoundedRect(QRectF(0, 0, wnd->geometry().width(), wnd->geometry().height()), 30, 30);
QRegion region(path.toFillPolygon().toPolygon());
wnd->setMask(region);
};
QObject::connect(wnd, &QWindow::widthChanged, f);
QObject::connect(wnd, &QWindow::heightChanged, f);
f();
Since you 'cut' the shape from the window itself, excluding title bar and frames you can leave the window flags as is.
Look at this way, I try to create something that you do but change completely your code.
the problem that makes change in your window size after you minimize the window is that you didn't set the initial width and height for the window so when you minimize the app it shows in the minimum width and height.
so you need to add just this in main.qml and set the initial width and height to the maximum.
width: maximumWidth
height:maximumHeight
but In the code below I change something else too.
For example, you didn't need to emit signals and then catch them in main.qml
you have access to mainWindow in TitleBar.qml.
in TitleBar.qml :
import QtQuick 2.0
import QtQuick.Controls 2.0
Rectangle {
anchors.fill: parent
height: 30
Row {
id: row
anchors.fill: parent
Label {
id: label
text: qsTr("Title ")
}
Button {
id: button
x: parent.width -80
text: qsTr("close")
onClicked:
{
mainWindow.close()
}
}
Button {
id: button1
x: parent.width -160
width: 90
text: qsTr("Minimized")
onClicked:
{
mainWindow.showMinimized()
}
}
}
}
and in main.qml :
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.0
import "."
Window {
id: mainWindow
visible: true
visibility: Window.FullScreen
title: qsTr("Hello World")
flags: Qt.FramelessWindowHint | Qt.Window | Qt.WA_TranslucentBackground
width: maximumWidth
height:maximumHeight
Rectangle {
id: content
anchors.fill: parent
x: 0
y: 20
width: mainWindow.width
height: mainWindow.height - mainTitleBar.height
anchors.top: mainTitleBar.bottom
anchors.left: mainTitleBar.left
color: "#00ff00"
}
TitleBar {
id: mainTitleBar
color: "#aaaaaa"
anchors.bottomMargin: parent.height -40
anchors.fill: parent
}
}

Mask from pictures, crop image behind cursor

I have a basic background from a blue image with a transparent background (PNG), how can I make a different background from the image after the arrow?
I tried the option using a mask, but it cuts the picture either in width or in height, this does not work
blue background:
it should be:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Window 2.15
import QtQuick.Controls.Styles 1.4
import QtQuick.Extras 1.4
import QtQuick.Extras.Private 1.0
import QtGraphicalEffects 1.0
Window {
width: 1280
height: 480
visible: true
title: qsTr("Hello World")
color: "#000"
CircularGauge {
id:gauge
property bool accelerating
width: 377
height: 377
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 101
maximumValue:8
value: accelerating ? maximumValue : 0
Component.onCompleted: forceActiveFocus()
Behavior on value { NumberAnimation { duration: 1500 }}
Keys.onSpacePressed: accelerating = true
Keys.onReleased: {
if (event.key === Qt.Key_Space) {
accelerating = false;
event.accepted = true;
}
}
style: CircularGaugeStyle {
labelStepSize: 1
labelInset: outerRadius / 6
minimumValueAngle: -110
maximumValueAngle: 110
background: Rectangle {
id: rectangle
implicitHeight: gauge.height
implicitWidth: gauge.width
color:"Transparent"
anchors.centerIn: parent
radius: 360
Image {
width: 417
height: 287
anchors.top: parent.top
source: "Blue_bg.png"
anchors.topMargin: -23
anchors.horizontalCenter: parent.horizontalCenter
asynchronous: true
sourceSize {
}
}
}
foreground: Item {
Text {
id: speedLabel
anchors.centerIn: parent
anchors.verticalCenterOffset: -20
text: "126"
font.pixelSize:76
color: "white"
antialiasing: true
}
}
tickmarkLabel: Text {
font.italic: true
font.bold: true
text: styleData.value
font.pixelSize: 30
color: styleData.value <= gauge.value ? "white" : "#ffffff"
antialiasing: true
}
}
}
}
How can I achieve this effect?
You can use a Canvas to draw an arc (see Draw an arc/circle sector in QML?). If you combine this with an OpacityMask (see QML Circular Gauge) you can mask the blue "background" (it's more like a foreground in the given example) to make that cool speedometer :-)
import QtQuick 2.12
import QtQuick.Window 2.12
import QtGraphicalEffects 1.0
Window {
width: 640
height: 480
visible: true
Image {
id: img
source: "blue.png"
visible: false
}
Canvas {
id: mask
anchors.fill: img
property double angle: 45
onPaint: {
var ctx = getContext("2d");
var centerX = width / 2;
var centerY = height / 2;
ctx.beginPath();
ctx.fillStyle = "black";
ctx.moveTo(centerX, centerY);
ctx.arc(centerX, centerY, width / 4, (Math.PI) * (1 + angle / 180), 0, false);
ctx.lineTo(centerX, centerY);
ctx.fill();
}
}
OpacityMask {
anchors.fill: img
source: img
maskSource: mask
}
}

Why delegate item center is draw at start position of Path?

When I learn about PathView,I found the first and last delegate item center point is draw at the Path.
I think the first delegate item x y poszition should be same startX startY,but actually it is not?
import QtQuick 2.0
import QtQuick.Window 2.15
Window {
id: root
width: 400
height: 400
visible: true
Canvas {
anchors.fill: parent
onPaint: {
var ctx = getContext("2d")
ctx.lineWidth = 1
ctx.strokeStyle = "#abc"
ctx.beginPath()
ctx.moveTo(0,0)
ctx.lineTo(root.width, root.height)
ctx.stroke()
}
}
Component {
id: myDelegate
Rectangle {
width: 100; height: 100
color: "#321"
Text {
anchors.centerIn: parent
text: index
}
}
}
PathView {
anchors.fill: parent
model: 2
delegate: myDelegate
path: Path {
startX: 0; startY: 0
PathLine{relativeX: root.width; relativeY: root.height}
}
}
}

How do I create a ripple button effect in QML?

I'm using QtQuick/QML and I want to create a ripple effect when I click on a button. I do know that this is available in Material Style, but I think it's an inherent property when you change the theme and I don't want to change anything else in my project.
Is there a way to add ONLY the ripple effect onto my button, and change nothing else? If so, how do I do it?
As Kostia Hvorov said, QtQuick.Controls.Material.impl.Ripple is the easiest way to go.
I would like to add my trick to handle rectangular background with radius:
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Controls.Material.impl 2.12
import QtGraphicalEffects 1.12
Column
{
spacing: 20
Button
{
anchors.horizontalCenter: parent.horizontalCenter
id: button
text: "ripple demo"
}
Ripple {
id: ripple
anchors.horizontalCenter: parent.horizontalCenter
clipRadius: 4
width: 200
height: 64
pressed: button.pressed
active: button.down || button.visualFocus || button.hovered
color: "#20FFFFFF"
layer.enabled: true
layer.effect: OpacityMask {
maskSource: Rectangle
{
width: ripple.width
height: ripple.height
radius: 4
}
}
}
}
Try it Online
Easiest way to do it - using Ripple from QtQuick.Controls.Material.impl
So just add Ripple to your background Rect:
Ripple {
clipRadius: height
width: parent.width
height: parent.height
pressed: control.pressed
anchor: control
active: control.down || control.visualFocus || control.hovered
color: control.flat && control.highlighted ? control.Material.highlightedRippleColor : control.Material.rippleColor
}
You can replace "control.Material.rippleColor" or/and "control.Material.highlightedRippleColor" to any color and get any ripple color effect.
But there is one problem, it will work only with rectangular background(without round) otherwise it will be looking bad.
I have made this with some PropertyAnimation. Here is how:
import QtQuick 2.15
import QtQuick.Controls 2.15
Button {
id: control
opacity: enabled ? 1.0 : 0.2
property int tripleWidth: width * 3
background: Rectangle {
border.width: 1
border.color: "black"
radius: 3
color: "white"
clip: true
Rectangle {
id: ripple
property int diameter: 0
property int pressX: 0
property int pressY: 0
x: pressX - radius
y: pressY - radius
color: "green"
radius: diameter / 2
width: diameter
height: diameter
opacity: 1 - diameter / control.tripleWidth
function animate(x, y, size) {
pressX = x
pressY = y
diameter = size
}
Behavior on diameter {
PropertyAnimation {
duration: 200
onRunningChanged: {
if(!running) {
duration = 0;
ripple.diameter = 0;
duration = 200;
}
}
}
}
}
}
onClicked: {
ripple.animate(pressX, pressY, control.tripleWidth)
}
contentItem: Item {
implicitWidth: txt.implicitWidth
implicitHeight: 20
Text {
id: txt
anchors.centerIn: parent
text: control.text
}
}
}
I Edit last Answer and its work.. Here is How:
import QtQuick 2.5
import QtQuick.Window 2.5
import QtQuick.Controls 2.5
RoundButton {
id: control
width: 93
height: 39
property int tripleWidth: width * 3
background: Rectangle {
border.width: 1
border.color: "black"
radius: 3
color: "white"
clip: true
Rectangle {
id: ripple
property int diameter: 0
property int pressX: 0
property int pressY: 0
x: pressX - radius
y: pressY - radius
color: "green"
radius: diameter / 2
width: diameter
height: diameter
opacity: 1
function animate(x, y, size) {
pressX = x
pressY = y
diameter = size
}
Behavior on diameter {
PropertyAnimation {
duration: 300
}
}
}
}
onHoveredChanged: {
ripple.opacity = 0
ripple.diameter = 0
}
onPressed: {
ripple.opacity = 0.8
ripple.animate(pressX, pressY, control.tripleWidth)
}
Timer {
id: timer
}
contentItem: Item {
implicitWidth: txt.implicitWidth
implicitHeight: 20
Text {
id: txt
font.pointSize: 15
anchors.centerIn: parent
}
}
onClicked: {
function delay(delayTime, cb) {
timer.interval = delayTime;
timer.repeat = false;
timer.triggered.connect(cb);
timer.start();
}
delay(10, function() {
ripple.opacity = 0
ripple.diameter = 0
})
}
}
Try it....

Proper way to implement zoom/scale in Qt Quick (QML) Flickable

I'm using Qt 5.2 beta, Qt Quick 2.1.
I have straight ahead problem with Flickable component.
Here is minimal working code example:
import QtQuick 2.1
import QtQuick.Controls 1.0
ApplicationWindow {
width: 300
height: 200
Rectangle {
anchors.fill: parent
color: "green"
Flickable {
id: flickArea
anchors {fill: parent; margins: 10; }
contentWidth: rect.width;
contentHeight: rect.height
Rectangle {
id: rect
x: 0; y: 0;
width: 200; height: 300;
color: "lightgrey"
Rectangle {
anchors { fill: parent; margins: 10; }
color: "red"
}
}
}
}
Button {
anchors.bottom: parent.bottom;
anchors.horizontalCenter: parent.horizontalCenter;
text: "Scale flickArea"
onClicked: { flickArea.scale += 0.2; }
}
}
When I'm doing scaling, I expect that all child elements will stay visible as it was before and inner area to become bigger.
But instead, child elements move out of Flickable content.
Can someone propose a normal way to avoid this problem without the need for manual recalculation of all offsets?
I got it work as expected this way, but IMO this way is little bit tricky:
import QtQuick 2.1
import QtQuick.Controls 1.0
ApplicationWindow {
width: 300
height: 200
Rectangle {
anchors.fill: parent
color: "green"
Flickable {
id: flickArea
anchors {fill: parent; margins: 10; }
contentWidth: rect.width*rect.scale
contentHeight: rect.height*rect.scale
Rectangle {
id: rect
transformOrigin: Item.TopLeft
x: 0; y: 0;
width: 200; height: 300;
color: "lightgrey"
Rectangle {
id: inner
anchors { fill: parent; margins: 10; }
color: "red"
}
}
}
}
Button {
anchors.bottom: parent.bottom;
anchors.horizontalCenter: parent.horizontalCenter;
text: "Scale flickArea"
onClicked: {
rect.scale += 0.2;
}
}
}
Can someone propose something better?
UPD. I did not close this question for 1 year, but still didn't get any better solution or better way to doing things.
using Scale transform seems better solution:
import QtQml 2.11
import QtQuick 2.11
import QtQuick.Window 2.11
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.11
import QtQuick.Controls 2.4
import QtQuick.Controls.Material 2.4
import QtCharts 2.2
import QtGraphicalEffects 1.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
property int scaleX: 1;
Rectangle {
anchors.fill: parent
color: "green"
Flickable {
id: flickArea
anchors {fill: parent; margins: 10; }
contentWidth: rect.width*rect.scale
contentHeight: rect.height*rect.scale
transform: Scale { origin.x: 0; origin.y: 240; xScale: scaleX}
Rectangle {
id: rect
transformOrigin: Item.TopLeft
x: 0; y: 0;
width: 200; height: 300;
color: "lightgrey"
Rectangle {
id: inner
anchors { fill: parent; margins: 10; }
color: "red"
}
}
}
}
Button {
anchors.bottom: parent.bottom;
anchors.horizontalCenter: parent.horizontalCenter;
text: "Scale flickArea"
onClicked: {
// flickArea.scale += 0.2;
scaleX += 1;
console.log(flickArea.contentWidth);
console.log(flickArea.scale)
}
}
}
A propar way to implement zoomable image in qml
import QtQuick 2.15
Flickable
{
id:flickable
property int imageWidth
property int imageHeight
property alias source: mImage.source
contentWidth: imageWidth
contentHeight:imageHeight
boundsBehavior: Flickable.StopAtBounds
boundsMovement: Flickable.StopAtBounds
states: [
State {
name: "state_StickToCenter" // state is used when content size is less than flickable size then content
// center should stick to flickable center
when : ( flickable.contentWidth < flickable.width || flickable.contentHeight< flickable.height )
PropertyChanges {
target: flickable.contentItem
anchors.horizontalCenter: width < flickable.width ? flickable.horizontalCenter : undefined
anchors.verticalCenter: height < flickable.height ? flickable.verticalCenter : undefined
}
}
]
onStateChanged: { cancelFlick(); returnToBounds(); }
Image
{
id:mImage
width:flickable.contentWidth;
height: flickable.contentHeight;
source: flickable.imageSource
fillMode: Image.PreserveAspectFit;
Component.onCompleted:
{
imageWidth = mImage.paintedWidth;
imageHeight = mImage.paintedHeight
}
autoTransform: true
PinchArea
{
id:pinchArea
anchors.fill: parent
property bool zoomTriggeredFromPinchArea:false
property point pinchCenter;
onPinchStarted: zoomTriggeredFromPinchArea=true;
onPinchUpdated:
{
var newZoomFactor = privateProperties.currentZoomFactor+ privateProperties.currentZoomFactor*(pinch.scale-1);
pinchCenter =pinch.center;
privateProperties.zoom(privateProperties.getBoundedScaleFactor(newZoomFactor))
}
onPinchFinished:
{
privateProperties.currentZoomFactor += privateProperties.currentZoomFactor*(pinch.scale-1);
privateProperties.currentZoomFactor = privateProperties.getBoundedScaleFactor(privateProperties.currentZoomFactor);
zoomTriggeredFromPinchArea=false;
}
MouseArea
{
id:mouseArea
anchors.fill: parent
propagateComposedEvents :true
scrollGestureEnabled: false
hoverEnabled: true
onDoubleClicked:
{
if(privateProperties.currentZoomFactor>1)resetScale();
else
{
var widthScale = (flickable.width+20)/mImage.width;
var heightScale = (flickable.height+20)/mImage.height;
var maxScale = Math.max(widthScale,heightScale);
if(maxScale>1)
{
privateProperties.pointOfDoubleClick = Qt.point(mouseX,mouseY);
privateProperties.useDoubleClickPoint = true;
privateProperties.currentZoomFactor = maxScale;
}
}
}
onWheel:
{
if(wheel.modifiers===Qt.ControlModifier)
{
wheel.accepted=true;
var newZoomFactor;
if(wheel.angleDelta.y>0)
newZoomFactor = privateProperties.currentZoomFactor + (privateProperties.currentZoomFactor*privateProperties.zoomStepFactor);
else newZoomFactor = privateProperties.currentZoomFactor - (privateProperties.currentZoomFactor*privateProperties.zoomStepFactor);
privateProperties.currentZoomFactor = privateProperties.getBoundedScaleFactor(newZoomFactor);
return;
}
wheel.accepted=false;
}
}
}
}
QtObject
{
id : privateProperties
property bool useDoubleClickPoint:false;
property point pointOfDoubleClick;
property real maxZoomFactor : 30.0
property real zoomStepFactor :0.3;
property real currentZoomFactor: 1
property real minZoomFactor :1;
property point scaleCenter : pinchArea.zoomTriggeredFromPinchArea
? pinchArea.pinchCenter : Qt.point(mouseArea.mouseX,mouseArea.mouseY);
Behavior on currentZoomFactor {
NumberAnimation { id:scaleNumberAnimation
duration: pinchArea.zoomTriggeredFromPinchArea ? 0 : privateProperties.useDoubleClickPoint ?
Math.min(200*privateProperties.currentZoomFactor,500) : 200 ;
onRunningChanged: if(!running) privateProperties.useDoubleClickPoint=false;
}
}
onCurrentZoomFactorChanged:
{
if(!pinchArea.zoomTriggeredFromPinchArea)
zoom(currentZoomFactor);
}
function zoom(scaleFactor)
{
var targetWidth = imageWidth*scaleFactor;
var targetHeight = imageHeight*scaleFactor;
if(useDoubleClickPoint) resizeContent(targetWidth,targetHeight,mapToItem(mImage,pointOfDoubleClick));
else resizeContent(targetWidth,targetHeight,scaleCenter);
returnToBounds();
}
function getBoundedScaleFactor(ScaleFactor)
{
if(ScaleFactor>maxZoomFactor)ScaleFactor = maxZoomFactor;
else if(ScaleFactor<minZoomFactor)ScaleFactor = minZoomFactor;
return ScaleFactor;
}
}
function resetScale()
{
privateProperties.pointOfDoubleClick = Qt.point(0,0);
privateProperties.useDoubleClickPoint = true;
privateProperties.currentZoomFactor = 1;
}
}

Resources