2
* Copyright 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 QtMultimedia 5.0
19
import Ubuntu.Components 1.0
20
import Ubuntu.Components.ListItems 1.0 as ListItems
21
import Ubuntu.Components.Popups 1.0
22
import Ubuntu.Content 0.1
23
import Ubuntu.Thumbnailer 0.1
25
import "../Components"
29
property bool pinchInProgress: zoomPinchArea.active
30
property var mediaSource
31
property real maxDimension: 0.
32
property bool showThumbnail: true
34
property bool isVideo: mediaSource.type === MediaSource.Video
35
property bool userInteracting: pinchInProgress || flickable.sizeScale != 1.0
36
property bool fullyZoomed: flickable.sizeScale == zoomPinchArea.maximumZoom
37
property bool fullyUnzoomed: flickable.sizeScale == zoomPinchArea.minimumZoom
38
property bool animateMediaOnHeight: false
39
property bool imageReady: image.status == Image.Ready
41
property alias paintedHeight: image.paintedHeight
42
property alias paintedWidth: image.paintedWidth
47
if (height > viewer.maxDimension)
48
viewer.maxDimension = height;
52
if (width > viewer.maxDimension)
53
viewer.maxDimension = width;
56
function zoomIn(centerX, centerY, factor) {
57
flickable.scaleCenterX = centerX / (flickable.sizeScale * flickable.width);
58
flickable.scaleCenterY = centerY / (flickable.sizeScale * flickable.height);
59
flickable.sizeScale = factor;
63
if (flickable.sizeScale != 1.0) {
64
flickable.scaleCenterX = flickable.contentX / flickable.width / (flickable.sizeScale - 1);
65
flickable.scaleCenterY = flickable.contentY / flickable.height / (flickable.sizeScale - 1);
66
flickable.sizeScale = 1.0;
76
anchors.centerIn: parent
78
running: image.status != Image.Ready
85
property real initialZoom
86
property real maximumScale: 3.0
87
property real minimumZoom: 1.0
88
property real maximumZoom: 3.0
89
property bool active: false
94
initialZoom = flickable.sizeScale;
95
center = zoomPinchArea.mapToItem(media, pinch.startCenter.x, pinch.startCenter.y);
96
zoomIn(center.x, center.y, initialZoom);
99
var zoomFactor = MathUtils.clamp(initialZoom * pinch.scale, minimumZoom, maximumZoom);
100
flickable.sizeScale = zoomFactor;
109
contentWidth: media.width
110
contentHeight: media.height
111
contentX: (sizeScale - 1) * scaleCenterX * width
112
contentY: (sizeScale - 1) * scaleCenterY * height
113
interactive: !viewer.pinchInProgress
115
property real sizeScale: 1.0
116
property real scaleCenterX: 0.0
117
property real scaleCenterY: 0.0
118
Behavior on sizeScale {
119
enabled: !viewer.pinchInProgress
120
UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration}
122
Behavior on scaleCenterX {
123
UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration}
125
Behavior on scaleCenterY {
126
UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration}
132
width: flickable.width * flickable.sizeScale
133
height: flickable.height * flickable.sizeScale
139
image.source = "image://photo/" + mediaSource.path
141
rightResolutionImage.source = "";
142
rightResolutionImage.source = "image://photo/" + mediaSource.path
147
enabled: viewer.animateMediaOnHeight
148
UbuntuNumberAnimation {}
156
source: viewer.isVideo ? "image://thumbnailer/" + mediaSource.path : "image://photo/" + mediaSource.path
158
width: viewer.maxDimension
159
height: viewer.maxDimension
161
fillMode: Image.PreserveAspectFit
162
visible: viewer.showThumbnail
163
opacity: status == Image.Ready ? 1.0 : 0.0
164
Behavior on opacity { UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration} }
169
id: highResolutionImage
173
// Load image using the photo image provider to ensure EXIF orientation
174
source: flickable.sizeScale > 1.0 ? "image://photo/" + mediaSource.path : ""
179
opacity: status == Image.Ready ? 1.0 : 0.0
180
fillMode: Image.PreserveAspectFit
187
anchors.centerIn: parent
188
name: "media-playback-start"
191
visible: viewer.isVideo
197
property bool eventAccepted: false
200
if (viewerMouseArea.eventAccepted)
204
viewer.animateMediaOnHeight = false
206
if (viewer.ListView.view.moving) {
207
// FIXME: workaround for Qt bug specific to touch:
208
// doubleClicked is received even though the MouseArea
209
// was tapped only once but another MouseArea was also
210
// tapped shortly before.
211
// Ref.: https://bugreports.qt.io/browse/QTBUG-39332
214
if (viewer.isVideo) return;
216
if (flickable.sizeScale < zoomPinchArea.maximumZoom) {
217
zoomIn(mouse.x, mouse.y, zoomPinchArea.maximumZoom);
223
viewerMouseArea.eventAccepted = false
231
viewerMouseArea.eventAccepted = true
232
viewer.animateMediaOnHeight = true
239
anchors.centerIn: parent
242
enabled: viewer.isVideo
244
if (viewer.isVideo) {
245
var url = mediaSource.path.toString().replace("file://", "video://");
246
Qt.openUrlExternally(url);