Merge lp:~fboucault/camera-app/gallery_pinch_to_zoom into lp:camera-app

Proposed by Florian Boucault
Status: Merged
Approved by: Ugo Riboni
Approved revision: 350
Merged at revision: 353
Proposed branch: lp:~fboucault/camera-app/gallery_pinch_to_zoom
Merge into: lp:camera-app
Diff against target: 275 lines (+133/-91)
3 files modified
GalleryView.qml (+1/-0)
SlideshowView.qml (+131/-90)
camera-app.qml (+1/-1)
To merge this branch: bzr merge lp:~fboucault/camera-app/gallery_pinch_to_zoom
Reviewer Review Type Date Requested Status
Ugo Riboni (community) Approve
PS Jenkins bot continuous-integration Needs Fixing
Review via email: mp+230356@code.launchpad.net

Commit message

Photo roll: added pinch to zoom.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ugo Riboni (uriboni) wrote :

Looking good

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'GalleryView.qml'
2--- GalleryView.qml 2014-07-31 19:03:14 +0000
3+++ GalleryView.qml 2014-08-11 17:21:02 +0000
4@@ -25,6 +25,7 @@
5
6 signal exit
7 property bool inView
8+ property bool touchAcquired: slideshowView.touchAcquired
9 property Item currentView: state == "GRID" ? photogridView : slideshowView
10 property var model: FoldersModel {
11 folders: [application.picturesLocation, application.videosLocation]
12
13=== modified file 'SlideshowView.qml'
14--- SlideshowView.qml 2014-07-29 11:57:12 +0000
15+++ SlideshowView.qml 2014-08-11 17:21:02 +0000
16@@ -30,6 +30,7 @@
17 property int currentIndex: listView.currentIndex
18 property string currentFilePath: slideshowView.model.get(slideshowView.currentIndex, "filePath")
19 property string currentFileType: slideshowView.model.get(slideshowView.currentIndex, "fileType")
20+ property bool touchAcquired: listView.currentItem ? listView.currentItem.pinchInProgress : false
21
22 signal toggleHeader
23 property list<Action> actions: [
24@@ -77,13 +78,17 @@
25 highlightRangeMode: ListView.StrictlyEnforceRange
26 snapMode: ListView.SnapOneItem
27 spacing: units.gu(1)
28+ interactive: currentItem ? !currentItem.pinchInProgress : true
29 property real maxDimension: Math.max(width, height)
30
31 delegate: Item {
32- function zoomIn(centerX, centerY) {
33- flickable.scaleCenterX = centerX / flickable.width;
34- flickable.scaleCenterY = centerY / flickable.height;
35- flickable.sizeScale = 3.0;
36+ id: delegate
37+ property bool pinchInProgress: zoomPinchArea.active
38+
39+ function zoomIn(centerX, centerY, factor) {
40+ flickable.scaleCenterX = centerX / (flickable.sizeScale * flickable.width);
41+ flickable.scaleCenterY = centerY / (flickable.sizeScale * flickable.height);
42+ flickable.sizeScale = factor;
43 }
44
45 function zoomOut() {
46@@ -103,94 +108,130 @@
47 running: image.status != Image.Ready
48 }
49
50- Flickable {
51- id: flickable
52+ PinchArea {
53+ id: zoomPinchArea
54 anchors.fill: parent
55- contentWidth: media.width
56- contentHeight: media.height
57- contentX: (sizeScale - 1) * scaleCenterX * width
58- contentY: (sizeScale - 1) * scaleCenterY * height
59-
60- property real sizeScale: 1.0
61- property real scaleCenterX: 0.0
62- property real scaleCenterY: 0.0
63- Behavior on sizeScale { UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration} }
64-
65- Item {
66- id: media
67-
68- width: flickable.width * flickable.sizeScale
69- height: flickable.height * flickable.sizeScale
70-
71- property bool isVideo: MimeTypeMapper.mimeTypeToContentType(fileType) === ContentType.Videos
72-
73- Image {
74- id: image
75- anchors.fill: parent
76- asynchronous: true
77- cache: false
78- source: "image://thumbnailer/" + fileURL.toString()
79- sourceSize {
80- width: listView.maxDimension
81- height: listView.maxDimension
82- }
83- fillMode: Image.PreserveAspectFit
84- opacity: status == Image.Ready ? 1.0 : 0.0
85- Behavior on opacity { UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration} }
86-
87- }
88-
89- Image {
90- id: highResolutionImage
91- anchors.fill: parent
92- asynchronous: true
93- cache: false
94- source: flickable.sizeScale > 1.0 ? fileURL : ""
95- sourceSize {
96- width: width
97- height: height
98- }
99- fillMode: Image.PreserveAspectFit
100- }
101- }
102-
103- Icon {
104- width: units.gu(5)
105- height: units.gu(5)
106- anchors.centerIn: parent
107- name: "media-playback-start"
108- color: "white"
109- opacity: 0.8
110- visible: media.isVideo
111- }
112-
113- MouseArea {
114+
115+ property real initialZoom
116+ property real maximumScale: 3.0
117+ property real minimumZoom: 1.0
118+ property real maximumZoom: 3.0
119+ property bool active: false
120+ property var center
121+
122+ onPinchStarted: {
123+ active = true;
124+ initialZoom = flickable.sizeScale;
125+ center = zoomPinchArea.mapToItem(media, pinch.startCenter.x, pinch.startCenter.y);
126+ zoomIn(center.x, center.y, initialZoom);
127+ }
128+ onPinchUpdated: {
129+ var zoomFactor = MathUtils.clamp(initialZoom * pinch.scale, minimumZoom, maximumZoom);
130+ flickable.sizeScale = zoomFactor;
131+ }
132+ onPinchFinished: {
133+ active = false;
134+ }
135+
136+ Flickable {
137+ id: flickable
138 anchors.fill: parent
139- onClicked: {
140- slideshowView.toggleHeader();
141- mouse.accepted = false;
142- }
143- onDoubleClicked: {
144- if (media.isVideo) {
145- return;
146- }
147-
148- if (flickable.sizeScale == 1.0) {
149- zoomIn(mouse.x, mouse.y);
150- } else {
151- zoomOut();
152- }
153- }
154- }
155-
156- MouseArea {
157- anchors.centerIn: parent
158- width: units.gu(10)
159- height: units.gu(10)
160- enabled: media.isVideo
161- onClicked: {
162- if (media.isVideo) {
163- Qt.openUrlExternally(fileURL);
164+ contentWidth: media.width
165+ contentHeight: media.height
166+ contentX: (sizeScale - 1) * scaleCenterX * width
167+ contentY: (sizeScale - 1) * scaleCenterY * height
168+ interactive: !delegate.pinchInProgress
169+
170+ property real sizeScale: 1.0
171+ property real scaleCenterX: 0.0
172+ property real scaleCenterY: 0.0
173+ Behavior on sizeScale {
174+ enabled: !delegate.pinchInProgress
175+ UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration}
176+ }
177+ Behavior on scaleCenterX {
178+ UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration}
179+ }
180+ Behavior on scaleCenterY {
181+ UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration}
182+ }
183+
184+ Item {
185+ id: media
186+
187+ width: flickable.width * flickable.sizeScale
188+ height: flickable.height * flickable.sizeScale
189+
190+ property bool isVideo: MimeTypeMapper.mimeTypeToContentType(fileType) === ContentType.Videos
191+
192+ Image {
193+ id: image
194+ anchors.fill: parent
195+ asynchronous: true
196+ cache: false
197+ source: "image://thumbnailer/" + fileURL.toString()
198+ sourceSize {
199+ width: listView.maxDimension
200+ height: listView.maxDimension
201+ }
202+ fillMode: Image.PreserveAspectFit
203+ opacity: status == Image.Ready ? 1.0 : 0.0
204+ Behavior on opacity { UbuntuNumberAnimation {duration: UbuntuAnimation.FastDuration} }
205+
206+ }
207+
208+ Image {
209+ id: highResolutionImage
210+ anchors.fill: parent
211+ asynchronous: true
212+ cache: false
213+ source: flickable.sizeScale > 1.0 ? fileURL : ""
214+ sourceSize {
215+ width: width
216+ height: height
217+ }
218+ fillMode: Image.PreserveAspectFit
219+ }
220+ }
221+
222+ Icon {
223+ width: units.gu(5)
224+ height: units.gu(5)
225+ anchors.centerIn: parent
226+ name: "media-playback-start"
227+ color: "white"
228+ opacity: 0.8
229+ visible: media.isVideo
230+ }
231+
232+ MouseArea {
233+ anchors.fill: parent
234+ onClicked: {
235+ slideshowView.toggleHeader();
236+ mouse.accepted = false;
237+ }
238+ onDoubleClicked: {
239+ if (media.isVideo) {
240+ return;
241+ }
242+
243+ if (flickable.sizeScale < zoomPinchArea.maximumZoom) {
244+ zoomIn(mouse.x, mouse.y, zoomPinchArea.maximumZoom);
245+ } else {
246+ zoomOut();
247+ }
248+ }
249+ }
250+
251+ MouseArea {
252+ anchors.centerIn: parent
253+ width: units.gu(10)
254+ height: units.gu(10)
255+ enabled: media.isVideo
256+ onClicked: {
257+ if (media.isVideo) {
258+ Qt.openUrlExternally(fileURL);
259+ }
260 }
261 }
262 }
263
264=== modified file 'camera-app.qml'
265--- camera-app.qml 2014-08-01 15:28:56 +0000
266+++ camera-app.qml 2014-08-11 17:21:02 +0000
267@@ -72,7 +72,7 @@
268 boundsBehavior: Flickable.StopAtBounds
269 contentWidth: contentItem.childrenRect.width
270 contentHeight: contentItem.childrenRect.height
271- interactive: !viewFinderView.touchAcquired
272+ interactive: !viewFinderView.touchAcquired && !galleryView.touchAcquired
273
274 Component.onCompleted: {
275 // FIXME: workaround for qtubuntu not returning values depending on the grid unit definition

Subscribers

People subscribed via source and target branches