@@ -26,10 +26,11 @@ import "../Components"
29− property alias source: image.source
29+ property alias source: lazyImage.source
30 property var zoomable: false
30 property var zoomable: false
31− property alias state: image.state
31+ property alias imageState: lazyImage.state
32− property alias scale: image.scale
32+ property alias scaleTo: lazyImage.scaleTo
33+ property alias asynchronous: lazyImage.asynchronous
34 Flickable {
35 Flickable {
35 id: flickable
36 id: flickable
@@ -37,8 +38,8 @@ Item {
37 clip: true
38 clip: true
38 contentHeight: imageContainer.height
39 contentHeight: imageContainer.height
39 contentWidth: imageContainer.width
40 contentWidth: imageContainer.width
40− onHeightChanged: image.calculateSize()
41+ onHeightChanged: image.resetScale()
41− onWidthChanged: image.calculateSize()
42+ onWidthChanged: image.resetScale()
42 anchors.fill: parent
43 anchors.fill: parent
@@ -47,40 +48,58 @@ Item {
47 width: Math.max(image.width * image.scale, flickable.width)
48 width: Math.max(image.width * image.scale, flickable.width)
48 height: Math.max(image.height * image.scale, flickable.height)
49 height: Math.max(image.height * image.scale, flickable.height)
50− LazyImage {
51+ Item {
52 objectName: "image"
53 objectName: "image"
53− property real prevScale
54+ property alias imageState: lazyImage.state
54− smooth: !flickable.movingVertically
55+ property var prevScale
55 anchors.centerIn: parent
56 anchors.centerIn: parent
56− fillMode: Image.PreserveAspectFit
62+ objectName: "lazyImage"
63+ smooth: !flickable.movingVertically
65+ fillMode: Image.PreserveAspectFit
69+ if (state == "ready") {
70+ image.imageReloaded();
76+ image.width = flickable.width;
77+ image.height = flickable.height;
58− function calculateSize() {
81+ function resetScale() {
59− image.scale = Math.min(flickable.width / image.width, flickable.height / image.height) * 0.98;
82+ image.scale = Math.min(flickable.width / image.width, flickable.height / image.height);
60 pinchArea.minScale = image.scale;
83 pinchArea.minScale = image.scale;
61 prevScale = Math.min(image.scale, 1);
84 prevScale = Math.min(image.scale, 1);
64 onScaleChanged: {
87 onScaleChanged: {
88+ var currentWidth = width * scale
89+ var currentHeight = height * scale
90+ var scaleRatio = scale / prevScale
65− if ((width * scale) > flickable.width) {
91+ if (currentWidth > flickable.width) {
66− var xoff = (flickable.width / 2 + flickable.contentX) * scale / prevScale;
92+ var xpos = flickable.width / 2 + flickable.contentX;
93+ var xoff = xpos * scaleRatio;
67 flickable.contentX = xoff - flickable.width / 2;
94 flickable.contentX = xoff - flickable.width / 2;
69− if ((height * scale) > flickable.height) {
96+ if (currentHeight > flickable.height) {
70− var yoff = (flickable.height / 2 + flickable.contentY) * scale / prevScale;
97+ var ypos = flickable.height / 2 + flickable.contentY;
98+ var yoff = ypos * scaleRatio;
71 flickable.contentY = yoff - flickable.height / 2;
99 flickable.contentY = yoff - flickable.height / 2;
74 prevScale = scale;
101 prevScale = scale;
78− if (state == "ready") {
79− image.width = flickable.width;
80− image.height = flickable.height;
@@ -88,7 +107,6 @@ Item {
88 id: pinchArea
107 id: pinchArea
89 objectName: "pinchArea"
108 objectName: "pinchArea"
90 property real minScale: 1.0
109 property real minScale: 1.0
91− property real lastScale: 1.0
92 anchors.fill: parent
110 anchors.fill: parent
93 enabled: zoomable ? zoomable : false
111 enabled: zoomable ? zoomable : false
@@ -103,20 +121,14 @@ Item {
103 objectName: "mouseArea"
121 objectName: "mouseArea"
105 anchors.fill: parent
123 anchors.fill: parent
106− property bool doubleClicked: false
107− property bool swipeDone: false
110− property real startScale: pinchArea.minScale
111 enabled: zoomable ? zoomable : false
124 enabled: zoomable ? zoomable : false
113 onWheel: {
126 onWheel: {
127+ var startScale = image.scale;
114 if (wheel.angleDelta.y > 0) {
128 if (wheel.angleDelta.y > 0) {
115− startScale = image.scale;
116 image.scale = startScale + 0.1;
129 image.scale = startScale + 0.1;
117 } else if (wheel.angleDelta.y < 0) {
130 } else if (wheel.angleDelta.y < 0) {
118− startScale = image.scale;
119− if (image.scale > 0.1) {
131+ if (image.scale > 0.1 && image.scale > pinchArea.minScale) {
120 image.scale = startScale - 0.1;
132 image.scale = startScale - 0.1;
@@ -124,21 +136,15 @@ Item {
126 onPressed: {
138 onPressed: {
127− startX = (mouse.x / image.scale);
139+ mouse.accepted = false;
128− startY = (mouse.y / image.scale);
129− startScale = image.scale;
132 onReleased: {
142 onReleased: {
133− if (image.scale == startScale) {
143+ mouse.accepted = false;
134− var deltaX = (mouse.x / image.scale) - startX;
144+ }
135− var deltaY = (mouse.y / image.scale) - startY;
137− if (image.scale == pinchArea.minScale &&
146+ onClicked: {
138− (Math.abs(deltaX) > 50 || Math.abs(deltaY) > 50)) {
147+ mouse.accepted = false;