added android components
[mardrone] / mardrone / imports / com / nokia / android.1.1 / PageStack.js
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the Qt Components project.
8 **
9 ** $QT_BEGIN_LICENSE:BSD$
10 ** You may use this file under the terms of the BSD license as follows:
11 **
12 ** "Redistribution and use in source and binary forms, with or without
13 ** modification, are permitted provided that the following conditions are
14 ** met:
15 **   * Redistributions of source code must retain the above copyright
16 **     notice, this list of conditions and the following disclaimer.
17 **   * Redistributions in binary form must reproduce the above copyright
18 **     notice, this list of conditions and the following disclaimer in
19 **     the documentation and/or other materials provided with the
20 **     distribution.
21 **   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22 **     the names of its contributors may be used to endorse or promote
23 **     products derived from this software without specific prior written
24 **     permission.
25 **
26 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40
41 // Page stack - items are page containers.
42 var pageStack = [];
43
44 // Returns the page stack depth.
45 function getDepth() {
46     return pageStack.length;
47 }
48
49 // Pushes a page on the stack.
50 function push(page, properties, replace, immediate) {
51     // page order sanity check
52     if ((!replace && page == currentPage)
53         || (replace && pageStack.length > 1
54         && page == pageStack[pageStack.length - 2].page)) {
55         throw new Error("Cannot navigate so that the resulting page stack has two consecutive entries of the same page instance.");
56     }
57
58     // figure out if more than one page is being pushed
59     var pages;
60     if (page instanceof Array) {
61         pages = page;
62         page = pages.pop();
63         if (page.createObject === undefined && page.parent === undefined && typeof page != "string") {
64             properties = properties || page.properties;
65             page = page.page;
66         }
67     }
68
69     // get the current container
70     var oldContainer = pageStack[pageStack.length - 1];
71
72     // pop the old container off the stack if this is a replace
73     if (oldContainer && replace) {
74         pageStack.pop();
75     }
76
77     // push any extra defined pages onto the stack
78     if (pages) {
79         var i;
80         for (i = 0; i < pages.length; i++) {
81             var tPage = pages[i];
82             var tProps;
83             if (tPage.createObject === undefined && tPage.parent === undefined && typeof tPage != "string") {
84                 tProps = tPage.properties;
85                 tPage = tPage.page;
86             }
87             pageStack.push(initPage(tPage, tProps));
88         }
89     }
90
91     // initialize the page
92     var container = initPage(page, properties);
93
94     // push the page container onto the stack
95     pageStack.push(container);
96
97     depth = pageStack.length;
98     currentPage = container.page;
99
100     // perform page transition
101     immediate = immediate || !oldContainer;
102     var orientationChange = false;
103     if (oldContainer) {
104         orientationChange = orientationChanges(oldContainer.page, container.page);
105         oldContainer.pushExit(replace, immediate, orientationChange);
106     }
107
108      // sync tool bar
109     var tools = container.page.tools || null;
110     if (toolBar) {
111         toolBar.setTools(tools, immediate ? "set" : replace ? "replace" : "push");
112     }
113
114     container.pushEnter(immediate, orientationChange);
115     return container.page;
116 }
117
118 // Initializes a page and its container.
119 function initPage(page, properties) {
120     var container = containerComponent.createObject(root);
121
122     var pageComp;
123     if (page.createObject) {
124         // page defined as component
125         pageComp = page;
126     } else if (typeof page == "string") {
127         // page defined as string (a url)
128         pageComp = Qt.createComponent(page);
129     }
130     if (pageComp) {
131         if (pageComp.status == Component.Error) {
132             throw new Error("Error while loading page: " + pageComp.errorString());
133         } else {
134             // instantiate page from component
135             page = pageComp.createObject(container);
136         }
137     }
138
139     container.page = page;
140     container.owner = page.parent;
141
142     // the page has to be reparented if
143     if (page.parent != container) {
144         page.parent = container;
145     }
146
147     if (page.pageStack !== undefined) {
148         page.pageStack = root;
149     }
150
151     // copy properties to the page
152     for (var prop in properties) {
153         page[prop] = properties[prop];
154     }
155
156     return container;
157 }
158
159 // Pops a page off the stack.
160 function pop(page, immediate) {
161     // make sure there are enough pages in the stack to pop
162     if (pageStack.length > 1) {
163         // pop the current container off the stack and get the next container
164         var oldContainer = pageStack.pop();
165         var container = pageStack[pageStack.length - 1];
166         if (page !== undefined) {
167             // an unwind target has been specified - pop until we find it
168             while (page != container.page && pageStack.length > 1) {
169                 container.cleanup();
170                 pageStack.pop();
171                 container = pageStack[pageStack.length - 1];
172             }
173         }
174
175         depth = pageStack.length;
176         currentPage = container.page;
177
178         // perform page transition
179         var orientationChange = orientationChanges(oldContainer.page, container.page);
180         oldContainer.popExit(immediate, orientationChange);
181         container.popEnter(immediate, orientationChange);
182
183         // sync tool bar
184         var tools = container.page.tools || null;
185         if (toolBar) {
186             toolBar.setTools(tools, immediate ? "set" : "pop");
187         }
188         return oldContainer.page;
189     } else {
190         return null;
191     }
192 }
193
194 // Checks if the orientation changes between oldPage and newPage
195 function orientationChanges(oldPage, newPage) {
196     return newPage.orientationLock != PageOrientation.Automatic
197            && newPage.orientationLock != PageOrientation.LockPrevious
198            && newPage.orientationLock != oldPage.orientationLock
199 }
200
201 // Clears the page stack.
202 function clear() {
203     var container;
204     while (container = pageStack.pop()) {
205         container.cleanup();
206     }
207     depth = 0;
208     currentPage = null;
209 }
210
211 // Iterates through all pages in the stack (top to bottom) to find a page.
212 function find(func) {
213     for (var i = pageStack.length - 1; i >= 0; i--) {
214         var page = pageStack[i].page;
215         if (func(page)) {
216             return page;
217         }
218     }
219     return null;
220 }
221