2 * Copyright (C) 2014 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 import Ubuntu.Components 0.1
19 import "Flickables" as Flickables
21 /*! \brief Zoomable for image.
23 This widget shows image contained in source,
24 can be zoomable accordingly with zoomable.
29 property alias source: lazyImage.source
30 property var zoomable: false
31 property alias imageState: lazyImage.state
32 property alias scaleTo: lazyImage.scaleTo
33 property alias asynchronous: lazyImage.asynchronous
35 Flickables.Flickable {
37 objectName: "flickable"
39 contentHeight: imageContainer.height
40 contentWidth: imageContainer.width
42 onHeightChanged: image.resetScale()
43 onWidthChanged: image.resetScale()
48 objectName: "imageContainer"
49 width: Math.max(image.width * image.scale, flickable.width)
50 height: Math.max(image.height * image.scale, flickable.height)
55 property alias imageState: lazyImage.state
56 property var prevScale
57 anchors.centerIn: parent
63 objectName: "lazyImage"
64 smooth: !flickable.movingVertically
66 fillMode: Image.PreserveAspectFit
70 if (state == "ready") {
71 image.imageReloaded();
77 image.height = lazyImage.sourceImage.implicitHeight
78 image.width = lazyImage.sourceImage.implicitWidth
82 function resetScale() {
83 image.scale = Math.min(flickable.width / image.width, flickable.height / image.height);
84 pinchArea.minScale = image.scale;
85 prevScale = Math.min(image.scale, 1);
89 var currentWidth = width * scale
90 var currentHeight = height * scale
91 var scaleRatio = scale / prevScale
92 if (currentWidth > flickable.width) {
93 var xpos = flickable.width / 2 + flickable.contentX;
94 var xoff = xpos * scaleRatio;
95 flickable.contentX = xoff - flickable.width / 2;
97 if (currentHeight > flickable.height) {
98 var ypos = flickable.height / 2 + flickable.contentY;
99 var yoff = ypos * scaleRatio;
100 flickable.contentY = yoff - flickable.height / 2;
109 objectName: "pinchArea"
110 property real minScale: 1.0
112 enabled: zoomable ? zoomable : false
115 pinch.minimumScale: minScale
116 pinch.maximumScale: 10
118 onPinchFinished: flickable.returnToBounds()
123 objectName: "mouseArea"
126 enabled: zoomable ? zoomable : false
129 var startScale = image.scale;
130 if (wheel.angleDelta.y > 0) {
131 image.scale = startScale + 0.1;
132 } else if (wheel.angleDelta.y < 0) {
133 if (image.scale > 0.1 && image.scale > pinchArea.minScale) {
134 image.scale = startScale - 0.1;
137 wheel.accepted = true;
141 mouse.accepted = false;
145 mouse.accepted = false;
149 mouse.accepted = false;