diff options
Diffstat (limited to 'qt-mobile/qml/mobilecomponents/private')
5 files changed, 491 insertions, 0 deletions
diff --git a/qt-mobile/qml/mobilecomponents/private/AbstractDrawer.qml b/qt-mobile/qml/mobilecomponents/private/AbstractDrawer.qml new file mode 100644 index 000000000..db662509c --- /dev/null +++ b/qt-mobile/qml/mobilecomponents/private/AbstractDrawer.qml @@ -0,0 +1,47 @@ +/* + * Copyright 2015 Marco Martin <mart@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 +import QtGraphicalEffects 1.0 +import org.kde.plasma.mobilecomponents 0.2 + +//TODO: This will become a QQC2 Drawer +//providing just a dummy api for now +Item { + id: root + anchors.fill: parent + z: 9999 + + default property alias page: mainPage.data + property Item contentItem + property bool opened + property int edge: Qt.LeftEdge + property real position: 0 + + function open () { } + function close () { } + signal clicked + + Item { + id: mainPage + anchors.fill: parent + onChildrenChanged: mainPage.children[0].anchors.fill = mainPage + } +} + diff --git a/qt-mobile/qml/mobilecomponents/private/ActionButton.qml b/qt-mobile/qml/mobilecomponents/private/ActionButton.qml new file mode 100644 index 000000000..5bf6ab086 --- /dev/null +++ b/qt-mobile/qml/mobilecomponents/private/ActionButton.qml @@ -0,0 +1,142 @@ +/* + * Copyright 2015 Marco Martin <mart@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 +import QtQuick.Layouts 1.2 +import QtGraphicalEffects 1.0 +import org.kde.plasma.mobilecomponents 0.2 + +MouseArea { + id: button + property alias iconSource: icon.source + Layout.minimumWidth: Units.iconSizes.large + Layout.maximumWidth: Layout.minimumWidth + implicitWidth: Units.iconSizes.large + implicitHeight: width + drag { + target: button + axis: Drag.XAxis + minimumX: contextDrawer ? 0 : parent.width/2 - width/2 + maximumX: globalDrawer ? parent.width : parent.width/2 - width/2 + } + + transform: Translate {} + onReleased: { + if (globalDrawer && x > Math.min(parent.width/4*3, parent.width/2 + globalDrawer.contentItem.width/2)) { + globalDrawer.open(); + contextDrawer.close(); + } else if (contextDrawer && x < Math.max(parent.width/4, parent.width/2 - contextDrawer.contentItem.width/2)) { + if (contextDrawer) { + contextDrawer.open(); + } + if (globalDrawer) { + globalDrawer.close(); + } + } else { + if (globalDrawer) { + globalDrawer.close(); + } + if (contextDrawer) { + contextDrawer.close(); + } + } + } + Connections { + target: globalDrawer + onPositionChanged: { + if (!button.pressed) { + button.x = globalDrawer.contentItem.width * globalDrawer.position + button.parent.width/2 - button.width/2; + } + } + } + Connections { + target: contextDrawer + onPositionChanged: { + if (!button.pressed) { + button.x = button.parent.width/2 - button.width/2 - contextDrawer.contentItem.width * contextDrawer.position; + } + } + } + onXChanged: { + if (button.pressed) { + globalDrawer.position = Math.min(1, Math.max(0, (x - button.parent.width/2 + button.width/2)/globalDrawer.contentItem.width)); + contextDrawer.position = Math.min(1, Math.max(0, (button.parent.width/2 - button.width/2 - x)/contextDrawer.contentItem.width)); + } + } + + Item { + id: background + anchors { + fill: parent + leftMargin: -Units.gridUnit + rightMargin: -Units.gridUnit + } + Rectangle { + radius: width/2 + anchors.centerIn: parent + height: parent.height - Units.smallSpacing*2 + width: height + color: button.pressed ? Theme.highlightColor : Theme.backgroundColor + Icon { + id: icon + anchors { + fill: parent + margins: Units.smallSpacing + } + } + ActionButtonArrow { + anchors { + right: parent.left + rightMargin: Units.smallSpacing + } + visible: contextDrawer && contextDrawer.enabled + inverted: true + } + ActionButtonArrow { + anchors { + left: parent.right + leftMargin: Units.smallSpacing + } + visible: globalDrawer && globalDrawer.enabled + } + Behavior on color { + ColorAnimation { + duration: Units.longDuration + easing.type: Easing.InOutQuad + } + } + Behavior on x { + NumberAnimation { + duration: Units.longDuration + easing.type: Easing.InOutQuad + } + } + } + } + DropShadow { + anchors.fill: background + horizontalOffset: 0 + verticalOffset: Units.smallSpacing/2 + radius: Units.gridUnit / 2.4 + samples: 16 + color: button.pressed ? "transparent" : Qt.rgba(0, 0, 0, 0.5) + source: background + } +} + diff --git a/qt-mobile/qml/mobilecomponents/private/ActionButtonArrow.qml b/qt-mobile/qml/mobilecomponents/private/ActionButtonArrow.qml new file mode 100644 index 000000000..7b585452b --- /dev/null +++ b/qt-mobile/qml/mobilecomponents/private/ActionButtonArrow.qml @@ -0,0 +1,56 @@ +/* + * Copyright 2015 Marco Martin <mart@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 +import QtQuick.Layouts 1.2 +import QtGraphicalEffects 1.0 +import org.kde.plasma.mobilecomponents 0.2 + +Canvas { + id: canvas + width: Units.gridUnit + height: width + property bool inverted + property color color: parent.color + anchors.verticalCenter: parent.verticalCenter + + onColorChanged: requestPaint() + + onPaint: { + var ctx = canvas.getContext("2d"); + ctx.fillStyle = canvas.color; + ctx.beginPath(); + if (inverted) { + ctx.moveTo(canvas.width, 0); + ctx.bezierCurveTo(canvas.width-canvas.width/8, 0, + canvas.width-canvas.width/8, canvas.height, + canvas.width, canvas.height); + ctx.lineTo(0, canvas.height/2); + } else { + ctx.moveTo(0, 0); + ctx.bezierCurveTo(canvas.width/8, 0, + canvas.width/8, canvas.height, + 0, canvas.height); + ctx.lineTo(canvas.width, canvas.height/2); + //ctx.lineTo(0, canvas.height); + } + ctx.fill(); + } +} + 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; +} + diff --git a/qt-mobile/qml/mobilecomponents/private/qmldir b/qt-mobile/qml/mobilecomponents/private/qmldir new file mode 100644 index 000000000..35e158210 --- /dev/null +++ b/qt-mobile/qml/mobilecomponents/private/qmldir @@ -0,0 +1,3 @@ +module org.kde.plasma.mobilecomponents.private +#plugin mobilecomponentsprivateplugin + |