on xenial help sign in
better animating + fixes
commit39122b05f60b518a65d55d4b10ac2f9ddb31297e authorNick Dedekind <nicholas.dedekind@gmail.com> dateTue 22 Jul 2014, 14:03 (12 years ago) parentc25c21e
6 files changed+208−93
qml/Stages/Animations/BaseSurfaceAnimation.qml+70 qml/Stages/Animations/SwipeFromBottomAnimation.qml+48 qml/Stages/Animations/SwipeUpAnimation.qml+49 qml/Stages/SurfaceContainer.qml+32−90 tests/mocks/Unity/Application/ApplicationDBusAdaptor.cpp+1−1 tests/mocks/Unity/Application/MirSurfaceItem.cpp+8−2
qml/Stages/Animations/BaseSurfaceAnimation.qmlnew file+70
@@ -0,0 +1,70 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
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.
7+ *
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.
12+ *
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/>.
15+ */
16+
17+import QtQuick 2.0
18+
19+Item {
20+ id: base
21+ property Item surface: null
22+ property Item surfaceArea: null
23+
24+ property list<QtObject> outChanges
25+ property list<QtObject> outAnimations
26+
27+ property list<QtObject> inChanges
28+ property list<QtObject> inAnimations
29+
30+ function start() {
31+ state = "prep"
32+ state = "in";
33+ }
34+ function end() {
35+ state = "out";
36+ }
37+
38+ states: [
39+ State {
40+ name: "baseAnimation"
41+ PropertyChanges { target: base.surface; anchors.fill: undefined }
42+ },
43+
44+ State {
45+ name: "prep"
46+ extend: "baseAnimation"
47+ changes: outChanges
48+ },
49+ State {
50+ name: "out"
51+ extend: "prep"
52+ },
53+ State {
54+ name: "in"
55+ extend: "baseAnimation"
56+ changes: inChanges
57+ }
58+ ]
59+
60+ transitions: [
61+ Transition {
62+ to: "out"
63+ animations: outAnimations
64+ },
65+ Transition {
66+ to: "in"
67+ animations: inAnimations
68+ }
69+ ]
70+}
qml/Stages/Animations/SwipeFromBottomAnimation.qmlnew file+48
@@ -0,0 +1,48 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
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.
7+ *
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.
12+ *
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/>.
15+ */
16+
17+import QtQuick 2.0
18+
19+BaseSurfaceAnimation {
20+ id: animation
21+
22+ outChanges: [ AnchorChanges { target: animation.surface; anchors.top: animation.surfaceArea.bottom } ]
23+ outAnimations: [
24+ SequentialAnimation {
25+ PropertyAction { target: animation.parent; property: "clip"; value: true }
26+ AnchorAnimation { easing.type: Easing.InOutQuad; duration: 400 }
27+ PropertyAction { target: animation.surface; property: "visible"; value: !animation.parent.removing }
28+ PropertyAction { target: animation.parent; property: "clip"; value: false }
29+ ScriptAction { script: { if (animation.parent.removing) animation.surface.release() } }
30+ }
31+ ]
32+
33+ inChanges: [
34+ AnchorChanges {
35+ target: animation.surface;
36+ anchors.top: animation.surfaceArea.top
37+ anchors.right: undefined
38+ anchors.bottom: undefined
39+ anchors.left: undefined
40+ } ]
41+ inAnimations: [
42+ SequentialAnimation {
43+ PropertyAction { target: animation.parent; property: "clip"; value: true }
44+ AnchorAnimation { easing.type: Easing.InOutQuad; duration: 400 }
45+ PropertyAction { target: animation.parent; property: "clip"; value: false }
46+ }
47+ ]
48+}
qml/Stages/Animations/SwipeUpAnimation.qmlnew file+49
@@ -0,0 +1,49 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
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.
7+ *
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.
12+ *
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/>.
15+ */
16+
17+import QtQuick 2.0
18+
19+BaseSurfaceAnimation {
20+ id: animation
21+
22+ outAnimations: [
23+ SequentialAnimation {
24+ PropertyAction { target: animation.parent; property: "clip"; value: true }
25+ PropertyAction { target: animation.surface; property: "visible"; value: true }
26+ AnchorAnimation { easing.type: Easing.InOutQuad; duration: 400 }
27+ PropertyAction { target: animation.parent; property: "clip"; value: false }
28+ ScriptAction { script: { if (animation.parent.removing) animation.surface.release() } }
29+ }
30+ ]
31+
32+ inChanges: [
33+ AnchorChanges {
34+ target: animation.surface;
35+ anchors.top: undefined
36+ anchors.right: undefined
37+ anchors.bottom: animation.surfaceArea.top
38+ anchors.left: undefined
39+ }
40+ ]
41+ inAnimations: [
42+ SequentialAnimation {
43+ PropertyAction { target: animation.parent; property: "clip"; value: true }
44+ AnchorAnimation { easing.type: Easing.InOutQuad; duration: 400 }
45+ PropertyAction { target: animation.surface; property: "visible"; value: false}
46+ PropertyAction { target: animation.parent; property: "clip"; value: false }
47+ }
48+ ]
49+}
qml/Stages/SurfaceContainer.qml+32−90
@@ -15,6 +15,7 @@
1515*/
1616
1717import QtQuick 2.0
18+import "Animations"
1819
1920Item {
2021 id: container
@@ -38,11 +39,21 @@ Item {
3839 Connections {
3940 target: surface
4041 onRemoved: {
42+ container.removing = true;
43+
44+ var childSurfaces = surface.childSurfaces;
45+ for (var i=0; i<childSurfaces.length; i++) {
46+ childSurfaces[i].removed();
47+ }
48+
49+ //if we don't have children, nothing will tell us to animate out, so do it.
50+ if (childSurfaces.length === 0) {
51+ animateOut();
52+ }
53+ // tell our parent to animate out.
4154 if (surface.parentSurface) {
4255 surface.parentSurface.parent.animateOut();
4356 }
44− container.removing = true;
45− animateOut();
4657 }
4758 }
4859
@@ -57,30 +68,27 @@ Item {
5768 source: Qt.resolvedUrl("SurfaceContainer.qml")
5869 onLoaded: {
5970 item.surface = modelData;
60− item.animateIn("swipeFromBottom");
61− container.animateIn("swipeUp");
71+ item.animateIn(swipeFromBottom);
72+ container.animateIn(swipeUp);
6273 }
6374 }
6475 }
6576
66− function animateIn(type) {
77+ function animateIn(component) {
78+ var animation = component.createObject(container, { "surface": container.surface, "surfaceArea": container.surfaceArea });
79+ animation.start();
80+
6781 var tmp = d.animations;
68− tmp.push(type);
82+ tmp.push(animation);
6983 d.animations = tmp;
70−
71− container.state = d.currentAnimation + "-prep";
72− container.state = d.currentAnimation + "-in";
7384 }
7485
7586 function animateOut() {
7687 if (d.animations.length > 0) {
7788 var tmp = d.animations;
7889 var popped = tmp.pop();
90+ popped.end();
7991 d.animations = tmp;
80− container.state = popped + "-out";
81− if (d.currentAnimation !== "") {
82− container.state = d.currentAnimation + "-in";
83− }
8492 } else {
8593 container.state = "initial";
8694 }
@@ -88,90 +96,24 @@ Item {
8896
8997 QtObject {
9098 id: d
91− property variant animations: []
92− property string currentAnimation: animations.length > 0 ? animations[animations.length-1] : ""
99+ property var animations: []
100+ property var currentAnimation: animations.length > 0 ? animations[animations.length-1] : undefined
101+ }
102+
103+ Component {
104+ id: swipeFromBottom
105+ SwipeFromBottomAnimation {}
106+ }
107+ Component {
108+ id: swipeUp
109+ SwipeUpAnimation {}
93110 }
94111
95112 states: [
96113 State {
97114 name: "initial"
98115 PropertyChanges { target: surface; anchors.fill: surfaceArea }
99− },
100−
101− State {
102− name: "baseAnimation"
103− PropertyChanges { target: surface; anchors.fill: undefined }
104− },
105−
106− State {
107− name: "swipeFromBottom-prep"
108− extend: "baseAnimation"
109− AnchorChanges { target: surface; anchors.top: surfaceArea.bottom }
110− },
111− State {
112− name: "swipeFromBottom-out"
113− extend: "swipeFromBottom-prep"
114− },
115− State {
116− name: "swipeFromBottom-in"
117− extend: "baseAnimation"
118− AnchorChanges { target: surface; anchors.top: surfaceArea.top }
119− },
120−
121− State {
122− name: "swipeUp-prep"
123− extend: "baseAnimation"
124− },
125− State {
126− name: "swipeUp-out"
127− extend: "swipeUp-prep"
128− },
129− State {
130− name: "swipeUp-in"
131− extend: "baseAnimation"
132− AnchorChanges { target: surface; anchors.bottom: surfaceArea.top }
133116 }
134117 // TODO: more animations!
135118 ]
136−
137− transitions: [
138− Transition {
139− to: "swipeFromBottom-in"
140− SequentialAnimation {
141− PropertyAction { target: surface.parent; property: "clip"; value: true }
142− AnchorAnimation { easing.type: Easing.InOutQuad; duration: 400 }
143− PropertyAction { target: surface.parent; property: "clip"; value: false }
144− }
145− },
146− Transition {
147− to: "swipeFromBottom-out"
148− SequentialAnimation {
149− PropertyAction { target: surface.parent; property: "clip"; value: true }
150− AnchorAnimation { easing.type: Easing.InOutQuad; duration: 400 }
151− PropertyAction { target: surface; property: "visible"; value: !removing }
152− PropertyAction { target: surface.parent; property: "clip"; value: false }
153− ScriptAction { script: { if (container.removing) surface.release() } }
154− }
155− },
156−
157− Transition {
158− to: "swipeUp-in"
159− SequentialAnimation {
160− PropertyAction { target: surface.parent; property: "clip"; value: true }
161− AnchorAnimation { easing.type: Easing.InOutQuad; duration: 400 }
162− PropertyAction { target: surface; property: "visible"; value: false}
163− PropertyAction { target: surface.parent; property: "clip"; value: false }
164− }
165− },
166− Transition {
167− to: "swipeUp-out"
168− SequentialAnimation {
169− PropertyAction { target: surface.parent; property: "clip"; value: true }
170− PropertyAction { target: surface; property: "visible"; value: true }
171− AnchorAnimation { easing.type: Easing.InOutQuad; duration: 400 }
172− PropertyAction { target: surface.parent; property: "clip"; value: false }
173− ScriptAction { script: { if (container.removing) surface.release() } }
174− }
175− }
176− ]
177119}
tests/mocks/Unity/Application/ApplicationDBusAdaptor.cpp+1−1
@@ -53,7 +53,7 @@ quint32 ApplicationDBusAdaptor::addChildSurface(const QString &appId, const QStr
5353 ApplicationInfo* application = m_applicationManager->findApplication(appId);
5454 if (!application) {
5555 qDebug() << "ApplicationDBusAdaptor::addChildSurface - No application found for " << appId;
56− return ~0;
56+ return 0;
5757 }
5858 quint32 surfaceId = ++nextId;
5959 MirSurfaceItem* surface = new MirSurfaceItem(QString("ChildSurface%1").arg(surfaceId),
tests/mocks/Unity/Application/MirSurfaceItem.cpp+8−2
@@ -64,10 +64,16 @@ void MirSurfaceItem::release()
6464 for (MirSurfaceItem* child : children) {
6565 child->release();
6666 }
67+ if (m_parentSurface) {
68+ m_parentSurface->removeChildSurface(this);
69+ }
6770
68− if (m_application)
71+ if (m_application) {
6972 m_application->setSurface(nullptr);
70− this->deleteLater();
73+ }
74+ if (!parent()) {
75+ deleteLater();
76+ }
7177}
7278
7379void MirSurfaceItem::setApplication(ApplicationInfo* application)