Unity 8
 All Classes Functions
ApplicationWindow.qml
1 /*
2  * Copyright 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 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.0
18 import Ubuntu.Components 1.1
19 import Unity.Application 0.1
20 
21 Item {
22  id: root
23 
24  // to be read from outside
25  readonly property bool fullscreen: application ? application.fullscreen : false
26  property alias interactive: sessionContainer.interactive
27 
28  // to be set from outside
29  property QtObject application
30  property int orientation
31 
32  QtObject {
33  id: d
34 
35  // helpers so that we don't have to check for the existence of an application everywhere
36  // (in order to avoid breaking qml binding due to a javascript exception)
37  readonly property string name: root.application ? root.application.name : ""
38  readonly property url icon: root.application ? root.application.icon : ""
39  readonly property int applicationState: root.application ? root.application.state : -1
40 
41  // Whether the Application had a surface before but lost it.
42  property bool hadSurface: sessionContainer.surfaceContainer.hadSurface
43 
44  property bool needToTakeScreenshot:
45  sessionContainer.surface && d.surfaceInitialized && screenshotImage.status === Image.Null
46  && d.applicationState === ApplicationInfoInterface.Stopped
47  onNeedToTakeScreenshotChanged: {
48  if (needToTakeScreenshot) {
49  screenshotImage.take();
50  }
51  }
52 
53  //FIXME - this is a hack to avoid the first few rendered frames as they
54  // might show the UI accommodating due to surface resizes on startup.
55  // Remove this when possible
56  property bool surfaceInitialized: false
57 
58  function forceSurfaceActiveFocusIfReady() {
59  if (sessionContainer.surface !== null &&
60  sessionContainer.surface.focus &&
61  sessionContainer.surface.parent === sessionContainer.surfaceContainer &&
62  sessionContainer.surface.enabled) {
63  sessionContainer.surface.forceActiveFocus();
64  }
65  }
66  }
67 
68  Timer {
69  id: surfaceInitTimer
70  interval: 100
71  onTriggered: { if (sessionContainer.surface) {d.surfaceInitialized = true;} }
72  }
73 
74  Connections {
75  target: sessionContainer.surface
76  // FIXME: I would rather not need to do this, but currently it doesn't get
77  // active focus without it and I don't know why.
78  onFocusChanged: d.forceSurfaceActiveFocusIfReady();
79  onParentChanged: d.forceSurfaceActiveFocusIfReady();
80  onEnabledChanged: d.forceSurfaceActiveFocusIfReady();
81  }
82 
83  Image {
84  id: screenshotImage
85  objectName: "screenshotImage"
86  source: ""
87  anchors.fill: parent
88 
89  function take() {
90  // Format: "image://application/$APP_ID/$CURRENT_TIME_MS"
91  // eg: "image://application/calculator-app/123456"
92  var timeMs = new Date().getTime();
93  source = "image://application/" + root.application.appId + "/" + timeMs;
94  }
95 
96  // Save memory by using a half-resolution (thus quarter size) screenshot
97  sourceSize.width: root.width / 2
98  sourceSize.height: root.height / 2
99  }
100 
101  Loader {
102  id: splashLoader
103  visible: active
104  active: false
105  anchors.fill: parent
106  sourceComponent: Component {
107  Splash { name: d.name; image: d.icon }
108  }
109  }
110 
111  SessionContainer {
112  id: sessionContainer
113  session: application ? application.session : null
114  anchors.fill: parent
115  orientation: root.orientation
116 
117  onSurfaceChanged: {
118  if (sessionContainer.surface) {
119  surfaceInitTimer.start();
120  d.forceSurfaceActiveFocusIfReady();
121  } else {
122  d.surfaceInitialized = false;
123  }
124  }
125  }
126 
127  StateGroup {
128  objectName: "applicationWindowStateGroup"
129  states: [
130  State {
131  name: "void"
132  when:
133  d.hadSurface && (!sessionContainer.surface || !d.surfaceInitialized)
134  &&
135  screenshotImage.status !== Image.Ready
136  },
137  State {
138  name: "splashScreen"
139  when:
140  !d.hadSurface && (!sessionContainer.surface || !d.surfaceInitialized)
141  &&
142  screenshotImage.status !== Image.Ready
143  },
144  State {
145  name: "surface"
146  when:
147  (sessionContainer.surface && d.surfaceInitialized)
148  &&
149  (d.applicationState !== ApplicationInfoInterface.Stopped
150  || screenshotImage.status !== Image.Ready)
151  },
152  State {
153  name: "screenshot"
154  when:
155  screenshotImage.status === Image.Ready
156  &&
157  (d.applicationState === ApplicationInfoInterface.Stopped
158  || !sessionContainer.surface || !d.surfaceInitialized)
159  }
160  ]
161 
162  transitions: [
163  Transition {
164  from: ""; to: "splashScreen"
165  PropertyAction { target: splashLoader; property: "active"; value: true }
166  PropertyAction { target: sessionContainer.surfaceContainer
167  property: "visible"; value: false }
168  },
169  Transition {
170  from: "splashScreen"; to: "surface"
171  SequentialAnimation {
172  PropertyAction { target: sessionContainer.surfaceContainer
173  property: "opacity"; value: 0.0 }
174  PropertyAction { target: sessionContainer.surfaceContainer
175  property: "visible"; value: true }
176  UbuntuNumberAnimation { target: sessionContainer.surfaceContainer; property: "opacity";
177  from: 0.0; to: 1.0
178  duration: UbuntuAnimation.BriskDuration }
179  PropertyAction { target: splashLoader; property: "active"; value: false }
180  }
181  },
182  Transition {
183  from: "surface"; to: "splashScreen"
184  SequentialAnimation {
185  PropertyAction { target: splashLoader; property: "active"; value: true }
186  PropertyAction { target: sessionContainer.surfaceContainer
187  property: "visible"; value: true }
188  UbuntuNumberAnimation { target: splashLoader; property: "opacity";
189  from: 0.0; to: 1.0
190  duration: UbuntuAnimation.BriskDuration }
191  PropertyAction { target: sessionContainer.surfaceContainer
192  property: "visible"; value: false }
193  }
194  },
195  Transition {
196  from: "surface"; to: "screenshot"
197  SequentialAnimation {
198  PropertyAction { target: screenshotImage
199  property: "visible"; value: true }
200  UbuntuNumberAnimation { target: screenshotImage; property: "opacity";
201  from: 0.0; to: 1.0
202  duration: UbuntuAnimation.BriskDuration }
203  PropertyAction { target: sessionContainer.surfaceContainer
204  property: "visible"; value: false }
205  ScriptAction { script: { if (sessionContainer.session) { sessionContainer.session.release(); } } }
206  }
207  },
208  Transition {
209  from: "screenshot"; to: "surface"
210  SequentialAnimation {
211  PropertyAction { target: sessionContainer.surfaceContainer
212  property: "visible"; value: true }
213  UbuntuNumberAnimation { target: screenshotImage; property: "opacity";
214  from: 1.0; to: 0.0
215  duration: UbuntuAnimation.BriskDuration }
216  PropertyAction { target: screenshotImage; property: "visible"; value: false }
217  PropertyAction { target: screenshotImage; property: "source"; value: "" }
218  }
219  },
220  Transition {
221  from: "surface"; to: "void"
222  SequentialAnimation {
223  PropertyAction { target: sessionContainer.surfaceContainer; property: "visible"; value: false }
224  ScriptAction { script: { if (sessionContainer.session) { sessionContainer.session.release(); } } }
225  }
226  },
227  Transition {
228  from: "void"; to: "surface"
229  SequentialAnimation {
230  PropertyAction { target: sessionContainer.surfaceContainer; property: "opacity"; value: 0.0 }
231  PropertyAction { target: sessionContainer.surfaceContainer; property: "visible"; value: true }
232  UbuntuNumberAnimation { target: sessionContainer.surfaceContainer; property: "opacity";
233  from: 0.0; to: 1.0
234  duration: UbuntuAnimation.BriskDuration }
235  }
236  }
237  ]
238  }
239 
240 }