Unity 8
SessionContainer.qml
1 /*
2  * Copyright 2014-2015 Canonical Ltd.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16 
17 import QtQuick 2.4
18 import "Animations"
19 
20 FocusScope {
21  id: root
22  objectName: "sessionContainer"
23  implicitWidth: _surfaceContainer.implicitWidth
24  implicitHeight: _surfaceContainer.implicitHeight
25  property QtObject session
26  readonly property var childSessions: session ? session.childSessions : null
27  readonly property alias surface: _surfaceContainer.surface
28  property alias interactive: _surfaceContainer.interactive
29  property alias surfaceOrientationAngle: _surfaceContainer.surfaceOrientationAngle
30  property alias resizeSurface: _surfaceContainer.resizeSurface
31 
32  property int requestedWidth: -1
33  property int requestedHeight: -1
34 
35  readonly property alias surfaceContainer: _surfaceContainer
36  SurfaceContainer {
37  id: _surfaceContainer
38  requestedWidth: root.requestedWidth
39  requestedHeight: root.requestedHeight
40  surface: session ? session.lastSurface : null
41  }
42 
43  // SurfaceContainer size drives SessionContainer size
44  Binding {
45  target: root; property: "width"; value: _surfaceContainer.width
46  when: root.requestedWidth >= 0
47  }
48  Binding {
49  target: root; property: "height"; value: _surfaceContainer.height
50  when: root.requestedHeight >= 0
51  }
52 
53  // SessionContainer size drives SurfaceContainer size
54  Binding {
55  target: _surfaceContainer; property: "width"; value: root.width
56  when: root.requestedWidth < 0
57  }
58  Binding {
59  target: _surfaceContainer; property: "height"; value: root.height
60  when: root.requestedHeight < 0
61  }
62 
63  Repeater {
64  id: childSessionsRepeater
65  model: root.childSessions
66 
67  delegate: Loader {
68  objectName: "childDelegate" + index
69  anchors.fill: surfaceContainer
70 
71  // Only way to do recursive qml items.
72  source: Qt.resolvedUrl("SessionContainer.qml")
73 
74  z: index
75 
76  // Since a Loader is a FocusScope, propagate its focus to the loaded Item
77  Binding {
78  target: item; when: item
79  property: "focus"; value: focus
80  }
81 
82  Binding {
83  target: item; when: item
84  property: "interactive"; value: index == (childSessionsRepeater.count - 1) && root.interactive
85  }
86 
87  Binding {
88  target: item; when: item
89  property: "session"; value: modelData
90  }
91 
92  Binding {
93  target: item; when: item
94  property: "width"; value: root.width
95  }
96 
97  Binding {
98  target: item; when: item
99  property: "height"; value: root.height
100  }
101  }
102  }
103 
104  states: [
105  State {
106  name: "rootSession"
107  when: root.session && !root.session.parentSession
108  },
109 
110  State {
111  name: "childSession"
112  when: root.session && root.session.parentSession !== null && root.session.live
113  && !root.session.lastSurface
114  },
115 
116  State {
117  name: "childSessionReady"
118  when: root.session && root.session.parentSession !== null && root.session.live
119  && root.session.lastSurface !== null
120  },
121 
122  State {
123  name: "childSessionZombie"
124  when: root.session && root.session.parentSession !== null && !root.session.live
125  }
126  ]
127 
128  transitions: [
129  Transition {
130  to: "childSessionReady"
131  ScriptAction { script: { if (!surfaceContainer.hadSurface) { animateIn(swipeFromBottom); } } }
132  },
133  Transition {
134  to: "childSessionZombie"
135  ScriptAction { script: { animateOut(); } }
136  }
137  ]
138 
139  function animateIn(component) {
140  var animation = component.createObject(root, { "container": root, });
141  animation.start();
142 
143  var tmp = d.animations;
144  tmp.push(animation);
145  d.animations = tmp;
146  }
147 
148  function animateOut() {
149  if (d.animations.length > 0) {
150  var tmp = d.animations;
151  var popped = tmp.pop();
152  popped.completed.connect(function() { root.session.release(); } );
153  popped.end();
154  d.animations = tmp;
155  }
156  }
157 
158  Component {
159  id: swipeFromBottom
160  SwipeFromBottomAnimation {}
161  }
162 
163  QtObject {
164  id: d
165  property var animations: []
166 
167  property var focusedChild: {
168  if (childSessionsRepeater.count == 0) {
169  return _surfaceContainer;
170  } else {
171  return childSessionsRepeater.itemAt(childSessionsRepeater.count - 1);
172  }
173  }
174  onFocusedChildChanged: {
175  focusedChild.focus = true;
176  }
177  }
178 }