summaryrefslogtreecommitdiffstats
path: root/qt-mobile/qml/mobilecomponents/private/PageStack.js
diff options
context:
space:
mode:
Diffstat (limited to 'qt-mobile/qml/mobilecomponents/private/PageStack.js')
-rw-r--r--qt-mobile/qml/mobilecomponents/private/PageStack.js243
1 files changed, 243 insertions, 0 deletions
diff --git a/qt-mobile/qml/mobilecomponents/private/PageStack.js b/qt-mobile/qml/mobilecomponents/private/PageStack.js
new file mode 100644
index 000000000..8986956b0
--- /dev/null
+++ b/qt-mobile/qml/mobilecomponents/private/PageStack.js
@@ -0,0 +1,243 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Components project.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Page stack. Items are page containers.
+var pageStack = [];
+
+// Page component cache map. Key is page url, value is page component.
+var componentCache = {};
+
+// Returns the page stack depth.
+function getDepth() {
+ return pageStack.length;
+}
+
+// Pushes a page on the stack.
+function push(page, properties, replace, immediate) {
+ // page order sanity check
+ if ((!replace && page == currentPage)
+ || (replace && pageStack.length > 1
+ && page == pageStack[pageStack.length - 2].page)) {
+ throw new Error("Cannot navigate so that the resulting page stack has two consecutive entries of the same page instance.");
+ }
+
+ // figure out if more than one page is being pushed
+ var pages;
+ if (page instanceof Array) {
+ pages = page;
+ page = pages.pop();
+ if (page.createObject === undefined && page.parent === undefined && typeof page != "string") {
+ properties = properties || page.properties;
+ page = page.page;
+ }
+ }
+
+ // get the current container
+ var oldContainer;
+ if (pageStack.length) {
+ oldContainer = pageStack[pageStack.length - 1];
+ }
+
+ // pop the old container off the stack if this is a replace
+ if (oldContainer && replace) {
+ pageStack.pop();
+ }
+
+ // push any extra defined pages onto the stack
+ if (pages) {
+ var i;
+ for (i = 0; i < pages.length; i++) {
+ var tPage = pages[i];
+ var tProps;
+ if (tPage.createObject === undefined && tPage.parent === undefined && typeof tPage != "string") {
+ tProps = tPage.properties;
+ tPage = tPage.page;
+ }
+ pageStack.push(initPage(tPage, tProps));
+ }
+ }
+
+ // initialize the page
+ var container = initPage(page, properties);
+
+ // push the page container onto the stack
+ pageStack.push(container);
+
+ depth = pageStack.length;
+ currentPage = container.page;
+
+ // perform page transition
+ //FIXME: this should be in for PageStack, out for PageRow?
+ //immediate = immediate || !oldContainer;
+ var orientationChange = false;
+ if (oldContainer) {
+ orientationChange = orientationChanges(oldContainer.page, container.page);
+ oldContainer.pushExit(replace, immediate, orientationChange);
+ }
+
+ // sync tool bar
+ var tools = container.page.tools || null;
+ if (toolBar) {
+ toolBar.setTools(tools, immediate ? "set" : replace ? "replace" : "push");
+ }
+
+ container.pushEnter(immediate, orientationChange);
+ return container.page;
+}
+
+// Initializes a page and its container.
+function initPage(page, properties) {
+ var container = containerComponent.createObject(root);
+
+ var pageComp;
+ if (page.createObject) {
+ // page defined as component
+ pageComp = page;
+ } else if (typeof page == "string") {
+ // page defined as string (a url)
+ pageComp = componentCache[page];
+ if (!pageComp) {
+ pageComp = componentCache[page] = Qt.createComponent(page);
+ }
+ }
+ if (pageComp) {
+ if (pageComp.status == Component.Error) {
+ throw new Error("Error while loading page: " + pageComp.errorString());
+ } else {
+ // instantiate page from component
+ page = pageComp.createObject(container.pageParent, properties || {});
+ }
+ } else {
+ // copy properties to the page
+ for (var prop in properties) {
+ if (properties.hasOwnProperty(prop)) {
+ page[prop] = properties[prop];
+ }
+ }
+ }
+
+ container.page = page;
+ if (page.parent == null || page.parent == container.pageParent) {
+ container.owner = container;
+ } else {
+ container.owner = page.parent;
+ }
+
+ // the page has to be reparented if
+ if (page.parent != container.pageParent) {
+ page.parent = container.pageParent;
+ }
+
+ if (page.pageStack !== undefined) {
+ page.pageStack = root;
+ }
+
+ page.anchors.fill = container.pageParent
+
+ return container;
+}
+
+// Pops a page off the stack.
+function pop(page, immediate) {
+ // make sure there are enough pages in the stack to pop
+ if (pageStack.length > 1) {
+ //unwind to itself means no pop
+ if (page !== undefined && page == pageStack[pageStack.length - 1].page) {
+ return
+ }
+ // pop the current container off the stack and get the next container
+ var oldContainer = pageStack.pop();
+ var container = pageStack[pageStack.length - 1];
+ if (page !== undefined) {
+ // an unwind target has been specified - pop until we find it
+ while (page != container.page && pageStack.length > 1) {
+ pageStack.pop();
+ container.popExit(immediate, false);
+ container = pageStack[pageStack.length - 1];
+ }
+ }
+
+ depth = pageStack.length;
+ currentPage = container.page;
+
+ // perform page transition
+ var orientationChange = orientationChanges(oldContainer.page, container.page);
+ oldContainer.popExit(immediate, orientationChange);
+ container.popEnter(immediate, orientationChange);
+
+ // sync tool bar
+ var tools = container.page.tools || null;
+ if (toolBar) {
+ toolBar.setTools(tools, immediate ? "set" : "pop");
+ }
+ return oldContainer.page;
+ } else {
+ return null;
+ }
+}
+
+// Checks if the orientation changes between oldPage and newPage
+function orientationChanges(oldPage, newPage) {
+ return newPage.orientationLock != 0 //PlasmaComponents.PageOrientation.Automatic
+ && newPage.orientationLock != 3//PlasmaComponents.PageOrientation.LockPrevious
+ && newPage.orientationLock != oldPage.orientationLock
+}
+
+// Clears the page stack.
+function clear() {
+ var container;
+ while (container = pageStack.pop()) {
+ container.cleanup();
+ }
+ depth = 0;
+ currentPage = null;
+}
+
+// Iterates through all pages in the stack (top to bottom) to find a page.
+function find(func) {
+ for (var i = pageStack.length - 1; i >= 0; i--) {
+ var page = pageStack[i].page;
+ if (func(page)) {
+ return page;
+ }
+ }
+ return null;
+}
+