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
20
/*! \brief Zoomable for image.
22
This widget shows image contained in source,
23
can be zoomable accordingly with zoomable.
28
property alias source: imageRenderer.source
29
property var zoomable: false
30
property alias imageStatus: imageRenderer.status
31
property alias asynchronous: imageRenderer.asynchronous
35
objectName: "flickable"
36
clip: true // FIXME maybe we can remove this, or just not clip in few cases
37
contentHeight: imageContainer.height
38
contentWidth: imageContainer.width
40
onHeightChanged: image.resetScale()
41
onWidthChanged: image.resetScale()
46
objectName: "imageContainer"
47
width: Math.max(image.width * image.scale, flickable.width)
48
height: Math.max(image.height * image.scale, flickable.height)
53
property alias imageStatus: imageRenderer.status
54
property var prevScale
55
anchors.centerIn: parent
61
objectName: "imageRenderer"
62
smooth: !flickable.movingVertically
64
fillMode: Image.PreserveAspectFit
66
readonly property int sourceSizeMultiplier: 3
68
sourceSize.width: root.width * sourceSizeMultiplier <= root.height * sourceSizeMultiplier ? root.width * sourceSizeMultiplier : 0
69
sourceSize.height: root.height * sourceSizeMultiplier <= root.width * sourceSizeMultiplier ? root.height * sourceSizeMultiplier : 0
72
if (status === Image.Ready) {
73
image.imageReloaded();
79
image.height = imageRenderer.implicitHeight
80
image.width = imageRenderer.implicitWidth
84
function resetScale() {
85
image.scale = Math.min(flickable.width / image.width, flickable.height / image.height);
86
pinchArea.minScale = image.scale;
87
prevScale = Math.min(image.scale, 1);
91
var currentWidth = width * scale
92
var currentHeight = height * scale
93
var scaleRatio = scale / prevScale
94
if (currentWidth > flickable.width) {
95
var xpos = flickable.width / 2 + flickable.contentX;
96
var xoff = xpos * scaleRatio;
97
flickable.contentX = xoff - flickable.width / 2;
99
if (currentHeight > flickable.height) {
100
var ypos = flickable.height / 2 + flickable.contentY;
101
var yoff = ypos * scaleRatio;
102
flickable.contentY = yoff - flickable.height / 2;
111
objectName: "pinchArea"
112
property real minScale: 1.0
114
enabled: zoomable ? zoomable : false
117
pinch.minimumScale: minScale
118
pinch.maximumScale: 10
120
onPinchFinished: flickable.returnToBounds()
125
objectName: "mouseArea"
128
enabled: zoomable ? zoomable : false
131
var startScale = image.scale;
132
if (wheel.angleDelta.y > 0) {
133
image.scale = startScale + 0.1;
134
} else if (wheel.angleDelta.y < 0) {
135
if (image.scale > 0.1 && image.scale > pinchArea.minScale) {
136
image.scale = startScale - 0.1;
139
wheel.accepted = true;
143
mouse.accepted = false;
147
mouse.accepted = false;
151
mouse.accepted = false;