From ca01d5f9f5e960337a044be6e00de58fd4fbdb05 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Fri, 24 Jan 2014 13:22:02 +0100 Subject: Make basicsuite demos run stand-alone This change will make the demos run standalone when built in Qt Creator. - Rename example directories to lowercase/non-whitespace to avoid build & deployment problems - Add title.txt files so titles remain displayed correctly in the launcher - Add a common shared source files used for the standalone apps, and .pro-files for each example - Remove .qmlproject files (not needed) - Adjust documentation to match the new directory structure Change-Id: Ib24e461952da3b2c88aab0363249115ea44ee0f2 Reviewed-by: Eirik Aavitsland --- basicsuite/photogallery/description.txt | 1 + basicsuite/photogallery/main.qml | 295 +++++++++++++++++++++++++++++++ basicsuite/photogallery/photogallery.pro | 12 ++ basicsuite/photogallery/preview_l.jpg | Bin 0 -> 55274 bytes basicsuite/photogallery/title.txt | 1 + 5 files changed, 309 insertions(+) create mode 100644 basicsuite/photogallery/description.txt create mode 100644 basicsuite/photogallery/main.qml create mode 100644 basicsuite/photogallery/photogallery.pro create mode 100644 basicsuite/photogallery/preview_l.jpg create mode 100644 basicsuite/photogallery/title.txt (limited to 'basicsuite/photogallery') diff --git a/basicsuite/photogallery/description.txt b/basicsuite/photogallery/description.txt new file mode 100644 index 0000000..f5e302c --- /dev/null +++ b/basicsuite/photogallery/description.txt @@ -0,0 +1 @@ +This is a simple photo gallery, showing images found in /data/images. diff --git a/basicsuite/photogallery/main.qml b/basicsuite/photogallery/main.qml new file mode 100644 index 0000000..5fbab8a --- /dev/null +++ b/basicsuite/photogallery/main.qml @@ -0,0 +1,295 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: For any questions to Digia, please use the contact form at +** http://qt.digia.com/ +** +** This file is part of the examples of the Qt Enterprise Embedded. +** +** $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 Digia Plc 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$ +** +****************************************************************************/ +import QtQuick 2.0 +import Qt.labs.folderlistmodel 1.0 + +Item { + id: root + + width: 320 + height: 480 + + Rectangle { + anchors.fill: parent + color: "black" + } + + FolderListModel { + id: imageList + folder: "/data/images" + nameFilters: ["*.png", "*.jpg"] + + showDirs: false + } + + Text { + id: noImages + color: "white" + visible: grid.count == 0 + text: "No images in " + imageList.folder + anchors.centerIn: parent + } + + GridView { + id: grid + + anchors.fill: parent + + cellHeight: root.width / 3 + cellWidth: cellHeight + + model: imageList + +// NumberAnimation on contentY { from: 0; to: 2000; duration: 3000; loops: 1; easing.type: Easing.InOutCubic } + + delegate: Rectangle { + + id: box + color: "white" + width: grid.cellWidth + height: grid.cellHeight + scale: 0.97 + rotation: 2; + antialiasing: true + + Rectangle { + id: sepia + color: "#b08050" + width: image.width + height: image.height + anchors.centerIn: parent + + property real fakeOpacity: image.status == Image.Ready ? 1.5 : 0 + Behavior on fakeOpacity { NumberAnimation { duration: 1000 } } + + opacity: fakeOpacity + visible: image.opacity <= 0.99; + antialiasing: true + } + + Image { + id: image + source: filePath + width: grid.cellWidth * 0.9 + height: grid.cellHeight * 0.9 + anchors.centerIn: sepia + asynchronous: true + opacity: sepia.fakeOpacity - .5 + sourceSize.width: width; + antialiasing: true + } + + MouseArea { + anchors.fill: parent + onClicked: { + root.showBigImage(filePath, box.x - grid.contentX, box.y - grid.contentY, image); + } + } + } + } + + function showBigImage(filePath, itemX, itemY, image) { + fakeBigImage.x = itemX; + fakeBigImage.y = itemY; + fakeBigImage.sourceSize = image.sourceSize; + fakeBigImage.source = filePath; + + beginEnterLargeAnimation.running = true; + } + + property int time: 500; + property real xPos: width < height ? 0 : width / 2 - height / 2; + property real yPos: width < height ? height / 2 - width / 2: 0; + property real size: Math.min(width, height); + + states: [ + State { name: "grid" }, + State { name: "enter-large" }, + State { name: "large" }, + State { name: "exit-large" } + ] + + SequentialAnimation { + id: beginEnterLargeAnimation + PropertyAction { target: mouseArea; property: "enabled"; value: "true" } + PropertyAction { target: fakeBigImage; property: "rotation"; value: 2; } + PropertyAction { target: fakeBigImage; property: "scale"; value: 0.97 * 0.9; } + PropertyAction { target: fakeBigImage; property: "width"; value: grid.cellWidth; } + PropertyAction { target: fakeBigImage; property: "height"; value: grid.cellHeight; } + PropertyAction { target: fakeBigImage; property: "visible"; value: true; } + + ParallelAnimation { + NumberAnimation { target: fakeBigImage; property: "rotation"; to: 0; duration: root.time; easing.type: Easing.InOutCubic } + NumberAnimation { target: fakeBigImage; property: "scale"; to: 1; duration: root.time; easing.type: Easing.InOutCubic } + NumberAnimation { target: fakeBigImage; property: "x"; to: root.xPos; duration: root.time; easing.type: Easing.InOutCubic } + NumberAnimation { target: fakeBigImage; property: "y"; to: root.yPos; duration: root.time; easing.type: Easing.InOutCubic } + NumberAnimation { target: fakeBigImage; property: "width"; to: root.size; duration: root.time; easing.type: Easing.InOutCubic } + NumberAnimation { target: fakeBigImage; property: "height"; to: root.size; duration: root.time; easing.type: Easing.InOutCubic } + NumberAnimation { target: grid; property: "opacity"; to: 0; duration: root.time; easing.type: Easing.InOutCubic } + } + ScriptAction { + script: { + + bigImage = realBigImageComponent.createObject(root); + bigImage.source = fakeBigImage.source; + } + } + } + + property Item bigImage; + property real targetRotation: 0; + property real targetWidth: 0 + property real targetHeight: 0 + property bool bigImageShowing: false; + + SequentialAnimation { + id: finalizeEnterLargeAnimation + ScriptAction { script: { + fakeBigImage.anchors.centerIn = root; + } + } + ParallelAnimation { + NumberAnimation { target: bigImage; property: "opacity"; to: 1; duration: root.time; easing.type: Easing.InOutCubic } + NumberAnimation { target: fakeBigImage; property: "rotation"; to: root.targetRotation; duration: root.time; easing.type: Easing.InOutCubic } + NumberAnimation { target: bigImage; property: "rotation"; to: root.targetRotation; duration: root.time; easing.type: Easing.InOutCubic } + NumberAnimation { target: fakeBigImage; property: "width"; to: root.targetWidth; duration: root.time; easing.type: Easing.InOutCubic } + NumberAnimation { target: fakeBigImage; property: "height"; to: root.targetHeight; duration: root.time; easing.type: Easing.InOutCubic } + NumberAnimation { target: bigImage; property: "width"; to: root.targetWidth; duration: root.time; easing.type: Easing.InOutCubic } + NumberAnimation { target: bigImage; property: "height"; to: root.targetHeight; duration: root.time; easing.type: Easing.InOutCubic } + } + PropertyAction { target: fakeBigImage; property: "visible"; value: false } + PropertyAction { target: root; property: "bigImageShowing"; value: true } + } + + SequentialAnimation { + id: backToGridAnimation + ParallelAnimation { + NumberAnimation { target: bigImage; property: "opacity"; to: 0; duration: root.time; easing.type: Easing.InOutCubic } + NumberAnimation { target: grid; property: "opacity"; to: 1; duration: root.time; easing.type: Easing.InOutCubic } + } + PropertyAction { target: fakeBigImage; property: "source"; value: "" } + PropertyAction { target: root; property: "bigImageShowing"; value: false } + PropertyAction { target: mouseArea; property: "enabled"; value: false } + ScriptAction { script: { + bigImage.destroy(); + fakeBigImage.anchors.centerIn = undefined + } + } + } + + Image { + id: fakeBigImage + width: grid.cellWidth + height: grid.cellHeight + visible: false + antialiasing: true + } + + Component { + id: realBigImageComponent + + Image { + id: realBigImage + + anchors.centerIn: parent; + + asynchronous: true; + + // Bound size to the current display size, to try to avoid any GL_MAX_TEXTURE_SIZE issues. + sourceSize: Qt.size(Math.max(root.width, root.height), Math.max(root.width, root.height)); + + opacity: 0 + onStatusChanged: { + + if (status != Image.Ready) + return; + + var imageIsLandscape = width > height; + var screenIsLandscape = root.width > root.height; + + var targetScale; + + // Rotation needed... + if (imageIsLandscape != screenIsLandscape && width != height) { + root.targetRotation = 90; + var aspect = width / height + var screenAspect = root.height / root.width + + if (aspect > screenAspect) { + targetScale = root.height / width + } else { + targetScale = root.width / height; + } + } else { + root.targetRotation = 0; + var aspect = height / width; + var screenAspect = root.height / root.width + + if (aspect > screenAspect) { + targetScale = root.height / height + } else { + targetScale = root.width / width; + } + } + + root.targetWidth = width * targetScale + root.targetHeight = height * targetScale; + + width = root.size + height = root.size; + + finalizeEnterLargeAnimation.running = true; + } + } + } + + MouseArea { + id: mouseArea + anchors.fill: parent + enabled: false + + onClicked: { + if (root.bigImageShowing) + backToGridAnimation.running = true; + } + } + +} diff --git a/basicsuite/photogallery/photogallery.pro b/basicsuite/photogallery/photogallery.pro new file mode 100644 index 0000000..04c33f3 --- /dev/null +++ b/basicsuite/photogallery/photogallery.pro @@ -0,0 +1,12 @@ +TARGET = photogallery + +include(../shared/shared.pri) + +content.files = \ + *.qml \ + *.png +content.path = $$DESTPATH + +OTHER_FILES += $${content.files} + +INSTALLS += target content \ No newline at end of file diff --git a/basicsuite/photogallery/preview_l.jpg b/basicsuite/photogallery/preview_l.jpg new file mode 100644 index 0000000..0b67f1d Binary files /dev/null and b/basicsuite/photogallery/preview_l.jpg differ diff --git a/basicsuite/photogallery/title.txt b/basicsuite/photogallery/title.txt new file mode 100644 index 0000000..4aee1d3 --- /dev/null +++ b/basicsuite/photogallery/title.txt @@ -0,0 +1 @@ +Photo Gallery -- cgit v1.2.3