on xenial help sign in
Refactor PreviewOverlay to fix weird zoom out/in animations when previewing images from the Previews

Approved by: Albert Astals Cid

commit28b1389ff10957149fb833d388d8a0452c26b21a authorAndrea Cimitan <andrea.cimitan@gmail.com> dateWed 18 Mar 2015, 10:18 (12 years ago) parent7c945c22f76ee3
4 files changed+106−36
qml/Dash/Previews/PreviewImageGallery.qml+25−6 qml/Dash/Previews/PreviewOverlay.qml+77−26 qml/Dash/Previews/PreviewZoomableImage.qml+3−3 tests/qmltests/Dash/Previews/tst_PreviewImageGallery.qml+1−1
qml/Dash/Previews/PreviewImageGallery.qml+25−6
@@ -38,6 +38,8 @@ PreviewWidget {
3838 model: root.widgetData["sources"]
3939 clip: true
4040
41+ onCurrentIndexChanged: overlay.updateInitialItem()
42+
4143 LazyImage {
4244 objectName: "placeholderScreenshot"
4345 anchors {
@@ -65,9 +67,8 @@ PreviewWidget {
6567 id: mouseArea
6668 anchors.fill: parent
6769 onClicked: {
68− overlay.delegateItem.currentIndex = index;
69− overlay.initialX = rootItem.mapFromItem(parent, 0, 0).x;
70− overlay.initialY = rootItem.mapFromItem(parent, 0, 0).y;
70+ previewImageListView.currentIndex = index;
71+ overlay.updateInitialItem();
7172 overlay.show();
7273 }
7374 }
@@ -78,9 +79,14 @@ PreviewWidget {
7879 id: overlay
7980 objectName: "overlay"
8081 parent: rootItem
81− width: parent.width
82− height: parent.height
83− initialScale: previewImageListView.height / rootItem.height
82+ anchors.fill: parent
83+
84+ function updateInitialItem() {
85+ initialX = rootItem.mapFromItem(previewImageListView.currentItem, 0, 0).x;
86+ initialY = rootItem.mapFromItem(previewImageListView.currentItem, 0, 0).y;
87+ initialWidth = previewImageListView.currentItem.width;
88+ initialHeight = previewImageListView.currentItem.height;
89+ }
8490
8591 delegate: ListView {
8692 id: overlayListView
@@ -92,6 +98,19 @@ PreviewWidget {
9298 snapMode: ListView.SnapOneItem
9399 boundsBehavior: Flickable.DragAndOvershootBounds
94100 model: root.widgetData["sources"]
101+ currentIndex: previewImageListView.currentIndex
102+
103+ onCurrentIndexChanged: {
104+ // if the index changed while overlay is visible, it was from user interaction,
105+ // let's update the index of the original listview
106+ if (overlay.visible) {
107+ previewImageListView.highlightMoveDuration = 0;
108+ previewImageListView.highlightResizeDuration = 0;
109+ previewImageListView.currentIndex = currentIndex;
110+ previewImageListView.highlightMoveDuration = -1;
111+ previewImageListView.highlightResizeDuration = -1;
112+ }
113+ }
95114
96115 delegate: Image {
97116 id: screenshot
qml/Dash/Previews/PreviewOverlay.qml+77−26
@@ -22,48 +22,99 @@ Rectangle {
2222 id: overlay
2323 objectName: "overlay"
2424
25− readonly property real scaleProgress: (scale - initialScale) / (1.0 - initialScale)
25+ readonly property real aspectRatio: width / height
26+ readonly property real initialAspectRatio: initialWidth / initialHeight
27+ readonly property real initialXScale: initialWidth / width
28+ readonly property real initialYScale: initialHeight / height
2629
2730 property alias delegate: loader.sourceComponent
2831 property alias delegateItem: loader.item
2932 property alias headerShown: overlayHeader.shown
30− property bool shown: false
31− property bool opening: false
3233 property real initialX: 0
3334 property real initialY: 0
34− property real initialScale: 0
35−
36− visible: scale > initialScale
37− clip: visible && scale < 1.0
38− scale: shown ? 1.0 : initialScale
35+ property real initialWidth: 1
36+ property real initialHeight: 1
37+
38+ property real xScale: initialXScale
39+ property real yScale: initialYScale
40+ property real progress: 0
41+
42+ implicitWidth: 1
43+ implicitHeight: 1
44+ visible: progress > 0
45+ clip: progress > 0 && progress < 1
46+ color: Qt.rgba(0, 0, 0, progress)
3947 transformOrigin: Item.TopLeft
40− transform: Translate {
41− x: overlay.initialX - overlay.initialX * overlay.scaleProgress
42− y: overlay.initialY - overlay.initialY * overlay.scaleProgress
43− }
44− color: Qt.rgba(0, 0, 0, scaleProgress)
45− radius: units.gu(1) - units.gu(1) * scaleProgress
48+ transform: [
49+ Scale {
50+ origin.x: 0
51+ origin.y: 0
52+ xScale: overlay.xScale
53+ yScale: overlay.yScale
54+ },
55+ Translate {
56+ x: overlay.initialX - overlay.initialX * overlay.progress
57+ y: overlay.initialY - overlay.initialY * overlay.progress
58+ }
59+ ]
60+ state: "hidden"
61+ states: [
62+ State {
63+ name: "shown"
64+ PropertyChanges { target: overlay; progress: 1; xScale: 1; yScale: 1 }
65+ },
66+ State {
67+ name: "hidden"
68+ PropertyChanges { target: overlay; progress: 0; xScale: initialXScale; yScale: initialYScale }
69+ }
70+ ]
71+ transitions: [
72+ Transition {
73+ from: "hidden"
74+ to: "shown"
75+ UbuntuNumberAnimation {
76+ target: overlay
77+ properties: "progress,xScale,yScale"
78+ duration: UbuntuAnimation.FastDuration
79+ }
80+ },
81+ Transition {
82+ from: "shown"
83+ to: "hidden"
84+ UbuntuNumberAnimation {
85+ target: overlay
86+ properties: "progress,xScale,yScale"
87+ duration: UbuntuAnimation.FastDuration / 2
88+ }
89+ }
90+ ]
4691
4792 function show() {
48− opening = true;
49− shown = true;
93+ state = "shown"
5094 }
5195
5296 function hide() {
53− opening = false;
54− shown = false;
55− }
56−
57− Behavior on scale {
58− UbuntuNumberAnimation {
59− duration: overlay.opening ? UbuntuAnimation.FastDuration :
60− UbuntuAnimation.FastDuration / 2
61− }
97+ state = "hidden"
6298 }
6399
64100 Loader {
65101 id: loader
66102 anchors.fill: parent
103+
104+ readonly property bool verticalScaling: initialAspectRatio / aspectRatio >= 1
105+ readonly property real initialXScale: verticalScaling ? 1 : aspectRatio / initialAspectRatio
106+ readonly property real initialYScale: verticalScaling ? initialAspectRatio / aspectRatio : 1
107+ readonly property real xScale: verticalScaling ? loader.initialXScale - loader.initialXScale * overlay.progress + overlay.progress :
108+ loader.yScale * overlay.yScale / overlay.xScale
109+ readonly property real yScale: verticalScaling ? loader.xScale * overlay.xScale / overlay.yScale :
110+ loader.initialYScale - loader.initialYScale * overlay.progress + overlay.progress
111+
112+ transform: Scale {
113+ origin.x: parent.width / 2
114+ origin.y: parent.height / 2
115+ xScale: loader.xScale
116+ yScale: loader.yScale
117+ }
67118 }
68119
69120 Rectangle {
@@ -77,7 +128,7 @@ Rectangle {
77128 }
78129 height: units.gu(7)
79130 visible: opacity > 0
80− opacity: overlay.scaleProgress > 0.6 && shown ? 0.8 : 0
131+ opacity: overlay.state == "shown" && overlay.progress > 0.8 && shown ? 0.8 : 0
81132 color: "black"
82133
83134 Behavior on opacity {
qml/Dash/Previews/PreviewZoomableImage.qml+3−3
@@ -59,9 +59,9 @@ PreviewWidget {
5959 id: overlay
6060 objectName: "overlay"
6161 parent: rootItem
62− width: parent.width
63− height: parent.height
64− initialScale: lazyImage.height / rootItem.height
62+ anchors.fill: parent
63+ initialWidth: lazyImage.width
64+ initialHeight: lazyImage.height
6565
6666 delegate: ZoomableImage {
6767 anchors.fill: parent
tests/qmltests/Dash/Previews/tst_PreviewImageGallery.qml+1−1
@@ -22,7 +22,7 @@ import Unity.Test 0.1 as UT
2222Rectangle {
2323 id: root
2424 width: units.gu(80)
25− height: units.gu(80)
25+ height: units.gu(70)
2626 color: "lightgrey"
2727
2828 property var sourcesModel0: {