From 89033ce125a67a76141c115a1e9b4347ee419e3a Mon Sep 17 00:00:00 2001 From: Mikko Gronoff Date: Wed, 15 Nov 2017 15:45:29 +0200 Subject: Doc: Bump version to 5.9.3 Change-Id: Ibb57b779b2b4608e6abd47e2fde973eb7f51e220 Reviewed-by: Tarja Sundqvist --- doc/b2qt-demos.qdoc | 2 +- doc/b2qt-demos.qdocconf | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/b2qt-demos.qdoc b/doc/b2qt-demos.qdoc index 8e794c9..10afdee 100644 --- a/doc/b2qt-demos.qdoc +++ b/doc/b2qt-demos.qdoc @@ -50,7 +50,7 @@ /*! \page index.html - \title Qt 5.9.2 for Device Creation Examples and Demos + \title Qt 5.9.3 for Device Creation Examples and Demos \SDK has a number of examples and demos. These are included in the \B2Q images, available in the launcher that is run by default at diff --git a/doc/b2qt-demos.qdocconf b/doc/b2qt-demos.qdocconf index a7d5ab8..962a53c 100644 --- a/doc/b2qt-demos.qdocconf +++ b/doc/b2qt-demos.qdocconf @@ -5,8 +5,8 @@ outputencoding = UTF-8 sourceencoding = UTF-8 project = QtforDeviceCreationDemos -description = Qt 5.9.2 for Device Creation Examples and Demos -version = 5.9.2 +description = Qt 5.9.3 for Device Creation Examples and Demos +version = 5.9.3 sourcedirs = . imagedirs += images @@ -21,9 +21,9 @@ exampledirs = .. qhp.projects = QtforDeviceCreationDemos qhp.QtforDeviceCreationDemos.file = b2qt-demos.qhp -qhp.QtforDeviceCreationDemos.namespace = org.qt-project.b2qt-demos.592 +qhp.QtforDeviceCreationDemos.namespace = org.qt-project.b2qt-demos.593 qhp.QtforDeviceCreationDemos.virtualFolder = b2qt-demos -qhp.QtforDeviceCreationDemos.indexTitle = Qt 5.9.2 for Device Creation Examples and Demos +qhp.QtforDeviceCreationDemos.indexTitle = Qt 5.9.3 for Device Creation Examples and Demos qhp.QtforDeviceCreationDemos.indexRoot = qhp.QtforDeviceCreationDemos.subprojects = demos @@ -35,4 +35,4 @@ manifestmeta.b2qt.names = "QtforDeviceCreationDemos/*" macro.B2Q = "Boot to Qt" macro.SDK = "Qt for Device Creation" -navigation.landingpage = "Qt 5.9.2 for Device Creation Examples and Demos" +navigation.landingpage = "Qt 5.9.3 for Device Creation Examples and Demos" -- cgit v1.2.3 From 55fee3bac1c053ee1de17b939f663ed6aa4e963b Mon Sep 17 00:00:00 2001 From: Mikko Gronoff Date: Mon, 18 Dec 2017 11:58:37 +0200 Subject: Doc: Bump version to 5.9.4 Change-Id: I49cc18f9b613ddc0fe4de92945048dc8d0ba4a1b Reviewed-by: Tarja Sundqvist --- doc/b2qt-demos.qdoc | 2 +- doc/b2qt-demos.qdocconf | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/b2qt-demos.qdoc b/doc/b2qt-demos.qdoc index 10afdee..621b346 100644 --- a/doc/b2qt-demos.qdoc +++ b/doc/b2qt-demos.qdoc @@ -50,7 +50,7 @@ /*! \page index.html - \title Qt 5.9.3 for Device Creation Examples and Demos + \title Qt 5.9.4 for Device Creation Examples and Demos \SDK has a number of examples and demos. These are included in the \B2Q images, available in the launcher that is run by default at diff --git a/doc/b2qt-demos.qdocconf b/doc/b2qt-demos.qdocconf index 962a53c..0768b5a 100644 --- a/doc/b2qt-demos.qdocconf +++ b/doc/b2qt-demos.qdocconf @@ -5,8 +5,8 @@ outputencoding = UTF-8 sourceencoding = UTF-8 project = QtforDeviceCreationDemos -description = Qt 5.9.3 for Device Creation Examples and Demos -version = 5.9.3 +description = Qt 5.9.4 for Device Creation Examples and Demos +version = 5.9.4 sourcedirs = . imagedirs += images @@ -21,9 +21,9 @@ exampledirs = .. qhp.projects = QtforDeviceCreationDemos qhp.QtforDeviceCreationDemos.file = b2qt-demos.qhp -qhp.QtforDeviceCreationDemos.namespace = org.qt-project.b2qt-demos.593 +qhp.QtforDeviceCreationDemos.namespace = org.qt-project.b2qt-demos.594 qhp.QtforDeviceCreationDemos.virtualFolder = b2qt-demos -qhp.QtforDeviceCreationDemos.indexTitle = Qt 5.9.3 for Device Creation Examples and Demos +qhp.QtforDeviceCreationDemos.indexTitle = Qt 5.9.4 for Device Creation Examples and Demos qhp.QtforDeviceCreationDemos.indexRoot = qhp.QtforDeviceCreationDemos.subprojects = demos @@ -35,4 +35,4 @@ manifestmeta.b2qt.names = "QtforDeviceCreationDemos/*" macro.B2Q = "Boot to Qt" macro.SDK = "Qt for Device Creation" -navigation.landingpage = "Qt 5.9.3 for Device Creation Examples and Demos" +navigation.landingpage = "Qt 5.9.4 for Device Creation Examples and Demos" -- cgit v1.2.3 From 0909f9baabc446e4a7bb85593e39fad474af88ab Mon Sep 17 00:00:00 2001 From: Mikko Gronoff Date: Mon, 19 Feb 2018 12:57:28 +0200 Subject: Doc: Bump version to 5.11.0 Task-number: QTBUG-66307 Change-Id: Ica4191efa5adf0396d0be0ac980e583734d0045c Reviewed-by: Tarja Sundqvist --- doc/b2qt-demos.qdoc | 2 +- doc/b2qt-demos.qdocconf | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/b2qt-demos.qdoc b/doc/b2qt-demos.qdoc index 1a14796..b399301 100644 --- a/doc/b2qt-demos.qdoc +++ b/doc/b2qt-demos.qdoc @@ -50,7 +50,7 @@ /*! \page index.html - \title Qt 5.10.1 for Device Creation Examples and Demos + \title Qt 5.11.0 for Device Creation Examples and Demos \SDK has a number of examples and demos. These are included in the \B2Q images, available in the launcher that is run by default at diff --git a/doc/b2qt-demos.qdocconf b/doc/b2qt-demos.qdocconf index 51931cb..79b9a71 100644 --- a/doc/b2qt-demos.qdocconf +++ b/doc/b2qt-demos.qdocconf @@ -5,8 +5,8 @@ outputencoding = UTF-8 sourceencoding = UTF-8 project = QtforDeviceCreationDemos -description = Qt 5.10.1 for Device Creation Examples and Demos -version = 5.10.1 +description = Qt 5.11.0 for Device Creation Examples and Demos +version = 5.11.0 sourcedirs = . imagedirs += images @@ -21,9 +21,9 @@ exampledirs = .. qhp.projects = QtforDeviceCreationDemos qhp.QtforDeviceCreationDemos.file = b2qt-demos.qhp -qhp.QtforDeviceCreationDemos.namespace = org.qt-project.b2qt-demos.5101 +qhp.QtforDeviceCreationDemos.namespace = org.qt-project.b2qt-demos.5110 qhp.QtforDeviceCreationDemos.virtualFolder = b2qt-demos -qhp.QtforDeviceCreationDemos.indexTitle = Qt 5.10.1 for Device Creation Examples and Demos +qhp.QtforDeviceCreationDemos.indexTitle = Qt 5.11.0 for Device Creation Examples and Demos qhp.QtforDeviceCreationDemos.indexRoot = qhp.QtforDeviceCreationDemos.subprojects = demos @@ -35,4 +35,4 @@ manifestmeta.b2qt.names = "QtforDeviceCreationDemos/*" macro.B2Q = "Boot to Qt" macro.SDK = "Qt for Device Creation" -navigation.landingpage = "Qt 5.10.1 for Device Creation Examples and Demos" +navigation.landingpage = "Qt 5.11.0 for Device Creation Examples and Demos" -- cgit v1.2.3 From 9e941af1f75b97e30ab0e427dcad3b51dba99358 Mon Sep 17 00:00:00 2001 From: Mikko Gronoff Date: Mon, 5 Mar 2018 12:32:10 +0200 Subject: Doc: Bump version to 5.9.5 Change-Id: Icc999332933b27a5a6c1c133045305a10f355eed Reviewed-by: Tarja Sundqvist --- doc/b2qt-demos.qdoc | 2 +- doc/b2qt-demos.qdocconf | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/b2qt-demos.qdoc b/doc/b2qt-demos.qdoc index 621b346..cb7a039 100644 --- a/doc/b2qt-demos.qdoc +++ b/doc/b2qt-demos.qdoc @@ -50,7 +50,7 @@ /*! \page index.html - \title Qt 5.9.4 for Device Creation Examples and Demos + \title Qt 5.9.5 for Device Creation Examples and Demos \SDK has a number of examples and demos. These are included in the \B2Q images, available in the launcher that is run by default at diff --git a/doc/b2qt-demos.qdocconf b/doc/b2qt-demos.qdocconf index 0768b5a..c079e0e 100644 --- a/doc/b2qt-demos.qdocconf +++ b/doc/b2qt-demos.qdocconf @@ -5,8 +5,8 @@ outputencoding = UTF-8 sourceencoding = UTF-8 project = QtforDeviceCreationDemos -description = Qt 5.9.4 for Device Creation Examples and Demos -version = 5.9.4 +description = Qt 5.9.5 for Device Creation Examples and Demos +version = 5.9.5 sourcedirs = . imagedirs += images @@ -21,9 +21,9 @@ exampledirs = .. qhp.projects = QtforDeviceCreationDemos qhp.QtforDeviceCreationDemos.file = b2qt-demos.qhp -qhp.QtforDeviceCreationDemos.namespace = org.qt-project.b2qt-demos.594 +qhp.QtforDeviceCreationDemos.namespace = org.qt-project.b2qt-demos.595 qhp.QtforDeviceCreationDemos.virtualFolder = b2qt-demos -qhp.QtforDeviceCreationDemos.indexTitle = Qt 5.9.4 for Device Creation Examples and Demos +qhp.QtforDeviceCreationDemos.indexTitle = Qt 5.9.5 for Device Creation Examples and Demos qhp.QtforDeviceCreationDemos.indexRoot = qhp.QtforDeviceCreationDemos.subprojects = demos @@ -35,4 +35,4 @@ manifestmeta.b2qt.names = "QtforDeviceCreationDemos/*" macro.B2Q = "Boot to Qt" macro.SDK = "Qt for Device Creation" -navigation.landingpage = "Qt 5.9.4 for Device Creation Examples and Demos" +navigation.landingpage = "Qt 5.9.5 for Device Creation Examples and Demos" -- cgit v1.2.3 From 2a50d497ef0e24732d5168d2d42c5d6bc27e23c6 Mon Sep 17 00:00:00 2001 From: Juho Annunen Date: Tue, 17 Apr 2018 13:25:51 +0300 Subject: Comment out 7 demos from demos.xml file Task-number: QTBUG-62794 Change-Id: Ib3afd9df51b7adad359d80407566a24cee9e1366 Reviewed-by: Sami Nurmenniemi --- basicsuite/demos.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/basicsuite/demos.xml b/basicsuite/demos.xml index f1ca6a0..e6c2cbe 100644 --- a/basicsuite/demos.xml +++ b/basicsuite/demos.xml @@ -1,6 +1,7 @@ + @@ -29,6 +31,7 @@ Qt Charts is part of the Qt Enterprise addons package which provides a set of ea + @@ -63,6 +67,7 @@ It can play content either from a file or a network source, both videos and musi + -- cgit v1.2.3 From 7c41444789be188fc47b3d68f4431d85d52d1e46 Mon Sep 17 00:00:00 2001 From: Juho Annunen Date: Tue, 17 Apr 2018 13:57:22 +0300 Subject: Update Charts demo to new UI theme Task-number: QTBUG-62792 Change-Id: I95c6fb038f5d427da2ed1ee6698e1afcfa436eee Reviewed-by: Sami Nurmenniemi --- basicsuite/enterprise-charts/BaseChart.qml | 64 ++++++++++++++++++++++ basicsuite/enterprise-charts/View1.qml | 19 +++---- basicsuite/enterprise-charts/View10.qml | 19 ++++--- basicsuite/enterprise-charts/View11.qml | 20 ++++--- basicsuite/enterprise-charts/View12.qml | 39 ++++++------- basicsuite/enterprise-charts/View2.qml | 15 +++-- basicsuite/enterprise-charts/View3.qml | 15 +++-- basicsuite/enterprise-charts/View4.qml | 26 +++++---- basicsuite/enterprise-charts/View5.qml | 16 ++++-- basicsuite/enterprise-charts/View6.qml | 21 ++++--- basicsuite/enterprise-charts/View7.qml | 20 ++++--- basicsuite/enterprise-charts/View8.qml | 21 ++++--- basicsuite/enterprise-charts/View9.qml | 21 ++++--- basicsuite/enterprise-charts/enterprise-charts.pro | 1 + basicsuite/enterprise-charts/main.qml | 9 +++ basicsuite/shared/SharedMain.qml | 9 +++ 16 files changed, 228 insertions(+), 107 deletions(-) create mode 100644 basicsuite/enterprise-charts/BaseChart.qml diff --git a/basicsuite/enterprise-charts/BaseChart.qml b/basicsuite/enterprise-charts/BaseChart.qml new file mode 100644 index 0000000..27811b0 --- /dev/null +++ b/basicsuite/enterprise-charts/BaseChart.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Device Creation. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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 QtCharts 2.0 + +ChartView{ + id: chart + titleFont.family: appFont + titleFont.styleName: "SemiBold" + titleColor: "white" + legend.alignment: Qt.AlignBottom + legend.font.family: appFont + legend.labelColor: "white" + antialiasing: true + backgroundColor: "transparent" +} diff --git a/basicsuite/enterprise-charts/View1.qml b/basicsuite/enterprise-charts/View1.qml index 64aa78c..f85a18e 100644 --- a/basicsuite/enterprise-charts/View1.qml +++ b/basicsuite/enterprise-charts/View1.qml @@ -53,31 +53,30 @@ import QtQuick 2.0 //![2] import QtCharts 2.0 -Rectangle { +Item { anchors.fill: parent property variant othersSlice: 0 + //![1] - ChartView { + BaseChart { id: chart title: "Top-5 car brand shares in Finland" anchors.fill: parent - legend.alignment: Qt.AlignBottom - antialiasing: true - PieSeries { id: pieSeries - PieSlice { label: "Volkswagen"; value: 13.5 } - PieSlice { label: "Toyota"; value: 10.9 } - PieSlice { label: "Ford"; value: 8.6 } - PieSlice { label: "Skoda"; value: 8.2 } - PieSlice { label: "Volvo"; value: 6.8 } + PieSlice { label: "Volkswagen"; value: 13.5; color: defaultGreen } + PieSlice { label: "Toyota"; value: 10.9; color: mediumGreen } + PieSlice { label: "Ford"; value: 8.6; color: darkGreen } + PieSlice { label: "Skoda"; value: 8.2; color: defaultGrey } + PieSlice { label: "Volvo"; value: 6.8; color: secondaryGrey } } } Component.onCompleted: { // You can also manipulate slices dynamically othersSlice = pieSeries.append("Others", 52.0); + othersSlice.color = mediumGrey; pieSeries.find("Volkswagen").exploded = true; } //![1] diff --git a/basicsuite/enterprise-charts/View10.qml b/basicsuite/enterprise-charts/View10.qml index adcd350..79ca4ab 100644 --- a/basicsuite/enterprise-charts/View10.qml +++ b/basicsuite/enterprise-charts/View10.qml @@ -51,21 +51,24 @@ import QtQuick 2.0 import QtCharts 2.0 -Rectangle { +Item { anchors.fill: parent - //![1] - ChartView { + BaseChart { title: "Horizontal Stacked Bar series" anchors.fill: parent - legend.alignment: Qt.AlignBottom - antialiasing: true HorizontalStackedBarSeries { axisY: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] } - BarSet { label: "Bob"; values: [2, 2, 3, 4, 5, 6] } - BarSet { label: "Susan"; values: [5, 1, 2, 4, 1, 7] } - BarSet { label: "James"; values: [3, 5, 8, 13, 5, 8] } + BarSet { label: "Bob"; color: defaultGreen; values: [2, 2, 3, 4, 5, 6] } + BarSet { label: "Susan"; color: defaultGrey; values: [5, 1, 2, 4, 1, 7] } + BarSet { label: "James"; color: secondaryGrey; values: [3, 5, 8, 13, 5, 8] } + } + Component.onCompleted: { + axes[0].labelsColor = "white"; + axes[1].labelsColor = "white"; + axes[0].labelsFont = appFont; + axes[1].labelsFont = appFont; } } //![1] diff --git a/basicsuite/enterprise-charts/View11.qml b/basicsuite/enterprise-charts/View11.qml index 37c3d80..dd81733 100644 --- a/basicsuite/enterprise-charts/View11.qml +++ b/basicsuite/enterprise-charts/View11.qml @@ -51,21 +51,25 @@ import QtQuick 2.0 import QtCharts 2.0 -Rectangle { +Item { anchors.fill: parent - //![1] - ChartView { + BaseChart { title: "Horizontal Percent Bar series" anchors.fill: parent - legend.alignment: Qt.AlignBottom - antialiasing: true HorizontalPercentBarSeries { axisY: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] } - BarSet { label: "Bob"; values: [2, 2, 3, 4, 5, 6] } - BarSet { label: "Susan"; values: [5, 1, 2, 4, 1, 7] } - BarSet { label: "James"; values: [3, 5, 8, 13, 5, 8] } + BarSet { label: "Bob"; color: defaultGreen; values: [2, 2, 3, 4, 5, 6] } + BarSet { label: "Susan"; color: defaultGrey; values: [5, 1, 2, 4, 1, 7] } + BarSet { label: "James"; color: secondaryGrey; values: [3, 5, 8, 13, 5, 8] } + } + + Component.onCompleted: { + axes[0].labelsColor = "white"; + axes[1].labelsColor = "white"; + axes[0].labelsFont = appFont; + axes[1].labelsFont = appFont; } } //![1] diff --git a/basicsuite/enterprise-charts/View12.qml b/basicsuite/enterprise-charts/View12.qml index 39d8a13..588ec4b 100644 --- a/basicsuite/enterprise-charts/View12.qml +++ b/basicsuite/enterprise-charts/View12.qml @@ -51,42 +51,39 @@ import QtQuick 2.0 import QtCharts 2.0 -Rectangle { +Item { anchors.fill: parent - //![1] - ChartView { + BaseChart { id: chart title: "Production costs" - anchors.fill: parent legend.visible: false - antialiasing: true - + anchors.fill: parent PieSeries { id: pieOuter size: 0.96 holeSize: 0.7 - PieSlice { id: slice; label: "Alpha"; value: 19511; color: "#8AB846"; borderColor: "#163430" } - PieSlice { label: "Epsilon"; value: 11105; color: "#C0EEFF"; borderColor: "#3B391C" } - PieSlice { label: "Psi"; value: 9352; color: "#DF8939"; borderColor: "#13060C" } + + PieSlice { id: slice; label: "Alpha"; value: 19511; color: defaultGreen; borderColor: "#163430" } + PieSlice { label: "Epsilon"; value: 11105; color: defaultGrey; borderColor: "#3B391C" } + PieSlice { label: "Psi"; value: 9352; color: darkGrey2; borderColor: "#13060C" } } PieSeries { size: 0.7 id: pieInner holeSize: 0.25 + PieSlice { label: "Materials"; value: 10334; color: mediumGreen; borderColor: "#163430" } + PieSlice { label: "Employee"; value: 3066; color: darkGreen; borderColor: "#163430" } + PieSlice { label: "Logistics"; value: 6111; color: mediumGreen; borderColor: "#163430" } - PieSlice { label: "Materials"; value: 10334; color: "#8AB846"; borderColor: "#163430" } - PieSlice { label: "Employee"; value: 3066; color: "#AAE356"; borderColor: "#163430" } - PieSlice { label: "Logistics"; value: 6111; color: "#99CC4E"; borderColor: "#163430" } - - PieSlice { label: "Materials"; value: 7371; color: "#C0EEFF"; borderColor: "#3B391C" } - PieSlice { label: "Employee"; value: 2443; color: "#C9FAFF"; borderColor: "#3B391C" } - PieSlice { label: "Logistics"; value: 1291; color: "#B0FAFF"; borderColor: "#3B391C" } + PieSlice { label: "Materials"; value: 7371; color: mediumGrey2; borderColor: "#3B391C" } + PieSlice { label: "Employee"; value: 2443; color: mediumGrey; borderColor: "#3B391C" } + PieSlice { label: "Logistics"; value: 1291; color: mediumGrey2; borderColor: "#3B391C" } - PieSlice { label: "Materials"; value: 4022; color: "#DF8939"; borderColor: "#13060C" } - PieSlice { label: "Employee"; value: 3998; color: "#FC9D42"; borderColor: "#13060C" } - PieSlice { label: "Logistics"; value: 1332; color: "#F2963F"; borderColor: "#13060C" } + PieSlice { label: "Materials"; value: 4022; color: secondaryGrey; borderColor: "#13060C" } + PieSlice { label: "Employee"; value: 3998; color: darkGrey; borderColor: "#13060C" } + PieSlice { label: "Logistics"; value: 1332; color: secondaryGrey; borderColor: "#13060C" } } } @@ -96,11 +93,15 @@ Rectangle { pieOuter.at(i).labelPosition = PieSlice.LabelOutside; pieOuter.at(i).labelVisible = true; pieOuter.at(i).borderWidth = 3; + pieOuter.at(i).labelColor = "white"; + pieOuter.at(i).labelFont = appFont; } for (var i = 0; i < pieInner.count; i++) { pieInner.at(i).labelPosition = PieSlice.LabelInsideNormal; pieInner.at(i).labelVisible = true; pieInner.at(i).borderWidth = 2; + pieInner.at(i).labelColor = "white"; + pieInner.at(i).labelFont = appFont; } } //![1] diff --git a/basicsuite/enterprise-charts/View2.qml b/basicsuite/enterprise-charts/View2.qml index 8f136cc..504e6a1 100644 --- a/basicsuite/enterprise-charts/View2.qml +++ b/basicsuite/enterprise-charts/View2.qml @@ -51,17 +51,15 @@ import QtQuick 2.0 import QtCharts 2.0 -Rectangle { +Item { anchors.fill: parent - //![1] - ChartView { + BaseChart { title: "Line" anchors.fill: parent - antialiasing: true - LineSeries { name: "LineSeries" + color: defaultGreen XYPoint { x: 0; y: 0 } XYPoint { x: 1.1; y: 2.1 } XYPoint { x: 1.9; y: 3.3 } @@ -70,6 +68,13 @@ Rectangle { XYPoint { x: 3.4; y: 3.0 } XYPoint { x: 4.1; y: 3.3 } } + + Component.onCompleted: { + axes[0].labelsColor = "white"; + axes[1].labelsColor = "white"; + axes[0].labelsFont = appFont; + axes[1].labelsFont = appFont; + } } //![1] } diff --git a/basicsuite/enterprise-charts/View3.qml b/basicsuite/enterprise-charts/View3.qml index 8429050..8c4e862 100644 --- a/basicsuite/enterprise-charts/View3.qml +++ b/basicsuite/enterprise-charts/View3.qml @@ -51,17 +51,15 @@ import QtQuick 2.0 import QtCharts 2.0 -Rectangle { +Item { anchors.fill: parent - //![1] - ChartView { + BaseChart { title: "Spline" anchors.fill: parent - antialiasing: true - SplineSeries { name: "SplineSeries" + color: defaultGreen XYPoint { x: 0; y: 0.0 } XYPoint { x: 1.1; y: 3.2 } XYPoint { x: 1.9; y: 2.4 } @@ -70,6 +68,13 @@ Rectangle { XYPoint { x: 3.4; y: 2.3 } XYPoint { x: 4.1; y: 3.1 } } + + Component.onCompleted: { + axes[0].labelsColor = "white"; + axes[1].labelsColor = "white"; + axes[0].labelsFont = appFont; + axes[1].labelsFont = appFont; + } } //![1] } diff --git a/basicsuite/enterprise-charts/View4.qml b/basicsuite/enterprise-charts/View4.qml index ac3ea56..606029a 100644 --- a/basicsuite/enterprise-charts/View4.qml +++ b/basicsuite/enterprise-charts/View4.qml @@ -51,15 +51,12 @@ import QtQuick 2.0 import QtCharts 2.0 -Rectangle { +Item { anchors.fill: parent - //![1] - ChartView { + BaseChart { title: "NHL All-Star Team Players" anchors.fill: parent - antialiasing: true - ValueAxis { id: valueAxis min: 2000 @@ -70,8 +67,8 @@ Rectangle { AreaSeries { name: "Russian" - color: "#FFD52B1E" - borderColor: "#FF0039A5" + color: mediumGrey2 + borderColor: darkGreen borderWidth: 3 axisX: valueAxis upperSeries: LineSeries { @@ -93,8 +90,8 @@ Rectangle { AreaSeries { name: "Swedish" - color: "#AF005292" - borderColor: "#AFFDCA00" + color: lightGrey + borderColor: mediumGreen borderWidth: 3 axisX: valueAxis upperSeries: LineSeries { @@ -115,8 +112,8 @@ Rectangle { AreaSeries { name: "Finnish" - color: "#00357F" - borderColor: "#FEFEFE" + color: secondaryGrey + borderColor: defaultGreen borderWidth: 3 axisX: valueAxis upperSeries: LineSeries { @@ -134,5 +131,12 @@ Rectangle { XYPoint { x: 2011; y: 1 } } } + + Component.onCompleted: { + axes[0].labelsColor = "white"; + axes[1].labelsColor = "white"; + axes[0].labelsFont = appFont; + axes[1].labelsFont = appFont; + } } } diff --git a/basicsuite/enterprise-charts/View5.qml b/basicsuite/enterprise-charts/View5.qml index f1005c3..17e9b2f 100644 --- a/basicsuite/enterprise-charts/View5.qml +++ b/basicsuite/enterprise-charts/View5.qml @@ -51,18 +51,16 @@ import QtQuick 2.0 import QtCharts 2.0 -Rectangle { +Item { anchors.fill: parent - //![1] - ChartView { + BaseChart { title: "Scatters" anchors.fill: parent - antialiasing: true - ScatterSeries { id: scatter1 name: "Scatter1" + color: defaultGreen XYPoint { x: 1.5; y: 1.5 } XYPoint { x: 1.5; y: 1.6 } XYPoint { x: 1.57; y: 1.55 } @@ -74,6 +72,7 @@ Rectangle { ScatterSeries { name: "Scatter2" + color: defaultGrey //![1] XYPoint { x: 2.0; y: 2.0 } XYPoint { x: 2.0; y: 2.1 } @@ -82,5 +81,12 @@ Rectangle { XYPoint { x: 2.4; y: 2.7 } XYPoint { x: 2.67; y: 2.65 } } + + Component.onCompleted: { + axes[0].labelsColor = "white"; + axes[1].labelsColor = "white"; + axes[0].labelsFont = appFont; + axes[1].labelsFont = appFont; + } } } diff --git a/basicsuite/enterprise-charts/View6.qml b/basicsuite/enterprise-charts/View6.qml index 6f29bf9..23d4b70 100644 --- a/basicsuite/enterprise-charts/View6.qml +++ b/basicsuite/enterprise-charts/View6.qml @@ -51,22 +51,25 @@ import QtQuick 2.0 import QtCharts 2.0 -Rectangle { +Item { anchors.fill: parent - //![1] - ChartView { + BaseChart { title: "Bar series" anchors.fill: parent - legend.alignment: Qt.AlignBottom - antialiasing: true - BarSeries { id: mySeries axisX: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] } - BarSet { label: "Bob"; values: [2, 2, 3, 4, 5, 6] } - BarSet { label: "Susan"; values: [5, 1, 2, 4, 1, 7] } - BarSet { label: "James"; values: [3, 5, 8, 13, 5, 8] } + BarSet { label: "Bob"; color: defaultGreen; values: [2, 2, 3, 4, 5, 6] } + BarSet { label: "Susan"; color: defaultGrey; values: [5, 1, 2, 4, 1, 7] } + BarSet { label: "James"; color: secondaryGrey; values: [3, 5, 8, 13, 5, 8] } + } + + Component.onCompleted: { + axes[0].labelsColor = "white"; + axes[1].labelsColor = "white"; + axes[0].labelsFont = appFont; + axes[1].labelsFont = appFont; } } //![1] diff --git a/basicsuite/enterprise-charts/View7.qml b/basicsuite/enterprise-charts/View7.qml index c8b6654..5b5426c 100644 --- a/basicsuite/enterprise-charts/View7.qml +++ b/basicsuite/enterprise-charts/View7.qml @@ -51,22 +51,24 @@ import QtQuick 2.0 import QtCharts 2.0 -Rectangle { +Item { anchors.fill: parent - //![1] - ChartView { + BaseChart { title: "Stacked Bar series" anchors.fill: parent - legend.alignment: Qt.AlignBottom - antialiasing: true - StackedBarSeries { id: mySeries axisX: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] } - BarSet { label: "Bob"; values: [2, 2, 3, 4, 5, 6] } - BarSet { label: "Susan"; values: [5, 1, 2, 4, 1, 7] } - BarSet { label: "James"; values: [3, 5, 8, 13, 5, 8] } + BarSet { label: "Bob"; color: defaultGreen; values: [2, 2, 3, 4, 5, 6] } + BarSet { label: "Susan"; color: defaultGrey; values: [5, 1, 2, 4, 1, 7] } + BarSet { label: "James"; color: secondaryGrey; values: [3, 5, 8, 13, 5, 8] } + } + Component.onCompleted: { + axes[0].labelsColor = "white"; + axes[1].labelsColor = "white"; + axes[0].labelsFont = appFont; + axes[1].labelsFont = appFont; } } //![1] diff --git a/basicsuite/enterprise-charts/View8.qml b/basicsuite/enterprise-charts/View8.qml index fbb30e3..ff7bed7 100644 --- a/basicsuite/enterprise-charts/View8.qml +++ b/basicsuite/enterprise-charts/View8.qml @@ -51,21 +51,24 @@ import QtQuick 2.0 import QtCharts 2.0 -Rectangle { +Item { anchors.fill: parent - //![1] - ChartView { + BaseChart { title: "Percent Bar series" anchors.fill: parent - legend.alignment: Qt.AlignBottom - antialiasing: true - PercentBarSeries { axisX: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] } - BarSet { label: "Bob"; values: [2, 2, 3, 4, 5, 6] } - BarSet { label: "Susan"; values: [5, 1, 2, 4, 1, 7] } - BarSet { label: "James"; values: [3, 5, 8, 13, 5, 8] } + BarSet { label: "Bob"; color: defaultGreen; values: [2, 2, 3, 4, 5, 6] } + BarSet { label: "Susan"; color: defaultGrey; values: [5, 1, 2, 4, 1, 7] } + BarSet { label: "James"; color: secondaryGrey; values: [3, 5, 8, 13, 5, 8] } + } + + Component.onCompleted: { + axes[0].labelsColor = "white"; + axes[1].labelsColor = "white"; + axes[0].labelsFont = appFont; + axes[1].labelsFont = appFont; } } //![1] diff --git a/basicsuite/enterprise-charts/View9.qml b/basicsuite/enterprise-charts/View9.qml index 23bc818..89a20b6 100644 --- a/basicsuite/enterprise-charts/View9.qml +++ b/basicsuite/enterprise-charts/View9.qml @@ -51,21 +51,24 @@ import QtQuick 2.0 import QtCharts 2.0 -Rectangle { +Item { anchors.fill: parent - //![1] - ChartView { + BaseChart { title: "Horizontal Bar series" anchors.fill: parent - legend.alignment: Qt.AlignBottom - antialiasing: true - HorizontalBarSeries { axisY: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] } - BarSet { label: "Bob"; values: [2, 2, 3, 4, 5, 6] } - BarSet { label: "Susan"; values: [5, 1, 2, 4, 1, 7] } - BarSet { label: "James"; values: [3, 5, 8, 13, 5, 8] } + BarSet { label: "Bob"; color: defaultGreen; values: [2, 2, 3, 4, 5, 6] } + BarSet { label: "Susan"; color: defaultGrey; values: [5, 1, 2, 4, 1, 7] } + BarSet { label: "James"; color: secondaryGrey; values: [3, 5, 8, 13, 5, 8] } + } + + Component.onCompleted: { + axes[0].labelsColor = "white"; + axes[1].labelsColor = "white"; + axes[0].labelsFont = appFont; + axes[1].labelsFont = appFont; } } //![1] diff --git a/basicsuite/enterprise-charts/enterprise-charts.pro b/basicsuite/enterprise-charts/enterprise-charts.pro index 7896c62..803feb0 100644 --- a/basicsuite/enterprise-charts/enterprise-charts.pro +++ b/basicsuite/enterprise-charts/enterprise-charts.pro @@ -4,6 +4,7 @@ include(../shared/shared.pri) b2qtdemo_deploy_defaults() content.files = \ + BaseChart.qml \ loader.qml \ main.qml \ View1.qml \ diff --git a/basicsuite/enterprise-charts/main.qml b/basicsuite/enterprise-charts/main.qml index d29ed2d..6c16b82 100644 --- a/basicsuite/enterprise-charts/main.qml +++ b/basicsuite/enterprise-charts/main.qml @@ -56,6 +56,14 @@ Rectangle { width: 600 height: 400 property bool sourceLoaded: false + color: defaultBackground + + property string darkGrey: "#222840" + property string darkGrey2: "#53586b" + property string mediumGrey: "#6b7080" + property string mediumGrey2: "#848895" + property string lightGrey: "#b5b7bf" + ListView { id: root @@ -112,6 +120,7 @@ Rectangle { color: "white" anchors.centerIn: parent text: "You can navigate between views using swipe or arrow keys" + font.family: appFont } Behavior on opacity { diff --git a/basicsuite/shared/SharedMain.qml b/basicsuite/shared/SharedMain.qml index ec6d13b..d9f38a8 100644 --- a/basicsuite/shared/SharedMain.qml +++ b/basicsuite/shared/SharedMain.qml @@ -60,6 +60,15 @@ Window { color: "black" + property string defaultGreen: "#41cd52" + property string mediumGreen: "#21be2b" + property string darkGreen: "#17a81a" + + property string defaultBackground: "#09102b" + + property string defaultGrey: "#9d9faa" + property string secondaryGrey: "#3a4055" + Item { id: root anchors.centerIn: window.contentItem -- cgit v1.2.3 From e365074240fe8ebc5b15c6ccc75cc969665fdd8d Mon Sep 17 00:00:00 2001 From: Juho Annunen Date: Tue, 17 Apr 2018 13:51:53 +0300 Subject: Add new fonts Task-number: QTBUG-65302 Change-Id: I9ec2e7f5f904aa148aa29048ccbb84060e1bb3f1 Reviewed-by: Sami Nurmenniemi Reviewed-by: Teemu Holappa --- basicsuite/shared/fonts.qrc | 15 +++++++++++++++ basicsuite/shared/fonts/TitilliumWeb-Black.ttf | Bin 0 -> 49356 bytes basicsuite/shared/fonts/TitilliumWeb-Bold.ttf | Bin 0 -> 59908 bytes basicsuite/shared/fonts/TitilliumWeb-BoldItalic.ttf | Bin 0 -> 69796 bytes basicsuite/shared/fonts/TitilliumWeb-ExtraLight.ttf | Bin 0 -> 63124 bytes .../shared/fonts/TitilliumWeb-ExtraLightItalic.ttf | Bin 0 -> 67788 bytes basicsuite/shared/fonts/TitilliumWeb-Italic.ttf | Bin 0 -> 72416 bytes basicsuite/shared/fonts/TitilliumWeb-Light.ttf | Bin 0 -> 64032 bytes basicsuite/shared/fonts/TitilliumWeb-LightItalic.ttf | Bin 0 -> 71720 bytes basicsuite/shared/fonts/TitilliumWeb-Regular.ttf | Bin 0 -> 63752 bytes basicsuite/shared/fonts/TitilliumWeb-SemiBold.ttf | Bin 0 -> 63044 bytes basicsuite/shared/fonts/TitilliumWeb-SemiBoldItalic.ttf | Bin 0 -> 71812 bytes basicsuite/shared/main.cpp | 8 +++++++- basicsuite/shared/shared.pri | 15 +++++++++++++++ 14 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 basicsuite/shared/fonts.qrc create mode 100644 basicsuite/shared/fonts/TitilliumWeb-Black.ttf create mode 100644 basicsuite/shared/fonts/TitilliumWeb-Bold.ttf create mode 100644 basicsuite/shared/fonts/TitilliumWeb-BoldItalic.ttf create mode 100644 basicsuite/shared/fonts/TitilliumWeb-ExtraLight.ttf create mode 100644 basicsuite/shared/fonts/TitilliumWeb-ExtraLightItalic.ttf create mode 100644 basicsuite/shared/fonts/TitilliumWeb-Italic.ttf create mode 100644 basicsuite/shared/fonts/TitilliumWeb-Light.ttf create mode 100644 basicsuite/shared/fonts/TitilliumWeb-LightItalic.ttf create mode 100644 basicsuite/shared/fonts/TitilliumWeb-Regular.ttf create mode 100644 basicsuite/shared/fonts/TitilliumWeb-SemiBold.ttf create mode 100644 basicsuite/shared/fonts/TitilliumWeb-SemiBoldItalic.ttf diff --git a/basicsuite/shared/fonts.qrc b/basicsuite/shared/fonts.qrc new file mode 100644 index 0000000..13b8cb2 --- /dev/null +++ b/basicsuite/shared/fonts.qrc @@ -0,0 +1,15 @@ + + + fonts/TitilliumWeb-Black.ttf + fonts/TitilliumWeb-Bold.ttf + fonts/TitilliumWeb-BoldItalic.ttf + fonts/TitilliumWeb-ExtraLight.ttf + fonts/TitilliumWeb-ExtraLightItalic.ttf + fonts/TitilliumWeb-Italic.ttf + fonts/TitilliumWeb-Light.ttf + fonts/TitilliumWeb-LightItalic.ttf + fonts/TitilliumWeb-Regular.ttf + fonts/TitilliumWeb-SemiBold.ttf + fonts/TitilliumWeb-SemiBoldItalic.ttf + + diff --git a/basicsuite/shared/fonts/TitilliumWeb-Black.ttf b/basicsuite/shared/fonts/TitilliumWeb-Black.ttf new file mode 100644 index 0000000..fc5c4b5 Binary files /dev/null and b/basicsuite/shared/fonts/TitilliumWeb-Black.ttf differ diff --git a/basicsuite/shared/fonts/TitilliumWeb-Bold.ttf b/basicsuite/shared/fonts/TitilliumWeb-Bold.ttf new file mode 100644 index 0000000..0af0fe7 Binary files /dev/null and b/basicsuite/shared/fonts/TitilliumWeb-Bold.ttf differ diff --git a/basicsuite/shared/fonts/TitilliumWeb-BoldItalic.ttf b/basicsuite/shared/fonts/TitilliumWeb-BoldItalic.ttf new file mode 100644 index 0000000..77425ea Binary files /dev/null and b/basicsuite/shared/fonts/TitilliumWeb-BoldItalic.ttf differ diff --git a/basicsuite/shared/fonts/TitilliumWeb-ExtraLight.ttf b/basicsuite/shared/fonts/TitilliumWeb-ExtraLight.ttf new file mode 100644 index 0000000..2b506ef Binary files /dev/null and b/basicsuite/shared/fonts/TitilliumWeb-ExtraLight.ttf differ diff --git a/basicsuite/shared/fonts/TitilliumWeb-ExtraLightItalic.ttf b/basicsuite/shared/fonts/TitilliumWeb-ExtraLightItalic.ttf new file mode 100644 index 0000000..c1be5ba Binary files /dev/null and b/basicsuite/shared/fonts/TitilliumWeb-ExtraLightItalic.ttf differ diff --git a/basicsuite/shared/fonts/TitilliumWeb-Italic.ttf b/basicsuite/shared/fonts/TitilliumWeb-Italic.ttf new file mode 100644 index 0000000..42f2c10 Binary files /dev/null and b/basicsuite/shared/fonts/TitilliumWeb-Italic.ttf differ diff --git a/basicsuite/shared/fonts/TitilliumWeb-Light.ttf b/basicsuite/shared/fonts/TitilliumWeb-Light.ttf new file mode 100644 index 0000000..ca67971 Binary files /dev/null and b/basicsuite/shared/fonts/TitilliumWeb-Light.ttf differ diff --git a/basicsuite/shared/fonts/TitilliumWeb-LightItalic.ttf b/basicsuite/shared/fonts/TitilliumWeb-LightItalic.ttf new file mode 100644 index 0000000..2ea724f Binary files /dev/null and b/basicsuite/shared/fonts/TitilliumWeb-LightItalic.ttf differ diff --git a/basicsuite/shared/fonts/TitilliumWeb-Regular.ttf b/basicsuite/shared/fonts/TitilliumWeb-Regular.ttf new file mode 100644 index 0000000..6da8219 Binary files /dev/null and b/basicsuite/shared/fonts/TitilliumWeb-Regular.ttf differ diff --git a/basicsuite/shared/fonts/TitilliumWeb-SemiBold.ttf b/basicsuite/shared/fonts/TitilliumWeb-SemiBold.ttf new file mode 100644 index 0000000..dfdcdbe Binary files /dev/null and b/basicsuite/shared/fonts/TitilliumWeb-SemiBold.ttf differ diff --git a/basicsuite/shared/fonts/TitilliumWeb-SemiBoldItalic.ttf b/basicsuite/shared/fonts/TitilliumWeb-SemiBoldItalic.ttf new file mode 100644 index 0000000..b68a669 Binary files /dev/null and b/basicsuite/shared/fonts/TitilliumWeb-SemiBoldItalic.ttf differ diff --git a/basicsuite/shared/main.cpp b/basicsuite/shared/main.cpp index 3c21bf5..4600236 100644 --- a/basicsuite/shared/main.cpp +++ b/basicsuite/shared/main.cpp @@ -76,7 +76,6 @@ int main(int argc, char **argv) QApplication app(argc, argv); - #if defined(USE_QTWEBENGINE) // This is currently needed by all QtWebEngine applications using the HW accelerated QQuickWebView. // It enables sharing the QOpenGLContext of all QQuickWindows of the application. @@ -84,6 +83,11 @@ int main(int argc, char **argv) QtWebEngine::initialize(); #endif + QFontDatabase::addApplicationFont(":/fonts/TitilliumWeb-Regular.ttf"); + QFontDatabase::addApplicationFont(":/fonts/TitilliumWeb-SemiBold.ttf"); + QFontDatabase::addApplicationFont(":/fonts/TitilliumWeb-Bold.ttf"); + QFontDatabase::addApplicationFont(":/fonts/TitilliumWeb-Black.ttf"); + QString path = app.applicationDirPath(); QPalette pal; @@ -117,7 +121,9 @@ int main(int argc, char **argv) DummyEngine engine; QQmlApplicationEngine applicationengine; + QString appFont("TitilliumWeb"); applicationengine.rootContext()->setContextProperty("engine", &engine); + applicationengine.rootContext()->setContextProperty("appFont", appFont); applicationengine.load(QUrl::fromLocalFile(path + "/SharedMain.qml")); app.exec(); diff --git a/basicsuite/shared/shared.pri b/basicsuite/shared/shared.pri index bc1c222..6105f78 100644 --- a/basicsuite/shared/shared.pri +++ b/basicsuite/shared/shared.pri @@ -25,3 +25,18 @@ defineTest(b2qtdemo_deploy_defaults) { export(OTHER_FILES) export(INSTALLS) } + +DISTFILES += $$PWD/fonts/TitilliumWeb-Black.ttf \ + $$PWD/fonts/TitilliumWeb-Bold.ttf \ + $$PWD/fonts/TitilliumWeb-BoldItalic.ttf \ + $$PWD/fonts/TitilliumWeb-ExtraLight.ttf \ + $$PWD/fonts/TitilliumWeb-ExtraLightItalic.ttf \ + $$PWD/fonts/TitilliumWeb-Italic.ttf \ + $$PWD/fonts/TitilliumWeb-Light.ttf \ + $$PWD/fonts/TitilliumWeb-LightItalic.ttf \ + $$PWD/fonts/TitilliumWeb-Regular.ttf \ + $$PWD/fonts/TitilliumWeb-SemiBold.ttf \ + $$PWD/fonts/TitilliumWeb-SemiBoldItalic.ttf + +RESOURCES += \ + $$PWD/fonts.qrc -- cgit v1.2.3 From 2e8942fe7661ba75da5c45d214d2efd6212910c8 Mon Sep 17 00:00:00 2001 From: Juho Annunen Date: Tue, 17 Apr 2018 14:04:55 +0300 Subject: Update GraphicalEffects demo to new UI theme Task-number: QTBUG-62790 Change-Id: Ie4953d8ca1209ed382ad82f1db35c3b1a997dd1d Reviewed-by: Teemu Holappa --- basicsuite/graphicaleffects/main.qml | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/basicsuite/graphicaleffects/main.qml b/basicsuite/graphicaleffects/main.qml index 1b31a9d..a1ee5e8 100644 --- a/basicsuite/graphicaleffects/main.qml +++ b/basicsuite/graphicaleffects/main.qml @@ -73,7 +73,7 @@ Item { anchors.right: checkers.left anchors.top: parent.top anchors.bottom: parent.bottom - color: "black" + color: defaultBackground } ListModel { @@ -102,8 +102,6 @@ Item { clip: true focus: true - highlightMoveDuration: 0 - onCurrentItemChanged: { var entry = listModel.get(currentIndex); loader.source = entry.file; @@ -111,9 +109,7 @@ Item { model: listModel - highlight: Rectangle { - color: "steelblue" - } + delegate: Item { id: delegateRoot @@ -121,20 +117,13 @@ Item { width: list.width height: root.height * 0.05 - Rectangle { - width: parent.width - height: 3 - anchors.bottom: parent.bottom - gradient: Gradient { - GradientStop { position: 0; color: "transparent" } - GradientStop { position: 0.5; color: "lightgray" } - GradientStop { position: 1; color: "transparent" } - } - } + property bool isSelected: list.currentIndex == index Text { - color: "white" - font.pixelSize: parent.height * 0.5 + color: parent.isSelected ? defaultGreen : "white" + font.pixelSize: parent.height * 0.625 + font.family: appFont + font.styleName: parent.isSelected ? "Bold" : "Regular" anchors.verticalCenter: parent.verticalCenter anchors.verticalCenterOffset: -2 x: parent.width * 0.1 @@ -162,14 +151,14 @@ Item { var h = canvas.height; - ctx.fillStyle = "rgb(50, 50, 50)" + ctx.fillStyle = "rgb(58, 64, 85)" ctx.beginPath(); ctx.roundedRect(0, 0, w, h, w * 0.1, w * 0.1); ctx.fill(); var margin = canvas.padding; var segmentSize = 4 - ctx.strokeStyle = "gray" + ctx.strokeStyle = defaultGrey ctx.beginPath(); ctx.moveTo(margin, margin); ctx.lineTo(margin, h-margin); @@ -189,7 +178,7 @@ Item { } Rectangle { - color: "red" + color: defaultGreen width: parent.width / 20 height: width radius: width / 2 @@ -208,6 +197,7 @@ Item { color: "white" font.pixelSize: canvas.padding * 0.5 + font.family: appFont } Text { @@ -222,6 +212,7 @@ Item { + (loader.item != undefined && typeof loader.item.feedbackY != 'undefined' ? ": " + loader.item.feedbackY.toFixed(2) : ""); color: "white" font.pixelSize: canvas.padding * 0.5 + font.family: appFont } MouseArea { -- cgit v1.2.3 From 04e4798de567c64a08e962f541b5dd35d60fedd3 Mon Sep 17 00:00:00 2001 From: Juho Annunen Date: Tue, 17 Apr 2018 15:02:13 +0300 Subject: Update Mediaplayer demo to new UI theme Task-number: QTBUG-62791 Change-Id: Id7cb520669fc696cec65da591414b045fe45754a Reviewed-by: Teemu Holappa --- basicsuite/mediaplayer/Content.qml | 0 basicsuite/mediaplayer/ContentVideo.qml | 0 basicsuite/mediaplayer/ControlBar.qml | 128 ++++++------------ basicsuite/mediaplayer/EffectSelectionPanel.qml | 29 ++-- basicsuite/mediaplayer/FileBrowser.qml | 19 +-- basicsuite/mediaplayer/ImageButton.qml | 15 ++- basicsuite/mediaplayer/MetadataView.qml | 24 +++- basicsuite/mediaplayer/ParameterPanel.qml | 5 +- basicsuite/mediaplayer/PlaybackControl.qml | 70 +++++----- basicsuite/mediaplayer/PlayerSlider.qml | 137 +++++++++++++++++++ basicsuite/mediaplayer/SeekControl.qml | 37 +----- basicsuite/mediaplayer/Slider.qml | 147 --------------------- basicsuite/mediaplayer/UrlBar.qml | 70 ++++------ basicsuite/mediaplayer/VolumeControl.qml | 126 +++++++++++++----- basicsuite/mediaplayer/images/FullscreenButton.png | Bin basicsuite/mediaplayer/images/PlaybackSlider.png | Bin basicsuite/mediaplayer/images/SliderHandle.png | Bin basicsuite/mediaplayer/images/SliderProgress.png | Bin basicsuite/mediaplayer/images/VolumeDown.png | Bin basicsuite/mediaplayer/images/VolumeUp.png | Bin basicsuite/mediaplayer/images/back_icon.svg | 1 + basicsuite/mediaplayer/images/bluetooth_icon.svg | 1 + basicsuite/mediaplayer/images/close_icon.svg | 1 + .../mediaplayer/images/header_toggle_icon.svg | 1 + basicsuite/mediaplayer/images/info_icon.svg | 1 + basicsuite/mediaplayer/images/language_icon.svg | 1 + basicsuite/mediaplayer/images/mute_icon.svg | 1 + basicsuite/mediaplayer/images/pause_icon.svg | 1 + basicsuite/mediaplayer/images/play_icon.svg | 1 + basicsuite/mediaplayer/images/power_icon.svg | 1 + basicsuite/mediaplayer/images/qt-logo.png | Bin basicsuite/mediaplayer/images/settings_icon.svg | 1 + .../images/settingsmenu_launcher_icon.svg | 1 + basicsuite/mediaplayer/images/stop_icon.svg | 1 + basicsuite/mediaplayer/images/titlebar.sci | 0 basicsuite/mediaplayer/images/volume_icon.svg | 1 + basicsuite/mediaplayer/main.qml | 44 ++---- basicsuite/mediaplayer/mediaplayer.pro | 1 - 38 files changed, 428 insertions(+), 438 deletions(-) mode change 100755 => 100644 basicsuite/mediaplayer/Content.qml mode change 100755 => 100644 basicsuite/mediaplayer/ContentVideo.qml mode change 100755 => 100644 basicsuite/mediaplayer/ControlBar.qml mode change 100755 => 100644 basicsuite/mediaplayer/EffectSelectionPanel.qml mode change 100755 => 100644 basicsuite/mediaplayer/ImageButton.qml mode change 100755 => 100644 basicsuite/mediaplayer/PlaybackControl.qml create mode 100644 basicsuite/mediaplayer/PlayerSlider.qml mode change 100755 => 100644 basicsuite/mediaplayer/SeekControl.qml delete mode 100644 basicsuite/mediaplayer/Slider.qml mode change 100755 => 100644 basicsuite/mediaplayer/VolumeControl.qml mode change 100755 => 100644 basicsuite/mediaplayer/images/FullscreenButton.png mode change 100755 => 100644 basicsuite/mediaplayer/images/PlaybackSlider.png mode change 100755 => 100644 basicsuite/mediaplayer/images/SliderHandle.png mode change 100755 => 100644 basicsuite/mediaplayer/images/SliderProgress.png mode change 100755 => 100644 basicsuite/mediaplayer/images/VolumeDown.png mode change 100755 => 100644 basicsuite/mediaplayer/images/VolumeUp.png create mode 100644 basicsuite/mediaplayer/images/back_icon.svg create mode 100644 basicsuite/mediaplayer/images/bluetooth_icon.svg create mode 100644 basicsuite/mediaplayer/images/close_icon.svg create mode 100644 basicsuite/mediaplayer/images/header_toggle_icon.svg create mode 100644 basicsuite/mediaplayer/images/info_icon.svg create mode 100644 basicsuite/mediaplayer/images/language_icon.svg create mode 100644 basicsuite/mediaplayer/images/mute_icon.svg create mode 100644 basicsuite/mediaplayer/images/pause_icon.svg create mode 100644 basicsuite/mediaplayer/images/play_icon.svg create mode 100644 basicsuite/mediaplayer/images/power_icon.svg mode change 100755 => 100644 basicsuite/mediaplayer/images/qt-logo.png create mode 100644 basicsuite/mediaplayer/images/settings_icon.svg create mode 100644 basicsuite/mediaplayer/images/settingsmenu_launcher_icon.svg create mode 100644 basicsuite/mediaplayer/images/stop_icon.svg mode change 100755 => 100644 basicsuite/mediaplayer/images/titlebar.sci create mode 100644 basicsuite/mediaplayer/images/volume_icon.svg mode change 100755 => 100644 basicsuite/mediaplayer/main.qml diff --git a/basicsuite/mediaplayer/Content.qml b/basicsuite/mediaplayer/Content.qml old mode 100755 new mode 100644 diff --git a/basicsuite/mediaplayer/ContentVideo.qml b/basicsuite/mediaplayer/ContentVideo.qml old mode 100755 new mode 100644 diff --git a/basicsuite/mediaplayer/ControlBar.qml b/basicsuite/mediaplayer/ControlBar.qml old mode 100755 new mode 100644 index 05d253e..e65a3a3 --- a/basicsuite/mediaplayer/ControlBar.qml +++ b/basicsuite/mediaplayer/ControlBar.qml @@ -53,8 +53,8 @@ import QtMultimedia 5.0 Rectangle { id: controlBar - height: 150 - color: "#88333333" + height: parent.height * 0.225 + color: defaultBackground property MediaPlayer mediaPlayer: null property bool isMouseAbove: false @@ -73,13 +73,13 @@ Rectangle { volumeControl.volume = mediaPlayer.volume; } -// MouseArea { -// anchors.fill: controlBar -// hoverEnabled: true + MouseArea { + anchors.fill: controlBar + hoverEnabled: true -// onEntered: controlBar.isMouseAbove = true; -// onExited: controlBar.isMouseAbove = false; -// } + onEntered: controlBar.isMouseAbove = true; + onExited: controlBar.isMouseAbove = false; + } function statusString(stat) { @@ -103,48 +103,12 @@ Rectangle { return "UnknownStatus"; } -// Text { -// id: statusText -// anchors.left: parent.left -// anchors.bottom: parent.top -// anchors.bottomMargin: 12 -// font.pixelSize: 18 -// color: "white" -// text: "Status: " + statusString(mediaPlayer.status) -// } - -// Text { -// anchors.verticalCenter: statusText.verticalCenter -// anchors.left: statusText.right -// anchors.leftMargin: 16 -// font.pixelSize: 18 -// color: "white" -// text: Math.round(mediaPlayer.bufferProgress * 100.0) + "%" -// } - - VolumeControl { - id: volumeControl - anchors.verticalCenter: playbackControl.verticalCenter - anchors.left: controlBar.left - anchors.leftMargin: 15 - onVolumeChanged: mediaPlayer.volume = volume - - Component.onCompleted: { - volumeControl.volume = 0.5; - } - - Connections { - target: mediaPlayer - onVolumeChanged: volumeControl.volume = mediaPlayer.volume - } - } - //Playback Controls PlaybackControl { id: playbackControl - anchors.horizontalCenter: controlBar.horizontalCenter - anchors.bottom: seekControl.top - anchors.bottomMargin: 20 + anchors.left: controlBar.left + anchors.top: controlBar.top + anchors.bottom: controlBar.bottom onPlayButtonPressed: { if (isPlaying) { @@ -171,12 +135,35 @@ Rectangle { onStopButtonPressed: mediaPlayer.stop(); } + //Seek controls + SeekControl { + id: seekControl + anchors.bottom: controlBar.bottom + anchors.bottomMargin: controlBar.height * 0.1 + anchors.right: volumeControl.left + anchors.left: playbackControl.right + anchors.rightMargin: 15 + anchors.leftMargin: 15 + enabled: playbackControl.isPlaybackEnabled + + duration: mediaPlayer.duration + + onSeekValueChanged: { + mediaPlayer.seek(newPosition); + position = mediaPlayer.position; + } + + Component.onCompleted: { + seekable = mediaPlayer.seekable; + } + } + //Toolbar Controls Row { id: toolbarMenuButtons - anchors.right: controlBar.right + anchors.right: volumeControl.left anchors.rightMargin: 15 - anchors.verticalCenter: playbackControl.verticalCenter + anchors.bottom: seekControl.top spacing: 22 ImageButton { @@ -204,41 +191,15 @@ Rectangle { } } -// ImageButton { -// id: fullscreenButton -// imageSource: "images/FullscreenButton.png" -// onClicked: { -// //Toggle fullscreen -// toggleFullScreen(); -// } -// checkable: true -// checked: applicationWindow.isFullScreen -// anchors.right: controlBar.right -// anchors.top: controlBar.top -// anchors.rightMargin: 15 -// anchors.topMargin: 15 -// } - - //Seek controls - SeekControl { - id: seekControl - anchors.bottom: controlBar.bottom - anchors.bottomMargin: 10 - anchors.right: controlBar.right - anchors.left: controlBar.left - anchors.rightMargin: 15 - anchors.leftMargin: 15 - enabled: playbackControl.isPlaybackEnabled - - duration: mediaPlayer.duration - - onSeekValueChanged: { - mediaPlayer.seek(newPosition); - position = mediaPlayer.position; - } + VolumeControl { + id: volumeControl + anchors.bottom: parent.bottom + anchors.right: parent.right + onVolumeChanged: mediaPlayer.volume = volume - Component.onCompleted: { - seekable = mediaPlayer.seekable; + Connections { + target: mediaPlayer + onVolumeChanged: volumeControl.volume = mediaPlayer.volume } } @@ -264,7 +225,6 @@ Rectangle { } onSeekableChanged: { - // console.log("seekableChanged: " + mediaPlayer.seekable); seekControl.seekable = mediaPlayer.seekable; } } diff --git a/basicsuite/mediaplayer/EffectSelectionPanel.qml b/basicsuite/mediaplayer/EffectSelectionPanel.qml old mode 100755 new mode 100644 index 4f29f50..68a9cac --- a/basicsuite/mediaplayer/EffectSelectionPanel.qml +++ b/basicsuite/mediaplayer/EffectSelectionPanel.qml @@ -51,7 +51,7 @@ import QtQuick 2.0 Rectangle { id: root - color: "#BB333333" + color: defaultBackground height: 78 property int itemHeight: 25 property string effectSource: "" @@ -76,14 +76,14 @@ Rectangle { ListElement { name: "Glow"; source: "Effects/EffectGlow.qml" } ListElement { name: "Isolate"; source: "Effects/EffectIsolate.qml" } //ListElement { name: "Magnify"; source: "Effects/EffectMagnify.qml" } -// ListElement { name: "Page curl"; source: "Effects/EffectPageCurl.qml" } + // ListElement { name: "Page curl"; source: "Effects/EffectPageCurl.qml" } ListElement { name: "Pixelate"; source: "Effects/EffectPixelate.qml" } ListElement { name: "Posterize"; source: "Effects/EffectPosterize.qml" } -// ListElement { name: "Ripple"; source: "Effects/EffectRipple.qml" } + // ListElement { name: "Ripple"; source: "Effects/EffectRipple.qml" } ListElement { name: "Sepia"; source: "Effects/EffectSepia.qml" } ListElement { name: "Sharpen"; source: "Effects/EffectSharpen.qml" } ListElement { name: "Shockwave"; source: "Effects/EffectShockwave.qml" } -// ListElement { name: "Tilt shift"; source: "Effects/EffectTiltShift.qml" } + // ListElement { name: "Tilt shift"; source: "Effects/EffectTiltShift.qml" } ListElement { name: "Toon"; source: "Effects/EffectToon.qml" } ListElement { name: "Warhol"; source: "Effects/EffectWarhol.qml" } ListElement { name: "Wobble"; source: "Effects/EffectWobble.qml" } @@ -104,6 +104,7 @@ Rectangle { height: 0.8 * itemHeight text: name color: "white" + font.family: appFont } states: [ @@ -155,16 +156,18 @@ Rectangle { delegate: Item { height: 40 width: parent.width - Rectangle { + property bool isSelected: list.currentIndex == index + Text { + color: parent.isSelected ? defaultGreen : "white" + text: name + anchors.centerIn: parent + font.pixelSize: 20 + font.family: appFont + font.styleName: parent.isSelected ? "Bold" : "Regular" + } + MouseArea { anchors.fill: parent - border.color: index == list.currentIndex ? "#44ffffff" : "transparent" - color: index == list.currentIndex ? "#22ffffff" : "transparent" - radius: 3 - Text { color: "white" ; text: name ; anchors.centerIn: parent; font.pixelSize: 20 } - MouseArea { - anchors.fill: parent - onClicked: list.currentIndex = index - } + onClicked: list.currentIndex = index } } } diff --git a/basicsuite/mediaplayer/FileBrowser.qml b/basicsuite/mediaplayer/FileBrowser.qml index 5ffe130..8bae836 100644 --- a/basicsuite/mediaplayer/FileBrowser.qml +++ b/basicsuite/mediaplayer/FileBrowser.qml @@ -50,6 +50,7 @@ import QtQuick 2.0 import Qt.labs.folderlistmodel 2.0 import QtQuick.Controls 1.4 +import QtDeviceUtilities.QtButtonImageProvider 1.0 Item { id: fileBrowser @@ -77,7 +78,7 @@ Item { Rectangle { id: root - color: "white" + color: defaultBackground property alias folder: folders.folder FolderListModel { @@ -110,7 +111,8 @@ Item { wrapMode: Text.WrapAtWordBoundaryOrAnywhere text: fileName font.pixelSize: parent.height * .1 - color: view.currentIndex === index ? "#80c342" : "#46484a" + font.family: appFont + color: view.currentIndex === index ? defaultGreen : "white" elide: Text.ElideRight } @@ -182,10 +184,10 @@ Item { Rectangle { width: parent.width; height: 70 - color: "#f6f6f6" + color: defaultBackground id: titleBar - Button { + QtButton { id: backButton text: qsTr("Back") anchors.left: parent.left @@ -203,17 +205,16 @@ Item { anchors.bottom: parent.bottom text: String(folders.folder).replace("file://", "") - color: "#46484a" + color: "white" elide: Text.ElideLeft verticalAlignment: Text.AlignVCenter font.pixelSize: backButton.height * .8 + font.family: appFont } - Button { + QtButton { id: cancelButton text: qsTr("Cancel") - checkable: true - checked: true anchors.right: parent.right anchors.rightMargin: parent.width * .05 anchors.verticalCenter: parent.verticalCenter @@ -224,7 +225,7 @@ Item { width: parent.width anchors.bottom: parent.bottom height: 2 - color: "#e4e4e4" + color: defaultGrey } } diff --git a/basicsuite/mediaplayer/ImageButton.qml b/basicsuite/mediaplayer/ImageButton.qml old mode 100755 new mode 100644 index 31bd315..4e26fc1 --- a/basicsuite/mediaplayer/ImageButton.qml +++ b/basicsuite/mediaplayer/ImageButton.qml @@ -49,6 +49,7 @@ ****************************************************************************/ import QtQuick 2.0 +import QtGraphicalEffects 1.0 Item { id: root @@ -75,13 +76,13 @@ Item { smooth: true } -// ColorOverlay { -// id: glowEffect -// anchors.fill: image -// source: image -// color: pressed ? "#22000000" : checked ? "orange" : "white" -// visible: checked || hover || pressed -// } + ColorOverlay { + id: glowEffect + anchors.fill: image + source: image + color: pressed ? "#22000000" : checked ? defaultGreen : "white" + visible: checked || hover || pressed + } MouseArea { id: mouseArea diff --git a/basicsuite/mediaplayer/MetadataView.qml b/basicsuite/mediaplayer/MetadataView.qml index e85df5e..79883d2 100644 --- a/basicsuite/mediaplayer/MetadataView.qml +++ b/basicsuite/mediaplayer/MetadataView.qml @@ -48,6 +48,7 @@ ** ****************************************************************************/ import QtQuick 2.0 +import QtMultimedia 5.0 Rectangle { id: root @@ -62,10 +63,12 @@ Rectangle { Rectangle { height: column.height + 30 width: 500 - color: "#BB222222" + color: defaultBackground + opacity: 0.9 anchors.centerIn: parent anchors.verticalCenterOffset: -50 - + border.color: defaultGrey + border.width: 2 Column { id: column @@ -80,6 +83,7 @@ Rectangle { visible: mediaPlayer && mediaPlayer.metaData.mediaType !== undefined color: "white" font.pixelSize: 24 + font.family: appFont width: parent.width wrapMode: Text.WordWrap } @@ -88,6 +92,7 @@ Rectangle { visible: mediaPlayer && mediaPlayer.metaData.title !== undefined color: "white" font.pixelSize: 24 + font.family: appFont width: parent.width wrapMode: Text.WordWrap } @@ -96,6 +101,7 @@ Rectangle { visible: mediaPlayer && mediaPlayer.metaData.leadPerformer !== undefined color: "white" font.pixelSize: 24 + font.family: appFont width: parent.width wrapMode: Text.WordWrap } @@ -104,6 +110,7 @@ Rectangle { visible: mediaPlayer && mediaPlayer.metaData.contributingArtist !== undefined color: "white" font.pixelSize: 24 + font.family: appFont width: parent.width wrapMode: Text.WordWrap } @@ -112,6 +119,7 @@ Rectangle { visible: mediaPlayer && mediaPlayer.metaData.albumTitle !== undefined color: "white" font.pixelSize: 24 + font.family: appFont width: parent.width wrapMode: Text.WordWrap } @@ -120,6 +128,7 @@ Rectangle { visible: mediaPlayer && mediaPlayer.metaData.albumArtist !== undefined color: "white" font.pixelSize: 24 + font.family: appFont width: parent.width wrapMode: Text.WordWrap } @@ -128,6 +137,7 @@ Rectangle { visible: mediaPlayer && mediaPlayer.metaData.author !== undefined color: "white" font.pixelSize: 24 + font.family: appFont width: parent.width wrapMode: Text.WordWrap } @@ -136,6 +146,7 @@ Rectangle { visible: mediaPlayer && mediaPlayer.metaData.composer !== undefined color: "white" font.pixelSize: 24 + font.family: appFont width: parent.width wrapMode: Text.WordWrap } @@ -144,6 +155,7 @@ Rectangle { visible: mediaPlayer && mediaPlayer.metaData.writer !== undefined color: "white" font.pixelSize: 24 + font.family: appFont width: parent.width wrapMode: Text.WordWrap } @@ -152,6 +164,7 @@ Rectangle { visible: mediaPlayer && mediaPlayer.metaData.genre !== undefined color: "white" font.pixelSize: 24 + font.family: appFont width: parent.width wrapMode: Text.WordWrap } @@ -160,6 +173,7 @@ Rectangle { visible: mediaPlayer && mediaPlayer.metaData.trackNumber !== undefined color: "white" font.pixelSize: 24 + font.family: appFont width: parent.width wrapMode: Text.WordWrap } @@ -168,6 +182,7 @@ Rectangle { visible: mediaPlayer && mediaPlayer.metaData.year !== undefined color: "white" font.pixelSize: 24 + font.family: appFont width: parent.width wrapMode: Text.WordWrap } @@ -176,6 +191,7 @@ Rectangle { visible: mediaPlayer && mediaPlayer.metaData.duration !== undefined color: "white" font.pixelSize: 24 + font.family: appFont width: parent.width wrapMode: Text.WordWrap } @@ -184,6 +200,7 @@ Rectangle { visible: mediaPlayer && mediaPlayer.metaData.resolution !== undefined color: "white" font.pixelSize: 24 + font.family: appFont width: parent.width wrapMode: Text.WordWrap } @@ -192,6 +209,7 @@ Rectangle { visible: mediaPlayer && mediaPlayer.metaData.audioBitRate !== undefined color: "white" font.pixelSize: 24 + font.family: appFont width: parent.width wrapMode: Text.WordWrap } @@ -200,6 +218,7 @@ Rectangle { visible: mediaPlayer && mediaPlayer.metaData.videoBitRate !== undefined color: "white" font.pixelSize: 24 + font.family: appFont width: parent.width wrapMode: Text.WordWrap } @@ -208,6 +227,7 @@ Rectangle { visible: mediaPlayer && mediaPlayer.metaData.date !== undefined color: "white" font.pixelSize: 24 + font.family: appFont width: parent.width wrapMode: Text.WordWrap } diff --git a/basicsuite/mediaplayer/ParameterPanel.qml b/basicsuite/mediaplayer/ParameterPanel.qml index bc6a73e..5b8e991 100644 --- a/basicsuite/mediaplayer/ParameterPanel.qml +++ b/basicsuite/mediaplayer/ParameterPanel.qml @@ -52,7 +52,7 @@ import QtQuick 2.0 Rectangle { id: root height: view.model.count * sliderHeight - color: "#BB333333" + color: defaultBackground property color lineColor: "black" property real spacing: 10 property real sliderHeight: 50 @@ -89,10 +89,11 @@ Rectangle { verticalAlignment: Text.AlignVCenter font.pixelSize: 20 font.capitalization: Font.Capitalize + font.family: appFont width: 90 } - Slider { + PlayerSlider { anchors { verticalCenter: text.verticalCenter verticalCenterOffset: 3 diff --git a/basicsuite/mediaplayer/PlaybackControl.qml b/basicsuite/mediaplayer/PlaybackControl.qml old mode 100755 new mode 100644 index 66c1c92..5fff05f --- a/basicsuite/mediaplayer/PlaybackControl.qml +++ b/basicsuite/mediaplayer/PlaybackControl.qml @@ -49,11 +49,13 @@ ****************************************************************************/ import QtQuick 2.0 +import QtDeviceUtilities.QtButtonImageProvider 1.0 Row { + anchors.leftMargin: parent.width * 0.02 id: root - spacing: 26 - height: playButton.height + spacing: parent.width * 0.02 + height: parent.height property bool isPlaybackEnabled: false property bool isPlaying: false @@ -64,46 +66,42 @@ Row { signal stopButtonPressed() //Playback Controls - ImageButton { - id: rateReverseButton - enabled: isPlaybackEnabled - imageSource: "images/RateButtonReverse.png" - anchors.verticalCenter: root.verticalCenter - onClicked: { - reverseButtonPressed(); + QtButton{ + id: playPauseButton + width: controlBar.width * 0.06 + height: width + anchors.bottom: parent.bottom + anchors.bottomMargin: root.spacing + fillColor: viewSettings.buttonGreenColor + Image{ + anchors.centerIn: parent + width: parent.width * 0.5 + height: width + source: !isPlaying ? "images/play_icon.svg" : "images/pause_icon.svg" + sourceSize.width: parent.width + sourceSize.height: parent.height } - } - ImageButton { - id: playButton - enabled: isPlaybackEnabled - imageSource: !isPlaying ? "images/PlayButton.png" : "images/PauseButton.png" - anchors.verticalCenter: root.verticalCenter -// anchors.right: rateForwardButton.left -// anchors.rightMargin: 10 onClicked: { playButtonPressed(); } } -// Rectangle{ -// enabled: isPlaybackEnabled -// color: "white" -// opacity: enabled ? 1 : 0.3 -// width: playButton.width -// height: width -// anchors.verticalCenter: root.verticalCenter -// MouseArea { -// anchors.fill: parent -// onClicked: stopButtonPressed(); -// } -// } - - ImageButton { - id: rateForwardButton - enabled: isPlaybackEnabled - imageSource: "images/RateButtonForward.png" - anchors.verticalCenter: root.verticalCenter + QtButton{ + id: stopButton + width: controlBar.width * 0.06 + height: width + anchors.bottom: parent.bottom + anchors.bottomMargin: root.spacing + fillColor: viewSettings.buttonGreenColor + Image{ + anchors.centerIn: parent + width: parent.width * 0.5 + height: width + source: "images/stop_icon.svg" + sourceSize.width: parent.width + sourceSize.height: parent.height + } onClicked: { - forwardButtonPressed(); + stopButtonPressed(); } } } diff --git a/basicsuite/mediaplayer/PlayerSlider.qml b/basicsuite/mediaplayer/PlayerSlider.qml new file mode 100644 index 0000000..d569866 --- /dev/null +++ b/basicsuite/mediaplayer/PlayerSlider.qml @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Device Creation. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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 + +Item { + id: slider + height: handle.height + // value is read/write. + property real value: 0 + property real maximum: 1 + property real minimum: 0 + property int xMax: width - handle.width + onXMaxChanged: updatePos() + onMinimumChanged: updatePos() + onValueChanged: if (!pressed) updatePos() + property bool mutable: true + property alias pressed : backgroundMouse.pressed + + signal valueChangedByHandle(int newValue) + + function updatePos() { + if (maximum > minimum) { + var pos = 0 + (value - minimum) * slider.xMax / (maximum - minimum); + pos = Math.min(pos, width - handle.width - 0); + pos = Math.max(pos, 0); + handle.x = pos; + } else { + handle.x = 0; + } + } + + Rectangle { + id: background + width: slider.width + anchors.verticalCenter: slider.verticalCenter + height: 5 + color: "#9d9faa" + radius: 2 + + MouseArea { + id: backgroundMouse + anchors.fill: parent + anchors.topMargin: -24 + anchors.bottomMargin: -24 + enabled: slider.mutable + drag.target: handle + drag.axis: Drag.XAxis + drag.minimumX: 0 + drag.maximumX: slider.xMax + onPressedChanged: { + value = Math.max(minimum, Math.min(maximum, (maximum - minimum) * (mouseX - handle.width/2) / slider.xMax + minimum)); + valueChangedByHandle(value); + updatePos(); + } + onPositionChanged: { + value = Math.max(minimum, Math.min(maximum, (maximum - minimum) * (mouseX - handle.width/2) / slider.xMax + minimum)); + valueChangedByHandle(value); + } + onWheel: { + value = Math.max(minimum, Math.min(maximum, value + (wheel.angleDelta.y > 0 ? 1 : -1) * (10 / slider.xMax) * (slider.maximum - slider.minimum))); + valueChangedByHandle(value); + updatePos(); + } + } + } + + Rectangle { + id: progress + height: 5 + anchors.verticalCenter: background.verticalCenter + anchors.left: background.left + anchors.right: handle.right + anchors.rightMargin: handle.width / 2 + visible: slider.enabled + color: "white" + radius: 2 + } + + Rectangle { + id: handle + width: 40 + height: width + radius: width / 2 + color: "#41cd52" + antialiasing: true + anchors.centerIn: handle + visible: true + } +} + diff --git a/basicsuite/mediaplayer/SeekControl.qml b/basicsuite/mediaplayer/SeekControl.qml old mode 100755 new mode 100644 index a7ca93f..16987f7 --- a/basicsuite/mediaplayer/SeekControl.qml +++ b/basicsuite/mediaplayer/SeekControl.qml @@ -48,11 +48,11 @@ ** ****************************************************************************/ import QtQuick 2.0 +import QtQuick.Controls 2.2 Item { id: root - height: seekSlider.height - + height: parent.height * 0.5 property int position: 0 property int duration: 0 property bool seekable: false @@ -62,29 +62,15 @@ Item { signal seekValueChanged(int newPosition) onPositionChanged: { - elapsedText.text = formatTime(position); seekSlider.value = position; } - onDurationChanged: { - remainingText.text = formatTime(duration); - } - - Text { - id: elapsedText - anchors.verticalCenter: seekSlider.verticalCenter - anchors.left: root.left - text: "00:00" - font.pixelSize: 20 - color: "#cccccc" - } - - Slider { + PlayerSlider { id: seekSlider - anchors.leftMargin: 30 - anchors.rightMargin: 30 - anchors.left: elapsedText.right - anchors.right: remainingText.left + anchors.leftMargin: parent.width * 0.02 + anchors.rightMargin: parent.width * 0.02 + anchors.left: parent.left + anchors.right: parent.right anchors.verticalCenter: root.verticalCenter mutable: root.seekable enabled: root.enabled @@ -98,15 +84,6 @@ Item { } } - Text { - id: remainingText - anchors.verticalCenter: seekSlider.verticalCenter - anchors.right: root.right - text: "00:00" - font.pixelSize: 20 - color: "#cccccc" - } - function formatTime(time) { time = time / 1000 var hours = Math.floor(time / 3600); diff --git a/basicsuite/mediaplayer/Slider.qml b/basicsuite/mediaplayer/Slider.qml deleted file mode 100644 index 0cacbc7..0000000 --- a/basicsuite/mediaplayer/Slider.qml +++ /dev/null @@ -1,147 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of Qt for Device Creation. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, 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 The Qt Company Ltd 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 - -Item { - id: slider - - height: handleBack.height - // value is read/write. - property real value: 0 - property real maximum: 1 - property real minimum: 0 - property int xMax: width - handle.width - onXMaxChanged: updatePos() - onMinimumChanged: updatePos() - onValueChanged: if (!pressed) updatePos() - property bool mutable: true - property alias pressed : backgroundMouse.pressed - - signal valueChangedByHandle(int newValue) - - function updatePos() { - if (maximum > minimum) { - var pos = 0 + (value - minimum) * slider.xMax / (maximum - minimum); - pos = Math.min(pos, width - handle.width - 0); - pos = Math.max(pos, 0); - handle.x = pos; - } else { - handle.x = 0; - } - } - - Rectangle { - id: background - width: slider.width - anchors.verticalCenter: slider.verticalCenter - height: 2 - color: "#666666" - - MouseArea { - id: backgroundMouse - anchors.fill: parent - anchors.topMargin: -24 - anchors.bottomMargin: -24 - enabled: slider.mutable - drag.target: handle - drag.axis: Drag.XAxis - drag.minimumX: 0 - drag.maximumX: slider.xMax - onPressedChanged: { - value = Math.max(minimum, Math.min(maximum, (maximum - minimum) * (mouseX - handle.width/2) / slider.xMax + minimum)); - valueChangedByHandle(value); - updatePos(); - } - onPositionChanged: { - value = Math.max(minimum, Math.min(maximum, (maximum - minimum) * (mouseX - handle.width/2) / slider.xMax + minimum)); - valueChangedByHandle(value); - } - onWheel: { - value = Math.max(minimum, Math.min(maximum, value + (wheel.angleDelta.y > 0 ? 1 : -1) * (10 / slider.xMax) * (slider.maximum - slider.minimum))); - valueChangedByHandle(value); - updatePos(); - } - } - } - - Rectangle { - id: progress - height: 5 - anchors.verticalCenter: background.verticalCenter - anchors.left: background.left - anchors.right: handle.right - anchors.rightMargin: handle.width / 2 - visible: slider.enabled - color: "#98c66c" - } - - Rectangle { - id: handleBack - width: 40 - height: width - radius: width / 2 - color: "#8898c66c" - antialiasing: true - anchors.centerIn: handle - visible: handle.visible - } - - Rectangle { - id: handle - width: 14 - height: width - radius: width / 2 - antialiasing: true - color: "#98c66c" - anchors.verticalCenter: background.verticalCenter - visible: slider.enabled - } -} - diff --git a/basicsuite/mediaplayer/UrlBar.qml b/basicsuite/mediaplayer/UrlBar.qml index dbaa8d0..78ba6ec 100644 --- a/basicsuite/mediaplayer/UrlBar.qml +++ b/basicsuite/mediaplayer/UrlBar.qml @@ -48,6 +48,7 @@ ** ****************************************************************************/ import QtQuick 2.0 +import QtQuick.Controls 2.0 Rectangle { id: root @@ -76,54 +77,39 @@ Rectangle { text: "Enter URL" color: "white" font.pixelSize: 20 + font.family: appFont } - BorderImage { - id: urlBar - source: "images/ControlBar.png" - border.top: 12 - border.bottom: 12 - border.left: 12 - border.right: 12 + TextField { + id: urlInput height: 70 - anchors.centerIn: parent - anchors.verticalCenterOffset: -170 width: 600 + anchors.horizontalCenter: parent.horizontalCenter + font.pixelSize: height * 0.45 + color: "white" + text: "" + placeholderText: "http://" + font.family: appFont + font.styleName: "Light" + background: Rectangle { + color: defaultBackground + opacity: 0.8 + border.color: viewSettings.borderColor + border.width: 2 + } + onAccepted: root.urlAccepted(urlInput.text); + } - Rectangle { + Rectangle { + anchors.right: urlBar.left + anchors.rightMargin: 32 + anchors.verticalCenter: urlBar.verticalCenter + height: 70 + width: 70 + color: defaultGrey + MouseArea { anchors.fill: parent - anchors.margins: 16 - color: "#66ffffff" - border.color: "#bbffffff" - radius: 2 - antialiasing: true - - TextInput { - id: urlInput - selectionColor: "#aaffffff" - selectedTextColor: "black" - selectByMouse: true - anchors.fill: parent - anchors.margins: 5 - font.pixelSize: 24 - color: "black" - text: "http://" - onAccepted: root.urlAccepted(urlInput.text); - - } + onClicked: { urlInput.text = ""; urlInput.paste(); } } } - -// Rectangle { -// anchors.right: urlBar.left -// anchors.rightMargin: 32 -// anchors.verticalCenter: urlBar.verticalCenter -// height: 70 -// width: 70 -// color: "gray" -// MouseArea { -// anchors.fill: parent -// onClicked: { urlInput.text = ""; urlInput.paste(); } -// } -// } } diff --git a/basicsuite/mediaplayer/VolumeControl.qml b/basicsuite/mediaplayer/VolumeControl.qml old mode 100755 new mode 100644 index f2bd427..c1f3dce --- a/basicsuite/mediaplayer/VolumeControl.qml +++ b/basicsuite/mediaplayer/VolumeControl.qml @@ -49,46 +49,110 @@ ****************************************************************************/ import QtQuick 2.0 - +import QtDeviceUtilities.QtButtonImageProvider 1.0 +import QtQuick.Controls 2.2 Item { id: root - width: 210 - height: volumeUp.height - + width: parent.width * 0.1 + height: parent.height property alias volume: volumeSlider.value + property bool muted: root.volume == 0.0 + property bool volumeItemUp: volumeItem.y == (volumeItem.height + volumeItem.height * 0.05) //Volume Controls - ImageButton { - id: volumeDown - imageSource: "images/VolumeDown.png" - anchors.verticalCenter: root.verticalCenter - anchors.left: root.left - scale: 1.4 + QtButton{ + id: toggleVolumeButton + width: controlBar.width * 0.06 + height: width + anchors.bottom: parent.bottom + anchors.bottomMargin: controlBar.width * 0.02 + anchors.horizontalCenter: parent.horizontalCenter + fillColor: viewSettings.buttonGreenColor + + Image{ + anchors.centerIn: parent + width: parent.width * 0.5 + height: width + source: !muted ? "images/volume_icon.svg" : "images/mute_icon.svg" + sourceSize.width: parent.width + sourceSize.height: parent.height + } onClicked: { - root.volume = 0.0; + if (volumeItem.opacity == 0) + volumeItem.opacity = 1; + else if (volumeItem.opacity > 0) + volumeItem.opacity = 0; + + if (volumeItem.y === 0) + volumeItem.y -= (volumeItem.height + volumeItem.height * 0.05); + else if (volumeItem !== 0) + volumeItem.y = 0; } } - Slider { - id: volumeSlider - anchors.left: volumeDown.right - anchors.leftMargin: 22 - anchors.rightMargin: 22 - anchors.right: volumeUp.left - maximum: 1.0 - minimum: 0.0 - anchors.verticalCenter: root.verticalCenter - anchors.verticalCenterOffset: 1 - } - ImageButton { - id: volumeUp - imageSource: "images/VolumeUp.png" - anchors.verticalCenter: root.verticalCenter - anchors.verticalCenterOffset: 1 - anchors.right: root.right - scale: 1.4 - onClicked: { - root.volume = 1.0 + Item{ + id: volumeItem + height: applicationWindow.height * 0.4 + anchors.right: toggleVolumeButton.left //? + opacity: 0 + y: 0 + z: -1000 + QtButton{ + id: muteVolumeButton + width: controlBar.width * 0.06 + height: width + anchors.bottom: parent.bottom + fillColor: viewSettings.buttonGrayColor + borderColor: "transparent" + Image{ + anchors.centerIn: parent + width: parent.width * 0.5 + height: parent.height * 0.5 + source: "images/mute_icon.svg" + sourceSize.width: parent.width + sourceSize.height: parent.height + } + onClicked: { + root.volume = 0.0 + } } + + Slider { + id: volumeSlider + anchors.bottom: muteVolumeButton.top + anchors.bottomMargin: parent.height * 0.05 + anchors.top: parent.top + anchors.horizontalCenter: muteVolumeButton.horizontalCenter + orientation: Qt.Vertical + + background: Rectangle{ + id: sliderBackground + x: volumeSlider.leftPadding + volumeSlider.availableWidth / 2 - width / 2 + y: volumeSlider.bottomPadding + implicitWidth: 5 + implicitHeight: 200 + height: volumeSlider.availableHeight + width: implicitWidth + radius: 2 + color: "white" + Rectangle{ + height: volumeSlider.visualPosition * parent.height + width: parent.width + color: defaultGrey + radius: 2 + } + } + handle: Rectangle{ + x: volumeSlider.leftPadding + volumeSlider.availableWidth / 2 - width / 2 + y: volumeSlider.bottomPadding + volumeSlider.visualPosition * (volumeSlider.availableHeight - height) + width: sliderBackground.width * 7 + height: width + radius: height * 0.5 + color: defaultGreen + } + } + + Behavior on opacity { NumberAnimation { duration: 100 } } + Behavior on y { NumberAnimation { duration: 100 } } } } diff --git a/basicsuite/mediaplayer/images/FullscreenButton.png b/basicsuite/mediaplayer/images/FullscreenButton.png old mode 100755 new mode 100644 diff --git a/basicsuite/mediaplayer/images/PlaybackSlider.png b/basicsuite/mediaplayer/images/PlaybackSlider.png old mode 100755 new mode 100644 diff --git a/basicsuite/mediaplayer/images/SliderHandle.png b/basicsuite/mediaplayer/images/SliderHandle.png old mode 100755 new mode 100644 diff --git a/basicsuite/mediaplayer/images/SliderProgress.png b/basicsuite/mediaplayer/images/SliderProgress.png old mode 100755 new mode 100644 diff --git a/basicsuite/mediaplayer/images/VolumeDown.png b/basicsuite/mediaplayer/images/VolumeDown.png old mode 100755 new mode 100644 diff --git a/basicsuite/mediaplayer/images/VolumeUp.png b/basicsuite/mediaplayer/images/VolumeUp.png old mode 100755 new mode 100644 diff --git a/basicsuite/mediaplayer/images/back_icon.svg b/basicsuite/mediaplayer/images/back_icon.svg new file mode 100644 index 0000000..6034bd7 --- /dev/null +++ b/basicsuite/mediaplayer/images/back_icon.svg @@ -0,0 +1 @@ +back_icon \ No newline at end of file diff --git a/basicsuite/mediaplayer/images/bluetooth_icon.svg b/basicsuite/mediaplayer/images/bluetooth_icon.svg new file mode 100644 index 0000000..5dfaa97 --- /dev/null +++ b/basicsuite/mediaplayer/images/bluetooth_icon.svg @@ -0,0 +1 @@ +bluetooth_icon \ No newline at end of file diff --git a/basicsuite/mediaplayer/images/close_icon.svg b/basicsuite/mediaplayer/images/close_icon.svg new file mode 100644 index 0000000..c98fe51 --- /dev/null +++ b/basicsuite/mediaplayer/images/close_icon.svg @@ -0,0 +1 @@ +close_icon \ No newline at end of file diff --git a/basicsuite/mediaplayer/images/header_toggle_icon.svg b/basicsuite/mediaplayer/images/header_toggle_icon.svg new file mode 100644 index 0000000..06d0b6a --- /dev/null +++ b/basicsuite/mediaplayer/images/header_toggle_icon.svg @@ -0,0 +1 @@ +header_toggle_icon \ No newline at end of file diff --git a/basicsuite/mediaplayer/images/info_icon.svg b/basicsuite/mediaplayer/images/info_icon.svg new file mode 100644 index 0000000..64d24c0 --- /dev/null +++ b/basicsuite/mediaplayer/images/info_icon.svg @@ -0,0 +1 @@ +info_icon \ No newline at end of file diff --git a/basicsuite/mediaplayer/images/language_icon.svg b/basicsuite/mediaplayer/images/language_icon.svg new file mode 100644 index 0000000..f1235c5 --- /dev/null +++ b/basicsuite/mediaplayer/images/language_icon.svg @@ -0,0 +1 @@ +language_icon \ No newline at end of file diff --git a/basicsuite/mediaplayer/images/mute_icon.svg b/basicsuite/mediaplayer/images/mute_icon.svg new file mode 100644 index 0000000..2ffd61f --- /dev/null +++ b/basicsuite/mediaplayer/images/mute_icon.svg @@ -0,0 +1 @@ +mute_icon \ No newline at end of file diff --git a/basicsuite/mediaplayer/images/pause_icon.svg b/basicsuite/mediaplayer/images/pause_icon.svg new file mode 100644 index 0000000..04000f9 --- /dev/null +++ b/basicsuite/mediaplayer/images/pause_icon.svg @@ -0,0 +1 @@ +pause_icon \ No newline at end of file diff --git a/basicsuite/mediaplayer/images/play_icon.svg b/basicsuite/mediaplayer/images/play_icon.svg new file mode 100644 index 0000000..ab27771 --- /dev/null +++ b/basicsuite/mediaplayer/images/play_icon.svg @@ -0,0 +1 @@ +play_icon \ No newline at end of file diff --git a/basicsuite/mediaplayer/images/power_icon.svg b/basicsuite/mediaplayer/images/power_icon.svg new file mode 100644 index 0000000..b922c0e --- /dev/null +++ b/basicsuite/mediaplayer/images/power_icon.svg @@ -0,0 +1 @@ +power_icon \ No newline at end of file diff --git a/basicsuite/mediaplayer/images/qt-logo.png b/basicsuite/mediaplayer/images/qt-logo.png old mode 100755 new mode 100644 diff --git a/basicsuite/mediaplayer/images/settings_icon.svg b/basicsuite/mediaplayer/images/settings_icon.svg new file mode 100644 index 0000000..7f5dbde --- /dev/null +++ b/basicsuite/mediaplayer/images/settings_icon.svg @@ -0,0 +1 @@ +settings_icon \ No newline at end of file diff --git a/basicsuite/mediaplayer/images/settingsmenu_launcher_icon.svg b/basicsuite/mediaplayer/images/settingsmenu_launcher_icon.svg new file mode 100644 index 0000000..479a79f --- /dev/null +++ b/basicsuite/mediaplayer/images/settingsmenu_launcher_icon.svg @@ -0,0 +1 @@ +settingsmenu_launcher_icon \ No newline at end of file diff --git a/basicsuite/mediaplayer/images/stop_icon.svg b/basicsuite/mediaplayer/images/stop_icon.svg new file mode 100644 index 0000000..2eeff5f --- /dev/null +++ b/basicsuite/mediaplayer/images/stop_icon.svg @@ -0,0 +1 @@ +stop_icon \ No newline at end of file diff --git a/basicsuite/mediaplayer/images/titlebar.sci b/basicsuite/mediaplayer/images/titlebar.sci old mode 100755 new mode 100644 diff --git a/basicsuite/mediaplayer/images/volume_icon.svg b/basicsuite/mediaplayer/images/volume_icon.svg new file mode 100644 index 0000000..12f944e --- /dev/null +++ b/basicsuite/mediaplayer/images/volume_icon.svg @@ -0,0 +1 @@ +volume_icon \ No newline at end of file diff --git a/basicsuite/mediaplayer/main.qml b/basicsuite/mediaplayer/main.qml old mode 100755 new mode 100644 index d1667bf..5f3ff42 --- a/basicsuite/mediaplayer/main.qml +++ b/basicsuite/mediaplayer/main.qml @@ -50,11 +50,14 @@ import QtQuick 2.0 import QtMultimedia 5.0 +import QtDeviceUtilities.QtButtonImageProvider 1.0 FocusScope { id: applicationWindow focus: true + property real buttonHeight: height * 0.05 + MouseArea { id: mouseActivityMonitor anchors.fill: parent @@ -114,15 +117,11 @@ FocusScope { onOpenFX: { applicationWindow.openFX(); } - - onToggleFullScreen: { -// viewer.toggleFullscreen(); - } } ParameterPanel { id: parameterPanel - opacity: controlBar.opacity + opacity: controlBar.opacity * 0.9 visible: effectSelectionPanel.visible && model.count !== 0 height: 116 width: 500 @@ -137,11 +136,10 @@ FocusScope { EffectSelectionPanel { id: effectSelectionPanel visible: false - opacity: controlBar.opacity + opacity: controlBar.opacity * 0.9 anchors { bottom: controlBar.top right: controlBar.right - // rightMargin: 15 bottomMargin: 15 } width: 250 @@ -165,33 +163,17 @@ FocusScope { } } - Rectangle { + ImageButton{ + id: infoButton anchors.right: parent.right anchors.top: parent.top anchors.rightMargin: 32 anchors.topMargin: 32 width: 40 height: 40 - radius: width / 2 - color: infoMouser.pressed ? "#BB999999" : "#88444444" - antialiasing: true - visible: content.videoPlayer.mediaPlayer.status !== MediaPlayer.NoMedia && controlBar.state === "VISIBLE" - - Text { - anchors.centerIn: parent - text: "i" - font.italic: true - font.bold: true - color: "white" - font.pixelSize: 28 - } - - MouseArea { - id: infoMouser - anchors.fill: parent - anchors.margins: -10 - onClicked: metadataView.opacity = 1 - } + imageSource: "images/info_icon.svg" + onClicked: metadataView.opacity = 1 + visible: content.videoPlayer.mediaPlayer.status !== MediaPlayer.NoMedia && content.videoPlayer.mediaPlayer.status !== MediaPlayer.InvalidMedia } MetadataView { @@ -223,7 +205,6 @@ FocusScope { openFX(); return; } else if (event.key === Qt.Key_F && event.modifiers & Qt.ControlModifier) { -// viewer.toggleFullscreen(); return; } else if (event.key === Qt.Key_Up || event.key === Qt.Key_VolumeUp) { content.videoPlayer.mediaPlayer.volume = Math.min(1, content.videoPlayer.mediaPlayer.volume + 0.1); @@ -241,7 +222,6 @@ FocusScope { } return; } else if (applicationWindow.isFullScreen && event.key === Qt.Key_Escape) { -// viewer.toggleFullscreen(); return; } @@ -271,10 +251,6 @@ FocusScope { } function openVideo() { - //videoFileBrowser.show() - // var videoFile = viewer.openFileDialog(); - // if (videoFile != "") - // content.openVideo(videoFile); fileBrowser.show() } diff --git a/basicsuite/mediaplayer/mediaplayer.pro b/basicsuite/mediaplayer/mediaplayer.pro index 4667caf..ba174e3 100644 --- a/basicsuite/mediaplayer/mediaplayer.pro +++ b/basicsuite/mediaplayer/mediaplayer.pro @@ -16,7 +16,6 @@ content.files = \ ParameterPanel.qml \ PlaybackControl.qml \ SeekControl.qml \ - Slider.qml \ UrlBar.qml \ VolumeControl.qml \ Effects \ -- cgit v1.2.3 From 3fa57962a03fb540c92844f16e8cd12422486683 Mon Sep 17 00:00:00 2001 From: Juho Annunen Date: Thu, 19 Apr 2018 13:04:50 +0300 Subject: Replace existing controls demos with controls 2 gallery example Task-number: QTBUG-62805 Change-Id: If63369430adffa875b0e96a148a03ab908a1dea2 Reviewed-by: Teemu Holappa --- basicsuite/demos.xml | 8 + .../doc/images/qtquickcontrols2-gallery-drawer.png | Bin 0 -> 15785 bytes .../doc/images/qtquickcontrols2-gallery-menu.png | Bin 0 -> 16618 bytes .../images/qtquickcontrols2-gallery-welcome.png | Bin 0 -> 20138 bytes .../doc/src/qtquickcontrols2-gallery.qdoc | 61 ++++ basicsuite/qtquickcontrols2/gallery.cpp | 82 ++++++ basicsuite/qtquickcontrols2/gallery.pro | 18 ++ .../qtquickcontrols2/icons/gallery/20x20/back.png | Bin 0 -> 220 bytes .../icons/gallery/20x20/drawer.png | Bin 0 -> 123 bytes .../qtquickcontrols2/icons/gallery/20x20/menu.png | Bin 0 -> 123 bytes .../icons/gallery/20x20@2/back.png | Bin 0 -> 289 bytes .../icons/gallery/20x20@2/drawer.png | Bin 0 -> 126 bytes .../icons/gallery/20x20@2/menu.png | Bin 0 -> 158 bytes .../icons/gallery/20x20@3/back.png | Bin 0 -> 351 bytes .../icons/gallery/20x20@3/drawer.png | Bin 0 -> 130 bytes .../icons/gallery/20x20@3/menu.png | Bin 0 -> 193 bytes .../icons/gallery/20x20@4/back.png | Bin 0 -> 452 bytes .../icons/gallery/20x20@4/drawer.png | Bin 0 -> 131 bytes .../icons/gallery/20x20@4/menu.png | Bin 0 -> 223 bytes .../qtquickcontrols2/icons/gallery/index.theme | 24 ++ basicsuite/qtquickcontrols2/images/arrow.png | Bin 0 -> 3060 bytes basicsuite/qtquickcontrols2/images/arrow@2x.png | Bin 0 -> 3240 bytes basicsuite/qtquickcontrols2/images/arrow@3x.png | Bin 0 -> 3370 bytes basicsuite/qtquickcontrols2/images/arrow@4x.png | Bin 0 -> 3615 bytes basicsuite/qtquickcontrols2/images/arrows.png | Bin 0 -> 768 bytes basicsuite/qtquickcontrols2/images/arrows@2x.png | Bin 0 -> 1290 bytes basicsuite/qtquickcontrols2/images/arrows@3x.png | Bin 0 -> 1883 bytes basicsuite/qtquickcontrols2/images/arrows@4x.png | Bin 0 -> 2765 bytes basicsuite/qtquickcontrols2/images/qt-logo.png | Bin 0 -> 2695 bytes basicsuite/qtquickcontrols2/images/qt-logo@2x.png | Bin 0 -> 5521 bytes basicsuite/qtquickcontrols2/images/qt-logo@3x.png | Bin 0 -> 8166 bytes basicsuite/qtquickcontrols2/images/qt-logo@4x.png | Bin 0 -> 11600 bytes basicsuite/qtquickcontrols2/main.qml | 315 +++++++++++++++++++++ .../qtquickcontrols2/pages/BusyIndicatorPage.qml | 73 +++++ basicsuite/qtquickcontrols2/pages/ButtonPage.qml | 91 ++++++ basicsuite/qtquickcontrols2/pages/CheckBoxPage.qml | 87 ++++++ basicsuite/qtquickcontrols2/pages/ComboBoxPage.qml | 97 +++++++ .../qtquickcontrols2/pages/DelayButtonPage.qml | 74 +++++ basicsuite/qtquickcontrols2/pages/DelegatePage.qml | 218 ++++++++++++++ basicsuite/qtquickcontrols2/pages/DialPage.qml | 74 +++++ basicsuite/qtquickcontrols2/pages/DialogPage.qml | 226 +++++++++++++++ basicsuite/qtquickcontrols2/pages/FramePage.qml | 94 ++++++ basicsuite/qtquickcontrols2/pages/GroupBoxPage.qml | 95 +++++++ .../qtquickcontrols2/pages/PageIndicatorPage.qml | 74 +++++ .../qtquickcontrols2/pages/ProgressBarPage.qml | 80 ++++++ .../qtquickcontrols2/pages/RadioButtonPage.qml | 86 ++++++ .../qtquickcontrols2/pages/RangeSliderPage.qml | 82 ++++++ .../qtquickcontrols2/pages/ScrollBarPage.qml | 87 ++++++ .../qtquickcontrols2/pages/ScrollIndicatorPage.qml | 87 ++++++ .../qtquickcontrols2/pages/ScrollablePage.qml | 71 +++++ basicsuite/qtquickcontrols2/pages/SliderPage.qml | 80 ++++++ basicsuite/qtquickcontrols2/pages/SpinBoxPage.qml | 76 +++++ .../qtquickcontrols2/pages/StackViewPage.qml | 96 +++++++ .../qtquickcontrols2/pages/SwipeViewPage.qml | 96 +++++++ basicsuite/qtquickcontrols2/pages/SwitchPage.qml | 86 ++++++ basicsuite/qtquickcontrols2/pages/TabBarPage.qml | 104 +++++++ basicsuite/qtquickcontrols2/pages/TextAreaPage.qml | 76 +++++ .../qtquickcontrols2/pages/TextFieldPage.qml | 74 +++++ basicsuite/qtquickcontrols2/pages/ToolTipPage.qml | 77 +++++ basicsuite/qtquickcontrols2/pages/TumblerPage.qml | 73 +++++ basicsuite/qtquickcontrols2/preview_l.jpg | Bin 0 -> 51411 bytes basicsuite/qtquickcontrols2/qtquickcontrols2.conf | 8 + basicsuite/shared/main.cpp | 12 +- basicsuite/shared/shared.pri | 2 +- 64 files changed, 3062 insertions(+), 2 deletions(-) create mode 100644 basicsuite/qtquickcontrols2/doc/images/qtquickcontrols2-gallery-drawer.png create mode 100644 basicsuite/qtquickcontrols2/doc/images/qtquickcontrols2-gallery-menu.png create mode 100644 basicsuite/qtquickcontrols2/doc/images/qtquickcontrols2-gallery-welcome.png create mode 100644 basicsuite/qtquickcontrols2/doc/src/qtquickcontrols2-gallery.qdoc create mode 100644 basicsuite/qtquickcontrols2/gallery.cpp create mode 100644 basicsuite/qtquickcontrols2/gallery.pro create mode 100644 basicsuite/qtquickcontrols2/icons/gallery/20x20/back.png create mode 100644 basicsuite/qtquickcontrols2/icons/gallery/20x20/drawer.png create mode 100644 basicsuite/qtquickcontrols2/icons/gallery/20x20/menu.png create mode 100644 basicsuite/qtquickcontrols2/icons/gallery/20x20@2/back.png create mode 100644 basicsuite/qtquickcontrols2/icons/gallery/20x20@2/drawer.png create mode 100644 basicsuite/qtquickcontrols2/icons/gallery/20x20@2/menu.png create mode 100644 basicsuite/qtquickcontrols2/icons/gallery/20x20@3/back.png create mode 100644 basicsuite/qtquickcontrols2/icons/gallery/20x20@3/drawer.png create mode 100644 basicsuite/qtquickcontrols2/icons/gallery/20x20@3/menu.png create mode 100644 basicsuite/qtquickcontrols2/icons/gallery/20x20@4/back.png create mode 100644 basicsuite/qtquickcontrols2/icons/gallery/20x20@4/drawer.png create mode 100644 basicsuite/qtquickcontrols2/icons/gallery/20x20@4/menu.png create mode 100644 basicsuite/qtquickcontrols2/icons/gallery/index.theme create mode 100644 basicsuite/qtquickcontrols2/images/arrow.png create mode 100644 basicsuite/qtquickcontrols2/images/arrow@2x.png create mode 100644 basicsuite/qtquickcontrols2/images/arrow@3x.png create mode 100644 basicsuite/qtquickcontrols2/images/arrow@4x.png create mode 100644 basicsuite/qtquickcontrols2/images/arrows.png create mode 100644 basicsuite/qtquickcontrols2/images/arrows@2x.png create mode 100644 basicsuite/qtquickcontrols2/images/arrows@3x.png create mode 100644 basicsuite/qtquickcontrols2/images/arrows@4x.png create mode 100644 basicsuite/qtquickcontrols2/images/qt-logo.png create mode 100644 basicsuite/qtquickcontrols2/images/qt-logo@2x.png create mode 100644 basicsuite/qtquickcontrols2/images/qt-logo@3x.png create mode 100644 basicsuite/qtquickcontrols2/images/qt-logo@4x.png create mode 100644 basicsuite/qtquickcontrols2/main.qml create mode 100644 basicsuite/qtquickcontrols2/pages/BusyIndicatorPage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/ButtonPage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/CheckBoxPage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/ComboBoxPage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/DelayButtonPage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/DelegatePage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/DialPage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/DialogPage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/FramePage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/GroupBoxPage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/PageIndicatorPage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/ProgressBarPage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/RadioButtonPage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/RangeSliderPage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/ScrollBarPage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/ScrollIndicatorPage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/ScrollablePage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/SliderPage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/SpinBoxPage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/StackViewPage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/SwipeViewPage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/SwitchPage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/TabBarPage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/TextAreaPage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/TextFieldPage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/ToolTipPage.qml create mode 100644 basicsuite/qtquickcontrols2/pages/TumblerPage.qml create mode 100644 basicsuite/qtquickcontrols2/preview_l.jpg create mode 100644 basicsuite/qtquickcontrols2/qtquickcontrols2.conf diff --git a/basicsuite/demos.xml b/basicsuite/demos.xml index e6c2cbe..e979a4d 100644 --- a/basicsuite/demos.xml +++ b/basicsuite/demos.xml @@ -93,4 +93,12 @@ Qt for Device Creation comes with Qt Virtual Keyboard - a framework that consist + + +The gallery example is a simple application with a drawer menu that contains all the Qt Quick Controls 2. + +Each menu item opens a page that shows the graphical appearance of a control, allows you to interact with the control, and explains in which circumstances it is handy to use this control. + + + diff --git a/basicsuite/qtquickcontrols2/doc/images/qtquickcontrols2-gallery-drawer.png b/basicsuite/qtquickcontrols2/doc/images/qtquickcontrols2-gallery-drawer.png new file mode 100644 index 0000000..9109fdd Binary files /dev/null and b/basicsuite/qtquickcontrols2/doc/images/qtquickcontrols2-gallery-drawer.png differ diff --git a/basicsuite/qtquickcontrols2/doc/images/qtquickcontrols2-gallery-menu.png b/basicsuite/qtquickcontrols2/doc/images/qtquickcontrols2-gallery-menu.png new file mode 100644 index 0000000..3cbfbe6 Binary files /dev/null and b/basicsuite/qtquickcontrols2/doc/images/qtquickcontrols2-gallery-menu.png differ diff --git a/basicsuite/qtquickcontrols2/doc/images/qtquickcontrols2-gallery-welcome.png b/basicsuite/qtquickcontrols2/doc/images/qtquickcontrols2-gallery-welcome.png new file mode 100644 index 0000000..e69e7e4 Binary files /dev/null and b/basicsuite/qtquickcontrols2/doc/images/qtquickcontrols2-gallery-welcome.png differ diff --git a/basicsuite/qtquickcontrols2/doc/src/qtquickcontrols2-gallery.qdoc b/basicsuite/qtquickcontrols2/doc/src/qtquickcontrols2-gallery.qdoc new file mode 100644 index 0000000..b96ba28 --- /dev/null +++ b/basicsuite/qtquickcontrols2/doc/src/qtquickcontrols2-gallery.qdoc @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example gallery + \title Qt Quick Controls 2 - Gallery + \ingroup qtquickcontrols2-examples + \brief A gallery of controls. + + \raw HTML +
+ +
+ \endraw + \image qtquickcontrols2-gallery-welcome.png + \caption Welcome Screen + \raw HTML + + \endraw + \image qtquickcontrols2-gallery-drawer.png + \caption Side Drawer + \raw HTML + + \endraw + \image qtquickcontrols2-gallery-menu.png + \caption Options Menu + \raw HTML +
+ \endraw + + The gallery example is a simple application with a drawer menu that contains + all the \l {Qt Quick Controls 2}. Each menu item opens a page that shows the + graphical appearance of a control, allows you to interact with the control, + and explains in which circumstances it is handy to use this control. + + \include examples-run.qdocinc +*/ diff --git a/basicsuite/qtquickcontrols2/gallery.cpp b/basicsuite/qtquickcontrols2/gallery.cpp new file mode 100644 index 0000000..04b988a --- /dev/null +++ b/basicsuite/qtquickcontrols2/gallery.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication::setApplicationName("Gallery"); + QGuiApplication::setOrganizationName("QtProject"); + QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + + QGuiApplication app(argc, argv); + + QIcon::setThemeName("gallery"); + + QSettings settings; + QString style = QQuickStyle::name(); + if (!style.isEmpty()) + settings.setValue("style", style); + else + QQuickStyle::setStyle(settings.value("style").toString()); + + QQmlApplicationEngine engine; + engine.rootContext()->setContextProperty("availableStyles", QQuickStyle::availableStyles()); + engine.load(QUrl("qrc:/main.qml")); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/basicsuite/qtquickcontrols2/gallery.pro b/basicsuite/qtquickcontrols2/gallery.pro new file mode 100644 index 0000000..9834b89 --- /dev/null +++ b/basicsuite/qtquickcontrols2/gallery.pro @@ -0,0 +1,18 @@ +TARGET = gallery + +include(../shared/shared.pri) +b2qtdemo_deploy_defaults() + +content.files = \ + main.qml \ + qtquickcontrols2.conf \ + icons/gallery/index.theme \ + $$files(icons/*.png, true) \ + $$files(images/*.png) \ + $$files(pages/*.qml) + +content.path = $$DESTPATH + +OTHER_FILES += $${content.files} + +INSTALLS += target content diff --git a/basicsuite/qtquickcontrols2/icons/gallery/20x20/back.png b/basicsuite/qtquickcontrols2/icons/gallery/20x20/back.png new file mode 100644 index 0000000..db43e27 Binary files /dev/null and b/basicsuite/qtquickcontrols2/icons/gallery/20x20/back.png differ diff --git a/basicsuite/qtquickcontrols2/icons/gallery/20x20/drawer.png b/basicsuite/qtquickcontrols2/icons/gallery/20x20/drawer.png new file mode 100644 index 0000000..1e974ef Binary files /dev/null and b/basicsuite/qtquickcontrols2/icons/gallery/20x20/drawer.png differ diff --git a/basicsuite/qtquickcontrols2/icons/gallery/20x20/menu.png b/basicsuite/qtquickcontrols2/icons/gallery/20x20/menu.png new file mode 100644 index 0000000..a10473d Binary files /dev/null and b/basicsuite/qtquickcontrols2/icons/gallery/20x20/menu.png differ diff --git a/basicsuite/qtquickcontrols2/icons/gallery/20x20@2/back.png b/basicsuite/qtquickcontrols2/icons/gallery/20x20@2/back.png new file mode 100644 index 0000000..c55ab31 Binary files /dev/null and b/basicsuite/qtquickcontrols2/icons/gallery/20x20@2/back.png differ diff --git a/basicsuite/qtquickcontrols2/icons/gallery/20x20@2/drawer.png b/basicsuite/qtquickcontrols2/icons/gallery/20x20@2/drawer.png new file mode 100644 index 0000000..eba3b6c Binary files /dev/null and b/basicsuite/qtquickcontrols2/icons/gallery/20x20@2/drawer.png differ diff --git a/basicsuite/qtquickcontrols2/icons/gallery/20x20@2/menu.png b/basicsuite/qtquickcontrols2/icons/gallery/20x20@2/menu.png new file mode 100644 index 0000000..649c2a0 Binary files /dev/null and b/basicsuite/qtquickcontrols2/icons/gallery/20x20@2/menu.png differ diff --git a/basicsuite/qtquickcontrols2/icons/gallery/20x20@3/back.png b/basicsuite/qtquickcontrols2/icons/gallery/20x20@3/back.png new file mode 100644 index 0000000..b228eb8 Binary files /dev/null and b/basicsuite/qtquickcontrols2/icons/gallery/20x20@3/back.png differ diff --git a/basicsuite/qtquickcontrols2/icons/gallery/20x20@3/drawer.png b/basicsuite/qtquickcontrols2/icons/gallery/20x20@3/drawer.png new file mode 100644 index 0000000..3584ed6 Binary files /dev/null and b/basicsuite/qtquickcontrols2/icons/gallery/20x20@3/drawer.png differ diff --git a/basicsuite/qtquickcontrols2/icons/gallery/20x20@3/menu.png b/basicsuite/qtquickcontrols2/icons/gallery/20x20@3/menu.png new file mode 100644 index 0000000..9554b69 Binary files /dev/null and b/basicsuite/qtquickcontrols2/icons/gallery/20x20@3/menu.png differ diff --git a/basicsuite/qtquickcontrols2/icons/gallery/20x20@4/back.png b/basicsuite/qtquickcontrols2/icons/gallery/20x20@4/back.png new file mode 100644 index 0000000..dd157e7 Binary files /dev/null and b/basicsuite/qtquickcontrols2/icons/gallery/20x20@4/back.png differ diff --git a/basicsuite/qtquickcontrols2/icons/gallery/20x20@4/drawer.png b/basicsuite/qtquickcontrols2/icons/gallery/20x20@4/drawer.png new file mode 100644 index 0000000..60d93af Binary files /dev/null and b/basicsuite/qtquickcontrols2/icons/gallery/20x20@4/drawer.png differ diff --git a/basicsuite/qtquickcontrols2/icons/gallery/20x20@4/menu.png b/basicsuite/qtquickcontrols2/icons/gallery/20x20@4/menu.png new file mode 100644 index 0000000..187c171 Binary files /dev/null and b/basicsuite/qtquickcontrols2/icons/gallery/20x20@4/menu.png differ diff --git a/basicsuite/qtquickcontrols2/icons/gallery/index.theme b/basicsuite/qtquickcontrols2/icons/gallery/index.theme new file mode 100644 index 0000000..a1bcd5e --- /dev/null +++ b/basicsuite/qtquickcontrols2/icons/gallery/index.theme @@ -0,0 +1,24 @@ +[Icon Theme] +Name=Gallery +Comment=Qt Quick Controls 2 Gallery Example Icon Theme + +Directories=20x20,20x20@2,20x20@3,20x20@4 + +[20x20] +Size=20 +Type=Fixed + +[20x20@2] +Size=20 +Scale=2 +Type=Fixed + +[20x20@3] +Size=20 +Scale=3 +Type=Fixed + +[20x20@4] +Size=20 +Scale=4 +Type=Fixed diff --git a/basicsuite/qtquickcontrols2/images/arrow.png b/basicsuite/qtquickcontrols2/images/arrow.png new file mode 100644 index 0000000..d81accb Binary files /dev/null and b/basicsuite/qtquickcontrols2/images/arrow.png differ diff --git a/basicsuite/qtquickcontrols2/images/arrow@2x.png b/basicsuite/qtquickcontrols2/images/arrow@2x.png new file mode 100644 index 0000000..309c018 Binary files /dev/null and b/basicsuite/qtquickcontrols2/images/arrow@2x.png differ diff --git a/basicsuite/qtquickcontrols2/images/arrow@3x.png b/basicsuite/qtquickcontrols2/images/arrow@3x.png new file mode 100644 index 0000000..e146ecc Binary files /dev/null and b/basicsuite/qtquickcontrols2/images/arrow@3x.png differ diff --git a/basicsuite/qtquickcontrols2/images/arrow@4x.png b/basicsuite/qtquickcontrols2/images/arrow@4x.png new file mode 100644 index 0000000..b2ad27f Binary files /dev/null and b/basicsuite/qtquickcontrols2/images/arrow@4x.png differ diff --git a/basicsuite/qtquickcontrols2/images/arrows.png b/basicsuite/qtquickcontrols2/images/arrows.png new file mode 100644 index 0000000..d38b94a Binary files /dev/null and b/basicsuite/qtquickcontrols2/images/arrows.png differ diff --git a/basicsuite/qtquickcontrols2/images/arrows@2x.png b/basicsuite/qtquickcontrols2/images/arrows@2x.png new file mode 100644 index 0000000..69b9342 Binary files /dev/null and b/basicsuite/qtquickcontrols2/images/arrows@2x.png differ diff --git a/basicsuite/qtquickcontrols2/images/arrows@3x.png b/basicsuite/qtquickcontrols2/images/arrows@3x.png new file mode 100644 index 0000000..7703252 Binary files /dev/null and b/basicsuite/qtquickcontrols2/images/arrows@3x.png differ diff --git a/basicsuite/qtquickcontrols2/images/arrows@4x.png b/basicsuite/qtquickcontrols2/images/arrows@4x.png new file mode 100644 index 0000000..66c1fac Binary files /dev/null and b/basicsuite/qtquickcontrols2/images/arrows@4x.png differ diff --git a/basicsuite/qtquickcontrols2/images/qt-logo.png b/basicsuite/qtquickcontrols2/images/qt-logo.png new file mode 100644 index 0000000..90e6f90 Binary files /dev/null and b/basicsuite/qtquickcontrols2/images/qt-logo.png differ diff --git a/basicsuite/qtquickcontrols2/images/qt-logo@2x.png b/basicsuite/qtquickcontrols2/images/qt-logo@2x.png new file mode 100644 index 0000000..22d111a Binary files /dev/null and b/basicsuite/qtquickcontrols2/images/qt-logo@2x.png differ diff --git a/basicsuite/qtquickcontrols2/images/qt-logo@3x.png b/basicsuite/qtquickcontrols2/images/qt-logo@3x.png new file mode 100644 index 0000000..627746c Binary files /dev/null and b/basicsuite/qtquickcontrols2/images/qt-logo@3x.png differ diff --git a/basicsuite/qtquickcontrols2/images/qt-logo@4x.png b/basicsuite/qtquickcontrols2/images/qt-logo@4x.png new file mode 100644 index 0000000..dc62286 Binary files /dev/null and b/basicsuite/qtquickcontrols2/images/qt-logo@4x.png differ diff --git a/basicsuite/qtquickcontrols2/main.qml b/basicsuite/qtquickcontrols2/main.qml new file mode 100644 index 0000000..cf9522b --- /dev/null +++ b/basicsuite/qtquickcontrols2/main.qml @@ -0,0 +1,315 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.9 +import QtQuick.Layouts 1.3 +import QtQuick.Controls 2.3 +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Universal 2.1 +import Qt.labs.settings 1.0 + +Page { + id: window + width: 360 + height: 520 + visible: true + + Settings { + id: settings + property string style: "Default" + } + + Shortcut { + sequences: ["Esc", "Back"] + enabled: stackView.depth > 1 + onActivated: { + stackView.pop() + listView.currentIndex = -1 + } + } + + Shortcut { + sequence: "Menu" + onActivated: optionsMenu.open() + } + + header: ToolBar { + Material.foreground: "white" + + RowLayout { + spacing: 20 + anchors.fill: parent + + ToolButton { + icon.source: stackView.depth > 1 ? "back.png" : "drawer.png" + onClicked: { + if (stackView.depth > 1) { + stackView.pop() + listView.currentIndex = -1 + } else { + drawer.open() + } + } + } + + Label { + id: titleLabel + text: listView.currentItem ? listView.currentItem.text : "Gallery" + font.pixelSize: 20 + elide: Label.ElideRight + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + Layout.fillWidth: true + } + + ToolButton { + icon.source: "menu.png" + onClicked: optionsMenu.open() + + Menu { + id: optionsMenu + x: parent.width - width + transformOrigin: Menu.TopRight + + MenuItem { + text: "Settings" + onTriggered: settingsDialog.open() + } + MenuItem { + text: "About" + onTriggered: aboutDialog.open() + } + } + } + } + } + + Drawer { + id: drawer + width: Math.min(window.width, window.height) / 3 * 2 + height: window.height + interactive: stackView.depth === 1 + + ListView { + id: listView + + focus: true + currentIndex: -1 + anchors.fill: parent + + delegate: ItemDelegate { + width: parent.width + text: model.title + highlighted: ListView.isCurrentItem + onClicked: { + listView.currentIndex = index + stackView.push(model.source) + drawer.close() + } + } + + model: ListModel { + ListElement { title: "BusyIndicator"; source: "BusyIndicatorPage.qml" } + ListElement { title: "Button"; source: "ButtonPage.qml" } + ListElement { title: "CheckBox"; source: "CheckBoxPage.qml" } + ListElement { title: "ComboBox"; source: "ComboBoxPage.qml" } + ListElement { title: "DelayButton"; source: "DelayButtonPage.qml" } + ListElement { title: "Dial"; source: "DialPage.qml" } + ListElement { title: "Dialog"; source: "DialogPage.qml" } + ListElement { title: "Delegates"; source: "DelegatePage.qml" } + ListElement { title: "Frame"; source: "FramePage.qml" } + ListElement { title: "GroupBox"; source: "GroupBoxPage.qml" } + ListElement { title: "PageIndicator"; source: "PageIndicatorPage.qml" } + ListElement { title: "ProgressBar"; source: "ProgressBarPage.qml" } + ListElement { title: "RadioButton"; source: "RadioButtonPage.qml" } + ListElement { title: "RangeSlider"; source: "RangeSliderPage.qml" } + ListElement { title: "ScrollBar"; source: "ScrollBarPage.qml" } + ListElement { title: "ScrollIndicator"; source: "ScrollIndicatorPage.qml" } + ListElement { title: "Slider"; source: "SliderPage.qml" } + ListElement { title: "SpinBox"; source: "SpinBoxPage.qml" } + ListElement { title: "StackView"; source: "StackViewPage.qml" } + ListElement { title: "SwipeView"; source: "SwipeViewPage.qml" } + ListElement { title: "Switch"; source: "SwitchPage.qml" } + ListElement { title: "TabBar"; source: "TabBarPage.qml" } + ListElement { title: "TextArea"; source: "TextAreaPage.qml" } + ListElement { title: "TextField"; source: "TextFieldPage.qml" } + ListElement { title: "ToolTip"; source: "ToolTipPage.qml" } + ListElement { title: "Tumbler"; source: "TumblerPage.qml" } + } + + ScrollIndicator.vertical: ScrollIndicator { } + } + } + + StackView { + id: stackView + anchors.fill: parent + + initialItem: Pane { + id: pane + + Image { + id: logo + width: pane.availableWidth / 2 + height: pane.availableHeight / 2 + anchors.centerIn: parent + anchors.verticalCenterOffset: -50 + fillMode: Image.PreserveAspectFit + source: "qt-logo.png" + } + + Label { + text: "Qt Quick Controls 2 provides a set of controls that can be used to build complete interfaces in Qt Quick." + anchors.margins: 20 + anchors.top: logo.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: arrow.top + horizontalAlignment: Label.AlignHCenter + verticalAlignment: Label.AlignVCenter + wrapMode: Label.Wrap + } + + Image { + id: arrow + source: "arrow.png" + anchors.left: parent.left + anchors.bottom: parent.bottom + } + } + } + + Dialog { + id: settingsDialog + x: Math.round((window.width - width) / 2) + y: Math.round(window.height / 6) + width: Math.round(Math.min(window.width, window.height) / 3 * 2) + modal: true + focus: true + title: "Settings" + + standardButtons: Dialog.Ok | Dialog.Cancel + onAccepted: { + settings.style = styleBox.displayText + settingsDialog.close() + } + onRejected: { + styleBox.currentIndex = styleBox.styleIndex + settingsDialog.close() + } + + contentItem: ColumnLayout { + id: settingsColumn + spacing: 20 + + RowLayout { + spacing: 10 + + Label { + text: "Style:" + } + + ComboBox { + id: styleBox + property int styleIndex: -1 + model: availableStyles + Component.onCompleted: { + styleIndex = find(settings.style, Qt.MatchFixedString) + if (styleIndex !== -1) + currentIndex = styleIndex + } + Layout.fillWidth: true + } + } + + Label { + text: "Restart required" + color: "#e41e25" + opacity: styleBox.currentIndex !== styleBox.styleIndex ? 1.0 : 0.0 + horizontalAlignment: Label.AlignHCenter + verticalAlignment: Label.AlignVCenter + Layout.fillWidth: true + Layout.fillHeight: true + } + } + } + + Dialog { + id: aboutDialog + modal: true + focus: true + title: "About" + x: (window.width - width) / 2 + y: window.height / 6 + width: Math.min(window.width, window.height) / 3 * 2 + contentHeight: aboutColumn.height + + Column { + id: aboutColumn + spacing: 20 + + Label { + width: aboutDialog.availableWidth + text: "The Qt Quick Controls 2 module delivers the next generation user interface controls based on Qt Quick." + wrapMode: Label.Wrap + font.pixelSize: 12 + } + + Label { + width: aboutDialog.availableWidth + text: "In comparison to the desktop-oriented Qt Quick Controls 1, Qt Quick Controls 2 " + + "are an order of magnitude simpler, lighter and faster, and are primarily targeted " + + "towards embedded and mobile platforms." + wrapMode: Label.Wrap + font.pixelSize: 12 + } + } + } +} diff --git a/basicsuite/qtquickcontrols2/pages/BusyIndicatorPage.qml b/basicsuite/qtquickcontrols2/pages/BusyIndicatorPage.qml new file mode 100644 index 0000000..3fbae0c --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/BusyIndicatorPage.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Controls 2.1 + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "BusyIndicator is used to indicate activity while content is being loaded," + + " or when the UI is blocked waiting for a resource to become available." + } + + BusyIndicator { + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/basicsuite/qtquickcontrols2/pages/ButtonPage.qml b/basicsuite/qtquickcontrols2/pages/ButtonPage.qml new file mode 100644 index 0000000..7ebceb4 --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/ButtonPage.qml @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Layouts 1.0 +import QtQuick.Controls 2.1 + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "Button presents a push-button that can be pushed or clicked by the user. " + + "Buttons are normally used to perform an action, or to answer a question." + } + + ColumnLayout { + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + + Button { + text: "First" + Layout.fillWidth: true + } + Button { + id: button + text: "Second" + highlighted: true + Layout.fillWidth: true + } + Button { + text: "Third" + enabled: false + Layout.fillWidth: true + } + } + } +} diff --git a/basicsuite/qtquickcontrols2/pages/CheckBoxPage.qml b/basicsuite/qtquickcontrols2/pages/CheckBoxPage.qml new file mode 100644 index 0000000..a8a1692 --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/CheckBoxPage.qml @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Controls 2.1 + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "CheckBox presents an option button that can be toggled on or off. " + + "Check boxes are typically used to select one or more options from a set of options." + } + + Column { + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + + CheckBox { + text: "First" + checked: true + } + CheckBox { + text: "Second" + } + CheckBox { + text: "Third" + checked: true + enabled: false + } + } + } +} diff --git a/basicsuite/qtquickcontrols2/pages/ComboBoxPage.qml b/basicsuite/qtquickcontrols2/pages/ComboBoxPage.qml new file mode 100644 index 0000000..bc89e99 --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/ComboBoxPage.qml @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Controls 2.2 + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "ComboBox is a combined button and popup list. It presents " + + "a list of options to the user that occupies minimal screen space." + } + + ComboBox { + model: ["First", "Second", "Third"] + anchors.horizontalCenter: parent.horizontalCenter + } + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "ComboBox can be made \l editable. An editable combo box auto-" + + "completes its text based on what is available in the model." + } + + ComboBox { + editable: true + model: ListModel { + id: model + ListElement { text: "Banana" } + ListElement { text: "Apple" } + ListElement { text: "Coconut" } + } + onAccepted: { + if (find(editText) === -1) + model.append({text: editText}) + } + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/basicsuite/qtquickcontrols2/pages/DelayButtonPage.qml b/basicsuite/qtquickcontrols2/pages/DelayButtonPage.qml new file mode 100644 index 0000000..974dcab --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/DelayButtonPage.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Controls 2.2 + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "DelayButton is a checkable button that incorporates a delay before the " + + "button is activated. This delay prevents accidental presses." + } + + DelayButton { + text: "DelayButton" + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/basicsuite/qtquickcontrols2/pages/DelegatePage.qml b/basicsuite/qtquickcontrols2/pages/DelegatePage.qml new file mode 100644 index 0000000..bf07e1b --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/DelegatePage.qml @@ -0,0 +1,218 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 2.1 + +Pane { + padding: 0 + + property var delegateComponentMap: { + "ItemDelegate": itemDelegateComponent, + "SwipeDelegate": swipeDelegateComponent, + "CheckDelegate": checkDelegateComponent, + "RadioDelegate": radioDelegateComponent, + "SwitchDelegate": switchDelegateComponent + } + + Component { + id: itemDelegateComponent + + ItemDelegate { + text: labelText + width: parent.width + } + } + + Component { + id: swipeDelegateComponent + + SwipeDelegate { + id: swipeDelegate + text: labelText + width: parent.width + + Component { + id: removeComponent + + Rectangle { + color: SwipeDelegate.pressed ? "#333" : "#444" + width: parent.width + height: parent.height + clip: true + + SwipeDelegate.onClicked: view.model.remove(ourIndex) + + Label { + font.pixelSize: swipeDelegate.font.pixelSize + text: "Remove" + color: "white" + anchors.centerIn: parent + } + } + } + + swipe.left: removeComponent + swipe.right: removeComponent + } + } + + Component { + id: checkDelegateComponent + + CheckDelegate { + text: labelText + width: parent.width + } + } + + ButtonGroup { + id: radioButtonGroup + } + + Component { + id: radioDelegateComponent + + RadioDelegate { + text: labelText + ButtonGroup.group: radioButtonGroup + } + } + + Component { + id: switchDelegateComponent + + SwitchDelegate { + text: labelText + } + } + + ColumnLayout { + id: column + spacing: 40 + anchors.fill: parent + anchors.topMargin: 20 + + Label { + Layout.fillWidth: true + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "Delegate controls are used as delegates in views such as ListView." + } + + ListView { + id: listView + Layout.fillWidth: true + Layout.fillHeight: true + clip: true + model: ListModel { + ListElement { type: "ItemDelegate"; text: "ItemDelegate" } + ListElement { type: "ItemDelegate"; text: "ItemDelegate" } + ListElement { type: "ItemDelegate"; text: "ItemDelegate" } + ListElement { type: "SwipeDelegate"; text: "SwipeDelegate" } + ListElement { type: "SwipeDelegate"; text: "SwipeDelegate" } + ListElement { type: "SwipeDelegate"; text: "SwipeDelegate" } + ListElement { type: "CheckDelegate"; text: "CheckDelegate" } + ListElement { type: "CheckDelegate"; text: "CheckDelegate" } + ListElement { type: "CheckDelegate"; text: "CheckDelegate" } + ListElement { type: "RadioDelegate"; text: "RadioDelegate" } + ListElement { type: "RadioDelegate"; text: "RadioDelegate" } + ListElement { type: "RadioDelegate"; text: "RadioDelegate" } + ListElement { type: "SwitchDelegate"; text: "SwitchDelegate" } + ListElement { type: "SwitchDelegate"; text: "SwitchDelegate" } + ListElement { type: "SwitchDelegate"; text: "SwitchDelegate" } + } + + section.property: "type" + section.delegate: Pane { + width: listView.width + height: sectionLabel.implicitHeight + 20 + + Label { + id: sectionLabel + text: section + anchors.centerIn: parent + } + } + + delegate: Loader { + id: delegateLoader + width: listView.width + sourceComponent: delegateComponentMap[text] + + property string labelText: text + property ListView view: listView + property int ourIndex: index + + // Can't find a way to do this in the SwipeDelegate component itself, + // so do it here instead. + ListView.onRemove: SequentialAnimation { + PropertyAction { + target: delegateLoader + property: "ListView.delayRemove" + value: true + } + NumberAnimation { + target: item + property: "height" + to: 0 + easing.type: Easing.InOutQuad + } + PropertyAction { + target: delegateLoader + property: "ListView.delayRemove" + value: false + } + } + } + } + } +} diff --git a/basicsuite/qtquickcontrols2/pages/DialPage.qml b/basicsuite/qtquickcontrols2/pages/DialPage.qml new file mode 100644 index 0000000..a8fa976 --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/DialPage.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Controls 2.1 + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "The Dial is similar to a traditional dial knob that is found on devices such as " + + "stereos or industrial equipment. It allows the user to specify a value within a range." + } + + Dial { + value: 0.5 + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/basicsuite/qtquickcontrols2/pages/DialogPage.qml b/basicsuite/qtquickcontrols2/pages/DialogPage.qml new file mode 100644 index 0000000..6458bf1 --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/DialogPage.qml @@ -0,0 +1,226 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Layouts 1.0 +import QtQuick.Controls 2.3 + +ScrollablePage { + id: page + + readonly property int buttonWidth: Math.max(button.implicitWidth, Math.min(button.implicitWidth * 2, page.availableWidth / 3)) + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "Dialog is a popup that is mostly used for short-term tasks " + + "and brief communications with the user." + } + + Button { + text: "Message" + anchors.horizontalCenter: parent.horizontalCenter + width: buttonWidth + onClicked: messageDialog.open() + + Dialog { + id: messageDialog + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + + title: "Message" + + Label { + text: "Lorem ipsum dolor sit amet..." + } + } + } + + Button { + id: button + text: "Confirmation" + anchors.horizontalCenter: parent.horizontalCenter + width: buttonWidth + onClicked: confirmationDialog.open() + + Dialog { + id: confirmationDialog + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + parent: Overlay.overlay + + modal: true + title: "Confirmation" + standardButtons: Dialog.Yes | Dialog.No + + Column { + spacing: 20 + anchors.fill: parent + Label { + text: "The document has been modified.\nDo you want to save your changes?" + } + CheckBox { + text: "Do not ask again" + anchors.right: parent.right + } + } + } + } + + Button { + text: "Content" + anchors.horizontalCenter: parent.horizontalCenter + width: buttonWidth + onClicked: contentDialog.open() + + Dialog { + id: contentDialog + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: Math.min(page.width, page.height) / 3 * 2 + contentHeight: logo.height * 2 + parent: Overlay.overlay + + modal: true + title: "Content" + standardButtons: Dialog.Close + + Flickable { + id: flickable + clip: true + anchors.fill: parent + contentHeight: column.height + + Column { + id: column + spacing: 20 + width: parent.width + + Image { + id: logo + width: parent.width / 2 + anchors.horizontalCenter: parent.horizontalCenter + fillMode: Image.PreserveAspectFit + source: "qt-logo.png" + } + + Label { + width: parent.width + text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc finibus " + + "in est quis laoreet. Interdum et malesuada fames ac ante ipsum primis " + + "in faucibus. Curabitur eget justo sollicitudin enim faucibus bibendum. " + + "Suspendisse potenti. Vestibulum cursus consequat mauris id sollicitudin. " + + "Duis facilisis hendrerit consectetur. Curabitur sapien tortor, efficitur " + + "id auctor nec, efficitur et nisl. Ut venenatis eros in nunc placerat, " + + "eu aliquam enim suscipit." + wrapMode: Label.Wrap + } + } + + ScrollIndicator.vertical: ScrollIndicator { + parent: contentDialog.contentItem + anchors.top: flickable.top + anchors.bottom: flickable.bottom + anchors.right: parent.right + anchors.rightMargin: -contentDialog.rightPadding + 1 + } + } + } + } + + Button { + text: "Input" + anchors.horizontalCenter: parent.horizontalCenter + width: buttonWidth + onClicked: inputDialog.open() + + Dialog { + id: inputDialog + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + parent: Overlay.overlay + + focus: true + modal: true + title: "Input" + standardButtons: Dialog.Ok | Dialog.Cancel + + ColumnLayout { + spacing: 20 + anchors.fill: parent + Label { + elide: Label.ElideRight + text: "Please enter the credentials:" + Layout.fillWidth: true + } + TextField { + focus: true + placeholderText: "Username" + Layout.fillWidth: true + } + TextField { + placeholderText: "Password" + echoMode: TextField.PasswordEchoOnEdit + Layout.fillWidth: true + } + } + } + } + } +} diff --git a/basicsuite/qtquickcontrols2/pages/FramePage.qml b/basicsuite/qtquickcontrols2/pages/FramePage.qml new file mode 100644 index 0000000..a1d7d7f --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/FramePage.qml @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Controls 2.1 + +ScrollablePage { + id: page + + readonly property int itemWidth: Math.max(button.implicitWidth, Math.min(button.implicitWidth * 3, page.availableWidth / 3 * 2)) + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "Frame is used to layout a logical group of controls together, within a visual frame." + } + + Frame { + anchors.horizontalCenter: parent.horizontalCenter + + Column { + spacing: 20 + width: page.itemWidth + + RadioButton { + text: "First" + checked: true + width: parent.width + } + RadioButton { + id: button + text: "Second" + width: parent.width + } + RadioButton { + text: "Third" + width: parent.width + } + } + } + } +} diff --git a/basicsuite/qtquickcontrols2/pages/GroupBoxPage.qml b/basicsuite/qtquickcontrols2/pages/GroupBoxPage.qml new file mode 100644 index 0000000..bb332a8 --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/GroupBoxPage.qml @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Controls 2.1 + +ScrollablePage { + id: page + + readonly property int itemWidth: Math.max(button.implicitWidth, Math.min(button.implicitWidth * 3, page.availableWidth / 3 * 2)) + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "A GroupBox provides a frame, a title on top of it, and a logical group of controls within that frame." + } + + GroupBox { + title: "Title" + anchors.horizontalCenter: parent.horizontalCenter + + Column { + spacing: 20 + width: page.itemWidth + + RadioButton { + text: "First" + checked: true + width: parent.width + } + RadioButton { + id: button + text: "Second" + width: parent.width + } + RadioButton { + text: "Third" + width: parent.width + } + } + } + } +} diff --git a/basicsuite/qtquickcontrols2/pages/PageIndicatorPage.qml b/basicsuite/qtquickcontrols2/pages/PageIndicatorPage.qml new file mode 100644 index 0000000..ed35c07 --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/PageIndicatorPage.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Controls 2.1 + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "PageIndicator is used to indicate the currently active page in a container of pages." + } + + PageIndicator { + count: 5 + currentIndex: 2 + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/basicsuite/qtquickcontrols2/pages/ProgressBarPage.qml b/basicsuite/qtquickcontrols2/pages/ProgressBarPage.qml new file mode 100644 index 0000000..36bba90 --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/ProgressBarPage.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Controls 2.1 + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "ProgressBar indicates the progress of an operation. It can be set in an " + + "indeterminate mode to indicate that the length of the operation is unknown." + } + + ProgressBar { + id: bar + value: 0.5 + anchors.horizontalCenter: parent.horizontalCenter + } + + ProgressBar { + indeterminate: true + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/basicsuite/qtquickcontrols2/pages/RadioButtonPage.qml b/basicsuite/qtquickcontrols2/pages/RadioButtonPage.qml new file mode 100644 index 0000000..451caf5 --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/RadioButtonPage.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Controls 2.1 + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "RadioButton presents an option button that can be toggled on or off. " + + "Radio buttons are typically used to select one option from a set of options." + } + + Column { + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + + RadioButton { + text: "First" + } + RadioButton { + text: "Second" + checked: true + } + RadioButton { + text: "Third" + enabled: false + } + } + } +} diff --git a/basicsuite/qtquickcontrols2/pages/RangeSliderPage.qml b/basicsuite/qtquickcontrols2/pages/RangeSliderPage.qml new file mode 100644 index 0000000..9e8d9a9 --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/RangeSliderPage.qml @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Controls 2.1 + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "RangeSlider is used to select a range specified by two values, by sliding each handle along a track." + } + + RangeSlider { + id: slider + first.value: 0.25 + second.value: 0.75 + anchors.horizontalCenter: parent.horizontalCenter + } + + RangeSlider { + orientation: Qt.Vertical + first.value: 0.25 + second.value: 0.75 + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/basicsuite/qtquickcontrols2/pages/ScrollBarPage.qml b/basicsuite/qtquickcontrols2/pages/ScrollBarPage.qml new file mode 100644 index 0000000..cc7de11 --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/ScrollBarPage.qml @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Controls 2.1 + +Flickable { + id: flickable + + contentHeight: pane.height + + Pane { + id: pane + width: flickable.width + height: flickable.height * 1.25 + + Column { + id: column + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "ScrollBar is an interactive bar that can be used to scroll to a specific position. " + + "A scroll bar can be either vertical or horizontal, and can be attached to any Flickable, " + + "such as ListView and GridView." + } + + Image { + rotation: 90 + source: "arrows.png" + anchors.horizontalCenter: parent.horizontalCenter + } + } + } + + ScrollBar.vertical: ScrollBar { } +} diff --git a/basicsuite/qtquickcontrols2/pages/ScrollIndicatorPage.qml b/basicsuite/qtquickcontrols2/pages/ScrollIndicatorPage.qml new file mode 100644 index 0000000..dd5ef46 --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/ScrollIndicatorPage.qml @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Controls 2.1 + +Flickable { + id: flickable + + contentHeight: pane.height + + Pane { + id: pane + width: flickable.width + height: flickable.height * 1.25 + + Column { + id: column + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "ScrollIndicator is a non-interactive indicator that indicates the current scroll position. " + + "A scroll indicator can be either vertical or horizontal, and can be attached to any Flickable, " + + "such as ListView and GridView." + } + + Image { + rotation: 90 + source: "arrows.png" + anchors.horizontalCenter: parent.horizontalCenter + } + } + } + + ScrollIndicator.vertical: ScrollIndicator { } +} diff --git a/basicsuite/qtquickcontrols2/pages/ScrollablePage.qml b/basicsuite/qtquickcontrols2/pages/ScrollablePage.qml new file mode 100644 index 0000000..90bd014 --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/ScrollablePage.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Controls 2.0 + +Page { + id: page + + default property alias content: pane.contentItem + + Flickable { + anchors.fill: parent + contentHeight: pane.implicitHeight + flickableDirection: Flickable.AutoFlickIfNeeded + + Pane { + id: pane + width: parent.width + } + + ScrollIndicator.vertical: ScrollIndicator { } + } +} diff --git a/basicsuite/qtquickcontrols2/pages/SliderPage.qml b/basicsuite/qtquickcontrols2/pages/SliderPage.qml new file mode 100644 index 0000000..9d941d0 --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/SliderPage.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Controls 2.1 + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "Slider is used to select a value by sliding a handle along a track." + } + + Slider { + id: slider + value: 0.5 + anchors.horizontalCenter: parent.horizontalCenter + } + + Slider { + orientation: Qt.Vertical + value: 0.5 + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/basicsuite/qtquickcontrols2/pages/SpinBoxPage.qml b/basicsuite/qtquickcontrols2/pages/SpinBoxPage.qml new file mode 100644 index 0000000..b063a37 --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/SpinBoxPage.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Controls 2.1 + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "SpinBox allows the user to choose an integer value by clicking the up or down indicator buttons, " + + "by pressing up or down on the keyboard, or by entering a text value in the input field." + } + + SpinBox { + id: box + value: 50 + anchors.horizontalCenter: parent.horizontalCenter + editable: true + } + } +} diff --git a/basicsuite/qtquickcontrols2/pages/StackViewPage.qml b/basicsuite/qtquickcontrols2/pages/StackViewPage.qml new file mode 100644 index 0000000..45884a7 --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/StackViewPage.qml @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Controls 2.1 + +StackView { + id: stackView + initialItem: page + + Component { + id: page + + Pane { + id: pane + width: parent ? parent.width : 0 // TODO: fix null parent on destruction + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "StackView provides a stack-based navigation model which can be used with a set of interlinked pages. " + + "Items are pushed onto the stack as the user navigates deeper into the material, and popped off again " + + "when he chooses to go back." + } + + Button { + id: button + text: "Push" + anchors.horizontalCenter: parent.horizontalCenter + width: Math.max(button.implicitWidth, Math.min(button.implicitWidth * 2, pane.availableWidth / 3)) + onClicked: stackView.push(page) + } + + Button { + text: "Pop" + enabled: stackView.depth > 1 + width: Math.max(button.implicitWidth, Math.min(button.implicitWidth * 2, pane.availableWidth / 3)) + anchors.horizontalCenter: parent.horizontalCenter + onClicked: stackView.pop() + } + } + } + } +} diff --git a/basicsuite/qtquickcontrols2/pages/SwipeViewPage.qml b/basicsuite/qtquickcontrols2/pages/SwipeViewPage.qml new file mode 100644 index 0000000..3c5d04c --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/SwipeViewPage.qml @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Controls 2.1 + +Pane { + id: pane + + SwipeView { + id: view + currentIndex: 1 + anchors.fill: parent + + Repeater { + model: 3 + + Pane { + width: view.width + height: view.height + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "SwipeView provides a navigation model that simplifies horizontal paged scrolling. " + + "The page indicator on the bottom shows which is the presently active page." + } + + Image { + source: "arrows.png" + anchors.horizontalCenter: parent.horizontalCenter + } + } + } + } + } + + PageIndicator { + count: view.count + currentIndex: view.currentIndex + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + } +} diff --git a/basicsuite/qtquickcontrols2/pages/SwitchPage.qml b/basicsuite/qtquickcontrols2/pages/SwitchPage.qml new file mode 100644 index 0000000..d894ed5 --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/SwitchPage.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Controls 2.1 + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "Switch is an option button that can be dragged or toggled on or off. " + + "Switches are typically used to select between two states." + } + + Column { + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + + Switch { + text: "First" + } + Switch { + text: "Second" + checked: true + } + Switch { + text: "Third" + enabled: false + } + } + } +} diff --git a/basicsuite/qtquickcontrols2/pages/TabBarPage.qml b/basicsuite/qtquickcontrols2/pages/TabBarPage.qml new file mode 100644 index 0000000..925691a --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/TabBarPage.qml @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Controls 2.1 + +Page { + id: page + + SwipeView { + id: swipeView + anchors.fill: parent + currentIndex: tabBar.currentIndex + + Repeater { + model: 3 + + Pane { + width: swipeView.width + height: swipeView.height + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "TabBar is a bar with icons or text which allows the user" + + "to switch between different subtasks, views, or modes." + } + + Image { + source: "arrows.png" + anchors.horizontalCenter: parent.horizontalCenter + } + } + } + } + } + + footer: TabBar { + id: tabBar + currentIndex: swipeView.currentIndex + + TabButton { + text: "First" + } + TabButton { + text: "Second" + } + TabButton { + text: "Third" + } + } +} diff --git a/basicsuite/qtquickcontrols2/pages/TextAreaPage.qml b/basicsuite/qtquickcontrols2/pages/TextAreaPage.qml new file mode 100644 index 0000000..d83096d --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/TextAreaPage.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Controls 2.1 + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "TextArea is a multi-line text editor." + } + + TextArea { + width: Math.max(implicitWidth, Math.min(implicitWidth * 3, pane.availableWidth / 3)) + anchors.horizontalCenter: parent.horizontalCenter + + wrapMode: TextArea.Wrap + text: "TextArea\n...\n...\n..." + } + } +} diff --git a/basicsuite/qtquickcontrols2/pages/TextFieldPage.qml b/basicsuite/qtquickcontrols2/pages/TextFieldPage.qml new file mode 100644 index 0000000..959d968 --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/TextFieldPage.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Controls 2.1 + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "TextField is a single-line text editor." + } + + TextField { + id: field + placeholderText: "TextField" + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/basicsuite/qtquickcontrols2/pages/ToolTipPage.qml b/basicsuite/qtquickcontrols2/pages/ToolTipPage.qml new file mode 100644 index 0000000..bc2aa81 --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/ToolTipPage.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Controls 2.1 + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "A tool tip is a short piece of text that informs the user of a control's function." + } + + Button { + text: "Tip" + anchors.horizontalCenter: parent.horizontalCenter + + ToolTip.timeout: 5000 + ToolTip.visible: pressed + ToolTip.text: "This is a tool tip." + } + } +} diff --git a/basicsuite/qtquickcontrols2/pages/TumblerPage.qml b/basicsuite/qtquickcontrols2/pages/TumblerPage.qml new file mode 100644 index 0000000..bc0aa24 --- /dev/null +++ b/basicsuite/qtquickcontrols2/pages/TumblerPage.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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.6 +import QtQuick.Controls 2.1 + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "Tumbler is used to select a value by spinning a wheel." + } + + Tumbler { + model: 10 + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/basicsuite/qtquickcontrols2/preview_l.jpg b/basicsuite/qtquickcontrols2/preview_l.jpg new file mode 100644 index 0000000..c840e8e Binary files /dev/null and b/basicsuite/qtquickcontrols2/preview_l.jpg differ diff --git a/basicsuite/qtquickcontrols2/qtquickcontrols2.conf b/basicsuite/qtquickcontrols2/qtquickcontrols2.conf new file mode 100644 index 0000000..da1a8f4 --- /dev/null +++ b/basicsuite/qtquickcontrols2/qtquickcontrols2.conf @@ -0,0 +1,8 @@ +[Material] +Primary=#41cd52 +Accent=#41cd52 +Theme=System + +[Universal] +Accent=#41cd52 +Theme=System diff --git a/basicsuite/shared/main.cpp b/basicsuite/shared/main.cpp index 4600236..00ceab1 100644 --- a/basicsuite/shared/main.cpp +++ b/basicsuite/shared/main.cpp @@ -63,6 +63,8 @@ #include #include #include +#include +#include #if defined(USE_QTWEBENGINE) #include @@ -73,7 +75,7 @@ int main(int argc, char **argv) { //qputenv("QT_IM_MODULE", QByteArray("qtvkb")); - + qputenv("QT_QUICK_CONTROLS_CONF", "/data/user/gallery/qtquickcontrols2.conf"); QApplication app(argc, argv); #if defined(USE_QTWEBENGINE) @@ -118,12 +120,20 @@ int main(int argc, char **argv) QGuiApplication::setFont(font); } + QSettings settings; + QString style = QQuickStyle::name(); + if (!style.isEmpty()) + settings.setValue("style", "Material"); + else + QQuickStyle::setStyle(settings.value("style").toString()); + DummyEngine engine; QQmlApplicationEngine applicationengine; QString appFont("TitilliumWeb"); applicationengine.rootContext()->setContextProperty("engine", &engine); applicationengine.rootContext()->setContextProperty("appFont", appFont); + applicationengine.rootContext()->setContextProperty("availableStyles", QQuickStyle::availableStyles()); applicationengine.load(QUrl::fromLocalFile(path + "/SharedMain.qml")); app.exec(); diff --git a/basicsuite/shared/shared.pri b/basicsuite/shared/shared.pri index 6105f78..05e0ba8 100644 --- a/basicsuite/shared/shared.pri +++ b/basicsuite/shared/shared.pri @@ -1,5 +1,5 @@ # widget dependecy is required by QtCharts demo -QT += quick widgets +QT += quick widgets quickcontrols2 qtHaveModule(webengine) { DEFINES += USE_QTWEBENGINE -- cgit v1.2.3 From f5c4c3a380f974aac954628d120ec3b0e028e36e Mon Sep 17 00:00:00 2001 From: Juho Annunen Date: Mon, 7 May 2018 12:24:06 +0300 Subject: Remove qtwebbrowser submodule Task-number: QTBUG-62793 Change-Id: I3ef7323ebaed7b16014e139a5110f1784240520a Reviewed-by: Samuli Piippo --- .gitmodules | 4 ---- basicsuite/qtwebbrowser/tqtc-qtwebbrowser | 1 - 2 files changed, 5 deletions(-) delete mode 160000 basicsuite/qtwebbrowser/tqtc-qtwebbrowser diff --git a/.gitmodules b/.gitmodules index 4784266..2ecbb11 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,3 @@ [submodule "tradeshow/enterprise-kinectdatavis/src/libfreenect"] path = tradeshow/enterprise-kinectdatavis/src/libfreenect url = https://github.com/OpenKinect/libfreenect.git -[submodule "basicsuite/qtwebbrowser/tqtc-qtwebbrowser"] - path = basicsuite/qtwebbrowser/tqtc-qtwebbrowser - url = ssh://codereview.qt-project.org:29418/qt-apps/qtwebbrowser - diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser deleted file mode 160000 index c86bb8a..0000000 --- a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c86bb8a400f79be205025598310926df5d01c7bc -- cgit v1.2.3 From e513aed3b9cb8ff3124c21ed01e45128fa686eee Mon Sep 17 00:00:00 2001 From: Juho Annunen Date: Tue, 17 Apr 2018 16:18:56 +0300 Subject: Update QtWebBrowser demo to new UI theme Task-number: QTBUG-62793 Change-Id: I8e1a0dcb229dc1b445a1b3a7787e6b818f246249 Reviewed-by: Teemu Holappa --- basicsuite/.gitignore | 6 + .../tqtc-qtwebbrowser/mockups/00_HomePage.png | Bin 0 -> 97167 bytes .../mockups/00_HomePage_DeleteBookmarks.png | Bin 0 -> 84637 bytes .../tqtc-qtwebbrowser/mockups/01_Browsing.png | Bin 0 -> 30856 bytes .../mockups/01_Browsing_Bookmark.png | Bin 0 -> 152513 bytes .../mockups/01_Browsing_Loading.png | Bin 0 -> 295182 bytes .../tqtc-qtwebbrowser/mockups/01_Browsing_NoKb.png | Bin 0 -> 27642 bytes .../mockups/01_Browsing_Private.png | Bin 0 -> 350083 bytes .../mockups/01_URLbox+Bookmark.png | Bin 0 -> 29019 bytes .../tqtc-qtwebbrowser/mockups/01_URLbox.png | Bin 0 -> 40493 bytes .../mockups/02_Selection_Link.png | Bin 0 -> 69875 bytes .../mockups/02_Selection_Text.png | Bin 0 -> 226165 bytes .../tqtc-qtwebbrowser/mockups/02_Selection_URL.png | Bin 0 -> 52933 bytes .../tqtc-qtwebbrowser/mockups/03_Tabs_1.png | Bin 0 -> 115301 bytes .../tqtc-qtwebbrowser/mockups/03_Tabs_10+.png | Bin 0 -> 28289 bytes .../tqtc-qtwebbrowser/mockups/03_Tabs_2.png | Bin 0 -> 154532 bytes .../tqtc-qtwebbrowser/mockups/03_Tabs_3.png | Bin 0 -> 181823 bytes .../tqtc-qtwebbrowser/mockups/03_Tabs_4.png | Bin 0 -> 189989 bytes .../tqtc-qtwebbrowser/mockups/03_Tabs_5+.png | Bin 0 -> 202098 bytes .../tqtc-qtwebbrowser/mockups/03_Tabs_5.png | Bin 0 -> 202229 bytes .../tqtc-qtwebbrowser/mockups/03_Tabs_New.png | Bin 0 -> 109443 bytes .../tqtc-qtwebbrowser/mockups/04_Settings.png | Bin 0 -> 37796 bytes .../tqtc-qtwebbrowser/mockups/Bookmarks_Button.png | Bin 0 -> 33185 bytes .../mockups/LightWebBrowserFunctions.xlsx | Bin 0 -> 14173 bytes .../mockups/LightWebBrowser_Specs.pdf | Bin 0 -> 1635131 bytes .../tqtc-qtwebbrowser/qtwebbrowser.pro | 2 + .../tqtc-qtwebbrowser/src/appengine.cpp | 115 ++++ .../qtwebbrowser/tqtc-qtwebbrowser/src/appengine.h | 100 +++ .../qtwebbrowser/tqtc-qtwebbrowser/src/main.cpp | 116 ++++ .../src/navigationhistoryproxymodel.cpp | 76 +++ .../src/navigationhistoryproxymodel.h | 75 +++ .../tqtc-qtwebbrowser/src/qml/BrowserWindow.qml | 479 ++++++++++++++ .../tqtc-qtwebbrowser/src/qml/CustomSwitch.qml | 122 ++++ .../src/qml/FeaturePermissionBar.qml | 140 ++++ .../tqtc-qtwebbrowser/src/qml/HomeScreen.qml | 603 ++++++++++++++++++ .../tqtc-qtwebbrowser/src/qml/Keyboard.qml | 69 ++ .../tqtc-qtwebbrowser/src/qml/Main.qml | 50 ++ .../tqtc-qtwebbrowser/src/qml/MockTouchPoint.qml | 63 ++ .../tqtc-qtwebbrowser/src/qml/NavigationBar.qml | 453 +++++++++++++ .../tqtc-qtwebbrowser/src/qml/PageView.qml | 705 +++++++++++++++++++++ .../tqtc-qtwebbrowser/src/qml/SettingsView.qml | 195 ++++++ .../tqtc-qtwebbrowser/src/qml/Utils.js | 60 ++ .../tqtc-qtwebbrowser/src/qml/assets/UIButton.qml | 77 +++ .../tqtc-qtwebbrowser/src/qml/assets/UIToolBar.qml | 168 +++++ .../src/qml/assets/icons/AppLogoColor.png | Bin 0 -> 6113 bytes .../src/qml/assets/icons/AppLogoGrey.png | Bin 0 -> 5539 bytes .../src/qml/assets/icons/Btn_Add.png | Bin 0 -> 1169 bytes .../src/qml/assets/icons/Btn_Back.png | Bin 0 -> 1184 bytes .../src/qml/assets/icons/Btn_Bookmark_Checked.png | Bin 0 -> 1696 bytes .../qml/assets/icons/Btn_Bookmark_Indicator.png | Bin 0 -> 1972 bytes .../src/qml/assets/icons/Btn_Bookmarks.png | Bin 0 -> 1792 bytes .../src/qml/assets/icons/Btn_Clear.png | Bin 0 -> 1467 bytes .../src/qml/assets/icons/Btn_Delete.png | Bin 0 -> 2793 bytes .../src/qml/assets/icons/Btn_Forward.png | Bin 0 -> 1178 bytes .../src/qml/assets/icons/Btn_Home.png | Bin 0 -> 1461 bytes .../src/qml/assets/icons/Btn_Reload.png | Bin 0 -> 1614 bytes .../src/qml/assets/icons/Btn_Search.png | Bin 0 -> 1691 bytes .../src/qml/assets/icons/Btn_Settings.png | Bin 0 -> 1149 bytes .../src/qml/assets/icons/Btn_Tabs.png | Bin 0 -> 1235 bytes .../src/qml/assets/icons/Btn_Up.png | Bin 0 -> 1223 bytes .../src/qml/assets/icons/Error_Icon.png | Bin 0 -> 4371 bytes .../src/qml/assets/icons/LightWebBrowser_Icons.svg | 243 +++++++ .../src/qml/assets/icons/about_blank.png | Bin 0 -> 6022 bytes .../tqtc-qtwebbrowser/src/qml/assets/icons/qt.png | Bin 0 -> 7345 bytes .../src/qml/assets/icons/touchpoint.png | Bin 0 -> 1331 bytes .../tqtc-qtwebbrowser/src/resources.qrc | 37 ++ .../qtwebbrowser/tqtc-qtwebbrowser/src/src.pro | 43 ++ .../src/touchmockingapplication.cpp | 282 +++++++++ .../src/touchmockingapplication.h | 80 +++ .../tqtc-qtwebbrowser/src/touchtracker.cpp | 169 +++++ .../tqtc-qtwebbrowser/src/touchtracker.h | 97 +++ 71 files changed, 4625 insertions(+) create mode 100644 basicsuite/.gitignore create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/00_HomePage.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/00_HomePage_DeleteBookmarks.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_Bookmark.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_Loading.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_NoKb.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_Private.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_URLbox+Bookmark.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_URLbox.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/02_Selection_Link.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/02_Selection_Text.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/02_Selection_URL.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_1.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_10+.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_2.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_3.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_4.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_5+.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_5.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_New.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/04_Settings.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/Bookmarks_Button.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/LightWebBrowserFunctions.xlsx create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/LightWebBrowser_Specs.pdf create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/qtwebbrowser.pro create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/appengine.cpp create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/appengine.h create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/main.cpp create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/navigationhistoryproxymodel.cpp create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/navigationhistoryproxymodel.h create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/BrowserWindow.qml create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/CustomSwitch.qml create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/FeaturePermissionBar.qml create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/HomeScreen.qml create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/Keyboard.qml create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/Main.qml create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/MockTouchPoint.qml create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/NavigationBar.qml create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/PageView.qml create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/SettingsView.qml create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/Utils.js create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/UIButton.qml create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/UIToolBar.qml create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/AppLogoColor.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/AppLogoGrey.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Add.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Back.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmark_Checked.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmark_Indicator.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmarks.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Clear.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Delete.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Forward.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Home.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Reload.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Search.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Settings.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Tabs.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Up.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Error_Icon.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/LightWebBrowser_Icons.svg create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/about_blank.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/qt.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/touchpoint.png create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/resources.qrc create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/src.pro create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchmockingapplication.cpp create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchmockingapplication.h create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchtracker.cpp create mode 100644 basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchtracker.h diff --git a/basicsuite/.gitignore b/basicsuite/.gitignore new file mode 100644 index 0000000..3cb11b4 --- /dev/null +++ b/basicsuite/.gitignore @@ -0,0 +1,6 @@ +*.o +moc_* +Makefile +*.pro.user +*.so +*.moc diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/00_HomePage.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/00_HomePage.png new file mode 100644 index 0000000..cf7c69c Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/00_HomePage.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/00_HomePage_DeleteBookmarks.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/00_HomePage_DeleteBookmarks.png new file mode 100644 index 0000000..95441e4 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/00_HomePage_DeleteBookmarks.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing.png new file mode 100644 index 0000000..d93a211 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_Bookmark.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_Bookmark.png new file mode 100644 index 0000000..0b880b8 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_Bookmark.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_Loading.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_Loading.png new file mode 100644 index 0000000..016b7f7 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_Loading.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_NoKb.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_NoKb.png new file mode 100644 index 0000000..e330c6c Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_NoKb.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_Private.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_Private.png new file mode 100644 index 0000000..50d1115 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_Private.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_URLbox+Bookmark.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_URLbox+Bookmark.png new file mode 100644 index 0000000..1d11050 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_URLbox+Bookmark.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_URLbox.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_URLbox.png new file mode 100644 index 0000000..eec1ae1 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_URLbox.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/02_Selection_Link.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/02_Selection_Link.png new file mode 100644 index 0000000..7edffa0 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/02_Selection_Link.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/02_Selection_Text.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/02_Selection_Text.png new file mode 100644 index 0000000..476fcbc Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/02_Selection_Text.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/02_Selection_URL.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/02_Selection_URL.png new file mode 100644 index 0000000..861e774 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/02_Selection_URL.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_1.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_1.png new file mode 100644 index 0000000..80a9a77 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_1.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_10+.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_10+.png new file mode 100644 index 0000000..58c833e Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_10+.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_2.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_2.png new file mode 100644 index 0000000..f4da8ae Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_2.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_3.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_3.png new file mode 100644 index 0000000..4d89730 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_3.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_4.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_4.png new file mode 100644 index 0000000..c4c74a0 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_4.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_5+.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_5+.png new file mode 100644 index 0000000..ccfc920 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_5+.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_5.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_5.png new file mode 100644 index 0000000..451dec4 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_5.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_New.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_New.png new file mode 100644 index 0000000..08ef407 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_New.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/04_Settings.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/04_Settings.png new file mode 100644 index 0000000..0de35da Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/04_Settings.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/Bookmarks_Button.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/Bookmarks_Button.png new file mode 100644 index 0000000..83849d3 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/Bookmarks_Button.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/LightWebBrowserFunctions.xlsx b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/LightWebBrowserFunctions.xlsx new file mode 100644 index 0000000..037813a Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/LightWebBrowserFunctions.xlsx differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/LightWebBrowser_Specs.pdf b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/LightWebBrowser_Specs.pdf new file mode 100644 index 0000000..8f77fe5 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/LightWebBrowser_Specs.pdf differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/qtwebbrowser.pro b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/qtwebbrowser.pro new file mode 100644 index 0000000..65d9262 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/qtwebbrowser.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = src diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/appengine.cpp b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/appengine.cpp new file mode 100644 index 0000000..7be0e5b --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/appengine.cpp @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtBrowser project. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPLv2 included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "appengine.h" + +#include +#include +#include +#include + +AppEngine::AppEngine(QObject *parent) + : QObject(parent) + , m_settings(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) % QDir::separator() % "settings.ini", QSettings::IniFormat, this) +{ + foreach (const QString &arg, QCoreApplication::arguments().mid(1)) { + if (arg.startsWith('-')) + continue; + const QUrl url(arg); + if (url.isValid()) { + m_initialUrl = url.toString(); + break; + } + } +} + +QString AppEngine::settingsPath() +{ + return m_settings.fileName(); +} + +QString AppEngine::initialUrl() const +{ + return m_initialUrl; +} + +QUrl AppEngine::fromUserInput(const QString& userInput) +{ + QFileInfo fileInfo(userInput); + if (fileInfo.exists()) + return QUrl::fromLocalFile(fileInfo.absoluteFilePath()); + return QUrl::fromUserInput(userInput); +} + +bool AppEngine::isUrl(const QString& userInput) +{ + if (userInput.startsWith(QStringLiteral("www.")) + || userInput.startsWith(QStringLiteral("http")) + || userInput.startsWith(QStringLiteral("ftp")) + || userInput.contains(QStringLiteral("://")) + || userInput.endsWith(QStringLiteral(".com"))) + return true; + return false; +} + +QString AppEngine::domainFromString(const QString& urlString) +{ + return QUrl::fromUserInput(urlString).host(); +} + +QString AppEngine::fallbackColor() +{ + static QList colors = QList() << QStringLiteral("#46a2da") + << QStringLiteral("#18394c") + << QStringLiteral("#ff8c0a") + << QStringLiteral("#5caa15"); + static int index = -1; + if (++index == colors.count()) + index = 0; + return colors[index]; +} + +QString AppEngine::restoreSetting(const QString &name, const QString &defaultValue) +{ + return m_settings.value(name, defaultValue).toString(); +} + +void AppEngine::saveSetting(const QString &name, const QString &value) +{ + m_settings.setValue(name, value); +} + diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/appengine.h b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/appengine.h new file mode 100644 index 0000000..808f3b7 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/appengine.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtBrowser project. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPLv2 included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef APPENGINE_H +#define APPENGINE_H + +#include +#include +#include +#include +#include +#include + +namespace utils { +inline bool isTouchEvent(const QEvent* event) +{ + switch (event->type()) { + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + return true; + default: + return false; + } +} + +inline bool isMouseEvent(const QEvent* event) +{ + switch (event->type()) { + case QEvent::MouseButtonPress: + case QEvent::MouseMove: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + return true; + default: + return false; + } +} + +} + +class AppEngine : public QObject { + Q_OBJECT + + Q_PROPERTY(QString settingsPath READ settingsPath FINAL CONSTANT) + Q_PROPERTY(QString initialUrl READ initialUrl FINAL CONSTANT) + +public: + AppEngine(QObject *parent = 0); + + QString settingsPath(); + QString initialUrl() const; + + Q_INVOKABLE bool isUrl(const QString& userInput); + Q_INVOKABLE QUrl fromUserInput(const QString& userInput); + Q_INVOKABLE QString domainFromString(const QString& urlString); + Q_INVOKABLE QString fallbackColor(); + Q_INVOKABLE QString restoreSetting(const QString &name, const QString &defaultValue = QString()); + Q_INVOKABLE void saveSetting(const QString &name, const QString &value); + +private: + QSettings m_settings; + QString m_initialUrl; +}; + +#endif // APPENGINE_H diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/main.cpp b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/main.cpp new file mode 100644 index 0000000..919629c --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/main.cpp @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtBrowser project. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPLv2 included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "appengine.h" +#include "navigationhistoryproxymodel.h" +#include "touchtracker.h" + +#if defined(DESKTOP_BUILD) +#include "touchmockingapplication.h" +#endif + +#include +#include +#include +#include +#include + +static QObject *engine_factory(QQmlEngine *engine, QJSEngine *scriptEngine) +{ + Q_UNUSED(engine); + Q_UNUSED(scriptEngine); + AppEngine *eng = new AppEngine(); + return eng; +} + +int main(int argc, char **argv) +{ + qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard")); + + //do not use any plugins installed on the device + qputenv("QML2_IMPORT_PATH", QByteArray()); + + // We use touch mocking on desktop and apply all the mobile switches. + QByteArrayList args = QByteArrayList() + << QByteArrayLiteral("--enable-embedded-switches") + << QByteArrayLiteral("--log-level=0"); + const int count = args.size() + argc; + QVector qargv(count); + + qargv[0] = argv[0]; + for (int i = 0; i < args.size(); ++i) + qargv[i + 1] = args[i].data(); + for (int i = args.size() + 1; i < count; ++i) + qargv[i] = argv[i - args.size()]; + + int qAppArgCount = qargv.size(); + +#if defined(DESKTOP_BUILD) + TouchMockingApplication app(qAppArgCount, qargv.data()); +#else + QGuiApplication app(qAppArgCount, qargv.data()); +#endif + + qmlRegisterType("WebBrowser", 1, 0, "SearchProxyModel"); + qmlRegisterType("WebBrowser", 1, 0, "TouchTracker"); + qmlRegisterSingletonType("WebBrowser", 1, 0, "AppEngine", engine_factory); + + QtWebEngine::initialize(); + + app.setOrganizationName("The Qt Company"); + app.setOrganizationDomain("qt.io"); + app.setApplicationName("qtwebbrowser"); + + QQuickView view; + view.setTitle("Yet Another Browser"); + view.setFlags(Qt::Window | Qt::WindowTitleHint); + view.setResizeMode(QQuickView::SizeRootObjectToView); + view.setColor(Qt::black); + view.setSource(QUrl("qrc:///qml/Main.qml")); + + QObject::connect(view.engine(), SIGNAL(quit()), &app, SLOT(quit())); + +#if defined(DESKTOP_BUILD) + view.show(); + if (view.size().isEmpty()) + view.setGeometry(0, 0, 800, 600); +#else + view.showFullScreen(); +#endif + + app.exec(); +} diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/navigationhistoryproxymodel.cpp b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/navigationhistoryproxymodel.cpp new file mode 100644 index 0000000..d574ae5 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/navigationhistoryproxymodel.cpp @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtBrowser project. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPLv2 included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "navigationhistoryproxymodel.h" + +NavigationHistoryProxyModel::NavigationHistoryProxyModel(QObject *parent) + : QSortFilterProxyModel(parent) +{ + +} + +bool NavigationHistoryProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +{ + QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); + + // Use UrlRole and TitleRole instead of DisplayRole + return (sourceModel()->data(index, Qt::UserRole + 1).toString().contains(filterRegExp()) + || sourceModel()->data(index, Qt::UserRole + 2).toString().contains(filterRegExp())); +} + +void NavigationHistoryProxyModel::setEnabled(bool enabled) +{ + if (dynamicSortFilter() == enabled) + return; + setDynamicSortFilter(enabled); + emit enabledChanged(); +} + +QString NavigationHistoryProxyModel::searchString() const +{ + return m_searchString; +} + +void NavigationHistoryProxyModel::setSearchString(const QString &pattern) +{ + if (m_searchString == pattern) + return; + + m_searchString = pattern; + setFilterRegExp(QRegExp(pattern, Qt::CaseInsensitive, QRegExp::FixedString)); + emit searchStringChanged(); +} diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/navigationhistoryproxymodel.h b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/navigationhistoryproxymodel.h new file mode 100644 index 0000000..c2e3886 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/navigationhistoryproxymodel.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtBrowser project. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPLv2 included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef NAVIGATIONHISTORYPROXYMODEL_H +#define NAVIGATIONHISTORYPROXYMODEL_H + +#include +#include +#include + +class NavigationHistoryProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT + + Q_PROPERTY(QAbstractItemModel * target READ sourceModel WRITE setSourceModel) + Q_PROPERTY(QString searchString READ searchString WRITE setSearchString NOTIFY searchStringChanged) + Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) + +public: + explicit NavigationHistoryProxyModel(QObject *parent = 0); + + + bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; + + bool enabled() const { return dynamicSortFilter(); } + void setEnabled(bool enabled); + + void setTarget(QAbstractItemModel *t); + + QString searchString() const ; + void setSearchString(const QString &pattern); + +signals: + void searchStringChanged(); + void enabledChanged(); + +private: + QString m_searchString; +}; + +#endif // NAVIGATIONHISTORYPROXYMODEL_H diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/BrowserWindow.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/BrowserWindow.qml new file mode 100644 index 0000000..91dd074 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/BrowserWindow.qml @@ -0,0 +1,479 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtBrowser project. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPLv2 included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.5 +import QtWebEngine 1.1 + +import QtQuick.Controls 1.0 +import QtQuick.Controls.Styles 1.0 +import QtQuick.Layouts 1.0 +import QtQuick.Controls.Private 1.0 +import QtQuick.Dialogs 1.2 + +import "assets" +import WebBrowser 1.0 +import "Utils.js" as Utils + +Item { + id: browserWindow + + property Item currentWebView: { + return tabView.get(tabView.currentIndex) ? tabView.get(tabView.currentIndex).item.webView : null + } + + property string googleSearchQuery: "https://www.google.com/search?sourceid=qtbrowser&ie=UTF-8&q=" + + property int toolBarSize: 80 + property string uiColor: settingsView.privateBrowsingEnabled ? "#3a4055" : "#09102b" + //property string uiColor: "#09102b" + + //property string uiSeparatorColor: settingsView.privateBrowsingEnabled ? "#717273" : "#7ebee5" + property string uiSeparatorColor: "#9d9faa" + + //property string toolBarSeparatorColor: settingsView.privateBrowsingEnabled ? "#929495" : "#a3d1ed" + property string toolBarSeparatorColor: "#9d9faa" + + property string toolBarFillColor: settingsView.privateBrowsingEnabled ? "#3a4055" : "#09102b" + //property string toolBarFillColor: "#09102b" + + //property string buttonPressedColor: settingsView.privateBrowsingEnabled ? "#3b3c3e" : "#3f91c4" + property string buttonPressedColor: "#41cd52" + property string emptyBackgroundColor: "#09102b" + //property string uiHighlightColor: "#fddd5c" + property string uiHighlightColor: "#41cd52" + property string inactivePagerColor: "#bcbdbe" + property string textFieldStrokeColor: "#9d9faa" + property string placeholderColor: "#a0a1a2" + property string iconOverlayColor: "#0e202c" + property string iconStrokeColor: "#9d9faa" + property string defaultFontFamily: appFont //"Open Sans" + + property int gridViewPageItemCount: 8 + property int gridViewMaxBookmarks: 3 * gridViewPageItemCount + property int tabViewMaxTabs: 10 + property int animationDuration: 200 + property int velocityThreshold: 400 + property int velocityY: 0 + property real touchY: 0 + property real touchReference: 0 + property bool touchGesture: false + + width: 1024 + height: 600 + visible: true + + Action { + shortcut: "Ctrl+D" + onTriggered: { + downloadView.visible = !downloadView.visible + } + } + + Action { + id: focus + shortcut: "Ctrl+L" + onTriggered: { + navigation.addressBar.forceActiveFocus(); + navigation.addressBar.selectAll(); + } + } + Action { + shortcut: "Ctrl+R" + onTriggered: { + if (currentWebView) + currentWebView.reload() + navigation.addressBar.forceActiveFocus() + } + } + Action { + id: newTabAction + shortcut: "Ctrl+T" + onTriggered: { + tabView.get(tabView.currentIndex).item.webView.takeSnapshot() + var tab = tabView.createEmptyTab() + + if (!tab) + return + + navigation.addressBar.selectAll(); + tabView.makeCurrent(tabView.count - 1) + navigation.addressBar.forceActiveFocus() + } + } + Action { + shortcut: "Ctrl+W" + onTriggered: tabView.remove(tabView.currentIndex) + } + + UIToolBar { + id: tabEditToolBar + + source: "icons/Btn_Add.png" + indicator: tabView.count + + anchors { + left: parent.left + right: parent.right + top: navigation.top + } + + visible: opacity != 0.0 + opacity: tabView.viewState == "list" ? 1.0 : 0.0 + onDoneClicked: tabView.viewState = "page" + onOptionClicked: newTabAction.trigger() + } + + UIToolBar { + id: settingsToolBar + z: 5 + title: qsTr("Settings") + visible: opacity != 0.0 + + anchors { + left: parent.left + right: parent.right + top: navigation.top + } + + onDoneClicked: { + settingsView.save() + settingsView.state = "disabled" + } + } + + UIToolBar { + id: fullScreenBar + z: 6 + title: qsTr("Leave Full Screen Mode") + visible: opacity != 0.0 + opacity: tabView.viewState == "fullscreen" ? 1.0 : 0.0 + anchors { + left: parent.left + right: parent.right + top: navigation.top + } + onDoneClicked: { + navigation.webView.triggerWebAction(WebEngineView.ExitFullScreen); + } + } + + NavigationBar { + id: navigation + + anchors { + left: parent.left + right: parent.right + } + } + Rectangle{ + anchors.bottom: navigation.bottom + anchors.left: navigation.left + anchors.right: navigation.right + height: 2 + color: "#9d9faa" + } + + PageView { + id: tabView + interactive: { + if (sslDialog.visible || homeScreen.state != "disabled" || urlDropDown.state == "enabled" || settingsView.state == "enabled") + return false + return true + } + + anchors { + top: navigation.bottom + left: parent.left + right: parent.right + } + + height: inputPanel.y + + Component.onCompleted: { + var tab = createEmptyTab() + + if (!tab) + return + + navigation.webView = tab.webView + var url = AppEngine.initialUrl + + navigation.load(); + } + onCurrentIndexChanged: { + if (!tabView.get(tabView.currentIndex)) + return + navigation.webView = tabView.get(tabView.currentIndex).item.webView + } + } + + QtObject{ + id: acceptedCertificates + + property var acceptedUrls : [] + + function shouldAutoAccept(certificateError){ + var domain = AppEngine.domainFromString(certificateError.url) + return acceptedUrls.indexOf(domain) >= 0 + } + } + + MessageDialog { + id: sslDialog + + property var certErrors: [] + property var currentError: null + visible: certErrors.length > 0 + icon: StandardIcon.Warning + standardButtons: StandardButton.No | StandardButton.Yes + title: "Server's certificate not trusted" + text: "Do you wish to continue?" + detailedText: "If you wish so, you may continue with an unverified certificate. " + + "Accepting an unverified certificate means " + + "you may not be connected with the host you tried to connect to.\n" + + "Do you wish to override the security check and continue?" + onYes: { + var cert = certErrors.shift() + var domain = AppEngine.domainFromString(cert.url) + acceptedCertificates.acceptedUrls.push(domain) + cert.ignoreCertificateError() + presentError() + } + onNo: reject() + onRejected: reject() + + function reject(){ + certErrors.shift().rejectCertificate() + presentError() + } + function enqueue(error){ + currentError = error + certErrors.push(error) + presentError() + } + function presentError(){ + informativeText = "SSL error from URL\n\n" + currentError.url + "\n\n" + currentError.description + "\n" + } + } + + Rectangle { + id: urlDropDown + color: "white" + visible: navigation.visible + + property string searchString: navigation.addressBar.text + + anchors { + left: parent.left + right: parent.right + top: navigation.bottom + } + + state: "disabled" + + states: [ + State { + name: "enabled" + PropertyChanges { + target: urlDropDown + height: browserWindow.height - toolBarSize - 3 + } + }, + State { + name: "disabled" + PropertyChanges { + target: urlDropDown + height: 0 + } + } + ] + + Rectangle { + anchors.fill: parent + color: emptyBackgroundColor + } + + SearchProxyModel { + id: proxy + target: navigation.webView.navigationHistory.items + searchString: urlDropDown.searchString + enabled: urlDropDown.state == "enabled" + } + + ListView { + id: historyList + property int remainingHeight: Math.min((historyList.count + 1) * toolBarSize, inputPanel.y - toolBarSize - 3) + model: proxy + clip: true + boundsBehavior: Flickable.StopAtBounds + footerPositioning: ListView.InlineFooter + visible: urlDropDown.state == "enabled" + + anchors { + top: parent.top + left: parent.left + right: parent.right + } + height: remainingHeight + delegate: Rectangle { + id: wrapper + width: historyList.width + height: toolBarSize + color: "#09102b" + MouseArea { + anchors.fill: parent + onClicked: { + if (!url) + return + navigation.webView.url = url + navigation.webView.forceActiveFocus() + } + } + + Column { + width: parent.width - 60 + height: parent.height + anchors { + verticalCenter: parent.verticalCenter + horizontalCenter: parent.horizontalCenter + } + Text { + property string highlightTitle: title ? title : "" + height: wrapper.height / 2 + width: parent.width + elide: Text.ElideRight + verticalAlignment: Text.AlignBottom + anchors{ + leftMargin: 30 + rightMargin: 30 + } + id: titleLabel + font.family: defaultFontFamily + font.pixelSize: 23 + color: "white" + text: Utils.highlight(highlightTitle, urlDropDown.searchString) + } + Text { + property string highlightUrl: url ? url : "" + height: wrapper.height / 2 - 1 + width: parent.width + elide: Text.ElideRight + verticalAlignment: Text.AlignTop + font.family: defaultFontFamily + font.pixelSize: 23 + color: "white" //uiColor + text: Utils.highlight(highlightUrl, urlDropDown.searchString) + } + Rectangle { + anchors.horizontalCenter: parent.horizontalCenter + width: historyList.width + height: 1 + color: iconStrokeColor + } + } + } + footer: Rectangle { + z: 5 + width: historyList.width + height: toolBarSize + color: "#09102b" + MouseArea { + anchors.fill: parent + onClicked: { + var string = urlDropDown.searchString + var constructedUrl = "" + if (AppEngine.isUrl(string)) { + constructedUrl = AppEngine.fromUserInput(string) + } else { + constructedUrl = AppEngine.fromUserInput(googleSearchQuery + string) + } + navigation.webView.url = constructedUrl + navigation.webView.forceActiveFocus() + } + } + Row { + height: parent.height + Rectangle { + id: searchIcon + height: parent.height + width: height + color: "transparent" + Image { + anchors.centerIn: parent + source: "assets/icons/Btn_Search.png" + } + } + Text { + id: searchText + height: parent.height + width: historyList.width - searchIcon.width - 30 + elide: Text.ElideRight + text: urlDropDown.searchString + verticalAlignment: Text.AlignVCenter + font.family: defaultFontFamily + font.pixelSize: 23 + color: "white" + } + } + } + } + + transitions: Transition { + PropertyAnimation { property: "height"; duration: animationDuration; easing.type : Easing.InSine } + } + } + + HomeScreen { + id: homeScreen + height: parent.height - toolBarSize + anchors { + top: navigation.bottom + left: parent.left + right: parent.right + } + } + + SettingsView { + id: settingsView + height: parent.height - toolBarSize + anchors { + top: navigation.bottom + left: parent.left + right: parent.right + } + } +} diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/CustomSwitch.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/CustomSwitch.qml new file mode 100644 index 0000000..d73f940 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/CustomSwitch.qml @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Device Utilities module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 2.0 +import QtDeviceUtilities.QtButtonImageProvider 1.0 +import QtQuick.Controls 2.1 + +Switch { + id: control + + property alias indicatorWidth: indicatorImg.width + property alias indicatorHeight: indicatorImg.height + + indicator: Image { + id: indicatorImg + width: 200 + height: 75 + sourceSize: Qt.size(width, height) + anchors.horizontalCenter: control.horizontalCenter + y: parent.height / 2 - height / 2 + source: "image://QtButton/10/#848895/transparent" + Text { + id: offText + anchors.left: parent.left + anchors.leftMargin: parent.width * 0.075 + anchors.verticalCenter: parent.verticalCenter + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + fontSizeMode: Text.Fit + minimumPixelSize: 1 + font.pixelSize: parent.height * 0.55 + color: "#3b4155" + text: "OFF" + font.family: defaultFontFamily + } + Text { + id: onText + anchors.right: parent.right + anchors.rightMargin: parent.width * 0.1 + anchors.verticalCenter: parent.verticalCenter + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + fontSizeMode: Text.Fit + minimumPixelSize: 1 + font.pixelSize: parent.height * 0.55 + color: "#3b4155" + text: "ON" + font.family: defaultFontFamily + } + + Binding { + target: qtHandle + property: "x" + value: control.checked ? indicatorImg.width - qtHandle.width - indicatorImg.width * 0.025 : indicatorImg.width * 0.025 + when: !mousearea.drag.active + } + + MouseArea { + anchors.fill: parent + onClicked: control.checked = !control.checked + } + + QtButton { + id: qtHandle + anchors.verticalCenter: parent.verticalCenter + width: parent.width * 0.475 + height: parent.height * 0.9 + fillColor: control.checked ? "#41cd52" : "#9d9faa"//viewSettings.buttonGreenColor : viewSettings.buttonGrayColor + text: control.checked ? "ON" : "OFF" + borderColor: "transparent" + Behavior on x { + NumberAnimation { duration: 50 } + } + + MouseArea { + id: mousearea + anchors.fill: parent + drag.target: qtHandle + drag.axis: Drag.XAxis + drag.minimumX: indicatorImg.width * 0.005 + drag.maximumX: indicatorImg.width - width - indicatorImg.width * 0.005 + + onClicked: { + control.checked = !control.checked + } + + onReleased: { + if (qtHandle.x > indicatorImg.width / 5 ) { + control.checked = true + } else { + control.checked = false + } + } + } + } + } +} diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/FeaturePermissionBar.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/FeaturePermissionBar.qml new file mode 100644 index 0000000..8595724 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/FeaturePermissionBar.qml @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtBrowser project. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPLv2 included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.1 +import QtQuick.Controls 1.0 +import QtWebEngine 1.1 +import QtQuick.Layouts 1.0 + +import "assets" + +Rectangle { + property var requestedFeature; + property url securityOrigin; + property WebEngineView view; + + id: permissionBar + visible: false + height: 50 + + onRequestedFeatureChanged: { + message.text = securityOrigin + " wants to access " + message.textForFeature(requestedFeature); + } + + + RowLayout { + spacing: 0 + anchors { + fill: permissionBar + } + Rectangle { + color: uiColor + anchors { + top: parent.top + bottom: parent.bottom + } + Layout.fillWidth: true + + Text { + id: message + width: parent.width + elide: Text.ElideRight + horizontalAlignment: Text.AlignHCenter + anchors { + leftMargin: 15 + rightMargin: 15 + verticalCenter: parent.verticalCenter + horizontalCenter: parent.horizontalCenter + } + font.family: defaultFontFamily + font.pixelSize: 20 + color: "white" + function textForFeature(feature) { + if (feature === WebEngineView.MediaAudioCapture) + return "your microphone" + if (feature === WebEngineView.MediaVideoCapture) + return "your camera" + if (feature === WebEngineView.MediaAudioVideoCapture) + return "your camera and microphone" + if (feature === WebEngineView.Geolocation) + return "your position" + } + } + } + Rectangle { + width: 1 + anchors { + top: parent.top + bottom: parent.bottom + } + color: uiSeparatorColor + } + + UIButton { + id: acceptButton + implicitHeight: permissionBar.height + implicitWidth: toolBarSize + buttonText: "Accept" + textSize: 18 + Layout.alignment: Qt.AlignRight + onClicked: { + view.grantFeaturePermission(securityOrigin, requestedFeature, true); + permissionBar.visible = false; + } + } + Rectangle { + width: 1 + anchors { + top: parent.top + bottom: parent.bottom + } + color: uiSeparatorColor + } + + UIButton { + buttonText: "Deny" + textSize: 18 + implicitHeight: permissionBar.height + implicitWidth: toolBarSize + Layout.alignment: Qt.AlignRight + onClicked: { + view.grantFeaturePermission(securityOrigin, requestedFeature, false); + permissionBar.visible = false + } + } + } +} diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/HomeScreen.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/HomeScreen.qml new file mode 100644 index 0000000..9d29729 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/HomeScreen.qml @@ -0,0 +1,603 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtBrowser project. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPLv2 included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.5 +import WebBrowser 1.0 +import "assets" + +Rectangle { + id: homeScreen + property int padding: 60 + property int cellSize: width / 5 - padding + property alias messageBox: messageBox + property alias count: gridView.count + property alias currentIndex: gridView.currentIndex + color: "#09102b" + function set(i) { + var p = (i - i % gridViewPageItemCount) / gridViewPageItemCount + gridView.contentX = p * gridView.page + } + + state: "enabled" + onStateChanged: { + if (state == "enabled" && !gridView.count) + messageBox.state = "empty" + } + + signal add(string title, string url, string iconUrl, string fallbackColor) + onAdd: { + if (listModel.count === gridViewMaxBookmarks) { + navigation.refresh() + messageBox.state = "full" + state = "enabled" + homeScreen.forceActiveFocus() + return + } + var icon = url.indexOf("qt.io") != -1 ? "assets/icons/qt.png" : iconUrl + var element = { "title": title, "url": url, "iconUrl": icon, "fallbackColor": fallbackColor } + listModel.append(element) + set(listModel.count - 1) + } + + signal remove(string url, int idx) + onRemove: { + var index = idx < 0 ? contains(url) : idx + if (index < 0) + return + + listModel.remove(index) + gridView.forceLayout() + navigation.refresh() + if (!listModel.count) + messageBox.state = "empty" + } + + function get(index) { + return listModel.get(index) + } + + function contains(url) { + for (var idx = 0; idx < listModel.count; ++idx) { + if (listModel.get(idx).url === url) + return idx; + } + return -1; + } + + states: [ + State { + name: "enabled" + AnchorChanges { + target: homeScreen + anchors.top: navigation.bottom + } + }, + State { + name: "disabled" + AnchorChanges { + target: homeScreen + anchors.top: homeScreen.parent.bottom + } + }, + State { + name: "edit" + } + ] + + transitions: Transition { + AnchorAnimation { duration: animationDuration; easing.type : Easing.InSine } + } + + ListModel { + id: listModel + property string defaultBookmarks: "[{\"fallbackColor\":\"#46a2da\",\"iconUrl\":\"assets/icons/qt.png\",\"title\":\"Qt - Home\",\"url\":\"http://www.qt.io/\"},{\"fallbackColor\":\"#18394c\",\"iconUrl\":\"http://www.topgear.com/sites/all/themes/custom/tg/apple-touch-icon-144x144.png\",\"title\":\"Top Gear\",\"url\":\"http://www.topgear.com/\"},{\"fallbackColor\":\"#46a2da\",\"iconUrl\":\"https://duckduckgo.com/assets/icons/meta/DDG-iOS-icon_152x152.png\",\"title\":\"DuckDuckGo\",\"url\":\"https://duckduckgo.com/\"},{\"fallbackColor\":\"#ff8c0a\",\"iconUrl\":\"http://www.blogsmithmedia.com/www.engadget.com/media/favicon-160x160.png\",\"title\":\"Engadget | Technology News, Advice and Features\",\"url\":\"http://www.engadget.com/\"},{\"fallbackColor\":\"#ff8c0a\",\"iconUrl\":\"https://www.openstreetmap.org/assets/favicon-194x194-32cdac24b02b88e09f0639bb92c760b2.png\",\"title\":\"OpenStreetMap\",\"url\":\"https://www.openstreetmap.org/\"},{\"fallbackColor\":\"#5caa15\",\"iconUrl\":\"http://www.redditstatic.com/icon.png\",\"title\":\"reddit: the front page of the internet\",\"url\":\"http://www.reddit.com/\"}]" + + Component.onCompleted: { + listModel.clear() + var string = AppEngine.restoreSetting("bookmarks", defaultBookmarks) + if (!string) + return + var list = JSON.parse(string) + for (var i = 0; i < list.length; ++i) { + listModel.append(list[i]) + } + navigation.refresh() + } + Component.onDestruction: { + var list = [] + for (var i = 0; i < listModel.count; ++i) { + list[i] = listModel.get(i) + } + AppEngine.saveSetting("bookmarks", JSON.stringify(list)) + } + } + + GridView { + id: gridView + + onCountChanged: { + if (!count) + messageBox.state = "empty" + else + messageBox.state = "disabled" + } + + property real dragStart: 0 + property real page: 4 * cellWidth + + anchors.fill: parent + model: listModel + cellWidth: homeScreen.cellSize + homeScreen.padding + cellHeight: cellWidth + flow: GridView.FlowTopToBottom + boundsBehavior: Flickable.StopAtBounds + maximumFlickVelocity: 0 + contentHeight: parent.height + + MouseArea { + z: -1 + enabled: homeScreen.state == "edit" + anchors.fill: parent + onClicked: homeScreen.state = "enabled" + } + + rightMargin: { + var margin = (parent.width - 4 * gridView.cellWidth - homeScreen.padding) / 2 + var padding = gridView.page - Math.round(gridView.count % gridViewPageItemCount / 2) * gridView.cellWidth + + if (padding == gridView.page) + return margin + + return margin + padding + } + + anchors { + topMargin: toolBarSize + leftMargin: (parent.width - 4 * gridView.cellWidth + homeScreen.padding) / 2 + } + + Behavior on contentX { + NumberAnimation { duration: 1.5 * animationDuration; easing.type : Easing.InSine} + } + + function snapToPage() { + if (dragging) { + dragStart = contentX + return + } + if (dragStart == 2 * page && contentX < 2 * page) { + contentX = page + return + } + if (dragStart == page) { + if (contentX < page) { + contentX = 0 + return + } + if (page < contentX) { + contentX = 2 * page + return + } + } + if (dragStart == 0 && 0 < contentX) { + contentX = page + return + } + contentX = 0 + } + + onDraggingChanged: snapToPage() + delegate: Rectangle { + id: square + property string iconColor: "#f6f6f6" + width: homeScreen.cellSize + height: width + border.color: iconStrokeColor + border.width: 1 + + Rectangle { + id: bg + anchors { + horizontalCenter: parent.horizontalCenter + top: parent.top + margins: 1 + } + state: "fallback" + width: square.width - 2 + height: width + states: [ + State { + name: "fallback" + PropertyChanges { + target: square + color: fallbackColor + } + PropertyChanges { + target: bg + color: square.color + } + }, + State { + name: "normal" + PropertyChanges { + target: square + color: iconColor + } + PropertyChanges { + target: bg + color: square.color + } + } + ] + + Image { + id: icon + smooth: true + anchors { + top: parent.top + horizontalCenter: parent.horizontalCenter + topMargin: width < bg.width ? 15 : 0 + } + width: { + if (!icon.sourceSize.width) + return 0 + if (icon.sourceSize.width < 100) + return 32 + + return bg.width + } + height: width + source: iconUrl + onStatusChanged: { + switch (status) { + case Image.Null: + case Image.Loading: + case Image.Error: + bg.state = "fallback" + break + case Image.Ready: + bg.state = "normal" + break + } + } + } + Text { + function cleanup(string) { + var t = string.replace("-", " ") + .replace("|", " ").replace(",", " ") + .replace(/\s\s+/g, "\n") + return t + } + + visible: icon.width != bg.width + text: cleanup(title) + font.family: defaultFontFamily + font.pixelSize: 18 + color: bg.state == "fallback" ? "white" : "black" + anchors { + top: icon.bottom + bottom: parent.bottom + left: parent.left + right: parent.right + leftMargin: 15 + rightMargin: 15 + bottomMargin: 15 + } + maximumLineCount: 3 + elide: Text.ElideRight + wrapMode: Text.Wrap + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + } + } + + Rectangle { + id: overlay + visible: opacity != 0.0 + anchors.fill: parent + color: iconOverlayColor + opacity: { + if (iconMouse.pressed) { + if (homeScreen.state != "edit") + return 0.1 + return 0.4 + } + if (homeScreen.state == "edit") + return 0.3 + return 0.0 + } + } + MouseArea { + id: iconMouse + anchors.fill: parent + onPressAndHold: { + if (homeScreen.state == "edit") { + homeScreen.state = "enabled" + return + } + homeScreen.state = "edit" + } + onClicked: { + if (homeScreen.state == "edit") { + homeScreen.state = "enabled" + return + } + navigation.load(url) + } + } + Rectangle { + enabled: homeScreen.state == "edit" + opacity: enabled ? 1.0 : 0.0 + width: image.sourceSize.width + height: image.sourceSize.height - 2 + radius: width / 2 + color: iconOverlayColor + anchors { + horizontalCenter: parent.right + verticalCenter: parent.top + } + Image { + id: image + opacity: { + if (deleteButton.pressed) + return 0.70 + return 1.0 + } + anchors { + top: parent.top + left: parent.left + } + source: "assets/icons/Btn_Delete.png" + MouseArea { + id: deleteButton + anchors.fill: parent + onClicked: { + mouse.accepted = true + remove(url, index) + } + } + } + Behavior on opacity { + NumberAnimation { duration: animationDuration } + } + } + } + } + Rectangle { + width: homeScreen.cellSize - homeScreen.padding / 2 - 10 + anchors { + left: parent.left + top: parent.top + bottom: parent.bottom + } + MouseArea { + enabled: homeScreen.state == "edit" + anchors.fill: parent + onClicked: homeScreen.state = "enabled" + } + color: "#09102b" + } + Rectangle { + width: homeScreen.cellSize - homeScreen.padding / 2 - 10 + anchors { + right: parent.right + top: parent.top + bottom: parent.bottom + } + MouseArea { + enabled: homeScreen.state == "edit" + anchors.fill: parent + onClicked: homeScreen.state = "enabled" + } + color: "#09102b" + } + Row { + id: pageIndicator + spacing: 20 + anchors { + bottomMargin: 40 + bottom: parent.bottom + horizontalCenter: parent.horizontalCenter + } + Repeater { + model: { + var c = gridView.count % gridViewPageItemCount + if (c > 0) + c = 1 + return Math.floor(gridView.count / gridViewPageItemCount) + c + } + delegate: Rectangle { + property bool active: index * gridView.page <= gridView.contentX && gridView.contentX < (index + 1) * gridView.page + width: 10 + height: width + radius: width / 2 + color: !active ? inactivePagerColor : uiColor + anchors.verticalCenter: parent.verticalCenter + MouseArea { + anchors.fill: parent + onClicked: gridView.contentX = index * gridView.page + } + } + } + } + + Rectangle { + id: messageBox + color: "white" + anchors.fill: parent + + Rectangle { + id: error + visible: messageBox.state != "empty" + height: childrenRect.height + anchors { + top: parent.top + left: parent.left + right: parent.right + topMargin: 50 + } + Image { + id: errorIcon + source: "assets/icons/Error_Icon.png" + anchors { + horizontalCenter: parent.horizontalCenter + top: parent.top + } + } + Text { + anchors { + topMargin: 30 + top: errorIcon.bottom + horizontalCenter: parent.horizontalCenter + } + font.family: defaultFontFamily + font.pixelSize: message.font.pixelSize + text: "Oops!..." + color: iconOverlayColor + } + } + + Text { + id: message + anchors { + top: error.bottom + horizontalCenter: parent.horizontalCenter + } + color: iconOverlayColor + font.family: defaultFontFamily + font.pixelSize: 28 + verticalAlignment: Text.AlignTop + horizontalAlignment: Text.AlignHCenter + } + + Rectangle { + color: parent.color + anchors { + top: message.bottom + bottom: parent.bottom + left: parent.left + right: parent.right + bottomMargin: 70 + } + UIButton { + color: uiColor + implicitWidth: 180 + implicitHeight: 70 + buttonText: "OK" + visible: messageBox.state != "empty" + anchors { + horizontalCenter: parent.horizontalCenter + bottom: parent.bottom + } + onClicked: { + if (messageBox.state == "tabsfull") { + homeScreen.state = "disabled" + tabView.viewState = "list" + return + } + if (messageBox.state == "full") { + messageBox.state = "disabled" + homeScreen.state = "edit" + return + } + } + } + } + + state: "disabled" + + states: [ + State { + name: "disabled" + PropertyChanges { + target: messageBox + visible: false + } + }, + State { + name: "empty" + PropertyChanges { + target: message + text: qsTr("No bookmarks have been saved so far.") + } + PropertyChanges { + target: messageBox + color: emptyBackgroundColor + visible: true + } + PropertyChanges { + target: error + anchors.topMargin: 30 + } + PropertyChanges { + target: navigation + state: "enabled" + } + }, + State { + name: "full" + PropertyChanges { + target: message + text: qsTr("24 bookmarks is the maximum limit.\nTo bookmark a new page you must delete a bookmark first.") + } + PropertyChanges { + target: messageBox + visible: true + } + PropertyChanges { + target: navigation + state: "enabled" + } + }, + State { + name: "tabsfull" + PropertyChanges { + target: message + text: qsTr("10 open tabs is the maximum limit.\nTo open a new tab you must close another one first.") + } + PropertyChanges { + target: messageBox + visible: true + } + PropertyChanges { + target: navigation + state: "enabled" + } + } + ] + } +} diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/Keyboard.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/Keyboard.qml new file mode 100644 index 0000000..13ab64e --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/Keyboard.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtBrowser project. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPLv2 included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.5 +import QtQuick.Enterprise.VirtualKeyboard 2.0 + +InputPanel { + id: inputPanel + property int windowHeight: 0 + property int animationDuration: 0 + + y: windowHeight + anchors { + left: parent.left + right: parent.right + } + states: State { + name: "visible" + when: Qt.inputMethod.visible + PropertyChanges { + target: inputPanel + y: windowHeight - inputPanel.height + } + } + transitions: Transition { + from: "" + to: "visible" + reversible: true + NumberAnimation { + properties: "y" + duration: animationDuration + easing.type: Easing.InOutQuad + } + } +} diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/Main.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/Main.qml new file mode 100644 index 0000000..3f01ecc --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/Main.qml @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtBrowser project. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPLv2 included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.5 + +Item { + BrowserWindow{ + id: root + anchors.fill: parent + Keyboard{ + id: inputPanel + windowHeight: root.height + animationDuration: root.animationDuration + } + } +} diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/MockTouchPoint.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/MockTouchPoint.qml new file mode 100644 index 0000000..f7fa1b1 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/MockTouchPoint.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtBrowser project. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPLv2 included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + id: mockTouchPoint + + property bool pressed: false + property int pointId: 0 + + Image { + source: "assets/icons/touchpoint.png" + x: -(width / 2) + y: -(height / 2) + height: parent.height + width: parent.width + opacity: parent.pressed ? 0.6 : 0.0 + + Behavior on opacity { + NumberAnimation { duration: 200 } + } + + Text { + text: mockTouchPoint.pointId + anchors.centerIn: parent + } + } +} diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/NavigationBar.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/NavigationBar.qml new file mode 100644 index 0000000..19efa0d --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/NavigationBar.qml @@ -0,0 +1,453 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtBrowser project. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPLv2 included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import QtQuick.Layouts 1.2 +import WebBrowser 1.0 + +import "assets" + +ToolBar { + id: root + + property alias addressBar: urlBar + property Item webView: null + + onWebViewChanged: { + + } + + visible: opacity != 0.0 + opacity: tabView.viewState == "page" ? 1.0 : 0.0 + + function load(url) { + if (url) + webView.url = url + homeScreen.state = "disabled" + } + + function refresh() { + if (urlBar.text == "") + bookmarksButton.bookmarked = false + else + bookmarksButton.bookmarked = homeScreen.contains(urlBar.text) !== -1 + } + + state: "enabled" + + style: ToolBarStyle { + background: Rectangle { + color: uiColor + implicitHeight: toolBarSize + 3 + } + padding { + left: 0 + right: 0 + top: 0 + bottom: 0 + } + } + + Behavior on y { + NumberAnimation { duration: animationDuration } + } + + states: [ + State { + name: "enabled" + PropertyChanges { + target: root + y: 0 + } + }, + State { + name: "tracking" + PropertyChanges { + target: root + y: { + var diff = touchReference - touchY + + if (velocityY > velocityThreshold) { + if (diff > 0) + return -root.height + else + return 0 + } + + if (!touchGesture || diff == 0) { + if (y < -root.height / 2) + return -root.height + else + return 0 + } + + if (diff > root.height) + return -root.height + + if (diff > 0) { + if (y == -root.height) + return -root.height + return -diff + } + + // diff < 0 + + if (y == 0) + return 0 + + diff = Math.abs(diff) + if (diff >= root.height) + return 0 + + return -root.height + diff + } + } + }, + State { + name: "disabled" + PropertyChanges { + target: root + y: -root.height + } + } + ] + + RowLayout { + height: toolBarSize + anchors { + top: parent.top + right: parent.right + left: parent.left + } + spacing: 0 + + UIButton { + id: backButton + source: "icons/Btn_Back.png" + color: uiColor + highlightColor: buttonPressedColor + onClicked: webView.goBack() + enabled: webView && webView.canGoBack + } + Rectangle { + width: 1 + anchors { + top: parent.top + bottom: parent.bottom + } + color: uiSeparatorColor + } + UIButton { + id: forwardButton + source: "icons/Btn_Forward.png" + color: uiColor + highlightColor: buttonPressedColor + onClicked: webView.goForward() + enabled: webView && webView.canGoForward + } + Rectangle { + width: 1 + anchors { + top: parent.top + bottom: parent.bottom + } + color: uiSeparatorColor + } + Rectangle { + Layout.fillWidth: true + implicitWidth: 10 + anchors { + top: parent.top + bottom: parent.bottom + } + color: uiColor + } + TextField { + id: urlBar + Layout.fillWidth: true + text: webView ? webView.url : "" + activeFocusOnPress: true + inputMethodHints: Qt.ImhUrlCharactersOnly | Qt.ImhNoPredictiveText | Qt.ImhNoAutoUppercase | Qt.ImhPreferLowercase + placeholderText: qsTr("Search or type a URL") + + onActiveFocusChanged: { + if (activeFocus) { + urlBar.selectAll() + root.state = "enabled" + homeScreen.state = "disabled" + urlDropDown.state = "enabled" + } else { + urlDropDown.state = "disabled" + root.state = "tracking" + } + } + + UIButton { + id: reloadButton + state: cancelButton.visible ? "edit" : "load" + states: [ + State { + name: "load" + PropertyChanges { + target: reloadButton + source: webView && webView.loading ? "icons/Btn_Clear.png" : "icons/Btn_Reload.png" + height: 54 + } + }, + State { + name: "edit" + PropertyChanges { + target: reloadButton + source: "icons/Btn_Clear.png" + height: 45 + visible: urlBar.text != "" + } + } + ] + height: 54 + width: height + color: "transparent" + highlightColor: "#eeeeee" + radius: width / 2 + anchors { + rightMargin: 1 + right: parent.right + verticalCenter: addressBar.verticalCenter; + } + onClicked: { + if (state == "load") { + webView.loading ? webView.stop() : webView.reload() + webView.forceActiveFocus() + return + } + urlBar.selectAll() + urlBar.remove(urlBar.selectionStart, urlBar.selectionEnd) + } + } + style: TextFieldStyle { + textColor: "white" + font.family: defaultFontFamily + font.pixelSize: 28 + selectionColor: uiHighlightColor + selectedTextColor: "white" + placeholderTextColor: placeholderColor + background: Rectangle { + implicitWidth: 514 + implicitHeight: 56 + border.color: textFieldStrokeColor + color: "#09102b" + border.width: 2 + } + padding { + left: 15 + right: reloadButton.width + } + } + onAccepted: { + webView.url = AppEngine.fromUserInput(text) + homeScreen.state = "disabled" + tabView.viewState = "page" + } + + onTextChanged: refresh() + onEditingFinished: { + selectAll() + webView.forceActiveFocus() + } + } + Rectangle { + visible: !cancelButton.visible + Layout.fillWidth: true + implicitWidth: 10 + anchors { + top: parent.top + bottom: parent.bottom + } + color: uiColor + } + + UIButton { + id: cancelButton + color: uiColor + visible: urlDropDown.state === "enabled" + highlightColor: buttonPressedColor + Text { + color: "white" + anchors.centerIn: parent + text: "Cancel" + font.family: defaultFontFamily + font.pixelSize: 28 + } + implicitWidth: 120 + onClicked: { + urlDropDown.state = "disabled" + webView.forceActiveFocus() + } + } + Rectangle { + width: 1 + anchors { + top: parent.top + bottom: parent.bottom + } + color: uiSeparatorColor + } + UIButton { + id: homeButton + source: "icons/Btn_Home.png" + color: uiColor + highlightColor: buttonPressedColor + onClicked: { + if (homeScreen.state == "disabled" || homeScreen.state == "edit") { + homeScreen.messageBox.state = "disabled" + homeScreen.state = "enabled" + homeScreen.forceActiveFocus() + } else if (homeScreen.state != "disabled") { + homeScreen.state = "disabled" + } + } + } + Rectangle { + width: 1 + anchors { + top: parent.top + bottom: parent.bottom + } + color: uiSeparatorColor + } + UIButton { + id: pageViewButton + source: "icons/Btn_Tabs.png" + color: uiColor + highlightColor: buttonPressedColor + onClicked: { + if (tabView.viewState == "list") { + tabView.viewState = "page" + } else { + tabView.get(tabView.currentIndex).item.webView.takeSnapshot() + homeScreen.state = "disabled" + tabView.viewState = "list" + } + } + Text { + anchors { + centerIn: parent + verticalCenterOffset: 4 + } + + text: tabView.count + font.family: defaultFontFamily + font.pixelSize: 16 + font.weight: Font.DemiBold + color: "white" + } + } + Rectangle { + width: 1 + anchors { + top: parent.top + bottom: parent.bottom + } + color: uiSeparatorColor + } + UIButton { + id: bookmarksButton + color: uiColor + highlightColor: buttonPressedColor + enabled: urlBar.text != "" && !settingsView.privateBrowsingEnabled + property bool bookmarked: false + source: bookmarked ? "icons/Btn_Bookmark_Checked.png" : "icons/Btn_Bookmarks.png" + onClicked: { + if (!webView) + return + var icon = webView.loading ? "" : webView.icon + var idx = homeScreen.contains(webView.url.toString()) + if (idx !== -1) { + homeScreen.remove("", idx) + return + } + var count = homeScreen.count + homeScreen.add(webView.title, webView.url, icon, AppEngine.fallbackColor()) + if (count < homeScreen.count) + bookmarked = true + } + Component.onCompleted: refresh() + } + Rectangle { + width: 1 + anchors { + top: parent.top + bottom: parent.bottom + } + color: uiSeparatorColor + } + UIButton { + id: settingsButton + source: "icons/Btn_Settings.png" + color: uiColor + highlightColor: buttonPressedColor + onClicked: { + settingsView.state = "enabled" + } + } + } + ProgressBar { + id: progressBar + height: 3 + anchors { + left: parent.left + bottom: parent.bottom + right: parent.right + leftMargin: -10 + rightMargin: -10 + } + style: ProgressBarStyle { + background: Rectangle { + height: 3 + color: emptyBackgroundColor + } + progress: Rectangle { + //color: settingsView.privateBrowsingEnabled ? "#46a2da" : "#317198" + color: "#41cd52" + } + } + minimumValue: 0 + maximumValue: 100 + value: (webView && webView.loadProgress < 100) ? webView.loadProgress : 0 + } +} diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/PageView.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/PageView.qml new file mode 100644 index 0000000..01445c6 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/PageView.qml @@ -0,0 +1,705 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtBrowser project. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPLv2 included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.5 +import QtWebEngine 1.1 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import QtQuick.Layouts 1.2 +import QtGraphicalEffects 1.0 + +import WebBrowser 1.0 +import "assets" + +Rectangle { + id: root + + property int itemWidth: browserWindow.width / 2 + property int itemHeight: browserWindow.height / 2 + + property bool interactive: true + + property alias currentIndex: pathView.currentIndex + property alias count: pathView.count + + property string viewState: "page" + + onViewStateChanged: { + if (viewState == "page" || viewState == "fullscreen") + homeScreen.state = "disabled" + } + + property QtObject otrProfile: WebEngineProfile { + offTheRecord: true + } + + property QtObject defaultProfile: WebEngineProfile { + storageName: "YABProfile" + offTheRecord: false + } + + Component { + id: tabComponent + Rectangle { + id: tabItem + property alias webView: webEngineView + property alias title: webEngineView.title + + property var image: QtObject { + property var snapshot: null + property string url: "about:blank" + } + + visible: opacity != 0.0 + + Behavior on opacity { + NumberAnimation { duration: animationDuration } + } + + anchors.fill: parent + + Action { + shortcut: "Ctrl+F" + onTriggered: { + findBar.visible = !findBar.visible + if (findBar.visible) { + findTextField.forceActiveFocus() + } + } + } + + FeaturePermissionBar { + id: permBar + view: webEngineView + anchors { + left: parent.left + right: parent.right + top: parent.top + } + z: 3 + } + + WebEngineView { + id: webEngineView + + anchors { + fill: parent + top: permBar.bottom + } + + profile: settingsView.privateBrowsingEnabled ? otrProfile : defaultProfile + enabled: root.interactive + + function takeSnapshot() { + if (webEngineView.url == "" || webEngineView.url == "about:blank") { + tabItem.image.url = "about:blank" + tabItem.image.snapshot = null + return + } + + if (tabItem.image.url == webEngineView.url || tabItem.opacity != 1.0) + return + + tabItem.image.url = webEngineView.url + webEngineView.grabToImage(function(result) { + tabItem.image.snapshot = result; + console.log("takeSnapshot("+result.url+")") + }); + } + + // Trigger a refresh to check if the new url is bookmarked. + onUrlChanged: navigation.refresh() + + + settings.autoLoadImages: settingsView.autoLoadImages + settings.javascriptEnabled: !settingsView.javaScriptDisabled + + // This should be enabled as we can switch to Qt 5.6 (i.e. import QtWebEngine 1.2) + // settings.pluginsEnabled: settingsView.pluginsEnabled + + onLoadingChanged: { + if (loading) + navigation.state = "enabled" + } + + onCertificateError: { + if (!acceptedCertificates.shouldAutoAccept(error)){ + error.defer() + sslDialog.enqueue(error) + } else{ + error.ignoreCertificateError() + } + } + + onNewViewRequested: { + webEngineView.takeSnapshot() + var tab + if (!request.userInitiated) { + print("Warning: Blocked a popup window.") + return + } + + tab = tabView.createEmptyTab() + + if (!tab) + return + + if (request.destination == WebEngineView.NewViewInTab) { + pathView.positionViewAtIndex(tabView.count - 1, PathView.Center) + request.openIn(tab.webView) + } else if (request.destination == WebEngineView.NewViewInBackgroundTab) { + var index = pathView.currentIndex + request.openIn(tab.webView) + pathView.positionViewAtIndex(index, PathView.Center) + } else if (request.destination == WebEngineView.NewViewInDialog) { + request.openIn(tab.webView) + } else { + request.openIn(tab.webView) + } + } + + onFeaturePermissionRequested: { + permBar.securityOrigin = securityOrigin; + permBar.requestedFeature = feature; + permBar.visible = true; + } + + onFullScreenRequested: { + if (request.toggleOn) + viewState = "fullscreen" + else + viewState = "page" + request.accept() + } + } + + Desaturate { + id: desaturate + visible: desaturation != 0.0 + anchors.fill: webEngineView + source: webEngineView + desaturation: root.interactive ? 0.0 : 1.0 + + Behavior on desaturation { + NumberAnimation { duration: animationDuration } + } + } + + FastBlur { + id: blur + visible: radius != 0.0 + anchors.fill: desaturate + source: desaturate + radius: desaturate.desaturation * 25 + } + + TouchTracker { + id: tracker + enabled: root.interactive + target: webEngineView + anchors.fill: parent + onTouchYChanged: browserWindow.touchY = tracker.touchY + onYVelocityChanged: browserWindow.velocityY = yVelocity + onTouchBegin: { + browserWindow.touchY = tracker.touchY + browserWindow.velocityY = yVelocity + browserWindow.touchReference = tracker.touchY + browserWindow.touchGesture = true + navigation.state = "tracking" + } + onTouchEnd: { + browserWindow.velocityY = yVelocity + browserWindow.touchGesture = false + navigation.state = "tracking" + } + onScrollDirectionChanged: { + browserWindow.velocityY = 0 + browserWindow.touchReference = tracker.touchY + } + } + + Rectangle { + opacity: { + if (inputPanel.state === "visible") + return 0.0 + if (webEngineView.url == "" || webEngineView.url == "about:blank") + return 1.0 + return 0.0 + } + anchors.fill: parent + visible: opacity != 0.0 + color: "#09102b" + Image { + id: placeholder + y: placeholder.height - navigation.y + anchors.horizontalCenter: parent.horizontalCenter + source: "assets/icons/AppLogoColor.png" + } + Text { + id: label + anchors { + top: placeholder.bottom + topMargin: 20 + horizontalCenter: placeholder.horizontalCenter + } + font.family: defaultFontFamily + font.pixelSize: 28 + color: "white" + text: "Qt WebBrowser" + } + + Behavior on opacity { + NumberAnimation { duration: animationDuration } + } + } + + Rectangle { + id: findBar + anchors { + right: webEngineView.right + left: webEngineView.left + top: webEngineView.top + } + height: toolBarSize / 2 + 10 + visible: false + color: uiColor + + RowLayout { + spacing: 0 + anchors.fill: parent + Rectangle { + width: 5 + anchors { + top: parent.top + bottom: parent.bottom + } + color: uiColor + } + TextField { + id: findTextField + Layout.fillWidth: true + onAccepted: { + webEngineView.findText(text) + } + style: TextFieldStyle { + textColor: "black" + font.family: defaultFontFamily + font.pixelSize: 28 + selectionColor: uiHighlightColor + selectedTextColor: "black" + placeholderTextColor: placeholderColor + background: Rectangle { + implicitWidth: 514 + implicitHeight: toolBarSize / 2 + border.color: textFieldStrokeColor + border.width: 1 + } + } + } + Rectangle { + width: 5 + anchors { + top: parent.top + bottom: parent.bottom + } + color: uiColor + } + Rectangle { + width: 1 + anchors { + top: parent.top + bottom: parent.bottom + } + color: uiSeparatorColor + } + UIButton { + id: findBackwardButton + iconSource: "assets/icons/Btn_Back.png" + implicitHeight: parent.height + onClicked: webEngineView.findText(findTextField.text, WebEngineView.FindBackward) + } + Rectangle { + width: 1 + anchors { + top: parent.top + bottom: parent.bottom + } + color: uiSeparatorColor + } + UIButton { + id: findForwardButton + iconSource: "assets/icons/Btn_Forward.png" + implicitHeight: parent.height + onClicked: webEngineView.findText(findTextField.text) + } + Rectangle { + width: 1 + anchors { + top: parent.top + bottom: parent.bottom + } + color: uiSeparatorColor + } + UIButton { + id: findCancelButton + iconSource: "assets/icons/Btn_Clear.png" + implicitHeight: parent.height + onClicked: findBar.visible = false + } + } + } + } + } + + ListModel { + id: listModel + } + + function makeCurrent(index) { + viewState = "list" + pathView.positionViewAtIndex(index, PathView.Center) + viewState = "page" + } + + function createEmptyTab() { + var tab = add(tabComponent) + return tab + } + + function add(component) { + if (listModel.count === tabViewMaxTabs) { + homeScreen.messageBox.state = "tabsfull" + homeScreen.state = "enabled" + homeScreen.forceActiveFocus() + return null + } + + var element = {"item": null } + element.item = component.createObject(root, { "width": root.width, "height": root.height, "opacity": 0.0 }) + + if (element.item == null) { + console.log("PageView::add(): Error creating object"); + return + } + + listModel.append(element) + return element.item + } + + function remove(index) { + pathView.interactive = false + pathView.currentItem.state = "" + pathView.currentItem.visible = false + listModel.remove(index) + pathView.decrementCurrentIndex() + pathView.interactive = true + } + + function get(index) { + return listModel.get(index) + } + + Component { + id: delegate + + Rectangle { + id: wrapper + + parent: item + + property real visibility: 0.0 + property bool isCurrentItem: PathView.isCurrentItem + + visible: PathView.onPath && visibility != 0.0 + state: isCurrentItem ? root.viewState : "list" + + Behavior on scale { + NumberAnimation { duration: animationDuration } + } + + states: [ + State { + name: "page" + PropertyChanges { target: wrapper; width: root.width; height: root.height; visibility: 0.0 } + PropertyChanges { target: pathView; interactive: false } + PropertyChanges { target: item; opacity: 1.0 } + PropertyChanges { target: navigation; state: "enabled" } + }, + State { + name: "list" + PropertyChanges { target: wrapper; width: itemWidth; height: itemHeight; visibility: 1.0 } + PropertyChanges { target: pathView; interactive: true } + PropertyChanges { target: item; opacity: 0.0 } + }, + State { + name: "fullscreen" + PropertyChanges { target: wrapper; width: root.width; height: root.height; visibility: 0.0 } + PropertyChanges { target: pathView; interactive: false } + PropertyChanges { target: item; opacity: 1.0 } + PropertyChanges { target: navigation; state: "disabled" } + } + ] + + transitions: Transition { + ParallelAnimation { + PropertyAnimation { property: "visibility"; duration: animationDuration; easing.type : Easing.InSine } + PropertyAnimation { properties: "x,y"; duration: animationDuration; easing.type: Easing.InSine } + PropertyAnimation { properties: "width,height"; duration: animationDuration; easing.type: Easing.InSine } + } + } + + width: itemWidth; height: itemHeight + scale: { + if (pathView.count == 1) + return 1.0 + if (pathView.count < 4) + return isCurrentItem ? 1.0 : 0.5 + + if (isCurrentItem) + return 1.0 + + var index1 = pathView.currentIndex - 2 + var index2 = pathView.currentIndex - 1 + var index4 = (pathView.currentIndex + 1) % pathView.count + var index5 = (pathView.currentIndex + 2) % pathView.count + + if (index1 < 0) + index1 = pathView.count + index1 + if (index2 < 0) + index2 = pathView.count + index2 + + switch (index) { + case index1 : + return 0.25 + case index2: + return 0.5 + case index4: + return 0.5 + case index5: + return 0.25 + } + + return 0.25 + } + z: PathView.itemZ + + MouseArea { + enabled: pathView.interactive + anchors.fill: wrapper + onClicked: { + mouse.accepted = true + if (index < 0) + return + + if (index == pathView.currentIndex) { + if (root.viewState == "list") + root.viewState = "page" + return + } + pathView.currentIndex = index + } + } + Rectangle { + id: shadow + visible: false + property real size: 24 + anchors { + top: parent.top + topMargin: 9 + horizontalCenter: parent.horizontalCenter + } + color: iconOverlayColor + radius: size / 2 + width: snapshot.width + height: snapshot.height + } + GaussianBlur { + anchors.fill: shadow + source: shadow + radius: shadow.size + samples: shadow.size * 2 + opacity: 0.3 + transparentBorder: true + visible: wrapper.visibility == 1.0 + } + + Rectangle { + id: snapshot + color: uiColor + + Image { + source: { + if (!item.image.snapshot) + return "assets/icons/about_blank.png" + return item.image.snapshot.url + } + anchors.fill: parent + Rectangle { + enabled: index == pathView.currentIndex && !pathView.moving && !pathView.flicking && wrapper.visibility == 1.0 + opacity: enabled ? 1.0 : 0.0 + visible: wrapper.visibility == 1.0 && listModel.count > 1 + width: image.sourceSize.width + height: image.sourceSize.height - 2 + radius: width / 2 + color: iconOverlayColor + anchors { + horizontalCenter: parent.right + verticalCenter: parent.top + } + Image { + id: image + opacity: { + if (closeButton.pressed) + return 0.70 + return 1.0 + } + anchors { + top: parent.top + left: parent.left + } + source: "assets/icons/Btn_Delete.png" + MouseArea { + id: closeButton + anchors.fill: parent + onClicked: { + mouse.accepted = true + remove(pathView.currentIndex) + } + } + } + Behavior on opacity { + NumberAnimation { duration: animationDuration / 2 } + } + } + } + anchors.fill: wrapper + } + + Text { + anchors { + topMargin: -25 + top: parent.top + horizontalCenter: parent.horizontalCenter + } + horizontalAlignment: Text.AlignHCenter + width: parent.width - image.width + elide: Text.ElideRight + text: item.title + font.pixelSize: 16 + font.family: defaultFontFamily + color: "white" + visible: wrapper.isCurrentItem && wrapper.visibility == 1.0 + } + } + } + + Rectangle { + color: "#09102b" + anchors.fill: parent + } + + PathView { + id: pathView + pathItemCount: 5 + anchors.fill: parent + model: listModel + delegate: delegate + highlightMoveDuration: animationDuration + highlightRangeMode: PathView.StrictlyEnforceRange + snapMode: PathView.SnapToItem + preferredHighlightBegin: 0.5 + preferredHighlightEnd: 0.5 + + dragMargin: itemHeight + + focus: pathView.interactive + + property real offset: 30 + + property real margin: { + if (count == 2) + return root.width / 4 - offset + if (count == 3) + return root.width / 8 + offset + if (count == 4) + return root.width / 8 - offset + + return offset + } + + property real middle: { + if (currentItem) + return (pathView.height / 2) - (currentItem.visibility * 50) + return (pathView.height / 2 - 50) + } + + path: Path { + startX: pathView.margin + startY: pathView.middle + + PathPercent { value: 0.0 } + PathAttribute { name: "itemZ"; value: 0 } + PathLine { + x: (pathView.width - itemWidth) / 2 + 106 + y: pathView.middle + } + PathPercent { value: 0.49 } + PathAttribute { name: "itemZ"; value: 6 } + + PathLine { relativeX: 0; relativeY: 0 } + + PathLine { + x: (pathView.width - itemWidth) / 2 + itemWidth - 106 + y: pathView.middle + } + PathPercent { value: 0.51 } + + PathLine { relativeX: 0; relativeY: 0 } + + PathAttribute { name: "itemZ"; value: 4 } + PathLine { + x: pathView.width - pathView.margin + y: pathView.middle + } + PathPercent { value: 1 } + PathAttribute { name: "itemZ"; value: 2 } + } + + Keys.onLeftPressed: decrementCurrentIndex() + Keys.onRightPressed: incrementCurrentIndex() + } +} diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/SettingsView.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/SettingsView.qml new file mode 100644 index 0000000..678b966 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/SettingsView.qml @@ -0,0 +1,195 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtBrowser project. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPLv2 included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.5 +import QtQuick.Layouts 1.0 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import Qt.labs.settings 1.0 + +import WebBrowser 1.0 + +Rectangle { + id: root + color: "#09102b" + property bool privateBrowsingEnabled: appSettings[0].active + property bool httpDiskCacheEnabled: appSettings[1].active + property bool autoLoadImages: appSettings[2].active + property bool javaScriptDisabled: appSettings[3].active + // property bool pluginsEnabled: appSettings[4].active + + property var appSettings: [ + { "name": "Private Browsing", "active": false, "notify": function(v) { privateBrowsingEnabled = v; } }, + { "name": "Enable HTTP Disk Cache", "active": true, "notify": function(v) { httpDiskCacheEnabled = v; } }, + { "name": "Auto Load Images", "active": true, "notify": function(v) { autoLoadImages = v; } }, + { "name": "Disable JavaScript", "active": false, "notify": function(v) { javaScriptDisabled = v; } }, +// { "name": "Enable Plugins", "active": false, "notify": function(v) { pluginsEnabled = v; } } + ] + + function save() { + for (var i = 0; i < appSettings.length; ++i) { + var setting = appSettings[i] + + listModel.get(i).active = setting.active + // Do not persist private browsing mode + if (setting.name === "Private Browsing") + continue + AppEngine.saveSetting(setting.name, setting.active) + } + } + + Rectangle{ + color: "#9d9faa" + height: 2 + anchors.top: root.top + anchors.right: root.right + anchors.left: root.left + z: 100 + } + + state: "disabled" + + states: [ + State { + name: "enabled" + AnchorChanges { + target: root + anchors.top: navigation.bottom + } + PropertyChanges { + target: settingsToolBar + opacity: 1.0 + } + }, + State { + name: "disabled" + AnchorChanges { + target: root + anchors.top: root.parent.bottom + } + PropertyChanges { + target: settingsToolBar + opacity: 0.0 + } + } + ] + + transitions: Transition { + AnchorAnimation { duration: animationDuration; easing.type : Easing.InSine } + } + + ListModel { + id: listModel + } + + ListView { + id: listView + leftMargin: 230 + rightMargin: leftMargin + anchors.fill: parent + model: listModel + delegate: Rectangle { + color: "transparent" + height: 100 + width: 560 + Text { + anchors.verticalCenter: parent.verticalCenter + font.family: defaultFontFamily + font.pixelSize: 28 + text: name + color: sw.enabled ? "white" : "#848895" + } + Rectangle { + anchors { + right: parent.right + verticalCenter: parent.verticalCenter + } + CustomSwitch { + id: sw + onCheckedChanged: { + var setting = appSettings[index] + setting.active = checked + setting.notify(checked) + } + enabled: { + var ok = appSettings[index].name.indexOf("Disk Cache") < 0 + return ok || !privateBrowsingEnabled + } + anchors.centerIn: parent + checked: { + if (enabled) + return active + return false + } + /*style: SwitchStyle { + handle: Rectangle { + width: 42 + height: 42 + radius: height / 2 + color: "white" + border.color: control.checked ? "#5caa14" : "#9b9b9b" + border.width: 1 + } + + groove: Rectangle { + implicitWidth: 72 + height: 42 + radius: height / 2 + border.color: control.checked ? "#5caa14" : "#9b9b9b" + color: control.checked ? "#5cff14" : "white" + border.width: 1 + } + }*/ + } + } + } + + Component.onCompleted: { + for (var i = 0; i < appSettings.length; ++i) { + var setting = appSettings[i] + var active = JSON.parse(AppEngine.restoreSetting(setting.name, setting.active)) + if (setting.active !== active) { + setting.active = active + setting.notify(active) + } + listModel.append(setting) + } + listView.forceLayout() + } + Component.onDestruction: root.save() + } +} diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/Utils.js b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/Utils.js new file mode 100644 index 0000000..88e2bbe --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/Utils.js @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtBrowser project. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPLv2 included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +. pragma library + +function quote(str, delimiter) { + // discuss at: http://phpjs.org/functions/preg_quote/ + // original by: booeyOH + // improved by: Ates Goral (http://magnetiq.com) + // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // improved by: Brett Zamir (http://brett-zamir.me) + // bugfixed by: Onno Marsman + // example 1: preg_quote("$40"); + // returns 1: '\\$40' + // example 2: preg_quote("*RRRING* Hello?"); + // returns 2: '\\*RRRING\\* Hello\\?' + // example 3: preg_quote("\\.+*?[^]$(){}=!<>|:"); + // returns 3: '\\\\\\.\\+\\*\\?\\[\\^\\]\\$\\(\\)\\{\\}\\=\\!\\<\\>\\|\\:' + + return String(str) + .replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + (delimiter || '') + '-]', 'g'), '\\$&'); +} + +function highlight( text, search ) +{ + return text.replace( new RegExp( "(" + quote( search ) + ")" , 'gi' ), "$1" ); +} diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/UIButton.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/UIButton.qml new file mode 100644 index 0000000..cc9351f --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/UIButton.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtBrowser project. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPLv2 included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import QtQuick.Layouts 1.2 + + +ToolButton { + id: root + implicitHeight: toolBarSize + implicitWidth: toolBarSize + + property alias buttonText: label.text + property alias textColor: label.color + property alias textSize: label.font.pixelSize + property string source: "" + property real radius: 0.0 + property string color: uiColor + property string highlightColor: buttonPressedColor + Text { + id: label + color: "white" + anchors.centerIn: parent + font.family: defaultFontFamily + font.pixelSize: 28 + } + style: ButtonStyle { + background: Rectangle { + opacity: root.enabled ? 1.0 : 0.3 + color: root.pressed || root.checked ? root.highlightColor : root.color + radius: root.radius + Image { + source: root.source + width: Math.min(sourceSize.width, root.width) + height: Math.min(sourceSize.height, root.height) + anchors.centerIn: parent + } + } + } +} + diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/UIToolBar.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/UIToolBar.qml new file mode 100644 index 0000000..39a0974 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/UIToolBar.qml @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtBrowser project. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPLv2 included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.5 +import QtQuick.Controls 1.0 +import QtQuick.Controls.Styles 1.0 +import QtQuick.Layouts 1.0 + +ToolBar { + id: root + + property alias title: titleBox.text + property alias source: toolBarButton.source + property alias indicator: indicatorText.text + + property int indicatorWidth: 40 + property int indicatorHeight: 32 + + signal optionClicked() + signal doneClicked() + + height: navigation.height + + style: ToolBarStyle { + background: Rectangle { + color: toolBarFillColor + } + padding { + left: 0 + right: 0 + top: 0 + bottom: 0 + } + } + + RowLayout { + spacing: 0 + height: toolBarSize + anchors.fill: parent + Rectangle { + width: childrenRect.width + anchors { + left: parent.left + top: parent.top + bottom: parent.bottom + } + color: toolBarFillColor + Text { + id: titleBox + visible: root.title !== "" + anchors { + leftMargin: visible ? 30 : 0 + left: parent.left + verticalCenter: parent.verticalCenter + } + color: "white" + font.pixelSize: 28 + font.family: defaultFontFamily + } + Rectangle { + visible: toolBarButton.visible && titleBox.visible + width: 1 + anchors { + top: parent.top + bottom: parent.bottom + } + color: toolBarSeparatorColor + } + UIButton { + id: toolBarButton + visible: root.source !== "" + color: toolBarFillColor + Component.onCompleted: toolBarButton.clicked.connect(root.optionClicked) + anchors.left: titleBox.right + } + } + Rectangle { + visible: toolBarButton.visible + width: 1 + anchors { + top: parent.top + bottom: parent.bottom + } + color: toolBarSeparatorColor + } + Rectangle { + width: indicatorWidth + anchors { + top: parent.top + bottom: parent.bottom + } + color: toolBarFillColor + } + Rectangle { + color: toolBarFillColor + Layout.fillWidth: true + anchors { + top: parent.top + bottom: parent.bottom + } + Rectangle { + visible: root.indicator !== "" + color: "transparent" + border.color: "white" + border.width: 2 + width: indicatorWidth + height: indicatorHeight + anchors.centerIn: parent + Text { + id: indicatorText + anchors.centerIn: parent + color: "white" + font.family: defaultFontFamily + font.pixelSize: 20 + } + } + } + Rectangle { + width: 1 + anchors { + top: parent.top + bottom: parent.bottom + } + color: toolBarSeparatorColor + } + UIButton { + id: doneButton + color: toolBarFillColor + buttonText: "Done" + implicitWidth: 120 + Component.onCompleted: doneButton.clicked.connect(root.doneClicked) + } + } +} diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/AppLogoColor.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/AppLogoColor.png new file mode 100644 index 0000000..2a49717 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/AppLogoColor.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/AppLogoGrey.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/AppLogoGrey.png new file mode 100644 index 0000000..b2baae5 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/AppLogoGrey.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Add.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Add.png new file mode 100644 index 0000000..3c45c42 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Add.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Back.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Back.png new file mode 100644 index 0000000..562c9f6 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Back.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmark_Checked.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmark_Checked.png new file mode 100644 index 0000000..a6dbe6a Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmark_Checked.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmark_Indicator.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmark_Indicator.png new file mode 100644 index 0000000..a8b8b6b Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmark_Indicator.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmarks.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmarks.png new file mode 100644 index 0000000..fc286cc Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmarks.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Clear.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Clear.png new file mode 100644 index 0000000..1c9870a Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Clear.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Delete.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Delete.png new file mode 100644 index 0000000..2010838 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Delete.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Forward.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Forward.png new file mode 100644 index 0000000..e4c96f8 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Forward.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Home.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Home.png new file mode 100644 index 0000000..7358a59 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Home.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Reload.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Reload.png new file mode 100644 index 0000000..cff41cd Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Reload.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Search.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Search.png new file mode 100644 index 0000000..a6ef383 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Search.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Settings.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Settings.png new file mode 100644 index 0000000..33d7400 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Settings.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Tabs.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Tabs.png new file mode 100644 index 0000000..c007408 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Tabs.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Up.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Up.png new file mode 100644 index 0000000..f70a78d Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Up.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Error_Icon.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Error_Icon.png new file mode 100644 index 0000000..cf40696 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Error_Icon.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/LightWebBrowser_Icons.svg b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/LightWebBrowser_Icons.svg new file mode 100644 index 0000000..fce4b40 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/LightWebBrowser_Icons.svg @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/about_blank.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/about_blank.png new file mode 100644 index 0000000..6901b0b Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/about_blank.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/qt.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/qt.png new file mode 100644 index 0000000..6a22d2e Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/qt.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/touchpoint.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/touchpoint.png new file mode 100644 index 0000000..7649ee9 Binary files /dev/null and b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/touchpoint.png differ diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/resources.qrc b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/resources.qrc new file mode 100644 index 0000000..451a67f --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/resources.qrc @@ -0,0 +1,37 @@ + + + qml/BrowserWindow.qml + qml/FeaturePermissionBar.qml + qml/MockTouchPoint.qml + qml/PageView.qml + qml/NavigationBar.qml + qml/HomeScreen.qml + qml/SettingsView.qml + qml/assets/UIButton.qml + qml/assets/UIToolBar.qml + qml/Utils.js + qml/assets/icons/Btn_Home.png + qml/assets/icons/Btn_Tabs.png + qml/assets/icons/Btn_Forward.png + qml/assets/icons/Btn_Back.png + qml/assets/icons/Btn_Reload.png + qml/assets/icons/Btn_Clear.png + qml/assets/icons/touchpoint.png + qml/assets/icons/Btn_Delete.png + qml/assets/icons/Btn_Bookmarks.png + qml/assets/icons/Btn_Bookmark_Checked.png + qml/assets/icons/Btn_Bookmark_Indicator.png + qml/assets/icons/Btn_Settings.png + qml/assets/icons/about_blank.png + qml/assets/icons/Btn_Add.png + qml/assets/icons/Btn_Up.png + qml/assets/icons/Btn_Search.png + qml/assets/icons/Error_Icon.png + qml/assets/icons/qt.png + qml/assets/icons/AppLogoColor.png + qml/assets/icons/AppLogoGrey.png + qml/Keyboard.qml + qml/Main.qml + qml/CustomSwitch.qml + + diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/src.pro b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/src.pro new file mode 100644 index 0000000..79e4bdc --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/src.pro @@ -0,0 +1,43 @@ +TARGET = qtwebbrowser + +CONFIG += c++11 +CONFIG -= app_bundle + +SOURCES = \ + appengine.cpp \ + main.cpp \ + navigationhistoryproxymodel.cpp \ + touchtracker.cpp + +HEADERS = \ + appengine.h \ + navigationhistoryproxymodel.h \ + touchtracker.h \ + +OTHER_FILES = \ + qml/assets/UIButton.qml \ + qml/assets/UIToolBar.qml \ + qml/ApplicationRoot.qml \ + qml/BrowserWindow.qml \ + qml/FeaturePermissionBar.qml \ + qml/MockTouchPoint.qml \ + qml/PageView.qml \ + qml/NavigationBar.qml \ + qml/HomeScreen.qml \ + qml/SettingsView.qml \ + qml/Keyboard.qml \ + qml/Window.qml + +QT += qml quick webengine + +RESOURCES += resources.qrc + +!cross_compile { + DEFINES += DESKTOP_BUILD + SOURCES += touchmockingapplication.cpp + HEADERS += touchmockingapplication.h + QT += gui-private +} else { + target.path =/data/user/qt/qtwebbrowser-app + INSTALLS += target +} diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchmockingapplication.cpp b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchmockingapplication.cpp new file mode 100644 index 0000000..256c45e --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchmockingapplication.cpp @@ -0,0 +1,282 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtBrowser project. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPLv2 included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "touchmockingapplication.h" +#include "appengine.h" + +#include +#include +#include +#include +#include +#include +#include + +using namespace utils; + +static inline QRectF touchRectForPosition(QPointF centerPoint) +{ + QRectF touchRect(0, 0, 40, 40); + touchRect.moveCenter(centerPoint); + return touchRect; +} + +TouchMockingApplication::TouchMockingApplication(int& argc, char** argv) + : QGuiApplication(argc, argv) + , m_realTouchEventReceived(false) + , m_pendingFakeTouchEventCount(0) + , m_holdingControl(false) +{ +} + +bool TouchMockingApplication::notify(QObject* target, QEvent* event) +{ + // We try to be smart, if we received real touch event, we are probably on a device + // with touch screen, and we should not have touch mocking. + + if (!event->spontaneous() || m_realTouchEventReceived) + return QGuiApplication::notify(target, event); + + if (isTouchEvent(event)) { + if (m_pendingFakeTouchEventCount) + --m_pendingFakeTouchEventCount; + else + m_realTouchEventReceived = true; + return QGuiApplication::notify(target, event); + } + + QQuickView* window = qobject_cast(target); + if (!window) + return QGuiApplication::notify(target, event); + + m_holdingControl = QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier); + + if (event->type() == QEvent::KeyRelease && static_cast(event)->key() == Qt::Key_Control) { + foreach (int id, m_heldTouchPoints) + if (m_touchPoints.contains(id) && !QGuiApplication::mouseButtons().testFlag(Qt::MouseButton(id))) { + m_touchPoints[id].setState(Qt::TouchPointReleased); + m_heldTouchPoints.remove(id); + } else + m_touchPoints[id].setState(Qt::TouchPointStationary); + + sendTouchEvent(window, m_heldTouchPoints.isEmpty() ? QEvent::TouchEnd : QEvent::TouchUpdate, static_cast(event)->timestamp()); + } + + if (isMouseEvent(event)) { + const QMouseEvent* const mouseEvent = static_cast(event); + + QTouchEvent::TouchPoint touchPoint; + touchPoint.setPressure(1); + + QEvent::Type touchType = QEvent::None; + + switch (mouseEvent->type()) { + case QEvent::MouseButtonPress: + touchPoint.setId(mouseEvent->button()); + if (m_touchPoints.contains(touchPoint.id())) { + touchPoint.setState(Qt::TouchPointMoved); + touchType = QEvent::TouchUpdate; + } else { + touchPoint.setState(Qt::TouchPointPressed); + // Check if more buttons are held down than just the event triggering one. + if (mouseEvent->buttons() > mouseEvent->button()) + touchType = QEvent::TouchUpdate; + else + touchType = QEvent::TouchBegin; + } + break; + case QEvent::MouseMove: + if (!mouseEvent->buttons()) { + // We have to swallow the event instead of propagating it, + // since we avoid sending the mouse release events and if the + // Flickable is the mouse grabber it would receive the event + // and would move the content. + event->accept(); + return true; + } + touchType = QEvent::TouchUpdate; + touchPoint.setId(mouseEvent->buttons()); + touchPoint.setState(Qt::TouchPointMoved); + break; + case QEvent::MouseButtonRelease: + // Check if any buttons are still held down after this event. + if (mouseEvent->buttons()) + touchType = QEvent::TouchUpdate; + else + touchType = QEvent::TouchEnd; + touchPoint.setId(mouseEvent->button()); + touchPoint.setState(Qt::TouchPointReleased); + break; + case QEvent::MouseButtonDblClick: + // Eat double-clicks, their accompanying press event is all we need. + event->accept(); + return true; + default: + Q_ASSERT_X(false, "multi-touch mocking", "unhandled event type"); + } + + // A move can have resulted in multiple buttons, so we need check them individually. + if (touchPoint.id() & Qt::LeftButton) + updateTouchPoint(mouseEvent, touchPoint, Qt::LeftButton); + if (touchPoint.id() & Qt::MidButton) + updateTouchPoint(mouseEvent, touchPoint, Qt::MidButton); + if (touchPoint.id() & Qt::RightButton) + updateTouchPoint(mouseEvent, touchPoint, Qt::RightButton); + + if (m_holdingControl && touchPoint.state() == Qt::TouchPointReleased) { + // We avoid sending the release event because the Flickable is + // listening to mouse events and would start a bounce-back + // animation if it received a mouse release. + event->accept(); + return true; + } + + // Update states for all other touch-points + for (QHash::iterator it = m_touchPoints.begin(), end = m_touchPoints.end(); it != end; ++it) { + if (!(it.value().id() & touchPoint.id())) + it.value().setState(Qt::TouchPointStationary); + } + + Q_ASSERT(touchType != QEvent::None); + + if (!sendTouchEvent(window, touchType, mouseEvent->timestamp())) + return QGuiApplication::notify(target, event); + + event->accept(); + return true; + } + + return QGuiApplication::notify(target, event); +} + +void TouchMockingApplication::updateTouchPoint(const QMouseEvent* mouseEvent, QTouchEvent::TouchPoint touchPoint, Qt::MouseButton mouseButton) +{ + // Ignore inserting additional touch points if Ctrl isn't held because it produces + // inconsistent touch events and results in assers in the gesture recognizers. + if (!m_holdingControl && m_touchPoints.size() && !m_touchPoints.contains(mouseButton)) + return; + + if (m_holdingControl && touchPoint.state() == Qt::TouchPointReleased) { + m_heldTouchPoints.insert(mouseButton); + return; + } + + // Gesture recognition uses the screen position for the initial threshold + // but since the canvas translates touch events we actually need to pass + // the screen position as the scene position to deliver the appropriate + // coordinates to the target. + touchPoint.setRect(touchRectForPosition(mouseEvent->localPos())); + touchPoint.setSceneRect(touchRectForPosition(mouseEvent->screenPos())); + + if (touchPoint.state() == Qt::TouchPointPressed) + touchPoint.setStartScenePos(mouseEvent->screenPos()); + else { + const QTouchEvent::TouchPoint& oldTouchPoint = m_touchPoints[mouseButton]; + touchPoint.setStartScenePos(oldTouchPoint.startScenePos()); + touchPoint.setLastPos(oldTouchPoint.pos()); + touchPoint.setLastScenePos(oldTouchPoint.scenePos()); + } + + // Update current touch-point. + touchPoint.setId(mouseButton); + m_touchPoints.insert(mouseButton, touchPoint); +} + +bool TouchMockingApplication::sendTouchEvent(QQuickView* window, QEvent::Type type, ulong timestamp) +{ + static QTouchDevice* device = 0; + if (!device) { + device = new QTouchDevice; + device->setType(QTouchDevice::TouchScreen); + QWindowSystemInterface::registerTouchDevice(device); + } + + m_pendingFakeTouchEventCount++; + + const QList& currentTouchPoints = m_touchPoints.values(); + Qt::TouchPointStates touchPointStates = 0; + foreach (const QTouchEvent::TouchPoint& touchPoint, currentTouchPoints) + touchPointStates |= touchPoint.state(); + + QTouchEvent event(type, device, Qt::NoModifier, touchPointStates, currentTouchPoints); + event.setTimestamp(timestamp); + event.setAccepted(false); + + QGuiApplication::notify(window, &event); + + updateVisualMockTouchPoints(window,m_holdingControl ? currentTouchPoints : QList()); + + // Get rid of touch-points that are no longer valid + foreach (const QTouchEvent::TouchPoint& touchPoint, currentTouchPoints) { + if (touchPoint.state() == Qt::TouchPointReleased) + m_touchPoints.remove(touchPoint.id()); + } + + return event.isAccepted(); +} + +void TouchMockingApplication::updateVisualMockTouchPoints(QQuickView* window,const QList& touchPoints) +{ + if (touchPoints.isEmpty()) { + // Hide all touch indicator items. + foreach (QQuickItem* item, m_activeMockComponents.values()) + item->setProperty("pressed", false); + + return; + } + + foreach (const QTouchEvent::TouchPoint& touchPoint, touchPoints) { + QQuickItem* mockTouchPointItem = m_activeMockComponents.value(touchPoint.id()); + + if (!mockTouchPointItem) { + QQmlComponent touchMockPointComponent(window->engine(), QUrl("qrc:///qml/MockTouchPoint.qml")); + mockTouchPointItem = qobject_cast(touchMockPointComponent.create()); + Q_ASSERT(mockTouchPointItem); + m_activeMockComponents.insert(touchPoint.id(), mockTouchPointItem); + mockTouchPointItem->setProperty("pointId", QVariant(touchPoint.id())); + mockTouchPointItem->setParent(window->rootObject()); + mockTouchPointItem->setParentItem(window->rootObject()); + } + + QRectF touchRect = touchPoint.rect(); + mockTouchPointItem->setX(touchRect.center().x()); + mockTouchPointItem->setY(touchRect.center().y()); + mockTouchPointItem->setWidth(touchRect.width()); + mockTouchPointItem->setHeight(touchRect.height()); + mockTouchPointItem->setProperty("pressed", QVariant(touchPoint.state() != Qt::TouchPointReleased)); + } +} diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchmockingapplication.h b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchmockingapplication.h new file mode 100644 index 0000000..88c5e20 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchmockingapplication.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtBrowser project. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPLv2 included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TOUCHMOCKINGAPPLICATION_H +#define TOUCHMOCKINGAPPLICATION_H + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QQuickView; +class QQuickItem; +QT_END_NAMESPACE + +class TouchMockingApplication : public QGuiApplication +{ + Q_OBJECT + +public: + TouchMockingApplication(int &argc, char **argv); + + virtual bool notify(QObject *, QEvent *) override; + +private: + void updateTouchPoint(const QMouseEvent *, QTouchEvent::TouchPoint, Qt::MouseButton); + bool sendTouchEvent(QQuickView *, QEvent::Type, ulong timestamp); + void updateVisualMockTouchPoints(QQuickView *,const QList &touchPoints); + +private: + bool m_realTouchEventReceived; + int m_pendingFakeTouchEventCount; + + QPointF m_lastPos; + QPointF m_lastScreenPos; + QPointF m_startScreenPos; + + QHash m_touchPoints; + QSet m_heldTouchPoints; + QHash m_activeMockComponents; + + bool m_holdingControl; +}; + +#endif // TOUCHMOCKINGAPPLICATION_H diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchtracker.cpp b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchtracker.cpp new file mode 100644 index 0000000..52a028a --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchtracker.cpp @@ -0,0 +1,169 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtBrowser project. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPLv2 included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "touchtracker.h" +#include "appengine.h" + +#include + +using namespace utils; + +TouchTracker::TouchTracker(QQuickItem *parent) + : QQuickItem(parent) + , m_blockEvents(false) + , m_diff(0) + , m_previousY(0) + , m_target(0) + , m_delegate(0) +{ + m_startPoint.ts = 0; + m_currentPoint.ts = 0; +} + +QQuickItem *TouchTracker::target() const +{ + return m_target; +} + +void TouchTracker::setTarget(QQuickItem * target) +{ + m_target = target; + emit targetChanged(); +} + +int TouchTracker::xVelocity() const +{ + qreal pos = qAbs(m_startPoint.x() - m_currentPoint.x()); + qreal time = qAbs(m_startPoint.ts - m_currentPoint.ts); + return pos / time * 1000; +} + +int TouchTracker::yVelocity() const +{ + qreal pos = qAbs(m_startPoint.y() - m_currentPoint.y()); + qreal time = qAbs(m_startPoint.ts - m_currentPoint.ts); + return pos / time * 1000; +} + + +qreal TouchTracker::touchX() const +{ + return m_currentPoint.x(); +} + +qreal TouchTracker::touchY() const +{ + return m_currentPoint.y(); +} + +bool TouchTracker::blockEvents() const +{ + return m_blockEvents; +} + +void TouchTracker::setBlockEvents(bool shouldBlock) +{ + if (m_blockEvents == shouldBlock) + return; + m_blockEvents = shouldBlock; + emit blockEventsChanged(); +} + +bool TouchTracker::eventFilter(QObject *obj, QEvent *event) +{ + if (obj != m_delegate) + return QQuickItem::eventFilter(obj, event); + + if (event->type() == QEvent::Wheel) + return m_blockEvents; + + if (!isTouchEvent(event)) + return QQuickItem::eventFilter(obj, event); + + const QTouchEvent *touch = static_cast(event); + const QList &points = touch->touchPoints(); + m_previousY = m_currentPoint.y(); + m_currentPoint.pos = m_target->mapToScene(points.at(0).pos()); + m_currentPoint.ts = QDateTime::currentMSecsSinceEpoch(); + int currentDiff = m_previousY - m_currentPoint.y(); + + if ((currentDiff > 0 && m_diff < 0) || (currentDiff < 0 && m_diff > 0)) + emit scrollDirectionChanged(); + + m_diff = currentDiff; + + emit touchChanged(); + emit velocityChanged(); + + if (event->type() == QEvent::TouchEnd) + emit touchEnd(); + + return m_blockEvents; +} + +void TouchTracker::touchEvent(QTouchEvent * event) +{ + if (!m_target) { + if (!m_blockEvents) + QQuickItem::touchEvent(event); + + return; + } + + event->setAccepted(false); + + const QList &points = event->touchPoints(); + m_currentPoint.pos = m_target->mapToScene(points.at(0).pos()); + m_currentPoint.ts = QDateTime::currentMSecsSinceEpoch(); + + if (event->type() == QEvent::TouchBegin) { + m_startPoint = m_currentPoint; + emit touchBegin(); + } + + emit touchChanged(); + + // We have to find the delegate to be able to filter + // events from the WebEngineView. + // This is a hack and should preferably be made easier + // with the API in some way. + QQuickItem *child = m_target->childAt(m_currentPoint.x(), m_currentPoint.y()); + if (child && m_delegate != child) { + child->installEventFilter(this); + m_delegate = child; + } +} diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchtracker.h b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchtracker.h new file mode 100644 index 0000000..3aaecd2 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchtracker.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtBrowser project. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPLv2 included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TOUCHTRACKER_H +#define TOUCHTRACKER_H + +#include +#include + +class TouchTracker : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(qreal touchX READ touchX NOTIFY touchChanged) + Q_PROPERTY(qreal touchY READ touchY NOTIFY touchChanged) + Q_PROPERTY(int xVelocity READ xVelocity NOTIFY velocityChanged) + Q_PROPERTY(int yVelocity READ yVelocity NOTIFY velocityChanged) + Q_PROPERTY(bool blockEvents READ blockEvents WRITE setBlockEvents NOTIFY blockEventsChanged) + Q_PROPERTY(QQuickItem* target READ target WRITE setTarget NOTIFY targetChanged) + + struct PositionInfo + { + QPointF pos; + qint64 ts; + qreal x() const { return pos.x(); } + qreal y() const { return pos.y(); } + }; + +public: + TouchTracker(QQuickItem *parent = 0); + + qreal touchX() const; + qreal touchY() const; + int xVelocity() const; + int yVelocity() const; + QQuickItem* target() const; + bool blockEvents() const; + void setBlockEvents(bool shouldBlock); + void setTarget(QQuickItem * target); + +signals: + void touchChanged(); + void blockEventsChanged(); + void targetChanged(); + void touchBegin(); + void touchEnd(); + void velocityChanged(); + void scrollDirectionChanged(); + +protected: + bool eventFilter(QObject *obj, QEvent *event); + void touchEvent(QTouchEvent *event) override; + +private: + bool m_blockEvents; + int m_diff; + int m_previousY; + PositionInfo m_startPoint; + PositionInfo m_currentPoint; + QQuickItem *m_target; + QQuickItem *m_delegate; +}; + +#endif // TOUCHTRACKER_H -- cgit v1.2.3 From da6035233fc3bcfbc4a3d65075ee4099349c09d0 Mon Sep 17 00:00:00 2001 From: Juho Annunen Date: Mon, 23 Apr 2018 15:17:33 +0300 Subject: Move common definitions to shared settings Task-number: QTBUG-65302 Change-Id: I2153e2f2b4aa295e87098256354ed034480294df Reviewed-by: Teemu Holappa --- basicsuite/enterprise-charts/View1.qml | 11 ++-- basicsuite/enterprise-charts/View10.qml | 7 +-- basicsuite/enterprise-charts/View11.qml | 7 +-- basicsuite/enterprise-charts/View12.qml | 15 +++--- basicsuite/enterprise-charts/View2.qml | 3 +- basicsuite/enterprise-charts/View3.qml | 3 +- basicsuite/enterprise-charts/View4.qml | 9 ++-- basicsuite/enterprise-charts/View5.qml | 5 +- basicsuite/enterprise-charts/View6.qml | 7 +-- basicsuite/enterprise-charts/View7.qml | 7 +-- basicsuite/enterprise-charts/View8.qml | 7 +-- basicsuite/enterprise-charts/View9.qml | 7 +-- basicsuite/enterprise-charts/enterprise-charts.pro | 3 +- basicsuite/enterprise-charts/main.qml | 3 +- basicsuite/graphicaleffects/graphicaleffects.pro | 3 +- basicsuite/graphicaleffects/main.qml | 9 ++-- basicsuite/mediaplayer/ControlBar.qml | 3 +- basicsuite/mediaplayer/EffectSelectionPanel.qml | 3 +- basicsuite/mediaplayer/FileBrowser.qml | 5 +- basicsuite/mediaplayer/MetadataView.qml | 3 +- basicsuite/mediaplayer/ParameterPanel.qml | 3 +- basicsuite/mediaplayer/PlayerSlider.qml | 5 +- basicsuite/mediaplayer/UrlBar.qml | 3 +- basicsuite/mediaplayer/main.qml | 1 + basicsuite/mediaplayer/mediaplayer.pro | 3 +- .../tqtc-qtwebbrowser/src/qml/BrowserWindow.qml | 8 +-- .../tqtc-qtwebbrowser/src/qml/CustomSwitch.qml | 7 +-- .../tqtc-qtwebbrowser/src/qml/SettingsView.qml | 2 +- basicsuite/shared/SharedMain.qml | 9 ---- basicsuite/shared/settings.js | 60 ++++++++++++++++++++++ basicsuite/shared/settings.qrc | 5 ++ basicsuite/shared/shared.pri | 2 +- 32 files changed, 152 insertions(+), 76 deletions(-) create mode 100644 basicsuite/shared/settings.js create mode 100644 basicsuite/shared/settings.qrc diff --git a/basicsuite/enterprise-charts/View1.qml b/basicsuite/enterprise-charts/View1.qml index f85a18e..e8c3407 100644 --- a/basicsuite/enterprise-charts/View1.qml +++ b/basicsuite/enterprise-charts/View1.qml @@ -52,6 +52,7 @@ import QtQuick 2.0 //![2] import QtCharts 2.0 +import "settings.js" as Settings Item { anchors.fill: parent @@ -65,11 +66,11 @@ Item { anchors.fill: parent PieSeries { id: pieSeries - PieSlice { label: "Volkswagen"; value: 13.5; color: defaultGreen } - PieSlice { label: "Toyota"; value: 10.9; color: mediumGreen } - PieSlice { label: "Ford"; value: 8.6; color: darkGreen } - PieSlice { label: "Skoda"; value: 8.2; color: defaultGrey } - PieSlice { label: "Volvo"; value: 6.8; color: secondaryGrey } + PieSlice { label: "Volkswagen"; value: 13.5; color: Settings.primaryGreen } + PieSlice { label: "Toyota"; value: 10.9; color: Settings.mediumGreen } + PieSlice { label: "Ford"; value: 8.6; color: Settings.darkGreen } + PieSlice { label: "Skoda"; value: 8.2; color: Settings.primaryGrey } + PieSlice { label: "Volvo"; value: 6.8; color: Settings.secondaryGrey } } } diff --git a/basicsuite/enterprise-charts/View10.qml b/basicsuite/enterprise-charts/View10.qml index 79ca4ab..6bb3eb5 100644 --- a/basicsuite/enterprise-charts/View10.qml +++ b/basicsuite/enterprise-charts/View10.qml @@ -50,6 +50,7 @@ import QtQuick 2.0 import QtCharts 2.0 +import "settings.js" as Settings Item { anchors.fill: parent @@ -60,9 +61,9 @@ Item { HorizontalStackedBarSeries { axisY: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] } - BarSet { label: "Bob"; color: defaultGreen; values: [2, 2, 3, 4, 5, 6] } - BarSet { label: "Susan"; color: defaultGrey; values: [5, 1, 2, 4, 1, 7] } - BarSet { label: "James"; color: secondaryGrey; values: [3, 5, 8, 13, 5, 8] } + BarSet { label: "Bob"; color: Settings.primaryGreen; values: [2, 2, 3, 4, 5, 6] } + BarSet { label: "Susan"; color: Settings.primaryGrey; values: [5, 1, 2, 4, 1, 7] } + BarSet { label: "James"; color: Settings.secondaryGrey; values: [3, 5, 8, 13, 5, 8] } } Component.onCompleted: { axes[0].labelsColor = "white"; diff --git a/basicsuite/enterprise-charts/View11.qml b/basicsuite/enterprise-charts/View11.qml index dd81733..c884627 100644 --- a/basicsuite/enterprise-charts/View11.qml +++ b/basicsuite/enterprise-charts/View11.qml @@ -50,6 +50,7 @@ import QtQuick 2.0 import QtCharts 2.0 +import "settings.js" as Settings Item { anchors.fill: parent @@ -60,9 +61,9 @@ Item { HorizontalPercentBarSeries { axisY: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] } - BarSet { label: "Bob"; color: defaultGreen; values: [2, 2, 3, 4, 5, 6] } - BarSet { label: "Susan"; color: defaultGrey; values: [5, 1, 2, 4, 1, 7] } - BarSet { label: "James"; color: secondaryGrey; values: [3, 5, 8, 13, 5, 8] } + BarSet { label: "Bob"; color: Settings.primaryGreen; values: [2, 2, 3, 4, 5, 6] } + BarSet { label: "Susan"; color: Settings.primaryGrey; values: [5, 1, 2, 4, 1, 7] } + BarSet { label: "James"; color: Settings.secondaryGrey; values: [3, 5, 8, 13, 5, 8] } } Component.onCompleted: { diff --git a/basicsuite/enterprise-charts/View12.qml b/basicsuite/enterprise-charts/View12.qml index 588ec4b..90cfa8e 100644 --- a/basicsuite/enterprise-charts/View12.qml +++ b/basicsuite/enterprise-charts/View12.qml @@ -50,6 +50,7 @@ import QtQuick 2.0 import QtCharts 2.0 +import "settings.js" as Settings Item { anchors.fill: parent @@ -64,8 +65,8 @@ Item { size: 0.96 holeSize: 0.7 - PieSlice { id: slice; label: "Alpha"; value: 19511; color: defaultGreen; borderColor: "#163430" } - PieSlice { label: "Epsilon"; value: 11105; color: defaultGrey; borderColor: "#3B391C" } + PieSlice { id: slice; label: "Alpha"; value: 19511; color: Settings.primaryGreen; borderColor: "#163430" } + PieSlice { label: "Epsilon"; value: 11105; color: Settings.primaryGrey; borderColor: "#3B391C" } PieSlice { label: "Psi"; value: 9352; color: darkGrey2; borderColor: "#13060C" } } @@ -73,17 +74,17 @@ Item { size: 0.7 id: pieInner holeSize: 0.25 - PieSlice { label: "Materials"; value: 10334; color: mediumGreen; borderColor: "#163430" } - PieSlice { label: "Employee"; value: 3066; color: darkGreen; borderColor: "#163430" } - PieSlice { label: "Logistics"; value: 6111; color: mediumGreen; borderColor: "#163430" } + PieSlice { label: "Materials"; value: 10334; color: Settings.mediumGreen; borderColor: "#163430" } + PieSlice { label: "Employee"; value: 3066; color: Settings.darkGreen; borderColor: "#163430" } + PieSlice { label: "Logistics"; value: 6111; color: Settings.mediumGreen; borderColor: "#163430" } PieSlice { label: "Materials"; value: 7371; color: mediumGrey2; borderColor: "#3B391C" } PieSlice { label: "Employee"; value: 2443; color: mediumGrey; borderColor: "#3B391C" } PieSlice { label: "Logistics"; value: 1291; color: mediumGrey2; borderColor: "#3B391C" } - PieSlice { label: "Materials"; value: 4022; color: secondaryGrey; borderColor: "#13060C" } + PieSlice { label: "Materials"; value: 4022; color: Settings.secondaryGrey; borderColor: "#13060C" } PieSlice { label: "Employee"; value: 3998; color: darkGrey; borderColor: "#13060C" } - PieSlice { label: "Logistics"; value: 1332; color: secondaryGrey; borderColor: "#13060C" } + PieSlice { label: "Logistics"; value: 1332; color: Settings.secondaryGrey; borderColor: "#13060C" } } } diff --git a/basicsuite/enterprise-charts/View2.qml b/basicsuite/enterprise-charts/View2.qml index 504e6a1..dbf8813 100644 --- a/basicsuite/enterprise-charts/View2.qml +++ b/basicsuite/enterprise-charts/View2.qml @@ -50,6 +50,7 @@ import QtQuick 2.0 import QtCharts 2.0 +import "settings.js" as Settings Item { anchors.fill: parent @@ -59,7 +60,7 @@ Item { anchors.fill: parent LineSeries { name: "LineSeries" - color: defaultGreen + color: Settings.primaryGreen XYPoint { x: 0; y: 0 } XYPoint { x: 1.1; y: 2.1 } XYPoint { x: 1.9; y: 3.3 } diff --git a/basicsuite/enterprise-charts/View3.qml b/basicsuite/enterprise-charts/View3.qml index 8c4e862..a0894fe 100644 --- a/basicsuite/enterprise-charts/View3.qml +++ b/basicsuite/enterprise-charts/View3.qml @@ -50,6 +50,7 @@ import QtQuick 2.0 import QtCharts 2.0 +import "settings.js" as Settings Item { anchors.fill: parent @@ -59,7 +60,7 @@ Item { anchors.fill: parent SplineSeries { name: "SplineSeries" - color: defaultGreen + color: Settings.primaryGreen XYPoint { x: 0; y: 0.0 } XYPoint { x: 1.1; y: 3.2 } XYPoint { x: 1.9; y: 2.4 } diff --git a/basicsuite/enterprise-charts/View4.qml b/basicsuite/enterprise-charts/View4.qml index 606029a..7b0b823 100644 --- a/basicsuite/enterprise-charts/View4.qml +++ b/basicsuite/enterprise-charts/View4.qml @@ -50,6 +50,7 @@ import QtQuick 2.0 import QtCharts 2.0 +import "settings.js" as Settings Item { anchors.fill: parent @@ -68,7 +69,7 @@ Item { AreaSeries { name: "Russian" color: mediumGrey2 - borderColor: darkGreen + borderColor: Settings.darkGreen borderWidth: 3 axisX: valueAxis upperSeries: LineSeries { @@ -91,7 +92,7 @@ Item { AreaSeries { name: "Swedish" color: lightGrey - borderColor: mediumGreen + borderColor: Settings.mediumGreen borderWidth: 3 axisX: valueAxis upperSeries: LineSeries { @@ -112,8 +113,8 @@ Item { AreaSeries { name: "Finnish" - color: secondaryGrey - borderColor: defaultGreen + color: Settings.secondaryGrey + borderColor: Settings.primaryGreen borderWidth: 3 axisX: valueAxis upperSeries: LineSeries { diff --git a/basicsuite/enterprise-charts/View5.qml b/basicsuite/enterprise-charts/View5.qml index 17e9b2f..9b8ba09 100644 --- a/basicsuite/enterprise-charts/View5.qml +++ b/basicsuite/enterprise-charts/View5.qml @@ -50,6 +50,7 @@ import QtQuick 2.0 import QtCharts 2.0 +import "settings.js" as Settings Item { anchors.fill: parent @@ -60,7 +61,7 @@ Item { ScatterSeries { id: scatter1 name: "Scatter1" - color: defaultGreen + color: Settings.primaryGreen XYPoint { x: 1.5; y: 1.5 } XYPoint { x: 1.5; y: 1.6 } XYPoint { x: 1.57; y: 1.55 } @@ -72,7 +73,7 @@ Item { ScatterSeries { name: "Scatter2" - color: defaultGrey + color: Settings.primaryGrey //![1] XYPoint { x: 2.0; y: 2.0 } XYPoint { x: 2.0; y: 2.1 } diff --git a/basicsuite/enterprise-charts/View6.qml b/basicsuite/enterprise-charts/View6.qml index 23d4b70..b2ee347 100644 --- a/basicsuite/enterprise-charts/View6.qml +++ b/basicsuite/enterprise-charts/View6.qml @@ -50,6 +50,7 @@ import QtQuick 2.0 import QtCharts 2.0 +import "settings.js" as Settings Item { anchors.fill: parent @@ -60,9 +61,9 @@ Item { BarSeries { id: mySeries axisX: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] } - BarSet { label: "Bob"; color: defaultGreen; values: [2, 2, 3, 4, 5, 6] } - BarSet { label: "Susan"; color: defaultGrey; values: [5, 1, 2, 4, 1, 7] } - BarSet { label: "James"; color: secondaryGrey; values: [3, 5, 8, 13, 5, 8] } + BarSet { label: "Bob"; color: Settings.primaryGreen; values: [2, 2, 3, 4, 5, 6] } + BarSet { label: "Susan"; color: Settings.primaryGrey; values: [5, 1, 2, 4, 1, 7] } + BarSet { label: "James"; color: Settings.secondaryGrey; values: [3, 5, 8, 13, 5, 8] } } Component.onCompleted: { diff --git a/basicsuite/enterprise-charts/View7.qml b/basicsuite/enterprise-charts/View7.qml index 5b5426c..afcfd03 100644 --- a/basicsuite/enterprise-charts/View7.qml +++ b/basicsuite/enterprise-charts/View7.qml @@ -50,6 +50,7 @@ import QtQuick 2.0 import QtCharts 2.0 +import "settings.js" as Settings Item { anchors.fill: parent @@ -60,9 +61,9 @@ Item { StackedBarSeries { id: mySeries axisX: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] } - BarSet { label: "Bob"; color: defaultGreen; values: [2, 2, 3, 4, 5, 6] } - BarSet { label: "Susan"; color: defaultGrey; values: [5, 1, 2, 4, 1, 7] } - BarSet { label: "James"; color: secondaryGrey; values: [3, 5, 8, 13, 5, 8] } + BarSet { label: "Bob"; color: Settings.primaryGreen; values: [2, 2, 3, 4, 5, 6] } + BarSet { label: "Susan"; color: Settings.primaryGrey; values: [5, 1, 2, 4, 1, 7] } + BarSet { label: "James"; color: Settings.secondaryGrey; values: [3, 5, 8, 13, 5, 8] } } Component.onCompleted: { axes[0].labelsColor = "white"; diff --git a/basicsuite/enterprise-charts/View8.qml b/basicsuite/enterprise-charts/View8.qml index ff7bed7..81fc60a 100644 --- a/basicsuite/enterprise-charts/View8.qml +++ b/basicsuite/enterprise-charts/View8.qml @@ -50,6 +50,7 @@ import QtQuick 2.0 import QtCharts 2.0 +import "settings.js" as Settings Item { anchors.fill: parent @@ -59,9 +60,9 @@ Item { anchors.fill: parent PercentBarSeries { axisX: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] } - BarSet { label: "Bob"; color: defaultGreen; values: [2, 2, 3, 4, 5, 6] } - BarSet { label: "Susan"; color: defaultGrey; values: [5, 1, 2, 4, 1, 7] } - BarSet { label: "James"; color: secondaryGrey; values: [3, 5, 8, 13, 5, 8] } + BarSet { label: "Bob"; color: Settings.primaryGreen; values: [2, 2, 3, 4, 5, 6] } + BarSet { label: "Susan"; color: Settings.primaryGrey; values: [5, 1, 2, 4, 1, 7] } + BarSet { label: "James"; color: Settings.secondaryGrey; values: [3, 5, 8, 13, 5, 8] } } Component.onCompleted: { diff --git a/basicsuite/enterprise-charts/View9.qml b/basicsuite/enterprise-charts/View9.qml index 89a20b6..ab68c5c 100644 --- a/basicsuite/enterprise-charts/View9.qml +++ b/basicsuite/enterprise-charts/View9.qml @@ -50,6 +50,7 @@ import QtQuick 2.0 import QtCharts 2.0 +import "settings.js" as Settings Item { anchors.fill: parent @@ -59,9 +60,9 @@ Item { anchors.fill: parent HorizontalBarSeries { axisY: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] } - BarSet { label: "Bob"; color: defaultGreen; values: [2, 2, 3, 4, 5, 6] } - BarSet { label: "Susan"; color: defaultGrey; values: [5, 1, 2, 4, 1, 7] } - BarSet { label: "James"; color: secondaryGrey; values: [3, 5, 8, 13, 5, 8] } + BarSet { label: "Bob"; color: Settings.primaryGreen; values: [2, 2, 3, 4, 5, 6] } + BarSet { label: "Susan"; color: Settings.primaryGrey; values: [5, 1, 2, 4, 1, 7] } + BarSet { label: "James"; color: Settings.secondaryGrey; values: [3, 5, 8, 13, 5, 8] } } Component.onCompleted: { diff --git a/basicsuite/enterprise-charts/enterprise-charts.pro b/basicsuite/enterprise-charts/enterprise-charts.pro index 803feb0..cef306b 100644 --- a/basicsuite/enterprise-charts/enterprise-charts.pro +++ b/basicsuite/enterprise-charts/enterprise-charts.pro @@ -18,7 +18,8 @@ content.files = \ View6.qml \ View7.qml \ View8.qml \ - View9.qml + View9.qml \ + ../shared/settings.js content.path = $$DESTPATH diff --git a/basicsuite/enterprise-charts/main.qml b/basicsuite/enterprise-charts/main.qml index 6c16b82..03b822e 100644 --- a/basicsuite/enterprise-charts/main.qml +++ b/basicsuite/enterprise-charts/main.qml @@ -51,12 +51,13 @@ //![1] import QtQuick 2.0 //![1] +import "settings.js" as Settings Rectangle { width: 600 height: 400 property bool sourceLoaded: false - color: defaultBackground + color: Settings.backgroundColor property string darkGrey: "#222840" property string darkGrey2: "#53586b" diff --git a/basicsuite/graphicaleffects/graphicaleffects.pro b/basicsuite/graphicaleffects/graphicaleffects.pro index 2c51fe7..3fe7c51 100644 --- a/basicsuite/graphicaleffects/graphicaleffects.pro +++ b/basicsuite/graphicaleffects/graphicaleffects.pro @@ -17,7 +17,8 @@ content.files = \ effect_OpacityMask.qml \ effect_ThresholdMask.qml \ main.qml \ - images + images \ + ../shared/settings.js content.path = $$DESTPATH diff --git a/basicsuite/graphicaleffects/main.qml b/basicsuite/graphicaleffects/main.qml index a1ee5e8..9da3676 100644 --- a/basicsuite/graphicaleffects/main.qml +++ b/basicsuite/graphicaleffects/main.qml @@ -48,6 +48,7 @@ ** ****************************************************************************/ import QtQuick 2.0 +import "settings.js" as Settings Item { id: root @@ -73,7 +74,7 @@ Item { anchors.right: checkers.left anchors.top: parent.top anchors.bottom: parent.bottom - color: defaultBackground + color: Settings.backgroundColor } ListModel { @@ -120,7 +121,7 @@ Item { property bool isSelected: list.currentIndex == index Text { - color: parent.isSelected ? defaultGreen : "white" + color: parent.isSelected ? Settings.primaryGreen : "white" font.pixelSize: parent.height * 0.625 font.family: appFont font.styleName: parent.isSelected ? "Bold" : "Regular" @@ -158,7 +159,7 @@ Item { var margin = canvas.padding; var segmentSize = 4 - ctx.strokeStyle = defaultGrey + ctx.strokeStyle = Settings.primaryGrey ctx.beginPath(); ctx.moveTo(margin, margin); ctx.lineTo(margin, h-margin); @@ -178,7 +179,7 @@ Item { } Rectangle { - color: defaultGreen + color: Settings.primaryGreen width: parent.width / 20 height: width radius: width / 2 diff --git a/basicsuite/mediaplayer/ControlBar.qml b/basicsuite/mediaplayer/ControlBar.qml index e65a3a3..f05cea8 100644 --- a/basicsuite/mediaplayer/ControlBar.qml +++ b/basicsuite/mediaplayer/ControlBar.qml @@ -50,11 +50,12 @@ import QtQuick 2.0 import QtMultimedia 5.0 +import "settings.js" as Settings Rectangle { id: controlBar height: parent.height * 0.225 - color: defaultBackground + color: Settings.backgroundColor property MediaPlayer mediaPlayer: null property bool isMouseAbove: false diff --git a/basicsuite/mediaplayer/EffectSelectionPanel.qml b/basicsuite/mediaplayer/EffectSelectionPanel.qml index 68a9cac..12c8a42 100644 --- a/basicsuite/mediaplayer/EffectSelectionPanel.qml +++ b/basicsuite/mediaplayer/EffectSelectionPanel.qml @@ -48,10 +48,11 @@ ** ****************************************************************************/ import QtQuick 2.0 +import "settings.js" as Settings Rectangle { id: root - color: defaultBackground + color: Settings.backgroundColor height: 78 property int itemHeight: 25 property string effectSource: "" diff --git a/basicsuite/mediaplayer/FileBrowser.qml b/basicsuite/mediaplayer/FileBrowser.qml index 8bae836..04e821a 100644 --- a/basicsuite/mediaplayer/FileBrowser.qml +++ b/basicsuite/mediaplayer/FileBrowser.qml @@ -51,6 +51,7 @@ import QtQuick 2.0 import Qt.labs.folderlistmodel 2.0 import QtQuick.Controls 1.4 import QtDeviceUtilities.QtButtonImageProvider 1.0 +import "settings.js" as Settings Item { id: fileBrowser @@ -78,7 +79,7 @@ Item { Rectangle { id: root - color: defaultBackground + color: Settings.backgroundColor property alias folder: folders.folder FolderListModel { @@ -184,7 +185,7 @@ Item { Rectangle { width: parent.width; height: 70 - color: defaultBackground + color: Settings.backgroundColor id: titleBar QtButton { diff --git a/basicsuite/mediaplayer/MetadataView.qml b/basicsuite/mediaplayer/MetadataView.qml index 79883d2..a995050 100644 --- a/basicsuite/mediaplayer/MetadataView.qml +++ b/basicsuite/mediaplayer/MetadataView.qml @@ -49,6 +49,7 @@ ****************************************************************************/ import QtQuick 2.0 import QtMultimedia 5.0 +import "settings.js" as Settings Rectangle { id: root @@ -63,7 +64,7 @@ Rectangle { Rectangle { height: column.height + 30 width: 500 - color: defaultBackground + color: Settings.backgroundColor opacity: 0.9 anchors.centerIn: parent anchors.verticalCenterOffset: -50 diff --git a/basicsuite/mediaplayer/ParameterPanel.qml b/basicsuite/mediaplayer/ParameterPanel.qml index 5b8e991..1378827 100644 --- a/basicsuite/mediaplayer/ParameterPanel.qml +++ b/basicsuite/mediaplayer/ParameterPanel.qml @@ -48,11 +48,12 @@ ** ****************************************************************************/ import QtQuick 2.0 +import "settings.js" as Settings Rectangle { id: root height: view.model.count * sliderHeight - color: defaultBackground + color: Settings.backgroundColor property color lineColor: "black" property real spacing: 10 property real sliderHeight: 50 diff --git a/basicsuite/mediaplayer/PlayerSlider.qml b/basicsuite/mediaplayer/PlayerSlider.qml index d569866..ef0556a 100644 --- a/basicsuite/mediaplayer/PlayerSlider.qml +++ b/basicsuite/mediaplayer/PlayerSlider.qml @@ -48,6 +48,7 @@ ** ****************************************************************************/ import QtQuick 2.0 +import "settings.js" as Settings Item { id: slider @@ -81,7 +82,7 @@ Item { width: slider.width anchors.verticalCenter: slider.verticalCenter height: 5 - color: "#9d9faa" + color: "red" //Settings.backgroundColor radius: 2 MouseArea { @@ -119,7 +120,7 @@ Item { anchors.right: handle.right anchors.rightMargin: handle.width / 2 visible: slider.enabled - color: "white" + color: "green" radius: 2 } diff --git a/basicsuite/mediaplayer/UrlBar.qml b/basicsuite/mediaplayer/UrlBar.qml index 78ba6ec..ca69f69 100644 --- a/basicsuite/mediaplayer/UrlBar.qml +++ b/basicsuite/mediaplayer/UrlBar.qml @@ -49,6 +49,7 @@ ****************************************************************************/ import QtQuick 2.0 import QtQuick.Controls 2.0 +import "settings.js" as Settings Rectangle { id: root @@ -92,7 +93,7 @@ Rectangle { font.family: appFont font.styleName: "Light" background: Rectangle { - color: defaultBackground + color: Settings.backgroundColor opacity: 0.8 border.color: viewSettings.borderColor border.width: 2 diff --git a/basicsuite/mediaplayer/main.qml b/basicsuite/mediaplayer/main.qml index 5f3ff42..66d03a1 100644 --- a/basicsuite/mediaplayer/main.qml +++ b/basicsuite/mediaplayer/main.qml @@ -51,6 +51,7 @@ import QtQuick 2.0 import QtMultimedia 5.0 import QtDeviceUtilities.QtButtonImageProvider 1.0 +import "settings.js" as Settings FocusScope { id: applicationWindow diff --git a/basicsuite/mediaplayer/mediaplayer.pro b/basicsuite/mediaplayer/mediaplayer.pro index ba174e3..3578abc 100644 --- a/basicsuite/mediaplayer/mediaplayer.pro +++ b/basicsuite/mediaplayer/mediaplayer.pro @@ -19,7 +19,8 @@ content.files = \ UrlBar.qml \ VolumeControl.qml \ Effects \ - images + images \ + ../shared/settings.js content.path = $$DESTPATH diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/BrowserWindow.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/BrowserWindow.qml index 91dd074..bb8c231 100644 --- a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/BrowserWindow.qml +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/BrowserWindow.qml @@ -59,28 +59,22 @@ Item { property int toolBarSize: 80 property string uiColor: settingsView.privateBrowsingEnabled ? "#3a4055" : "#09102b" - //property string uiColor: "#09102b" - //property string uiSeparatorColor: settingsView.privateBrowsingEnabled ? "#717273" : "#7ebee5" property string uiSeparatorColor: "#9d9faa" - //property string toolBarSeparatorColor: settingsView.privateBrowsingEnabled ? "#929495" : "#a3d1ed" property string toolBarSeparatorColor: "#9d9faa" property string toolBarFillColor: settingsView.privateBrowsingEnabled ? "#3a4055" : "#09102b" - //property string toolBarFillColor: "#09102b" - //property string buttonPressedColor: settingsView.privateBrowsingEnabled ? "#3b3c3e" : "#3f91c4" property string buttonPressedColor: "#41cd52" property string emptyBackgroundColor: "#09102b" - //property string uiHighlightColor: "#fddd5c" property string uiHighlightColor: "#41cd52" property string inactivePagerColor: "#bcbdbe" property string textFieldStrokeColor: "#9d9faa" property string placeholderColor: "#a0a1a2" property string iconOverlayColor: "#0e202c" property string iconStrokeColor: "#9d9faa" - property string defaultFontFamily: appFont //"Open Sans" + property string defaultFontFamily: appFont property int gridViewPageItemCount: 8 property int gridViewMaxBookmarks: 3 * gridViewPageItemCount diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/CustomSwitch.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/CustomSwitch.qml index d73f940..7f8f674 100644 --- a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/CustomSwitch.qml +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/CustomSwitch.qml @@ -35,6 +35,7 @@ Switch { property alias indicatorWidth: indicatorImg.width property alias indicatorHeight: indicatorImg.height + property string switchTextColor: "#3b4155" indicator: Image { id: indicatorImg @@ -54,7 +55,7 @@ Switch { fontSizeMode: Text.Fit minimumPixelSize: 1 font.pixelSize: parent.height * 0.55 - color: "#3b4155" + color: switchTextColor text: "OFF" font.family: defaultFontFamily } @@ -68,7 +69,7 @@ Switch { fontSizeMode: Text.Fit minimumPixelSize: 1 font.pixelSize: parent.height * 0.55 - color: "#3b4155" + color: switchTextColor text: "ON" font.family: defaultFontFamily } @@ -90,7 +91,7 @@ Switch { anchors.verticalCenter: parent.verticalCenter width: parent.width * 0.475 height: parent.height * 0.9 - fillColor: control.checked ? "#41cd52" : "#9d9faa"//viewSettings.buttonGreenColor : viewSettings.buttonGrayColor + fillColor: control.checked ? buttonPressedColor : toolBarSeparatorColor text: control.checked ? "ON" : "OFF" borderColor: "transparent" Behavior on x { diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/SettingsView.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/SettingsView.qml index 678b966..81397fd 100644 --- a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/SettingsView.qml +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/SettingsView.qml @@ -73,7 +73,7 @@ Rectangle { } Rectangle{ - color: "#9d9faa" + color: toolBarSeparatorColor height: 2 anchors.top: root.top anchors.right: root.right diff --git a/basicsuite/shared/SharedMain.qml b/basicsuite/shared/SharedMain.qml index d9f38a8..ec6d13b 100644 --- a/basicsuite/shared/SharedMain.qml +++ b/basicsuite/shared/SharedMain.qml @@ -60,15 +60,6 @@ Window { color: "black" - property string defaultGreen: "#41cd52" - property string mediumGreen: "#21be2b" - property string darkGreen: "#17a81a" - - property string defaultBackground: "#09102b" - - property string defaultGrey: "#9d9faa" - property string secondaryGrey: "#3a4055" - Item { id: root anchors.centerIn: window.contentItem diff --git a/basicsuite/shared/settings.js b/basicsuite/shared/settings.js new file mode 100644 index 0000000..8dcc976 --- /dev/null +++ b/basicsuite/shared/settings.js @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Device Creation. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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$ +** +****************************************************************************/ +.pragma library + +var backgroundColor = "#09102b" + +var primaryGreen = "#41cd52" +var mediumGreen = "#21be2b" +var darkGreen = "#17a81a" + +var primaryGrey = "#9d9faa" +var secondaryGrey = "#3a4055" + diff --git a/basicsuite/shared/settings.qrc b/basicsuite/shared/settings.qrc new file mode 100644 index 0000000..576a1e9 --- /dev/null +++ b/basicsuite/shared/settings.qrc @@ -0,0 +1,5 @@ + + + settings.js + + diff --git a/basicsuite/shared/shared.pri b/basicsuite/shared/shared.pri index 05e0ba8..223bb02 100644 --- a/basicsuite/shared/shared.pri +++ b/basicsuite/shared/shared.pri @@ -6,7 +6,7 @@ qtHaveModule(webengine) { QT += webengine } -DESTPATH = /data/user/$$TARGET +DESTPATH = /data/user/qt/$$TARGET target.path = $$DESTPATH SOURCES += $$PWD/main.cpp \ -- cgit v1.2.3 From d0833655c54c05925bd214f545bc904d53860fb3 Mon Sep 17 00:00:00 2001 From: Juho Annunen Date: Fri, 27 Apr 2018 09:34:46 +0300 Subject: Add new Ebike demo to basicsuite Task-number: QTBUG-67917 Change-Id: I88e783ff7bcc530b13edfd3e21565953433293dc Reviewed-by: Teemu Holappa --- basicsuite/demos.xml | 8 + basicsuite/ebike-ui/.gitignore | 73 + basicsuite/ebike-ui/BikeInfoTab.qml | 483 +++ basicsuite/ebike-ui/BikeStyle/Colors.qml | 125 + basicsuite/ebike-ui/BikeStyle/UILayout.qml | 257 ++ basicsuite/ebike-ui/BikeStyle/qmldir | 2 + basicsuite/ebike-ui/ClockView.qml | 72 + basicsuite/ebike-ui/ColumnSpacer.qml | 45 + basicsuite/ebike-ui/ConfigurationDrawer.qml | 147 + basicsuite/ebike-ui/ConfigurationItem.qml | 63 + basicsuite/ebike-ui/FpsItem.qml | 77 + basicsuite/ebike-ui/GeneralTab.qml | 279 ++ basicsuite/ebike-ui/IconifiedTabButton.qml | 70 + basicsuite/ebike-ui/LightsBox.qml | 81 + basicsuite/ebike-ui/MainPage.qml | 94 + basicsuite/ebike-ui/ModeBox.qml | 101 + basicsuite/ebike-ui/MusicPlayer.qml | 239 + basicsuite/ebike-ui/NaviBox.qml | 129 + basicsuite/ebike-ui/NaviButton.qml | 83 + basicsuite/ebike-ui/NaviGuide.qml | 139 + basicsuite/ebike-ui/NaviPage.qml | 691 +++ basicsuite/ebike-ui/NaviTripInfo.qml | 147 + basicsuite/ebike-ui/SpeedView.qml | 526 +++ basicsuite/ebike-ui/StatsBox.qml | 157 + basicsuite/ebike-ui/StatsPage.qml | 314 ++ basicsuite/ebike-ui/StatsRow.qml | 102 + basicsuite/ebike-ui/ToggleSwitch.qml | 66 + basicsuite/ebike-ui/TripChart.qml | 236 + basicsuite/ebike-ui/ViewTab.qml | 148 + basicsuite/ebike-ui/app.pro | 141 + basicsuite/ebike-ui/brightnesscontroller.cpp | 91 + basicsuite/ebike-ui/brightnesscontroller.h | 69 + .../ebike-ui/datamodelplugin/datamodelplugin.pro | 39 + basicsuite/ebike-ui/datamodelplugin/plugin.cpp | 109 + basicsuite/ebike-ui/datamodelplugin/qmldir | 2 + basicsuite/ebike-ui/datastore.cpp | 300 ++ basicsuite/ebike-ui/datastore.h | 163 + basicsuite/ebike-ui/ebike-ui.pro | 7 + basicsuite/ebike-ui/ebike_en.ts | 290 ++ basicsuite/ebike-ui/ebike_fi.ts | 290 ++ basicsuite/ebike-ui/fonts/Montserrat-Black.ttf | Bin 0 -> 194544 bytes .../ebike-ui/fonts/Montserrat-BlackItalic.ttf | Bin 0 -> 190120 bytes basicsuite/ebike-ui/fonts/Montserrat-Bold.ttf | Bin 0 -> 191648 bytes .../ebike-ui/fonts/Montserrat-BoldItalic.ttf | Bin 0 -> 195604 bytes basicsuite/ebike-ui/fonts/Montserrat-ExtraBold.ttf | Bin 0 -> 191644 bytes .../ebike-ui/fonts/Montserrat-ExtraBoldItalic.ttf | Bin 0 -> 191664 bytes .../ebike-ui/fonts/Montserrat-ExtraLight.ttf | Bin 0 -> 196472 bytes .../ebike-ui/fonts/Montserrat-ExtraLightItalic.ttf | Bin 0 -> 194348 bytes basicsuite/ebike-ui/fonts/Montserrat-Italic.ttf | Bin 0 -> 191936 bytes basicsuite/ebike-ui/fonts/Montserrat-Light.ttf | Bin 0 -> 192116 bytes .../ebike-ui/fonts/Montserrat-LightItalic.ttf | Bin 0 -> 192128 bytes basicsuite/ebike-ui/fonts/Montserrat-Medium.ttf | Bin 0 -> 192488 bytes .../ebike-ui/fonts/Montserrat-MediumItalic.ttf | Bin 0 -> 193096 bytes basicsuite/ebike-ui/fonts/Montserrat-Regular.ttf | Bin 0 -> 190648 bytes basicsuite/ebike-ui/fonts/Montserrat-SemiBold.ttf | Bin 0 -> 192268 bytes .../ebike-ui/fonts/Montserrat-SemiBoldItalic.ttf | Bin 0 -> 192648 bytes basicsuite/ebike-ui/fonts/Montserrat-Thin.ttf | Bin 0 -> 191468 bytes .../ebike-ui/fonts/Montserrat-ThinItalic.ttf | Bin 0 -> 192540 bytes basicsuite/ebike-ui/fonts/OFL.txt | 93 + basicsuite/ebike-ui/fonts/Teko-Bold.ttf | Bin 0 -> 305800 bytes basicsuite/ebike-ui/fonts/Teko-Light.ttf | Bin 0 -> 301528 bytes basicsuite/ebike-ui/fonts/Teko-Medium.ttf | Bin 0 -> 310028 bytes basicsuite/ebike-ui/fonts/Teko-Regular.ttf | Bin 0 -> 311780 bytes basicsuite/ebike-ui/fonts/Teko-SemiBold.ttf | Bin 0 -> 317004 bytes basicsuite/ebike-ui/fonts/fontawesome-webfont.ttf | Bin 0 -> 165548 bytes basicsuite/ebike-ui/fpscounter.cpp | 79 + basicsuite/ebike-ui/fpscounter.h | 77 + basicsuite/ebike-ui/images/arrow_left.png | Bin 0 -> 227 bytes basicsuite/ebike-ui/images/arrow_right.png | Bin 0 -> 236 bytes basicsuite/ebike-ui/images/assist.png | Bin 0 -> 415 bytes basicsuite/ebike-ui/images/battery.png | Bin 0 -> 292 bytes basicsuite/ebike-ui/images/bike-battery.png | Bin 0 -> 11471 bytes basicsuite/ebike-ui/images/bike-brakes.png | Bin 0 -> 10578 bytes basicsuite/ebike-ui/images/bike-chain.png | Bin 0 -> 10742 bytes basicsuite/ebike-ui/images/bike-frontwheel.png | Bin 0 -> 11648 bytes basicsuite/ebike-ui/images/bike-gears.png | Bin 0 -> 10874 bytes basicsuite/ebike-ui/images/bike-light.png | Bin 0 -> 10457 bytes basicsuite/ebike-ui/images/bike-rearwheel.png | Bin 0 -> 11595 bytes .../ebike-ui/images/blue_circle_gps_area.png | Bin 0 -> 1089 bytes basicsuite/ebike-ui/images/calories.png | Bin 0 -> 447 bytes basicsuite/ebike-ui/images/checkmark.png | Bin 0 -> 208 bytes .../ebike-ui/images/curtain_shadow_handle.png | Bin 0 -> 1787 bytes basicsuite/ebike-ui/images/curtain_up_arrow.png | Bin 0 -> 210 bytes basicsuite/ebike-ui/images/fps_icon.png | Bin 0 -> 1061 bytes basicsuite/ebike-ui/images/info.png | Bin 0 -> 439 bytes basicsuite/ebike-ui/images/info_selected.png | Bin 0 -> 368 bytes basicsuite/ebike-ui/images/lights_off.png | Bin 0 -> 1325 bytes basicsuite/ebike-ui/images/lights_on.png | Bin 0 -> 1310 bytes basicsuite/ebike-ui/images/list.png | Bin 0 -> 179 bytes basicsuite/ebike-ui/images/list_selected.png | Bin 0 -> 159 bytes basicsuite/ebike-ui/images/map-marker.png | Bin 0 -> 815 bytes basicsuite/ebike-ui/images/map_btn_shadow.png | Bin 0 -> 1188 bytes basicsuite/ebike-ui/images/map_destination.png | Bin 0 -> 973 bytes basicsuite/ebike-ui/images/map_locate.png | Bin 0 -> 366 bytes basicsuite/ebike-ui/images/map_location_arrow.png | Bin 0 -> 611 bytes basicsuite/ebike-ui/images/map_zoomin.png | Bin 0 -> 434 bytes basicsuite/ebike-ui/images/map_zoomout.png | Bin 0 -> 421 bytes basicsuite/ebike-ui/images/nav_bear_l.png | Bin 0 -> 870 bytes basicsuite/ebike-ui/images/nav_bear_r.png | Bin 0 -> 878 bytes basicsuite/ebike-ui/images/nav_hard_l.png | Bin 0 -> 1113 bytes basicsuite/ebike-ui/images/nav_hard_r.png | Bin 0 -> 1057 bytes basicsuite/ebike-ui/images/nav_left.png | Bin 0 -> 848 bytes basicsuite/ebike-ui/images/nav_light_left.png | Bin 0 -> 1090 bytes basicsuite/ebike-ui/images/nav_light_right.png | Bin 0 -> 1113 bytes basicsuite/ebike-ui/images/nav_nodir.png | Bin 0 -> 820 bytes basicsuite/ebike-ui/images/nav_right.png | Bin 0 -> 799 bytes basicsuite/ebike-ui/images/nav_straight.png | Bin 0 -> 379 bytes basicsuite/ebike-ui/images/nav_uturn_l.png | Bin 0 -> 1283 bytes basicsuite/ebike-ui/images/nav_uturn_r.png | Bin 0 -> 1287 bytes .../ebike-ui/images/navigation_widget_shadow.png | Bin 0 -> 3222 bytes basicsuite/ebike-ui/images/nextsong.png | Bin 0 -> 344 bytes basicsuite/ebike-ui/images/nextsong_pressed.png | Bin 0 -> 348 bytes basicsuite/ebike-ui/images/ok.png | Bin 0 -> 425 bytes basicsuite/ebike-ui/images/pause.png | Bin 0 -> 173 bytes basicsuite/ebike-ui/images/pause_pressed.png | Bin 0 -> 172 bytes basicsuite/ebike-ui/images/placeholder.png | Bin 0 -> 1769 bytes basicsuite/ebike-ui/images/play.png | Bin 0 -> 362 bytes basicsuite/ebike-ui/images/play_pressed.png | Bin 0 -> 362 bytes basicsuite/ebike-ui/images/prevsong.png | Bin 0 -> 349 bytes basicsuite/ebike-ui/images/prevsong_pressed.png | Bin 0 -> 353 bytes basicsuite/ebike-ui/images/search.png | Bin 0 -> 463 bytes basicsuite/ebike-ui/images/search_cancel.png | Bin 0 -> 322 bytes basicsuite/ebike-ui/images/settings.png | Bin 0 -> 630 bytes basicsuite/ebike-ui/images/settings_selected.png | Bin 0 -> 445 bytes .../ebike-ui/images/small_input_box_shadow.png | Bin 0 -> 1141 bytes .../ebike-ui/images/small_speedometer_arrow.png | Bin 0 -> 185 bytes .../ebike-ui/images/small_speedometer_shadow.png | Bin 0 -> 3137 bytes basicsuite/ebike-ui/images/speed.png | Bin 0 -> 400 bytes basicsuite/ebike-ui/images/spinner.png | Bin 0 -> 3470 bytes basicsuite/ebike-ui/images/top_curtain_drag.png | Bin 0 -> 1200 bytes basicsuite/ebike-ui/images/trip.png | Bin 0 -> 381 bytes basicsuite/ebike-ui/images/warning.png | Bin 0 -> 418 bytes basicsuite/ebike-ui/main.qml | 350 ++ basicsuite/ebike-ui/mapbox.cpp | 89 + basicsuite/ebike-ui/mapbox.h | 68 + basicsuite/ebike-ui/mapboxsuggestions.cpp | 109 + basicsuite/ebike-ui/mapboxsuggestions.h | 89 + basicsuite/ebike-ui/moment.js | 4551 ++++++++++++++++++++ basicsuite/ebike-ui/mostrecent.bson | Bin 0 -> 3440 bytes basicsuite/ebike-ui/navigation.cpp | 97 + basicsuite/ebike-ui/navigation.h | 103 + basicsuite/ebike-ui/preview_l.jpg | Bin 0 -> 28660 bytes basicsuite/ebike-ui/qml.qrc | 107 + basicsuite/ebike-ui/qtquickcontrols2.conf | 15 + basicsuite/ebike-ui/socketclient.cpp | 152 + basicsuite/ebike-ui/socketclient.h | 86 + basicsuite/ebike-ui/suggestionsmodel.cpp | 157 + basicsuite/ebike-ui/suggestionsmodel.h | 82 + basicsuite/ebike-ui/tripdatamodel.cpp | 135 + basicsuite/ebike-ui/tripdatamodel.h | 96 + basicsuite/shared/main.cpp | 11 + 151 files changed, 13001 insertions(+) create mode 100644 basicsuite/ebike-ui/.gitignore create mode 100644 basicsuite/ebike-ui/BikeInfoTab.qml create mode 100644 basicsuite/ebike-ui/BikeStyle/Colors.qml create mode 100644 basicsuite/ebike-ui/BikeStyle/UILayout.qml create mode 100644 basicsuite/ebike-ui/BikeStyle/qmldir create mode 100644 basicsuite/ebike-ui/ClockView.qml create mode 100644 basicsuite/ebike-ui/ColumnSpacer.qml create mode 100644 basicsuite/ebike-ui/ConfigurationDrawer.qml create mode 100644 basicsuite/ebike-ui/ConfigurationItem.qml create mode 100644 basicsuite/ebike-ui/FpsItem.qml create mode 100644 basicsuite/ebike-ui/GeneralTab.qml create mode 100644 basicsuite/ebike-ui/IconifiedTabButton.qml create mode 100644 basicsuite/ebike-ui/LightsBox.qml create mode 100644 basicsuite/ebike-ui/MainPage.qml create mode 100644 basicsuite/ebike-ui/ModeBox.qml create mode 100644 basicsuite/ebike-ui/MusicPlayer.qml create mode 100644 basicsuite/ebike-ui/NaviBox.qml create mode 100644 basicsuite/ebike-ui/NaviButton.qml create mode 100644 basicsuite/ebike-ui/NaviGuide.qml create mode 100644 basicsuite/ebike-ui/NaviPage.qml create mode 100644 basicsuite/ebike-ui/NaviTripInfo.qml create mode 100644 basicsuite/ebike-ui/SpeedView.qml create mode 100644 basicsuite/ebike-ui/StatsBox.qml create mode 100644 basicsuite/ebike-ui/StatsPage.qml create mode 100644 basicsuite/ebike-ui/StatsRow.qml create mode 100644 basicsuite/ebike-ui/ToggleSwitch.qml create mode 100644 basicsuite/ebike-ui/TripChart.qml create mode 100644 basicsuite/ebike-ui/ViewTab.qml create mode 100644 basicsuite/ebike-ui/app.pro create mode 100644 basicsuite/ebike-ui/brightnesscontroller.cpp create mode 100644 basicsuite/ebike-ui/brightnesscontroller.h create mode 100644 basicsuite/ebike-ui/datamodelplugin/datamodelplugin.pro create mode 100644 basicsuite/ebike-ui/datamodelplugin/plugin.cpp create mode 100644 basicsuite/ebike-ui/datamodelplugin/qmldir create mode 100644 basicsuite/ebike-ui/datastore.cpp create mode 100644 basicsuite/ebike-ui/datastore.h create mode 100644 basicsuite/ebike-ui/ebike-ui.pro create mode 100644 basicsuite/ebike-ui/ebike_en.ts create mode 100644 basicsuite/ebike-ui/ebike_fi.ts create mode 100644 basicsuite/ebike-ui/fonts/Montserrat-Black.ttf create mode 100644 basicsuite/ebike-ui/fonts/Montserrat-BlackItalic.ttf create mode 100644 basicsuite/ebike-ui/fonts/Montserrat-Bold.ttf create mode 100644 basicsuite/ebike-ui/fonts/Montserrat-BoldItalic.ttf create mode 100644 basicsuite/ebike-ui/fonts/Montserrat-ExtraBold.ttf create mode 100644 basicsuite/ebike-ui/fonts/Montserrat-ExtraBoldItalic.ttf create mode 100644 basicsuite/ebike-ui/fonts/Montserrat-ExtraLight.ttf create mode 100644 basicsuite/ebike-ui/fonts/Montserrat-ExtraLightItalic.ttf create mode 100644 basicsuite/ebike-ui/fonts/Montserrat-Italic.ttf create mode 100644 basicsuite/ebike-ui/fonts/Montserrat-Light.ttf create mode 100644 basicsuite/ebike-ui/fonts/Montserrat-LightItalic.ttf create mode 100644 basicsuite/ebike-ui/fonts/Montserrat-Medium.ttf create mode 100644 basicsuite/ebike-ui/fonts/Montserrat-MediumItalic.ttf create mode 100644 basicsuite/ebike-ui/fonts/Montserrat-Regular.ttf create mode 100644 basicsuite/ebike-ui/fonts/Montserrat-SemiBold.ttf create mode 100644 basicsuite/ebike-ui/fonts/Montserrat-SemiBoldItalic.ttf create mode 100644 basicsuite/ebike-ui/fonts/Montserrat-Thin.ttf create mode 100644 basicsuite/ebike-ui/fonts/Montserrat-ThinItalic.ttf create mode 100644 basicsuite/ebike-ui/fonts/OFL.txt create mode 100644 basicsuite/ebike-ui/fonts/Teko-Bold.ttf create mode 100644 basicsuite/ebike-ui/fonts/Teko-Light.ttf create mode 100644 basicsuite/ebike-ui/fonts/Teko-Medium.ttf create mode 100644 basicsuite/ebike-ui/fonts/Teko-Regular.ttf create mode 100644 basicsuite/ebike-ui/fonts/Teko-SemiBold.ttf create mode 100644 basicsuite/ebike-ui/fonts/fontawesome-webfont.ttf create mode 100644 basicsuite/ebike-ui/fpscounter.cpp create mode 100644 basicsuite/ebike-ui/fpscounter.h create mode 100644 basicsuite/ebike-ui/images/arrow_left.png create mode 100644 basicsuite/ebike-ui/images/arrow_right.png create mode 100644 basicsuite/ebike-ui/images/assist.png create mode 100644 basicsuite/ebike-ui/images/battery.png create mode 100644 basicsuite/ebike-ui/images/bike-battery.png create mode 100644 basicsuite/ebike-ui/images/bike-brakes.png create mode 100644 basicsuite/ebike-ui/images/bike-chain.png create mode 100644 basicsuite/ebike-ui/images/bike-frontwheel.png create mode 100644 basicsuite/ebike-ui/images/bike-gears.png create mode 100644 basicsuite/ebike-ui/images/bike-light.png create mode 100644 basicsuite/ebike-ui/images/bike-rearwheel.png create mode 100644 basicsuite/ebike-ui/images/blue_circle_gps_area.png create mode 100644 basicsuite/ebike-ui/images/calories.png create mode 100644 basicsuite/ebike-ui/images/checkmark.png create mode 100644 basicsuite/ebike-ui/images/curtain_shadow_handle.png create mode 100644 basicsuite/ebike-ui/images/curtain_up_arrow.png create mode 100644 basicsuite/ebike-ui/images/fps_icon.png create mode 100644 basicsuite/ebike-ui/images/info.png create mode 100644 basicsuite/ebike-ui/images/info_selected.png create mode 100644 basicsuite/ebike-ui/images/lights_off.png create mode 100644 basicsuite/ebike-ui/images/lights_on.png create mode 100644 basicsuite/ebike-ui/images/list.png create mode 100644 basicsuite/ebike-ui/images/list_selected.png create mode 100644 basicsuite/ebike-ui/images/map-marker.png create mode 100644 basicsuite/ebike-ui/images/map_btn_shadow.png create mode 100644 basicsuite/ebike-ui/images/map_destination.png create mode 100644 basicsuite/ebike-ui/images/map_locate.png create mode 100644 basicsuite/ebike-ui/images/map_location_arrow.png create mode 100644 basicsuite/ebike-ui/images/map_zoomin.png create mode 100644 basicsuite/ebike-ui/images/map_zoomout.png create mode 100644 basicsuite/ebike-ui/images/nav_bear_l.png create mode 100644 basicsuite/ebike-ui/images/nav_bear_r.png create mode 100644 basicsuite/ebike-ui/images/nav_hard_l.png create mode 100644 basicsuite/ebike-ui/images/nav_hard_r.png create mode 100644 basicsuite/ebike-ui/images/nav_left.png create mode 100644 basicsuite/ebike-ui/images/nav_light_left.png create mode 100644 basicsuite/ebike-ui/images/nav_light_right.png create mode 100644 basicsuite/ebike-ui/images/nav_nodir.png create mode 100644 basicsuite/ebike-ui/images/nav_right.png create mode 100644 basicsuite/ebike-ui/images/nav_straight.png create mode 100644 basicsuite/ebike-ui/images/nav_uturn_l.png create mode 100644 basicsuite/ebike-ui/images/nav_uturn_r.png create mode 100644 basicsuite/ebike-ui/images/navigation_widget_shadow.png create mode 100644 basicsuite/ebike-ui/images/nextsong.png create mode 100644 basicsuite/ebike-ui/images/nextsong_pressed.png create mode 100644 basicsuite/ebike-ui/images/ok.png create mode 100644 basicsuite/ebike-ui/images/pause.png create mode 100644 basicsuite/ebike-ui/images/pause_pressed.png create mode 100644 basicsuite/ebike-ui/images/placeholder.png create mode 100644 basicsuite/ebike-ui/images/play.png create mode 100644 basicsuite/ebike-ui/images/play_pressed.png create mode 100644 basicsuite/ebike-ui/images/prevsong.png create mode 100644 basicsuite/ebike-ui/images/prevsong_pressed.png create mode 100644 basicsuite/ebike-ui/images/search.png create mode 100644 basicsuite/ebike-ui/images/search_cancel.png create mode 100644 basicsuite/ebike-ui/images/settings.png create mode 100644 basicsuite/ebike-ui/images/settings_selected.png create mode 100644 basicsuite/ebike-ui/images/small_input_box_shadow.png create mode 100644 basicsuite/ebike-ui/images/small_speedometer_arrow.png create mode 100644 basicsuite/ebike-ui/images/small_speedometer_shadow.png create mode 100644 basicsuite/ebike-ui/images/speed.png create mode 100644 basicsuite/ebike-ui/images/spinner.png create mode 100644 basicsuite/ebike-ui/images/top_curtain_drag.png create mode 100644 basicsuite/ebike-ui/images/trip.png create mode 100644 basicsuite/ebike-ui/images/warning.png create mode 100644 basicsuite/ebike-ui/main.qml create mode 100644 basicsuite/ebike-ui/mapbox.cpp create mode 100644 basicsuite/ebike-ui/mapbox.h create mode 100644 basicsuite/ebike-ui/mapboxsuggestions.cpp create mode 100644 basicsuite/ebike-ui/mapboxsuggestions.h create mode 100644 basicsuite/ebike-ui/moment.js create mode 100644 basicsuite/ebike-ui/mostrecent.bson create mode 100644 basicsuite/ebike-ui/navigation.cpp create mode 100644 basicsuite/ebike-ui/navigation.h create mode 100644 basicsuite/ebike-ui/preview_l.jpg create mode 100644 basicsuite/ebike-ui/qml.qrc create mode 100644 basicsuite/ebike-ui/qtquickcontrols2.conf create mode 100644 basicsuite/ebike-ui/socketclient.cpp create mode 100644 basicsuite/ebike-ui/socketclient.h create mode 100644 basicsuite/ebike-ui/suggestionsmodel.cpp create mode 100644 basicsuite/ebike-ui/suggestionsmodel.h create mode 100644 basicsuite/ebike-ui/tripdatamodel.cpp create mode 100644 basicsuite/ebike-ui/tripdatamodel.h diff --git a/basicsuite/demos.xml b/basicsuite/demos.xml index e979a4d..4b7c3e7 100644 --- a/basicsuite/demos.xml +++ b/basicsuite/demos.xml @@ -93,6 +93,14 @@ Qt for Device Creation comes with Qt Virtual Keyboard - a framework that consist + + +An E-bike instrument cluster concept designed and implemented by Qt. + +The entire concept is a testament that Qt brings the HMI designers and Software engineers together by using the same tools, allowing them to fast prototyping through collaborative workflow. In addition to that, Qt is optimized for running on low end SoC even the ones that don't have GPU acceleration for graphics. + + + The gallery example is a simple application with a drawer menu that contains all the Qt Quick Controls 2. diff --git a/basicsuite/ebike-ui/.gitignore b/basicsuite/ebike-ui/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/basicsuite/ebike-ui/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/basicsuite/ebike-ui/BikeInfoTab.qml b/basicsuite/ebike-ui/BikeInfoTab.qml new file mode 100644 index 0000000..0dc4f27 --- /dev/null +++ b/basicsuite/ebike-ui/BikeInfoTab.qml @@ -0,0 +1,483 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.9 +import QtQuick.Controls 2.2 +import QtQuick.Layouts 1.3 +import DataStore 1.0 + +import "./BikeStyle" + +Item { + property string selectedComponent: "battery" + property string bikeImageSource: "images/bike-battery.png" + property string componentName: "Battery" + property string componentStatusImageSource: "images/ok.png" + property color statusLineColor: selectedComponent === "rearwheel" ? Colors.bikeInfoLineWarning : Colors.bikeInfoLineOk + property int statusLineLength: 280 + property string primaryDetails: "Health" + property string primaryDetailsValue: "85%" + property bool primaryDetailsOk: true + property var activeComponent: batteryCircle + + function updateComponent() { + if (selectedComponent === "") + bikeImageSource = "images/bike.png"; + else + bikeImageSource = "images/bike-" + selectedComponent + ".png"; + + if (selectedComponent === "battery") { + componentName = "Battery"; + primaryDetails = "Health"; + primaryDetailsValue = "85%"; + primaryDetailsOk = true; + statusLineLength = 280; + } else if (selectedComponent === "brakes") { + componentName = "Brakes"; + primaryDetails = "Health"; + primaryDetailsValue = "85%"; + primaryDetailsOk = true; + statusLineLength = 448; + } else if (selectedComponent === "chain") { + componentName = "Chain"; + primaryDetails = "Health"; + primaryDetailsValue = "85%"; + primaryDetailsOk = true; + statusLineLength = 0; + } else if (selectedComponent === "gears") { + componentName = "Gears"; + primaryDetails = "Health"; + primaryDetailsValue = "85%"; + primaryDetailsOk = true; + statusLineLength = 245; + } else if (selectedComponent === "light") { + componentName = "Light"; + primaryDetails = "Health"; + primaryDetailsValue = "85%"; + primaryDetailsOk = true; + statusLineLength = 300; + } else if (selectedComponent === "frontwheel") { + componentName = "Front wheel"; + primaryDetails = "Tire pressure"; + primaryDetailsValue = "6.8 bar / 100 psi"; + primaryDetailsOk = true; + statusLineLength = 340; + } else if (selectedComponent === "rearwheel") { + componentName = "Rear wheel"; + primaryDetails = "Tire pressure"; + primaryDetailsValue = "4.0 bar / 58 psi"; + primaryDetailsOk = false; + statusLineLength = 210; + } + } + + Text { + id: bikeInfoText + anchors { + top: parent.top + left: parent.left + right: parent.right + } + height: UILayout.configurationItemHeight + width: parent.width + text: qsTr("BIKE INFO") + font { + family: "Montserrat, Medium" + weight: Font.Medium + pixelSize: UILayout.configurationTitleSize + } + color: Colors.tabTitleColor + verticalAlignment: Text.AlignVCenter + } + + ColumnSpacer { + id: spacer + anchors.top: bikeInfoText.bottom + color: Colors.tabItemBorder + } + + + Image { + id: bikeImage + anchors { + top: spacer.bottom + right: parent.right + rightMargin: -30 + } + source: bikeImageSource + } + + Rectangle { + id: brakesCircle + width: 2 * UILayout.bikeInfoCircleRadius + height: 2 * UILayout.bikeInfoCircleRadius + radius: UILayout.bikeInfoCircleRadius + anchors { + verticalCenter: bikeImage.top + verticalCenterOffset: 43 + horizontalCenter: bikeImage.left + horizontalCenterOffset: 243 + } + + color: "transparent" + border.width: UILayout.bikeInfoLineWidth + border.color: selectedComponent === "brakes" ? Colors.bikeInfoLineOk : Colors.bikeInfoDeselected + + MouseArea { + anchors.fill: parent + onClicked: { + activeComponent = brakesCircle; + selectedComponent = "brakes" + updateComponent() + } + } + } + + Rectangle { + id: lightCircle + width: 2 * UILayout.bikeInfoCircleRadius + height: 2 * UILayout.bikeInfoCircleRadius + radius: UILayout.bikeInfoCircleRadius + anchors { + verticalCenter: bikeImage.top + verticalCenterOffset: 77 + horizontalCenter: bikeImage.left + horizontalCenterOffset: 252 + } + + color: "transparent" + border.width: UILayout.bikeInfoLineWidth + border.color: selectedComponent === "light" ? Colors.bikeInfoLineOk : Colors.bikeInfoDeselected + + MouseArea { + anchors.fill: parent + onClicked: { + activeComponent = lightCircle; + selectedComponent = "light" + updateComponent() + } + } + } + + Rectangle { + id: batteryCircle + width: 2 * UILayout.bikeInfoCircleRadius + height: 2 * UILayout.bikeInfoCircleRadius + radius: UILayout.bikeInfoCircleRadius + anchors { + verticalCenter: bikeImage.top + verticalCenterOffset: 106 + horizontalCenter: bikeImage.left + horizontalCenterOffset: 200 + } + + color: "transparent" + border.width: UILayout.bikeInfoLineWidth + border.color: selectedComponent === "battery" ? Colors.bikeInfoLineOk : Colors.bikeInfoDeselected + + MouseArea { + anchors.fill: parent + onClicked: { + activeComponent = batteryCircle; + selectedComponent = "battery" + updateComponent() + } + } + } + + Rectangle { + id: gearsCircle + width: 2 * UILayout.bikeInfoCircleRadius + height: 2 * UILayout.bikeInfoCircleRadius + radius: UILayout.bikeInfoCircleRadius + anchors { + verticalCenter: bikeImage.top + verticalCenterOffset: 143 + horizontalCenter: bikeImage.left + horizontalCenterOffset: 106 + } + + color: "transparent" + border.width: UILayout.bikeInfoLineWidth + border.color: selectedComponent === "gears" ? Colors.bikeInfoLineOk : Colors.bikeInfoDeselected + + MouseArea { + anchors.fill: parent + onClicked: { + activeComponent = gearsCircle; + selectedComponent = "gears" + updateComponent() + } + } + } + + Rectangle { + id: rearWheelCircle + width: 2 * UILayout.bikeInfoCircleRadius + height: 2 * UILayout.bikeInfoCircleRadius + radius: UILayout.bikeInfoCircleRadius + anchors { + verticalCenter: bikeImage.top + verticalCenterOffset: 144 + horizontalCenter: bikeImage.left + horizontalCenterOffset: 56 + } + + color: "transparent" + border.width: UILayout.bikeInfoLineWidth + border.color: selectedComponent === "rearwheel" ? Colors.bikeInfoLineWarning : Colors.bikeInfoDeselected + + MouseArea { + anchors.fill: parent + onClicked: { + activeComponent = rearWheelCircle; + selectedComponent = "rearwheel" + updateComponent() + } + } + + Image { + anchors.centerIn: parent + source: "images/warning.png" + } + } + + Rectangle { + id: frontWheelCircle + width: 2 * UILayout.bikeInfoCircleRadius + height: 2 * UILayout.bikeInfoCircleRadius + radius: UILayout.bikeInfoCircleRadius + anchors { + verticalCenter: bikeImage.top + verticalCenterOffset: 144 + horizontalCenter: bikeImage.left + horizontalCenterOffset: 322 + } + + color: "transparent" + border.width: UILayout.bikeInfoLineWidth + border.color: selectedComponent === "frontwheel" ? Colors.bikeInfoLineOk : Colors.bikeInfoDeselected + + MouseArea { + anchors.fill: parent + onClicked: { + activeComponent = frontWheelCircle; + selectedComponent = "frontwheel" + updateComponent() + } + } + } + + Canvas { + id: slantedLine + anchors { + left: statusLineHorizontal.right + top: statusLineHorizontal.top + right: activeComponent.horizontalCenter + bottom: activeComponent.verticalCenter + } + + onPaint: { + var ctx = getContext("2d"); + ctx.reset(); + + // Calculate line length and subtract circle radius + var lineLength = Math.sqrt(slantedLine.width * slantedLine.width + + slantedLine.height * slantedLine.height); + lineLength -= UILayout.bikeInfoCircleRadius; + + // Calculate angle + var angle = Math.atan2(slantedLine.height, slantedLine.width); + + // Calculate new endpoints + var x = Math.cos(angle) * lineLength; + var y = Math.sin(angle) * lineLength; + + ctx.lineCap = "round"; + ctx.strokeStyle = statusLineColor; + ctx.lineWidth = UILayout.bikeInfoLineWidth; + ctx.beginPath(); + ctx.moveTo(0, 1); + ctx.lineTo(x, y); + ctx.stroke(); + } + } + + Image { + id: componentStatusImage + anchors { + verticalCenter: spacer.bottom + verticalCenterOffset: (UILayout.bikeInfoComponentBaselineOffset + UILayout.bikeInfoComponentLineOffset) / 2 + left: parent.left + } + source: componentStatusImageSource + visible: selectedComponent != "" + } + + Text { + id: componentNameText + anchors { + baseline: spacer.bottom + baselineOffset: UILayout.bikeInfoComponentBaselineOffset + left: componentStatusImage.right + leftMargin: 5 + } + font { + family: "Montserrat, Medium" + weight: Font.Medium + pixelSize: UILayout.bikeInfoComponentHeaderTextSize + } + color: Colors.bikeInfoComponentHeader + text: componentName + visible: selectedComponent != "" + } + + // The line goes here somehow + Rectangle { + id: statusLineHorizontal + anchors { + top: componentNameText.baseline + topMargin: UILayout.bikeInfoComponentLineOffset + left: parent.left + } + height: UILayout.bikeInfoLineWidth + width: statusLineLength + color: statusLineColor + visible: selectedComponent != "" + } + + Text { + id: primaryDetailsText + anchors { + baseline: statusLineHorizontal.bottom + baselineOffset: UILayout.bikeInfoLineDetailsMargin + left: parent.left + } + font { + family: "Montserrat, Light" + weight: Font.Light + pixelSize: UILayout.bikeInfoInfoHeaderTextSize + } + color: Colors.bikeInfoComponentText + text: primaryDetails + visible: selectedComponent != "" + } + + Text { + id: primaryDetailsValueText + anchors { + baseline: primaryDetailsText.baseline + baselineOffset: UILayout.bikeInfoDetailsValueMargin + left: parent.left + } + font { + family: "Montserrat, Medium" + weight: Font.Medium + pixelSize: UILayout.bikeInfoInfoHeaderTextSize + } + color: primaryDetailsOk ? Colors.bikeInfoComponentOk : Colors.bikeInfoComponentWarning + text: primaryDetailsValue + visible: selectedComponent != "" + } + + Text { + id: lastMaintenanceText + anchors { + baseline: primaryDetailsValueText.baseline + baselineOffset: UILayout.bikeInfoDetailsBaselineMargin + left: parent.left + } + font { + family: "Montserrat, Light" + weight: Font.Light + pixelSize: UILayout.bikeInfoInfoHeaderTextSize + } + color: Colors.bikeInfoComponentText + text: qsTr("Last maintenance") + visible: selectedComponent != "" + } + + Text { + id: lastMaintenanceValueText + anchors { + baseline: lastMaintenanceText.baseline + baselineOffset: UILayout.bikeInfoDetailsValueMargin + left: parent.left + } + font { + family: "Montserrat, Medium" + weight: Font.Medium + pixelSize: UILayout.bikeInfoInfoHeaderTextSize + } + color: Colors.bikeInfoComponentOk + text: "10/3/2017" + visible: selectedComponent != "" + } + + Text { + id: nextMaintenanceText + anchors { + baseline: lastMaintenanceValueText.baseline + baselineOffset: UILayout.bikeInfoDetailsBaselineMargin + left: parent.left + } + font { + family: "Montserrat, Light" + weight: Font.Light + pixelSize: UILayout.bikeInfoInfoHeaderTextSize + } + color: Colors.bikeInfoComponentText + text: qsTr("Scheduled maintenance") + visible: selectedComponent != "" + } + + Text { + id: nextMaintenanceValueText + anchors { + baseline: nextMaintenanceText.baseline + baselineOffset: UILayout.bikeInfoDetailsValueMargin + left: parent.left + } + font { + family: "Montserrat, Medium" + weight: Font.Medium + pixelSize: UILayout.bikeInfoInfoHeaderTextSize + } + color: Colors.bikeInfoComponentOk + text: "10/3/2018" + visible: selectedComponent != "" + } +} diff --git a/basicsuite/ebike-ui/BikeStyle/Colors.qml b/basicsuite/ebike-ui/BikeStyle/Colors.qml new file mode 100644 index 0000000..0086c7e --- /dev/null +++ b/basicsuite/ebike-ui/BikeStyle/Colors.qml @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +pragma Singleton +import QtQuick 2.9 + +QtObject { + readonly property color clockText: "#d7dbe4" + readonly property color clockBackground: "#020611" + readonly property color mainBackground: "#1b1f2a" + readonly property color separator: "#040809" + readonly property color dottedRing: "#52576b" + readonly property color distanceText: "#ffffff" + readonly property color distanceUnit: "#acafbc" + readonly property color speedViewBackgroundCornered: "#020611" + readonly property color speedText: "#ffffff" + readonly property color speedUnit: "#acafbc" + readonly property color averageSpeedText: "#ffffff" + readonly property color averageSpeedUnit: "#acafbc" + readonly property color assistDistanceText: "#ffffff" + readonly property color assistDistanceUnit: "#acafbc" + readonly property color modeSelected: "#a0e63e" + readonly property color modeUnselected: "#acafbc" + readonly property color speedGradientStart: "#fcff2a" + readonly property color speedGradientEnd: "#41cd52" + readonly property color batteryGradientStart: "#34daea" + readonly property color batteryGradientEnd: "#3aeb95" + readonly property color assistPowerGradientStart: "#ffd200" + readonly property color assistPowerGradientEnd: "#f7971e" + readonly property color assistPowerEmpty: "#52576b" + readonly property color musicPlayerBackground: "#020611" + readonly property color musicPlayerSongText: "#d7dbe4" + readonly property color musicPlayerTimeText: "#989ba8" + readonly property color naviPageSuggestionBorder: "#a0e63e" + readonly property color naviPageSuggestionText: "#1b1f2a" + readonly property color naviPageSuggestionsDivider: "#989ba8" + readonly property color naviPageIconBackground: "#1b1f2a" + readonly property color naviPageIconPressedBackground: "#a0e63e" + readonly property color naviPageTripBackground: "#1b1f2a" + readonly property color naviPageTripDivider: "#acafbc" + readonly property color naviPageGuideBackground: "#1b1f2a" + readonly property color naviPageGuideTextColor: "#ffffff" + readonly property color naviPageGuideUnitColor: "#acafbc" + readonly property color naviPageGuideAddressColor: "#ffffff" + readonly property color curtainBackground: "#020611" + readonly property color tabBackground: "#020611" + readonly property color activeTabBorder: "#a0e63e" + readonly property color activeTabIcon: "#ffffff" + readonly property color tabIcon: "#989ba8" + readonly property color tabTitleColor: "#ffffff" + readonly property color tabItemColor: "#989ba8" + readonly property color tabItemBorder: "#1b1f2a" + readonly property color languageTextColor: "#acafbc" + readonly property color checkboxBorderColorChecked: "#a0e63e" + readonly property color checkboxBorderColor: "#acafbc" + readonly property color checkboxCheckedText: "#ffffff" + readonly property color checkboxUncheckedBackground: "#020611" + readonly property color sliderBackground: "#52576b" + readonly property color sliderInnerBackground: "#000000" + readonly property color sliderMinimumValue: "#fcff2a" + readonly property color sliderMaximumValue: "#41cd52" + readonly property color activeButtonBackground: "#a0e63e" + readonly property color inactiveButtonBackground: "#020611" + readonly property color activeButtonText: "#020611" + readonly property color inactiveButtonText: "#acafbc" + readonly property color inactiveButtonBorder: "#acafbc" + readonly property color switchOn: "#a0e63e" + readonly property color switchOff: "#ffffff" + readonly property color switchBackgroundOn: "#4da0e63e" + readonly property color switchBackgroundOff: "#52576b" + readonly property color bikeInfoDeselected: "#ffffff" + readonly property color bikeInfoLineOk: "#a0e63e" + readonly property color bikeInfoLineWarning: "#d4145a" + readonly property color bikeInfoComponentHeader: "#ffffff" + readonly property color bikeInfoComponentText: "#acafbc" + readonly property color bikeInfoComponentOk: "#ffffff" + readonly property color bikeInfoComponentWarning: "#d4145a" + readonly property color chartSpeed: "#a0e63e" + readonly property color chartAssistpower: "#34daea" + readonly property color chartLegend: "#ffffff" + readonly property color chartLabel: "#989ba8" + readonly property color chartTimeLabel: "#acafbc" + readonly property color chartGridLine: "#111520" + readonly property color statsButtonPressed: "#a0e63e" + readonly property color statsButtonInactive: "#52576b" + readonly property color statsButtonActive: "#848794" + readonly property color statsButtonInactiveText: "#52576b" + readonly property color statsButtonActiveText: "#ffffff" + readonly property color statsDescriptionText: "#989ba8" + readonly property color statsValueText: "#ffffff" + readonly property color statsSeparator: "#111520" +} diff --git a/basicsuite/ebike-ui/BikeStyle/UILayout.qml b/basicsuite/ebike-ui/BikeStyle/UILayout.qml new file mode 100644 index 0000000..55f6baf --- /dev/null +++ b/basicsuite/ebike-ui/BikeStyle/UILayout.qml @@ -0,0 +1,257 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +pragma Singleton +import QtQuick 2.9 + +QtObject { + readonly property int clockBaselineMargin: 25 + readonly property int clockFontSize: 18 + + readonly property int statsIconTop: 56 + readonly property int statsIconLeft: 50 + readonly property int statsIconSeparator: 20 + readonly property int statsIconWidth: 40 + readonly property int statsIconHeight: 40 + readonly property int statsTextSeparator: 15 + readonly property int statsTextSize: 20 + readonly property int statsTextTopOffset: 0 + readonly property int statsUnitBaselineOffset: 0 + + readonly property int lightsIconBottom: 90 + readonly property int lightsIconLeft: 50 + readonly property int lightsIconWidth: 80 + readonly property int lightsIconHeight: 80 + + readonly property int naviModeCenterMargin: 90 + + readonly property int naviIconTop: 45 + readonly property int naviIconRight: 50 + readonly property int naviIconWidth: 80 + readonly property int naviIconHeight: 80 + readonly property int naviTextSize: 26 + readonly property int naviTextMargin: 30 + + readonly property int modeBottomOffset: 84 + readonly property int modeDistance: 50 + readonly property int modeTextSize: 20 + + readonly property int speedViewTop: 78 + readonly property int speedViewRadius: 150 /* Normal mode */ + readonly property int speedViewRadiusMinified: 90 /* Minified to corner mode */ + readonly property int speedViewRadiusEnlarged: 205 /* Enlarged to full screen mode */ + readonly property int speedViewDots: 96 + readonly property int speedViewDotsMinified: 48 + readonly property int speedViewDotsEnlarged: 128 + readonly property int speedViewCornerLeftMargin: 15 + readonly property int speedViewCornerBottomMargin: 15 + readonly property int speedViewInnerRadius: 125 + readonly property int speedViewInnerRadiusMinified: 65 + readonly property int speedViewInnerRadiusEnlarged: 185 + readonly property int speedViewInnerWidth: 12 + readonly property int speedViewInnerWidthMinified: 8 + readonly property double speedViewSpeedStart: Math.PI * 0.5 + Math.PI / 30 + readonly property double speedViewSpeedEnd: Math.PI * 1.5 - Math.PI / 30 + readonly property double speedViewBatteryStart: Math.PI * 0.5 - Math.PI / 30 + readonly property double speedViewBatteryEnd: -Math.PI * 0.5 + Math.PI / 30 + readonly property double speedViewAssistPowerStart: Math.PI * 0.5 + Math.PI / 34 + readonly property double speedViewAssistPowerEnd: Math.PI * 0.5 - Math.PI / 34 + readonly property int speedViewAssistPowerWidth: 6 + readonly property int speedViewAssistPowerRadius: 230 + readonly property int speedViewAssistPowerBottomOffset: 104 + readonly property int speedBaselineOffset: 137 + readonly property int speedBaselineOffsetMinified: 73 + readonly property int speedBaselineOffsetEnlarged: 155 + readonly property int speedTextSize: 108 + readonly property int speedTextSizeMinified: 80 + readonly property int speedTextSizeEnlarged: 190 + readonly property int speedUnitsSize: 14 + readonly property int speedUnitsSizeEnlarged: 18 + readonly property int speedTextUnitMargin: 24 + readonly property int speedTextUnitMarginMinified: 18 + readonly property int speedTextUnitMarginEnlarged: 30 + readonly property int speedIconsCenterOffset: 71 + readonly property int speedIconsCenterOffsetEnlarged: 111 + readonly property int speedInfoTextsOffsetEnlarged: -34 + readonly property int speedInfoTextsSize: 38 + readonly property int speedInfoTextsSizeEnlarged: 64 + readonly property int speedInfoUnitsOffset: 24 + readonly property int speedInfoUnitsOffsetEnlarged: 34 + readonly property int averageSpeedIconMargin: -5 + readonly property int averageSpeedIconWidth: 40 + readonly property int averageSpeedIconHeight: 40 + readonly property int assistDistanceIconMargin: -5 + readonly property int assistDistanceIconWidth: 40 + readonly property int assistDistanceIconHeight: 40 + readonly property int assistPowerIconOffset: 49 + readonly property int assistPowerIconOffsetEnlarged: 100 + readonly property int assistPowerIconWidth: 30 + readonly property int assistPowerIconHeight: 30 + readonly property int assistPowerCircleRadius: 6 + readonly property int assistPowerCircleOffset: 8 + readonly property int assistPowerCircleVerticalOffset: 5 + readonly property int assistPowerCircleTopMargin: 7 + readonly property int speedometerCornerArrowWidth: 40 + readonly property int speedometerCornerArrowHeight: 40 + readonly property int ringValueText: 14 + + readonly property int musicPlayerWidth: 260 + readonly property int musicPlayerHeight: 75 + readonly property int musicPlayerCorner: 20 + readonly property int musicPlayerIconWidth: 40 + readonly property int musicPlayerIconHeight: 40 + readonly property int musicPlayerIconBottom: 5 + readonly property int musicPlayerIconSpacing: 50 + readonly property int musicPlayerTextBottom: 5 + readonly property int musicPlayerTextSize: 16 + + readonly property int naviPageLocationWidth: 300 + readonly property int naviPageLocationHeight: 40 + readonly property int naviPageLocationRadius: 20 + readonly property int naviPageLocationTopMargin: 60 + readonly property int naviPageLocationLeftPadding: 20 + readonly property int naviPageIconBackgroundWidth: 50 + readonly property int naviPageIconBackgroundHeight: 50 + readonly property int naviPageIconBackgroundRadius: 25 + readonly property int naviPageIconWidth: 40 + readonly property int naviPageIconHeight: 40 + readonly property int naviPageIconTopMargin: 15 + readonly property int naviPageIconRightMargin: 15 + readonly property int naviPageIconSpacing: 15 + readonly property int naviPageSuggestionsOffset: 5 + readonly property int naviPageSuggestionHeight: 40 + readonly property int naviPageSuggestionTextSize: 16 + + readonly property int naviPageSearchIconWidth: 40 + readonly property int naviPageSearchIconHeight: 40 + readonly property int naviPageSearchIconMargin: 5 + readonly property int naviPageSearchTextSize: 16 + + readonly property int naviPageTripWidth: 220 + readonly property int naviPageTripHeight: 40 + readonly property int naviPageTripRadius: 20 + readonly property int naviPageTripDividerWidth: 2 + readonly property int naviPageTripDividerHeight: 20 + readonly property int naviPageTripBottomMargin: 15 + readonly property int naviPageTripSearchMargin: 15 + readonly property int naviPageTripTotalTextSize: 18 + readonly property int naviPageTripTotalUnitSize: 18 + + readonly property int naviPageGuideRadius: 90 + readonly property int naviPageGuideRightMargin: 15 + readonly property int naviPageGuideBottomMargin: 15 + readonly property int naviPageGuideArrowTopMargin: 30 + readonly property int naviPageGuideArrowLeftMargin: 50 + readonly property int naviPageGuideArrowWidth: 80 + readonly property int naviPageGuideArrowHeight: 80 + readonly property int naviPageGuideAddressBaselineMargin: 20 + readonly property int naviPageGuideAddressRightMargin: 20 + readonly property int naviPageGuideAddressTextSize: 14 + readonly property int naviPageGuideDistanceBaselineMargin: 20 + readonly property int naviPageGuideDistanceTextSize: 26 + readonly property int naviPageGuideUnitTextSize: 26 + + readonly property int tabBarTabHeight: 60 + readonly property int tabBarFontSize: 24 + readonly property int tabButtonTopMargin: 13 + readonly property int tabButtonIconWidth: 40 + readonly property int tabButtonIconHeight: 40 + readonly property int curtainMargin: 30 + readonly property int curtainCloseHeight: 30 + readonly property int configurationItemHeight: 59 + readonly property int configurationItemSeparator: 1 + readonly property int configurationTextSize: 18 + readonly property int configurationTitleSize: 18 + readonly property int languageTextSize: 18 + readonly property int checkboxWidth: 20 + readonly property int checkboxHeight: 20 + readonly property int checkboxRadius: 5 + readonly property int checkboxLabelSize: 16 + readonly property int checkboxTextOffset: 10 + readonly property int checkboxSliderOffset: 20 + readonly property int sliderHandleRadius: 10 + readonly property int sliderHandleRadiusInner: 6 + readonly property int sliderWidth: 256 + readonly property int sliderHeight: 4 + readonly property int switchWidth: 50 + readonly property int switchHeight: 20 + readonly property int switchIndicatorRadius: 15 + readonly property int unitButtonWidthMargin: 20 + readonly property int unitButtonHeight: 40 + readonly property int unitButtonSpacing: 10 + readonly property int unitFontSize: 16 + readonly property int bikeInfoComponentBaselineOffset: 30 + readonly property int bikeInfoComponentLineOffset: 14 + readonly property int bikeInfoLineWidth: 2 + readonly property int bikeInfoLineDetailsMargin: 24 + readonly property int bikeInfoDetailsValueMargin: 20 + readonly property int bikeInfoDetailsBaselineMargin: 30 + readonly property int bikeInfoComponentHeaderTextSize: 18 + readonly property int bikeInfoInfoHeaderTextSize: 18 + readonly property int bikeInfoCircleRadius: 17 + + readonly property int statsTripButtonWidth: 40 + readonly property int statsTripButtonHeight: 40 + readonly property int statsTripButtonMarginSide: 30 + readonly property int statsTripButtonMarginTop: 60 + readonly property int statsEndtripWidth: 150 + readonly property int statsEndtripHeight: 40 + readonly property int statsEndtripMargin: 60 + readonly property int statsEndtripTextSize: 16 + readonly property int statsDescriptionTextSize: 18 + readonly property int statsValueTextSize: 18 + readonly property int statsOdometerMarginRight: 30 + readonly property int statsOdometerBaselineOffset: 40 + readonly property int statsTopMargin: 28 + readonly property int statsHeight: 39 + readonly property int statsCenterOffset: 30 + readonly property int chartWidth: 440 + readonly property int chartHeight: 200 + readonly property int chartBottomMargin: 0 + readonly property int chartRightMargin: 0 + readonly property int chartLegendTextSize: 14 + readonly property int chartTimeLabelSize: 14 + readonly property int chartSpeedLabelSize: 14 + readonly property int chartAssistpowerLabelSize: 14 + + readonly property int topViewHeight: 229 + readonly property int bottomViewHeight: 251 + readonly property int horizontalViewSeparatorHeight: 1 + readonly property int horizontalViewSeparatorWidth: 170 + readonly property int verticalViewSeparatorHeightTop: 110 + readonly property int verticalViewSeparatorHeightBottom: 132 + readonly property int verticalViewSeparatorWidth: 1 +} diff --git a/basicsuite/ebike-ui/BikeStyle/qmldir b/basicsuite/ebike-ui/BikeStyle/qmldir new file mode 100644 index 0000000..e8e9d2f --- /dev/null +++ b/basicsuite/ebike-ui/BikeStyle/qmldir @@ -0,0 +1,2 @@ +singleton Colors 1.0 Colors.qml +singleton UILayout 1.0 UILayout.qml diff --git a/basicsuite/ebike-ui/ClockView.qml b/basicsuite/ebike-ui/ClockView.qml new file mode 100644 index 0000000..21310c0 --- /dev/null +++ b/basicsuite/ebike-ui/ClockView.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.7 +import "./BikeStyle" +// Permanent placeholder for time display +Item { + width: backgroundImage.width + height: backgroundImage.height + z: 1 + + // Timer that will show the current time at the top of the screen + Timer { + interval: 500; running: true; repeat: true + onTriggered: timeLabel.text = new Date().toLocaleTimeString(Qt.locale("en_US"), Locale.ShortFormat) + } + + Image { + id: backgroundImage + source: "images/top_curtain_drag.png" + anchors.centerIn: parent + } + + Text { + id: timeLabel + anchors { + horizontalCenter: parent.horizontalCenter + baseline: parent.top + baselineOffset: UILayout.clockBaselineMargin + } + color: Colors.clockText + text: "--:--" + font { + family: "Montserrat, Medium" + weight: Font.Medium + pixelSize: UILayout.clockFontSize + } + } +} diff --git a/basicsuite/ebike-ui/ColumnSpacer.qml b/basicsuite/ebike-ui/ColumnSpacer.qml new file mode 100644 index 0000000..2cdfe98 --- /dev/null +++ b/basicsuite/ebike-ui/ColumnSpacer.qml @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +import "./BikeStyle" + +Rectangle { + height: UILayout.configurationItemSeparator + width: parent.width + color: Colors.tabItemBorder +} diff --git a/basicsuite/ebike-ui/ConfigurationDrawer.qml b/basicsuite/ebike-ui/ConfigurationDrawer.qml new file mode 100644 index 0000000..258a264 --- /dev/null +++ b/basicsuite/ebike-ui/ConfigurationDrawer.qml @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.9 +import QtQuick.Controls 2.2 +import QtQuick.Layouts 1.3 +import "./BikeStyle" + +Drawer { + property alias bikeInfoTab: bikeInfoTab + property alias generalTab: generalTab + property alias viewTab: viewTab + + background: Rectangle { + color: Colors.curtainBackground + width: parent.width + height: parent.height + } + + TabBar { + id: bar + anchors { + left: parent.left + right: parent.right + leftMargin: UILayout.curtainMargin + rightMargin: UILayout.curtainMargin + } + height: UILayout.tabBarTabHeight + background: Rectangle { + color: Colors.curtainBackground + } + + IconifiedTabButton { + id: bikeInfoTabButton + height: parent.height + bar: bar + deselectedIcon: "images/info.png" + selectedIcon: "images/info_selected.png" + } + + IconifiedTabButton { + id: configurationTabButton + height: parent.height + bar: bar + deselectedIcon: "images/settings.png" + selectedIcon: "images/settings_selected.png" + } + + IconifiedTabButton { + id: viewTabButton + height: parent.height + bar: bar + deselectedIcon: "images/list.png" + selectedIcon: "images/list_selected.png" + } + } + + StackLayout { + id: stackLayout + anchors { + left: parent.left + right: parent.right + top: bar.bottom + leftMargin: UILayout.curtainMargin + rightMargin: UILayout.curtainMargin + } + height: 290 + currentIndex: bar.currentIndex + + BikeInfoTab { + id: bikeInfoTab + } + + GeneralTab { + id: generalTab + } + + ViewTab { + id: viewTab + + onResetDemo: { + // Reset trip data + datastore.resetDemo() + // Reset navigation + naviPage.resetDemo() + } + } + } + + Rectangle { + id: drawerClose + anchors { + top: stackLayout.bottom + left: parent.left + right: parent.right + } + + width: parent.width + height: drawerCloseImage.implicitHeight + color: "transparent" + + Image { + id: drawerCloseImage + source: "images/curtain_shadow_handle.png" + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + } + + MouseArea { + anchors.fill: parent + onClicked: drawer.close() + } + } +} diff --git a/basicsuite/ebike-ui/ConfigurationItem.qml b/basicsuite/ebike-ui/ConfigurationItem.qml new file mode 100644 index 0000000..350e910 --- /dev/null +++ b/basicsuite/ebike-ui/ConfigurationItem.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.9 + +import "./BikeStyle" + +Rectangle { + property string description + + color: "transparent" + height: UILayout.configurationItemHeight + width: parent.width + + Text { + anchors { + top: parent.top + bottom: parent.bottom + left: parent.left + } + text: description + font { + family: "Montserrat, Light" + weight: Font.Light + pixelSize: UILayout.configurationTextSize + } + color: Colors.tabItemColor + verticalAlignment: Text.AlignVCenter + } +} diff --git a/basicsuite/ebike-ui/FpsItem.qml b/basicsuite/ebike-ui/FpsItem.qml new file mode 100644 index 0000000..0ab183d --- /dev/null +++ b/basicsuite/ebike-ui/FpsItem.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + id: fpsItem + property int frameCounter: 0 + property int fpsValue: 0; + + width: spinnerImage.width + fpsText.width + height: 48 + z: 1 + + Image { + id: spinnerImage + source: "images/fps_icon.png" + NumberAnimation on rotation { + from: 0 + to: 360 + duration: 800 + loops: Animation.Infinite + } + onRotationChanged: frameCounter++; + } + + Text { + id: fpsText + anchors.right: parent.right + anchors.verticalCenter: spinnerImage.verticalCenter + color: "red" + text: "Fps: " + fpsItem.fpsValue + } + + Timer { + interval: 2000 + repeat: true + running: true + onTriggered: { + fpsValue = frameCounter / 2; + frameCounter = 0; + } + } +} diff --git a/basicsuite/ebike-ui/GeneralTab.qml b/basicsuite/ebike-ui/GeneralTab.qml new file mode 100644 index 0000000..697a451 --- /dev/null +++ b/basicsuite/ebike-ui/GeneralTab.qml @@ -0,0 +1,279 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.9 +import QtQuick.Controls 2.2 +import QtQuick.Layouts 1.3 +import DataStore 1.0 + +import "./BikeStyle" + +Item { + Column { + anchors.left: parent.left + anchors.right: parent.right + + Text { + height: UILayout.configurationItemHeight + width: parent.width + text: qsTr("GENERAL") + font { + family: "Montserrat, Medium" + weight: Font.Medium + pixelSize: UILayout.configurationTitleSize + } + color: Colors.tabTitleColor + verticalAlignment: Text.AlignVCenter + } + + ColumnSpacer { + color: Colors.tabItemBorder + } + + ConfigurationItem { + description: qsTr("Language") + + Text { + anchors { + top: parent.top + bottom: parent.bottom + right: parent.right + } + text: qsTr("English") + font { + family: "Montserrat, Medium" + weight: Font.Medium + pixelSize: UILayout.languageTextSize + } + color: Colors.languageTextColor + verticalAlignment: Text.AlignVCenter + } + } + + ColumnSpacer { + color: Colors.tabItemBorder + } + + ConfigurationItem { + description: qsTr("Brightness") + + Text { + anchors { + right: autoBrightness.left + rightMargin: UILayout.checkboxTextOffset + verticalCenter: autoBrightness.verticalCenter + } + text: qsTr("Auto") + font { + family: "Montserrat, Medium" + weight: Font.Medium + pixelSize: UILayout.checkboxLabelSize + } + color: Colors.checkboxCheckedText + } + + CheckBox { + id: autoBrightness + width: UILayout.checkboxWidth + anchors { + right: brightnessSlider.left + rightMargin: UILayout.checkboxSliderOffset + verticalCenter: brightnessSlider.verticalCenter + } + checked: brightness.automatic + + indicator: Rectangle { + implicitWidth: UILayout.checkboxWidth + implicitHeight: UILayout.checkboxHeight + y: parent.height / 2 - height / 2 + radius: UILayout.checkboxRadius + color: Colors.checkboxUncheckedBackground + border.color: autoBrightness.checked ? Colors.checkboxBorderColorChecked : Colors.checkboxBorderColor + border.width: autoBrightness.checked ? 2 : 1 + + Image { + source: "images/checkmark.png" + anchors.centerIn: parent + visible: autoBrightness.checked + } + } + + contentItem: Item {} + + onToggled: brightness.automatic = checked + } + + Slider { + id: brightnessSlider + value: 4 + anchors { + top: parent.top + bottom: parent.bottom + right: parent.right + } + from: 6 + to: 1 + stepSize: -1 + snapMode: Slider.SnapAlways + onMoved: brightness.brightness = value + + background: Rectangle { + x: brightnessSlider.leftPadding + y: brightnessSlider.topPadding + brightnessSlider.availableHeight / 2 - height / 2 + implicitWidth: UILayout.sliderWidth + implicitHeight: UILayout.sliderHeight + width: brightnessSlider.availableWidth + height: implicitHeight + radius: UILayout.sliderHeight / 2 + color: Colors.sliderBackground + + Rectangle { + // Since gradient is only available vertically, we must draw and rotate + width: parent.height + height: brightnessSlider.visualPosition * parent.width + radius: UILayout.sliderHeight / 2 + gradient: Gradient { + GradientStop { position: 0; color: Colors.sliderMinimumValue } + GradientStop { position: 1; color: Colors.sliderMaximumValue } + } + + transform: Rotation { origin.x: 0; origin.y: UILayout.sliderHeight; angle: -90} + } + } + + handle: Rectangle { + x: brightnessSlider.leftPadding + brightnessSlider.visualPosition * (brightnessSlider.availableWidth - width) + y: brightnessSlider.topPadding + brightnessSlider.availableHeight / 2 - height / 2 + implicitWidth: 2 * UILayout.sliderHandleRadius + implicitHeight: 2 * UILayout.sliderHandleRadius + radius: UILayout.sliderHandleRadius + color: Colors.sliderMaximumValue + + Rectangle { + anchors.centerIn: parent + implicitWidth: 2 * UILayout.sliderHandleRadiusInner + implicitHeight: 2 * UILayout.sliderHandleRadiusInner + radius: UILayout.sliderHandleRadiusInner + color: Colors.sliderInnerBackground + } + } + } + } + + ColumnSpacer { + color: Colors.tabItemBorder + } + + ConfigurationItem { + description: qsTr("Units") + + RoundButton { + id: kmhButton + width: UILayout.unitButtonWidthMargin * 2 + kmhText.implicitWidth + height: UILayout.unitButtonHeight + radius: height / 2 + anchors { + verticalCenter: parent.verticalCenter + right: parent.right + } + + background: Rectangle { + width: parent.width + height: parent.height + radius: parent.radius + color: datastore.unit === DataStore.Kmh ? Colors.activeButtonBackground : Colors.inactiveButtonBackground + border.color: Colors.inactiveButtonBorder + border.width: datastore.unit === DataStore.Kmh ? 0 : 1 + } + + contentItem: Text { + id: kmhText + font { + family: "Montserrat, Medium" + weight: Font.Medium + pixelSize: UILayout.unitFontSize + } + text: "km/h" + color: datastore.unit === DataStore.Kmh ? Colors.activeButtonText : Colors.inactiveButtonText + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + onClicked: datastore.unit = DataStore.Kmh + } + + RoundButton { + id: mphButton + width: UILayout.unitButtonWidthMargin * 2 + mphText.implicitWidth + height: UILayout.unitButtonHeight + radius: height / 2 + anchors { + verticalCenter: parent.verticalCenter + right: kmhButton.left + rightMargin: UILayout.unitButtonSpacing + } + + background: Rectangle { + width: parent.width + height: parent.height + radius: parent.radius + color: datastore.unit === DataStore.Mph ? Colors.activeButtonBackground : Colors.inactiveButtonBackground + border.color: Colors.inactiveButtonBorder + border.width: datastore.unit === DataStore.Mph ? 0 : 1 + } + + contentItem: Text { + id: mphText + text: "mph" + font { + family: "Montserrat, Medium" + weight: Font.Medium + pixelSize: UILayout.unitFontSize + } + color: datastore.unit === DataStore.Mph ? Colors.activeButtonText : Colors.inactiveButtonText + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + onClicked: datastore.unit = DataStore.Mph + } + } + + ColumnSpacer { + color: Colors.tabItemBorder + } + } +} diff --git a/basicsuite/ebike-ui/IconifiedTabButton.qml b/basicsuite/ebike-ui/IconifiedTabButton.qml new file mode 100644 index 0000000..572ce51 --- /dev/null +++ b/basicsuite/ebike-ui/IconifiedTabButton.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 2.9 +import QtQuick.Controls 2.2 + +import "./BikeStyle" + +TabButton { + property string deselectedIcon + property string selectedIcon + property var bar + + contentItem: Image { + width: UILayout.tabButtonIconWidth + height: UILayout.tabButtonIconHeight + source: bar.currentItem === parent ? selectedIcon : deselectedIcon + fillMode: Image.Pad + anchors { + top: parent.top + topMargin: UILayout.tabButtonTopMargin + horizontalCenter: parent.horizontalCenter + } + } + + background: Rectangle { + color: Colors.tabBackground + height: parent.height + + Rectangle { + visible: bar.currentItem === parent.parent + width: parent.width + height: 2 + anchors.bottom: parent.bottom + color: Colors.activeTabBorder + } + } +} diff --git a/basicsuite/ebike-ui/LightsBox.qml b/basicsuite/ebike-ui/LightsBox.qml new file mode 100644 index 0000000..327c819 --- /dev/null +++ b/basicsuite/ebike-ui/LightsBox.qml @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.7 +import QtQuick.Extras 1.4 + +import "./BikeStyle" + +// Bottom-left corner, controls +Item { + width: 320 + height: UILayout.bottomViewHeight + + Image { + id: lightsIcon + width: UILayout.lightsIconWidth + height: UILayout.lightsIconHeight + source: datastore.lights ? "images/lights_on.png" : "images/lights_off.png" + fillMode: Image.PreserveAspectFit + anchors { + left: parent.left + leftMargin: UILayout.lightsIconLeft + bottom: parent.bottom + bottomMargin: UILayout.lightsIconBottom + } + } + + MouseArea { + anchors.fill: parent + onClicked: datastore.lights = !datastore.lights + } + + Rectangle { + width: UILayout.horizontalViewSeparatorWidth + height: UILayout.horizontalViewSeparatorHeight + anchors.top: parent.top + anchors.left: parent.left + color: Colors.separator + } + + Rectangle { + width: UILayout.verticalViewSeparatorWidth + height: UILayout.verticalViewSeparatorHeightBottom + anchors.bottom: parent.bottom + anchors.right: parent.right + color: Colors.separator + } +} diff --git a/basicsuite/ebike-ui/MainPage.qml b/basicsuite/ebike-ui/MainPage.qml new file mode 100644 index 0000000..ae36401 --- /dev/null +++ b/basicsuite/ebike-ui/MainPage.qml @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.7 +import QtQuick.Controls 2.0 +import QtQuick.Extras 1.4 + +import "./BikeStyle" + +Page { + background: Rectangle { + color: Colors.mainBackground + } + property alias statsButton: statsButton + property alias naviButton: naviButton + property alias lightsButton: lightsButton + property alias modeButton: modeButton + property string naviGuideArrowSource + property string naviGuideDistance + property string naviGuideAddress + + StatsBox { + id: statsButton + anchors.left: parent.left + anchors.top: parent.top + + MouseArea { + anchors.fill: parent + onClicked: { + swipeView.currentIndex = 0 + } + } + } + + NaviBox { + id: naviButton + anchors.right: parent.right + anchors.top: parent.top + arrowSource: naviGuideArrowSource + distance: naviGuideDistance + + MouseArea { + anchors.fill: parent + onClicked: { + swipeView.currentIndex = 2 + } + } + } + + LightsBox { + id: lightsButton + anchors.left: parent.left + anchors.bottom: parent.bottom + } + + ModeBox { + id: modeButton + anchors.right: parent.right + anchors.bottom: parent.bottom + } +} diff --git a/basicsuite/ebike-ui/ModeBox.qml b/basicsuite/ebike-ui/ModeBox.qml new file mode 100644 index 0000000..ad4eba7 --- /dev/null +++ b/basicsuite/ebike-ui/ModeBox.qml @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.7 +import QtQuick.Extras 1.4 +import DataStore 1.0 + +import "./BikeStyle" + +// Bottom-right corner, mode +Item { + width: 320 + height: UILayout.bottomViewHeight + + Text { + id: sportModeText + anchors { + baseline: parent.bottom + baselineOffset: -UILayout.modeBottomOffset + horizontalCenter: parent.right + horizontalCenterOffset: -UILayout.naviModeCenterMargin + } + color: datastore.mode == DataStore.Sport ? Colors.modeSelected : Colors.modeUnselected + font { + family: "Montserrat, Medium" + weight: Font.Medium + pixelSize: UILayout.modeTextSize + } + text: qsTr("SPORT") + } + + Text { + id: cruiseModeText + anchors { + baseline: sportModeText.baseline + baselineOffset: -UILayout.modeDistance + horizontalCenter: sportModeText.horizontalCenter + } + color: datastore.mode == DataStore.Cruise ? Colors.modeSelected : Colors.modeUnselected + font { + family: "Montserrat, Medium" + weight: Font.Medium + pixelSize: UILayout.modeTextSize + } + text: qsTr("CRUISE") + } + + MouseArea { + anchors.fill: parent + onClicked: datastore.toggleMode() + } + + Rectangle { + width: UILayout.horizontalViewSeparatorWidth + height: UILayout.horizontalViewSeparatorHeight + anchors.top: parent.top + anchors.right: parent.right + color: Colors.separator + } + + Rectangle { + width: UILayout.verticalViewSeparatorWidth + height: UILayout.verticalViewSeparatorHeightBottom + anchors.bottom: parent.bottom + anchors.left: parent.left + color: Colors.separator + } +} diff --git a/basicsuite/ebike-ui/MusicPlayer.qml b/basicsuite/ebike-ui/MusicPlayer.qml new file mode 100644 index 0000000..9d44534 --- /dev/null +++ b/basicsuite/ebike-ui/MusicPlayer.qml @@ -0,0 +1,239 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.7 + +import "./BikeStyle" + +Rectangle { + id: musicPlayer + width: UILayout.musicPlayerWidth + height: UILayout.musicPlayerHeight + UILayout.musicPlayerCorner + radius: UILayout.musicPlayerCorner + color: Colors.musicPlayerBackground + anchors { + horizontalCenter: parent.horizontalCenter + bottom: parent.bottom + bottomMargin: -UILayout.musicPlayerCorner + } + state: "hidden" + property bool isPlaying: false + property var songList: [ + ["Post Malone - Rockstar", 218], + ["Ed Sheeran - Perfect", 263], + ["Imagine Dragons - Thunder", 187] + ] + property int currentSong: 0 + + function setupSong() { + var dur = songList[currentSong][1]; + timeAnimation.stop(); + songTimeText.songDuration = dur; + timeAnimation.from = dur; + timeAnimation.to = 0; + timeAnimation.duration = dur * 1000; + if (isPlaying) + timeAnimation.start(); + } + + function previousSong() { + if (currentSong === 0) + currentSong = songList.length - 1; + else + currentSong -= 1; + setupSong(); + } + + function nextSong() { + if (currentSong >= (songList.length - 1)) + currentSong = 0; + else + currentSong += 1; + setupSong(); + } + + Component.onCompleted: setupSong() + + Image { + id: playIcon + width: UILayout.musicPlayerIconWidth + height: UILayout.musicPlayerIconHeight + source: isPlaying + ? (playIconArea.pressed ? "images/pause_pressed.png" : "images/pause.png") + : (playIconArea.pressed ? "images/play_pressed.png" : "images/play.png") + anchors { + horizontalCenter: parent.horizontalCenter + bottom: parent.bottom + bottomMargin: UILayout.musicPlayerIconBottom + UILayout.musicPlayerCorner + } + + MouseArea { + id: playIconArea + anchors { + fill: parent + margins: -UILayout.musicPlayerIconSpacing / 2 + } + onClicked: { + isPlaying = !isPlaying + if (isPlaying) { + if (timeAnimation.running) + timeAnimation.resume() + else + timeAnimation.start() + } else + timeAnimation.pause() + } + } + } + + Image { + id: previousIcon + width: UILayout.musicPlayerIconWidth + height: UILayout.musicPlayerIconHeight + source: previousIconArea.pressed ? "images/prevsong_pressed.png" : "images/prevsong.png" + anchors { + right: playIcon.left + rightMargin: UILayout.musicPlayerIconSpacing + bottom: playIcon.bottom + } + + MouseArea { + id: previousIconArea + anchors { + fill: parent + margins: -UILayout.musicPlayerIconSpacing / 2 + } + onClicked: previousSong() + } + } + + Image { + id: nextIcon + width: UILayout.musicPlayerIconWidth + height: UILayout.musicPlayerIconHeight + source: nextIconArea.pressed ? "images/nextsong_pressed.png" : "images/nextsong.png" + anchors { + left: playIcon.right + leftMargin: UILayout.musicPlayerIconSpacing + bottom: playIcon.bottom + } + + MouseArea { + id: nextIconArea + anchors { + fill: parent + margins: -UILayout.musicPlayerIconSpacing / 2 + } + onClicked: nextSong() + } + } + + Text { + id: songTitleText + anchors { + left: previousIcon.left + right: nextIcon.right + rightMargin: songTimeText.width + 5 + baseline: previousIcon.top + baselineOffset: -UILayout.musicPlayerTextBottom + } + + color: Colors.musicPlayerSongText + font { + family: "Montserrat, Regular" + weight: Font.Normal + pixelSize: UILayout.musicPlayerTextSize + } + text: songList[currentSong][0] + elide: Text.ElideRight + } + + // Function for pretty-printing duration + function splitDuration(duration) { + var minutes = Math.floor(duration / 60); + var seconds = Math.floor(duration % 60); + if (seconds < 10) + seconds = "0" + seconds; + return minutes + ":" + seconds; + } + + Text { + property int songDuration + id: songTimeText + anchors { + right: nextIcon.right + baseline: nextIcon.top + baselineOffset: -UILayout.musicPlayerTextBottom + } + + color: Colors.musicPlayerTimeText + font { + family: "Montserrat, Regular" + weight: Font.Normal + pixelSize: UILayout.musicPlayerTextSize + } + text: splitDuration(songDuration) + + NumberAnimation { + id: timeAnimation + target: songTimeText + property: "songDuration" + onStopped: { + if (isPlaying) + nextSong(); + } + } + } + + states: State { + name: "hidden" + PropertyChanges { + target: musicPlayer + anchors.bottomMargin: -musicPlayer.height + } + } + + transitions: Transition { + from: "" + to: "hidden" + reversible: true + NumberAnimation { + properties: "anchors.bottomMargin" + duration: 250 + easing.type: Easing.InOutQuad + } + } +} diff --git a/basicsuite/ebike-ui/NaviBox.qml b/basicsuite/ebike-ui/NaviBox.qml new file mode 100644 index 0000000..53b55c8 --- /dev/null +++ b/basicsuite/ebike-ui/NaviBox.qml @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.7 +import QtQuick.Controls 2.0 + +import "./BikeStyle" + +// Top-right corner, navi +Item { + width: 320 + height: UILayout.topViewHeight + property string arrowSource: "images/nav_right.png" + property string distance: "0" + property string unit: "m" + + Image { + id: naviIcon + width: UILayout.naviIconWidth + height: UILayout.naviIconHeight + source: arrowSource + anchors { + top: parent.top + topMargin: UILayout.naviIconTop + horizontalCenter: parent.right + horizontalCenterOffset: -UILayout.naviModeCenterMargin + } + } + + Item { + id: container + anchors.horizontalCenter: naviIcon.horizontalCenter + anchors.top: naviIcon.bottom + height: 30 + width: naviText.width + 5 + naviUnit.width + visible: navigation.active + + Text { + id: naviText + anchors.baseline: container.bottom + color: Colors.distanceText + font { + family: "Montserrat, Bold" + weight: Font.Bold + pixelSize: UILayout.naviTextSize + } + text: Math.round(datastore.convertSmallDistance(distance) / 10) * 10 + } + + Text { + id: naviUnit + anchors { + baseline: container.bottom + left: naviText.right + leftMargin: 5 + } + color: Colors.distanceUnit + font { + family: "Montserrat, Light" + weight: Font.Light + pixelSize: UILayout.naviTextSize + } + text: datastore.smallUnit + } + } + + Text { + id: navigateText + anchors.horizontalCenter: naviIcon.horizontalCenter + anchors.top: naviIcon.bottom + visible: !navigation.active + color: Colors.modeUnselected + font { + family: "Montserrat, Medium" + weight: Font.Medium + pixelSize: UILayout.modeTextSize + } + text: qsTr("NAVIGATE") + } + + Rectangle { + width: UILayout.horizontalViewSeparatorWidth + height: UILayout.horizontalViewSeparatorHeight + anchors.bottom: parent.bottom + anchors.right: parent.right + color: Colors.separator + } + + Rectangle { + width: UILayout.verticalViewSeparatorWidth + height: UILayout.verticalViewSeparatorHeightTop + anchors.top: parent.top + anchors.left: parent.left + color: Colors.separator + } +} diff --git a/basicsuite/ebike-ui/NaviButton.qml b/basicsuite/ebike-ui/NaviButton.qml new file mode 100644 index 0000000..a34d540 --- /dev/null +++ b/basicsuite/ebike-ui/NaviButton.qml @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.9 +import QtQuick.Controls 2.2 + +import "./BikeStyle" + +RoundButton { + property string iconSource + + width: UILayout.naviPageIconBackgroundWidth + height: UILayout.naviPageIconBackgroundHeight + radius: UILayout.naviPageIconBackgroundRadius + z: 1 + + background: Item { + id: naviButtonBackground + width: parent.width + height: parent.height + + Image { + id: naviButtonShadow + fillMode: Image.Pad + anchors { + horizontalCenter: naviButtonBackground.horizontalCenter + verticalCenter: naviButtonBackground.verticalCenter + horizontalCenterOffset: 1 + verticalCenterOffset: 1 + } + source: "images/map_btn_shadow.png" + } + + Rectangle { + width: UILayout.naviPageIconBackgroundWidth + height: UILayout.naviPageIconBackgroundHeight + radius: UILayout.naviPageIconBackgroundRadius + color: parent.parent.down ? Colors.naviPageIconPressedBackground : Colors.naviPageIconBackground + } + } + + contentItem: Item {} + Image { + anchors.centerIn: parent + width: UILayout.naviPageIconWidth + height: UILayout.naviPageIconHeight + source: iconSource + z: 3 + } +} diff --git a/basicsuite/ebike-ui/NaviGuide.qml b/basicsuite/ebike-ui/NaviGuide.qml new file mode 100644 index 0000000..1ba6f5e --- /dev/null +++ b/basicsuite/ebike-ui/NaviGuide.qml @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.9 + +import "./BikeStyle" + +Rectangle { + property string arrowSource: "images/nav_nodir.png" + property string address: "-" + property string distance: "0" + property string unit: "m" + + width: UILayout.naviPageGuideRadius * 2 + height: width + radius: width + color: Colors.naviPageGuideBackground + z: 1 + + Rectangle { + width: UILayout.naviPageGuideRadius + height: width + radius: 10 + color: Colors.naviPageGuideBackground + anchors.right: parent.right + anchors.bottom: parent.bottom + } + + Image { + id: guideArrow + anchors { + top: parent.top + topMargin: UILayout.naviPageGuideArrowTopMargin + left: parent.left + leftMargin: UILayout.naviPageGuideArrowLeftMargin + } + source: arrowSource + width: UILayout.naviPageGuideArrowWidth + height: UILayout.naviPageGuideArrowHeight + } + + Text { + id: naviAddressText + anchors { + baseline: parent.bottom + baselineOffset: -UILayout.naviPageGuideAddressBaselineMargin + right: parent.right + rightMargin: UILayout.naviPageGuideAddressRightMargin + } + width: 123 + horizontalAlignment: Text.AlignRight + color: Colors.naviPageGuideAddressColor + font { + family: "Montserrat, Medium" + weight: Font.Medium + pixelSize: UILayout.naviPageGuideAddressTextSize + } + fontSizeMode: Text.Fit + wrapMode: Text.WordWrap + minimumPixelSize: 9 + text: address + } + + Text { + id: naviUnit + anchors { + baseline: naviAddressText.baseline + baselineOffset: -UILayout.naviPageGuideDistanceBaselineMargin + right: naviAddressText.right + } + color: Colors.naviPageGuideUnitColor + font { + family: "Montserrat, Light" + weight: Font.Light + pixelSize: UILayout.naviPageGuideUnitTextSize + } + text: datastore.smallUnit + } + + Text { + id: naviDistance + anchors { + baseline: naviUnit.baseline + right: naviUnit.left + rightMargin: 10 + } + color: Colors.naviPageGuideTextColor + font { + family: "Montserrat, Bold" + weight: Font.Bold + pixelSize: UILayout.naviPageGuideDistanceTextSize + } + text: Math.round(datastore.convertSmallDistance(distance) / 10) * 10 + } + + Image { + source: "images/navigation_widget_shadow.png" + anchors { + horizontalCenter: parent.horizontalCenter + verticalCenter: parent.verticalCenter + horizontalCenterOffset: 1 + verticalCenterOffset: 1 + } + z: -1 + } +} diff --git a/basicsuite/ebike-ui/NaviPage.qml b/basicsuite/ebike-ui/NaviPage.qml new file mode 100644 index 0000000..e6c8805 --- /dev/null +++ b/basicsuite/ebike-ui/NaviPage.qml @@ -0,0 +1,691 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.7 +import QtQuick.Controls 2.2 +import QtPositioning 5.3 +import QtLocation 5.9 +import QtQuick.VirtualKeyboard 2.1 + +import "./BikeStyle" + +Page { + id: mapContainer + property var startCoordinate: QtPositioning.coordinate(36.131961, -115.153048) + property var destinationCoordinate: QtPositioning.coordinate(90, 0) + property var targetPlace + property real totalDistance + property real metersPerSecond // This is calculated at the start of a trip + property real totalTravelTime: totalDistance / metersPerSecond + property real naviGuideSegmentDistance: 0 + property string naviGuideArrowSource: "images/nav_nodir.png" + property string naviGuideDistance + property string naviGuideAddress: "-" + property alias routeQuery: routeQuery + property alias routeModel: routeModel + property alias targetEdit: targetEdit + property var routeSegmentList + property var currentSegment + property int routeSegment + property int pathSegment + + function resetDemo() { + // Clear/reset everything + naviGuideArrowSource = "images/nav_nodir.png" + naviGuideDistance = "-" + naviGuideAddress = "-" + navigation.active = false + navigationArrowAnimation.stop() + targetEdit.clear() + + map.focus = true + routeQuery.clearWaypoints() + routeModel.reset() + navigationArrowItem.coordinate = navigation.coordinate + destinationCoordinate = QtPositioning.coordinate(90, 0) + map.center = navigation.coordinate + } + + TextField { + id: targetEdit + width: UILayout.naviPageLocationWidth + height: UILayout.naviPageLocationHeight + anchors { + horizontalCenter: parent.horizontalCenter + top: parent.top + topMargin: UILayout.naviPageLocationTopMargin + } + background: Rectangle { + radius: UILayout.naviPageLocationRadius + implicitWidth: UILayout.naviPageLocationWidth + implicitHeight: UILayout.naviPageLocationHeight + border.color: Colors.naviPageSuggestionBorder + border.width: targetEdit.activeFocus ? 2 : 0 + } + font { + family: "Montserrat, Medium" + weight: Font.Medium + pixelSize: UILayout.naviPageSearchTextSize + } + cursorVisible: !navigation.active + inputMethodHints: Qt.ImhNoPredictiveText // This should disable lookup on the device + + leftPadding: UILayout.naviPageLocationLeftPadding + rightPadding: UILayout.naviPageSearchIconMargin + UILayout.naviPageSearchIconWidth + placeholderText: qsTr("Where do you want to go?") + z: 1 + autoScroll: false + + // Update search text whenever text is edited + onTextEdited: suggest.search = text + + // If in navigation mode, disable editing + readOnly: navigation.active + + Image { + source: navigation.active ? "images/search_cancel.png" : "images/search.png" + width: UILayout.naviPageSearchIconWidth + height: UILayout.naviPageSearchIconHeight + anchors { + top: parent.top + bottom: parent.bottom + right: parent.right + rightMargin: UILayout.naviPageSearchIconMargin + } + visible: !suggest.loading + + MouseArea { + anchors.fill: parent + enabled: navigation.active + onClicked: { + naviGuideArrowSource = "images/nav_nodir.png" + naviGuideDistance = "-" + naviGuideAddress = "-" + navigation.active = false + navigationArrowAnimation.stop() + targetEdit.clear() + } + } + } + + // Show a busy indicator whenever suggestions are loading + BusyIndicator { + width: height + anchors { + top: targetEdit.top + bottom: targetEdit.bottom + right: targetEdit.right + rightMargin: UILayout.naviPageSearchIconMargin + } + running: suggest.loading + } + + Image { + id: naviInputShadow + source: "images/small_input_box_shadow.png" + anchors { + horizontalCenter: parent.horizontalCenter + verticalCenter: parent.verticalCenter + horizontalCenterOffset: 1 + verticalCenterOffset: 1 + } + visible: false + z: -2 + } + } + + ListView { + id: targetList + anchors { + top: targetEdit.bottom; + topMargin: UILayout.naviPageSuggestionsOffset + horizontalCenter: targetEdit.horizontalCenter + } + width: UILayout.naviPageLocationWidth + height: 3 * UILayout.naviPageSuggestionHeight + model: suggestions + visible: targetEdit.activeFocus && !navigation.active + z: 1 + currentIndex: -1 + + delegate: Component { + Rectangle { + width: parent.width + height: UILayout.naviPageSuggestionHeight + color: "white" + border.color: Colors.naviPageSuggestionsDivider + border.width: 1 + + Text { + width: parent.width + height: parent.height + verticalAlignment: Text.AlignVCenter + leftPadding: 10 + elide: Text.ElideRight + text: placename + color: Colors.naviPageSuggestionText + font { + family: "Montserrat, Medium" + weight: Font.Medium + pixelSize: UILayout.naviPageSuggestionTextSize + } + } + + MouseArea { + anchors.fill: parent + onClicked: targetList.currentIndex = index + } + } + } + + onCurrentIndexChanged: { + // Called when the currentIndex is reset, ignore that + if (targetList.currentIndex == -1) + return; + + // Get current place name + targetPlace = model.get(targetList.currentIndex) + suggestions.addToMostRecent(targetPlace) + + // Reset search + targetList.currentIndex = -1 + // Update current text + targetEdit.text = targetPlace.place_name + // Clear the model and stop any search + suggestions.clear() + suggest.stopSuggest() + + targetEdit.cursorPosition = 0 + targetEdit.ensureVisible(1) + navigation.active = true + map.focus = true + + destinationCoordinate = QtPositioning.coordinate(targetPlace.center[1], targetPlace.center[0]); + routeQuery.clearWaypoints() + routeQuery.addWaypoint(map.center) + routeQuery.addWaypoint(destinationCoordinate) + routeQuery.travelModes = RouteQuery.BicycleTravel + routeQuery.routeOptimizations = RouteQuery.ShortestRoute + routeModel.update() + } + } + + // Zoom and location icons + NaviButton { + id: gpsCenter + anchors { + top: parent.top + topMargin: UILayout.naviPageIconTopMargin + right: parent.right + rightMargin: UILayout.naviPageIconRightMargin + } + iconSource: "images/map_locate.png" + onClicked: { + navigationArrowItem.coordinate = navigation.coordinate + map.center = navigation.coordinate + } + } + + NaviButton { + id: zoomIn + anchors { + top: gpsCenter.bottom + topMargin: UILayout.naviPageIconSpacing + right: parent.right + rightMargin: UILayout.naviPageIconRightMargin + } + iconSource: "images/map_zoomin.png" + autoRepeat: true + onClicked: navigation.zoomlevel += 0.1 + } + + NaviButton { + id: zoomOut + anchors { + top: zoomIn.bottom + topMargin: UILayout.naviPageIconSpacing + right: parent.right + rightMargin: UILayout.naviPageIconRightMargin + } + iconSource: "images/map_zoomout.png" + autoRepeat: true + onClicked: navigation.zoomlevel -= 0.1 + } + + NaviGuide { + id: naviGuide + anchors { + right: parent.right + bottom: parent.bottom + rightMargin: UILayout.naviPageGuideRightMargin + bottomMargin: UILayout.naviPageGuideBottomMargin + } + arrowSource: naviGuideArrowSource + distance: naviGuideDistance + address: naviGuideAddress + visible: navigation.active + } + + NaviTripInfo { + id: totalTripInfo + z: 1 + visible: navigation.active + anchors { + bottom: parent.bottom + bottomMargin: UILayout.naviPageTripBottomMargin + horizontalCenter: parent.horizontalCenter + } + + remainingDistance: totalDistance + remainingTravelTime: totalTravelTime + } + + RouteQuery { + id: routeQuery + numberAlternativeRoutes: 0 + } + + function updateNaviGuide(segment, nextsegment) { + var maneuver = segment.maneuver; + naviGuideSegmentDistance = maneuver.distanceToNextInstruction; + navigationArrowAnimation.pathDistance = naviGuideSegmentDistance; + naviGuideDistance = maneuver.distanceToNextInstruction; + + if (nextsegment) { + var nextmaneuver = nextsegment.maneuver; + naviGuideAddress = nextmaneuver.instructionText; + switch (nextmaneuver.direction) { + case RouteManeuver.NoDirection: + naviGuideArrowSource = "images/nav_nodir.png"; + break; + case RouteManeuver.DirectionForward: + naviGuideArrowSource = "images/nav_straight.png"; + break; + case RouteManeuver.DirectionBearRight: + naviGuideArrowSource = "images/nav_bear_r.png"; + break; + case RouteManeuver.DirectionLightRight: + naviGuideArrowSource = "images/nav_light_right.png"; + break; + case RouteManeuver.DirectionRight: + naviGuideArrowSource = "images/nav_right.png"; + break; + case RouteManeuver.DirectionHardRight: + naviGuideArrowSource = "images/nav_hard_r.png"; + break; + case RouteManeuver.DirectionUTurnRight: + naviGuideArrowSource = "images/nav_uturn_r.png"; + break; + case RouteManeuver.DirectionUTurnLeft: + naviGuideArrowSource = "images/nav_uturn_l.png"; + break; + case RouteManeuver.DirectionHardLeft: + naviGuideArrowSource = "images/nav_hard_l.png"; + break; + case RouteManeuver.DirectionLeft: + naviGuideArrowSource = "images/nav_left.png"; + break; + case RouteManeuver.DirectionLightLeft: + naviGuideArrowSource = "images/nav_light_left.png"; + break; + case RouteManeuver.DirectionBearLeft: + naviGuideArrowSource = "images/nav_bear_l.png"; + break; + } + } else { + naviGuideAddress = "-"; + naviGuideArrowSource = "images/nav_nodir.png"; + } + } + + function setNextAnimation() { + if (!navigation.active) + return; + var position = QtPositioning.coordinate(currentSegment.maneuver.position.longitude, + currentSegment.maneuver.position.latitude); + + // Update the navigation instructions + if (pathSegment === 0) { + var nextSegment = routeSegmentList[routeSegment + 1]; + updateNaviGuide(currentSegment, nextSegment); + } + + var startPos = navigationArrowItem.coordinate; + var path = currentSegment.path; + pathSegment += 1; + if (pathSegment >= path.length) { + routeSegment += 1; + currentSegment = routeSegmentList[routeSegment]; + if (!currentSegment) { + naviGuideArrowSource = "images/nav_nodir.png"; + navigation.active = false; + targetEdit.clear(); + return; + } + pathSegment = 0; + setNextAnimation(); + return; + } + var endPos = path[pathSegment]; + + // Calculate new direction + var oldDir = navigationArrowAnimation.rotationDirection; + var newDir = startPos.azimuthTo(endPos); + + // Calculate the duration of the animation + var diff = oldDir - newDir; + if (Math.abs(diff) < 15) + navigationArrowAnimation.rotationDuration = 0; + else if (diff < -180) + navigationArrowAnimation.rotationDuration = (diff + 360) * 5; + else if (diff > 180) + navigationArrowAnimation.rotationDuration = (360 - diff) * 5; + else + navigationArrowAnimation.rotationDuration = Math.abs(diff) * 5; + + // Set animation details + var pathDistance = startPos.distanceTo(endPos); + var nextDistance = navigationArrowAnimation.pathDistance - pathDistance; + var nextRemainingDistance = navigationArrowAnimation.remainingDistance - pathDistance; + navigationArrowAnimation.coordinateDuration = pathDistance * 40; + navigationArrowAnimation.rotationDirection = startPos.azimuthTo(endPos); + navigationArrowAnimation.pathDistance = nextDistance; + navigationArrowAnimation.remainingDistance = nextRemainingDistance; + navigationArrowAnimation.sourceCoordinate = startPos; + navigationArrowAnimation.targetCoordinate = endPos; + navigationArrowAnimation.start(); + } + + RouteModel { + id: routeModel + plugin: map.plugin + query: routeQuery + onStatusChanged: { + if (status === RouteModel.Ready) { + switch (count) { + case 0: + // technically not an error + console.log('mapping error', errorString) + break + case 1: + break + } + } else if (status === RouteModel.Error) { + console.log('mapping error', errorString) + } + } + onRoutesChanged: { + if (count === 0) + return; + var route = routeModel.get(0); + + totalDistance = route.distance; + metersPerSecond = route.distance / route.travelTime; + navigationArrowAnimation.remainingDistance = route.distance; + + routeManeuverModel.clear(); + currentSegment = route.segments[0]; + routeSegmentList = route.segments; + + routeSegment = 0; + pathSegment = 0; + setNextAnimation(); + } + } + + // Model that is used to display individual instructions + ListModel { + id: routeManeuverModel + } + + Map { + id: map + gesture.enabled: true + anchors.fill: parent + plugin: mapboxgl + + center: navigation.coordinate + zoomLevel: navigation.zoomlevel + bearing: navigation.direction + + onCenterChanged: { + suggest.center = map.center + } + + Behavior on bearing { + RotationAnimation { + duration: 250 + direction: RotationAnimation.Shortest + } + } + + Behavior on center { + id: centerBehavior + enabled: true + CoordinateAnimation { duration: 1500 } + } + + MapQuickItem { + id: navigationArrowItem + z: 3 + coordinate: navigation.routePosition + anchorPoint.x: navigationArrowImage.width / 2 + anchorPoint.y: navigationArrowImage.height / 2 + sourceItem: Image { + id: navigationArrowImage + source: "images/map_location_arrow.png" + width: 30 + height: 30 + } + } + + MapQuickItem { + id: navigationCircleItem + z: 2 + coordinate: navigation.routePosition + anchorPoint.x: navigationCircleImage.width / 2 + anchorPoint.y: navigationCircleImage.height / 2 + sourceItem: Image { + id: navigationCircleImage + source: "images/blue_circle_gps_area.png" + width: 100 + height: 100 + } + } + + MapQuickItem { + id: destinationQuickItem + z: 3 + coordinate: destinationCoordinate + anchorPoint.x: destinationImage.width / 2 + anchorPoint.y: destinationImage.height - 10 + sourceItem: Image { + id: destinationImage + source: "images/map_destination.png" + width: 40 + height: 40 + } + visible: navigation.active + } + + MapItemView { + model: routeModel + delegate: routeDelegate + } + + Component { + id: routeDelegate + + MapRoute { + id: route + route: routeData + line.color: "#3698e8" + line.width: 6 + smooth: true + visible: index === 0 // Show only one route (numberAlternativeRoutes not respected yet) + } + } + + SequentialAnimation { + id: navigationArrowAnimation + property real rotationDuration: 0; + property real rotationDirection: 0; + property real coordinateDuration: 0; + property real pathDistance: 0; + property real remainingDistance: 0; + property var sourceCoordinate: navigation.routePosition; + property var targetCoordinate: startCoordinate; + + RotationAnimation { + target: map + property: "bearing" + duration: navigationArrowAnimation.rotationDuration + to: navigationArrowAnimation.rotationDirection + direction: RotationAnimation.Shortest + } + + ParallelAnimation { + CoordinateAnimation { + target: map + property: "center" + duration: navigationArrowAnimation.coordinateDuration + to: navigationArrowAnimation.targetCoordinate + } + + CoordinateAnimation { + target: navigationArrowItem + property: "coordinate" + duration: navigationArrowAnimation.coordinateDuration + to: navigationArrowAnimation.targetCoordinate + } + + CoordinateAnimation { + target: navigationCircleItem + property: "coordinate" + duration: navigationArrowAnimation.coordinateDuration + to: navigationArrowAnimation.targetCoordinate + } + + NumberAnimation { + target: mapContainer + property: "naviGuideDistance" + duration: navigationArrowAnimation.coordinateDuration + to: navigationArrowAnimation.pathDistance + } + + NumberAnimation { + target: mapContainer + property: "totalDistance" + duration: navigationArrowAnimation.coordinateDuration + to: navigationArrowAnimation.remainingDistance + } + } + + onStopped: setNextAnimation() + } + + MouseArea { + // Whenever the user taps on the map, move focus to it + anchors.fill: parent + onClicked: map.focus = true + } + } + + Plugin { + id: mapboxgl + name: "mapbox" + PluginParameter { + name: "mapbox.access_token" + value: "pk.eyJ1IjoibWFwYm94NHF0IiwiYSI6ImNpd3J3eDE0eDEzdm8ydHM3YzhzajlrN2oifQ.keEkjqm79SiFDFjnesTcgQ" + } + PluginParameter { + name: "mapbox.mapping.map_id" + value: "mapbox.run-bike-hike" + } + } + + states: [ + State { + name: ""; + when: !navigation.active + PropertyChanges { + target: targetEdit + width: UILayout.naviPageLocationWidth + anchors.topMargin: UILayout.naviPageLocationTopMargin + anchors.bottomMargin: 0 + } + AnchorChanges { + target: targetEdit + anchors.top: parent.top + anchors.bottom: undefined + } + PropertyChanges { + target: naviInputShadow + visible: false + } + }, + State { + name: "NAVIGATING"; + when: navigation.active + PropertyChanges { + target: targetEdit + width: UILayout.naviPageTripWidth + anchors.topMargin: 0 + anchors.bottomMargin: UILayout.naviPageTripSearchMargin + } + AnchorChanges { + target: targetEdit + anchors.top: undefined + anchors.bottom: totalTripInfo.top + } + PropertyChanges { + target: naviInputShadow + visible: true + } + } + ] + + transitions: Transition { + NumberAnimation { + properties: "width" + easing.type: Easing.InOutQuad + duration: 250 + } + AnchorAnimation { + duration: 250 + } + } +} diff --git a/basicsuite/ebike-ui/NaviTripInfo.qml b/basicsuite/ebike-ui/NaviTripInfo.qml new file mode 100644 index 0000000..e024aab --- /dev/null +++ b/basicsuite/ebike-ui/NaviTripInfo.qml @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.9 + +import "./BikeStyle" + +Rectangle { + property real remainingDistance: 0 + property real remainingTravelTime: 0 + property var remainingDistanceSplit: datastore.splitDistance(remainingDistance, true) + property var remainingTravelTimeSplit: datastore.splitDuration(remainingTravelTime) + + width: UILayout.naviPageTripWidth + height: UILayout.naviPageTripHeight + radius: UILayout.naviPageTripRadius + color: Colors.naviPageTripBackground + + Rectangle { + width: UILayout.naviPageTripDividerWidth + height: UILayout.naviPageTripDividerHeight + radius: 2 + color: Colors.naviPageTripDivider + anchors.centerIn: parent + } + + Item { + height: parent.height + width: naviTripDistanceRemainingText.width + 5 + naviTripDistanceUnitText.width + anchors { + verticalCenter: parent.verticalCenter + horizontalCenter: parent.horizontalCenter + horizontalCenterOffset: -parent.width / 4 + } + + Text { + id: naviTripDistanceRemainingText + anchors.verticalCenter: parent.verticalCenter + color: Colors.naviPageGuideTextColor + font { + family: "Montserrat, Medium" + weight: Font.Medium + pixelSize: UILayout.naviPageTripTotalTextSize + } + text: remainingDistanceSplit.decimal ? remainingDistanceSplit.value.toFixed(1) : remainingDistanceSplit.value.toFixed(0) + } + + Text { + id: naviTripDistanceUnitText + anchors { + verticalCenter: parent.verticalCenter + left: naviTripDistanceRemainingText.right + leftMargin: 5 + } + color: Colors.naviPageGuideUnitColor + font { + family: "Montserrat, Light" + weight: Font.Light + pixelSize: UILayout.naviPageTripTotalUnitSize + } + text: remainingDistanceSplit.unit + } + } + + + Item { + height: parent.height + width: naviTripTimeRemainingText.width + 5 + naviTripTimeUnitText.width + anchors { + verticalCenter: parent.verticalCenter + horizontalCenter: parent.horizontalCenter + horizontalCenterOffset: parent.width / 4 + } + + Text { + id: naviTripTimeRemainingText + anchors.verticalCenter: parent.verticalCenter + color: Colors.naviPageGuideTextColor + font { + family: "Montserrat, Medium" + weight: Font.Medium + pixelSize: UILayout.naviPageTripTotalTextSize + } + text: remainingTravelTimeSplit.value.toFixed(0) + } + + Text { + id: naviTripTimeUnitText + anchors { + verticalCenter: parent.verticalCenter + left: naviTripTimeRemainingText.right + leftMargin: 5 + } + color: Colors.naviPageGuideUnitColor + font { + family: "Montserrat, Light" + weight: Font.Light + pixelSize: UILayout.naviPageTripTotalUnitSize + } + text: remainingTravelTimeSplit.unit + } + } + + Image { + source: "images/small_input_box_shadow.png" + anchors { + horizontalCenter: parent.horizontalCenter + verticalCenter: parent.verticalCenter + horizontalCenterOffset: 1 + verticalCenterOffset: 1 + } + z: -1 + } +} diff --git a/basicsuite/ebike-ui/SpeedView.qml b/basicsuite/ebike-ui/SpeedView.qml new file mode 100644 index 0000000..d62e710 --- /dev/null +++ b/basicsuite/ebike-ui/SpeedView.qml @@ -0,0 +1,526 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.9 +import DataStore 1.0 +import "./BikeStyle" + +Rectangle { + width: UILayout.speedViewRadius * 2 + 2 + height: UILayout.speedViewRadius * 2 + 2 + color: "transparent" + radius: width * 0.5 + z: 1 + anchors { + horizontalCenter: parent.horizontalCenter + top: parent.top + topMargin: UILayout.speedViewTop + } + property int dotcount: UILayout.speedViewDots + property int curvewidth: UILayout.speedViewInnerWidth + property int speedTextSize: UILayout.speedTextSize + property int speedBaselineOffset: UILayout.speedBaselineOffset + 1 + property int innerRadius: UILayout.speedViewInnerRadius + property int speedUnitsSize: UILayout.speedUnitsSize + property int speedUnitBaselineOffset: UILayout.speedTextUnitMargin + property int speedIconsOffset: UILayout.speedIconsCenterOffset + property int speedInfoTextsOffset: 0 + property int speedInfoTextsSize: UILayout.speedInfoTextsSize + property int speedInfoUnitsOffset: UILayout.speedInfoUnitsOffset + property int assistPowerIconOffset: UILayout.assistPowerIconOffset + property bool enlarged: false + property alias cornerRectangle: cornerRectangle + property bool showZero: false + + signal showMain() + + // Speed info + Text { + id: speedText + anchors { + horizontalCenter: speedView.horizontalCenter + baseline: speedView.bottom + baselineOffset: -speedBaselineOffset + } + + color: Colors.speedText + font { + family: "Teko, Light" + weight: Font.Light + pixelSize: speedTextSize + } + text: showZero ? "0" : datastore.speed.toFixed(0) + } + + Text { + id: speedUnit + anchors { + horizontalCenter: speedText.horizontalCenter + baseline: speedText.baseline + baselineOffset: speedUnitBaselineOffset + } + + color: Colors.speedUnit + font { + family: "Montserrat, Light" + weight: Font.Light + pixelSize: speedUnitsSize + } + text: datastore.unit === DataStore.Kmh ? qsTr("km/h") : qsTr("mph") + } + + // Average speed info + Text { + id: averageSpeedText + anchors { + baseline: speedText.baseline + baselineOffset: speedInfoTextsOffset + horizontalCenter: speedText.horizontalCenter + horizontalCenterOffset: -speedIconsOffset + } + visible: speedView.state !== "CORNERED" + + color: Colors.averageSpeedText + font { + family: "Teko, Light" + weight: Font.Light + pixelSize: speedInfoTextsSize + } + text: datastore.averagespeed.toFixed(0) + } + + Text { + id: averageSpeedUnit + anchors { + horizontalCenter: averageSpeedText.horizontalCenter + baseline: averageSpeedText.baseline + baselineOffset: speedInfoUnitsOffset + } + visible: speedView.state !== "CORNERED" + + color: Colors.averageSpeedUnit + font { + family: "Montserrat, Light" + weight: Font.Light + pixelSize: speedUnitsSize + } + horizontalAlignment: Text.AlignHCenter + text: datastore.unit === DataStore.Kmh ? qsTr("AVG\nkm/h") : qsTr("AVG\nmph") + } + + Image { + id: averageSpeedIcon + width: UILayout.averageSpeedIconWidth + height: UILayout.averageSpeedIconHeight + source: "images/speed.png" + anchors { + horizontalCenter: averageSpeedText.horizontalCenter + bottom: averageSpeedText.top + bottomMargin: UILayout.averageSpeedIconMargin + } + visible: speedView.state !== "CORNERED" + } + + // Assist info + Text { + id: assistDistanceText + anchors { + baseline: speedText.baseline + baselineOffset: speedInfoTextsOffset + horizontalCenter: speedText.horizontalCenter + horizontalCenterOffset: speedIconsOffset + } + visible: speedView.state !== "CORNERED" + + color: Colors.assistDistanceText + font { + family: "Teko, Light" + weight: Font.Light + pixelSize: speedInfoTextsSize + } + text: datastore.assistdistance.toFixed(0) + } + + Text { + id: assistDistanceUnit + anchors { + horizontalCenter: assistDistanceText.horizontalCenter + baseline: assistDistanceText.baseline + baselineOffset: speedInfoUnitsOffset + } + visible: speedView.state !== "CORNERED" + + color: Colors.assistDistanceUnit + font { + family: "Montserrat, Light" + weight: Font.Light + pixelSize: speedUnitsSize + } + horizontalAlignment: Text.AlignHCenter + text: datastore.unit === DataStore.Kmh ? qsTr("km\nassist\nleft") : qsTr("mi.\nassist\nleft") + } + + Image { + id: assistDistanceIcon + width: UILayout.assistDistanceIconWidth + height: UILayout.assistDistanceIconHeight + source: "images/battery.png" + anchors { + horizontalCenter: assistDistanceText.horizontalCenter + bottom: assistDistanceText.top + bottomMargin: UILayout.assistDistanceIconMargin + } + visible: speedView.state !== "CORNERED" + } + + // Assist power icon + Image { + id: assistPowerIcon + width: UILayout.assistPowerTconWidth + height: UILayout.assistPowerTconHeight + source: "images/assist.png" + anchors { + horizontalCenter: speedView.horizontalCenter + top: parent.verticalCenter + topMargin: assistPowerIconOffset + } + visible: speedView.state !== "CORNERED" + } + + Gradient { + id: assistPowerGradient + GradientStop { position: 0.0; color: Colors.assistPowerGradientStart } + GradientStop { position: 1.0; color: Colors.assistPowerGradientEnd } + } + + // Assist power circles + Rectangle { + id: assistPowerIcon1 + width: UILayout.assistPowerCircleRadius * 2 + height: width + radius: UILayout.assistPowerCircleRadius + anchors { + right: assistPowerIcon2.left + rightMargin: UILayout.assistPowerCircleOffset + bottom: assistPowerIcon2.bottom + bottomMargin: UILayout.assistPowerCircleVerticalOffset + } + color: Colors.assistPowerEmpty + gradient: datastore.assistpower > 2.0 ? assistPowerGradient : null + visible: speedView.state !== "CORNERED" + } + + Rectangle { + id: assistPowerIcon2 + width: UILayout.assistPowerCircleRadius * 2 + height: width + radius: UILayout.assistPowerCircleRadius + anchors { + right: parent.horizontalCenter + rightMargin: UILayout.assistPowerCircleOffset / 2 + top: assistPowerIcon.bottom + topMargin: UILayout.assistPowerCircleTopMargin + } + color: Colors.assistPowerEmpty + gradient: datastore.assistpower > 25.0 ? assistPowerGradient : null + visible: speedView.state !== "CORNERED" + } + + Rectangle { + id: assistPowerIcon3 + width: UILayout.assistPowerCircleRadius * 2 + height: width + radius: UILayout.assistPowerCircleRadius + anchors { + left: parent.horizontalCenter + leftMargin: UILayout.assistPowerCircleOffset / 2 + top: assistPowerIcon.bottom + topMargin: UILayout.assistPowerCircleTopMargin + } + color: Colors.assistPowerEmpty + gradient: datastore.assistpower > 50.0 ? assistPowerGradient : null + visible: speedView.state !== "CORNERED" + } + + Rectangle { + id: assistPowerIcon4 + width: UILayout.assistPowerCircleRadius * 2 + height: width + radius: UILayout.assistPowerCircleRadius + anchors { + left: assistPowerIcon3.right + leftMargin: UILayout.assistPowerCircleOffset + bottom: assistPowerIcon3.bottom + bottomMargin: UILayout.assistPowerCircleVerticalOffset + } + color: Colors.assistPowerEmpty + gradient: datastore.assistpower > 75.0 ? assistPowerGradient : null + visible: speedView.state !== "CORNERED" + } + + // Numbers for speed and battery level + Text { + anchors { + baseline: parent.bottom + baselineOffset: 20 + right: parent.horizontalCenter + rightMargin: 10 + } + visible: speedView.state !== "CORNERED" + + color: Colors.dottedRing + font { + family: "Montserrat, Regular" + weight: Font.Normal + pixelSize: UILayout.ringValueText + } + text: "0" + } + + Text { + anchors { + baseline: parent.bottom + baselineOffset: 20 + left: parent.horizontalCenter + leftMargin: 10 + } + visible: speedView.state !== "CORNERED" + + color: Colors.dottedRing + font { + family: "Montserrat, Regular" + weight: Font.Normal + pixelSize: UILayout.ringValueText + } + text: "0 %" + } + + Text { + anchors { + baseline: parent.verticalCenter + baselineOffset: -10 + right: parent.left + rightMargin: 9 + } + visible: speedView.state !== "CORNERED" + + color: Colors.dottedRing + font { + family: "Montserrat, Regular" + weight: Font.Normal + pixelSize: UILayout.ringValueText + } + text: "30" + } + + Text { + anchors { + baseline: parent.verticalCenter + baselineOffset: -10 + left: parent.right + leftMargin: 9 + } + visible: speedView.state !== "CORNERED" + + color: Colors.dottedRing + font { + family: "Montserrat, Regular" + weight: Font.Normal + pixelSize: UILayout.ringValueText + } + text: "50 %" + } + + Text { + anchors { + baseline: parent.top + baselineOffset: -10 + right: parent.horizontalCenter + rightMargin: 10 + } + visible: speedView.state !== "CORNERED" + + color: Colors.dottedRing + font { + family: "Montserrat, Regular" + weight: Font.Normal + pixelSize: UILayout.ringValueText + } + text: "60" + } + + Text { + anchors { + baseline: parent.top + baselineOffset: -10 + left: parent.horizontalCenter + leftMargin: 10 + } + visible: speedView.state !== "CORNERED" + + color: Colors.dottedRing + font { + family: "Montserrat, Regular" + weight: Font.Normal + pixelSize: UILayout.ringValueText + } + text: "100 %" + } + + Rectangle { + id: cornerRectangle + width: UILayout.speedViewRadiusMinified + height: width + // By default this is centered, and invisible + anchors.horizontalCenter: speedView.horizontalCenter + anchors.verticalCenter: speedView.verticalCenter + color: "transparent" + radius: 10 + z: -1 + + Image { + source: "images/small_speedometer_arrow.png" + width: UILayout.speedometerCornerArrowWidth + height: UILayout.speedometerCornerArrowHeight + anchors.left: parent.left + anchors.bottom: parent.bottom + visible: swipeView.currentIndex != 1 + } + } + + Image { + source: "images/small_speedometer_shadow.png" + anchors { + horizontalCenter: parent.horizontalCenter + verticalCenter: parent.verticalCenter + horizontalCenterOffset: 1 + verticalCenterOffset: 1 + } + z: -1 + + visible: speedView.state == "CORNERED" + } + + Canvas { + id: speedArc + anchors.fill: parent + + Component.onCompleted: { + datastore.onSpeedChanged.connect(speedArc.requestPaint) + datastore.onBatterylevelChanged.connect(speedArc.requestPaint) + } + + onPaint: { + var ctx = getContext("2d"); + ctx.reset(); + + var currentRadius = (speedView.width - 2) / 2; + var centerX = speedView.width / 2; + var centerY = speedView.height / 2; + + // Draw the dotted circle (if not in corner mode) + if (speedView.state !== "CORNERED") { + ctx.fillStyle = Colors.dottedRing; + var angleStep = Math.PI * 2.0 / dotcount; + for (var angle = 0; angle <= Math.PI * 2; angle += angleStep) { + var x = currentRadius * Math.cos(angle); + var y = currentRadius * Math.sin(angle); + ctx.fillRect(centerX + x, centerY + y, 2, 2); + } + } + + // Draw speed and battery view bases + ctx.lineCap = "round"; + ctx.strokeStyle = Colors.dottedRing; + ctx.lineWidth = curvewidth; + ctx.beginPath(); + ctx.arc(centerX, centerY, innerRadius, + UILayout.speedViewSpeedStart, UILayout.speedViewSpeedEnd); + ctx.stroke(); + ctx.beginPath(); + ctx.arc(centerX, centerY, innerRadius, + UILayout.speedViewBatteryStart, UILayout.speedViewBatteryEnd, true); + ctx.stroke(); + + // Draw speed gradient + if (!showZero) { + var speedArcLength = UILayout.speedViewSpeedEnd - UILayout.speedViewSpeedStart; + var speedAngle = Math.min(UILayout.speedViewSpeedEnd, + UILayout.speedViewSpeedStart + speedArcLength * (datastore.speed / 60)); + var speedAngleX = Math.cos(speedAngle) * innerRadius; + var speedAngleY = Math.sin(speedAngle) * innerRadius; + var speedGradient = ctx.createLinearGradient(centerX, centerY + innerRadius, + centerX + speedAngleX, centerY + speedAngleY); + speedGradient.addColorStop(0.0, Colors.speedGradientStart); + speedGradient.addColorStop(1.0, Colors.speedGradientEnd); + ctx.strokeStyle = speedGradient; + ctx.beginPath(); + ctx.arc(centerX, centerY, innerRadius, + UILayout.speedViewSpeedStart, speedAngle); + ctx.stroke(); + } + + // Draw battery gradient + var batteryArcLength = UILayout.speedViewBatteryEnd - UILayout.speedViewBatteryStart; + var batteryAngle = Math.max(UILayout.speedViewBatteryEnd, + UILayout.speedViewBatteryStart + batteryArcLength * (datastore.batterylevel / 100)); + var batteryAngleX = Math.cos(batteryAngle) * innerRadius; + var batteryAngleY = Math.sin(batteryAngle) * innerRadius; + var batteryGradient = ctx.createLinearGradient(centerX, centerY + innerRadius, + centerX + batteryAngleX, centerY + batteryAngleY); + //centerX, centerY - innerRadius); + batteryGradient.addColorStop(0.0, Colors.batteryGradientStart); + batteryGradient.addColorStop(1.0, Colors.batteryGradientEnd); + ctx.strokeStyle = batteryGradient; + ctx.beginPath(); + ctx.arc(centerX, centerY, innerRadius, + UILayout.speedViewBatteryStart, batteryAngle, true); + ctx.stroke(); + } + } + + MouseArea { + anchors.fill: parent + onClicked: { + if (enlarged) + enlarged = false + else if (swipeView.currentIndex === 1) + enlarged = true + else + speedView.showMain() + } + } +} diff --git a/basicsuite/ebike-ui/StatsBox.qml b/basicsuite/ebike-ui/StatsBox.qml new file mode 100644 index 0000000..7d6f24c --- /dev/null +++ b/basicsuite/ebike-ui/StatsBox.qml @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.7 +import QtQuick.Controls 2.0 +import DataStore 1.0 + +import "./BikeStyle" + +// Top-left corner, stats +Item { + width: 320 + height: UILayout.topViewHeight + + Image { + id: tripIcon + width: UILayout.statsIconWidth + height: UILayout.statsIconHeight + source: "images/trip.png" + anchors { + top: parent.top + left: parent.left + topMargin: UILayout.statsIconTop + leftMargin: UILayout.statsIconLeft + } + } + + Text { + id: tripText + color: Colors.distanceText + anchors { + top: tripIcon.top + topMargin: UILayout.statsTextTopOffset + left: tripIcon.right + leftMargin: UILayout.statsTextSeparator + } + font { + family: "Montserrat, Bold" + weight: Font.Bold + pixelSize: UILayout.statsTextSize + } + text: datastore.trip.toFixed(1) + } + + Text { + id: tripUnitText + color: Colors.distanceUnit + anchors { + baseline: tripIcon.bottom + baselineOffset: -UILayout.statsUnitBaselineOffset + left: tripIcon.right + leftMargin: UILayout.statsTextSeparator + } + font { + family: "Montserrat, Light" + weight: Font.Light + pixelSize: UILayout.statsTextSize + } + text: datastore.unit === DataStore.Kmh ? "km" : "mi." + } + + Image { + id: calIcon + width: UILayout.statsIconWidth + height: UILayout.statsIconHeight + source: "images/calories.png" + anchors { + top: tripIcon.bottom + left: parent.left + topMargin: UILayout.statsIconSeparator + leftMargin: UILayout.statsIconLeft + } + } + + Text { + id: calText + color: Colors.distanceText + anchors { + top: calIcon.top + topMargin: UILayout.statsTextTopOffset + left: calIcon.right + leftMargin: UILayout.statsTextSeparator + } + font { + family: "Montserrat, Bold" + weight: Font.Bold + pixelSize: UILayout.statsTextSize + } + text: datastore.calories.toFixed(0) + } + + Text { + id: calUnitText + color: Colors.distanceUnit + anchors { + baseline: calIcon.bottom + baselineOffset: -UILayout.statsUnitBaselineOffset + left: calIcon.right + leftMargin: UILayout.statsTextSeparator + } + font { + family: "Montserrat, Light" + weight: Font.Light + pixelSize: UILayout.statsTextSize + } + text: "kcal" + } + + Rectangle { + width: UILayout.horizontalViewSeparatorWidth + height: UILayout.horizontalViewSeparatorHeight + anchors.bottom: parent.bottom + anchors.left: parent.left + color: Colors.separator + } + + Rectangle { + width: UILayout.verticalViewSeparatorWidth + height: UILayout.verticalViewSeparatorHheightTop + anchors.top: parent.top + anchors.right: parent.right + color: Colors.separator + } +} diff --git a/basicsuite/ebike-ui/StatsPage.qml b/basicsuite/ebike-ui/StatsPage.qml new file mode 100644 index 0000000..959b813 --- /dev/null +++ b/basicsuite/ebike-ui/StatsPage.qml @@ -0,0 +1,314 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.9 +import QtQuick.Controls 2.2 +import QtCharts 2.2 +import DataStore 1.0 + +import "./BikeStyle" +import "moment.js" as Moment + +Page { + id: statsPage + background: Rectangle { + color: Colors.mainBackground + } + + // Function for pretty-printing duration + function splitDuration(duration) { + var hours = Math.floor(duration / 3600); + var minutes = Math.floor((duration % 3600) / 60); + var seconds = Math.floor(duration % 60); + if (minutes < 10) + minutes = "0" + minutes; + return hours + ":" + minutes; + } + + function timestampToReadable(timestamp) { + return Moment.moment.unix(timestamp).calendar(); + } + + // On new trip data (save clicked), switch index to new trip + Connections { + target: tripdata + onTripDataSaved: tripView.setCurrentIndex(index) + } + + RoundButton { + id: endTrip + width: UILayout.statsEndtripWidth + height: UILayout.statsEndtripHeight + radius: height / 2 + anchors { + horizontalCenter: parent.horizontalCenter + top: parent.top + topMargin: UILayout.statsEndtripMargin + } + + background: Rectangle { + anchors.fill: parent + color: parent.down ? Colors.statsButtonPressed : "transparent" + radius: parent.radius + border.color: Colors.statsButtonActive + border.width: parent.down ? 0 : 1 + } + + contentItem: Text { + color: Colors.statsButtonActiveText + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + text: qsTr("END TRIP") + font { + family: "Montserrat, Medium" + weight: Font.Medium + pixelSize: UILayout.statsEndtripTextSize + } + } + visible: tripView.currentIndex === 0 + onClicked: tripdata.endTrip() + } + + Text { + id: tripDateText + anchors { + horizontalCenter: parent.horizontalCenter + verticalCenter: parent.top + verticalCenterOffset: UILayout.statsEndtripMargin + UILayout.statsEndtripHeight / 2 + } + color: Colors.statsButtonActiveText + text: qsTr("YESTERDAY") + font { + family: "Montserrat, Medium" + weight: Font.Medium + pixelSize: UILayout.statsEndtripTextSize + } + visible: tripView.currentIndex > 0 + } + + RoundButton { + id: previousChart + width: UILayout.statsTripButtonWidth + height: UILayout.statsTripButtonHeight + radius: height / 2 + anchors { + left: parent.left + top: endTrip.top + leftMargin: UILayout.statsTripButtonMarginSide + } + enabled: tripView.currentIndex > 0 + + background: Rectangle { + anchors.fill: parent + color: parent.down ? Colors.statsButtonPressed : "transparent" + radius: parent.radius + border.color: enabled ? Colors.statsButtonActive : Colors.statsButtonInactive + border.width: parent.down ? 0 : 1 + } + + contentItem: Item {} + Image { + anchors.centerIn: parent + source: "images/arrow_left.png" + opacity: parent.enabled ? 1.0 : 0.3 + } + + onClicked: tripView.decrementCurrentIndex() + } + + RoundButton { + id: nextChart + width: UILayout.statsTripButtonWidth + height: UILayout.statsTripButtonHeight + radius: height / 2 + anchors { + right: parent.right + top: endTrip.top + rightMargin: UILayout.statsTripButtonMarginSide + } + enabled: tripView.currentIndex < tripView.count - 1 + + background: Rectangle { + anchors.fill: parent + color: parent.down ? Colors.statsButtonPressed : "transparent" + radius: parent.radius + border.color: enabled ? Colors.statsButtonActive : Colors.statsButtonInactive + border.width: parent.down ? 0 : 1 + } + + contentItem: Item {} + Image { + anchors.centerIn: parent + source: "images/arrow_right.png" + opacity: parent.enabled ? 1.0 : 0.3 + } + + onClicked: tripView.incrementCurrentIndex() + } + + // Odometer + Item { + width: odometerText.width + odometerUnit.width + odometerDescription.width + 2 * 4 + anchors { + right: parent.right + bottom: parent.top + rightMargin: UILayout.statsOdometerMarginRight + bottomMargin: -UILayout.statsOdometerBaselineOffset + } + + Text { + id: odometerDescription + anchors.right: odometerText.left + anchors.rightMargin: 4 + anchors.baseline: parent.bottom + color: Colors.statsDescriptionText + text: qsTr("Total") + font { + family: "Montserrat, Light" + weight: Font.Light + pixelSize: UILayout.statsDescriptionTextSize + } + } + + Text { + id: odometerText + anchors.right: odometerUnit.left + anchors.rightMargin: 4 + anchors.baseline: parent.bottom + color: Colors.statsValueText + text: datastore.odometer.toFixed(1) + font { + family: "Montserrat, Bold" + weight: Font.Bold + pixelSize: UILayout.statsValueTextSize + } + } + + Text { + id: odometerUnit + anchors.right: parent.right + anchors.baseline: parent.bottom + color: Colors.statsDescriptionText + text: datastore.unit === DataStore.Kmh ? qsTr("km") : qsTr("mi.") + font { + family: "Montserrat, Light" + weight: Font.Light + pixelSize: UILayout.statsDescriptionTextSize + } + } + } + + SwipeView { + id: tripView + anchors { + left: parent.left + right: parent.right + top: endTrip.bottom + bottom: tripChart.top + leftMargin: UILayout.statsTripButtonMarginSide + rightMargin: UILayout.statsTripButtonMarginSide + topMargin: UILayout.statsTopMargin + } + // Hide any excess content, since we are using margins + clip: true + + // Load data on first show + Component.onCompleted: tripdata.refresh() + + onCurrentIndexChanged: tripDateText.text = timestampToReadable(tripdata.get(currentIndex).starttime) + + Repeater { + model: tripdata + + Column { + width: tripView.width + height: tripView.height + + ColumnSpacer { + color: Colors.statsSeparator + } + + StatsRow { + leftTitle: qsTr("Duration (h:m)") + leftValue: splitDuration(duration) + rightTitle: datastore.unit === DataStore.Kmh ? qsTr("Max. speed (km/h)") : qsTr("Max. speed (mph)") + rightValue: maxspeed.toFixed(1) + } + + ColumnSpacer { + color: Colors.statsSeparator + } + + StatsRow { + leftTitle: datastore.unit === DataStore.Kmh ? qsTr("Distance (km)") : qsTr("Distance (mi.)") + leftValue: distance.toFixed(1) + rightTitle: datastore.unit === DataStore.Kmh ? qsTr("Avg. speed (km/h)") : qsTr("Avg. speed (mph)") + rightValue: avgspeed.toFixed(1) + } + + ColumnSpacer { + color: Colors.statsSeparator + } + + StatsRow { + leftTitle: qsTr("Calories (kcal)") + leftValue: calories.toFixed(1) + rightTitle: qsTr("Ascent (m)") + rightValue: ascent.toFixed(1) + } + + ColumnSpacer { + color: Colors.statsSeparator + } + } + } + } + + TripChart { + id: tripChart + width: UILayout.chartWidth + height: UILayout.chartHeight + anchors { + bottom: parent.bottom + right: parent.right + bottomMargin: UILayout.chartBottomMargin + rightMargin: UILayout.chartRightMargin + } + animationRunning: tripView.currentIndex === 0 + tripDetails: tripdata.get(currentIndex) + currentIndex: tripView.currentIndex + } +} diff --git a/basicsuite/ebike-ui/StatsRow.qml b/basicsuite/ebike-ui/StatsRow.qml new file mode 100644 index 0000000..df0f523 --- /dev/null +++ b/basicsuite/ebike-ui/StatsRow.qml @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.9 + +import "./BikeStyle" + +Item { + property string leftTitle + property string leftValue + property string rightTitle + property string rightValue + height: UILayout.statsHeight + width: parent.width + + Text { + text: leftTitle + anchors.left: parent.left + height: parent.height + color: Colors.statsDescriptionText + verticalAlignment: Text.AlignVCenter + font { + family: "Montserrat, Light" + weight: Font.Light + pixelSize: UILayout.statsDescriptionTextSize + } + } + + Text { + text: leftValue + anchors.right: parent.horizontalCenter + anchors.rightMargin: UILayout.statsCenterOffset + height: parent.height + color: Colors.statsValueText + verticalAlignment: Text.AlignVCenter + font { + family: "Montserrat, Bold" + weight: Font.Bold + pixelSize: UILayout.statsValueTextSize + } + } + + Text { + text: rightTitle + anchors.left: parent.horizontalCenter + anchors.leftMargin: UILayout.statsCenterOffset + height: parent.height + color: Colors.statsDescriptionText + verticalAlignment: Text.AlignVCenter + font { + family: "Montserrat, Light" + weight: Font.Light + pixelSize: UILayout.statsDescriptionTextSize + } + } + + Text { + text: rightValue + anchors.right: parent.right + height: parent.height + color: Colors.statsValueText + verticalAlignment: Text.AlignVCenter + font { + family: "Montserrat, Bold" + weight: Font.Bold + pixelSize: UILayout.statsValueTextSize + } + } +} diff --git a/basicsuite/ebike-ui/ToggleSwitch.qml b/basicsuite/ebike-ui/ToggleSwitch.qml new file mode 100644 index 0000000..94af651 --- /dev/null +++ b/basicsuite/ebike-ui/ToggleSwitch.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.9 +import QtQuick.Controls 2.2 + +import "./BikeStyle" + +Switch { + id: control + + implicitWidth: indicator.implicitWidth + implicitHeight: indicator.implicitHeight + + indicator: Rectangle { + implicitWidth: UILayout.switchWidth + implicitHeight: UILayout.switchHeight + radius: height / 2 + y: parent.height / 2 - height / 2 + color: control.checked ? Colors.switchBackgroundOn : Colors.switchBackgroundOff + + Rectangle { + x: control.checked ? parent.width - width : 0 + y: UILayout.switchHeight / 2 - UILayout.switchIndicatorRadius + width: 2 * UILayout.switchIndicatorRadius + height: 2 * UILayout.switchIndicatorRadius + radius: UILayout.switchIndicatorRadius + color: control.checked ? Colors.switchOn : Colors.switchOff + } + } + + contentItem: Text {} +} diff --git a/basicsuite/ebike-ui/TripChart.qml b/basicsuite/ebike-ui/TripChart.qml new file mode 100644 index 0000000..72812a5 --- /dev/null +++ b/basicsuite/ebike-ui/TripChart.qml @@ -0,0 +1,236 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.9 +import QtCharts 2.2 +import DataStore 1.0 + +import "./BikeStyle" + +ChartView { + property var exampleTrips: [ + [[0, 0], [15, 250], [30, 0], [30, 0], [25, 450], [20, 400], [10, 200], [10, 200], [20, 350], [20, 300], [10, 200], [10, 100], [10, 100], [10, 175], [10, 150], [15, 200], [15, 250], [10, 200], [15, 250], [0, 0]], + [[0, 0], [5, 100], [10, 200], [10, 200], [10, 150], [15, 250], [15, 275], [15, 200], [20, 350], [5, 50], [15, 200], [15, 250], [15, 225], [20, 300], [25, 425], [25, 400], [15, 200], [8, 125], [10, 175], [0, 0]], + [[0, 0], [20, 375], [15, 250], [15, 300], [15, 275], [0, 0], [10, 200], [10, 100], [10, 100], [15, 250], [10, 200], [10, 100], [10, 100], [8, 100], [25, 50], [15, 200], [15, 250], [10, 200], [8, 100], [0, 0]], + [[0, 0], [15, 300], [15, 200], [15, 250], [10, 450], [20, 375], [20, 350], [20, 250], [15, 200], [15, 225], [8, 150], [8, 100], [8, 125], [8, 100], [10, 150], [15, 200], [15, 250], [20, 300], [15, 250], [0, 0]] + ] + property bool animationRunning: false + property int currentIndex + property var tripDetails + + id: tripChart + antialiasing: true + backgroundColor: "transparent" + backgroundRoundness: 0 + title: "" + legend { + markerShape: Legend.MarkerShapeCircle + reverseMarkers: true + labelColor: "#ffffff" + font { + family: "Montserrat, Regular" + weight: Font.Normal + pixelSize: UILayout.chartLegendTextSize + } + } + + margins { + top: 0 + bottom: 0 + left: 0 + right: 0 + } + + // X-axis is a timestamp value + DateTimeAxis { + id: axisX + format: Qt.locale("en_US").timeFormat(Locale.ShortFormat) + tickCount: 3 + // No grid and no line + gridVisible: false + lineVisible: false + titleVisible: false + labelsColor: Colors.chartTimeLabel + labelsFont { + family: "Montserrat, Light" + weight: Font.Light + pixelSize: UILayout.chartTimeLabelSize + } + } + + ValueAxis { + id: speedAxis + min: 0 + max: 50 + gridLineColor: Colors.chartGridLine + labelsColor: Colors.chartSpeed + labelsFont { + family: "Montserrat, Regular" + weight: Font.Normal + pixelSize: UILayout.chartSpeedLabelSize + } + titleVisible: false + lineVisible: false + labelFormat: "%.0f" + } + + ValueAxis { + id: assistAxis + min: 0 + max: 500 + labelsColor: Colors.chartAssistpower + labelsFont { + family: "Montserrat, Regular" + weight: Font.Normal + pixelSize: UILayout.chartAssistpowerLabelSize + } + titleVisible: false + lineVisible: false + gridVisible: false + labelFormat: "%.0f" + } + + SplineSeries { + id: assistSeries + name: qsTr("Pedal assist (W)") + + axisX: axisX + axisYRight: assistAxis + pointsVisible: true + } + + SplineSeries { + id: speedSeries + name: datastore.unit === DataStore.Kmh ? qsTr("Speed (km/h)") : qsTr("Speed (mph)") + + axisX: axisX + axisY: speedAxis + pointsVisible: true + } + + function updateTripGraph() { + if (currentIndex === 0 ) { + // Clear all current values (resets the graph) + speedSeries.removePoints(0, speedSeries.count); + assistSeries.removePoints(0, assistSeries.count); + } else if (currentIndex > 0) { + // Clear all current values + speedSeries.removePoints(0, speedSeries.count); + assistSeries.removePoints(0, assistSeries.count); + var seriesdata = exampleTrips[currentIndex % 4]; + + var now = tripDetails.starttime * 1000; + var duration = tripDetails.duration / seriesdata.length; + + axisX.min = new Date(now - 60000); + for (var i = 0; i < seriesdata.length; i++) { + speedSeries.append(now, seriesdata[i][0]); + assistSeries.append(now, seriesdata[i][1]); + now += duration * 1000; + } + now -= duration * 1000; + axisX.max = new Date(now + 60000); + } + } + + onTripDetailsChanged: updateTripGraph() + + onCurrentIndexChanged: updateTripGraph() + + // Make sure we have a proper value here + onAnimationRunningChanged: tripAnimationTimer.lastUpdate = new Date().getTime() + + Timer { + id: tripAnimationTimer + property real lastUpdate: new Date().getTime() + property int currentIndex: 0 + property var values: [[0, 0], + [10, 200], + [15, 250], + [15, 250], + [8, 150], + [5, 100], + [20, 400], + [20, 375], + [15, 275], + [15, 250], + [25, 450], + [15, 200], + [15, 200], + [10, 175], + [10, 150], + [5, 100], + [8, 125], + [10, 200], + [15, 250], + [0, 0]] + + // Animate only if visible on screen + running: animationRunning && (swipeView.currentIndex === 0) + repeat: true + interval: 200 + onTriggered: { + var now = new Date().getTime(); + // Load a few initial numbers if empty + if (speedSeries.count === 0) { + speedSeries.append(now, values[0][0]); + assistSeries.append(now, values[0][1]); + speedSeries.append(now + 5000, values[1][0]); + assistSeries.append(now + 5000, values[1][1]); + speedSeries.append(now + 10000, values[2][0]); + assistSeries.append(now + 10000, values[2][1]); + speedSeries.append(now + 15000, values[3][0]); + assistSeries.append(now + 15000, values[3][1]); + currentIndex = 4; + } + + if (now - lastUpdate > 5000) { + speedSeries.append(now + 15000, values[currentIndex][0]); + assistSeries.append(now + 15000, values[currentIndex][1]); + if (speedSeries.count > 17) + speedSeries.remove(0); + if (assistSeries.count > 17) + assistSeries.remove(0); + currentIndex += 1; + if (currentIndex == 20) + currentIndex = 0; + lastUpdate = now; + } + axisX.min = new Date(now - 50 * 1000); + axisX.max = new Date(now); + } + } +} diff --git a/basicsuite/ebike-ui/ViewTab.qml b/basicsuite/ebike-ui/ViewTab.qml new file mode 100644 index 0000000..040436a --- /dev/null +++ b/basicsuite/ebike-ui/ViewTab.qml @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.9 +import QtQuick.Controls 2.2 +import QtQuick.Layouts 1.3 + +import "./BikeStyle" + +Item { + property alias musicPlayerSwitch: musicPlayerSwitch + + signal resetDemo + + Column { + anchors.left: parent.left + anchors.right: parent.right + + Text { + height: UILayout.configurationItemHeight + width: parent.width + text: qsTr("VIEW") + font { + family: "Montserrat, Medium" + weight: Font.Medium + pixelSize: UILayout.configurationTitleSize + } + color: Colors.tabTitleColor + verticalAlignment: Text.AlignVCenter + } + + ColumnSpacer { + color: Colors.tabItemBorder + } + + ConfigurationItem { + description: qsTr("Show FPS") + + ToggleSwitch { + anchors { + top: parent.top + bottom: parent.bottom + right: parent.right + } + checked: fps.visible + onCheckedChanged: fps.visible = checked + } + } + + ColumnSpacer { + color: Colors.tabItemBorder + } + + ConfigurationItem { + description: qsTr("Audio controls") + + ToggleSwitch { + id: musicPlayerSwitch + anchors { + top: parent.top + bottom: parent.bottom + right: parent.right + } + checked: false + onCheckedChanged: musicPlayer.state = (checked ? "" : "hidden") + } + } + + ColumnSpacer { + color: Colors.tabItemBorder + } + + ConfigurationItem { + description: qsTr("Reset demo") + + RoundButton { + id: resetButton + width: UILayout.unitButtonWidthMargin * 2 + mphText.implicitWidth + height: UILayout.unitButtonHeight + radius: height / 2 + anchors { + verticalCenter: parent.verticalCenter + right: parent.right + } + + background: Rectangle { + anchors.fill: parent + color: parent.down ? Colors.statsButtonPressed : "transparent" + radius: parent.radius + border.color: Colors.statsButtonActive + border.width: parent.down ? 0 : 1 + } + + contentItem: Text { + id: mphText + text: "RESET DEMO" + font { + family: "Montserrat, Medium" + weight: Font.Medium + pixelSize: UILayout.unitFontSize + } + color: Colors.statsButtonActiveText + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + onClicked: resetDemo() + } + } + + ColumnSpacer { + color: Colors.tabItemBorder + } + } +} diff --git a/basicsuite/ebike-ui/app.pro b/basicsuite/ebike-ui/app.pro new file mode 100644 index 0000000..dd993f1 --- /dev/null +++ b/basicsuite/ebike-ui/app.pro @@ -0,0 +1,141 @@ +QT += quick +CONFIG += c++11 +TARGET = ebike + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which as been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +include(../shared/shared.pri) +b2qtdemo_deploy_defaults() + +content.files = \ + qtquickcontrols2.conf \ + main.qml \ + NaviPage.qml \ + StatsPage.qml \ + MainPage.qml \ + SpeedView.qml \ + StatsBox.qml \ + NaviBox.qml \ + LightsBox.qml \ + ModeBox.qml \ + ClockView.qml \ + MusicPlayer.qml \ + ConfigurationDrawer.qml \ + IconifiedTabButton.qml \ + GeneralTab.qml \ + ColumnSpacer.qml \ + BikeInfoTab.qml \ + TripChart.qml \ + FpsItem.qml \ + NaviGuide.qml \ + NaviTripInfo.qml \ + ViewTab.qml \ + moment.js \ + StatsRow.qml \ + ConfigurationItem.qml \ + NaviButton.qml \ + ToggleSwitch.qml \ + mostrecent.bson + +content.path = $$DESTPATH + +style.files = \ + BikeStyle/Colors.qml \ + BikeStyle/qmldir \ + BikeStyle/UILayout.qml + + +images.files = \ + images/lights_off.png \ + images/lights_on.png \ + images/map-marker.png \ + images/trip.png \ + images/calories.png \ + images/nextsong.png \ + images/nextsong_pressed.png \ + images/play.png \ + images/play_pressed.png \ + images/prevsong.png \ + images/prevsong_pressed.png \ + images/speed.png \ + images/battery.png \ + images/assist.png \ + images/arrow_left.png \ + images/top_curtain_drag.png \ + images/spinner.png \ + images/checkmark.png \ + images/nav_left.png \ + images/nav_right.png \ + images/nav_straight.png \ + images/small_speedometer_arrow.png \ + images/map_locate.png \ + images/map_zoomin.png \ + images/map_zoomout.png \ + images/info.png \ + images/info_selected.png \ + images/list.png \ + images/list_selected.png \ + images/settings.png \ + images/settings_selected.png \ + images/curtain_up_arrow.png \ + images/search.png \ + images/search_cancel.png \ + images/fps_icon.png \ + images/arrow_right.png \ + images/curtain_shadow_handle.png \ + images/map_btn_shadow.png \ + images/map_destination.png \ + images/map_location_arrow.png \ + images/small_speedometer_shadow.png \ + images/navigation_widget_shadow.png \ + images/small_input_box_shadow.png \ + images/nav_bear_l.png \ + images/nav_bear_r.png \ + images/nav_hard_l.png \ + images/nav_hard_r.png \ + images/nav_light_left.png \ + images/nav_light_right.png \ + images/nav_nodir.png \ + images/nav_uturn_l.png \ + images/nav_uturn_r.png \ + images/pause.png \ + images/pause_pressed.png \ + images/ok.png \ + images/warning.png \ + images/bike-battery.png \ + images/bike-brakes.png \ + images/bike-chain.png \ + images/bike-frontwheel.png \ + images/bike-gears.png \ + images/bike-rearwheel.png \ + images/bike-light.png \ + images/blue_circle_gps_area.png + +OTHER_FILES += $${images.files} +INSTALLS += images +images.path = $$DESTPATH/images +export(images.files) +export(images.path) + +OTHER_FILES += $${style.files} +INSTALLS += style +style.path = $$DESTPATH/BikeStyle +export(style.files) +export(style.path) +export(OTHER_FILES) +export(INSTALLS) + + +OTHER_FILES += $${content.files} + +INSTALLS += target content + diff --git a/basicsuite/ebike-ui/brightnesscontroller.cpp b/basicsuite/ebike-ui/brightnesscontroller.cpp new file mode 100644 index 0000000..a6e2e30 --- /dev/null +++ b/basicsuite/ebike-ui/brightnesscontroller.cpp @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "brightnesscontroller.h" + +static const char brightnessSource[] = "/sys/class/backlight/backlight/brightness"; +static const int brightnessMax = 6; +static const int brightnessMin = 1; + +BrightnessController::BrightnessController(QObject *parent) + : QObject(parent) + , m_automatic(false) +{ + QFile brightnessfile(brightnessSource); + if (brightnessfile.exists() && brightnessfile.open(QIODevice::ReadOnly)) { + char data[1]; + if (brightnessfile.read(data, 1)) { + m_brightness = static_cast(data[0] - '0'); + } + } else { + // By default set to half + m_brightness = (brightnessMax + brightnessMin) / 2; + } +} + +void BrightnessController::setBrightness(int brightness) +{ + if (m_brightness == brightness) + return; + + // Valid values are between 1-6 + if (brightness < brightnessMin || brightness > brightnessMax) + return; + + QFile brightnessfile(brightnessSource); + if (brightnessfile.exists() && brightnessfile.open(QIODevice::WriteOnly)) { + char data[1] = {static_cast('0' + brightness)}; + if (brightnessfile.write(data, 1) == 1) { + m_brightness = brightness; + emit brightnessChanged(m_brightness); + } + } else { + // File does not exists, simulate changes + m_brightness = brightness; + emit brightnessChanged(m_brightness); + } +} + +void BrightnessController::setAutomatic(bool automatic) +{ + if (m_automatic == automatic) + return; + + m_automatic = automatic; + emit automaticChanged(m_automatic); +} diff --git a/basicsuite/ebike-ui/brightnesscontroller.h b/basicsuite/ebike-ui/brightnesscontroller.h new file mode 100644 index 0000000..7b85f58 --- /dev/null +++ b/basicsuite/ebike-ui/brightnesscontroller.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef BRIGHTNESSCONTROLLER_H +#define BRIGHTNESSCONTROLLER_H + +#include + +class BrightnessController : public QObject +{ + Q_OBJECT + Q_PROPERTY(int brightness READ brightness WRITE setBrightness NOTIFY brightnessChanged) + Q_PROPERTY(bool automatic READ automatic WRITE setAutomatic NOTIFY automaticChanged) + +public: + explicit BrightnessController(QObject *parent = nullptr); + +public: + int brightness() const { return m_brightness; } + bool automatic() const { return m_automatic; } + + void setBrightness(int brightness); + void setAutomatic(bool automatic); + +signals: + void brightnessChanged(int brightness); + void automaticChanged(bool automatic); + +public slots: + +private: + int m_brightness; + bool m_automatic; +}; + +#endif // BRIGHTNESSCONTROLLER_H diff --git a/basicsuite/ebike-ui/datamodelplugin/datamodelplugin.pro b/basicsuite/ebike-ui/datamodelplugin/datamodelplugin.pro new file mode 100644 index 0000000..ce22eec --- /dev/null +++ b/basicsuite/ebike-ui/datamodelplugin/datamodelplugin.pro @@ -0,0 +1,39 @@ +TEMPLATE = lib +CONFIG += plugin +QT += qml quick positioning charts + +TARGET = ebikedatamodelplugin + +SOURCES += plugin.cpp \ + $$PWD/../socketclient.cpp \ + $$PWD/../datastore.cpp \ + $$PWD/../navigation.cpp \ + $$PWD/../mapboxsuggestions.cpp \ + $$PWD/../suggestionsmodel.cpp \ + $$PWD/../mapbox.cpp \ + $$PWD/../brightnesscontroller.cpp \ + $$PWD/../fpscounter.cpp \ + $$PWD/../tripdatamodel.cpp + +HEADERS += \ + $$PWD/../socketclient.h \ + $$PWD/../datastore.h \ + $$PWD/../navigation.h \ + $$PWD/../mapboxsuggestions.h \ + $$PWD/../suggestionsmodel.h \ + $$PWD/../mapbox.h \ + $$PWD/../brightnesscontroller.h \ + $$PWD/../fpscounter.h \ + $$PWD/../tripdatamodel.h + +INCLUDEPATH += $$PWD/../ + +pluginfiles.files += \ + qmldir \ + +B2QT_DEPLOYPATH = /data/user/qt/qmlplugins/DataStore +target.path += $$B2QT_DEPLOYPATH +pluginfiles.path += $$B2QT_DEPLOYPATH + +INSTALLS += target pluginfiles + diff --git a/basicsuite/ebike-ui/datamodelplugin/plugin.cpp b/basicsuite/ebike-ui/datamodelplugin/plugin.cpp new file mode 100644 index 0000000..a07e4e6 --- /dev/null +++ b/basicsuite/ebike-ui/datamodelplugin/plugin.cpp @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Device Creation. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 The Qt Company Ltd 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$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "datastore.h" +#include "tripdatamodel.h" +#include "navigation.h" +#include "mapbox.h" +#include "mapboxsuggestions.h" +#include "suggestionsmodel.h" +#include "brightnesscontroller.h" +#include "fpscounter.h" + +class QExampleQmlPlugin : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") + +public: + + void registerTypes(const char *uri) + { + qmlRegisterType("DataStore", 1, 0, "DataStore"); + } + + void initializeEngine(QQmlEngine *engine, const char *uri) + { + // Setup data store for connection to backend server + DataStore *datastore = new DataStore(engine); + datastore->connectToServer("datasocket"); + + // Setup mapbox and suggestions + MapBox *mapbox = new MapBox(engine); + MapBoxSuggestions *suggest = new MapBoxSuggestions(mapbox, engine); + + // Setup navigation container + Navigation *navi = new Navigation(mapbox, engine); + + // Brightness controller + BrightnessController *brightness = new BrightnessController(engine); + + // FPS counter + FpsCounter *fps = new FpsCounter(engine); + + QQmlContext *context = engine->rootContext(); + context->setContextProperty("datastore", datastore); + context->setContextProperty("tripdata", datastore->tripDataModel()); + context->setContextProperty("navigation", navi); + context->setContextProperty("suggest", suggest); + context->setContextProperty("suggestions", suggest->suggestions()); + context->setContextProperty("brightness", brightness); + context->setContextProperty("fps", fps); + } +}; + + +#include "plugin.moc" diff --git a/basicsuite/ebike-ui/datamodelplugin/qmldir b/basicsuite/ebike-ui/datamodelplugin/qmldir new file mode 100644 index 0000000..3018d21 --- /dev/null +++ b/basicsuite/ebike-ui/datamodelplugin/qmldir @@ -0,0 +1,2 @@ +module DataStore +plugin ebikedatamodelplugin diff --git a/basicsuite/ebike-ui/datastore.cpp b/basicsuite/ebike-ui/datastore.cpp new file mode 100644 index 0000000..73567ac --- /dev/null +++ b/basicsuite/ebike-ui/datastore.cpp @@ -0,0 +1,300 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +#include "socketclient.h" +#include "datastore.h" +#include "tripdatamodel.h" + +// Speed conversions from m/s to km/h and mph +static const double msToKmh = 3.6; +static const double msToMph = 2.2369418519393043; +// Distance conversions to and from m to km and mi +static const double mToKm = 0.001; +static const double mToMi = 0.000621371; +static const double kmToM = 1000.0; +static const double miToM = 1609.344; +static const double mToYd = 1760.0 / 1609.344; + +DataStore::DataStore(QObject *parent) + : QObject(parent) + , m_client(new SocketClient(this)) + , m_unit(Mph) + , m_trips(new TripDataModel(this, this)) +{ + connect(m_client, &SocketClient::connected, this, &DataStore::requestStatus); + connect(m_client, &SocketClient::newMessage, this, &DataStore::parseMessage); +} + +void DataStore::connectToServer(const QString &servername) +{ + m_client->connectToServer(servername); +} + +void DataStore::getTrips() +{ + m_client->sendToServer(QJsonObject{{"method", "gettrips"}}); +} + +void DataStore::endTrip() +{ + m_client->sendToServer(QJsonObject{{"method", "endtrip"}}); +} + +void DataStore::toggleMode() +{ + setMode(mode() == Cruise ? Sport : Cruise); +} + +void DataStore::resetDemo() +{ + m_client->sendToServer(QJsonObject{{"method", "reset"}}); +} + +double DataStore::speed() const +{ + return convertSpeed(m_properties.value("speed").toDouble()); +} + +double DataStore::topSpeed() const +{ + return convertSpeed(m_properties.value("topspeed").toDouble()); +} + +double DataStore::averageSpeed() const +{ + return convertSpeed(m_current.value("distance").toDouble() / m_current.value("duration").toDouble()); +} + +double DataStore::odometer() const +{ + return convertDistance(m_properties.value("odometer").toDouble()); +} + +double DataStore::trip() const +{ + return convertDistance(m_current.value("distance").toDouble()); +} + +double DataStore::calories() const +{ + return m_current.value("calories").toDouble(); +} + +double DataStore::assistDistance() const +{ + return convertDistance(m_properties.value("assistdistance").toDouble()); +} + +double DataStore::assistPower() const +{ + return m_properties.value("assistpower").toDouble(); +} + +double DataStore::batteryLevel() const +{ + return m_properties.value("batterylevel").toDouble(); +} + +bool DataStore::lights() const +{ + return m_properties.value("lights").toBool(); +} + +DataStore::Mode DataStore::mode() const +{ + return static_cast(m_properties.value("mode").toInt()); +} + +DataStore::Unit DataStore::unit() const +{ + return m_unit; +} + +int DataStore::arrow() const +{ + return m_properties.value("arrow").toInt(); +} + +double DataStore::legDistance() const +{ + return m_properties.value("legdistance").toDouble(); +} + +double DataStore::tripRemaining() const +{ + return m_properties.value("tripremaining").toDouble(); +} + +QString DataStore::smallUnit() const +{ + return m_unit == Kmh ? "m" : "yd"; +} + +void DataStore::setLights(bool lights) +{ + if (m_properties.value("lights").toBool() == lights) + return; + + m_properties.insert("lights", lights); + m_client->sendToServer(QJsonObject{{"method", "set"}, {"key", "lights"}, {"value", lights}}); + emit lightsChanged(); +} + +void DataStore::setMode(Mode mode) +{ + if (DataStore::mode() == mode) + return; + + m_properties.insert("mode", mode); + m_client->sendToServer(QJsonObject{{"method", "set"}, {"key", "mode"}, {"value", static_cast(mode)}}); + emit modeChanged(); +} + +void DataStore::setUnit(DataStore::Unit unit) +{ + if (m_unit == unit) + return; + + m_unit = unit; + emit unitChanged(); + // Also emit all the other signals that are affected by mode change + emit speedChanged(); + emit averagespeedChanged(); + emit odometerChanged(); + emit tripChanged(); + emit assistdistanceChanged(); + emit smallUnitChanged(smallUnit()); +} + +double DataStore::convertSpeed(double speed) const +{ + return speed * (m_unit == Kmh ? msToKmh : msToMph); +} + +double DataStore::convertDistance(double distance) const +{ + return distance * (m_unit == Kmh ? mToKm : mToMi); +} + +double DataStore::convertSmallDistance(double distance) const +{ + return distance * (m_unit == Kmh ? 1.0 : mToYd); +} + +QString DataStore::getSmallUnit() const +{ + return m_unit == Kmh ? "m" : "yd"; +} + +QJsonObject DataStore::splitDistance(double distance, bool round) const +{ + if (m_unit == Kmh) { + if (distance >= kmToM) + return QJsonObject{{"value", distance * mToKm}, {"unit", "km"}, {"decimal", true}}; + else { + if (round) + distance = qRound(distance / 10) * 10; + return QJsonObject{{"value", distance}, {"unit", "m"}, {"decimal", false}}; + } + } else { + if (distance >= miToM) + return QJsonObject{{"value", distance * mToMi}, {"unit", "mi."}, {"decimal", true}}; + else { + distance *= mToYd; + if (round) + distance = qRound(distance / 10) * 10; + return QJsonObject{{"value", distance}, {"unit", "yd"}, {"decimal", false}}; + } + } +} + +QJsonObject DataStore::splitDuration(double duration) const +{ + if (duration >= 60.0) + return QJsonObject{{"value", duration / 60.0}, {"unit", "min"}}; + else + return QJsonObject{{"value", duration}, {"unit", "s"}}; +} + +void DataStore::requestStatus() +{ + m_client->sendToServer(QJsonObject{{"method", "getall"}}); +} + +void DataStore::emitByName(const QString &valuename) +{ + // Use QMetaObject information to find a proper signal + const QMetaObject *meta = metaObject(); + + // Find the notifier signal + QString signalName = QString("%1Changed()").arg(valuename); + int methodIndex = meta->indexOfSignal(signalName.toLatin1().constData()); + meta->method(methodIndex).invoke(this, Qt::AutoConnection); +} + +void DataStore::parseMessage(const QJsonObject &message) +{ + QString method = message.value("method").toString(); + + // If we are updating just one, simply insert new value and emit + if (method == "updateone") { + QString key = message.value("key").toString(); + m_properties.insert(key, message.value("value")); + emitByName(key); + // If we are updating many, then iterate over the list and update each value + } else if (method == "updatemany") { + foreach (const QJsonValue &value, message.value("values").toArray()) { + QJsonObject obj = value.toObject(); + QString key = obj.value("key").toString(); + m_properties.insert(key, obj.value("value")); + emitByName(key); + } + } else if (method == "trips") { + m_trips->setTrips(message.value("trips").toArray()); + } else if (method == "trip") { + m_trips->addTrip(message.value("trip").toObject()); + } else if (method == "currenttrip") { + m_current = message.value("currenttrip").toObject(); + m_trips->setCurrentTrip(m_current); + emit currentTripChanged(); + } else if (method == "reset") { + emit demoReset(); + } +} diff --git a/basicsuite/ebike-ui/datastore.h b/basicsuite/ebike-ui/datastore.h new file mode 100644 index 0000000..20fa388 --- /dev/null +++ b/basicsuite/ebike-ui/datastore.h @@ -0,0 +1,163 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DATASTORE_H +#define DATASTORE_H + +#include +#include + +class SocketClient; +class TripDataModel; + +class DataStore: public QObject +{ + Q_OBJECT + + // Different measured properties + Q_PROPERTY(double speed READ speed NOTIFY speedChanged) + Q_PROPERTY(double topspeed READ topSpeed NOTIFY topspeedChanged) + Q_PROPERTY(double averagespeed READ averageSpeed NOTIFY currentTripChanged) + Q_PROPERTY(double odometer READ odometer NOTIFY odometerChanged) + Q_PROPERTY(double trip READ trip NOTIFY currentTripChanged) + Q_PROPERTY(double calories READ calories NOTIFY currentTripChanged) + Q_PROPERTY(double assistdistance READ assistDistance NOTIFY assistdistanceChanged) + Q_PROPERTY(double assistpower READ assistPower NOTIFY assistpowerChanged) + Q_PROPERTY(double batterylevel READ batteryLevel NOTIFY batterylevelChanged) + + // Toggles for lights and mode + Q_PROPERTY(bool lights READ lights WRITE setLights NOTIFY lightsChanged) + Q_PROPERTY(Mode mode READ mode WRITE setMode NOTIFY modeChanged) + + // Current units + Q_PROPERTY(Unit unit READ unit WRITE setUnit NOTIFY unitChanged) + Q_PROPERTY(QString smallUnit READ smallUnit NOTIFY smallUnitChanged) + + // Navigation + Q_PROPERTY(int arrow READ arrow NOTIFY arrowChanged) + Q_PROPERTY(double legdistance READ legDistance NOTIFY legdistanceChanged) + Q_PROPERTY(double tripremaining READ tripRemaining NOTIFY tripremainingChanged) + +public: + explicit DataStore(QObject *parent = nullptr); + + enum Mode { Cruise, Sport }; + Q_ENUM(Mode) + + enum Unit { Kmh, Mph }; + Q_ENUM(Unit) + +public: + // Getters + double speed() const; + double topSpeed() const; + double averageSpeed() const; + double odometer() const; + double trip() const; + double calories() const; + double assistDistance() const; + double assistPower() const; + double batteryLevel() const; + bool lights() const; + Mode mode() const; + Unit unit() const; + int arrow() const; + double legDistance() const; + double tripRemaining() const; + QString smallUnit() const; + + // Setters + void setLights(bool lights); + void setMode(Mode mode); + void setUnit(Unit unit); + + // Get trip data model + TripDataModel *tripDataModel() const { return m_trips; } + + // Convert speed and distance to proper units + Q_INVOKABLE double convertSpeed(double speed) const; + Q_INVOKABLE double convertDistance(double distance) const; + Q_INVOKABLE double convertSmallDistance(double distance) const; + Q_INVOKABLE QString getSmallUnit() const; + + // Split and convert distance and duration to value and unit + Q_INVOKABLE QJsonObject splitDistance(double distance, bool round=false) const; + Q_INVOKABLE QJsonObject splitDuration(double duration) const; + +private: + void emitByName(const QString &valuename); + +signals: + void speedChanged(); + void topspeedChanged(); + void averagespeedChanged(); + void odometerChanged(); + void tripChanged(); + void caloriesChanged(); + void assistdistanceChanged(); + void assistpowerChanged(); + void batterylevelChanged(); + void lightsChanged(); + void modeChanged(); + void unitChanged(); + void arrowChanged(); + void legdistanceChanged(); + void tripremainingChanged(); + void currentTripChanged(); + void smallUnitChanged(QString smallUnit); + void demoReset(); + +public slots: + void connectToServer(const QString &servername); + void getTrips(); + void endTrip(); + void toggleMode(); + void resetDemo(); + +private slots: + void requestStatus(); + void parseMessage(const QJsonObject &message); + +private: + SocketClient *m_client; + QJsonObject m_properties; + QJsonObject m_current; + Unit m_unit; + TripDataModel *m_trips; + int m_smallUnit; +}; + +#endif // DATASTORE_H diff --git a/basicsuite/ebike-ui/ebike-ui.pro b/basicsuite/ebike-ui/ebike-ui.pro new file mode 100644 index 0000000..70443af --- /dev/null +++ b/basicsuite/ebike-ui/ebike-ui.pro @@ -0,0 +1,7 @@ +TEMPLATE = subdirs +CONFIG += ordered + +SUBDIRS += \ + datamodelplugin \ + app.pro + diff --git a/basicsuite/ebike-ui/ebike_en.ts b/basicsuite/ebike-ui/ebike_en.ts new file mode 100644 index 0000000..14679be --- /dev/null +++ b/basicsuite/ebike-ui/ebike_en.ts @@ -0,0 +1,290 @@ + + + + + BikeInfoTab + + + BIKE INFO + BIKE INFO + + + + Next maintenance + Next maintenance + + + + 15000 km + 15000 km + + + + 10000 mi. + 10000 mi. + + + + Battery health + Battery health + + + + Excellent + Excellent + + + + System Log + System Log + + + + ConfigurationDrawer + + LIST + LIST + + + TBD + TBD + + + + GeneralTab + + + GENERAL + GENERAL + + + + Language + Language + + + + English + English + + + + Brightness + Brightness + + + + Auto + Auto + + + + Units + Units + + + + ModeBox + + + SPORT + SPORT + + + + CRUISE + CRUISE + + + + MusicPlayer + + + Singer McSongface - Some really long title here + + + + + NaviPage + + + <i>Where do you want to go?</i> + <i>Where do you want to go?</i> + + + + SpeedView + + + km/h + km/h + + + + mph + mph + + + + AVG +km/h + AVG +km/h + + + + AVG +mph + AVG +mph + + + + km +assist +left + km +assist +left + + + + mi. +assist +left + mi. +assist +left + + + + StatsPage + + + END TRIP + END TRIP + + + + YESTERDAY + YESTERDAY + + + + Total + Total + + + + km + km + + + + mi. + mi. + + + + Duration (h:m) + Duration (h:m) + + + + Max. speed (km/h) + Max. speed (km/h) + + + + Max. speed (mph) + Max. speed (mph) + + + + Distance (km) + Distance (km) + + + + Distance (mi.) + Distance (mi.) + + + + Avg. speed (km/h) + Avg. speed (km/h) + + + + Avg. speed (mph) + Avg. speed (mph) + + + + Calories (kcal) + Calories (kcal) + + + + Ascent (m) + Ascent (m) + + + + SuggestionsModel + + + Place + Place + + + + TripChart + + + Speed (km/h) + Speed (km/h) + + + + Speed (mph) + Speed (mph) + + + + Pedal assist (W) + Pedal assist (W) + + + + ViewTab + + + VIEW + VIEW + + + + Show FPS + Show FPS + + + + Audio controls + Audio controls + + + + TBD + TBD + + + + mainview + + + Qt eBike + Qt eBike + + + diff --git a/basicsuite/ebike-ui/ebike_fi.ts b/basicsuite/ebike-ui/ebike_fi.ts new file mode 100644 index 0000000..9601fc7 --- /dev/null +++ b/basicsuite/ebike-ui/ebike_fi.ts @@ -0,0 +1,290 @@ + + + + + BikeInfoTab + + + BIKE INFO + PYÖRÄN TIEDOT + + + + Next maintenance + Seuraava huolto + + + + 15000 km + 15000 km + + + + 10000 mi. + 10000 mi. + + + + Battery health + Akun tila + + + + Excellent + Loistava + + + + System Log + Järjestelmälogi + + + + ConfigurationDrawer + + LIST + LISTA + + + TBD + MYÖH + + + + GeneralTab + + + GENERAL + YLEINEN + + + + Language + Kieli + + + + English + englanti + + + + Brightness + Kirkkaus + + + + Auto + Auto + + + + Units + Yksiköt + + + + ModeBox + + + SPORT + SPORT + + + + CRUISE + CRUISE + + + + MusicPlayer + + + Singer McSongface - Some really long title here + + + + + NaviPage + + + <i>Where do you want to go?</i> + <i>Mihin haluat mennä?</i> + + + + SpeedView + + + km/h + km/h + + + + mph + mph + + + + AVG +km/h + KESK +km/h + + + + AVG +mph + KESK +mph + + + + km +assist +left + km +avustus +jäljellä + + + + mi. +assist +left + mi. +avustus +jäljellä + + + + StatsPage + + + END TRIP + LOPETA MATKA + + + + YESTERDAY + EILEN + + + + Total + Yhteensä + + + + km + km + + + + mi. + mi. + + + + Duration (h:m) + Kesto (h:m) + + + + Max. speed (km/h) + Huippunopeus (km/h) + + + + Max. speed (mph) + Huippunopeus (mph) + + + + Distance (km) + Etäisyys (km) + + + + Distance (mi.) + Etäisyys (mi.) + + + + Avg. speed (km/h) + Keskinopeus (km/h) + + + + Avg. speed (mph) + Keskinopeus (mph) + + + + Calories (kcal) + Kalorit (kcal) + + + + Ascent (m) + Nousu (m) + + + + SuggestionsModel + + + Place + Paikka + + + + TripChart + + + Speed (km/h) + Nopeus (km/h) + + + + Speed (mph) + Nopeus (mph) + + + + Pedal assist (W) + Avustusteho (W) + + + + ViewTab + + + VIEW + NÄYTÄ + + + + Show FPS + Näytä FPS + + + + Audio controls + Musiikkisoitin + + + + TBD + MYÖH + + + + mainview + + + Qt eBike + Qt eBike + + + diff --git a/basicsuite/ebike-ui/fonts/Montserrat-Black.ttf b/basicsuite/ebike-ui/fonts/Montserrat-Black.ttf new file mode 100644 index 0000000..bf5443c Binary files /dev/null and b/basicsuite/ebike-ui/fonts/Montserrat-Black.ttf differ diff --git a/basicsuite/ebike-ui/fonts/Montserrat-BlackItalic.ttf b/basicsuite/ebike-ui/fonts/Montserrat-BlackItalic.ttf new file mode 100644 index 0000000..3eee3a7 Binary files /dev/null and b/basicsuite/ebike-ui/fonts/Montserrat-BlackItalic.ttf differ diff --git a/basicsuite/ebike-ui/fonts/Montserrat-Bold.ttf b/basicsuite/ebike-ui/fonts/Montserrat-Bold.ttf new file mode 100644 index 0000000..8e9a5f3 Binary files /dev/null and b/basicsuite/ebike-ui/fonts/Montserrat-Bold.ttf differ diff --git a/basicsuite/ebike-ui/fonts/Montserrat-BoldItalic.ttf b/basicsuite/ebike-ui/fonts/Montserrat-BoldItalic.ttf new file mode 100644 index 0000000..2c33630 Binary files /dev/null and b/basicsuite/ebike-ui/fonts/Montserrat-BoldItalic.ttf differ diff --git a/basicsuite/ebike-ui/fonts/Montserrat-ExtraBold.ttf b/basicsuite/ebike-ui/fonts/Montserrat-ExtraBold.ttf new file mode 100644 index 0000000..1e3692d Binary files /dev/null and b/basicsuite/ebike-ui/fonts/Montserrat-ExtraBold.ttf differ diff --git a/basicsuite/ebike-ui/fonts/Montserrat-ExtraBoldItalic.ttf b/basicsuite/ebike-ui/fonts/Montserrat-ExtraBoldItalic.ttf new file mode 100644 index 0000000..5f6c382 Binary files /dev/null and b/basicsuite/ebike-ui/fonts/Montserrat-ExtraBoldItalic.ttf differ diff --git a/basicsuite/ebike-ui/fonts/Montserrat-ExtraLight.ttf b/basicsuite/ebike-ui/fonts/Montserrat-ExtraLight.ttf new file mode 100644 index 0000000..7490dc7 Binary files /dev/null and b/basicsuite/ebike-ui/fonts/Montserrat-ExtraLight.ttf differ diff --git a/basicsuite/ebike-ui/fonts/Montserrat-ExtraLightItalic.ttf b/basicsuite/ebike-ui/fonts/Montserrat-ExtraLightItalic.ttf new file mode 100644 index 0000000..24e1354 Binary files /dev/null and b/basicsuite/ebike-ui/fonts/Montserrat-ExtraLightItalic.ttf differ diff --git a/basicsuite/ebike-ui/fonts/Montserrat-Italic.ttf b/basicsuite/ebike-ui/fonts/Montserrat-Italic.ttf new file mode 100644 index 0000000..c5a36e5 Binary files /dev/null and b/basicsuite/ebike-ui/fonts/Montserrat-Italic.ttf differ diff --git a/basicsuite/ebike-ui/fonts/Montserrat-Light.ttf b/basicsuite/ebike-ui/fonts/Montserrat-Light.ttf new file mode 100644 index 0000000..e66dc5b Binary files /dev/null and b/basicsuite/ebike-ui/fonts/Montserrat-Light.ttf differ diff --git a/basicsuite/ebike-ui/fonts/Montserrat-LightItalic.ttf b/basicsuite/ebike-ui/fonts/Montserrat-LightItalic.ttf new file mode 100644 index 0000000..b78b8b7 Binary files /dev/null and b/basicsuite/ebike-ui/fonts/Montserrat-LightItalic.ttf differ diff --git a/basicsuite/ebike-ui/fonts/Montserrat-Medium.ttf b/basicsuite/ebike-ui/fonts/Montserrat-Medium.ttf new file mode 100644 index 0000000..88d70b8 Binary files /dev/null and b/basicsuite/ebike-ui/fonts/Montserrat-Medium.ttf differ diff --git a/basicsuite/ebike-ui/fonts/Montserrat-MediumItalic.ttf b/basicsuite/ebike-ui/fonts/Montserrat-MediumItalic.ttf new file mode 100644 index 0000000..225fd18 Binary files /dev/null and b/basicsuite/ebike-ui/fonts/Montserrat-MediumItalic.ttf differ diff --git a/basicsuite/ebike-ui/fonts/Montserrat-Regular.ttf b/basicsuite/ebike-ui/fonts/Montserrat-Regular.ttf new file mode 100644 index 0000000..626355a Binary files /dev/null and b/basicsuite/ebike-ui/fonts/Montserrat-Regular.ttf differ diff --git a/basicsuite/ebike-ui/fonts/Montserrat-SemiBold.ttf b/basicsuite/ebike-ui/fonts/Montserrat-SemiBold.ttf new file mode 100644 index 0000000..6157045 Binary files /dev/null and b/basicsuite/ebike-ui/fonts/Montserrat-SemiBold.ttf differ diff --git a/basicsuite/ebike-ui/fonts/Montserrat-SemiBoldItalic.ttf b/basicsuite/ebike-ui/fonts/Montserrat-SemiBoldItalic.ttf new file mode 100644 index 0000000..c6dd977 Binary files /dev/null and b/basicsuite/ebike-ui/fonts/Montserrat-SemiBoldItalic.ttf differ diff --git a/basicsuite/ebike-ui/fonts/Montserrat-Thin.ttf b/basicsuite/ebike-ui/fonts/Montserrat-Thin.ttf new file mode 100644 index 0000000..dc16a02 Binary files /dev/null and b/basicsuite/ebike-ui/fonts/Montserrat-Thin.ttf differ diff --git a/basicsuite/ebike-ui/fonts/Montserrat-ThinItalic.ttf b/basicsuite/ebike-ui/fonts/Montserrat-ThinItalic.ttf new file mode 100644 index 0000000..b9e12f4 Binary files /dev/null and b/basicsuite/ebike-ui/fonts/Montserrat-ThinItalic.ttf differ diff --git a/basicsuite/ebike-ui/fonts/OFL.txt b/basicsuite/ebike-ui/fonts/OFL.txt new file mode 100644 index 0000000..74605df --- /dev/null +++ b/basicsuite/ebike-ui/fonts/OFL.txt @@ -0,0 +1,93 @@ +Copyright (c) 2014, Indian Type Foundry (info@indiantypefoundry.com). + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/basicsuite/ebike-ui/fonts/Teko-Bold.ttf b/basicsuite/ebike-ui/fonts/Teko-Bold.ttf new file mode 100644 index 0000000..d061824 Binary files /dev/null and b/basicsuite/ebike-ui/fonts/Teko-Bold.ttf differ diff --git a/basicsuite/ebike-ui/fonts/Teko-Light.ttf b/basicsuite/ebike-ui/fonts/Teko-Light.ttf new file mode 100644 index 0000000..ec5194a Binary files /dev/null and b/basicsuite/ebike-ui/fonts/Teko-Light.ttf differ diff --git a/basicsuite/ebike-ui/fonts/Teko-Medium.ttf b/basicsuite/ebike-ui/fonts/Teko-Medium.ttf new file mode 100644 index 0000000..cc38086 Binary files /dev/null and b/basicsuite/ebike-ui/fonts/Teko-Medium.ttf differ diff --git a/basicsuite/ebike-ui/fonts/Teko-Regular.ttf b/basicsuite/ebike-ui/fonts/Teko-Regular.ttf new file mode 100644 index 0000000..3161e63 Binary files /dev/null and b/basicsuite/ebike-ui/fonts/Teko-Regular.ttf differ diff --git a/basicsuite/ebike-ui/fonts/Teko-SemiBold.ttf b/basicsuite/ebike-ui/fonts/Teko-SemiBold.ttf new file mode 100644 index 0000000..bc17e5a Binary files /dev/null and b/basicsuite/ebike-ui/fonts/Teko-SemiBold.ttf differ diff --git a/basicsuite/ebike-ui/fonts/fontawesome-webfont.ttf b/basicsuite/ebike-ui/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/basicsuite/ebike-ui/fonts/fontawesome-webfont.ttf differ diff --git a/basicsuite/ebike-ui/fpscounter.cpp b/basicsuite/ebike-ui/fpscounter.cpp new file mode 100644 index 0000000..137dcb4 --- /dev/null +++ b/basicsuite/ebike-ui/fpscounter.cpp @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "fpscounter.h" + +FpsCounter::FpsCounter(QObject *parent) + : QObject(parent) + , m_frameCounter(0) + , m_fps(0.0) + , m_visible(false) +{ +} + +void FpsCounter::setVisible(bool visible) +{ + if (m_visible == visible) + return; + + m_visible = visible; + emit visibleChanged(m_visible); +} + +void FpsCounter::setWindow(QQuickWindow *window) +{ + connect(window, &QQuickWindow::frameSwapped, this, &FpsCounter::frameUpdated); + startTimer(1000); + m_timer.start(); +} + +void FpsCounter::timerEvent(QTimerEvent *) +{ + // Calculate new FPS + qreal newfps = qRound(m_frameCounter * 1000.0 / m_timer.elapsed()); + m_frameCounter = 0; + m_timer.start(); + + // If there is no change, do nothing + if (qFuzzyCompare(m_fps, newfps)) + return; + + // Otherwise emit new fps + m_fps = newfps; + emit fpsChanged(m_fps); +} diff --git a/basicsuite/ebike-ui/fpscounter.h b/basicsuite/ebike-ui/fpscounter.h new file mode 100644 index 0000000..7828844 --- /dev/null +++ b/basicsuite/ebike-ui/fpscounter.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef FPSCOUNTER_H +#define FPSCOUNTER_H + +#include +#include + +class QQuickWindow; + +class FpsCounter : public QObject +{ + Q_OBJECT + Q_PROPERTY(qreal fps READ fps NOTIFY fpsChanged) + Q_PROPERTY(bool visible READ visible WRITE setVisible NOTIFY visibleChanged) + +public: + explicit FpsCounter(QObject *parent = nullptr); + +public: + qreal fps() const { return m_fps; } + bool visible() const { return m_visible; } + void setVisible(bool visible); + void setWindow(QQuickWindow *window); + +protected: + void timerEvent(QTimerEvent *); + +signals: + void fpsChanged(qreal fps); + void visibleChanged(bool visible); + +private slots: + void frameUpdated() { m_frameCounter++; } + +private: + QElapsedTimer m_timer; + int m_frameCounter; + qreal m_fps; + bool m_visible; +}; + +#endif // FPSCOUNTER_H diff --git a/basicsuite/ebike-ui/images/arrow_left.png b/basicsuite/ebike-ui/images/arrow_left.png new file mode 100644 index 0000000..6c67a2c Binary files /dev/null and b/basicsuite/ebike-ui/images/arrow_left.png differ diff --git a/basicsuite/ebike-ui/images/arrow_right.png b/basicsuite/ebike-ui/images/arrow_right.png new file mode 100644 index 0000000..b8cfb2e Binary files /dev/null and b/basicsuite/ebike-ui/images/arrow_right.png differ diff --git a/basicsuite/ebike-ui/images/assist.png b/basicsuite/ebike-ui/images/assist.png new file mode 100644 index 0000000..4a2bc95 Binary files /dev/null and b/basicsuite/ebike-ui/images/assist.png differ diff --git a/basicsuite/ebike-ui/images/battery.png b/basicsuite/ebike-ui/images/battery.png new file mode 100644 index 0000000..170c48d Binary files /dev/null and b/basicsuite/ebike-ui/images/battery.png differ diff --git a/basicsuite/ebike-ui/images/bike-battery.png b/basicsuite/ebike-ui/images/bike-battery.png new file mode 100644 index 0000000..e354d33 Binary files /dev/null and b/basicsuite/ebike-ui/images/bike-battery.png differ diff --git a/basicsuite/ebike-ui/images/bike-brakes.png b/basicsuite/ebike-ui/images/bike-brakes.png new file mode 100644 index 0000000..c271d75 Binary files /dev/null and b/basicsuite/ebike-ui/images/bike-brakes.png differ diff --git a/basicsuite/ebike-ui/images/bike-chain.png b/basicsuite/ebike-ui/images/bike-chain.png new file mode 100644 index 0000000..07879a4 Binary files /dev/null and b/basicsuite/ebike-ui/images/bike-chain.png differ diff --git a/basicsuite/ebike-ui/images/bike-frontwheel.png b/basicsuite/ebike-ui/images/bike-frontwheel.png new file mode 100644 index 0000000..ab9297f Binary files /dev/null and b/basicsuite/ebike-ui/images/bike-frontwheel.png differ diff --git a/basicsuite/ebike-ui/images/bike-gears.png b/basicsuite/ebike-ui/images/bike-gears.png new file mode 100644 index 0000000..c977644 Binary files /dev/null and b/basicsuite/ebike-ui/images/bike-gears.png differ diff --git a/basicsuite/ebike-ui/images/bike-light.png b/basicsuite/ebike-ui/images/bike-light.png new file mode 100644 index 0000000..b18da3c Binary files /dev/null and b/basicsuite/ebike-ui/images/bike-light.png differ diff --git a/basicsuite/ebike-ui/images/bike-rearwheel.png b/basicsuite/ebike-ui/images/bike-rearwheel.png new file mode 100644 index 0000000..fb02923 Binary files /dev/null and b/basicsuite/ebike-ui/images/bike-rearwheel.png differ diff --git a/basicsuite/ebike-ui/images/blue_circle_gps_area.png b/basicsuite/ebike-ui/images/blue_circle_gps_area.png new file mode 100644 index 0000000..06e1b6e Binary files /dev/null and b/basicsuite/ebike-ui/images/blue_circle_gps_area.png differ diff --git a/basicsuite/ebike-ui/images/calories.png b/basicsuite/ebike-ui/images/calories.png new file mode 100644 index 0000000..fe3cbb1 Binary files /dev/null and b/basicsuite/ebike-ui/images/calories.png differ diff --git a/basicsuite/ebike-ui/images/checkmark.png b/basicsuite/ebike-ui/images/checkmark.png new file mode 100644 index 0000000..0e1b387 Binary files /dev/null and b/basicsuite/ebike-ui/images/checkmark.png differ diff --git a/basicsuite/ebike-ui/images/curtain_shadow_handle.png b/basicsuite/ebike-ui/images/curtain_shadow_handle.png new file mode 100644 index 0000000..afaf3ec Binary files /dev/null and b/basicsuite/ebike-ui/images/curtain_shadow_handle.png differ diff --git a/basicsuite/ebike-ui/images/curtain_up_arrow.png b/basicsuite/ebike-ui/images/curtain_up_arrow.png new file mode 100644 index 0000000..97095d0 Binary files /dev/null and b/basicsuite/ebike-ui/images/curtain_up_arrow.png differ diff --git a/basicsuite/ebike-ui/images/fps_icon.png b/basicsuite/ebike-ui/images/fps_icon.png new file mode 100644 index 0000000..4cecab7 Binary files /dev/null and b/basicsuite/ebike-ui/images/fps_icon.png differ diff --git a/basicsuite/ebike-ui/images/info.png b/basicsuite/ebike-ui/images/info.png new file mode 100644 index 0000000..6ad9192 Binary files /dev/null and b/basicsuite/ebike-ui/images/info.png differ diff --git a/basicsuite/ebike-ui/images/info_selected.png b/basicsuite/ebike-ui/images/info_selected.png new file mode 100644 index 0000000..25056ff Binary files /dev/null and b/basicsuite/ebike-ui/images/info_selected.png differ diff --git a/basicsuite/ebike-ui/images/lights_off.png b/basicsuite/ebike-ui/images/lights_off.png new file mode 100644 index 0000000..4ad0abd Binary files /dev/null and b/basicsuite/ebike-ui/images/lights_off.png differ diff --git a/basicsuite/ebike-ui/images/lights_on.png b/basicsuite/ebike-ui/images/lights_on.png new file mode 100644 index 0000000..6da9893 Binary files /dev/null and b/basicsuite/ebike-ui/images/lights_on.png differ diff --git a/basicsuite/ebike-ui/images/list.png b/basicsuite/ebike-ui/images/list.png new file mode 100644 index 0000000..2e1633d Binary files /dev/null and b/basicsuite/ebike-ui/images/list.png differ diff --git a/basicsuite/ebike-ui/images/list_selected.png b/basicsuite/ebike-ui/images/list_selected.png new file mode 100644 index 0000000..1c61a5e Binary files /dev/null and b/basicsuite/ebike-ui/images/list_selected.png differ diff --git a/basicsuite/ebike-ui/images/map-marker.png b/basicsuite/ebike-ui/images/map-marker.png new file mode 100644 index 0000000..e2dd669 Binary files /dev/null and b/basicsuite/ebike-ui/images/map-marker.png differ diff --git a/basicsuite/ebike-ui/images/map_btn_shadow.png b/basicsuite/ebike-ui/images/map_btn_shadow.png new file mode 100644 index 0000000..c40b9b1 Binary files /dev/null and b/basicsuite/ebike-ui/images/map_btn_shadow.png differ diff --git a/basicsuite/ebike-ui/images/map_destination.png b/basicsuite/ebike-ui/images/map_destination.png new file mode 100644 index 0000000..a41b134 Binary files /dev/null and b/basicsuite/ebike-ui/images/map_destination.png differ diff --git a/basicsuite/ebike-ui/images/map_locate.png b/basicsuite/ebike-ui/images/map_locate.png new file mode 100644 index 0000000..2579c94 Binary files /dev/null and b/basicsuite/ebike-ui/images/map_locate.png differ diff --git a/basicsuite/ebike-ui/images/map_location_arrow.png b/basicsuite/ebike-ui/images/map_location_arrow.png new file mode 100644 index 0000000..9ec4d44 Binary files /dev/null and b/basicsuite/ebike-ui/images/map_location_arrow.png differ diff --git a/basicsuite/ebike-ui/images/map_zoomin.png b/basicsuite/ebike-ui/images/map_zoomin.png new file mode 100644 index 0000000..aea24fe Binary files /dev/null and b/basicsuite/ebike-ui/images/map_zoomin.png differ diff --git a/basicsuite/ebike-ui/images/map_zoomout.png b/basicsuite/ebike-ui/images/map_zoomout.png new file mode 100644 index 0000000..e3f90da Binary files /dev/null and b/basicsuite/ebike-ui/images/map_zoomout.png differ diff --git a/basicsuite/ebike-ui/images/nav_bear_l.png b/basicsuite/ebike-ui/images/nav_bear_l.png new file mode 100644 index 0000000..b078fbf Binary files /dev/null and b/basicsuite/ebike-ui/images/nav_bear_l.png differ diff --git a/basicsuite/ebike-ui/images/nav_bear_r.png b/basicsuite/ebike-ui/images/nav_bear_r.png new file mode 100644 index 0000000..84b48c1 Binary files /dev/null and b/basicsuite/ebike-ui/images/nav_bear_r.png differ diff --git a/basicsuite/ebike-ui/images/nav_hard_l.png b/basicsuite/ebike-ui/images/nav_hard_l.png new file mode 100644 index 0000000..7235cc3 Binary files /dev/null and b/basicsuite/ebike-ui/images/nav_hard_l.png differ diff --git a/basicsuite/ebike-ui/images/nav_hard_r.png b/basicsuite/ebike-ui/images/nav_hard_r.png new file mode 100644 index 0000000..4a19b65 Binary files /dev/null and b/basicsuite/ebike-ui/images/nav_hard_r.png differ diff --git a/basicsuite/ebike-ui/images/nav_left.png b/basicsuite/ebike-ui/images/nav_left.png new file mode 100644 index 0000000..5a5aa26 Binary files /dev/null and b/basicsuite/ebike-ui/images/nav_left.png differ diff --git a/basicsuite/ebike-ui/images/nav_light_left.png b/basicsuite/ebike-ui/images/nav_light_left.png new file mode 100644 index 0000000..7c88914 Binary files /dev/null and b/basicsuite/ebike-ui/images/nav_light_left.png differ diff --git a/basicsuite/ebike-ui/images/nav_light_right.png b/basicsuite/ebike-ui/images/nav_light_right.png new file mode 100644 index 0000000..3bb07ff Binary files /dev/null and b/basicsuite/ebike-ui/images/nav_light_right.png differ diff --git a/basicsuite/ebike-ui/images/nav_nodir.png b/basicsuite/ebike-ui/images/nav_nodir.png new file mode 100644 index 0000000..7fc92a7 Binary files /dev/null and b/basicsuite/ebike-ui/images/nav_nodir.png differ diff --git a/basicsuite/ebike-ui/images/nav_right.png b/basicsuite/ebike-ui/images/nav_right.png new file mode 100644 index 0000000..8eecf13 Binary files /dev/null and b/basicsuite/ebike-ui/images/nav_right.png differ diff --git a/basicsuite/ebike-ui/images/nav_straight.png b/basicsuite/ebike-ui/images/nav_straight.png new file mode 100644 index 0000000..44a58c8 Binary files /dev/null and b/basicsuite/ebike-ui/images/nav_straight.png differ diff --git a/basicsuite/ebike-ui/images/nav_uturn_l.png b/basicsuite/ebike-ui/images/nav_uturn_l.png new file mode 100644 index 0000000..c9714d3 Binary files /dev/null and b/basicsuite/ebike-ui/images/nav_uturn_l.png differ diff --git a/basicsuite/ebike-ui/images/nav_uturn_r.png b/basicsuite/ebike-ui/images/nav_uturn_r.png new file mode 100644 index 0000000..a4aee58 Binary files /dev/null and b/basicsuite/ebike-ui/images/nav_uturn_r.png differ diff --git a/basicsuite/ebike-ui/images/navigation_widget_shadow.png b/basicsuite/ebike-ui/images/navigation_widget_shadow.png new file mode 100644 index 0000000..4de81eb Binary files /dev/null and b/basicsuite/ebike-ui/images/navigation_widget_shadow.png differ diff --git a/basicsuite/ebike-ui/images/nextsong.png b/basicsuite/ebike-ui/images/nextsong.png new file mode 100644 index 0000000..90d6520 Binary files /dev/null and b/basicsuite/ebike-ui/images/nextsong.png differ diff --git a/basicsuite/ebike-ui/images/nextsong_pressed.png b/basicsuite/ebike-ui/images/nextsong_pressed.png new file mode 100644 index 0000000..b764100 Binary files /dev/null and b/basicsuite/ebike-ui/images/nextsong_pressed.png differ diff --git a/basicsuite/ebike-ui/images/ok.png b/basicsuite/ebike-ui/images/ok.png new file mode 100644 index 0000000..6d862a4 Binary files /dev/null and b/basicsuite/ebike-ui/images/ok.png differ diff --git a/basicsuite/ebike-ui/images/pause.png b/basicsuite/ebike-ui/images/pause.png new file mode 100644 index 0000000..9425527 Binary files /dev/null and b/basicsuite/ebike-ui/images/pause.png differ diff --git a/basicsuite/ebike-ui/images/pause_pressed.png b/basicsuite/ebike-ui/images/pause_pressed.png new file mode 100644 index 0000000..b90e029 Binary files /dev/null and b/basicsuite/ebike-ui/images/pause_pressed.png differ diff --git a/basicsuite/ebike-ui/images/placeholder.png b/basicsuite/ebike-ui/images/placeholder.png new file mode 100644 index 0000000..a0e647e Binary files /dev/null and b/basicsuite/ebike-ui/images/placeholder.png differ diff --git a/basicsuite/ebike-ui/images/play.png b/basicsuite/ebike-ui/images/play.png new file mode 100644 index 0000000..d31ae43 Binary files /dev/null and b/basicsuite/ebike-ui/images/play.png differ diff --git a/basicsuite/ebike-ui/images/play_pressed.png b/basicsuite/ebike-ui/images/play_pressed.png new file mode 100644 index 0000000..3cd498b Binary files /dev/null and b/basicsuite/ebike-ui/images/play_pressed.png differ diff --git a/basicsuite/ebike-ui/images/prevsong.png b/basicsuite/ebike-ui/images/prevsong.png new file mode 100644 index 0000000..63d2619 Binary files /dev/null and b/basicsuite/ebike-ui/images/prevsong.png differ diff --git a/basicsuite/ebike-ui/images/prevsong_pressed.png b/basicsuite/ebike-ui/images/prevsong_pressed.png new file mode 100644 index 0000000..dbe5690 Binary files /dev/null and b/basicsuite/ebike-ui/images/prevsong_pressed.png differ diff --git a/basicsuite/ebike-ui/images/search.png b/basicsuite/ebike-ui/images/search.png new file mode 100644 index 0000000..f840e72 Binary files /dev/null and b/basicsuite/ebike-ui/images/search.png differ diff --git a/basicsuite/ebike-ui/images/search_cancel.png b/basicsuite/ebike-ui/images/search_cancel.png new file mode 100644 index 0000000..679ce32 Binary files /dev/null and b/basicsuite/ebike-ui/images/search_cancel.png differ diff --git a/basicsuite/ebike-ui/images/settings.png b/basicsuite/ebike-ui/images/settings.png new file mode 100644 index 0000000..9651de6 Binary files /dev/null and b/basicsuite/ebike-ui/images/settings.png differ diff --git a/basicsuite/ebike-ui/images/settings_selected.png b/basicsuite/ebike-ui/images/settings_selected.png new file mode 100644 index 0000000..2e8cd7f Binary files /dev/null and b/basicsuite/ebike-ui/images/settings_selected.png differ diff --git a/basicsuite/ebike-ui/images/small_input_box_shadow.png b/basicsuite/ebike-ui/images/small_input_box_shadow.png new file mode 100644 index 0000000..401c0f2 Binary files /dev/null and b/basicsuite/ebike-ui/images/small_input_box_shadow.png differ diff --git a/basicsuite/ebike-ui/images/small_speedometer_arrow.png b/basicsuite/ebike-ui/images/small_speedometer_arrow.png new file mode 100644 index 0000000..4959e8d Binary files /dev/null and b/basicsuite/ebike-ui/images/small_speedometer_arrow.png differ diff --git a/basicsuite/ebike-ui/images/small_speedometer_shadow.png b/basicsuite/ebike-ui/images/small_speedometer_shadow.png new file mode 100644 index 0000000..5b37857 Binary files /dev/null and b/basicsuite/ebike-ui/images/small_speedometer_shadow.png differ diff --git a/basicsuite/ebike-ui/images/speed.png b/basicsuite/ebike-ui/images/speed.png new file mode 100644 index 0000000..17d2e6d Binary files /dev/null and b/basicsuite/ebike-ui/images/speed.png differ diff --git a/basicsuite/ebike-ui/images/spinner.png b/basicsuite/ebike-ui/images/spinner.png new file mode 100644 index 0000000..e59efb2 Binary files /dev/null and b/basicsuite/ebike-ui/images/spinner.png differ diff --git a/basicsuite/ebike-ui/images/top_curtain_drag.png b/basicsuite/ebike-ui/images/top_curtain_drag.png new file mode 100644 index 0000000..28388c6 Binary files /dev/null and b/basicsuite/ebike-ui/images/top_curtain_drag.png differ diff --git a/basicsuite/ebike-ui/images/trip.png b/basicsuite/ebike-ui/images/trip.png new file mode 100644 index 0000000..5a1761c Binary files /dev/null and b/basicsuite/ebike-ui/images/trip.png differ diff --git a/basicsuite/ebike-ui/images/warning.png b/basicsuite/ebike-ui/images/warning.png new file mode 100644 index 0000000..0c37552 Binary files /dev/null and b/basicsuite/ebike-ui/images/warning.png differ diff --git a/basicsuite/ebike-ui/main.qml b/basicsuite/ebike-ui/main.qml new file mode 100644 index 0000000..33fe5e8 --- /dev/null +++ b/basicsuite/ebike-ui/main.qml @@ -0,0 +1,350 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.7 +import QtQuick.Controls 2.2 +import QtQuick.Layouts 1.3 +import QtQuick.VirtualKeyboard 2.1 +import QtQml 2.2 +import DataStore 1.0 + +import "./BikeStyle" + +Rectangle { + visible: true + width: 640 + height: 480 + color: "#111520" + id: root + + // Permanent placeholder for time display + ClockView { + id: clockButton + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + + MouseArea { + anchors.rightMargin: -20 + anchors.leftMargin: -20 + anchors.bottomMargin: -20 + anchors.fill: parent + onClicked: drawer.open() + } + } + + FpsItem { + anchors.top: parent.top + anchors.left: parent.left + visible: fps.visible + } + + // The always-visible speed view + SpeedView { + id: speedView + onShowMain: swipeView.currentIndex = 1 + showZero: naviPage.targetEdit.activeFocus + + states: [ + State { + name: "" + when: swipeView.currentIndex == 1 && (!speedView.enlarged) + PropertyChanges { + target: speedView + width: UILayout.speedViewRadius * 2 + 2 + height: UILayout.speedViewRadius * 2 + 2 + anchors.topMargin: UILayout.speedViewTop + anchors.leftMargin: 0 + anchors.bottomMargin: 0 + color: "transparent" + dotcount: UILayout.speedViewDots + curvewidth: UILayout.speedViewInnerWidth + speedTextSize: UILayout.speedTextSize + speedBaselineOffset: UILayout.speedBaselineOffset + 1 + innerRadius: UILayout.speedViewInnerRadius + speedUnitsSize: UILayout.speedUnitsSize + speedUnitBaselineOffset: UILayout.speedTextUnitMargin + speedIconsOffset: UILayout.speedIconsCenterOffset + speedInfoTextsOffset: 0 + speedInfoTextsSize: UILayout.speedInfoTextsSize + speedInfoUnitsOffset: UILayout.speedInfoUnitsOffset + assistPowerIconOffset: UILayout.assistPowerIconOffset + } + AnchorChanges { + target: speedView + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + anchors.left: undefined + anchors.bottom: undefined + } + PropertyChanges { + target: speedView.cornerRectangle + color: "transparent" + } + AnchorChanges { + target: speedView.cornerRectangle + anchors.horizontalCenter: speedView.horizontalCenter + anchors.verticalCenter: speedView.verticalCenter + anchors.left: undefined + anchors.bottom: undefined + } + StateChangeScript { + script: { + if (musicPlayer.lastMusicPlayerState === "" && (!drawer.viewTab.musicPlayerSwitch.checked)) + musicPlayer.state = ""; + } + } + }, + State { + name: "CORNERED" + when: swipeView.currentIndex != 1 + PropertyChanges { + target: speedView + width: UILayout.speedViewRadiusMinified * 2 + height: UILayout.speedViewRadiusMinified * 2 + anchors.topMargin: 0 + anchors.leftMargin: UILayout.speedViewCornerLeftMargin + anchors.bottomMargin: UILayout.speedViewCornerBottomMargin + color: Colors.speedViewBackgroundCornered + dotcount: UILayout.speedViewDotsMinified + curvewidth: UILayout.speedViewInnerWidthMinified + speedTextSize: UILayout.speedTextSizeMinified + speedBaselineOffset: UILayout.speedBaselineOffsetMinified + innerRadius: UILayout.speedViewInnerRadiusMinified + speedUnitBaselineOffset: UILayout.speedTextUnitMarginMinified + } + AnchorChanges { + target: speedView + anchors.horizontalCenter: undefined + anchors.top: undefined + anchors.left: parent.left + anchors.bottom: parent.bottom + } + PropertyChanges { + target: speedView.cornerRectangle + color: Colors.speedViewBackgroundCornered + } + AnchorChanges { + target: speedView.cornerRectangle + anchors.horizontalCenter: undefined + anchors.verticalCenter: undefined + anchors.left: speedView.left + anchors.bottom: speedView.bottom + } + StateChangeScript { + script: { + musicPlayer.lastMusicPlayerState = musicPlayer.state; + musicPlayer.state = "hidden"; + } + } + }, + State { + name: "ENLARGED" + when: swipeView.currentIndex == 1 && speedView.enlarged + PropertyChanges { + target: speedView + width: UILayout.speedViewRadiusEnlarged * 2 + height: UILayout.speedViewRadiusEnlarged * 2 + anchors.topMargin: 35 + dotcount: UILayout.speedViewDotsEnlarged + speedTextSize: UILayout.speedTextSizeEnlarged + speedBaselineOffset: UILayout.speedBaselineOffsetEnlarged + innerRadius: UILayout.speedViewInnerRadiusEnlarged + speedUnitsSize: UILayout.speedUnitsSizeEnlarged + speedUnitBaselineOffset: UILayout.speedTextUnitMarginEnlarged + speedIconsOffset: UILayout.speedIconsCenterOffsetEnlarged + speedInfoTextsOffset: UILayout.speedInfoTextsOffsetEnlarged + speedInfoTextsSize: UILayout.speedInfoTextsSizeEnlarged + speedInfoUnitsOffset: UILayout.speedInfoUnitsOffsetEnlarged + assistPowerIconOffset: UILayout.assistPowerIconOffsetEnlarged + } + PropertyChanges { + target: mainPage.statsButton + anchors.leftMargin: -mainPage.statsButton.width + anchors.topMargin: -mainPage.statsButton.height + } + PropertyChanges { + target: mainPage.naviButton + anchors.rightMargin: -mainPage.naviButton.width + anchors.topMargin: -mainPage.naviButton.height + } + PropertyChanges { + target: mainPage.lightsButton + anchors.leftMargin: -mainPage.statsButton.width + anchors.bottomMargin: -mainPage.statsButton.height + } + PropertyChanges { + target: mainPage.modeButton + anchors.rightMargin: -mainPage.statsButton.width + anchors.bottomMargin: -mainPage.statsButton.height + } + PropertyChanges { + target: clockButton + anchors.topMargin: -clockButton.height + } + AnchorChanges { + target: speedView + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + anchors.left: undefined + anchors.bottom: undefined + } + StateChangeScript { + script: { + musicPlayer.lastMusicPlayerState = musicPlayer.state; + musicPlayer.state = "hidden"; + } + } + } + ] + + transitions: [ + Transition { + from: ""; to: "ENLARGED" + NumberAnimation { + properties: "anchors.leftMargin,anchors.rightMargin,anchors.topMargin,anchors.bottomMargin" + duration: 250 + } + NumberAnimation { + properties: "width,height,dotcount,speedTextSize,speedBaselineOffset,innerRadius,speedUnitsSize,speedUnitBaselineOffset,speedIconsOffset,speedInfoTextsOffset,speedInfoTextsSize,speedInfoUnitsOffset,assistPowerIconOffset" + duration: 250 + } + AnchorAnimation { + duration: 250 + } + }, + Transition { + from: "ENLARGED"; to: "" + NumberAnimation { + properties: "anchors.leftMargin,anchors.rightMargin,anchors.topMargin,anchors.bottomMargin" + easing.type: Easing.OutBack + duration: 250 + } + NumberAnimation { + properties: "width,height,dotcount,speedTextSize,speedBaselineOffset,innerRadius,speedUnitsSize,speedUnitBaselineOffset,speedIconsOffset,speedInfoTextsOffset,speedInfoTextsSize,speedInfoUnitsOffset,assistPowerIconOffset" + duration: 250 + } + AnchorAnimation { + duration: 250 + } + }, + Transition { + NumberAnimation { + properties: "width,height,curvewidth,speedTextSize,speedBaselineOffset,innerRadius,speedUnitMargin" + easing.type: Easing.OutBack + duration: 250 + } + ColorAnimation { + duration: 250 + } + AnchorAnimation { + easing.type: Easing.OutBack + duration: 250 + } + } + ] + } + + // Configuration and settings drawer + ConfigurationDrawer { + id: drawer + height: 350 + width: root.width + edge: Qt.TopEdge + dragMargin: 20 + } + + // Inactive swipe view, for animations + SwipeView { + id: swipeView + anchors.fill: parent + currentIndex: 1 + interactive: false + + // List of pages + StatsPage {} + MainPage { + id: mainPage + naviGuideArrowSource: naviPage.naviGuideArrowSource + naviGuideDistance: naviPage.naviGuideDistance + naviGuideAddress: naviPage.naviGuideAddress + } + NaviPage { + id: naviPage; + } + } + + // Music player + MusicPlayer { + id: musicPlayer + property string lastMusicPlayerState: "unknown" + z: 1 + } + + Connections { + target: datastore + onDemoReset: drawer.close() + } + + // Virtual keyboard + InputPanel { + id: inputPanel + z: 99 + x: 0 + y: root.height + width: root.width + + states: State { + name: "visible" + when: inputPanel.active + PropertyChanges { + target: inputPanel + y: root.height - inputPanel.height + } + } + transitions: Transition { + from: "" + to: "visible" + reversible: true + ParallelAnimation { + NumberAnimation { + properties: "y" + duration: 250 + easing.type: Easing.InOutQuad + } + } + } + } +} diff --git a/basicsuite/ebike-ui/mapbox.cpp b/basicsuite/ebike-ui/mapbox.cpp new file mode 100644 index 0000000..9d2303d --- /dev/null +++ b/basicsuite/ebike-ui/mapbox.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include + +#include "mapbox.h" + +#define MAPBOX_URL "https://api.mapbox.com/" +#define MAPBOX_TOKEN "pk.eyJ1IjoibWFwYm94NHF0IiwiYSI6ImNpd3J3eDE0eDEzdm8ydHM3YzhzajlrN2oifQ.keEkjqm79SiFDFjnesTcgQ" + +MapBox::MapBox(QObject *parent) + : QObject(parent) + , m_nam(new QNetworkAccessManager(this)) +{ +} + +const QUrl MapBox::createUrl(const QString &path, QUrlQuery params) const +{ + // Create URL and set path + QUrl url(MAPBOX_URL); + url.setPath(path, QUrl::TolerantMode); + + // Add access token to query params + params.addQueryItem("access_token", MAPBOX_TOKEN); + url.setQuery(params); + + return url; +} + +QNetworkReply *MapBox::get(const QUrl &url) const +{ + return m_nam->get(QNetworkRequest(url)); +} + +QNetworkReply *MapBox::getGeocoding(const QString &query, const QGeoCoordinate &proximity) +{ + QUrlQuery params; + params.addQueryItem("autocomplete", "true"); + params.addQueryItem("limit", "3"); + if (proximity.isValid()) + params.addQueryItem("proximity", QString("%1,%2").arg(proximity.longitude()).arg(proximity.latitude())); + QUrl url = createUrl(QString("/geocoding/v5/mapbox.places/%1.json").arg(QString(QUrl::toPercentEncoding(query))), params); + + return get(url); +} + +QNetworkReply *MapBox::getDirections(const QGeoCoordinate &source, const QGeoCoordinate &destination, const QString &type) +{ + QString where = QString("%1,%2;%3,%4").arg(source.longitude()).arg(source.latitude()).arg(destination.longitude()).arg(destination.latitude()); + QUrlQuery params; + params.addQueryItem("steps", "true"); + params.addQueryItem("geometries", "geojson"); + QUrl url = createUrl(QString("/directions/v5/mapbox/%1/%2.json").arg(type).arg(QString(QUrl::toPercentEncoding(where))), params); + + return get(url); +} diff --git a/basicsuite/ebike-ui/mapbox.h b/basicsuite/ebike-ui/mapbox.h new file mode 100644 index 0000000..5bd295f --- /dev/null +++ b/basicsuite/ebike-ui/mapbox.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MAPBOX_H +#define MAPBOX_H + +#include +#include +#include + +class QNetworkAccessManager; +class QNetworkReply; + +class MapBox : public QObject +{ + Q_OBJECT + +public: + explicit MapBox(QObject *parent = nullptr); + +public: + const QUrl createUrl(const QString &path, QUrlQuery params) const; + QNetworkReply *get(const QUrl &url) const; + QNetworkReply *getGeocoding(const QString &query, const QGeoCoordinate &proximity=QGeoCoordinate()); + QNetworkReply *getDirections(const QGeoCoordinate &source, const QGeoCoordinate &destination, const QString &type=QString("cycling")); + +signals: + +public slots: + +private: + QNetworkAccessManager *m_nam; +}; + +#endif // MAPBOX_H diff --git a/basicsuite/ebike-ui/mapboxsuggestions.cpp b/basicsuite/ebike-ui/mapboxsuggestions.cpp new file mode 100644 index 0000000..3f66766 --- /dev/null +++ b/basicsuite/ebike-ui/mapboxsuggestions.cpp @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mapboxsuggestions.h" +#include "mapbox.h" +#include "suggestionsmodel.h" + +MapBoxSuggestions::MapBoxSuggestions(MapBox *mapbox, QObject *parent) + : QObject(parent) + , m_mapbox(mapbox) + , m_timer(new QTimer(this)) + , m_suggestions(new SuggestionsModel(this)) +{ + // Setup timer to request 500ms after user stops typing + m_timer->setSingleShot(true); + m_timer->setInterval(500); + + // Connect timer signal + connect(m_timer, &QTimer::timeout, this, &MapBoxSuggestions::loadSuggestions); +} + +void MapBoxSuggestions::stopSuggest() +{ + m_timer->stop(); +} + +void MapBoxSuggestions::setSearch(const QString &search) +{ + if (m_search == search) + return; + + m_search = search; + m_timer->start(); + emit searchChanged(m_search); +} + +void MapBoxSuggestions::loadSuggestions() +{ + QNetworkReply *reply = m_mapbox->getGeocoding(m_search, m_center); + connect(reply, &QNetworkReply::finished, this, &MapBoxSuggestions::handleReply); + m_requests.append(reply); + emit loadingChanged(); +} + +void MapBoxSuggestions::handleReply() +{ + QNetworkReply *reply = qobject_cast(sender()); + QJsonParseError error; + QJsonDocument doc = QJsonDocument::fromJson(reply->readAll(), &error); + if (error.error == QJsonParseError::NoError) { + QJsonObject obj = doc.object(); + m_suggestions->setSuggestions(obj.value("features").toArray()); + emit suggestionsChanged(); + } + + m_requests.removeOne(reply); + emit loadingChanged(); + reply->deleteLater(); +} + +void MapBoxSuggestions::setCenter(const QGeoCoordinate ¢er) +{ + if (m_center != center) { + m_center = center; + emit centerChanged(); + } +} diff --git a/basicsuite/ebike-ui/mapboxsuggestions.h b/basicsuite/ebike-ui/mapboxsuggestions.h new file mode 100644 index 0000000..8dc1506 --- /dev/null +++ b/basicsuite/ebike-ui/mapboxsuggestions.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MAPBOXSUGGESTIONS_H +#define MAPBOXSUGGESTIONS_H + +#include +#include + +class MapBox; +class QNetworkReply; +class QTimer; +class SuggestionsModel; + +class MapBoxSuggestions : public QObject +{ + Q_OBJECT + Q_PROPERTY(SuggestionsModel suggestions READ suggestions NOTIFY suggestionsChanged) + Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged) + Q_PROPERTY(QGeoCoordinate center READ center WRITE setCenter NOTIFY centerChanged) + Q_PROPERTY(QString search READ search WRITE setSearch NOTIFY searchChanged) + +public: + explicit MapBoxSuggestions(MapBox *mapbox, QObject *parent = nullptr); + +public: + SuggestionsModel *suggestions() const { return m_suggestions; } + bool loading() const { return m_requests.size() > 0; } + const QGeoCoordinate center() { return m_center; } + void setCenter(const QGeoCoordinate ¢er); + const QString search() const { return m_search; } + void setSearch(const QString &search); + +signals: + void suggestionsChanged(); + void loadingChanged(); + void centerChanged(); + void searchChanged(QString search); + +public slots: + void stopSuggest(); + +private slots: + void loadSuggestions(); + void handleReply(); + +private: + MapBox *m_mapbox; + QTimer *m_timer; + QList m_requests; + SuggestionsModel *m_suggestions; + QGeoCoordinate m_center; + QString m_search; +}; + +#endif // MAPBOXSUGGESTIONS_H diff --git a/basicsuite/ebike-ui/moment.js b/basicsuite/ebike-ui/moment.js new file mode 100644 index 0000000..eaf827d --- /dev/null +++ b/basicsuite/ebike-ui/moment.js @@ -0,0 +1,4551 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! moment.js +//! version : 2.19.2 +//! authors : Tim Wood, Iskren Chernev, Moment.js contributors +//! license : MIT +//! momentjs.com + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + global.moment = factory() +}(this, (function () { 'use strict'; + +var hookCallback; + +function hooks () { + return hookCallback.apply(null, arguments); +} + +// This is done to register the method called with moment() +// without creating circular dependencies. +function setHookCallback (callback) { + hookCallback = callback; +} + +function isArray(input) { + return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]'; +} + +function isObject(input) { + // IE8 will treat undefined and null as object if it wasn't for + // input != null + return input != null && Object.prototype.toString.call(input) === '[object Object]'; +} + +function isObjectEmpty(obj) { + if (Object.getOwnPropertyNames) { + return (Object.getOwnPropertyNames(obj).length === 0); + } else { + var k; + for (k in obj) { + if (obj.hasOwnProperty(k)) { + return false; + } + } + return true; + } +} + +function isUndefined(input) { + return input === void 0; +} + +function isNumber(input) { + return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]'; +} + +function isDate(input) { + return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]'; +} + +function map(arr, fn) { + var res = [], i; + for (i = 0; i < arr.length; ++i) { + res.push(fn(arr[i], i)); + } + return res; +} + +function hasOwnProp(a, b) { + return Object.prototype.hasOwnProperty.call(a, b); +} + +function extend(a, b) { + for (var i in b) { + if (hasOwnProp(b, i)) { + a[i] = b[i]; + } + } + + if (hasOwnProp(b, 'toString')) { + a.toString = b.toString; + } + + if (hasOwnProp(b, 'valueOf')) { + a.valueOf = b.valueOf; + } + + return a; +} + +function createUTC (input, format, locale, strict) { + return createLocalOrUTC(input, format, locale, strict, true).utc(); +} + +function defaultParsingFlags() { + // We need to deep clone this object. + return { + empty : false, + unusedTokens : [], + unusedInput : [], + overflow : -2, + charsLeftOver : 0, + nullInput : false, + invalidMonth : null, + invalidFormat : false, + userInvalidated : false, + iso : false, + parsedDateParts : [], + meridiem : null, + rfc2822 : false, + weekdayMismatch : false + }; +} + +function getParsingFlags(m) { + if (m._pf == null) { + m._pf = defaultParsingFlags(); + } + return m._pf; +} + +var some; +if (Array.prototype.some) { + some = Array.prototype.some; +} else { + some = function (fun) { + var t = Object(this); + var len = t.length >>> 0; + + for (var i = 0; i < len; i++) { + if (i in t && fun.call(this, t[i], i, t)) { + return true; + } + } + + return false; + }; +} + +function isValid(m) { + if (m._isValid == null) { + var flags = getParsingFlags(m); + var parsedParts = some.call(flags.parsedDateParts, function (i) { + return i != null; + }); + var isNowValid = !isNaN(m._d.getTime()) && + flags.overflow < 0 && + !flags.empty && + !flags.invalidMonth && + !flags.invalidWeekday && + !flags.weekdayMismatch && + !flags.nullInput && + !flags.invalidFormat && + !flags.userInvalidated && + (!flags.meridiem || (flags.meridiem && parsedParts)); + + if (m._strict) { + isNowValid = isNowValid && + flags.charsLeftOver === 0 && + flags.unusedTokens.length === 0 && + flags.bigHour === undefined; + } + + if (Object.isFrozen == null || !Object.isFrozen(m)) { + m._isValid = isNowValid; + } + else { + return isNowValid; + } + } + return m._isValid; +} + +function createInvalid (flags) { + var m = createUTC(NaN); + if (flags != null) { + extend(getParsingFlags(m), flags); + } + else { + getParsingFlags(m).userInvalidated = true; + } + + return m; +} + +// Plugins that add properties should also add the key here (null value), +// so we can properly clone ourselves. +var momentProperties = hooks.momentProperties = []; + +function copyConfig(to, from) { + var i, prop, val; + + if (!isUndefined(from._isAMomentObject)) { + to._isAMomentObject = from._isAMomentObject; + } + if (!isUndefined(from._i)) { + to._i = from._i; + } + if (!isUndefined(from._f)) { + to._f = from._f; + } + if (!isUndefined(from._l)) { + to._l = from._l; + } + if (!isUndefined(from._strict)) { + to._strict = from._strict; + } + if (!isUndefined(from._tzm)) { + to._tzm = from._tzm; + } + if (!isUndefined(from._isUTC)) { + to._isUTC = from._isUTC; + } + if (!isUndefined(from._offset)) { + to._offset = from._offset; + } + if (!isUndefined(from._pf)) { + to._pf = getParsingFlags(from); + } + if (!isUndefined(from._locale)) { + to._locale = from._locale; + } + + if (momentProperties.length > 0) { + for (i = 0; i < momentProperties.length; i++) { + prop = momentProperties[i]; + val = from[prop]; + if (!isUndefined(val)) { + to[prop] = val; + } + } + } + + return to; +} + +var updateInProgress = false; + +// Moment prototype object +function Moment(config) { + copyConfig(this, config); + this._d = new Date(config._d != null ? config._d.getTime() : NaN); + if (!this.isValid()) { + this._d = new Date(NaN); + } + // Prevent infinite loop in case updateOffset creates new moment + // objects. + if (updateInProgress === false) { + updateInProgress = true; + hooks.updateOffset(this); + updateInProgress = false; + } +} + +function isMoment (obj) { + return obj instanceof Moment || (obj != null && obj._isAMomentObject != null); +} + +function absFloor (number) { + if (number < 0) { + // -0 -> 0 + return Math.ceil(number) || 0; + } else { + return Math.floor(number); + } +} + +function toInt(argumentForCoercion) { + var coercedNumber = +argumentForCoercion, + value = 0; + + if (coercedNumber !== 0 && isFinite(coercedNumber)) { + value = absFloor(coercedNumber); + } + + return value; +} + +// compare two arrays, return the number of differences +function compareArrays(array1, array2, dontConvert) { + var len = Math.min(array1.length, array2.length), + lengthDiff = Math.abs(array1.length - array2.length), + diffs = 0, + i; + for (i = 0; i < len; i++) { + if ((dontConvert && array1[i] !== array2[i]) || + (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) { + diffs++; + } + } + return diffs + lengthDiff; +} + +function warn(msg) { + if (hooks.suppressDeprecationWarnings === false && + (typeof console !== 'undefined') && console.warn) { + console.warn('Deprecation warning: ' + msg); + } +} + +function deprecate(msg, fn) { + var firstTime = true; + + return extend(function () { + if (hooks.deprecationHandler != null) { + hooks.deprecationHandler(null, msg); + } + if (firstTime) { + var args = []; + var arg; + for (var i = 0; i < arguments.length; i++) { + arg = ''; + if (typeof arguments[i] === 'object') { + arg += '\n[' + i + '] '; + for (var key in arguments[0]) { + arg += key + ': ' + arguments[0][key] + ', '; + } + arg = arg.slice(0, -2); // Remove trailing comma and space + } else { + arg = arguments[i]; + } + args.push(arg); + } + warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack); + firstTime = false; + } + return fn.apply(this, arguments); + }, fn); +} + +var deprecations = {}; + +function deprecateSimple(name, msg) { + if (hooks.deprecationHandler != null) { + hooks.deprecationHandler(name, msg); + } + if (!deprecations[name]) { + warn(msg); + deprecations[name] = true; + } +} + +hooks.suppressDeprecationWarnings = false; +hooks.deprecationHandler = null; + +function isFunction(input) { + return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]'; +} + +function set (config) { + var prop, i; + for (i in config) { + prop = config[i]; + if (isFunction(prop)) { + this[i] = prop; + } else { + this['_' + i] = prop; + } + } + this._config = config; + // Lenient ordinal parsing accepts just a number in addition to + // number + (possibly) stuff coming from _dayOfMonthOrdinalParse. + // TODO: Remove "ordinalParse" fallback in next major release. + this._dayOfMonthOrdinalParseLenient = new RegExp( + (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + + '|' + (/\d{1,2}/).source); +} + +function mergeConfigs(parentConfig, childConfig) { + var res = extend({}, parentConfig), prop; + for (prop in childConfig) { + if (hasOwnProp(childConfig, prop)) { + if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) { + res[prop] = {}; + extend(res[prop], parentConfig[prop]); + extend(res[prop], childConfig[prop]); + } else if (childConfig[prop] != null) { + res[prop] = childConfig[prop]; + } else { + delete res[prop]; + } + } + } + for (prop in parentConfig) { + if (hasOwnProp(parentConfig, prop) && + !hasOwnProp(childConfig, prop) && + isObject(parentConfig[prop])) { + // make sure changes to properties don't modify parent config + res[prop] = extend({}, res[prop]); + } + } + return res; +} + +function Locale(config) { + if (config != null) { + this.set(config); + } +} + +var keys; + +if (Object.keys) { + keys = Object.keys; +} else { + keys = function (obj) { + var i, res = []; + for (i in obj) { + if (hasOwnProp(obj, i)) { + res.push(i); + } + } + return res; + }; +} + +var defaultCalendar = { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' +}; + +function calendar (key, mom, now) { + var output = this._calendar[key] || this._calendar['sameElse']; + return isFunction(output) ? output.call(mom, now) : output; +} + +var defaultLongDateFormat = { + LTS : 'h:mm:ss A', + LT : 'h:mm A', + L : 'MM/DD/YYYY', + LL : 'MMMM D, YYYY', + LLL : 'MMMM D, YYYY h:mm A', + LLLL : 'dddd, MMMM D, YYYY h:mm A' +}; + +function longDateFormat (key) { + var format = this._longDateFormat[key], + formatUpper = this._longDateFormat[key.toUpperCase()]; + + if (format || !formatUpper) { + return format; + } + + this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) { + return val.slice(1); + }); + + return this._longDateFormat[key]; +} + +var defaultInvalidDate = 'Invalid date'; + +function invalidDate () { + return this._invalidDate; +} + +var defaultOrdinal = '%d'; +var defaultDayOfMonthOrdinalParse = /\d{1,2}/; + +function ordinal (number) { + return this._ordinal.replace('%d', number); +} + +var defaultRelativeTime = { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + ss : '%d seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' +}; + +function relativeTime (number, withoutSuffix, string, isFuture) { + var output = this._relativeTime[string]; + return (isFunction(output)) ? + output(number, withoutSuffix, string, isFuture) : + output.replace(/%d/i, number); +} + +function pastFuture (diff, output) { + var format = this._relativeTime[diff > 0 ? 'future' : 'past']; + return isFunction(format) ? format(output) : format.replace(/%s/i, output); +} + +var aliases = {}; + +function addUnitAlias (unit, shorthand) { + var lowerCase = unit.toLowerCase(); + aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit; +} + +function normalizeUnits(units) { + return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined; +} + +function normalizeObjectUnits(inputObject) { + var normalizedInput = {}, + normalizedProp, + prop; + + for (prop in inputObject) { + if (hasOwnProp(inputObject, prop)) { + normalizedProp = normalizeUnits(prop); + if (normalizedProp) { + normalizedInput[normalizedProp] = inputObject[prop]; + } + } + } + + return normalizedInput; +} + +var priorities = {}; + +function addUnitPriority(unit, priority) { + priorities[unit] = priority; +} + +function getPrioritizedUnits(unitsObj) { + var units = []; + for (var u in unitsObj) { + units.push({unit: u, priority: priorities[u]}); + } + units.sort(function (a, b) { + return a.priority - b.priority; + }); + return units; +} + +function zeroFill(number, targetLength, forceSign) { + var absNumber = '' + Math.abs(number), + zerosToFill = targetLength - absNumber.length, + sign = number >= 0; + return (sign ? (forceSign ? '+' : '') : '-') + + Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber; +} + +var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g; + +var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g; + +var formatFunctions = {}; + +var formatTokenFunctions = {}; + +// token: 'M' +// padded: ['MM', 2] +// ordinal: 'Mo' +// callback: function () { this.month() + 1 } +function addFormatToken (token, padded, ordinal, callback) { + var func = callback; + if (typeof callback === 'string') { + func = function () { + return this[callback](); + }; + } + if (token) { + formatTokenFunctions[token] = func; + } + if (padded) { + formatTokenFunctions[padded[0]] = function () { + return zeroFill(func.apply(this, arguments), padded[1], padded[2]); + }; + } + if (ordinal) { + formatTokenFunctions[ordinal] = function () { + return this.localeData().ordinal(func.apply(this, arguments), token); + }; + } +} + +function removeFormattingTokens(input) { + if (input.match(/\[[\s\S]/)) { + return input.replace(/^\[|\]$/g, ''); + } + return input.replace(/\\/g, ''); +} + +function makeFormatFunction(format) { + var array = format.match(formattingTokens), i, length; + + for (i = 0, length = array.length; i < length; i++) { + if (formatTokenFunctions[array[i]]) { + array[i] = formatTokenFunctions[array[i]]; + } else { + array[i] = removeFormattingTokens(array[i]); + } + } + + return function (mom) { + var output = '', i; + for (i = 0; i < length; i++) { + output += isFunction(array[i]) ? array[i].call(mom, format) : array[i]; + } + return output; + }; +} + +// format date using native date object +function formatMoment(m, format) { + if (!m.isValid()) { + return m.localeData().invalidDate(); + } + + format = expandFormat(format, m.localeData()); + formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format); + + return formatFunctions[format](m); +} + +function expandFormat(format, locale) { + var i = 5; + + function replaceLongDateFormatTokens(input) { + return locale.longDateFormat(input) || input; + } + + localFormattingTokens.lastIndex = 0; + while (i >= 0 && localFormattingTokens.test(format)) { + format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); + localFormattingTokens.lastIndex = 0; + i -= 1; + } + + return format; +} + +var match1 = /\d/; // 0 - 9 +var match2 = /\d\d/; // 00 - 99 +var match3 = /\d{3}/; // 000 - 999 +var match4 = /\d{4}/; // 0000 - 9999 +var match6 = /[+-]?\d{6}/; // -999999 - 999999 +var match1to2 = /\d\d?/; // 0 - 99 +var match3to4 = /\d\d\d\d?/; // 999 - 9999 +var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999 +var match1to3 = /\d{1,3}/; // 0 - 999 +var match1to4 = /\d{1,4}/; // 0 - 9999 +var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999 + +var matchUnsigned = /\d+/; // 0 - inf +var matchSigned = /[+-]?\d+/; // -inf - inf + +var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z +var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z + +var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123 + +// any word (or two) characters or numbers including two/three word month in arabic. +// includes scottish gaelic two word and hyphenated months +var matchWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i; + + +var regexes = {}; + +function addRegexToken (token, regex, strictRegex) { + regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) { + return (isStrict && strictRegex) ? strictRegex : regex; + }; +} + +function getParseRegexForToken (token, config) { + if (!hasOwnProp(regexes, token)) { + return new RegExp(unescapeFormat(token)); + } + + return regexes[token](config._strict, config._locale); +} + +// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript +function unescapeFormat(s) { + return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { + return p1 || p2 || p3 || p4; + })); +} + +function regexEscape(s) { + return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); +} + +var tokens = {}; + +function addParseToken (token, callback) { + var i, func = callback; + if (typeof token === 'string') { + token = [token]; + } + if (isNumber(callback)) { + func = function (input, array) { + array[callback] = toInt(input); + }; + } + for (i = 0; i < token.length; i++) { + tokens[token[i]] = func; + } +} + +function addWeekParseToken (token, callback) { + addParseToken(token, function (input, array, config, token) { + config._w = config._w || {}; + callback(input, config._w, config, token); + }); +} + +function addTimeToArrayFromToken(token, input, config) { + if (input != null && hasOwnProp(tokens, token)) { + tokens[token](input, config._a, config, token); + } +} + +var YEAR = 0; +var MONTH = 1; +var DATE = 2; +var HOUR = 3; +var MINUTE = 4; +var SECOND = 5; +var MILLISECOND = 6; +var WEEK = 7; +var WEEKDAY = 8; + +// FORMATTING + +addFormatToken('Y', 0, 0, function () { + var y = this.year(); + return y <= 9999 ? '' + y : '+' + y; +}); + +addFormatToken(0, ['YY', 2], 0, function () { + return this.year() % 100; +}); + +addFormatToken(0, ['YYYY', 4], 0, 'year'); +addFormatToken(0, ['YYYYY', 5], 0, 'year'); +addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); + +// ALIASES + +addUnitAlias('year', 'y'); + +// PRIORITIES + +addUnitPriority('year', 1); + +// PARSING + +addRegexToken('Y', matchSigned); +addRegexToken('YY', match1to2, match2); +addRegexToken('YYYY', match1to4, match4); +addRegexToken('YYYYY', match1to6, match6); +addRegexToken('YYYYYY', match1to6, match6); + +addParseToken(['YYYYY', 'YYYYYY'], YEAR); +addParseToken('YYYY', function (input, array) { + array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input); +}); +addParseToken('YY', function (input, array) { + array[YEAR] = hooks.parseTwoDigitYear(input); +}); +addParseToken('Y', function (input, array) { + array[YEAR] = parseInt(input, 10); +}); + +// HELPERS + +function daysInYear(year) { + return isLeapYear(year) ? 366 : 365; +} + +function isLeapYear(year) { + return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; +} + +// HOOKS + +hooks.parseTwoDigitYear = function (input) { + return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); +}; + +// MOMENTS + +var getSetYear = makeGetSet('FullYear', true); + +function getIsLeapYear () { + return isLeapYear(this.year()); +} + +function makeGetSet (unit, keepTime) { + return function (value) { + if (value != null) { + set$1(this, unit, value); + hooks.updateOffset(this, keepTime); + return this; + } else { + return get(this, unit); + } + }; +} + +function get (mom, unit) { + return mom.isValid() ? + mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN; +} + +function set$1 (mom, unit, value) { + if (mom.isValid() && !isNaN(value)) { + if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) { + mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month())); + } + else { + mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); + } + } +} + +// MOMENTS + +function stringGet (units) { + units = normalizeUnits(units); + if (isFunction(this[units])) { + return this[units](); + } + return this; +} + + +function stringSet (units, value) { + if (typeof units === 'object') { + units = normalizeObjectUnits(units); + var prioritized = getPrioritizedUnits(units); + for (var i = 0; i < prioritized.length; i++) { + this[prioritized[i].unit](units[prioritized[i].unit]); + } + } else { + units = normalizeUnits(units); + if (isFunction(this[units])) { + return this[units](value); + } + } + return this; +} + +function mod(n, x) { + return ((n % x) + x) % x; +} + +var indexOf; + +if (Array.prototype.indexOf) { + indexOf = Array.prototype.indexOf; +} else { + indexOf = function (o) { + // I know + var i; + for (i = 0; i < this.length; ++i) { + if (this[i] === o) { + return i; + } + } + return -1; + }; +} + +function daysInMonth(year, month) { + if (isNaN(year) || isNaN(month)) { + return NaN; + } + var modMonth = mod(month, 12); + year += (month - modMonth) / 12; + return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2); +} + +// FORMATTING + +addFormatToken('M', ['MM', 2], 'Mo', function () { + return this.month() + 1; +}); + +addFormatToken('MMM', 0, 0, function (format) { + return this.localeData().monthsShort(this, format); +}); + +addFormatToken('MMMM', 0, 0, function (format) { + return this.localeData().months(this, format); +}); + +// ALIASES + +addUnitAlias('month', 'M'); + +// PRIORITY + +addUnitPriority('month', 8); + +// PARSING + +addRegexToken('M', match1to2); +addRegexToken('MM', match1to2, match2); +addRegexToken('MMM', function (isStrict, locale) { + return locale.monthsShortRegex(isStrict); +}); +addRegexToken('MMMM', function (isStrict, locale) { + return locale.monthsRegex(isStrict); +}); + +addParseToken(['M', 'MM'], function (input, array) { + array[MONTH] = toInt(input) - 1; +}); + +addParseToken(['MMM', 'MMMM'], function (input, array, config, token) { + var month = config._locale.monthsParse(input, token, config._strict); + // if we didn't find a month name, mark the date as invalid. + if (month != null) { + array[MONTH] = month; + } else { + getParsingFlags(config).invalidMonth = input; + } +}); + +// LOCALES + +var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/; +var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'); +function localeMonths (m, format) { + if (!m) { + return isArray(this._months) ? this._months : + this._months['standalone']; + } + return isArray(this._months) ? this._months[m.month()] : + this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()]; +} + +var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'); +function localeMonthsShort (m, format) { + if (!m) { + return isArray(this._monthsShort) ? this._monthsShort : + this._monthsShort['standalone']; + } + return isArray(this._monthsShort) ? this._monthsShort[m.month()] : + this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()]; +} + +function handleStrictParse(monthName, format, strict) { + var i, ii, mom, llc = monthName.toLocaleLowerCase(); + if (!this._monthsParse) { + // this is not used + this._monthsParse = []; + this._longMonthsParse = []; + this._shortMonthsParse = []; + for (i = 0; i < 12; ++i) { + mom = createUTC([2000, i]); + this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase(); + this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase(); + } + } + + if (strict) { + if (format === 'MMM') { + ii = indexOf.call(this._shortMonthsParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._longMonthsParse, llc); + return ii !== -1 ? ii : null; + } + } else { + if (format === 'MMM') { + ii = indexOf.call(this._shortMonthsParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._longMonthsParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._longMonthsParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._shortMonthsParse, llc); + return ii !== -1 ? ii : null; + } + } +} + +function localeMonthsParse (monthName, format, strict) { + var i, mom, regex; + + if (this._monthsParseExact) { + return handleStrictParse.call(this, monthName, format, strict); + } + + if (!this._monthsParse) { + this._monthsParse = []; + this._longMonthsParse = []; + this._shortMonthsParse = []; + } + + // TODO: add sorting + // Sorting makes sure if one month (or abbr) is a prefix of another + // see sorting in computeMonthsParse + for (i = 0; i < 12; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, i]); + if (strict && !this._longMonthsParse[i]) { + this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i'); + this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i'); + } + if (!strict && !this._monthsParse[i]) { + regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); + this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); + } + // test the regex + if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) { + return i; + } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) { + return i; + } else if (!strict && this._monthsParse[i].test(monthName)) { + return i; + } + } +} + +// MOMENTS + +function setMonth (mom, value) { + var dayOfMonth; + + if (!mom.isValid()) { + // No op + return mom; + } + + if (typeof value === 'string') { + if (/^\d+$/.test(value)) { + value = toInt(value); + } else { + value = mom.localeData().monthsParse(value); + // TODO: Another silent failure? + if (!isNumber(value)) { + return mom; + } + } + } + + dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value)); + mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); + return mom; +} + +function getSetMonth (value) { + if (value != null) { + setMonth(this, value); + hooks.updateOffset(this, true); + return this; + } else { + return get(this, 'Month'); + } +} + +function getDaysInMonth () { + return daysInMonth(this.year(), this.month()); +} + +var defaultMonthsShortRegex = matchWord; +function monthsShortRegex (isStrict) { + if (this._monthsParseExact) { + if (!hasOwnProp(this, '_monthsRegex')) { + computeMonthsParse.call(this); + } + if (isStrict) { + return this._monthsShortStrictRegex; + } else { + return this._monthsShortRegex; + } + } else { + if (!hasOwnProp(this, '_monthsShortRegex')) { + this._monthsShortRegex = defaultMonthsShortRegex; + } + return this._monthsShortStrictRegex && isStrict ? + this._monthsShortStrictRegex : this._monthsShortRegex; + } +} + +var defaultMonthsRegex = matchWord; +function monthsRegex (isStrict) { + if (this._monthsParseExact) { + if (!hasOwnProp(this, '_monthsRegex')) { + computeMonthsParse.call(this); + } + if (isStrict) { + return this._monthsStrictRegex; + } else { + return this._monthsRegex; + } + } else { + if (!hasOwnProp(this, '_monthsRegex')) { + this._monthsRegex = defaultMonthsRegex; + } + return this._monthsStrictRegex && isStrict ? + this._monthsStrictRegex : this._monthsRegex; + } +} + +function computeMonthsParse () { + function cmpLenRev(a, b) { + return b.length - a.length; + } + + var shortPieces = [], longPieces = [], mixedPieces = [], + i, mom; + for (i = 0; i < 12; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, i]); + shortPieces.push(this.monthsShort(mom, '')); + longPieces.push(this.months(mom, '')); + mixedPieces.push(this.months(mom, '')); + mixedPieces.push(this.monthsShort(mom, '')); + } + // Sorting makes sure if one month (or abbr) is a prefix of another it + // will match the longer piece. + shortPieces.sort(cmpLenRev); + longPieces.sort(cmpLenRev); + mixedPieces.sort(cmpLenRev); + for (i = 0; i < 12; i++) { + shortPieces[i] = regexEscape(shortPieces[i]); + longPieces[i] = regexEscape(longPieces[i]); + } + for (i = 0; i < 24; i++) { + mixedPieces[i] = regexEscape(mixedPieces[i]); + } + + this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); + this._monthsShortRegex = this._monthsRegex; + this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); + this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); +} + +function createDate (y, m, d, h, M, s, ms) { + // can't just apply() to create a date: + // https://stackoverflow.com/q/181348 + var date = new Date(y, m, d, h, M, s, ms); + + // the date constructor remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0 && isFinite(date.getFullYear())) { + date.setFullYear(y); + } + return date; +} + +function createUTCDate (y) { + var date = new Date(Date.UTC.apply(null, arguments)); + + // the Date.UTC function remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) { + date.setUTCFullYear(y); + } + return date; +} + +// start-of-first-week - start-of-year +function firstWeekOffset(year, dow, doy) { + var // first-week day -- which january is always in the first week (4 for iso, 1 for other) + fwd = 7 + dow - doy, + // first-week day local weekday -- which local weekday is fwd + fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7; + + return -fwdlw + fwd - 1; +} + +// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday +function dayOfYearFromWeeks(year, week, weekday, dow, doy) { + var localWeekday = (7 + weekday - dow) % 7, + weekOffset = firstWeekOffset(year, dow, doy), + dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset, + resYear, resDayOfYear; + + if (dayOfYear <= 0) { + resYear = year - 1; + resDayOfYear = daysInYear(resYear) + dayOfYear; + } else if (dayOfYear > daysInYear(year)) { + resYear = year + 1; + resDayOfYear = dayOfYear - daysInYear(year); + } else { + resYear = year; + resDayOfYear = dayOfYear; + } + + return { + year: resYear, + dayOfYear: resDayOfYear + }; +} + +function weekOfYear(mom, dow, doy) { + var weekOffset = firstWeekOffset(mom.year(), dow, doy), + week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1, + resWeek, resYear; + + if (week < 1) { + resYear = mom.year() - 1; + resWeek = week + weeksInYear(resYear, dow, doy); + } else if (week > weeksInYear(mom.year(), dow, doy)) { + resWeek = week - weeksInYear(mom.year(), dow, doy); + resYear = mom.year() + 1; + } else { + resYear = mom.year(); + resWeek = week; + } + + return { + week: resWeek, + year: resYear + }; +} + +function weeksInYear(year, dow, doy) { + var weekOffset = firstWeekOffset(year, dow, doy), + weekOffsetNext = firstWeekOffset(year + 1, dow, doy); + return (daysInYear(year) - weekOffset + weekOffsetNext) / 7; +} + +// FORMATTING + +addFormatToken('w', ['ww', 2], 'wo', 'week'); +addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); + +// ALIASES + +addUnitAlias('week', 'w'); +addUnitAlias('isoWeek', 'W'); + +// PRIORITIES + +addUnitPriority('week', 5); +addUnitPriority('isoWeek', 5); + +// PARSING + +addRegexToken('w', match1to2); +addRegexToken('ww', match1to2, match2); +addRegexToken('W', match1to2); +addRegexToken('WW', match1to2, match2); + +addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) { + week[token.substr(0, 1)] = toInt(input); +}); + +// HELPERS + +// LOCALES + +function localeWeek (mom) { + return weekOfYear(mom, this._week.dow, this._week.doy).week; +} + +var defaultLocaleWeek = { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. +}; + +function localeFirstDayOfWeek () { + return this._week.dow; +} + +function localeFirstDayOfYear () { + return this._week.doy; +} + +// MOMENTS + +function getSetWeek (input) { + var week = this.localeData().week(this); + return input == null ? week : this.add((input - week) * 7, 'd'); +} + +function getSetISOWeek (input) { + var week = weekOfYear(this, 1, 4).week; + return input == null ? week : this.add((input - week) * 7, 'd'); +} + +// FORMATTING + +addFormatToken('d', 0, 'do', 'day'); + +addFormatToken('dd', 0, 0, function (format) { + return this.localeData().weekdaysMin(this, format); +}); + +addFormatToken('ddd', 0, 0, function (format) { + return this.localeData().weekdaysShort(this, format); +}); + +addFormatToken('dddd', 0, 0, function (format) { + return this.localeData().weekdays(this, format); +}); + +addFormatToken('e', 0, 0, 'weekday'); +addFormatToken('E', 0, 0, 'isoWeekday'); + +// ALIASES + +addUnitAlias('day', 'd'); +addUnitAlias('weekday', 'e'); +addUnitAlias('isoWeekday', 'E'); + +// PRIORITY +addUnitPriority('day', 11); +addUnitPriority('weekday', 11); +addUnitPriority('isoWeekday', 11); + +// PARSING + +addRegexToken('d', match1to2); +addRegexToken('e', match1to2); +addRegexToken('E', match1to2); +addRegexToken('dd', function (isStrict, locale) { + return locale.weekdaysMinRegex(isStrict); +}); +addRegexToken('ddd', function (isStrict, locale) { + return locale.weekdaysShortRegex(isStrict); +}); +addRegexToken('dddd', function (isStrict, locale) { + return locale.weekdaysRegex(isStrict); +}); + +addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) { + var weekday = config._locale.weekdaysParse(input, token, config._strict); + // if we didn't get a weekday name, mark the date as invalid + if (weekday != null) { + week.d = weekday; + } else { + getParsingFlags(config).invalidWeekday = input; + } +}); + +addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) { + week[token] = toInt(input); +}); + +// HELPERS + +function parseWeekday(input, locale) { + if (typeof input !== 'string') { + return input; + } + + if (!isNaN(input)) { + return parseInt(input, 10); + } + + input = locale.weekdaysParse(input); + if (typeof input === 'number') { + return input; + } + + return null; +} + +function parseIsoWeekday(input, locale) { + if (typeof input === 'string') { + return locale.weekdaysParse(input) % 7 || 7; + } + return isNaN(input) ? null : input; +} + +// LOCALES + +var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'); +function localeWeekdays (m, format) { + if (!m) { + return isArray(this._weekdays) ? this._weekdays : + this._weekdays['standalone']; + } + return isArray(this._weekdays) ? this._weekdays[m.day()] : + this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()]; +} + +var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'); +function localeWeekdaysShort (m) { + return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort; +} + +var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'); +function localeWeekdaysMin (m) { + return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin; +} + +function handleStrictParse$1(weekdayName, format, strict) { + var i, ii, mom, llc = weekdayName.toLocaleLowerCase(); + if (!this._weekdaysParse) { + this._weekdaysParse = []; + this._shortWeekdaysParse = []; + this._minWeekdaysParse = []; + + for (i = 0; i < 7; ++i) { + mom = createUTC([2000, 1]).day(i); + this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase(); + this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase(); + this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase(); + } + } + + if (strict) { + if (format === 'dddd') { + ii = indexOf.call(this._weekdaysParse, llc); + return ii !== -1 ? ii : null; + } else if (format === 'ddd') { + ii = indexOf.call(this._shortWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } + } else { + if (format === 'dddd') { + ii = indexOf.call(this._weekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._shortWeekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else if (format === 'ddd') { + ii = indexOf.call(this._shortWeekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._weekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._minWeekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._weekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._shortWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } + } +} + +function localeWeekdaysParse (weekdayName, format, strict) { + var i, mom, regex; + + if (this._weekdaysParseExact) { + return handleStrictParse$1.call(this, weekdayName, format, strict); + } + + if (!this._weekdaysParse) { + this._weekdaysParse = []; + this._minWeekdaysParse = []; + this._shortWeekdaysParse = []; + this._fullWeekdaysParse = []; + } + + for (i = 0; i < 7; i++) { + // make the regex if we don't have it already + + mom = createUTC([2000, 1]).day(i); + if (strict && !this._fullWeekdaysParse[i]) { + this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\.?') + '$', 'i'); + this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\.?') + '$', 'i'); + this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\.?') + '$', 'i'); + } + if (!this._weekdaysParse[i]) { + regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); + this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); + } + // test the regex + if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (!strict && this._weekdaysParse[i].test(weekdayName)) { + return i; + } + } +} + +// MOMENTS + +function getSetDayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); + if (input != null) { + input = parseWeekday(input, this.localeData()); + return this.add(input - day, 'd'); + } else { + return day; + } +} + +function getSetLocaleDayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; + return input == null ? weekday : this.add(input - weekday, 'd'); +} + +function getSetISODayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + + // behaves the same as moment#day except + // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) + // as a setter, sunday should belong to the previous week. + + if (input != null) { + var weekday = parseIsoWeekday(input, this.localeData()); + return this.day(this.day() % 7 ? weekday : weekday - 7); + } else { + return this.day() || 7; + } +} + +var defaultWeekdaysRegex = matchWord; +function weekdaysRegex (isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + if (isStrict) { + return this._weekdaysStrictRegex; + } else { + return this._weekdaysRegex; + } + } else { + if (!hasOwnProp(this, '_weekdaysRegex')) { + this._weekdaysRegex = defaultWeekdaysRegex; + } + return this._weekdaysStrictRegex && isStrict ? + this._weekdaysStrictRegex : this._weekdaysRegex; + } +} + +var defaultWeekdaysShortRegex = matchWord; +function weekdaysShortRegex (isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + if (isStrict) { + return this._weekdaysShortStrictRegex; + } else { + return this._weekdaysShortRegex; + } + } else { + if (!hasOwnProp(this, '_weekdaysShortRegex')) { + this._weekdaysShortRegex = defaultWeekdaysShortRegex; + } + return this._weekdaysShortStrictRegex && isStrict ? + this._weekdaysShortStrictRegex : this._weekdaysShortRegex; + } +} + +var defaultWeekdaysMinRegex = matchWord; +function weekdaysMinRegex (isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + if (isStrict) { + return this._weekdaysMinStrictRegex; + } else { + return this._weekdaysMinRegex; + } + } else { + if (!hasOwnProp(this, '_weekdaysMinRegex')) { + this._weekdaysMinRegex = defaultWeekdaysMinRegex; + } + return this._weekdaysMinStrictRegex && isStrict ? + this._weekdaysMinStrictRegex : this._weekdaysMinRegex; + } +} + + +function computeWeekdaysParse () { + function cmpLenRev(a, b) { + return b.length - a.length; + } + + var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [], + i, mom, minp, shortp, longp; + for (i = 0; i < 7; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, 1]).day(i); + minp = this.weekdaysMin(mom, ''); + shortp = this.weekdaysShort(mom, ''); + longp = this.weekdays(mom, ''); + minPieces.push(minp); + shortPieces.push(shortp); + longPieces.push(longp); + mixedPieces.push(minp); + mixedPieces.push(shortp); + mixedPieces.push(longp); + } + // Sorting makes sure if one weekday (or abbr) is a prefix of another it + // will match the longer piece. + minPieces.sort(cmpLenRev); + shortPieces.sort(cmpLenRev); + longPieces.sort(cmpLenRev); + mixedPieces.sort(cmpLenRev); + for (i = 0; i < 7; i++) { + shortPieces[i] = regexEscape(shortPieces[i]); + longPieces[i] = regexEscape(longPieces[i]); + mixedPieces[i] = regexEscape(mixedPieces[i]); + } + + this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); + this._weekdaysShortRegex = this._weekdaysRegex; + this._weekdaysMinRegex = this._weekdaysRegex; + + this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); + this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); + this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i'); +} + +// FORMATTING + +function hFormat() { + return this.hours() % 12 || 12; +} + +function kFormat() { + return this.hours() || 24; +} + +addFormatToken('H', ['HH', 2], 0, 'hour'); +addFormatToken('h', ['hh', 2], 0, hFormat); +addFormatToken('k', ['kk', 2], 0, kFormat); + +addFormatToken('hmm', 0, 0, function () { + return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2); +}); + +addFormatToken('hmmss', 0, 0, function () { + return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + + zeroFill(this.seconds(), 2); +}); + +addFormatToken('Hmm', 0, 0, function () { + return '' + this.hours() + zeroFill(this.minutes(), 2); +}); + +addFormatToken('Hmmss', 0, 0, function () { + return '' + this.hours() + zeroFill(this.minutes(), 2) + + zeroFill(this.seconds(), 2); +}); + +function meridiem (token, lowercase) { + addFormatToken(token, 0, 0, function () { + return this.localeData().meridiem(this.hours(), this.minutes(), lowercase); + }); +} + +meridiem('a', true); +meridiem('A', false); + +// ALIASES + +addUnitAlias('hour', 'h'); + +// PRIORITY +addUnitPriority('hour', 13); + +// PARSING + +function matchMeridiem (isStrict, locale) { + return locale._meridiemParse; +} + +addRegexToken('a', matchMeridiem); +addRegexToken('A', matchMeridiem); +addRegexToken('H', match1to2); +addRegexToken('h', match1to2); +addRegexToken('k', match1to2); +addRegexToken('HH', match1to2, match2); +addRegexToken('hh', match1to2, match2); +addRegexToken('kk', match1to2, match2); + +addRegexToken('hmm', match3to4); +addRegexToken('hmmss', match5to6); +addRegexToken('Hmm', match3to4); +addRegexToken('Hmmss', match5to6); + +addParseToken(['H', 'HH'], HOUR); +addParseToken(['k', 'kk'], function (input, array, config) { + var kInput = toInt(input); + array[HOUR] = kInput === 24 ? 0 : kInput; +}); +addParseToken(['a', 'A'], function (input, array, config) { + config._isPm = config._locale.isPM(input); + config._meridiem = input; +}); +addParseToken(['h', 'hh'], function (input, array, config) { + array[HOUR] = toInt(input); + getParsingFlags(config).bigHour = true; +}); +addParseToken('hmm', function (input, array, config) { + var pos = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos)); + array[MINUTE] = toInt(input.substr(pos)); + getParsingFlags(config).bigHour = true; +}); +addParseToken('hmmss', function (input, array, config) { + var pos1 = input.length - 4; + var pos2 = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos1)); + array[MINUTE] = toInt(input.substr(pos1, 2)); + array[SECOND] = toInt(input.substr(pos2)); + getParsingFlags(config).bigHour = true; +}); +addParseToken('Hmm', function (input, array, config) { + var pos = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos)); + array[MINUTE] = toInt(input.substr(pos)); +}); +addParseToken('Hmmss', function (input, array, config) { + var pos1 = input.length - 4; + var pos2 = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos1)); + array[MINUTE] = toInt(input.substr(pos1, 2)); + array[SECOND] = toInt(input.substr(pos2)); +}); + +// LOCALES + +function localeIsPM (input) { + // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays + // Using charAt should be more compatible. + return ((input + '').toLowerCase().charAt(0) === 'p'); +} + +var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i; +function localeMeridiem (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'pm' : 'PM'; + } else { + return isLower ? 'am' : 'AM'; + } +} + + +// MOMENTS + +// Setting the hour should keep the time, because the user explicitly +// specified which hour he wants. So trying to maintain the same hour (in +// a new timezone) makes sense. Adding/subtracting hours does not follow +// this rule. +var getSetHour = makeGetSet('Hours', true); + +// months +// week +// weekdays +// meridiem +var baseConfig = { + calendar: defaultCalendar, + longDateFormat: defaultLongDateFormat, + invalidDate: defaultInvalidDate, + ordinal: defaultOrdinal, + dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse, + relativeTime: defaultRelativeTime, + + months: defaultLocaleMonths, + monthsShort: defaultLocaleMonthsShort, + + week: defaultLocaleWeek, + + weekdays: defaultLocaleWeekdays, + weekdaysMin: defaultLocaleWeekdaysMin, + weekdaysShort: defaultLocaleWeekdaysShort, + + meridiemParse: defaultLocaleMeridiemParse +}; + +// internal storage for locale config files +var locales = {}; +var localeFamilies = {}; +var globalLocale; + +function normalizeLocale(key) { + return key ? key.toLowerCase().replace('_', '-') : key; +} + +// pick the locale from the array +// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each +// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root +function chooseLocale(names) { + var i = 0, j, next, locale, split; + + while (i < names.length) { + split = normalizeLocale(names[i]).split('-'); + j = split.length; + next = normalizeLocale(names[i + 1]); + next = next ? next.split('-') : null; + while (j > 0) { + locale = loadLocale(split.slice(0, j).join('-')); + if (locale) { + return locale; + } + if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { + //the next array item is better than a shallower substring of this one + break; + } + j--; + } + i++; + } + return null; +} + +function loadLocale(name) { + var oldLocale = null; + // TODO: Find a better way to register and load all the locales in Node + if (!locales[name] && (typeof module !== 'undefined') && + module && module.exports) { + try { + oldLocale = globalLocale._abbr; + var aliasedRequire = require; + aliasedRequire('./locale/' + name); + getSetGlobalLocale(oldLocale); + } catch (e) {} + } + return locales[name]; +} + +// This function will load locale and then set the global locale. If +// no arguments are passed in, it will simply return the current global +// locale key. +function getSetGlobalLocale (key, values) { + var data; + if (key) { + if (isUndefined(values)) { + data = getLocale(key); + } + else { + data = defineLocale(key, values); + } + + if (data) { + // moment.duration._locale = moment._locale = data; + globalLocale = data; + } + } + + return globalLocale._abbr; +} + +function defineLocale (name, config) { + if (config !== null) { + var parentConfig = baseConfig; + config.abbr = name; + if (locales[name] != null) { + deprecateSimple('defineLocaleOverride', + 'use moment.updateLocale(localeName, config) to change ' + + 'an existing locale. moment.defineLocale(localeName, ' + + 'config) should only be used for creating a new locale ' + + 'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'); + parentConfig = locales[name]._config; + } else if (config.parentLocale != null) { + if (locales[config.parentLocale] != null) { + parentConfig = locales[config.parentLocale]._config; + } else { + if (!localeFamilies[config.parentLocale]) { + localeFamilies[config.parentLocale] = []; + } + localeFamilies[config.parentLocale].push({ + name: name, + config: config + }); + return null; + } + } + locales[name] = new Locale(mergeConfigs(parentConfig, config)); + + if (localeFamilies[name]) { + localeFamilies[name].forEach(function (x) { + defineLocale(x.name, x.config); + }); + } + + // backwards compat for now: also set the locale + // make sure we set the locale AFTER all child locales have been + // created, so we won't end up with the child locale set. + getSetGlobalLocale(name); + + + return locales[name]; + } else { + // useful for testing + delete locales[name]; + return null; + } +} + +function updateLocale(name, config) { + if (config != null) { + var locale, tmpLocale, parentConfig = baseConfig; + // MERGE + tmpLocale = loadLocale(name); + if (tmpLocale != null) { + parentConfig = tmpLocale._config; + } + config = mergeConfigs(parentConfig, config); + locale = new Locale(config); + locale.parentLocale = locales[name]; + locales[name] = locale; + + // backwards compat for now: also set the locale + getSetGlobalLocale(name); + } else { + // pass null for config to unupdate, useful for tests + if (locales[name] != null) { + if (locales[name].parentLocale != null) { + locales[name] = locales[name].parentLocale; + } else if (locales[name] != null) { + delete locales[name]; + } + } + } + return locales[name]; +} + +// returns locale data +function getLocale (key) { + var locale; + + if (key && key._locale && key._locale._abbr) { + key = key._locale._abbr; + } + + if (!key) { + return globalLocale; + } + + if (!isArray(key)) { + //short-circuit everything else + locale = loadLocale(key); + if (locale) { + return locale; + } + key = [key]; + } + + return chooseLocale(key); +} + +function listLocales() { + return keys(locales); +} + +function checkOverflow (m) { + var overflow; + var a = m._a; + + if (a && getParsingFlags(m).overflow === -2) { + overflow = + a[MONTH] < 0 || a[MONTH] > 11 ? MONTH : + a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE : + a[HOUR] < 0 || a[HOUR] > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR : + a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE : + a[SECOND] < 0 || a[SECOND] > 59 ? SECOND : + a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND : + -1; + + if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { + overflow = DATE; + } + if (getParsingFlags(m)._overflowWeeks && overflow === -1) { + overflow = WEEK; + } + if (getParsingFlags(m)._overflowWeekday && overflow === -1) { + overflow = WEEKDAY; + } + + getParsingFlags(m).overflow = overflow; + } + + return m; +} + +// Pick the first defined of two or three arguments. +function defaults(a, b, c) { + if (a != null) { + return a; + } + if (b != null) { + return b; + } + return c; +} + +function currentDateArray(config) { + // hooks is actually the exported moment object + var nowValue = new Date(hooks.now()); + if (config._useUTC) { + return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()]; + } + return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; +} + +// convert an array to a date. +// the array should mirror the parameters below +// note: all values past the year are optional and will default to the lowest possible value. +// [year, month, day , hour, minute, second, millisecond] +function configFromArray (config) { + var i, date, input = [], currentDate, yearToUse; + + if (config._d) { + return; + } + + currentDate = currentDateArray(config); + + //compute day of the year from weeks and weekdays + if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { + dayOfYearFromWeekInfo(config); + } + + //if the day of the year is set, figure out what it is + if (config._dayOfYear != null) { + yearToUse = defaults(config._a[YEAR], currentDate[YEAR]); + + if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) { + getParsingFlags(config)._overflowDayOfYear = true; + } + + date = createUTCDate(yearToUse, 0, config._dayOfYear); + config._a[MONTH] = date.getUTCMonth(); + config._a[DATE] = date.getUTCDate(); + } + + // Default to current date. + // * if no year, month, day of month are given, default to today + // * if day of month is given, default month and year + // * if month is given, default only year + // * if year is given, don't default anything + for (i = 0; i < 3 && config._a[i] == null; ++i) { + config._a[i] = input[i] = currentDate[i]; + } + + // Zero out whatever was not defaulted, including time + for (; i < 7; i++) { + config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; + } + + // Check for 24:00:00.000 + if (config._a[HOUR] === 24 && + config._a[MINUTE] === 0 && + config._a[SECOND] === 0 && + config._a[MILLISECOND] === 0) { + config._nextDay = true; + config._a[HOUR] = 0; + } + + config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input); + // Apply timezone offset from input. The actual utcOffset can be changed + // with parseZone. + if (config._tzm != null) { + config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); + } + + if (config._nextDay) { + config._a[HOUR] = 24; + } + + // check for mismatching day of week + if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== config._d.getDay()) { + getParsingFlags(config).weekdayMismatch = true; + } +} + +function dayOfYearFromWeekInfo(config) { + var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow; + + w = config._w; + if (w.GG != null || w.W != null || w.E != null) { + dow = 1; + doy = 4; + + // TODO: We need to take the current isoWeekYear, but that depends on + // how we interpret now (local, utc, fixed offset). So create + // a now version of current config (take local/utc/offset flags, and + // create now). + weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year); + week = defaults(w.W, 1); + weekday = defaults(w.E, 1); + if (weekday < 1 || weekday > 7) { + weekdayOverflow = true; + } + } else { + dow = config._locale._week.dow; + doy = config._locale._week.doy; + + var curWeek = weekOfYear(createLocal(), dow, doy); + + weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); + + // Default to current week. + week = defaults(w.w, curWeek.week); + + if (w.d != null) { + // weekday -- low day numbers are considered next week + weekday = w.d; + if (weekday < 0 || weekday > 6) { + weekdayOverflow = true; + } + } else if (w.e != null) { + // local weekday -- counting starts from beginning of week + weekday = w.e + dow; + if (w.e < 0 || w.e > 6) { + weekdayOverflow = true; + } + } else { + // default to beginning of week + weekday = dow; + } + } + if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { + getParsingFlags(config)._overflowWeeks = true; + } else if (weekdayOverflow != null) { + getParsingFlags(config)._overflowWeekday = true; + } else { + temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); + config._a[YEAR] = temp.year; + config._dayOfYear = temp.dayOfYear; + } +} + +// iso 8601 regex +// 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) +var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; +var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; + +var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/; + +var isoDates = [ + ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], + ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/], + ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/], + ['GGGG-[W]WW', /\d{4}-W\d\d/, false], + ['YYYY-DDD', /\d{4}-\d{3}/], + ['YYYY-MM', /\d{4}-\d\d/, false], + ['YYYYYYMMDD', /[+-]\d{10}/], + ['YYYYMMDD', /\d{8}/], + // YYYYMM is NOT allowed by the standard + ['GGGG[W]WWE', /\d{4}W\d{3}/], + ['GGGG[W]WW', /\d{4}W\d{2}/, false], + ['YYYYDDD', /\d{7}/] +]; + +// iso time formats and regexes +var isoTimes = [ + ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/], + ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/], + ['HH:mm:ss', /\d\d:\d\d:\d\d/], + ['HH:mm', /\d\d:\d\d/], + ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/], + ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/], + ['HHmmss', /\d\d\d\d\d\d/], + ['HHmm', /\d\d\d\d/], + ['HH', /\d\d/] +]; + +var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; + +// date from iso format +function configFromISO(config) { + var i, l, + string = config._i, + match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string), + allowTime, dateFormat, timeFormat, tzFormat; + + if (match) { + getParsingFlags(config).iso = true; + + for (i = 0, l = isoDates.length; i < l; i++) { + if (isoDates[i][1].exec(match[1])) { + dateFormat = isoDates[i][0]; + allowTime = isoDates[i][2] !== false; + break; + } + } + if (dateFormat == null) { + config._isValid = false; + return; + } + if (match[3]) { + for (i = 0, l = isoTimes.length; i < l; i++) { + if (isoTimes[i][1].exec(match[3])) { + // match[2] should be 'T' or space + timeFormat = (match[2] || ' ') + isoTimes[i][0]; + break; + } + } + if (timeFormat == null) { + config._isValid = false; + return; + } + } + if (!allowTime && timeFormat != null) { + config._isValid = false; + return; + } + if (match[4]) { + if (tzRegex.exec(match[4])) { + tzFormat = 'Z'; + } else { + config._isValid = false; + return; + } + } + config._f = dateFormat + (timeFormat || '') + (tzFormat || ''); + configFromStringAndFormat(config); + } else { + config._isValid = false; + } +} + +// RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3 +var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/; + +function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) { + var result = [ + untruncateYear(yearStr), + defaultLocaleMonthsShort.indexOf(monthStr), + parseInt(dayStr, 10), + parseInt(hourStr, 10), + parseInt(minuteStr, 10) + ]; + + if (secondStr) { + result.push(parseInt(secondStr, 10)); + } + + return result; +} + +function untruncateYear(yearStr) { + var year = parseInt(yearStr, 10); + if (year <= 49) { + return 2000 + year; + } else if (year <= 999) { + return 1900 + year; + } + return year; +} + +function preprocessRFC2822(s) { + // Remove comments and folding whitespace and replace multiple-spaces with a single space + return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').trim(); +} + +function checkWeekday(weekdayStr, parsedInput, config) { + if (weekdayStr) { + // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check. + var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr), + weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay(); + if (weekdayProvided !== weekdayActual) { + getParsingFlags(config).weekdayMismatch = true; + config._isValid = false; + return false; + } + } + return true; +} + +var obsOffsets = { + UT: 0, + GMT: 0, + EDT: -4 * 60, + EST: -5 * 60, + CDT: -5 * 60, + CST: -6 * 60, + MDT: -6 * 60, + MST: -7 * 60, + PDT: -7 * 60, + PST: -8 * 60 +}; + +function calculateOffset(obsOffset, militaryOffset, numOffset) { + if (obsOffset) { + return obsOffsets[obsOffset]; + } else if (militaryOffset) { + // the only allowed military tz is Z + return 0; + } else { + var hm = parseInt(numOffset, 10); + var m = hm % 100, h = (hm - m) / 100; + return h * 60 + m; + } +} + +// date and time from ref 2822 format +function configFromRFC2822(config) { + var match = rfc2822.exec(preprocessRFC2822(config._i)); + if (match) { + var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]); + if (!checkWeekday(match[1], parsedArray, config)) { + return; + } + + config._a = parsedArray; + config._tzm = calculateOffset(match[8], match[9], match[10]); + + config._d = createUTCDate.apply(null, config._a); + config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); + + getParsingFlags(config).rfc2822 = true; + } else { + config._isValid = false; + } +} + +// date from iso format or fallback +function configFromString(config) { + var matched = aspNetJsonRegex.exec(config._i); + + if (matched !== null) { + config._d = new Date(+matched[1]); + return; + } + + configFromISO(config); + if (config._isValid === false) { + delete config._isValid; + } else { + return; + } + + configFromRFC2822(config); + if (config._isValid === false) { + delete config._isValid; + } else { + return; + } + + // Final attempt, use Input Fallback + hooks.createFromInputFallback(config); +} + +hooks.createFromInputFallback = deprecate( + 'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' + + 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' + + 'discouraged and will be removed in an upcoming major release. Please refer to ' + + 'http://momentjs.com/guides/#/warnings/js-date/ for more info.', + function (config) { + config._d = new Date(config._i + (config._useUTC ? ' UTC' : '')); + } +); + +// constant that refers to the ISO standard +hooks.ISO_8601 = function () {}; + +// constant that refers to the RFC 2822 form +hooks.RFC_2822 = function () {}; + +// date from string and format string +function configFromStringAndFormat(config) { + // TODO: Move this to another part of the creation flow to prevent circular deps + if (config._f === hooks.ISO_8601) { + configFromISO(config); + return; + } + if (config._f === hooks.RFC_2822) { + configFromRFC2822(config); + return; + } + config._a = []; + getParsingFlags(config).empty = true; + + // This array is used to make a Date, either with `new Date` or `Date.UTC` + var string = '' + config._i, + i, parsedInput, tokens, token, skipped, + stringLength = string.length, + totalParsedInputLength = 0; + + tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; + + for (i = 0; i < tokens.length; i++) { + token = tokens[i]; + parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; + // console.log('token', token, 'parsedInput', parsedInput, + // 'regex', getParseRegexForToken(token, config)); + if (parsedInput) { + skipped = string.substr(0, string.indexOf(parsedInput)); + if (skipped.length > 0) { + getParsingFlags(config).unusedInput.push(skipped); + } + string = string.slice(string.indexOf(parsedInput) + parsedInput.length); + totalParsedInputLength += parsedInput.length; + } + // don't parse if it's not a known token + if (formatTokenFunctions[token]) { + if (parsedInput) { + getParsingFlags(config).empty = false; + } + else { + getParsingFlags(config).unusedTokens.push(token); + } + addTimeToArrayFromToken(token, parsedInput, config); + } + else if (config._strict && !parsedInput) { + getParsingFlags(config).unusedTokens.push(token); + } + } + + // add remaining unparsed input length to the string + getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength; + if (string.length > 0) { + getParsingFlags(config).unusedInput.push(string); + } + + // clear _12h flag if hour is <= 12 + if (config._a[HOUR] <= 12 && + getParsingFlags(config).bigHour === true && + config._a[HOUR] > 0) { + getParsingFlags(config).bigHour = undefined; + } + + getParsingFlags(config).parsedDateParts = config._a.slice(0); + getParsingFlags(config).meridiem = config._meridiem; + // handle meridiem + config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem); + + configFromArray(config); + checkOverflow(config); +} + + +function meridiemFixWrap (locale, hour, meridiem) { + var isPm; + + if (meridiem == null) { + // nothing to do + return hour; + } + if (locale.meridiemHour != null) { + return locale.meridiemHour(hour, meridiem); + } else if (locale.isPM != null) { + // Fallback + isPm = locale.isPM(meridiem); + if (isPm && hour < 12) { + hour += 12; + } + if (!isPm && hour === 12) { + hour = 0; + } + return hour; + } else { + // this is not supposed to happen + return hour; + } +} + +// date from string and array of format strings +function configFromStringAndArray(config) { + var tempConfig, + bestMoment, + + scoreToBeat, + i, + currentScore; + + if (config._f.length === 0) { + getParsingFlags(config).invalidFormat = true; + config._d = new Date(NaN); + return; + } + + for (i = 0; i < config._f.length; i++) { + currentScore = 0; + tempConfig = copyConfig({}, config); + if (config._useUTC != null) { + tempConfig._useUTC = config._useUTC; + } + tempConfig._f = config._f[i]; + configFromStringAndFormat(tempConfig); + + if (!isValid(tempConfig)) { + continue; + } + + // if there is any input that was not parsed add a penalty for that format + currentScore += getParsingFlags(tempConfig).charsLeftOver; + + //or tokens + currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10; + + getParsingFlags(tempConfig).score = currentScore; + + if (scoreToBeat == null || currentScore < scoreToBeat) { + scoreToBeat = currentScore; + bestMoment = tempConfig; + } + } + + extend(config, bestMoment || tempConfig); +} + +function configFromObject(config) { + if (config._d) { + return; + } + + var i = normalizeObjectUnits(config._i); + config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) { + return obj && parseInt(obj, 10); + }); + + configFromArray(config); +} + +function createFromConfig (config) { + var res = new Moment(checkOverflow(prepareConfig(config))); + if (res._nextDay) { + // Adding is smart enough around DST + res.add(1, 'd'); + res._nextDay = undefined; + } + + return res; +} + +function prepareConfig (config) { + var input = config._i, + format = config._f; + + config._locale = config._locale || getLocale(config._l); + + if (input === null || (format === undefined && input === '')) { + return createInvalid({nullInput: true}); + } + + if (typeof input === 'string') { + config._i = input = config._locale.preparse(input); + } + + if (isMoment(input)) { + return new Moment(checkOverflow(input)); + } else if (isDate(input)) { + config._d = input; + } else if (isArray(format)) { + configFromStringAndArray(config); + } else if (format) { + configFromStringAndFormat(config); + } else { + configFromInput(config); + } + + if (!isValid(config)) { + config._d = null; + } + + return config; +} + +function configFromInput(config) { + var input = config._i; + if (isUndefined(input)) { + config._d = new Date(hooks.now()); + } else if (isDate(input)) { + config._d = new Date(input.valueOf()); + } else if (typeof input === 'string') { + configFromString(config); + } else if (isArray(input)) { + config._a = map(input.slice(0), function (obj) { + return parseInt(obj, 10); + }); + configFromArray(config); + } else if (isObject(input)) { + configFromObject(config); + } else if (isNumber(input)) { + // from milliseconds + config._d = new Date(input); + } else { + hooks.createFromInputFallback(config); + } +} + +function createLocalOrUTC (input, format, locale, strict, isUTC) { + var c = {}; + + if (locale === true || locale === false) { + strict = locale; + locale = undefined; + } + + if ((isObject(input) && isObjectEmpty(input)) || + (isArray(input) && input.length === 0)) { + input = undefined; + } + // object construction must be done this way. + // https://github.com/moment/moment/issues/1423 + c._isAMomentObject = true; + c._useUTC = c._isUTC = isUTC; + c._l = locale; + c._i = input; + c._f = format; + c._strict = strict; + + return createFromConfig(c); +} + +function createLocal (input, format, locale, strict) { + return createLocalOrUTC(input, format, locale, strict, false); +} + +var prototypeMin = deprecate( + 'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', + function () { + var other = createLocal.apply(null, arguments); + if (this.isValid() && other.isValid()) { + return other < this ? this : other; + } else { + return createInvalid(); + } + } +); + +var prototypeMax = deprecate( + 'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', + function () { + var other = createLocal.apply(null, arguments); + if (this.isValid() && other.isValid()) { + return other > this ? this : other; + } else { + return createInvalid(); + } + } +); + +// Pick a moment m from moments so that m[fn](other) is true for all +// other. This relies on the function fn to be transitive. +// +// moments should either be an array of moment objects or an array, whose +// first element is an array of moment objects. +function pickBy(fn, moments) { + var res, i; + if (moments.length === 1 && isArray(moments[0])) { + moments = moments[0]; + } + if (!moments.length) { + return createLocal(); + } + res = moments[0]; + for (i = 1; i < moments.length; ++i) { + if (!moments[i].isValid() || moments[i][fn](res)) { + res = moments[i]; + } + } + return res; +} + +// TODO: Use [].sort instead? +function min () { + var args = [].slice.call(arguments, 0); + + return pickBy('isBefore', args); +} + +function max () { + var args = [].slice.call(arguments, 0); + + return pickBy('isAfter', args); +} + +var now = function () { + return Date.now ? Date.now() : +(new Date()); +}; + +var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond']; + +function isDurationValid(m) { + for (var key in m) { + if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) { + return false; + } + } + + var unitHasDecimal = false; + for (var i = 0; i < ordering.length; ++i) { + if (m[ordering[i]]) { + if (unitHasDecimal) { + return false; // only allow non-integers for smallest unit + } + if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) { + unitHasDecimal = true; + } + } + } + + return true; +} + +function isValid$1() { + return this._isValid; +} + +function createInvalid$1() { + return createDuration(NaN); +} + +function Duration (duration) { + var normalizedInput = normalizeObjectUnits(duration), + years = normalizedInput.year || 0, + quarters = normalizedInput.quarter || 0, + months = normalizedInput.month || 0, + weeks = normalizedInput.week || 0, + days = normalizedInput.day || 0, + hours = normalizedInput.hour || 0, + minutes = normalizedInput.minute || 0, + seconds = normalizedInput.second || 0, + milliseconds = normalizedInput.millisecond || 0; + + this._isValid = isDurationValid(normalizedInput); + + // representation for dateAddRemove + this._milliseconds = +milliseconds + + seconds * 1e3 + // 1000 + minutes * 6e4 + // 1000 * 60 + hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978 + // Because of dateAddRemove treats 24 hours as different from a + // day when working around DST, we need to store them separately + this._days = +days + + weeks * 7; + // It is impossible to translate months into days without knowing + // which months you are are talking about, so we have to store + // it separately. + this._months = +months + + quarters * 3 + + years * 12; + + this._data = {}; + + this._locale = getLocale(); + + this._bubble(); +} + +function isDuration (obj) { + return obj instanceof Duration; +} + +function absRound (number) { + if (number < 0) { + return Math.round(-1 * number) * -1; + } else { + return Math.round(number); + } +} + +// FORMATTING + +function offset (token, separator) { + addFormatToken(token, 0, 0, function () { + var offset = this.utcOffset(); + var sign = '+'; + if (offset < 0) { + offset = -offset; + sign = '-'; + } + return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2); + }); +} + +offset('Z', ':'); +offset('ZZ', ''); + +// PARSING + +addRegexToken('Z', matchShortOffset); +addRegexToken('ZZ', matchShortOffset); +addParseToken(['Z', 'ZZ'], function (input, array, config) { + config._useUTC = true; + config._tzm = offsetFromString(matchShortOffset, input); +}); + +// HELPERS + +// timezone chunker +// '+10:00' > ['10', '00'] +// '-1530' > ['-15', '30'] +var chunkOffset = /([\+\-]|\d\d)/gi; + +function offsetFromString(matcher, string) { + var matches = (string || '').match(matcher); + + if (matches === null) { + return null; + } + + var chunk = matches[matches.length - 1] || []; + var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0]; + var minutes = +(parts[1] * 60) + toInt(parts[2]); + + return minutes === 0 ? + 0 : + parts[0] === '+' ? minutes : -minutes; +} + +// Return a moment from input, that is local/utc/zone equivalent to model. +function cloneWithOffset(input, model) { + var res, diff; + if (model._isUTC) { + res = model.clone(); + diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); + // Use low-level api, because this fn is low-level api. + res._d.setTime(res._d.valueOf() + diff); + hooks.updateOffset(res, false); + return res; + } else { + return createLocal(input).local(); + } +} + +function getDateOffset (m) { + // On Firefox.24 Date#getTimezoneOffset returns a floating point. + // https://github.com/moment/moment/pull/1871 + return -Math.round(m._d.getTimezoneOffset() / 15) * 15; +} + +// HOOKS + +// This function will be called whenever a moment is mutated. +// It is intended to keep the offset in sync with the timezone. +hooks.updateOffset = function () {}; + +// MOMENTS + +// keepLocalTime = true means only change the timezone, without +// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--> +// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset +// +0200, so we adjust the time as needed, to be valid. +// +// Keeping the time actually adds/subtracts (one hour) +// from the actual represented time. That is why we call updateOffset +// a second time. In case it wants us to change the offset again +// _changeInProgress == true case, then we have to adjust, because +// there is no such time in the given timezone. +function getSetOffset (input, keepLocalTime, keepMinutes) { + var offset = this._offset || 0, + localAdjust; + if (!this.isValid()) { + return input != null ? this : NaN; + } + if (input != null) { + if (typeof input === 'string') { + input = offsetFromString(matchShortOffset, input); + if (input === null) { + return this; + } + } else if (Math.abs(input) < 16 && !keepMinutes) { + input = input * 60; + } + if (!this._isUTC && keepLocalTime) { + localAdjust = getDateOffset(this); + } + this._offset = input; + this._isUTC = true; + if (localAdjust != null) { + this.add(localAdjust, 'm'); + } + if (offset !== input) { + if (!keepLocalTime || this._changeInProgress) { + addSubtract(this, createDuration(input - offset, 'm'), 1, false); + } else if (!this._changeInProgress) { + this._changeInProgress = true; + hooks.updateOffset(this, true); + this._changeInProgress = null; + } + } + return this; + } else { + return this._isUTC ? offset : getDateOffset(this); + } +} + +function getSetZone (input, keepLocalTime) { + if (input != null) { + if (typeof input !== 'string') { + input = -input; + } + + this.utcOffset(input, keepLocalTime); + + return this; + } else { + return -this.utcOffset(); + } +} + +function setOffsetToUTC (keepLocalTime) { + return this.utcOffset(0, keepLocalTime); +} + +function setOffsetToLocal (keepLocalTime) { + if (this._isUTC) { + this.utcOffset(0, keepLocalTime); + this._isUTC = false; + + if (keepLocalTime) { + this.subtract(getDateOffset(this), 'm'); + } + } + return this; +} + +function setOffsetToParsedOffset () { + if (this._tzm != null) { + this.utcOffset(this._tzm, false, true); + } else if (typeof this._i === 'string') { + var tZone = offsetFromString(matchOffset, this._i); + if (tZone != null) { + this.utcOffset(tZone); + } + else { + this.utcOffset(0, true); + } + } + return this; +} + +function hasAlignedHourOffset (input) { + if (!this.isValid()) { + return false; + } + input = input ? createLocal(input).utcOffset() : 0; + + return (this.utcOffset() - input) % 60 === 0; +} + +function isDaylightSavingTime () { + return ( + this.utcOffset() > this.clone().month(0).utcOffset() || + this.utcOffset() > this.clone().month(5).utcOffset() + ); +} + +function isDaylightSavingTimeShifted () { + if (!isUndefined(this._isDSTShifted)) { + return this._isDSTShifted; + } + + var c = {}; + + copyConfig(c, this); + c = prepareConfig(c); + + if (c._a) { + var other = c._isUTC ? createUTC(c._a) : createLocal(c._a); + this._isDSTShifted = this.isValid() && + compareArrays(c._a, other.toArray()) > 0; + } else { + this._isDSTShifted = false; + } + + return this._isDSTShifted; +} + +function isLocal () { + return this.isValid() ? !this._isUTC : false; +} + +function isUtcOffset () { + return this.isValid() ? this._isUTC : false; +} + +function isUtc () { + return this.isValid() ? this._isUTC && this._offset === 0 : false; +} + +// ASP.NET json date format regex +var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; + +// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html +// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere +// and further modified to allow for strings containing both week and day +var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; + +function createDuration (input, key) { + var duration = input, + // matching against regexp is expensive, do it on demand + match = null, + sign, + ret, + diffRes; + + if (isDuration(input)) { + duration = { + ms : input._milliseconds, + d : input._days, + M : input._months + }; + } else if (isNumber(input)) { + duration = {}; + if (key) { + duration[key] = input; + } else { + duration.milliseconds = input; + } + } else if (!!(match = aspNetRegex.exec(input))) { + sign = (match[1] === '-') ? -1 : 1; + duration = { + y : 0, + d : toInt(match[DATE]) * sign, + h : toInt(match[HOUR]) * sign, + m : toInt(match[MINUTE]) * sign, + s : toInt(match[SECOND]) * sign, + ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match + }; + } else if (!!(match = isoRegex.exec(input))) { + sign = (match[1] === '-') ? -1 : (match[1] === '+') ? 1 : 1; + duration = { + y : parseIso(match[2], sign), + M : parseIso(match[3], sign), + w : parseIso(match[4], sign), + d : parseIso(match[5], sign), + h : parseIso(match[6], sign), + m : parseIso(match[7], sign), + s : parseIso(match[8], sign) + }; + } else if (duration == null) {// checks for null or undefined + duration = {}; + } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) { + diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to)); + + duration = {}; + duration.ms = diffRes.milliseconds; + duration.M = diffRes.months; + } + + ret = new Duration(duration); + + if (isDuration(input) && hasOwnProp(input, '_locale')) { + ret._locale = input._locale; + } + + return ret; +} + +createDuration.fn = Duration.prototype; +createDuration.invalid = createInvalid$1; + +function parseIso (inp, sign) { + // We'd normally use ~~inp for this, but unfortunately it also + // converts floats to ints. + // inp may be undefined, so careful calling replace on it. + var res = inp && parseFloat(inp.replace(',', '.')); + // apply sign while we're at it + return (isNaN(res) ? 0 : res) * sign; +} + +function positiveMomentsDifference(base, other) { + var res = {milliseconds: 0, months: 0}; + + res.months = other.month() - base.month() + + (other.year() - base.year()) * 12; + if (base.clone().add(res.months, 'M').isAfter(other)) { + --res.months; + } + + res.milliseconds = +other - +(base.clone().add(res.months, 'M')); + + return res; +} + +function momentsDifference(base, other) { + var res; + if (!(base.isValid() && other.isValid())) { + return {milliseconds: 0, months: 0}; + } + + other = cloneWithOffset(other, base); + if (base.isBefore(other)) { + res = positiveMomentsDifference(base, other); + } else { + res = positiveMomentsDifference(other, base); + res.milliseconds = -res.milliseconds; + res.months = -res.months; + } + + return res; +} + +// TODO: remove 'name' arg after deprecation is removed +function createAdder(direction, name) { + return function (val, period) { + var dur, tmp; + //invert the arguments, but complain about it + if (period !== null && !isNaN(+period)) { + deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' + + 'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'); + tmp = val; val = period; period = tmp; + } + + val = typeof val === 'string' ? +val : val; + dur = createDuration(val, period); + addSubtract(this, dur, direction); + return this; + }; +} + +function addSubtract (mom, duration, isAdding, updateOffset) { + var milliseconds = duration._milliseconds, + days = absRound(duration._days), + months = absRound(duration._months); + + if (!mom.isValid()) { + // No op + return; + } + + updateOffset = updateOffset == null ? true : updateOffset; + + if (months) { + setMonth(mom, get(mom, 'Month') + months * isAdding); + } + if (days) { + set$1(mom, 'Date', get(mom, 'Date') + days * isAdding); + } + if (milliseconds) { + mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding); + } + if (updateOffset) { + hooks.updateOffset(mom, days || months); + } +} + +var add = createAdder(1, 'add'); +var subtract = createAdder(-1, 'subtract'); + +function getCalendarFormat(myMoment, now) { + var diff = myMoment.diff(now, 'days', true); + return diff < -6 ? 'sameElse' : + diff < -1 ? 'lastWeek' : + diff < 0 ? 'lastDay' : + diff < 1 ? 'sameDay' : + diff < 2 ? 'nextDay' : + diff < 7 ? 'nextWeek' : 'sameElse'; +} + +function calendar$1 (time, formats) { + // We want to compare the start of today, vs this. + // Getting start-of-today depends on whether we're local/utc/offset or not. + var now = time || createLocal(), + sod = cloneWithOffset(now, this).startOf('day'), + format = hooks.calendarFormat(this, sod) || 'sameElse'; + + var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]); + + return this.format(output || this.localeData().calendar(format, this, createLocal(now))); +} + +function clone () { + return new Moment(this); +} + +function isAfter (input, units) { + var localInput = isMoment(input) ? input : createLocal(input); + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(!isUndefined(units) ? units : 'millisecond'); + if (units === 'millisecond') { + return this.valueOf() > localInput.valueOf(); + } else { + return localInput.valueOf() < this.clone().startOf(units).valueOf(); + } +} + +function isBefore (input, units) { + var localInput = isMoment(input) ? input : createLocal(input); + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(!isUndefined(units) ? units : 'millisecond'); + if (units === 'millisecond') { + return this.valueOf() < localInput.valueOf(); + } else { + return this.clone().endOf(units).valueOf() < localInput.valueOf(); + } +} + +function isBetween (from, to, units, inclusivity) { + inclusivity = inclusivity || '()'; + return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) && + (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units)); +} + +function isSame (input, units) { + var localInput = isMoment(input) ? input : createLocal(input), + inputMs; + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(units || 'millisecond'); + if (units === 'millisecond') { + return this.valueOf() === localInput.valueOf(); + } else { + inputMs = localInput.valueOf(); + return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf(); + } +} + +function isSameOrAfter (input, units) { + return this.isSame(input, units) || this.isAfter(input,units); +} + +function isSameOrBefore (input, units) { + return this.isSame(input, units) || this.isBefore(input,units); +} + +function diff (input, units, asFloat) { + var that, + zoneDelta, + delta, output; + + if (!this.isValid()) { + return NaN; + } + + that = cloneWithOffset(input, this); + + if (!that.isValid()) { + return NaN; + } + + zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4; + + units = normalizeUnits(units); + + switch (units) { + case 'year': output = monthDiff(this, that) / 12; break; + case 'month': output = monthDiff(this, that); break; + case 'quarter': output = monthDiff(this, that) / 3; break; + case 'second': output = (this - that) / 1e3; break; // 1000 + case 'minute': output = (this - that) / 6e4; break; // 1000 * 60 + case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60 + case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst + case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst + default: output = this - that; + } + + return asFloat ? output : absFloor(output); +} + +function monthDiff (a, b) { + // difference in months + var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()), + // b is in (anchor - 1 month, anchor + 1 month) + anchor = a.clone().add(wholeMonthDiff, 'months'), + anchor2, adjust; + + if (b - anchor < 0) { + anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); + // linear across the month + adjust = (b - anchor) / (anchor - anchor2); + } else { + anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); + // linear across the month + adjust = (b - anchor) / (anchor2 - anchor); + } + + //check for negative zero, return zero if negative zero + return -(wholeMonthDiff + adjust) || 0; +} + +hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ'; +hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]'; + +function toString () { + return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); +} + +function toISOString() { + if (!this.isValid()) { + return null; + } + var m = this.clone().utc(); + if (m.year() < 0 || m.year() > 9999) { + return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); + } + if (isFunction(Date.prototype.toISOString)) { + // native implementation is ~50x faster, use it when we can + return this.toDate().toISOString(); + } + return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); +} + +/** + * Return a human readable representation of a moment that can + * also be evaluated to get a new moment which is the same + * + * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects + */ +function inspect () { + if (!this.isValid()) { + return 'moment.invalid(/* ' + this._i + ' */)'; + } + var func = 'moment'; + var zone = ''; + if (!this.isLocal()) { + func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone'; + zone = 'Z'; + } + var prefix = '[' + func + '("]'; + var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY'; + var datetime = '-MM-DD[T]HH:mm:ss.SSS'; + var suffix = zone + '[")]'; + + return this.format(prefix + year + datetime + suffix); +} + +function format (inputString) { + if (!inputString) { + inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat; + } + var output = formatMoment(this, inputString); + return this.localeData().postformat(output); +} + +function from (time, withoutSuffix) { + if (this.isValid() && + ((isMoment(time) && time.isValid()) || + createLocal(time).isValid())) { + return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); + } else { + return this.localeData().invalidDate(); + } +} + +function fromNow (withoutSuffix) { + return this.from(createLocal(), withoutSuffix); +} + +function to (time, withoutSuffix) { + if (this.isValid() && + ((isMoment(time) && time.isValid()) || + createLocal(time).isValid())) { + return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix); + } else { + return this.localeData().invalidDate(); + } +} + +function toNow (withoutSuffix) { + return this.to(createLocal(), withoutSuffix); +} + +// If passed a locale key, it will set the locale for this +// instance. Otherwise, it will return the locale configuration +// variables for this instance. +function locale (key) { + var newLocaleData; + + if (key === undefined) { + return this._locale._abbr; + } else { + newLocaleData = getLocale(key); + if (newLocaleData != null) { + this._locale = newLocaleData; + } + return this; + } +} + +var lang = deprecate( + 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', + function (key) { + if (key === undefined) { + return this.localeData(); + } else { + return this.locale(key); + } + } +); + +function localeData () { + return this._locale; +} + +function startOf (units) { + units = normalizeUnits(units); + // the following switch intentionally omits break keywords + // to utilize falling through the cases. + switch (units) { + case 'year': + this.month(0); + /* falls through */ + case 'quarter': + case 'month': + this.date(1); + /* falls through */ + case 'week': + case 'isoWeek': + case 'day': + case 'date': + this.hours(0); + /* falls through */ + case 'hour': + this.minutes(0); + /* falls through */ + case 'minute': + this.seconds(0); + /* falls through */ + case 'second': + this.milliseconds(0); + } + + // weeks are a special case + if (units === 'week') { + this.weekday(0); + } + if (units === 'isoWeek') { + this.isoWeekday(1); + } + + // quarters are also special + if (units === 'quarter') { + this.month(Math.floor(this.month() / 3) * 3); + } + + return this; +} + +function endOf (units) { + units = normalizeUnits(units); + if (units === undefined || units === 'millisecond') { + return this; + } + + // 'date' is an alias for 'day', so it should be considered as such. + if (units === 'date') { + units = 'day'; + } + + return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms'); +} + +function valueOf () { + return this._d.valueOf() - ((this._offset || 0) * 60000); +} + +function unix () { + return Math.floor(this.valueOf() / 1000); +} + +function toDate () { + return new Date(this.valueOf()); +} + +function toArray () { + var m = this; + return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()]; +} + +function toObject () { + var m = this; + return { + years: m.year(), + months: m.month(), + date: m.date(), + hours: m.hours(), + minutes: m.minutes(), + seconds: m.seconds(), + milliseconds: m.milliseconds() + }; +} + +function toJSON () { + // new Date(NaN).toJSON() === null + return this.isValid() ? this.toISOString() : null; +} + +function isValid$2 () { + return isValid(this); +} + +function parsingFlags () { + return extend({}, getParsingFlags(this)); +} + +function invalidAt () { + return getParsingFlags(this).overflow; +} + +function creationData() { + return { + input: this._i, + format: this._f, + locale: this._locale, + isUTC: this._isUTC, + strict: this._strict + }; +} + +// FORMATTING + +addFormatToken(0, ['gg', 2], 0, function () { + return this.weekYear() % 100; +}); + +addFormatToken(0, ['GG', 2], 0, function () { + return this.isoWeekYear() % 100; +}); + +function addWeekYearFormatToken (token, getter) { + addFormatToken(0, [token, token.length], 0, getter); +} + +addWeekYearFormatToken('gggg', 'weekYear'); +addWeekYearFormatToken('ggggg', 'weekYear'); +addWeekYearFormatToken('GGGG', 'isoWeekYear'); +addWeekYearFormatToken('GGGGG', 'isoWeekYear'); + +// ALIASES + +addUnitAlias('weekYear', 'gg'); +addUnitAlias('isoWeekYear', 'GG'); + +// PRIORITY + +addUnitPriority('weekYear', 1); +addUnitPriority('isoWeekYear', 1); + + +// PARSING + +addRegexToken('G', matchSigned); +addRegexToken('g', matchSigned); +addRegexToken('GG', match1to2, match2); +addRegexToken('gg', match1to2, match2); +addRegexToken('GGGG', match1to4, match4); +addRegexToken('gggg', match1to4, match4); +addRegexToken('GGGGG', match1to6, match6); +addRegexToken('ggggg', match1to6, match6); + +addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) { + week[token.substr(0, 2)] = toInt(input); +}); + +addWeekParseToken(['gg', 'GG'], function (input, week, config, token) { + week[token] = hooks.parseTwoDigitYear(input); +}); + +// MOMENTS + +function getSetWeekYear (input) { + return getSetWeekYearHelper.call(this, + input, + this.week(), + this.weekday(), + this.localeData()._week.dow, + this.localeData()._week.doy); +} + +function getSetISOWeekYear (input) { + return getSetWeekYearHelper.call(this, + input, this.isoWeek(), this.isoWeekday(), 1, 4); +} + +function getISOWeeksInYear () { + return weeksInYear(this.year(), 1, 4); +} + +function getWeeksInYear () { + var weekInfo = this.localeData()._week; + return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); +} + +function getSetWeekYearHelper(input, week, weekday, dow, doy) { + var weeksTarget; + if (input == null) { + return weekOfYear(this, dow, doy).year; + } else { + weeksTarget = weeksInYear(input, dow, doy); + if (week > weeksTarget) { + week = weeksTarget; + } + return setWeekAll.call(this, input, week, weekday, dow, doy); + } +} + +function setWeekAll(weekYear, week, weekday, dow, doy) { + var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy), + date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear); + + this.year(date.getUTCFullYear()); + this.month(date.getUTCMonth()); + this.date(date.getUTCDate()); + return this; +} + +// FORMATTING + +addFormatToken('Q', 0, 'Qo', 'quarter'); + +// ALIASES + +addUnitAlias('quarter', 'Q'); + +// PRIORITY + +addUnitPriority('quarter', 7); + +// PARSING + +addRegexToken('Q', match1); +addParseToken('Q', function (input, array) { + array[MONTH] = (toInt(input) - 1) * 3; +}); + +// MOMENTS + +function getSetQuarter (input) { + return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); +} + +// FORMATTING + +addFormatToken('D', ['DD', 2], 'Do', 'date'); + +// ALIASES + +addUnitAlias('date', 'D'); + +// PRIOROITY +addUnitPriority('date', 9); + +// PARSING + +addRegexToken('D', match1to2); +addRegexToken('DD', match1to2, match2); +addRegexToken('Do', function (isStrict, locale) { + // TODO: Remove "ordinalParse" fallback in next major release. + return isStrict ? + (locale._dayOfMonthOrdinalParse || locale._ordinalParse) : + locale._dayOfMonthOrdinalParseLenient; +}); + +addParseToken(['D', 'DD'], DATE); +addParseToken('Do', function (input, array) { + array[DATE] = toInt(input.match(match1to2)[0], 10); +}); + +// MOMENTS + +var getSetDayOfMonth = makeGetSet('Date', true); + +// FORMATTING + +addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); + +// ALIASES + +addUnitAlias('dayOfYear', 'DDD'); + +// PRIORITY +addUnitPriority('dayOfYear', 4); + +// PARSING + +addRegexToken('DDD', match1to3); +addRegexToken('DDDD', match3); +addParseToken(['DDD', 'DDDD'], function (input, array, config) { + config._dayOfYear = toInt(input); +}); + +// HELPERS + +// MOMENTS + +function getSetDayOfYear (input) { + var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1; + return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); +} + +// FORMATTING + +addFormatToken('m', ['mm', 2], 0, 'minute'); + +// ALIASES + +addUnitAlias('minute', 'm'); + +// PRIORITY + +addUnitPriority('minute', 14); + +// PARSING + +addRegexToken('m', match1to2); +addRegexToken('mm', match1to2, match2); +addParseToken(['m', 'mm'], MINUTE); + +// MOMENTS + +var getSetMinute = makeGetSet('Minutes', false); + +// FORMATTING + +addFormatToken('s', ['ss', 2], 0, 'second'); + +// ALIASES + +addUnitAlias('second', 's'); + +// PRIORITY + +addUnitPriority('second', 15); + +// PARSING + +addRegexToken('s', match1to2); +addRegexToken('ss', match1to2, match2); +addParseToken(['s', 'ss'], SECOND); + +// MOMENTS + +var getSetSecond = makeGetSet('Seconds', false); + +// FORMATTING + +addFormatToken('S', 0, 0, function () { + return ~~(this.millisecond() / 100); +}); + +addFormatToken(0, ['SS', 2], 0, function () { + return ~~(this.millisecond() / 10); +}); + +addFormatToken(0, ['SSS', 3], 0, 'millisecond'); +addFormatToken(0, ['SSSS', 4], 0, function () { + return this.millisecond() * 10; +}); +addFormatToken(0, ['SSSSS', 5], 0, function () { + return this.millisecond() * 100; +}); +addFormatToken(0, ['SSSSSS', 6], 0, function () { + return this.millisecond() * 1000; +}); +addFormatToken(0, ['SSSSSSS', 7], 0, function () { + return this.millisecond() * 10000; +}); +addFormatToken(0, ['SSSSSSSS', 8], 0, function () { + return this.millisecond() * 100000; +}); +addFormatToken(0, ['SSSSSSSSS', 9], 0, function () { + return this.millisecond() * 1000000; +}); + + +// ALIASES + +addUnitAlias('millisecond', 'ms'); + +// PRIORITY + +addUnitPriority('millisecond', 16); + +// PARSING + +addRegexToken('S', match1to3, match1); +addRegexToken('SS', match1to3, match2); +addRegexToken('SSS', match1to3, match3); + +var token; +for (token = 'SSSS'; token.length <= 9; token += 'S') { + addRegexToken(token, matchUnsigned); +} + +function parseMs(input, array) { + array[MILLISECOND] = toInt(('0.' + input) * 1000); +} + +for (token = 'S'; token.length <= 9; token += 'S') { + addParseToken(token, parseMs); +} +// MOMENTS + +var getSetMillisecond = makeGetSet('Milliseconds', false); + +// FORMATTING + +addFormatToken('z', 0, 0, 'zoneAbbr'); +addFormatToken('zz', 0, 0, 'zoneName'); + +// MOMENTS + +function getZoneAbbr () { + return this._isUTC ? 'UTC' : ''; +} + +function getZoneName () { + return this._isUTC ? 'Coordinated Universal Time' : ''; +} + +var proto = Moment.prototype; + +proto.add = add; +proto.calendar = calendar$1; +proto.clone = clone; +proto.diff = diff; +proto.endOf = endOf; +proto.format = format; +proto.from = from; +proto.fromNow = fromNow; +proto.to = to; +proto.toNow = toNow; +proto.get = stringGet; +proto.invalidAt = invalidAt; +proto.isAfter = isAfter; +proto.isBefore = isBefore; +proto.isBetween = isBetween; +proto.isSame = isSame; +proto.isSameOrAfter = isSameOrAfter; +proto.isSameOrBefore = isSameOrBefore; +proto.isValid = isValid$2; +proto.lang = lang; +proto.locale = locale; +proto.localeData = localeData; +proto.max = prototypeMax; +proto.min = prototypeMin; +proto.parsingFlags = parsingFlags; +proto.set = stringSet; +proto.startOf = startOf; +proto.subtract = subtract; +proto.toArray = toArray; +proto.toObject = toObject; +proto.toDate = toDate; +proto.toISOString = toISOString; +proto.inspect = inspect; +proto.toJSON = toJSON; +proto.toString = toString; +proto.unix = unix; +proto.valueOf = valueOf; +proto.creationData = creationData; + +// Year +proto.year = getSetYear; +proto.isLeapYear = getIsLeapYear; + +// Week Year +proto.weekYear = getSetWeekYear; +proto.isoWeekYear = getSetISOWeekYear; + +// Quarter +proto.quarter = proto.quarters = getSetQuarter; + +// Month +proto.month = getSetMonth; +proto.daysInMonth = getDaysInMonth; + +// Week +proto.week = proto.weeks = getSetWeek; +proto.isoWeek = proto.isoWeeks = getSetISOWeek; +proto.weeksInYear = getWeeksInYear; +proto.isoWeeksInYear = getISOWeeksInYear; + +// Day +proto.date = getSetDayOfMonth; +proto.day = proto.days = getSetDayOfWeek; +proto.weekday = getSetLocaleDayOfWeek; +proto.isoWeekday = getSetISODayOfWeek; +proto.dayOfYear = getSetDayOfYear; + +// Hour +proto.hour = proto.hours = getSetHour; + +// Minute +proto.minute = proto.minutes = getSetMinute; + +// Second +proto.second = proto.seconds = getSetSecond; + +// Millisecond +proto.millisecond = proto.milliseconds = getSetMillisecond; + +// Offset +proto.utcOffset = getSetOffset; +proto.utc = setOffsetToUTC; +proto.local = setOffsetToLocal; +proto.parseZone = setOffsetToParsedOffset; +proto.hasAlignedHourOffset = hasAlignedHourOffset; +proto.isDST = isDaylightSavingTime; +proto.isLocal = isLocal; +proto.isUtcOffset = isUtcOffset; +proto.isUtc = isUtc; +proto.isUTC = isUtc; + +// Timezone +proto.zoneAbbr = getZoneAbbr; +proto.zoneName = getZoneName; + +// Deprecations +proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth); +proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth); +proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear); +proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone); +proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted); + +function createUnix (input) { + return createLocal(input * 1000); +} + +function createInZone () { + return createLocal.apply(null, arguments).parseZone(); +} + +function preParsePostFormat (string) { + return string; +} + +var proto$1 = Locale.prototype; + +proto$1.calendar = calendar; +proto$1.longDateFormat = longDateFormat; +proto$1.invalidDate = invalidDate; +proto$1.ordinal = ordinal; +proto$1.preparse = preParsePostFormat; +proto$1.postformat = preParsePostFormat; +proto$1.relativeTime = relativeTime; +proto$1.pastFuture = pastFuture; +proto$1.set = set; + +// Month +proto$1.months = localeMonths; +proto$1.monthsShort = localeMonthsShort; +proto$1.monthsParse = localeMonthsParse; +proto$1.monthsRegex = monthsRegex; +proto$1.monthsShortRegex = monthsShortRegex; + +// Week +proto$1.week = localeWeek; +proto$1.firstDayOfYear = localeFirstDayOfYear; +proto$1.firstDayOfWeek = localeFirstDayOfWeek; + +// Day of Week +proto$1.weekdays = localeWeekdays; +proto$1.weekdaysMin = localeWeekdaysMin; +proto$1.weekdaysShort = localeWeekdaysShort; +proto$1.weekdaysParse = localeWeekdaysParse; + +proto$1.weekdaysRegex = weekdaysRegex; +proto$1.weekdaysShortRegex = weekdaysShortRegex; +proto$1.weekdaysMinRegex = weekdaysMinRegex; + +// Hours +proto$1.isPM = localeIsPM; +proto$1.meridiem = localeMeridiem; + +function get$1 (format, index, field, setter) { + var locale = getLocale(); + var utc = createUTC().set(setter, index); + return locale[field](utc, format); +} + +function listMonthsImpl (format, index, field) { + if (isNumber(format)) { + index = format; + format = undefined; + } + + format = format || ''; + + if (index != null) { + return get$1(format, index, field, 'month'); + } + + var i; + var out = []; + for (i = 0; i < 12; i++) { + out[i] = get$1(format, i, field, 'month'); + } + return out; +} + +// () +// (5) +// (fmt, 5) +// (fmt) +// (true) +// (true, 5) +// (true, fmt, 5) +// (true, fmt) +function listWeekdaysImpl (localeSorted, format, index, field) { + if (typeof localeSorted === 'boolean') { + if (isNumber(format)) { + index = format; + format = undefined; + } + + format = format || ''; + } else { + format = localeSorted; + index = format; + localeSorted = false; + + if (isNumber(format)) { + index = format; + format = undefined; + } + + format = format || ''; + } + + var locale = getLocale(), + shift = localeSorted ? locale._week.dow : 0; + + if (index != null) { + return get$1(format, (index + shift) % 7, field, 'day'); + } + + var i; + var out = []; + for (i = 0; i < 7; i++) { + out[i] = get$1(format, (i + shift) % 7, field, 'day'); + } + return out; +} + +function listMonths (format, index) { + return listMonthsImpl(format, index, 'months'); +} + +function listMonthsShort (format, index) { + return listMonthsImpl(format, index, 'monthsShort'); +} + +function listWeekdays (localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdays'); +} + +function listWeekdaysShort (localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort'); +} + +function listWeekdaysMin (localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin'); +} + +getSetGlobalLocale('en', { + dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, + ordinal : function (number) { + var b = number % 10, + output = (toInt(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + } +}); + +// Side effect imports +hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale); +hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale); + +var mathAbs = Math.abs; + +function abs () { + var data = this._data; + + this._milliseconds = mathAbs(this._milliseconds); + this._days = mathAbs(this._days); + this._months = mathAbs(this._months); + + data.milliseconds = mathAbs(data.milliseconds); + data.seconds = mathAbs(data.seconds); + data.minutes = mathAbs(data.minutes); + data.hours = mathAbs(data.hours); + data.months = mathAbs(data.months); + data.years = mathAbs(data.years); + + return this; +} + +function addSubtract$1 (duration, input, value, direction) { + var other = createDuration(input, value); + + duration._milliseconds += direction * other._milliseconds; + duration._days += direction * other._days; + duration._months += direction * other._months; + + return duration._bubble(); +} + +// supports only 2.0-style add(1, 's') or add(duration) +function add$1 (input, value) { + return addSubtract$1(this, input, value, 1); +} + +// supports only 2.0-style subtract(1, 's') or subtract(duration) +function subtract$1 (input, value) { + return addSubtract$1(this, input, value, -1); +} + +function absCeil (number) { + if (number < 0) { + return Math.floor(number); + } else { + return Math.ceil(number); + } +} + +function bubble () { + var milliseconds = this._milliseconds; + var days = this._days; + var months = this._months; + var data = this._data; + var seconds, minutes, hours, years, monthsFromDays; + + // if we have a mix of positive and negative values, bubble down first + // check: https://github.com/moment/moment/issues/2166 + if (!((milliseconds >= 0 && days >= 0 && months >= 0) || + (milliseconds <= 0 && days <= 0 && months <= 0))) { + milliseconds += absCeil(monthsToDays(months) + days) * 864e5; + days = 0; + months = 0; + } + + // The following code bubbles up values, see the tests for + // examples of what that means. + data.milliseconds = milliseconds % 1000; + + seconds = absFloor(milliseconds / 1000); + data.seconds = seconds % 60; + + minutes = absFloor(seconds / 60); + data.minutes = minutes % 60; + + hours = absFloor(minutes / 60); + data.hours = hours % 24; + + days += absFloor(hours / 24); + + // convert days to months + monthsFromDays = absFloor(daysToMonths(days)); + months += monthsFromDays; + days -= absCeil(monthsToDays(monthsFromDays)); + + // 12 months -> 1 year + years = absFloor(months / 12); + months %= 12; + + data.days = days; + data.months = months; + data.years = years; + + return this; +} + +function daysToMonths (days) { + // 400 years have 146097 days (taking into account leap year rules) + // 400 years have 12 months === 4800 + return days * 4800 / 146097; +} + +function monthsToDays (months) { + // the reverse of daysToMonths + return months * 146097 / 4800; +} + +function as (units) { + if (!this.isValid()) { + return NaN; + } + var days; + var months; + var milliseconds = this._milliseconds; + + units = normalizeUnits(units); + + if (units === 'month' || units === 'year') { + days = this._days + milliseconds / 864e5; + months = this._months + daysToMonths(days); + return units === 'month' ? months : months / 12; + } else { + // handle milliseconds separately because of floating point math errors (issue #1867) + days = this._days + Math.round(monthsToDays(this._months)); + switch (units) { + case 'week' : return days / 7 + milliseconds / 6048e5; + case 'day' : return days + milliseconds / 864e5; + case 'hour' : return days * 24 + milliseconds / 36e5; + case 'minute' : return days * 1440 + milliseconds / 6e4; + case 'second' : return days * 86400 + milliseconds / 1000; + // Math.floor prevents floating point math errors here + case 'millisecond': return Math.floor(days * 864e5) + milliseconds; + default: throw new Error('Unknown unit ' + units); + } + } +} + +// TODO: Use this.as('ms')? +function valueOf$1 () { + if (!this.isValid()) { + return NaN; + } + return ( + this._milliseconds + + this._days * 864e5 + + (this._months % 12) * 2592e6 + + toInt(this._months / 12) * 31536e6 + ); +} + +function makeAs (alias) { + return function () { + return this.as(alias); + }; +} + +var asMilliseconds = makeAs('ms'); +var asSeconds = makeAs('s'); +var asMinutes = makeAs('m'); +var asHours = makeAs('h'); +var asDays = makeAs('d'); +var asWeeks = makeAs('w'); +var asMonths = makeAs('M'); +var asYears = makeAs('y'); + +function clone$1 () { + return createDuration(this); +} + +function get$2 (units) { + units = normalizeUnits(units); + return this.isValid() ? this[units + 's']() : NaN; +} + +function makeGetter(name) { + return function () { + return this.isValid() ? this._data[name] : NaN; + }; +} + +var milliseconds = makeGetter('milliseconds'); +var seconds = makeGetter('seconds'); +var minutes = makeGetter('minutes'); +var hours = makeGetter('hours'); +var days = makeGetter('days'); +var months = makeGetter('months'); +var years = makeGetter('years'); + +function weeks () { + return absFloor(this.days() / 7); +} + +var round = Math.round; +var thresholds = { + ss: 44, // a few seconds to seconds + s : 45, // seconds to minute + m : 45, // minutes to hour + h : 22, // hours to day + d : 26, // days to month + M : 11 // months to year +}; + +// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize +function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { + return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); +} + +function relativeTime$1 (posNegDuration, withoutSuffix, locale) { + var duration = createDuration(posNegDuration).abs(); + var seconds = round(duration.as('s')); + var minutes = round(duration.as('m')); + var hours = round(duration.as('h')); + var days = round(duration.as('d')); + var months = round(duration.as('M')); + var years = round(duration.as('y')); + + var a = seconds <= thresholds.ss && ['s', seconds] || + seconds < thresholds.s && ['ss', seconds] || + minutes <= 1 && ['m'] || + minutes < thresholds.m && ['mm', minutes] || + hours <= 1 && ['h'] || + hours < thresholds.h && ['hh', hours] || + days <= 1 && ['d'] || + days < thresholds.d && ['dd', days] || + months <= 1 && ['M'] || + months < thresholds.M && ['MM', months] || + years <= 1 && ['y'] || ['yy', years]; + + a[2] = withoutSuffix; + a[3] = +posNegDuration > 0; + a[4] = locale; + return substituteTimeAgo.apply(null, a); +} + +// This function allows you to set the rounding function for relative time strings +function getSetRelativeTimeRounding (roundingFunction) { + if (roundingFunction === undefined) { + return round; + } + if (typeof(roundingFunction) === 'function') { + round = roundingFunction; + return true; + } + return false; +} + +// This function allows you to set a threshold for relative time strings +function getSetRelativeTimeThreshold (threshold, limit) { + if (thresholds[threshold] === undefined) { + return false; + } + if (limit === undefined) { + return thresholds[threshold]; + } + thresholds[threshold] = limit; + if (threshold === 's') { + thresholds.ss = limit - 1; + } + return true; +} + +function humanize (withSuffix) { + if (!this.isValid()) { + return this.localeData().invalidDate(); + } + + var locale = this.localeData(); + var output = relativeTime$1(this, !withSuffix, locale); + + if (withSuffix) { + output = locale.pastFuture(+this, output); + } + + return locale.postformat(output); +} + +var abs$1 = Math.abs; + +function sign(x) { + return ((x > 0) - (x < 0)) || +x; +} + +function toISOString$1() { + // for ISO strings we do not use the normal bubbling rules: + // * milliseconds bubble up until they become hours + // * days do not bubble at all + // * months bubble up until they become years + // This is because there is no context-free conversion between hours and days + // (think of clock changes) + // and also not between days and months (28-31 days per month) + if (!this.isValid()) { + return this.localeData().invalidDate(); + } + + var seconds = abs$1(this._milliseconds) / 1000; + var days = abs$1(this._days); + var months = abs$1(this._months); + var minutes, hours, years; + + // 3600 seconds -> 60 minutes -> 1 hour + minutes = absFloor(seconds / 60); + hours = absFloor(minutes / 60); + seconds %= 60; + minutes %= 60; + + // 12 months -> 1 year + years = absFloor(months / 12); + months %= 12; + + + // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js + var Y = years; + var M = months; + var D = days; + var h = hours; + var m = minutes; + var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : ''; + var total = this.asSeconds(); + + if (!total) { + // this is the same as C#'s (Noda) and python (isodate)... + // but not other JS (goog.date) + return 'P0D'; + } + + var totalSign = total < 0 ? '-' : ''; + var ymSign = sign(this._months) !== sign(total) ? '-' : ''; + var daysSign = sign(this._days) !== sign(total) ? '-' : ''; + var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : ''; + + return totalSign + 'P' + + (Y ? ymSign + Y + 'Y' : '') + + (M ? ymSign + M + 'M' : '') + + (D ? daysSign + D + 'D' : '') + + ((h || m || s) ? 'T' : '') + + (h ? hmsSign + h + 'H' : '') + + (m ? hmsSign + m + 'M' : '') + + (s ? hmsSign + s + 'S' : ''); +} + +var proto$2 = Duration.prototype; + +proto$2.isValid = isValid$1; +proto$2.abs = abs; +proto$2.add = add$1; +proto$2.subtract = subtract$1; +proto$2.as = as; +proto$2.asMilliseconds = asMilliseconds; +proto$2.asSeconds = asSeconds; +proto$2.asMinutes = asMinutes; +proto$2.asHours = asHours; +proto$2.asDays = asDays; +proto$2.asWeeks = asWeeks; +proto$2.asMonths = asMonths; +proto$2.asYears = asYears; +proto$2.valueOf = valueOf$1; +proto$2._bubble = bubble; +proto$2.clone = clone$1; +proto$2.get = get$2; +proto$2.milliseconds = milliseconds; +proto$2.seconds = seconds; +proto$2.minutes = minutes; +proto$2.hours = hours; +proto$2.days = days; +proto$2.weeks = weeks; +proto$2.months = months; +proto$2.years = years; +proto$2.humanize = humanize; +proto$2.toISOString = toISOString$1; +proto$2.toString = toISOString$1; +proto$2.toJSON = toISOString$1; +proto$2.locale = locale; +proto$2.localeData = localeData; + +// Deprecations +proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1); +proto$2.lang = lang; + +// Side effect imports + +// FORMATTING + +addFormatToken('X', 0, 0, 'unix'); +addFormatToken('x', 0, 0, 'valueOf'); + +// PARSING + +addRegexToken('x', matchSigned); +addRegexToken('X', matchTimestamp); +addParseToken('X', function (input, array, config) { + config._d = new Date(parseFloat(input, 10) * 1000); +}); +addParseToken('x', function (input, array, config) { + config._d = new Date(toInt(input)); +}); + +// Side effect imports + + +hooks.version = '2.19.2'; + +setHookCallback(createLocal); + +hooks.fn = proto; +hooks.min = min; +hooks.max = max; +hooks.now = now; +hooks.utc = createUTC; +hooks.unix = createUnix; +hooks.months = listMonths; +hooks.isDate = isDate; +hooks.locale = getSetGlobalLocale; +hooks.invalid = createInvalid; +hooks.duration = createDuration; +hooks.isMoment = isMoment; +hooks.weekdays = listWeekdays; +hooks.parseZone = createInZone; +hooks.localeData = getLocale; +hooks.isDuration = isDuration; +hooks.monthsShort = listMonthsShort; +hooks.weekdaysMin = listWeekdaysMin; +hooks.defineLocale = defineLocale; +hooks.updateLocale = updateLocale; +hooks.locales = listLocales; +hooks.weekdaysShort = listWeekdaysShort; +hooks.normalizeUnits = normalizeUnits; +hooks.relativeTimeRounding = getSetRelativeTimeRounding; +hooks.relativeTimeThreshold = getSetRelativeTimeThreshold; +hooks.calendarFormat = getCalendarFormat; +hooks.prototype = proto; + +return hooks; + +}))); diff --git a/basicsuite/ebike-ui/mostrecent.bson b/basicsuite/ebike-ui/mostrecent.bson new file mode 100644 index 0000000..5e9edea Binary files /dev/null and b/basicsuite/ebike-ui/mostrecent.bson differ diff --git a/basicsuite/ebike-ui/navigation.cpp b/basicsuite/ebike-ui/navigation.cpp new file mode 100644 index 0000000..067636e --- /dev/null +++ b/basicsuite/ebike-ui/navigation.cpp @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +#include "navigation.h" +#include "mapbox.h" + +Navigation::Navigation(MapBox *mapbox, QObject *parent) + : QObject(parent) + , m_mapbox(mapbox) + , m_position(QGeoCoordinate(36.131961, -115.153048), QDateTime::currentDateTime()) + , m_zoomlevel(18) + , m_active(false) + , m_routeDirection(0) + , m_routePosition(m_position.coordinate()) +{ + m_position.setAttribute(QGeoPositionInfo::Direction, 0); +} + +void Navigation::setPosition(const QGeoPositionInfo &position) +{ + if (m_position != position) { + m_position = position; + emit positionChanged(m_position); + } +} + +void Navigation::setCoordinate(const QGeoCoordinate &coordinate) +{ + if (m_position.coordinate() != coordinate) { + m_position.setCoordinate(coordinate); + emit coordinateChanged(m_position.coordinate()); + } +} + +void Navigation::setDirection(qreal direction) +{ + if (qFuzzyCompare(m_position.attribute(QGeoPositionInfo::Direction), direction)) + return; + + m_position.setAttribute(QGeoPositionInfo::Direction, direction); + emit directionChanged(direction); +} + +void Navigation::setZoomLevel(qreal zoomlevel) +{ + if (qFuzzyCompare(m_zoomlevel, zoomlevel)) + return; + + m_zoomlevel = zoomlevel; + emit zoomLevelChanged(m_zoomlevel); +} + +void Navigation::setActive(bool active) +{ + if (m_active == active) + return; + + m_active = active; + emit activeChanged(m_active); +} diff --git a/basicsuite/ebike-ui/navigation.h b/basicsuite/ebike-ui/navigation.h new file mode 100644 index 0000000..6c9533f --- /dev/null +++ b/basicsuite/ebike-ui/navigation.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef NAVIGATION_H +#define NAVIGATION_H + +#include +#include +#include +#include +#include + +#include + +class MapBox; + +class Navigation : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QGeoPositionInfo position READ position WRITE setPosition NOTIFY positionChanged) + Q_PROPERTY(QGeoCoordinate coordinate READ coordinate WRITE setCoordinate NOTIFY coordinateChanged) + Q_PROPERTY(qreal direction READ direction WRITE setDirection NOTIFY directionChanged) + Q_PROPERTY(qreal zoomlevel READ zoomLevel WRITE setZoomLevel NOTIFY zoomLevelChanged) + Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged) + Q_PROPERTY(qreal routeDirection READ routeDirection NOTIFY routeDirectionChanged) + Q_PROPERTY(QGeoCoordinate routePosition READ routePosition NOTIFY routePositionChanged) + +public: + explicit Navigation(MapBox *mapbox, QObject *parent = nullptr); + +public: + // Getters + const QGeoPositionInfo &position() const { return m_position; } + QGeoCoordinate coordinate() const { return m_position.coordinate(); } + qreal direction() const { return m_position.attribute(QGeoPositionInfo::Direction); } + qreal zoomLevel() const { return m_zoomlevel; } + bool active() const { return m_active; } + + qreal routeDirection() const { return m_routeDirection; } + QGeoCoordinate routePosition() const { return m_routePosition; } + + // Setters + void setPosition(const QGeoPositionInfo &position); + void setCoordinate(const QGeoCoordinate &coordinate); + void setDirection(qreal direction); + void setZoomLevel(qreal zoomlevel); + void setActive(bool active); + +signals: + void positionChanged(QGeoPositionInfo position); + void coordinateChanged(QGeoCoordinate coordinate); + void directionChanged(qreal direction); + void zoomLevelChanged(qreal zoomlevel); + void activeChanged(bool active); + + void routeDirectionChanged(qreal routeDirection); + void routePositionChanged(QGeoCoordinate routePosition); + +private: + MapBox *m_mapbox; + QGeoPositionInfo m_position; + qreal m_zoomlevel; + bool m_active; + + qreal m_routeDirection; + QGeoCoordinate m_routePosition; +}; + +#endif // NAVIGATION_H diff --git a/basicsuite/ebike-ui/preview_l.jpg b/basicsuite/ebike-ui/preview_l.jpg new file mode 100644 index 0000000..4cd0851 Binary files /dev/null and b/basicsuite/ebike-ui/preview_l.jpg differ diff --git a/basicsuite/ebike-ui/qml.qrc b/basicsuite/ebike-ui/qml.qrc new file mode 100644 index 0000000..810c477 --- /dev/null +++ b/basicsuite/ebike-ui/qml.qrc @@ -0,0 +1,107 @@ + + + qtquickcontrols2.conf + mainview.qml + NaviPage.qml + StatsPage.qml + MainPage.qml + BikeStyle/Colors.qml + BikeStyle/qmldir + SpeedView.qml + fonts/Montserrat-Medium.ttf + fonts/Montserrat-Bold.ttf + fonts/Montserrat-Light.ttf + fonts/Montserrat-Regular.ttf + StatsBox.qml + BikeStyle/UILayout.qml + NaviBox.qml + LightsBox.qml + ModeBox.qml + ClockView.qml + images/lights_off.png + images/lights_on.png + fonts/Teko-Bold.ttf + fonts/Teko-Light.ttf + fonts/Teko-Medium.ttf + fonts/Teko-Regular.ttf + MusicPlayer.qml + images/map-marker.png + images/trip.png + images/calories.png + images/nextsong.png + images/nextsong_pressed.png + images/play.png + images/play_pressed.png + images/prevsong.png + images/prevsong_pressed.png + images/speed.png + images/battery.png + images/assist.png + ConfigurationDrawer.qml + IconifiedTabButton.qml + fonts/fontawesome-webfont.ttf + GeneralTab.qml + ColumnSpacer.qml + BikeInfoTab.qml + TripChart.qml + images/top_curtain_drag.png + FpsItem.qml + images/spinner.png + images/checkmark.png + images/nav_left.png + images/nav_right.png + images/nav_straight.png + images/small_speedometer_arrow.png + images/map_locate.png + images/map_zoomin.png + images/map_zoomout.png + images/info.png + images/info_selected.png + images/list.png + images/list_selected.png + images/settings.png + images/settings_selected.png + ConfigurationItem.qml + images/curtain_up_arrow.png + NaviButton.qml + images/search.png + images/search_cancel.png + NaviGuide.qml + images/arrow_left.png + images/arrow_right.png + StatsRow.qml + images/fps_icon.png + images/curtain_shadow_handle.png + images/map_btn_shadow.png + images/map_destination.png + images/map_location_arrow.png + NaviTripInfo.qml + moment.js + images/small_speedometer_shadow.png + images/navigation_widget_shadow.png + images/small_input_box_shadow.png + images/nav_bear_l.png + images/nav_bear_r.png + images/nav_hard_l.png + images/nav_hard_r.png + images/nav_light_left.png + images/nav_light_right.png + images/nav_nodir.png + images/nav_uturn_l.png + images/nav_uturn_r.png + ViewTab.qml + images/pause.png + images/pause_pressed.png + images/ok.png + images/warning.png + images/bike-battery.png + images/bike-brakes.png + images/bike-chain.png + images/bike-frontwheel.png + images/bike-gears.png + images/bike-rearwheel.png + images/bike-light.png + ToggleSwitch.qml + images/blue_circle_gps_area.png + + diff --git a/basicsuite/ebike-ui/qtquickcontrols2.conf b/basicsuite/ebike-ui/qtquickcontrols2.conf new file mode 100644 index 0000000..1764b16 --- /dev/null +++ b/basicsuite/ebike-ui/qtquickcontrols2.conf @@ -0,0 +1,15 @@ +; This file can be edited to change the style of the application +; See Styling Qt Quick Controls 2 in the documentation for details: +; http://doc.qt.io/qt-5/qtquickcontrols2-styles.html + +[Controls] +Style=Default + +[Universal] +Theme=Light +;Accent=Steel + +[Material] +Theme=Light +;Accent=BlueGrey +;Primary=BlueGray diff --git a/basicsuite/ebike-ui/socketclient.cpp b/basicsuite/ebike-ui/socketclient.cpp new file mode 100644 index 0000000..d40d268 --- /dev/null +++ b/basicsuite/ebike-ui/socketclient.cpp @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include "socketclient.h" + +SocketClient::SocketClient(QObject *parent) + : QObject(parent) + , m_socket(new QLocalSocket(this)) +{ + // Connect socket signals + connect(m_socket, &QLocalSocket::connected, this, &SocketClient::connected); + connect(m_socket, &QLocalSocket::disconnected, this, &SocketClient::disconnected); + connect(m_socket, &QLocalSocket::readyRead, this, &SocketClient::readyRead); + + // Setup timer to try to reconnect after disconnect + m_connectionTimer.setInterval(5000); + connect(&m_connectionTimer, &QTimer::timeout, this, &SocketClient::reconnect); + connect(m_socket, &QLocalSocket::connected, &m_connectionTimer, &QTimer::stop); + connect(m_socket, &QLocalSocket::disconnected, + &m_connectionTimer, static_cast(&QTimer::start)); + connect(m_socket, static_cast(&QLocalSocket::error), + &m_connectionTimer, static_cast(&QTimer::start)); +} + +void SocketClient::connectToServer(const QString &servername) +{ + m_servername = servername; + reconnect(); +} + +void SocketClient::reconnect() +{ + qDebug("Connecting to server..."); + m_socket->connectToServer(m_servername); +} + +qint64 SocketClient::write(const QByteArray &data) +{ + return m_socket->write(data); +} + +/** + * @brief send a QByteArray to the server + * @param message + * + * Adds the length of the message as a header and sends the message to the server. + */ +void SocketClient::sendToServer(const QByteArray &message) +{ + // Prepend the message length + QByteArray data; + QDataStream stream(&data, QIODevice::WriteOnly); + stream << static_cast(message.size() + 4); + data.append(message); + + write(data); +} + +/** + * @brief send a Json object to the server + * @param message + * + * Sends a QJsonObject object to the server, encoded in Qt's internal binary format. + */ +void SocketClient::sendToServer(const QJsonObject &message) +{ + QJsonDocument doc(message); + sendToServer(doc.toBinaryData()); +} + +/** + * @brief reads incoming data from the server + * + * Parses only message headers and body as QByteArray, but does not care about + * the contents. All complete messages are processed at @see parseMessage. + */ +void SocketClient::readyRead() +{ + m_data += m_socket->readAll(); + + bool messagefound = true; + while (messagefound) { + messagefound = false; + // If we have at least some data + if (m_data.size() >= 4) { + // Extract message size + qint32 messagesize; + QDataStream stream(m_data.left(4)); + stream >> messagesize; + + // If we have enough data for at least one message + if (m_data.size() >= messagesize) { + // Extract actual message + QByteArray message = m_data.mid(4, messagesize - 4); + parseMessage(message); + // Drop necessary amount of bytes + m_data = m_data.mid(messagesize); + messagefound = true; // Try to parse another message + } + } + } +} + +/** + * @brief parse the contents of a QByteArray + * @param message + * + * Contents are parsed from QJsonDocument's binary data. This separation allows + * the format to be changed later on, if need be. + */ +void SocketClient::parseMessage(const QByteArray &message) +{ + // Parse message from raw format + QJsonDocument doc = QJsonDocument::fromBinaryData(message); + emit newMessage(doc.object()); +} diff --git a/basicsuite/ebike-ui/socketclient.h b/basicsuite/ebike-ui/socketclient.h new file mode 100644 index 0000000..dc100a2 --- /dev/null +++ b/basicsuite/ebike-ui/socketclient.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SOCKETCLIENT_H +#define SOCKETCLIENT_H + +#include +#include +#include +#include + +/** + * @brief The SocketClient class + * + * Socket container and message parser for client communications. + */ +class SocketClient : public QObject +{ + Q_OBJECT + +public: + explicit SocketClient(QObject *parent = nullptr); + +public: + QLocalSocket* socket(void) const { return m_socket; } + qint64 write(const QByteArray &data); + void sendToServer(const QByteArray &message); + void sendToServer(const QJsonObject &message); + +private: + void parseMessage(const QByteArray &message); + +signals: + void connected(); + void disconnected(); + + void newMessage(const QJsonObject &message); + +public slots: + void connectToServer(const QString &servername); + +private slots: + void reconnect(); + void readyRead(); + +private: + QLocalSocket *m_socket; + QString m_servername; + QTimer m_connectionTimer; + QByteArray m_data; +}; + +#endif // SOCKETCLIENT_H diff --git a/basicsuite/ebike-ui/suggestionsmodel.cpp b/basicsuite/ebike-ui/suggestionsmodel.cpp new file mode 100644 index 0000000..fa028f0 --- /dev/null +++ b/basicsuite/ebike-ui/suggestionsmodel.cpp @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include + +#include "suggestionsmodel.h" + +#define EBIKE_DEMO_MODE + +static const char mostRecentFilename[] = "mostrecent.bson"; + +SuggestionsModel::SuggestionsModel(QObject *parent) + : QAbstractListModel(parent) +{ + loadMostRecent(); +} + +SuggestionsModel::SuggestionsModel(const QJsonArray &suggestions, QObject *parent) + : QAbstractListModel(parent) + , m_suggestions(suggestions) +{ + loadMostRecent(); +} + +QVariant SuggestionsModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + // Only horizontal header + if (orientation == Qt::Vertical) + return QVariant(); + + if (role == Qt::DisplayRole && section == 0) + return tr("Place"); + + return QAbstractListModel::headerData(section, orientation, role); +} + +int SuggestionsModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return m_suggestions.isEmpty() ? m_mostrecent.size() : m_suggestions.size(); +} + +QVariant SuggestionsModel::data(const QModelIndex &index, int role) const +{ + QJsonObject obj = get(index.row()); + if (role == Qt::DisplayRole) { + return obj.value("place_name").toVariant(); + } else if (role == PlaceNameRole) { + return obj.value("place_name").toVariant(); + } + + return QVariant(); +} + +QHash SuggestionsModel::roleNames() const +{ + QHash roles = QAbstractListModel::roleNames(); + roles[PlaceNameRole] = "placename"; + return roles; +} + +const QJsonObject SuggestionsModel::get(int index) const +{ + return m_suggestions.isEmpty() ? + m_mostrecent[index].toObject() : + m_suggestions[index].toObject(); +} + +void SuggestionsModel::setSuggestions(const QJsonArray &suggestions) +{ + beginResetModel(); + m_suggestions = suggestions; + endResetModel(); + emit emptyChanged(); +} + +void SuggestionsModel::clear() +{ + beginResetModel(); + m_suggestions = QJsonArray(); + endResetModel(); + emit emptyChanged(); +} + +void SuggestionsModel::addToMostRecent(const QJsonObject &place) +{ + Q_UNUSED(place) + // For the demo, do not add new most recent places +#ifndef EBIKE_DEMO_MODE + if (!m_mostrecent.contains(place)) + m_mostrecent.prepend(place); + if (m_mostrecent.size() > 3) + m_mostrecent.pop_back(); + saveMostRecent(); +#endif +} + +void SuggestionsModel::loadMostRecent() +{ + QDir dir(QCoreApplication::applicationDirPath()); + + // Load most recent places + QString mostRecentFilepath = dir.absoluteFilePath(mostRecentFilename); + QFile mostRecentFile(mostRecentFilepath); + if (mostRecentFile.open(QIODevice::ReadOnly)) { + QJsonDocument doc = QJsonDocument::fromBinaryData(mostRecentFile.readAll()); + m_mostrecent = doc.array(); + } +} + +void SuggestionsModel::saveMostRecent() const +{ + QDir dir(QCoreApplication::applicationDirPath()); + + // Load most recent places + QString mostRecentFilepath = dir.absoluteFilePath(mostRecentFilename); + QFile mostRecentFile(mostRecentFilepath); + if (mostRecentFile.open(QIODevice::WriteOnly)) { + QJsonDocument doc(m_mostrecent); + mostRecentFile.write(doc.toBinaryData()); + } +} diff --git a/basicsuite/ebike-ui/suggestionsmodel.h b/basicsuite/ebike-ui/suggestionsmodel.h new file mode 100644 index 0000000..5bf22b5 --- /dev/null +++ b/basicsuite/ebike-ui/suggestionsmodel.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SUGGESTIONSMODEL_H +#define SUGGESTIONSMODEL_H + +#include +#include +#include + +class SuggestionsModel : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY(bool empty READ isEmpty RESET clear NOTIFY emptyChanged) + +public: + explicit SuggestionsModel(QObject *parent = nullptr); + explicit SuggestionsModel(const QJsonArray &suggestions, QObject *parent = nullptr); + enum SuggestionRoles { + PlaceNameRole = Qt::UserRole + 1 + }; + +public: + virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; + virtual int rowCount(const QModelIndex &parent) const; + virtual QVariant data(const QModelIndex &index, int role) const; + virtual QHash roleNames() const; + + Q_INVOKABLE const QJsonObject get(int index) const; + bool isEmpty() const { return m_suggestions.size() == 0; } + + void setSuggestions(const QJsonArray &suggestions); + Q_INVOKABLE void clear(); + + Q_INVOKABLE void addToMostRecent(const QJsonObject &place); + +private: + void loadMostRecent(); + void saveMostRecent() const; + +signals: + void emptyChanged(); + +private: + QJsonArray m_mostrecent; + QJsonArray m_suggestions; +}; + +#endif // SUGGESTIONSMODEL_H diff --git a/basicsuite/ebike-ui/tripdatamodel.cpp b/basicsuite/ebike-ui/tripdatamodel.cpp new file mode 100644 index 0000000..b74605f --- /dev/null +++ b/basicsuite/ebike-ui/tripdatamodel.cpp @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "datastore.h" +#include "tripdatamodel.h" + +#include + +TripDataModel::TripDataModel(DataStore *datastore, QObject *parent) + : QAbstractListModel(parent) + , m_datastore(datastore) + , m_refreshing(false) + , m_saving(false) +{ +} + +int TripDataModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return m_trips.count() + 1; // +1 for current trip +} + +QVariant TripDataModel::data(const QModelIndex &index, int role) const +{ + QJsonObject obj = get(index.row()); + if (role == DurationRole) + return obj.value("duration").toDouble(); // Seconds + else if (role == DistanceRole) + return m_datastore->convertDistance(obj.value("distance").toDouble()); + else if (role == CaloriesRole) + return obj.value("calories").toDouble(); + else if (role == MaxspeedRole) + return m_datastore->convertSpeed(obj.value("maxspeed").toDouble()); + else if (role == AvgspeedRole) + return m_datastore->convertSpeed(obj.value("distance").toDouble() / obj.value("duration").toDouble()); + else if (role == AscentRole) + return obj.value("ascent").toDouble(); + else if (role == StartTimeRole) + return obj.value("starttime").toDouble(); + + return QVariant(); +} + +QHash TripDataModel::roleNames() const +{ + QHash roles = QAbstractListModel::roleNames(); + roles[DurationRole] = "duration"; + roles[DistanceRole] = "distance"; + roles[CaloriesRole] = "calories"; + roles[MaxspeedRole] = "maxspeed"; + roles[AvgspeedRole] = "avgspeed"; + roles[AscentRole] = "ascent"; + roles[StartTimeRole] = "starttime"; + + return roles; +} + +void TripDataModel::setTrips(const QJsonArray &trips) +{ + beginResetModel(); + m_trips = trips; + endResetModel(); + m_refreshing = false; + emit refreshingChanged(m_refreshing); + emit refreshed(); +} + +void TripDataModel::addTrip(const QJsonObject &trip) +{ + // Always append at the beginning of the list, easy to calculate + int newRow = 0; + beginInsertRows(QModelIndex(), newRow, newRow); + m_trips.append(trip); + endInsertRows(); + emit tripDataSaved(newRow); +} + +const QJsonObject TripDataModel::get(int index) const +{ + return index == 0 ? m_current : m_trips.at(m_trips.count() - index).toObject(); +} + +void TripDataModel::refresh() +{ + m_refreshing = true; + emit refreshingChanged(m_refreshing); + m_datastore->getTrips(); +} + +void TripDataModel::endTrip() +{ + m_saving = true; + emit savingChanged(m_saving); + m_datastore->endTrip(); +} + +void TripDataModel::setCurrentTrip(const QJsonObject ¤t) +{ + m_current = current; + QModelIndex currentIndex = index(0); + emit dataChanged(currentIndex, currentIndex); +} diff --git a/basicsuite/ebike-ui/tripdatamodel.h b/basicsuite/ebike-ui/tripdatamodel.h new file mode 100644 index 0000000..56be84e --- /dev/null +++ b/basicsuite/ebike-ui/tripdatamodel.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TRIPDATAMODEL_H +#define TRIPDATAMODEL_H + +#include +#include +#include + +class DataStore; + +class TripDataModel : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY(bool refreshing READ refreshing NOTIFY refreshingChanged) + Q_PROPERTY(bool saving READ saving NOTIFY savingChanged) + +public: + explicit TripDataModel(DataStore *datastore, QObject *parent = nullptr); + enum TripDataRoles { + DurationRole = Qt::UserRole + 1, + DistanceRole, + CaloriesRole, + MaxspeedRole, + AvgspeedRole, + AscentRole, + StartTimeRole + }; + +public: + virtual int rowCount(const QModelIndex &parent) const; + virtual QVariant data(const QModelIndex &index, int role) const; + virtual QHash roleNames() const; + + Q_INVOKABLE const QJsonObject get(int index) const; + + void setTrips(const QJsonArray &trips); + void addTrip(const QJsonObject &trip); + + bool refreshing() const { return m_refreshing; } + bool saving() const { return m_saving; } + +signals: + void refreshed(); + void refreshingChanged(bool refreshing); + void savingChanged(bool saving); + void tripDataSaved(int index); + +public slots: + void refresh(); + void endTrip(); + void setCurrentTrip(const QJsonObject ¤t); + +private: + DataStore *m_datastore; + QJsonArray m_trips; + QJsonObject m_current; + bool m_refreshing; + bool m_saving; +}; + +#endif // TRIPDATAMODEL_H diff --git a/basicsuite/shared/main.cpp b/basicsuite/shared/main.cpp index 00ceab1..6fba612 100644 --- a/basicsuite/shared/main.cpp +++ b/basicsuite/shared/main.cpp @@ -90,6 +90,17 @@ int main(int argc, char **argv) QFontDatabase::addApplicationFont(":/fonts/TitilliumWeb-Bold.ttf"); QFontDatabase::addApplicationFont(":/fonts/TitilliumWeb-Black.ttf"); + //For eBike demo + QFontDatabase::addApplicationFont(":/fonts/Montserrat-Bold.ttf"); + QFontDatabase::addApplicationFont(":/fonts/Montserrat-Light.ttf"); + QFontDatabase::addApplicationFont(":/fonts/Montserrat-Medium.ttf"); + QFontDatabase::addApplicationFont(":/fonts/Montserrat-Regular.ttf"); + QFontDatabase::addApplicationFont(":/fonts/Teko-Bold.ttf"); + QFontDatabase::addApplicationFont(":/fonts/Teko-Light.ttf"); + QFontDatabase::addApplicationFont(":/fonts/Teko-Medium.ttf"); + QFontDatabase::addApplicationFont(":/fonts/Teko-Regular.ttf"); + QFontDatabase::addApplicationFont(":/fonts/fontawesome-webfont.ttf"); + QString path = app.applicationDirPath(); QPalette pal; -- cgit v1.2.3 From 783ca9418ab50499f0ca02131bcf42bdfe5beda9 Mon Sep 17 00:00:00 2001 From: Mikko Gronoff Date: Wed, 9 May 2018 06:19:32 +0300 Subject: Doc: bump version to 5.9.6 Change-Id: I9a277b95784cb49f35da68f48433805bd584b6f5 Reviewed-by: Samuli Piippo --- doc/b2qt-demos.qdoc | 4 ++-- doc/b2qt-demos.qdocconf | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/b2qt-demos.qdoc b/doc/b2qt-demos.qdoc index cb7a039..7ea263e 100644 --- a/doc/b2qt-demos.qdoc +++ b/doc/b2qt-demos.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of Qt for Device Creation. @@ -50,7 +50,7 @@ /*! \page index.html - \title Qt 5.9.5 for Device Creation Examples and Demos + \title Qt 5.9.6 for Device Creation Examples and Demos \SDK has a number of examples and demos. These are included in the \B2Q images, available in the launcher that is run by default at diff --git a/doc/b2qt-demos.qdocconf b/doc/b2qt-demos.qdocconf index c079e0e..a18902b 100644 --- a/doc/b2qt-demos.qdocconf +++ b/doc/b2qt-demos.qdocconf @@ -5,8 +5,8 @@ outputencoding = UTF-8 sourceencoding = UTF-8 project = QtforDeviceCreationDemos -description = Qt 5.9.5 for Device Creation Examples and Demos -version = 5.9.5 +description = Qt 5.9.6 for Device Creation Examples and Demos +version = 5.9.6 sourcedirs = . imagedirs += images @@ -21,9 +21,9 @@ exampledirs = .. qhp.projects = QtforDeviceCreationDemos qhp.QtforDeviceCreationDemos.file = b2qt-demos.qhp -qhp.QtforDeviceCreationDemos.namespace = org.qt-project.b2qt-demos.595 +qhp.QtforDeviceCreationDemos.namespace = org.qt-project.b2qt-demos.596 qhp.QtforDeviceCreationDemos.virtualFolder = b2qt-demos -qhp.QtforDeviceCreationDemos.indexTitle = Qt 5.9.5 for Device Creation Examples and Demos +qhp.QtforDeviceCreationDemos.indexTitle = Qt 5.9.6 for Device Creation Examples and Demos qhp.QtforDeviceCreationDemos.indexRoot = qhp.QtforDeviceCreationDemos.subprojects = demos @@ -35,4 +35,4 @@ manifestmeta.b2qt.names = "QtforDeviceCreationDemos/*" macro.B2Q = "Boot to Qt" macro.SDK = "Qt for Device Creation" -navigation.landingpage = "Qt 5.9.5 for Device Creation Examples and Demos" +navigation.landingpage = "Qt 5.9.6 for Device Creation Examples and Demos" -- cgit v1.2.3 From 6b5a6d07b7520dbdda5ffc5b7eb6f859024889f6 Mon Sep 17 00:00:00 2001 From: Sami Nurmenniemi Date: Fri, 18 May 2018 14:38:07 +0300 Subject: Fix paths for demos.xml Task-number: QTBUG-67917 Change-Id: Ibb1b64aaa110a62f2b28dee6fa21f3bc665e364f Reviewed-by: Mikko Gronoff --- basicsuite/demos.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/basicsuite/demos.xml b/basicsuite/demos.xml index 4b7c3e7..91b7ad9 100644 --- a/basicsuite/demos.xml +++ b/basicsuite/demos.xml @@ -93,7 +93,7 @@ Qt for Device Creation comes with Qt Virtual Keyboard - a framework that consist - + An E-bike instrument cluster concept designed and implemented by Qt. @@ -101,7 +101,7 @@ The entire concept is a testament that Qt brings the HMI designers and Software - + The gallery example is a simple application with a drawer menu that contains all the Qt Quick Controls 2. -- cgit v1.2.3 From 28e9fdf3151b0ae971f75e9386a6ff1e3c370bf6 Mon Sep 17 00:00:00 2001 From: Sami Nurmenniemi Date: Fri, 18 May 2018 16:03:30 +0300 Subject: Fix Media Player demo color definitions Task-number: QTBUG-62791 Change-Id: I2bd15e2e873aa7343a072b846918296e7cbce205 Reviewed-by: Mikko Gronoff --- basicsuite/mediaplayer/EffectSelectionPanel.qml | 2 +- basicsuite/mediaplayer/FileBrowser.qml | 4 ++-- basicsuite/mediaplayer/ImageButton.qml | 3 ++- basicsuite/mediaplayer/MetadataView.qml | 2 +- basicsuite/mediaplayer/UrlBar.qml | 2 +- basicsuite/mediaplayer/VolumeControl.qml | 6 ++++-- 6 files changed, 11 insertions(+), 8 deletions(-) diff --git a/basicsuite/mediaplayer/EffectSelectionPanel.qml b/basicsuite/mediaplayer/EffectSelectionPanel.qml index 12c8a42..4daded0 100644 --- a/basicsuite/mediaplayer/EffectSelectionPanel.qml +++ b/basicsuite/mediaplayer/EffectSelectionPanel.qml @@ -159,7 +159,7 @@ Rectangle { width: parent.width property bool isSelected: list.currentIndex == index Text { - color: parent.isSelected ? defaultGreen : "white" + color: parent.isSelected ? Settings.primaryGreen : "white" text: name anchors.centerIn: parent font.pixelSize: 20 diff --git a/basicsuite/mediaplayer/FileBrowser.qml b/basicsuite/mediaplayer/FileBrowser.qml index 04e821a..aae608f 100644 --- a/basicsuite/mediaplayer/FileBrowser.qml +++ b/basicsuite/mediaplayer/FileBrowser.qml @@ -113,7 +113,7 @@ Item { text: fileName font.pixelSize: parent.height * .1 font.family: appFont - color: view.currentIndex === index ? defaultGreen : "white" + color: view.currentIndex === index ? Settings.primaryGreen : "white" elide: Text.ElideRight } @@ -226,7 +226,7 @@ Item { width: parent.width anchors.bottom: parent.bottom height: 2 - color: defaultGrey + color: Settings.primaryGrey } } diff --git a/basicsuite/mediaplayer/ImageButton.qml b/basicsuite/mediaplayer/ImageButton.qml index 4e26fc1..982cc49 100644 --- a/basicsuite/mediaplayer/ImageButton.qml +++ b/basicsuite/mediaplayer/ImageButton.qml @@ -50,6 +50,7 @@ import QtQuick 2.0 import QtGraphicalEffects 1.0 +import "settings.js" as Settings Item { id: root @@ -80,7 +81,7 @@ Item { id: glowEffect anchors.fill: image source: image - color: pressed ? "#22000000" : checked ? defaultGreen : "white" + color: pressed ? "#22000000" : checked ? Settings.primaryGreen : "white" visible: checked || hover || pressed } diff --git a/basicsuite/mediaplayer/MetadataView.qml b/basicsuite/mediaplayer/MetadataView.qml index a995050..d6f45d8 100644 --- a/basicsuite/mediaplayer/MetadataView.qml +++ b/basicsuite/mediaplayer/MetadataView.qml @@ -68,7 +68,7 @@ Rectangle { opacity: 0.9 anchors.centerIn: parent anchors.verticalCenterOffset: -50 - border.color: defaultGrey + border.color: Settings.primaryGrey border.width: 2 Column { diff --git a/basicsuite/mediaplayer/UrlBar.qml b/basicsuite/mediaplayer/UrlBar.qml index ca69f69..80a9259 100644 --- a/basicsuite/mediaplayer/UrlBar.qml +++ b/basicsuite/mediaplayer/UrlBar.qml @@ -107,7 +107,7 @@ Rectangle { anchors.verticalCenter: urlBar.verticalCenter height: 70 width: 70 - color: defaultGrey + color: Settings.primaryGrey MouseArea { anchors.fill: parent onClicked: { urlInput.text = ""; urlInput.paste(); } diff --git a/basicsuite/mediaplayer/VolumeControl.qml b/basicsuite/mediaplayer/VolumeControl.qml index c1f3dce..3a83491 100644 --- a/basicsuite/mediaplayer/VolumeControl.qml +++ b/basicsuite/mediaplayer/VolumeControl.qml @@ -51,6 +51,8 @@ import QtQuick 2.0 import QtDeviceUtilities.QtButtonImageProvider 1.0 import QtQuick.Controls 2.2 +import "settings.js" as Settings + Item { id: root width: parent.width * 0.1 @@ -138,7 +140,7 @@ Item { Rectangle{ height: volumeSlider.visualPosition * parent.height width: parent.width - color: defaultGrey + color: Settings.primaryGrey radius: 2 } } @@ -148,7 +150,7 @@ Item { width: sliderBackground.width * 7 height: width radius: height * 0.5 - color: defaultGreen + color: Settings.primaryGreen } } -- cgit v1.2.3 From 6ed3d300c256a0b75c5cca1f57263f064bf31e42 Mon Sep 17 00:00:00 2001 From: Sami Nurmenniemi Date: Mon, 21 May 2018 11:44:05 +0300 Subject: Temporarily disable e-bike from the basicsuite demo set Change-Id: Ia75480ce0624921683459cba68b1efaedbd61cfb Reviewed-by: Mikko Gronoff --- basicsuite/demos.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/basicsuite/demos.xml b/basicsuite/demos.xml index 91b7ad9..2c79f1a 100644 --- a/basicsuite/demos.xml +++ b/basicsuite/demos.xml @@ -93,6 +93,7 @@ Qt for Device Creation comes with Qt Virtual Keyboard - a framework that consist + -- cgit v1.2.3 From a70868f7bf3c2d44bd7b190fb9c2ad0c38849646 Mon Sep 17 00:00:00 2001 From: Sami Nurmenniemi Date: Tue, 22 May 2018 11:57:28 +0300 Subject: Enable ebike demo Added datacollector, which is generates mock data to the demo. It needs to be configured to run as a service or manually started before running the demo. Without running datacollector, the demo does not show any changing data. Task-number: QTBUG-67917 Change-Id: Ia113b76b5eb024353051b93d9d518211ee2cd601 Reviewed-by: Teemu Holappa --- basicsuite/basicsuite.pro | 6 + basicsuite/datacollector/abstractdatasource.cpp | 42 ++++ basicsuite/datacollector/abstractdatasource.h | 71 +++++++ basicsuite/datacollector/datacollector.pro | 50 +++++ basicsuite/datacollector/main.cpp | 63 ++++++ basicsuite/datacollector/mockdatasource.cpp | 236 ++++++++++++++++++++++ basicsuite/datacollector/mockdatasource.h | 90 +++++++++ basicsuite/datacollector/socketclient.cpp | 89 +++++++++ basicsuite/datacollector/socketclient.h | 72 +++++++ basicsuite/datacollector/socketserver.cpp | 94 +++++++++ basicsuite/datacollector/socketserver.h | 69 +++++++ basicsuite/datacollector/tripdata.cpp | 253 ++++++++++++++++++++++++ basicsuite/datacollector/tripdata.h | 115 +++++++++++ basicsuite/datacollector/unixsignalhandler.cpp | 149 ++++++++++++++ basicsuite/datacollector/unixsignalhandler.h | 77 ++++++++ basicsuite/demos.xml | 2 - basicsuite/ebike-ui/datamodelplugin/plugin.cpp | 3 + 17 files changed, 1479 insertions(+), 2 deletions(-) create mode 100644 basicsuite/datacollector/abstractdatasource.cpp create mode 100644 basicsuite/datacollector/abstractdatasource.h create mode 100644 basicsuite/datacollector/datacollector.pro create mode 100644 basicsuite/datacollector/main.cpp create mode 100644 basicsuite/datacollector/mockdatasource.cpp create mode 100644 basicsuite/datacollector/mockdatasource.h create mode 100644 basicsuite/datacollector/socketclient.cpp create mode 100644 basicsuite/datacollector/socketclient.h create mode 100644 basicsuite/datacollector/socketserver.cpp create mode 100644 basicsuite/datacollector/socketserver.h create mode 100644 basicsuite/datacollector/tripdata.cpp create mode 100644 basicsuite/datacollector/tripdata.h create mode 100644 basicsuite/datacollector/unixsignalhandler.cpp create mode 100644 basicsuite/datacollector/unixsignalhandler.h diff --git a/basicsuite/basicsuite.pro b/basicsuite/basicsuite.pro index b943f4c..e64894b 100644 --- a/basicsuite/basicsuite.pro +++ b/basicsuite/basicsuite.pro @@ -9,3 +9,9 @@ qtHaveModule(multimedia) { SUBDIRS += \ camera } + +qtHaveModule(charts) { + SUBDIRS += \ + ebike-ui \ + datacollector +} diff --git a/basicsuite/datacollector/abstractdatasource.cpp b/basicsuite/datacollector/abstractdatasource.cpp new file mode 100644 index 0000000..e7e7aa3 --- /dev/null +++ b/basicsuite/datacollector/abstractdatasource.cpp @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "abstractdatasource.h" + +AbstractDataSource::AbstractDataSource(QObject *parent) + : QObject(parent) +{ +} diff --git a/basicsuite/datacollector/abstractdatasource.h b/basicsuite/datacollector/abstractdatasource.h new file mode 100644 index 0000000..3fc0e1b --- /dev/null +++ b/basicsuite/datacollector/abstractdatasource.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ABSTRACTDATASOURCE_H +#define ABSTRACTDATASOURCE_H + +#include +#include + +class AbstractDataSource : public QObject +{ + Q_OBJECT + +public: + explicit AbstractDataSource(QObject *parent = nullptr); + virtual ~AbstractDataSource() {} + +public: + virtual void setSpeed(double speed)=0; + virtual void setTopSpeed(double topSpeed)=0; + virtual void setAverageSpeed(double averageSpeed)=0; + virtual void setLifetime(double lifetime)=0; + virtual void setOdometer(double odometer)=0; + virtual void setCalories(double calories)=0; + virtual void setBatteryLevel(int batteryLevel)=0; + virtual void setAssistDistance(int assistdistance)=0; + virtual void setAssistPower(int assistpower)=0; + virtual void setCurrentTrip(const QJsonObject ¤t)=0; + +signals: + void dataUpdate(const QJsonObject &update); + +public slots: + virtual void parseMessage(const QJsonObject &message)=0; + virtual void shutdown()=0; +}; + +#endif // ABSTRACTDATASOURCE_H diff --git a/basicsuite/datacollector/datacollector.pro b/basicsuite/datacollector/datacollector.pro new file mode 100644 index 0000000..a01e690 --- /dev/null +++ b/basicsuite/datacollector/datacollector.pro @@ -0,0 +1,50 @@ +QT -= gui +QT += network + +CONFIG += c++11 console +CONFIG -= app_bundle + +QMAKE_CXXFLAGS += -Os + +if(linux*imx7*g++) { + message("Building for IMX7") + + #Use FLTO for better size, other for better speed + #(both needs to be used with proper Qt libs) + + if(linux-ffopt-imx7-g++) { + } + else { + DEFINES += USE_FLTO + } + + contains(DEFINES,USE_FLTO) { + message("Building with FLTO") + QMAKE_CXXFLAGS += -flto + QMAKE_LFLAGS += -flto + } else { + message("Building with Sections Optimization") + QMAKE_CXXFLAGS += -ffunction-sections -fdata-sections + QMAKE_LFLAGS += -Wl,--gc-sections + #QMAKE_LFLAGS += -Wl,--print-gc-sections + } +} + +SOURCES += main.cpp \ + socketserver.cpp \ + socketclient.cpp \ + abstractdatasource.cpp \ + mockdatasource.cpp \ + tripdata.cpp \ + unixsignalhandler.cpp + +HEADERS += \ + socketserver.h \ + socketclient.h \ + abstractdatasource.h \ + mockdatasource.h \ + tripdata.h \ + unixsignalhandler.h + +target.path += /data/user/qt/$$TARGET +INSTALLS += target diff --git a/basicsuite/datacollector/main.cpp b/basicsuite/datacollector/main.cpp new file mode 100644 index 0000000..438abbb --- /dev/null +++ b/basicsuite/datacollector/main.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "socketserver.h" +#include "mockdatasource.h" +#include "unixsignalhandler.h" + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + + SocketServer* server = new SocketServer(&app); + AbstractDataSource* ds = new MockDataSource(&app); + UnixSignalHandler* handler = new UnixSignalHandler(&app); + + QObject::connect(ds, &AbstractDataSource::dataUpdate, + server, static_cast(&SocketServer::sendToClients)); + QObject::connect(server, &SocketServer::clientMessage, + ds, &AbstractDataSource::parseMessage); + QObject::connect(handler, &UnixSignalHandler::sigInt, + ds, &AbstractDataSource::shutdown); + QObject::connect(handler, &UnixSignalHandler::sigInt, + &app, &QCoreApplication::quit); + + UnixSignalHandler::setupSignalHandlers(); + + return app.exec(); +} diff --git a/basicsuite/datacollector/mockdatasource.cpp b/basicsuite/datacollector/mockdatasource.cpp new file mode 100644 index 0000000..1932ce3 --- /dev/null +++ b/basicsuite/datacollector/mockdatasource.cpp @@ -0,0 +1,236 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "mockdatasource.h" + +static const char currentTripFilename[] = "currenttrip.bson"; +static const char tripDataFilename[] = "tripdata.bson"; +static const char statisticsFilename[] = "stats.bson"; + +MockDataSource::MockDataSource(QObject *parent) + : AbstractDataSource(parent) +{ + connect(&m_updateTimer, &QTimer::timeout, this, &MockDataSource::generateData); + + QDir dir(QCoreApplication::applicationDirPath()); + + // Load current status + m_dataFile = dir.absoluteFilePath(statisticsFilename); + QFile dataFile(m_dataFile); + if (dataFile.open(QIODevice::ReadOnly)) { + QJsonDocument doc = QJsonDocument::fromBinaryData(dataFile.readAll()); + m_data = doc.object(); + m_lifetime = m_data.value("lifetime").toDouble(); + } else { + // Set some default values in case data file did not exist + m_data.insert("speed", 0.0); + m_data.insert("topspeed", 0.0); + m_data.insert("odometer", 0.0); + m_data.insert("batterylevel", 100); + m_lifetime = 0.0; + } + + // Try to load current trip data as well as recorded trip(s) + m_currentFile = dir.absoluteFilePath(currentTripFilename); + m_current.load(m_currentFile); + m_tripsFile = dir.absoluteFilePath(tripDataFilename); + m_trips.load(m_tripsFile); + + m_updateTimer.start(100); + m_elapsedTimer.start(); + + // Generate the list of static trips to be shown on reset + m_resettrips << TripData(2100, 6800, 225, 6.944, 3.2, 1515008400.0) // 3.1.2018 11:40 + << TripData(2700, 10700, 300, 8.333, 2.5, 1515122400.0) // 4.1.2018 19:20 + << TripData(3900, 13700, 370, 6.944, 5, 1515197100.0) // 5.1.2018 16:05 + << TripData(1500, 3300, 150, 6.944, 4.7, 1515260100.0) // 6.1.2018 9:35 + << TripData(4500, 15800, 450, 5.556, 3.2, 1515359700.0); // 7.1.2018 13:15 +} + +void MockDataSource::shutdown() +{ + m_current.save(m_currentFile); + m_trips.save(m_tripsFile); +} + +void MockDataSource::setSpeed(double speed) +{ + updateOne("speed", speed); +} + +void MockDataSource::setTopSpeed(double topspeed) +{ + updateOne("topspeed", topspeed); +} + +void MockDataSource::setAverageSpeed(double averagespeed) +{ + updateOne("averagespeed", averagespeed); +} + +void MockDataSource::setLifetime(double lifetime) +{ + updateOne("lifetime", lifetime); +} + +void MockDataSource::setOdometer(double odometer) +{ + updateOne("odometer", odometer); +} + +void MockDataSource::setCalories(double calories) +{ + updateOne("calories", calories); +} + +void MockDataSource::setBatteryLevel(int batterylevel) +{ + updateOne("batterylevel", batterylevel); +} + +void MockDataSource::setAssistDistance(int assistdistance) +{ + updateOne("assistdistance", assistdistance); +} + +void MockDataSource::setAssistPower(int assistpower) +{ + updateOne("assistpower", assistpower); +} + +void MockDataSource::setCurrentTrip(const QJsonObject ¤t) +{ + emit dataUpdate(QJsonObject{{"method", "currenttrip"}, {"currenttrip", current}}); +} + +void MockDataSource::updateOne(const QString &key, const QJsonValue &value) +{ + m_data.insert(key, value); + emit dataUpdate(QJsonObject{{"method", "updateone"}, {"key", key}, {"value", value}}); +} + +void MockDataSource::generateData() +{ + static int spd = 1; + static int btr = 101; + + double x = static_cast(spd) / 500; + double speed = 4.5 * (1.5 + (0.75 * sin(2 * M_PI * x) + 0.5 * sin(6 * M_PI * x - M_PI_2))) - 1.5; + double dist = speed / 10; // 10 times per second + double elapsed = static_cast(m_elapsedTimer.elapsed()) / 1000.0; + + setAssistPower(speed * 9.5); + setSpeed(speed); + if (speed > m_data.value("topspeed").toDouble()) + setTopSpeed(speed); + setAverageSpeed(m_data.value("odometer").toDouble() / (m_lifetime + elapsed)); + setOdometer(m_data.value("odometer").toDouble() + dist); + setLifetime(m_lifetime + elapsed); + + // Update trip data + if (speed > m_current.maxSpeed()) + m_current.setMaxSpeed(speed); + m_current.addDistance(dist); + m_current.addDuration(0.1); + m_current.addCalories(0.01); + + setCurrentTrip(m_current); + + if (spd % 50 == 0) { + btr -= 1; + setBatteryLevel(btr); + setAssistDistance(500 * btr); + if (btr == 0) + btr = 100; + } + + // Save the current trip and statistics files every 10 seconds + if (spd % 100 == 0) { + m_current.save(m_currentFile); + QFile dataFile(m_dataFile); + if (dataFile.open(QIODevice::WriteOnly)) { + QJsonDocument doc(m_data); + dataFile.write(doc.toBinaryData()); + } + } + + spd++; +} + +void MockDataSource::parseMessage(const QJsonObject &message) +{ + QString method = message.value("method").toString(); + + if (method == "set") { + m_data.insert(message.value("key").toString(), message.value("value")); + } else if (method == "getall") { + QJsonArray values; + // Iterate over all data + QJsonObject::ConstIterator it = m_data.constBegin(); + while (it != m_data.constEnd()) { + values.append(QJsonObject{{"key", it.key()}, {"value", it.value()}}); + ++it; + } + + emit dataUpdate(QJsonObject{{"method", "updatemany"}, {"values", values}}); + setCurrentTrip(m_current); + } else if (method == "gettrips") { + emit dataUpdate(QJsonObject{{"method", "trips"}, {"trips", m_trips.toJsonArray()}}); + } else if (method == "endtrip") { + // Append current trip to list of trips and send to frontend + m_trips.append(m_current); + emit dataUpdate(QJsonObject{{"method", "trip"}, {"trip", m_current.toJsonObject()}}); + // Then clear it and its save file + m_current.clear(); + m_current.setStartTime(); + QFile::remove(m_currentFile); + // Send update of an empty trip to frontend + setCurrentTrip(m_current); + // Also save current trip list to file (in case of a crash) + m_trips.save(m_tripsFile); + } else if (method == "reset") { + // Demo only method, to reset trip history + m_trips = m_resettrips; + emit dataUpdate(QJsonObject{{"method", "reset"}}); + emit dataUpdate(QJsonObject{{"method", "trips"}, {"trips", m_trips.toJsonArray()}}); + } +} diff --git a/basicsuite/datacollector/mockdatasource.h b/basicsuite/datacollector/mockdatasource.h new file mode 100644 index 0000000..fe82e19 --- /dev/null +++ b/basicsuite/datacollector/mockdatasource.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MOCKDATASOURCE_H +#define MOCKDATASOURCE_H + +#include +#include +#include +#include "abstractdatasource.h" +#include "tripdata.h" + +class MockDataSource: public AbstractDataSource +{ + Q_OBJECT + +public: + explicit MockDataSource(QObject *parent = nullptr); + +public: + void setSpeed(double speed); + void setTopSpeed(double topSpeed); + void setAverageSpeed(double averageSpeed); + void setLifetime(double lifetime); + void setOdometer(double odometer); + void setTrip(double trip); + void setCalories(double calories); + void setBatteryLevel(int batteryLevel); + void setAssistDistance(int assistdistance); + void setAssistPower(int assistpower); + void setCurrentTrip(const QJsonObject ¤t); + +public slots: + void parseMessage(const QJsonObject &message); + void shutdown(); + +private: + void updateOne(const QString &key, const QJsonValue &value); + +private slots: + void generateData(); + +private: + QTimer m_updateTimer; + QElapsedTimer m_elapsedTimer; + double m_lifetime; + + QJsonObject m_data; + QString m_dataFile; + TripData m_current; + Trips m_trips; + Trips m_resettrips; + QString m_currentFile; + QString m_tripsFile; +}; + +#endif // MOCKDATASOURCE_H diff --git a/basicsuite/datacollector/socketclient.cpp b/basicsuite/datacollector/socketclient.cpp new file mode 100644 index 0000000..a17f3dc --- /dev/null +++ b/basicsuite/datacollector/socketclient.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +#include "socketclient.h" + +SocketClient::SocketClient(QLocalSocket *socket, QObject *parent) + : QObject(parent) + , m_socket(socket) +{ + // Connect socket signals + connect(m_socket, &QLocalSocket::connected, this, &SocketClient::connected); + connect(m_socket, &QLocalSocket::disconnected, this, &SocketClient::disconnected); + connect(m_socket, &QLocalSocket::readyRead, this, &SocketClient::readyRead); +} + +qint64 SocketClient::write(const QByteArray &data) { + return m_socket->write(data); +} + +void SocketClient::readyRead() { + m_data += m_socket->readAll(); + + bool messagefound = true; + while (messagefound) { + messagefound = false; + // If we have at least some data + if (m_data.size() >= 4) { + // Extract message size + qint32 messagesize; + QDataStream stream(m_data.left(4)); + stream >> messagesize; + + // If we have enough data for at least one message + if (m_data.size() >= messagesize) { + // Extract actual message + QByteArray message = m_data.mid(4, messagesize - 4); + parseMessage(message); + // Drop necessary amount of bytes + m_data = m_data.mid(messagesize); + messagefound = true; // Try to parse another message + } + } + } +} + +void SocketClient::parseMessage(const QByteArray &message) { + // Parse message from raw format + QJsonDocument doc = QJsonDocument::fromBinaryData(message); + QJsonObject obj = doc.object(); + + emit clientMessage(obj); +} diff --git a/basicsuite/datacollector/socketclient.h b/basicsuite/datacollector/socketclient.h new file mode 100644 index 0000000..c489fd5 --- /dev/null +++ b/basicsuite/datacollector/socketclient.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SOCKETCLIENT_H +#define SOCKETCLIENT_H + +#include +#include + +class SocketClient : public QObject +{ + Q_OBJECT + +public: + explicit SocketClient(QLocalSocket *socket, QObject *parent = nullptr); + +public: + QLocalSocket *socket(void) const { return m_socket; } + qint64 write(const QByteArray& data); + +private: + void parseMessage(const QByteArray& message); + +signals: + void connected(); + void disconnected(); + void clientMessage(const QJsonObject &message); + +public slots: + +private slots: + void readyRead(); + +private: + QLocalSocket *m_socket; + QByteArray m_data; +}; + +#endif // SOCKETCLIENT_H diff --git a/basicsuite/datacollector/socketserver.cpp b/basicsuite/datacollector/socketserver.cpp new file mode 100644 index 0000000..9391316 --- /dev/null +++ b/basicsuite/datacollector/socketserver.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +#include "socketserver.h" +#include "socketclient.h" + +SocketServer::SocketServer(QObject *parent) + : QObject(parent) + , m_server(new QLocalServer(this)) +{ + connect(m_server, &QLocalServer::newConnection, this, &SocketServer::processConnected); + QLocalServer::removeServer("datasocket"); + m_server->listen("datasocket"); +} + +void SocketServer::processConnected(void) { + while (m_server->hasPendingConnections()) { + QLocalSocket* socket = m_server->nextPendingConnection(); + qDebug() << "Client connected" << socket; + if (socket) { + SocketClient *client = new SocketClient(socket, this); + connect(client, &SocketClient::disconnected, this, &SocketServer::processDisconnected); + connect(client, &SocketClient::clientMessage, this, &SocketServer::clientMessage); + m_clients.append(client); + } + } +} + +void SocketServer::processDisconnected(void) { + SocketClient *client = qobject_cast(sender()); + qDebug() << "Client disconnected" << client->socket(); + m_clients.removeOne(client); + client->deleteLater(); +} + +void SocketServer::sendToClients(const QByteArray &message) { + // Prepend the message length + QByteArray data; + QDataStream stream(&data, QIODevice::WriteOnly); + stream << static_cast(message.size() + 4); + data.append(message); + + foreach (SocketClient *client, m_clients) { + client->write(data); + } +} + +/** + * @brief sendToClients + * @param message + * + * Converts a JSON object to its binary representation and sends it to all clients + */ +void SocketServer::sendToClients(const QJsonObject &message) { + QJsonDocument doc(message); + sendToClients(doc.toBinaryData()); +} diff --git a/basicsuite/datacollector/socketserver.h b/basicsuite/datacollector/socketserver.h new file mode 100644 index 0000000..e48232c --- /dev/null +++ b/basicsuite/datacollector/socketserver.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SOCKETSERVER_H +#define SOCKETSERVER_H + +#include +#include + +class QLocalServer; +class SocketClient; + +class SocketServer: public QObject +{ + Q_OBJECT + +public: + explicit SocketServer(QObject *parent = nullptr); + +signals: + void clientMessage(const QJsonObject &message); + +public slots: + void sendToClients(const QByteArray &message); + void sendToClients(const QJsonObject &message); + +private slots: + void processConnected(); + void processDisconnected(); + +private: + QLocalServer *m_server; + QList m_clients; +}; + +#endif // SOCKETSERVER_H diff --git a/basicsuite/datacollector/tripdata.cpp b/basicsuite/datacollector/tripdata.cpp new file mode 100644 index 0000000..7ce5590 --- /dev/null +++ b/basicsuite/datacollector/tripdata.cpp @@ -0,0 +1,253 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include + +#include "tripdata.h" + +TripData::TripData() + : m_duration(0.0) + , m_distance(0.0) + , m_calories(0.0) + , m_maxspeed(0.0) + , m_ascent(0.0) + , m_starttime(static_cast(QDateTime::currentMSecsSinceEpoch()) / 1000.0) +{ +} + +TripData::TripData(double duration, double distance, double calories, + double maxspeed, double ascent, double starttime) + : m_duration(duration) + , m_distance(distance) + , m_calories(calories) + , m_maxspeed(maxspeed) + , m_ascent(ascent) + , m_starttime(starttime) +{ +} + +TripData::TripData(const QJsonObject &data) + : m_duration(data.value("duration").toDouble()) + , m_distance(data.value("distance").toDouble()) + , m_calories(data.value("calories").toDouble()) + , m_maxspeed(data.value("maxspeed").toDouble()) + , m_ascent(data.value("ascent").toDouble()) + , m_starttime(data.value("starttime").toDouble()) +{ +} + +bool TripData::load(const QString &filename) +{ + QFile jsonfile(filename); + if (jsonfile.open(QIODevice::ReadOnly)) { + QJsonDocument doc = QJsonDocument::fromBinaryData(jsonfile.readAll()); + QJsonObject data = doc.object(); + + m_duration = data.value("duration").toDouble(); + m_distance = data.value("distance").toDouble(); + m_calories = data.value("calories").toDouble(); + m_maxspeed = data.value("maxspeed").toDouble(); + m_ascent = data.value("ascent").toDouble(); + m_starttime = data.value("starttime").toDouble(); + + return true; + } + return false; +} + +void TripData::save(const QString &filename) const +{ + QFile jsonfile(filename); + if (jsonfile.open(QIODevice::WriteOnly)) { + QJsonDocument doc(toJsonObject()); + jsonfile.write(doc.toBinaryData()); + } +} + +void TripData::setDuration(double duration) +{ + if (qFuzzyCompare(m_duration, duration)) + return; + + m_duration = duration; +} + +void TripData::setDistance(double distance) +{ + if (qFuzzyCompare(m_distance, distance)) + return; + + m_distance = distance; +} + +void TripData::setCalories(double calories) +{ + if (qFuzzyCompare(m_calories, calories)) + return; + + m_calories = calories; +} + +void TripData::setMaxSpeed(double maxspeed) +{ + if (qFuzzyCompare(m_maxspeed, maxspeed)) + return; + + m_maxspeed = maxspeed; +} + +void TripData::setAscent(double ascent) +{ + if (qFuzzyCompare(m_ascent, ascent)) + return; + + m_ascent = ascent; +} + +void TripData::setStartTime(double starttime) +{ + // Special value means reset to current timestamp + if (starttime == 0.0) + starttime = static_cast(QDateTime::currentMSecsSinceEpoch()) / 1000.0; + + if (qFuzzyCompare(m_starttime, starttime)) + return; + + m_starttime = starttime; +} + +void TripData::addDuration(double duration) +{ + m_duration += duration; +} + +void TripData::addDistance(double distance) +{ + m_distance += distance; +} + +void TripData::addCalories(double calories) +{ + m_calories += calories; +} + +void TripData::clear() +{ + m_duration = 0.0; + m_distance = 0.0; + m_calories = 0.0; + m_maxspeed = 0.0; + m_ascent = 0.0; + m_starttime = 0.0; +} + +TripData::operator QJsonObject() const +{ + return toJsonObject(); +} + +const QJsonObject TripData::toJsonObject(void) const +{ + QJsonObject data; + + data.insert("duration", m_duration); + data.insert("distance", m_distance); + data.insert("calories", m_calories); + data.insert("maxspeed", m_maxspeed); + data.insert("avgspeed", m_distance / m_duration); + data.insert("ascent", m_ascent); + data.insert("starttime", m_starttime); + + return data; +} + +TripData TripData::fromJsonObject(const QJsonObject &data) +{ + return TripData(data); +} + +TripData TripData::fromFile(const QString &filename) +{ + TripData trip; + trip.load(filename); + return trip; +} + +bool Trips::load(const QString &filename) +{ + QFile jsonfile(filename); + if (jsonfile.open(QIODevice::ReadOnly)) { + QJsonDocument doc = QJsonDocument::fromBinaryData(jsonfile.readAll()); + clear(); + foreach (const QJsonValue &trip, doc.array()) + append(trip.toObject()); + return true; + } + return false; +} + +void Trips::save(const QString &filename) const +{ + QFile jsonfile(filename); + if (jsonfile.open(QIODevice::WriteOnly)) { + QJsonDocument doc(*this); + jsonfile.write(doc.toBinaryData()); + } +} + +Trips::operator QJsonArray() const +{ + return toJsonArray(); +} + +const QJsonArray Trips::toJsonArray() const +{ + QJsonArray array; + foreach (const TripData &data, *this) + array.append(data.toJsonObject()); + + return array; +} + +Trips Trips::fromFile(const QString &filename) +{ + Trips trips; + trips.load(filename); + return trips; +} diff --git a/basicsuite/datacollector/tripdata.h b/basicsuite/datacollector/tripdata.h new file mode 100644 index 0000000..36fd9c8 --- /dev/null +++ b/basicsuite/datacollector/tripdata.h @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TRIPDATA_H +#define TRIPDATA_H + +#include +#include +#include + +class TripData +{ +public: + TripData(); + TripData(double duration, double distance, double calories, + double maxspeed, double ascent, double starttime); + TripData(const QJsonObject &data); + +public: + double duration() const { return m_duration; } + double distance() const { return m_distance; } + double calories() const { return m_calories; } + double maxSpeed() const { return m_maxspeed; } + double avgSpeed() const { return m_distance / m_duration; } + double ascent() const { return m_ascent; } + double startTime() const { return m_starttime; } + + void setDuration(double duration); + void setDistance(double distance); + void setCalories(double calories); + void setMaxSpeed(double maxspeed); + void setAscent(double ascent); + void setStartTime(double starttime=0); + void addDuration(double duration); + void addDistance(double distance); + void addCalories(double calories); + void clear(); + + // Load from file + bool load(const QString &filename); + + // Save to file + void save(const QString &filename) const; + + // Convert to Json Object + operator QJsonObject() const; + const QJsonObject toJsonObject(void) const; + + // Create from Json + static TripData fromJsonObject(const QJsonObject &data); + + // Load from binary Json data + static TripData fromFile(const QString &filename); + +private: + QElapsedTimer m_timer; + double m_duration; // Seconds + double m_distance; // Meters + double m_calories; // calories, not kcal + double m_maxspeed; // m/s + double m_ascent; // meters + double m_starttime; // Timestamp of the start of the trip +}; + +class Trips: public QList +{ +public: + // Load from file + bool load(const QString &filename); + + // Save to file + void save(const QString &filename) const; + + // Convert to Json Array + operator QJsonArray() const; + const QJsonArray toJsonArray(void) const; + + // Load from binary Json data + static Trips fromFile(const QString &filename); +}; + +#endif // TRIPDATA_H diff --git a/basicsuite/datacollector/unixsignalhandler.cpp b/basicsuite/datacollector/unixsignalhandler.cpp new file mode 100644 index 0000000..61fd87b --- /dev/null +++ b/basicsuite/datacollector/unixsignalhandler.cpp @@ -0,0 +1,149 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include "unixsignalhandler.h" + +int UnixSignalHandler::sigintFd[2] = {0}; +int UnixSignalHandler::sighupFd[2] = {0}; +int UnixSignalHandler::sigtermFd[2] = {0}; + +UnixSignalHandler::UnixSignalHandler(QObject *parent) + : QObject(parent) +{ + if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sigintFd)) + qFatal("Couldn't create INT socketpair"); + + if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sighupFd)) + qFatal("Couldn't create HUP socketpair"); + + if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sigtermFd)) + qFatal("Couldn't create TERM socketpair"); + + m_sigintNotifier = new QSocketNotifier(sigintFd[1], QSocketNotifier::Read, this); + connect(m_sigintNotifier, &QSocketNotifier::activated, + this, &UnixSignalHandler::handleSigInt); + m_sighupNotifier = new QSocketNotifier(sighupFd[1], QSocketNotifier::Read, this); + connect(m_sighupNotifier, &QSocketNotifier::activated, + this, &UnixSignalHandler::handleSigHup); + m_sigtermNotifier = new QSocketNotifier(sigtermFd[1], QSocketNotifier::Read, this); + connect(m_sigtermNotifier, &QSocketNotifier::activated, + this, &UnixSignalHandler::handleSigTerm); +} + +int UnixSignalHandler::setupSignalHandlers() +{ + struct sigaction sig_int, sig_hup, sig_term; + + sig_int.sa_handler = UnixSignalHandler::sigIntHandler; + sigemptyset(&sig_int.sa_mask); + sig_int.sa_flags = 0; + sig_int.sa_flags |= SA_RESTART; + + if (sigaction(SIGINT, &sig_int, 0)) + return 1; + + sig_hup.sa_handler = UnixSignalHandler::sigHupHandler; + sigemptyset(&sig_hup.sa_mask); + sig_hup.sa_flags = 0; + sig_hup.sa_flags |= SA_RESTART; + + if (sigaction(SIGHUP, &sig_hup, 0)) + return 2; + + sig_term.sa_handler = UnixSignalHandler::sigTermHandler; + sigemptyset(&sig_term.sa_mask); + sig_term.sa_flags |= SA_RESTART; + + if (sigaction(SIGTERM, &sig_term, 0)) + return 3; + + return 0; +} + +void UnixSignalHandler::sigIntHandler(int) +{ + char a = 1; + ::write(sigintFd[0], &a, sizeof(a)); +} + +void UnixSignalHandler::sigHupHandler(int) +{ + char a = 1; + ::write(sighupFd[0], &a, sizeof(a)); +} + +void UnixSignalHandler::sigTermHandler(int) +{ + char a = 1; + ::write(sigtermFd[0], &a, sizeof(a)); +} + +void UnixSignalHandler::handleSigInt() +{ + m_sigintNotifier->setEnabled(false); + char tmp; + ::read(sigintFd[1], &tmp, sizeof(tmp)); + + emit sigInt(); + + m_sigintNotifier->setEnabled(true); +} + +void UnixSignalHandler::handleSigHup() +{ + m_sighupNotifier->setEnabled(false); + char tmp; + ::read(sighupFd[1], &tmp, sizeof(tmp)); + + emit sigHup(); + + m_sighupNotifier->setEnabled(true); +} + +void UnixSignalHandler::handleSigTerm() +{ + m_sigtermNotifier->setEnabled(false); + char tmp; + ::read(sigtermFd[1], &tmp, sizeof(tmp)); + + emit sigTerm(); + + m_sigtermNotifier->setEnabled(true); +} diff --git a/basicsuite/datacollector/unixsignalhandler.h b/basicsuite/datacollector/unixsignalhandler.h new file mode 100644 index 0000000..63c5d53 --- /dev/null +++ b/basicsuite/datacollector/unixsignalhandler.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the E-Bike demo project. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef UNIXSIGNALHANDLER_H +#define UNIXSIGNALHANDLER_H + +#include + +class QSocketNotifier; + +class UnixSignalHandler : public QObject +{ + Q_OBJECT + +public: + explicit UnixSignalHandler(QObject *parent = nullptr); + +public: + static int setupSignalHandlers(); + static void sigIntHandler(int); + static void sigHupHandler(int); + static void sigTermHandler(int); + +signals: + void sigInt(); + void sigHup(); + void sigTerm(); + +private slots: + void handleSigInt(); + void handleSigHup(); + void handleSigTerm(); + +private: + static int sigintFd[2]; + static int sighupFd[2]; + static int sigtermFd[2]; + + QSocketNotifier *m_sigintNotifier; + QSocketNotifier *m_sighupNotifier; + QSocketNotifier *m_sigtermNotifier; +}; + +#endif // UNIXSIGNALHANDLER_H diff --git a/basicsuite/demos.xml b/basicsuite/demos.xml index 2c79f1a..91b7ad9 100644 --- a/basicsuite/demos.xml +++ b/basicsuite/demos.xml @@ -93,7 +93,6 @@ Qt for Device Creation comes with Qt Virtual Keyboard - a framework that consist - diff --git a/basicsuite/ebike-ui/datamodelplugin/plugin.cpp b/basicsuite/ebike-ui/datamodelplugin/plugin.cpp index a07e4e6..098a6a8 100644 --- a/basicsuite/ebike-ui/datamodelplugin/plugin.cpp +++ b/basicsuite/ebike-ui/datamodelplugin/plugin.cpp @@ -72,11 +72,14 @@ public: void registerTypes(const char *uri) { + Q_UNUSED(uri); qmlRegisterType("DataStore", 1, 0, "DataStore"); } void initializeEngine(QQmlEngine *engine, const char *uri) { + Q_UNUSED(uri); + // Setup data store for connection to backend server DataStore *datastore = new DataStore(engine); datastore->connectToServer("datasocket"); -- cgit v1.2.3 From 173d934c701d6d8dc274d7dc7421dac63bf21e22 Mon Sep 17 00:00:00 2001 From: Mikko Gronoff Date: Tue, 22 May 2018 09:37:17 +0300 Subject: Update Boot2Qt demos appearing in QtCreator New demos: E-Bike, Quick Controls 2 Gallery Removed demos: About B2Qt, Cinematic Demo, Camera, Data visualization, Canvas3D, Dashboard, Controls Gallery & Flat controls. Task-number: QTBUG-67917 Change-Id: I562737e7fd3e851e8a84cb3b71acc939a216032f Reviewed-by: Sami Nurmenniemi Reviewed-by: Tarja Sundqvist --- basicsuite/qtquickcontrols2/gallery.pro | 18 ---- basicsuite/qtquickcontrols2/qtquickcontrols2.pro | 18 ++++ doc/b2qt-demos.qdoc | 111 ++++------------------- 3 files changed, 34 insertions(+), 113 deletions(-) delete mode 100644 basicsuite/qtquickcontrols2/gallery.pro create mode 100644 basicsuite/qtquickcontrols2/qtquickcontrols2.pro diff --git a/basicsuite/qtquickcontrols2/gallery.pro b/basicsuite/qtquickcontrols2/gallery.pro deleted file mode 100644 index 9834b89..0000000 --- a/basicsuite/qtquickcontrols2/gallery.pro +++ /dev/null @@ -1,18 +0,0 @@ -TARGET = gallery - -include(../shared/shared.pri) -b2qtdemo_deploy_defaults() - -content.files = \ - main.qml \ - qtquickcontrols2.conf \ - icons/gallery/index.theme \ - $$files(icons/*.png, true) \ - $$files(images/*.png) \ - $$files(pages/*.qml) - -content.path = $$DESTPATH - -OTHER_FILES += $${content.files} - -INSTALLS += target content diff --git a/basicsuite/qtquickcontrols2/qtquickcontrols2.pro b/basicsuite/qtquickcontrols2/qtquickcontrols2.pro new file mode 100644 index 0000000..9834b89 --- /dev/null +++ b/basicsuite/qtquickcontrols2/qtquickcontrols2.pro @@ -0,0 +1,18 @@ +TARGET = gallery + +include(../shared/shared.pri) +b2qtdemo_deploy_defaults() + +content.files = \ + main.qml \ + qtquickcontrols2.conf \ + icons/gallery/index.theme \ + $$files(icons/*.png, true) \ + $$files(images/*.png) \ + $$files(pages/*.qml) + +content.path = $$DESTPATH + +OTHER_FILES += $${content.files} + +INSTALLS += target content diff --git a/doc/b2qt-demos.qdoc b/doc/b2qt-demos.qdoc index b399301..91122fe 100644 --- a/doc/b2qt-demos.qdoc +++ b/doc/b2qt-demos.qdoc @@ -63,32 +63,20 @@ */ /*! - \example basicsuite/about-b2qt - \title About Qt for Device Creation + \example basicsuite/ebike-ui + \title e-bike Demo \ingroup b2qt-demos - \brief Displays information about Qt for Device Creation. + \brief An E-bike instrument cluster concept. - \image b2qt-demo-about-b2qt.jpg + \image b2qt-demo-ebike-ui.jpg - A demo that provides an introduction to what Qt for Device Creation is all about. -*/ - -/*! - \example basicsuite/camera - \title Camera - \ingroup b2qt-demos - \brief Demonstrates using camera in a QML application. - - \image b2qt-demo-camera.jpg + An E-bike instrument cluster concept designed and implemented by Qt. - This example demonstrates the use of the camera features provided by Qt Multimedia with - Qt Quick. - - Demo can be used to take pictures. Files are saved inside the \c {/data/images/} folder - and can be then viewed with the \l {Photo Gallery} demo application. + The entire concept is a testament that Qt brings the HMI designers and Software engineers together + by using the same tools, allowing them to fast prototyping through collaborative workflow. + In addition to that, Qt is optimized for running on low end SoC even the ones that don't have GPU acceleration + for graphics. - Camera parameters such as flash mode, scene mode or white balance can be changed. The - availability of parameters depends on what the camera driver provides. */ /*! @@ -119,40 +107,6 @@ It can play from a file or from a network source, both videos and music. */ -/*! - \example basicsuite/canvas3d-planets - \title Qt Canvas3D Planets - \ingroup b2qt-demos - \brief Demonstrates the usage of Qt Canvas 3D, a WebGL-like API for QML, and popular JavaScript frameworks like three.js. - - \image b2qt-demo-canvas3d-planets.jpg - - The demo uses Qt Quick and Canvas 3D in combination with \l{http://threejs.org/}{three.js}, - \l{https://github.com/jeromeetienne/threex.planets}{threex.planets}, and Qt Quick - Controls. Tapping on a planet changes the view and moves to the chosen planet. Use the sliders - to adjust the zoom levels and viewing distance. Tapping outside the controls moves the focus - back to the solar view. -*/ - -/*! - \example basicsuite/qt5-cinematicdemo - \title Qt 5 Cinematic Demo - \ingroup b2qt-demos - \brief A cool demonstration of the graphical prowess of Qt 5 and Qt Quick 2. - - \image b2qt-demo-qt5-cinematicdemo.jpg - - The Qt5 Cinematic Experience is a demo by "QUIt Coding", a small group of talented individuals - enjoying software development with cutting edge technologies. They are official members of the - Qt Ambassador Program. - - The demo shows off a number features of Qt Quick 2.0. A nicely styled list control of movie - covers with lighting effects, particles and transitions. The information roll-down curvy - curtain is implemented using inline GLSL in the QML file. - - More awesome looking Qt Quick examples are available from \l {http://quitcoding.com}. -*/ - /*! \example basicsuite/textinput \title Text Input @@ -181,49 +135,16 @@ */ /*! - \example basicsuite/enterprise-dashboard - \title Dashboard - \ingroup b2qt-demos - \brief A car dashboard created using Qt Quick Enterprise Controls. - - \image b2qt-demo-enterprise-dashboard.jpg - - This example project demonstrates using several CircularGauge controls to create a car dashboard. -*/ - -/*! - \example basicsuite/enterprise-qtdatavis3d - \title Qt Data Visualization - \ingroup b2qt-demos - \brief An interactive showcase for Qt Data Visualization 3D. - - \image b2qt-demo-enterprise-qtdatavis3d.jpg - - This example demonstrates how to use the Qt Data Visualization module to display 3D data visualizations in QML. -*/ - -/*! - \example basicsuite/enterprise-gallery - \title Enterprise Controls Gallery - \ingroup b2qt-demos - \brief An interactive showcase for Qt Quick Enterprise Controls. - - \image b2qt-demo-enterprise-gallery.jpg - - This example project demonstrates the various UI controls provided by Qt Quick Enterprise Controls. -*/ - -/*! - \example basicsuite/enterprise-flat-controls - \title Enterprise Flat Controls + \example basicsuite/qtquickcontrols2 + \title Qt Quick Controls 2 - Gallery \ingroup b2qt-demos - \brief The Flat Style Gallery example showcases the Qt Quick Controls. + \brief A gallery of controls. - \image b2qt-demo-enterprise-flat-controls.jpg + \image b2qt-demo-qtquickcontrols2.jpg - This demo combines both the standard Quick Controls as well as the Qt Quick Enterprise Controls - both of which are using the new Flat style. The Flat style for Qt Quick Controls has a modern - look and feel and is perfect for the touch driven interfaces commonly developed by device creators. + The gallery example is a simple application with a drawer menu that contains all the Qt Quick Controls 2. Each + menu item opens a page that shows the graphical appearance of a control, allows you to interact with the control, + and explains in which circumstances it is handy to use this control. */ /*! -- cgit v1.2.3 From 054a2eabcae4a3eb6f7036b0706a96ed0c1f9a00 Mon Sep 17 00:00:00 2001 From: Mikko Gronoff Date: Thu, 24 May 2018 10:13:40 +0300 Subject: doc: add missing doc images for e-bike & quickcontrols2 demo Change-Id: I966708859b17d2f8ba613db12747bd55f508faff Reviewed-by: Tarja Sundqvist --- doc/images/b2qt-demo-ebike-ui.jpg | Bin 0 -> 19877 bytes doc/images/b2qt-demo-qtquickcontrols2.jpg | Bin 0 -> 12162 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/images/b2qt-demo-ebike-ui.jpg create mode 100644 doc/images/b2qt-demo-qtquickcontrols2.jpg diff --git a/doc/images/b2qt-demo-ebike-ui.jpg b/doc/images/b2qt-demo-ebike-ui.jpg new file mode 100644 index 0000000..570e609 Binary files /dev/null and b/doc/images/b2qt-demo-ebike-ui.jpg differ diff --git a/doc/images/b2qt-demo-qtquickcontrols2.jpg b/doc/images/b2qt-demo-qtquickcontrols2.jpg new file mode 100644 index 0000000..89a4fcb Binary files /dev/null and b/doc/images/b2qt-demo-qtquickcontrols2.jpg differ -- cgit v1.2.3 From 4fa8854c0471006458eaf0f7fb97a0206f8ae043 Mon Sep 17 00:00:00 2001 From: Tarja Sundqvist Date: Thu, 24 May 2018 13:17:43 +0300 Subject: Doc: remove outdate doc folder under qtquickcontrols2 example basicsuite/qtquickcontrol2 directory has /doc folder that seems to contain some outdated content that is not used at all. Change-Id: Ib11cf99f3f22c217b1c73b0470f6f6a43bf03346 Reviewed-by: Mikko Gronoff --- .../doc/images/qtquickcontrols2-gallery-drawer.png | Bin 15785 -> 0 bytes .../doc/images/qtquickcontrols2-gallery-menu.png | Bin 16618 -> 0 bytes .../images/qtquickcontrols2-gallery-welcome.png | Bin 20138 -> 0 bytes .../doc/src/qtquickcontrols2-gallery.qdoc | 61 --------------------- 4 files changed, 61 deletions(-) delete mode 100644 basicsuite/qtquickcontrols2/doc/images/qtquickcontrols2-gallery-drawer.png delete mode 100644 basicsuite/qtquickcontrols2/doc/images/qtquickcontrols2-gallery-menu.png delete mode 100644 basicsuite/qtquickcontrols2/doc/images/qtquickcontrols2-gallery-welcome.png delete mode 100644 basicsuite/qtquickcontrols2/doc/src/qtquickcontrols2-gallery.qdoc diff --git a/basicsuite/qtquickcontrols2/doc/images/qtquickcontrols2-gallery-drawer.png b/basicsuite/qtquickcontrols2/doc/images/qtquickcontrols2-gallery-drawer.png deleted file mode 100644 index 9109fdd..0000000 Binary files a/basicsuite/qtquickcontrols2/doc/images/qtquickcontrols2-gallery-drawer.png and /dev/null differ diff --git a/basicsuite/qtquickcontrols2/doc/images/qtquickcontrols2-gallery-menu.png b/basicsuite/qtquickcontrols2/doc/images/qtquickcontrols2-gallery-menu.png deleted file mode 100644 index 3cbfbe6..0000000 Binary files a/basicsuite/qtquickcontrols2/doc/images/qtquickcontrols2-gallery-menu.png and /dev/null differ diff --git a/basicsuite/qtquickcontrols2/doc/images/qtquickcontrols2-gallery-welcome.png b/basicsuite/qtquickcontrols2/doc/images/qtquickcontrols2-gallery-welcome.png deleted file mode 100644 index e69e7e4..0000000 Binary files a/basicsuite/qtquickcontrols2/doc/images/qtquickcontrols2-gallery-welcome.png and /dev/null differ diff --git a/basicsuite/qtquickcontrols2/doc/src/qtquickcontrols2-gallery.qdoc b/basicsuite/qtquickcontrols2/doc/src/qtquickcontrols2-gallery.qdoc deleted file mode 100644 index b96ba28..0000000 --- a/basicsuite/qtquickcontrols2/doc/src/qtquickcontrols2-gallery.qdoc +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example gallery - \title Qt Quick Controls 2 - Gallery - \ingroup qtquickcontrols2-examples - \brief A gallery of controls. - - \raw HTML -
- -
- \endraw - \image qtquickcontrols2-gallery-welcome.png - \caption Welcome Screen - \raw HTML - - \endraw - \image qtquickcontrols2-gallery-drawer.png - \caption Side Drawer - \raw HTML - - \endraw - \image qtquickcontrols2-gallery-menu.png - \caption Options Menu - \raw HTML -
- \endraw - - The gallery example is a simple application with a drawer menu that contains - all the \l {Qt Quick Controls 2}. Each menu item opens a page that shows the - graphical appearance of a control, allows you to interact with the control, - and explains in which circumstances it is handy to use this control. - - \include examples-run.qdocinc -*/ -- cgit v1.2.3 From 9f18bb741e2eb0f3f70c410c5cedf1f4a514d413 Mon Sep 17 00:00:00 2001 From: Mikko Gronoff Date: Fri, 25 May 2018 13:21:01 +0300 Subject: Doc: Bump version to 5.11.1 Change-Id: I3cdbfee08f972a2082604cecc52a84e221ef83d5 Reviewed-by: Tarja Sundqvist --- doc/b2qt-demos.qdoc | 2 +- doc/b2qt-demos.qdocconf | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/b2qt-demos.qdoc b/doc/b2qt-demos.qdoc index 91122fe..dd50bf4 100644 --- a/doc/b2qt-demos.qdoc +++ b/doc/b2qt-demos.qdoc @@ -50,7 +50,7 @@ /*! \page index.html - \title Qt 5.11.0 for Device Creation Examples and Demos + \title Qt 5.11.1 for Device Creation Examples and Demos \SDK has a number of examples and demos. These are included in the \B2Q images, available in the launcher that is run by default at diff --git a/doc/b2qt-demos.qdocconf b/doc/b2qt-demos.qdocconf index 79b9a71..1394cda 100644 --- a/doc/b2qt-demos.qdocconf +++ b/doc/b2qt-demos.qdocconf @@ -5,8 +5,8 @@ outputencoding = UTF-8 sourceencoding = UTF-8 project = QtforDeviceCreationDemos -description = Qt 5.11.0 for Device Creation Examples and Demos -version = 5.11.0 +description = Qt 5.11.1 for Device Creation Examples and Demos +version = 5.11.1 sourcedirs = . imagedirs += images @@ -21,9 +21,9 @@ exampledirs = .. qhp.projects = QtforDeviceCreationDemos qhp.QtforDeviceCreationDemos.file = b2qt-demos.qhp -qhp.QtforDeviceCreationDemos.namespace = org.qt-project.b2qt-demos.5110 +qhp.QtforDeviceCreationDemos.namespace = org.qt-project.b2qt-demos.5111 qhp.QtforDeviceCreationDemos.virtualFolder = b2qt-demos -qhp.QtforDeviceCreationDemos.indexTitle = Qt 5.11.0 for Device Creation Examples and Demos +qhp.QtforDeviceCreationDemos.indexTitle = Qt 5.11.1 for Device Creation Examples and Demos qhp.QtforDeviceCreationDemos.indexRoot = qhp.QtforDeviceCreationDemos.subprojects = demos @@ -35,4 +35,4 @@ manifestmeta.b2qt.names = "QtforDeviceCreationDemos/*" macro.B2Q = "Boot to Qt" macro.SDK = "Qt for Device Creation" -navigation.landingpage = "Qt 5.11.0 for Device Creation Examples and Demos" +navigation.landingpage = "Qt 5.11.1 for Device Creation Examples and Demos" -- cgit v1.2.3 From 773a661b7d21c8553a3c5d773e85850dcf4e70ae Mon Sep 17 00:00:00 2001 From: Samuli Piippo Date: Thu, 31 May 2018 14:35:28 +0300 Subject: Disable webbrowser demo from all imx7 boards Change-Id: I6acab41eddec0cc642b586dbb3e03b9334956893 Reviewed-by: Sami Nurmenniemi --- basicsuite/demos.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basicsuite/demos.xml b/basicsuite/demos.xml index 91b7ad9..1d3a135 100644 --- a/basicsuite/demos.xml +++ b/basicsuite/demos.xml @@ -77,7 +77,7 @@ The demo shows off a number features of Qt Quick. A nicely styled list control o
--> - + This example demonstrates the use of Qt WebEngine with Qt Quick. -- cgit v1.2.3 From a60797871ea11ade6b583869e361ffef88e2213b Mon Sep 17 00:00:00 2001 From: Juho Annunen Date: Wed, 13 Jun 2018 09:43:54 +0300 Subject: Update Boot2Qt Launcher demo icons & doc images Task-number: QTBUG-68819 Change-Id: Idf1c1933765af2efc4e8193f5b03f99828cbc7b6 Reviewed-by: Mikko Gronoff --- basicsuite/enterprise-charts/preview_l.jpg | Bin 27257 -> 52504 bytes basicsuite/graphicaleffects/preview_l.jpg | Bin 80965 -> 91339 bytes basicsuite/mediaplayer/preview_l.jpg | Bin 65701 -> 59359 bytes basicsuite/qtwebbrowser/preview_l.jpg | Bin 25655 -> 46434 bytes doc/images/b2qt-demo-enterprise-charts.jpg | Bin 48 -> 30530 bytes doc/images/b2qt-demo-graphicaleffects.jpg | Bin 47 -> 36084 bytes doc/images/b2qt-demo-mediaplayer.jpg | Bin 42 -> 27063 bytes doc/images/b2qt-demo-qtwebbrowser.jpg | Bin 43 -> 22315 bytes 8 files changed, 0 insertions(+), 0 deletions(-) mode change 120000 => 100644 doc/images/b2qt-demo-enterprise-charts.jpg mode change 120000 => 100644 doc/images/b2qt-demo-graphicaleffects.jpg mode change 120000 => 100644 doc/images/b2qt-demo-mediaplayer.jpg mode change 120000 => 100644 doc/images/b2qt-demo-qtwebbrowser.jpg diff --git a/basicsuite/enterprise-charts/preview_l.jpg b/basicsuite/enterprise-charts/preview_l.jpg index 131cc8f..a298283 100644 Binary files a/basicsuite/enterprise-charts/preview_l.jpg and b/basicsuite/enterprise-charts/preview_l.jpg differ diff --git a/basicsuite/graphicaleffects/preview_l.jpg b/basicsuite/graphicaleffects/preview_l.jpg index fde1964..d5333c8 100644 Binary files a/basicsuite/graphicaleffects/preview_l.jpg and b/basicsuite/graphicaleffects/preview_l.jpg differ diff --git a/basicsuite/mediaplayer/preview_l.jpg b/basicsuite/mediaplayer/preview_l.jpg index f6cc262..98f528e 100644 Binary files a/basicsuite/mediaplayer/preview_l.jpg and b/basicsuite/mediaplayer/preview_l.jpg differ diff --git a/basicsuite/qtwebbrowser/preview_l.jpg b/basicsuite/qtwebbrowser/preview_l.jpg index e96d576..d4ddedc 100644 Binary files a/basicsuite/qtwebbrowser/preview_l.jpg and b/basicsuite/qtwebbrowser/preview_l.jpg differ diff --git a/doc/images/b2qt-demo-enterprise-charts.jpg b/doc/images/b2qt-demo-enterprise-charts.jpg deleted file mode 120000 index e2f9e6c..0000000 --- a/doc/images/b2qt-demo-enterprise-charts.jpg +++ /dev/null @@ -1 +0,0 @@ -../../basicsuite/enterprise-charts/preview_l.jpg \ No newline at end of file diff --git a/doc/images/b2qt-demo-enterprise-charts.jpg b/doc/images/b2qt-demo-enterprise-charts.jpg new file mode 100644 index 0000000..b472087 Binary files /dev/null and b/doc/images/b2qt-demo-enterprise-charts.jpg differ diff --git a/doc/images/b2qt-demo-graphicaleffects.jpg b/doc/images/b2qt-demo-graphicaleffects.jpg deleted file mode 120000 index 5a092e2..0000000 --- a/doc/images/b2qt-demo-graphicaleffects.jpg +++ /dev/null @@ -1 +0,0 @@ -../../basicsuite/graphicaleffects/preview_l.jpg \ No newline at end of file diff --git a/doc/images/b2qt-demo-graphicaleffects.jpg b/doc/images/b2qt-demo-graphicaleffects.jpg new file mode 100644 index 0000000..da1255b Binary files /dev/null and b/doc/images/b2qt-demo-graphicaleffects.jpg differ diff --git a/doc/images/b2qt-demo-mediaplayer.jpg b/doc/images/b2qt-demo-mediaplayer.jpg deleted file mode 120000 index cce5a00..0000000 --- a/doc/images/b2qt-demo-mediaplayer.jpg +++ /dev/null @@ -1 +0,0 @@ -../../basicsuite/mediaplayer/preview_l.jpg \ No newline at end of file diff --git a/doc/images/b2qt-demo-mediaplayer.jpg b/doc/images/b2qt-demo-mediaplayer.jpg new file mode 100644 index 0000000..d61efbc Binary files /dev/null and b/doc/images/b2qt-demo-mediaplayer.jpg differ diff --git a/doc/images/b2qt-demo-qtwebbrowser.jpg b/doc/images/b2qt-demo-qtwebbrowser.jpg deleted file mode 120000 index 13dea2f..0000000 --- a/doc/images/b2qt-demo-qtwebbrowser.jpg +++ /dev/null @@ -1 +0,0 @@ -../../basicsuite/qtwebbrowser/preview_l.jpg \ No newline at end of file diff --git a/doc/images/b2qt-demo-qtwebbrowser.jpg b/doc/images/b2qt-demo-qtwebbrowser.jpg new file mode 100644 index 0000000..c63de25 Binary files /dev/null and b/doc/images/b2qt-demo-qtwebbrowser.jpg differ -- cgit v1.2.3 From 0b0d77ed36616ec7c10d7ceb5ea90196b11d4ff8 Mon Sep 17 00:00:00 2001 From: Juho Annunen Date: Fri, 15 Jun 2018 14:42:56 +0300 Subject: Fix mediaplayer color definitions Task-number: QTBUG-68471 Change-Id: I292f40ce195f0e2f914353cb237e3009774c11bb Reviewed-by: Sami Nurmenniemi --- basicsuite/mediaplayer/PlaybackControl.qml | 5 +++-- basicsuite/mediaplayer/UrlBar.qml | 2 +- basicsuite/mediaplayer/VolumeControl.qml | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/basicsuite/mediaplayer/PlaybackControl.qml b/basicsuite/mediaplayer/PlaybackControl.qml index 5fff05f..7c90fa6 100644 --- a/basicsuite/mediaplayer/PlaybackControl.qml +++ b/basicsuite/mediaplayer/PlaybackControl.qml @@ -50,6 +50,7 @@ import QtQuick 2.0 import QtDeviceUtilities.QtButtonImageProvider 1.0 +import "settings.js" as Settings Row { anchors.leftMargin: parent.width * 0.02 @@ -72,7 +73,7 @@ Row { height: width anchors.bottom: parent.bottom anchors.bottomMargin: root.spacing - fillColor: viewSettings.buttonGreenColor + fillColor: Settings.primaryGreen Image{ anchors.centerIn: parent width: parent.width * 0.5 @@ -91,7 +92,7 @@ Row { height: width anchors.bottom: parent.bottom anchors.bottomMargin: root.spacing - fillColor: viewSettings.buttonGreenColor + fillColor: Settings.primaryGreen Image{ anchors.centerIn: parent width: parent.width * 0.5 diff --git a/basicsuite/mediaplayer/UrlBar.qml b/basicsuite/mediaplayer/UrlBar.qml index 80a9259..cb822ff 100644 --- a/basicsuite/mediaplayer/UrlBar.qml +++ b/basicsuite/mediaplayer/UrlBar.qml @@ -95,7 +95,7 @@ Rectangle { background: Rectangle { color: Settings.backgroundColor opacity: 0.8 - border.color: viewSettings.borderColor + border.color: Settings.primaryGrey border.width: 2 } onAccepted: root.urlAccepted(urlInput.text); diff --git a/basicsuite/mediaplayer/VolumeControl.qml b/basicsuite/mediaplayer/VolumeControl.qml index 3a83491..9536d12 100644 --- a/basicsuite/mediaplayer/VolumeControl.qml +++ b/basicsuite/mediaplayer/VolumeControl.qml @@ -69,7 +69,7 @@ Item { anchors.bottom: parent.bottom anchors.bottomMargin: controlBar.width * 0.02 anchors.horizontalCenter: parent.horizontalCenter - fillColor: viewSettings.buttonGreenColor + fillColor: Settings.primaryGreen Image{ anchors.centerIn: parent @@ -104,7 +104,7 @@ Item { width: controlBar.width * 0.06 height: width anchors.bottom: parent.bottom - fillColor: viewSettings.buttonGrayColor + fillColor: Settings.primaryGrey borderColor: "transparent" Image{ anchors.centerIn: parent -- cgit v1.2.3 From c20966fc4163ceccaa884e6b6253729dfa4776a7 Mon Sep 17 00:00:00 2001 From: Juho Annunen Date: Mon, 18 Jun 2018 14:37:08 +0300 Subject: Move info button to mediaplayer-demo footer Task-number: QTBUG-68674 Change-Id: I4e2c3dc499461dcbb9c4d6e8a03027d70419c160 Reviewed-by: Kimmo Ollila --- basicsuite/mediaplayer/ControlBar.qml | 10 ++++++++++ basicsuite/mediaplayer/main.qml | 13 ------------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/basicsuite/mediaplayer/ControlBar.qml b/basicsuite/mediaplayer/ControlBar.qml index f05cea8..fed8a77 100644 --- a/basicsuite/mediaplayer/ControlBar.qml +++ b/basicsuite/mediaplayer/ControlBar.qml @@ -172,6 +172,7 @@ Rectangle { imageSource: "images/FXButton.png" checkable: true checked: effectSelectionPanel.visible + onClicked: { openFX(); } @@ -179,6 +180,7 @@ Rectangle { ImageButton { id: fileButton imageSource: "images/FileButton.png" + onClicked: { openFile(); } @@ -186,10 +188,18 @@ Rectangle { ImageButton { id: urlButton imageSource: "images/UrlButton.png" + onClicked: { openURL(); } } + ImageButton{ + id: infoButton + + imageSource: "images/info_icon.svg" + onClicked: metadataView.opacity = 1 + visible: content.videoPlayer.mediaPlayer.status !== MediaPlayer.NoMedia && content.videoPlayer.mediaPlayer.status !== MediaPlayer.InvalidMedia + } } VolumeControl { diff --git a/basicsuite/mediaplayer/main.qml b/basicsuite/mediaplayer/main.qml index 66d03a1..ec8719d 100644 --- a/basicsuite/mediaplayer/main.qml +++ b/basicsuite/mediaplayer/main.qml @@ -164,19 +164,6 @@ FocusScope { } } - ImageButton{ - id: infoButton - anchors.right: parent.right - anchors.top: parent.top - anchors.rightMargin: 32 - anchors.topMargin: 32 - width: 40 - height: 40 - imageSource: "images/info_icon.svg" - onClicked: metadataView.opacity = 1 - visible: content.videoPlayer.mediaPlayer.status !== MediaPlayer.NoMedia && content.videoPlayer.mediaPlayer.status !== MediaPlayer.InvalidMedia - } - MetadataView { id: metadataView mediaPlayer: content.videoPlayer.mediaPlayer -- cgit v1.2.3 From cc9de3791859538441fc5a174c69f556638cce03 Mon Sep 17 00:00:00 2001 From: Juho Annunen Date: Wed, 13 Jun 2018 10:17:50 +0300 Subject: Fix mediaplayer slider color definitions Task-number: QTBUG-62791 Change-Id: I1d9547680adbed937ee3b5e413c9c2f76304af28 Reviewed-by: Kimmo Ollila --- basicsuite/mediaplayer/PlayerSlider.qml | 6 +++--- basicsuite/mediaplayer/mediaplayer.pro | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/basicsuite/mediaplayer/PlayerSlider.qml b/basicsuite/mediaplayer/PlayerSlider.qml index ef0556a..68c21e1 100644 --- a/basicsuite/mediaplayer/PlayerSlider.qml +++ b/basicsuite/mediaplayer/PlayerSlider.qml @@ -82,7 +82,7 @@ Item { width: slider.width anchors.verticalCenter: slider.verticalCenter height: 5 - color: "red" //Settings.backgroundColor + color: Settings.primaryGrey radius: 2 MouseArea { @@ -120,7 +120,7 @@ Item { anchors.right: handle.right anchors.rightMargin: handle.width / 2 visible: slider.enabled - color: "green" + color: "white" radius: 2 } @@ -129,7 +129,7 @@ Item { width: 40 height: width radius: width / 2 - color: "#41cd52" + color: Settings.primaryGreen antialiasing: true anchors.centerIn: handle visible: true diff --git a/basicsuite/mediaplayer/mediaplayer.pro b/basicsuite/mediaplayer/mediaplayer.pro index 3578abc..1487620 100644 --- a/basicsuite/mediaplayer/mediaplayer.pro +++ b/basicsuite/mediaplayer/mediaplayer.pro @@ -15,6 +15,7 @@ content.files = \ MetadataView.qml \ ParameterPanel.qml \ PlaybackControl.qml \ + PlayerSlider.qml \ SeekControl.qml \ UrlBar.qml \ VolumeControl.qml \ -- cgit v1.2.3 From 1510d968c05f52abb26ea8af8eac015b2b733573 Mon Sep 17 00:00:00 2001 From: Mikko Gronoff Date: Thu, 21 Jun 2018 14:19:57 +0300 Subject: Doc: bump version to 5.9.7 Change-Id: I52d7739b4eedbf523ae2e19b279266bc7b5cc2c6 Reviewed-by: Tarja Sundqvist --- doc/b2qt-demos.qdoc | 2 +- doc/b2qt-demos.qdocconf | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/b2qt-demos.qdoc b/doc/b2qt-demos.qdoc index 7ea263e..2304cc5 100644 --- a/doc/b2qt-demos.qdoc +++ b/doc/b2qt-demos.qdoc @@ -50,7 +50,7 @@ /*! \page index.html - \title Qt 5.9.6 for Device Creation Examples and Demos + \title Qt 5.9.7 for Device Creation Examples and Demos \SDK has a number of examples and demos. These are included in the \B2Q images, available in the launcher that is run by default at diff --git a/doc/b2qt-demos.qdocconf b/doc/b2qt-demos.qdocconf index a18902b..1d54d34 100644 --- a/doc/b2qt-demos.qdocconf +++ b/doc/b2qt-demos.qdocconf @@ -5,8 +5,8 @@ outputencoding = UTF-8 sourceencoding = UTF-8 project = QtforDeviceCreationDemos -description = Qt 5.9.6 for Device Creation Examples and Demos -version = 5.9.6 +description = Qt 5.9.7 for Device Creation Examples and Demos +version = 5.9.7 sourcedirs = . imagedirs += images @@ -21,9 +21,9 @@ exampledirs = .. qhp.projects = QtforDeviceCreationDemos qhp.QtforDeviceCreationDemos.file = b2qt-demos.qhp -qhp.QtforDeviceCreationDemos.namespace = org.qt-project.b2qt-demos.596 +qhp.QtforDeviceCreationDemos.namespace = org.qt-project.b2qt-demos.597 qhp.QtforDeviceCreationDemos.virtualFolder = b2qt-demos -qhp.QtforDeviceCreationDemos.indexTitle = Qt 5.9.6 for Device Creation Examples and Demos +qhp.QtforDeviceCreationDemos.indexTitle = Qt 5.9.7 for Device Creation Examples and Demos qhp.QtforDeviceCreationDemos.indexRoot = qhp.QtforDeviceCreationDemos.subprojects = demos @@ -35,4 +35,4 @@ manifestmeta.b2qt.names = "QtforDeviceCreationDemos/*" macro.B2Q = "Boot to Qt" macro.SDK = "Qt for Device Creation" -navigation.landingpage = "Qt 5.9.6 for Device Creation Examples and Demos" +navigation.landingpage = "Qt 5.9.7 for Device Creation Examples and Demos" -- cgit v1.2.3 From a5ba6719eaae7c7a79c43005fa0213626aec3496 Mon Sep 17 00:00:00 2001 From: Mikko Gronoff Date: Tue, 26 Jun 2018 10:03:40 +0300 Subject: Doc: Bump version to 5.11.2 Change-Id: I13ae5e9aed32e37aaa2f529d221c81506132046a Reviewed-by: Tarja Sundqvist --- doc/b2qt-demos.qdoc | 2 +- doc/b2qt-demos.qdocconf | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/b2qt-demos.qdoc b/doc/b2qt-demos.qdoc index dd50bf4..687e374 100644 --- a/doc/b2qt-demos.qdoc +++ b/doc/b2qt-demos.qdoc @@ -50,7 +50,7 @@ /*! \page index.html - \title Qt 5.11.1 for Device Creation Examples and Demos + \title Qt 5.11.2 for Device Creation Examples and Demos \SDK has a number of examples and demos. These are included in the \B2Q images, available in the launcher that is run by default at diff --git a/doc/b2qt-demos.qdocconf b/doc/b2qt-demos.qdocconf index 1394cda..907f639 100644 --- a/doc/b2qt-demos.qdocconf +++ b/doc/b2qt-demos.qdocconf @@ -5,8 +5,8 @@ outputencoding = UTF-8 sourceencoding = UTF-8 project = QtforDeviceCreationDemos -description = Qt 5.11.1 for Device Creation Examples and Demos -version = 5.11.1 +description = Qt 5.11.2 for Device Creation Examples and Demos +version = 5.11.2 sourcedirs = . imagedirs += images @@ -21,9 +21,9 @@ exampledirs = .. qhp.projects = QtforDeviceCreationDemos qhp.QtforDeviceCreationDemos.file = b2qt-demos.qhp -qhp.QtforDeviceCreationDemos.namespace = org.qt-project.b2qt-demos.5111 +qhp.QtforDeviceCreationDemos.namespace = org.qt-project.b2qt-demos.5112 qhp.QtforDeviceCreationDemos.virtualFolder = b2qt-demos -qhp.QtforDeviceCreationDemos.indexTitle = Qt 5.11.1 for Device Creation Examples and Demos +qhp.QtforDeviceCreationDemos.indexTitle = Qt 5.11.2 for Device Creation Examples and Demos qhp.QtforDeviceCreationDemos.indexRoot = qhp.QtforDeviceCreationDemos.subprojects = demos @@ -35,4 +35,4 @@ manifestmeta.b2qt.names = "QtforDeviceCreationDemos/*" macro.B2Q = "Boot to Qt" macro.SDK = "Qt for Device Creation" -navigation.landingpage = "Qt 5.11.1 for Device Creation Examples and Demos" +navigation.landingpage = "Qt 5.11.2 for Device Creation Examples and Demos" -- cgit v1.2.3 From 57bc95f418a0e42921bba984d35d5999c6a6cf8f Mon Sep 17 00:00:00 2001 From: Juho Annunen Date: Tue, 17 Jul 2018 15:50:48 +0300 Subject: Fix qtquickcontrols2 demo image paths & controls theme Task-number: QTBUG-62805 Change-Id: I6cbd41384c003b1e29567af0c0c56341d5e93f6e Reviewed-by: Kimmo Ollila --- basicsuite/qtquickcontrols2/main.qml | 10 +++++----- basicsuite/qtquickcontrols2/pages/DialogPage.qml | 2 +- basicsuite/qtquickcontrols2/pages/ScrollBarPage.qml | 2 +- .../qtquickcontrols2/pages/ScrollIndicatorPage.qml | 2 +- basicsuite/qtquickcontrols2/pages/SwipeViewPage.qml | 2 +- basicsuite/qtquickcontrols2/pages/TabBarPage.qml | 2 +- basicsuite/qtquickcontrols2/qtquickcontrols2.pro | 14 +++++++------- basicsuite/shared/main.cpp | 17 ++++++++++------- 8 files changed, 27 insertions(+), 24 deletions(-) diff --git a/basicsuite/qtquickcontrols2/main.qml b/basicsuite/qtquickcontrols2/main.qml index cf9522b..473cdea 100644 --- a/basicsuite/qtquickcontrols2/main.qml +++ b/basicsuite/qtquickcontrols2/main.qml @@ -88,7 +88,7 @@ Page { anchors.fill: parent ToolButton { - icon.source: stackView.depth > 1 ? "back.png" : "drawer.png" + icon.name: stackView.depth > 1 ? "back" : "drawer" onClicked: { if (stackView.depth > 1) { stackView.pop() @@ -110,7 +110,7 @@ Page { } ToolButton { - icon.source: "menu.png" + icon.name: "menu" onClicked: optionsMenu.open() Menu { @@ -150,7 +150,7 @@ Page { highlighted: ListView.isCurrentItem onClicked: { listView.currentIndex = index - stackView.push(model.source) + stackView.push("pages/" + model.source) drawer.close() } } @@ -202,7 +202,7 @@ Page { anchors.centerIn: parent anchors.verticalCenterOffset: -50 fillMode: Image.PreserveAspectFit - source: "qt-logo.png" + source: "images/qt-logo.png" } Label { @@ -219,7 +219,7 @@ Page { Image { id: arrow - source: "arrow.png" + source: "images/arrow.png" anchors.left: parent.left anchors.bottom: parent.bottom } diff --git a/basicsuite/qtquickcontrols2/pages/DialogPage.qml b/basicsuite/qtquickcontrols2/pages/DialogPage.qml index 6458bf1..8bade21 100644 --- a/basicsuite/qtquickcontrols2/pages/DialogPage.qml +++ b/basicsuite/qtquickcontrols2/pages/DialogPage.qml @@ -156,7 +156,7 @@ ScrollablePage { width: parent.width / 2 anchors.horizontalCenter: parent.horizontalCenter fillMode: Image.PreserveAspectFit - source: "qt-logo.png" + source: "../images/qt-logo.png" } Label { diff --git a/basicsuite/qtquickcontrols2/pages/ScrollBarPage.qml b/basicsuite/qtquickcontrols2/pages/ScrollBarPage.qml index cc7de11..aaa1d8e 100644 --- a/basicsuite/qtquickcontrols2/pages/ScrollBarPage.qml +++ b/basicsuite/qtquickcontrols2/pages/ScrollBarPage.qml @@ -77,7 +77,7 @@ Flickable { Image { rotation: 90 - source: "arrows.png" + source: "../images/arrows.png" anchors.horizontalCenter: parent.horizontalCenter } } diff --git a/basicsuite/qtquickcontrols2/pages/ScrollIndicatorPage.qml b/basicsuite/qtquickcontrols2/pages/ScrollIndicatorPage.qml index dd5ef46..89b8bc1 100644 --- a/basicsuite/qtquickcontrols2/pages/ScrollIndicatorPage.qml +++ b/basicsuite/qtquickcontrols2/pages/ScrollIndicatorPage.qml @@ -77,7 +77,7 @@ Flickable { Image { rotation: 90 - source: "arrows.png" + source: "../images/arrows.png" anchors.horizontalCenter: parent.horizontalCenter } } diff --git a/basicsuite/qtquickcontrols2/pages/SwipeViewPage.qml b/basicsuite/qtquickcontrols2/pages/SwipeViewPage.qml index 3c5d04c..d09ac50 100644 --- a/basicsuite/qtquickcontrols2/pages/SwipeViewPage.qml +++ b/basicsuite/qtquickcontrols2/pages/SwipeViewPage.qml @@ -79,7 +79,7 @@ Pane { } Image { - source: "arrows.png" + source: "../images/arrows.png" anchors.horizontalCenter: parent.horizontalCenter } } diff --git a/basicsuite/qtquickcontrols2/pages/TabBarPage.qml b/basicsuite/qtquickcontrols2/pages/TabBarPage.qml index 925691a..16200fc 100644 --- a/basicsuite/qtquickcontrols2/pages/TabBarPage.qml +++ b/basicsuite/qtquickcontrols2/pages/TabBarPage.qml @@ -79,7 +79,7 @@ Page { } Image { - source: "arrows.png" + source: "../images/arrows.png" anchors.horizontalCenter: parent.horizontalCenter } } diff --git a/basicsuite/qtquickcontrols2/qtquickcontrols2.pro b/basicsuite/qtquickcontrols2/qtquickcontrols2.pro index 9834b89..1d3eac1 100644 --- a/basicsuite/qtquickcontrols2/qtquickcontrols2.pro +++ b/basicsuite/qtquickcontrols2/qtquickcontrols2.pro @@ -1,15 +1,15 @@ -TARGET = gallery +TARGET = qtquickcontrols2 include(../shared/shared.pri) b2qtdemo_deploy_defaults() content.files = \ - main.qml \ - qtquickcontrols2.conf \ - icons/gallery/index.theme \ - $$files(icons/*.png, true) \ - $$files(images/*.png) \ - $$files(pages/*.qml) + $$PWD/preview_l.jpg \ + $$PWD/main.qml \ + $$PWD/qtquickcontrols2.conf \ + $$PWD/images \ + $$PWD/icons \ + $$PWD/pages content.path = $$DESTPATH diff --git a/basicsuite/shared/main.cpp b/basicsuite/shared/main.cpp index 6fba612..265092c 100644 --- a/basicsuite/shared/main.cpp +++ b/basicsuite/shared/main.cpp @@ -65,6 +65,7 @@ #include #include #include +#include #if defined(USE_QTWEBENGINE) #include @@ -75,7 +76,10 @@ int main(int argc, char **argv) { //qputenv("QT_IM_MODULE", QByteArray("qtvkb")); - qputenv("QT_QUICK_CONTROLS_CONF", "/data/user/gallery/qtquickcontrols2.conf"); + qputenv("QT_QUICK_CONTROLS_CONF", "/data/user/qt/qtquickcontrols2/qtquickcontrols2.conf"); + QIcon::setThemeName("gallery"); + QIcon::setThemeSearchPaths(QStringList() << "/data/user/qt/qtquickcontrols2/icons"); + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication app(argc, argv); #if defined(USE_QTWEBENGINE) @@ -131,12 +135,11 @@ int main(int argc, char **argv) QGuiApplication::setFont(font); } - QSettings settings; - QString style = QQuickStyle::name(); - if (!style.isEmpty()) - settings.setValue("style", "Material"); - else - QQuickStyle::setStyle(settings.value("style").toString()); + QSettings styleSettings; + QString style = styleSettings.value("style").toString(); + if (style.isEmpty() || style == "Default") + styleSettings.setValue("style", "Material"); + QQuickStyle::setStyle(styleSettings.value("style").toString()); DummyEngine engine; -- cgit v1.2.3 From 83bffe92202f5cd7ed9ce642edebd617bb1c6303 Mon Sep 17 00:00:00 2001 From: Juho Annunen Date: Thu, 19 Jul 2018 12:44:14 +0300 Subject: Move color definitions to QSettings Task-number: QTBUG-69536 Change-Id: Ib18f19ce57266393e8d1c8ae8e7322e73ccafa53 Reviewed-by: Kimmo Ollila --- basicsuite/shared/main.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/basicsuite/shared/main.cpp b/basicsuite/shared/main.cpp index 265092c..58ff00f 100644 --- a/basicsuite/shared/main.cpp +++ b/basicsuite/shared/main.cpp @@ -148,6 +148,17 @@ int main(int argc, char **argv) applicationengine.rootContext()->setContextProperty("engine", &engine); applicationengine.rootContext()->setContextProperty("appFont", appFont); applicationengine.rootContext()->setContextProperty("availableStyles", QQuickStyle::availableStyles()); + + + QSettings themeColorSettings("QtLauncher", "colorSettings"); + + applicationengine.rootContext()->setContextProperty("_backgroundColor", themeColorSettings.value("backgroundColor", "#09102b")); + applicationengine.rootContext()->setContextProperty("_primaryGreen", themeColorSettings.value("primaryGreen", "#41cd52")); + applicationengine.rootContext()->setContextProperty("_mediumGreen", themeColorSettings.value("mediumGreen", "#21be2b")); + applicationengine.rootContext()->setContextProperty("_darkGreen", themeColorSettings.value("darkGreen", "#17a81a")); + applicationengine.rootContext()->setContextProperty("_primaryGrey", themeColorSettings.value("primaryGrey", "#9d9faa")); + applicationengine.rootContext()->setContextProperty("_secondaryGrey", themeColorSettings.value("secondaryGrey", "#3a4055")); + applicationengine.load(QUrl::fromLocalFile(path + "/SharedMain.qml")); app.exec(); -- cgit v1.2.3 From a60eb6782491ca42dd9139ad0a14866cdf064d40 Mon Sep 17 00:00:00 2001 From: Samuli Piippo Date: Thu, 2 Aug 2018 09:40:55 +0300 Subject: Disable graphical effect from imx7 boards GraphicalEffects require gpu which the imx7 boards do not have. ... also fix exclude filtering for webbrowser Change-Id: I0a14cbc1cec72a7b1e8f89bde22cb147bb2b7dbf Reviewed-by: Teemu Holappa --- basicsuite/demos.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/basicsuite/demos.xml b/basicsuite/demos.xml index 1d3a135..d0add1b 100644 --- a/basicsuite/demos.xml +++ b/basicsuite/demos.xml @@ -51,7 +51,7 @@ Shows how to make a 3D surface plot, displaying three layers from three differen --> - + This example shows the Qt Quick ShaderEffect type and the Qt Graphical Effects module. Qt Quick provides the ability to use inline GLSL in your Qt Quick applications to create stunning visual effects. @@ -77,7 +77,7 @@ The demo shows off a number features of Qt Quick. A nicely styled list control o --> - + This example demonstrates the use of Qt WebEngine with Qt Quick. -- cgit v1.2.3 From 4aa85d783e7e3e729ee4a4d772869236bf60d326 Mon Sep 17 00:00:00 2001 From: Juho Annunen Date: Mon, 30 Jul 2018 11:27:56 +0300 Subject: Use QSettings for color definitions Task-number: QTBUG-69536 Change-Id: I4c1fa7758db6f593dd38050a75d276fcc85346ac Reviewed-by: Teemu Holappa --- basicsuite/enterprise-charts/View1.qml | 11 +++++------ basicsuite/enterprise-charts/View10.qml | 7 +++---- basicsuite/enterprise-charts/View11.qml | 7 +++---- basicsuite/enterprise-charts/View12.qml | 15 +++++++-------- basicsuite/enterprise-charts/View2.qml | 3 +-- basicsuite/enterprise-charts/View3.qml | 3 +-- basicsuite/enterprise-charts/View4.qml | 9 ++++----- basicsuite/enterprise-charts/View5.qml | 5 ++--- basicsuite/enterprise-charts/View6.qml | 7 +++---- basicsuite/enterprise-charts/View7.qml | 7 +++---- basicsuite/enterprise-charts/View8.qml | 7 +++---- basicsuite/enterprise-charts/View9.qml | 7 +++---- basicsuite/enterprise-charts/enterprise-charts.pro | 1 - basicsuite/enterprise-charts/main.qml | 3 +-- basicsuite/graphicaleffects/graphicaleffects.pro | 1 - basicsuite/graphicaleffects/main.qml | 9 ++++----- basicsuite/mediaplayer/ControlBar.qml | 3 +-- basicsuite/mediaplayer/EffectSelectionPanel.qml | 5 ++--- basicsuite/mediaplayer/FileBrowser.qml | 11 ++++++----- basicsuite/mediaplayer/ImageButton.qml | 3 +-- basicsuite/mediaplayer/MetadataView.qml | 5 ++--- basicsuite/mediaplayer/ParameterPanel.qml | 3 +-- basicsuite/mediaplayer/PlaybackControl.qml | 5 ++--- basicsuite/mediaplayer/PlayerSlider.qml | 5 ++--- basicsuite/mediaplayer/UrlBar.qml | 7 +++---- basicsuite/mediaplayer/VolumeControl.qml | 9 ++++----- basicsuite/mediaplayer/main.qml | 1 - basicsuite/mediaplayer/mediaplayer.pro | 3 +-- 28 files changed, 68 insertions(+), 94 deletions(-) diff --git a/basicsuite/enterprise-charts/View1.qml b/basicsuite/enterprise-charts/View1.qml index e8c3407..dad431b 100644 --- a/basicsuite/enterprise-charts/View1.qml +++ b/basicsuite/enterprise-charts/View1.qml @@ -52,7 +52,6 @@ import QtQuick 2.0 //![2] import QtCharts 2.0 -import "settings.js" as Settings Item { anchors.fill: parent @@ -66,11 +65,11 @@ Item { anchors.fill: parent PieSeries { id: pieSeries - PieSlice { label: "Volkswagen"; value: 13.5; color: Settings.primaryGreen } - PieSlice { label: "Toyota"; value: 10.9; color: Settings.mediumGreen } - PieSlice { label: "Ford"; value: 8.6; color: Settings.darkGreen } - PieSlice { label: "Skoda"; value: 8.2; color: Settings.primaryGrey } - PieSlice { label: "Volvo"; value: 6.8; color: Settings.secondaryGrey } + PieSlice { label: "Volkswagen"; value: 13.5; color: _primaryGreen } + PieSlice { label: "Toyota"; value: 10.9; color: _mediumGreen } + PieSlice { label: "Ford"; value: 8.6; color: _darkGreen } + PieSlice { label: "Skoda"; value: 8.2; color: _primaryGrey } + PieSlice { label: "Volvo"; value: 6.8; color: _secondaryGrey } } } diff --git a/basicsuite/enterprise-charts/View10.qml b/basicsuite/enterprise-charts/View10.qml index 6bb3eb5..b61236f 100644 --- a/basicsuite/enterprise-charts/View10.qml +++ b/basicsuite/enterprise-charts/View10.qml @@ -50,7 +50,6 @@ import QtQuick 2.0 import QtCharts 2.0 -import "settings.js" as Settings Item { anchors.fill: parent @@ -61,9 +60,9 @@ Item { HorizontalStackedBarSeries { axisY: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] } - BarSet { label: "Bob"; color: Settings.primaryGreen; values: [2, 2, 3, 4, 5, 6] } - BarSet { label: "Susan"; color: Settings.primaryGrey; values: [5, 1, 2, 4, 1, 7] } - BarSet { label: "James"; color: Settings.secondaryGrey; values: [3, 5, 8, 13, 5, 8] } + BarSet { label: "Bob"; color: _primaryGreen; values: [2, 2, 3, 4, 5, 6] } + BarSet { label: "Susan"; color: _primaryGrey; values: [5, 1, 2, 4, 1, 7] } + BarSet { label: "James"; color: _secondaryGrey; values: [3, 5, 8, 13, 5, 8] } } Component.onCompleted: { axes[0].labelsColor = "white"; diff --git a/basicsuite/enterprise-charts/View11.qml b/basicsuite/enterprise-charts/View11.qml index c884627..319e94a 100644 --- a/basicsuite/enterprise-charts/View11.qml +++ b/basicsuite/enterprise-charts/View11.qml @@ -50,7 +50,6 @@ import QtQuick 2.0 import QtCharts 2.0 -import "settings.js" as Settings Item { anchors.fill: parent @@ -61,9 +60,9 @@ Item { HorizontalPercentBarSeries { axisY: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] } - BarSet { label: "Bob"; color: Settings.primaryGreen; values: [2, 2, 3, 4, 5, 6] } - BarSet { label: "Susan"; color: Settings.primaryGrey; values: [5, 1, 2, 4, 1, 7] } - BarSet { label: "James"; color: Settings.secondaryGrey; values: [3, 5, 8, 13, 5, 8] } + BarSet { label: "Bob"; color: _primaryGreen; values: [2, 2, 3, 4, 5, 6] } + BarSet { label: "Susan"; color: _primaryGrey; values: [5, 1, 2, 4, 1, 7] } + BarSet { label: "James"; color: _secondaryGrey; values: [3, 5, 8, 13, 5, 8] } } Component.onCompleted: { diff --git a/basicsuite/enterprise-charts/View12.qml b/basicsuite/enterprise-charts/View12.qml index 90cfa8e..bd40cbd 100644 --- a/basicsuite/enterprise-charts/View12.qml +++ b/basicsuite/enterprise-charts/View12.qml @@ -50,7 +50,6 @@ import QtQuick 2.0 import QtCharts 2.0 -import "settings.js" as Settings Item { anchors.fill: parent @@ -65,8 +64,8 @@ Item { size: 0.96 holeSize: 0.7 - PieSlice { id: slice; label: "Alpha"; value: 19511; color: Settings.primaryGreen; borderColor: "#163430" } - PieSlice { label: "Epsilon"; value: 11105; color: Settings.primaryGrey; borderColor: "#3B391C" } + PieSlice { id: slice; label: "Alpha"; value: 19511; color: _primaryGreen; borderColor: "#163430" } + PieSlice { label: "Epsilon"; value: 11105; color: _primaryGrey; borderColor: "#3B391C" } PieSlice { label: "Psi"; value: 9352; color: darkGrey2; borderColor: "#13060C" } } @@ -74,17 +73,17 @@ Item { size: 0.7 id: pieInner holeSize: 0.25 - PieSlice { label: "Materials"; value: 10334; color: Settings.mediumGreen; borderColor: "#163430" } - PieSlice { label: "Employee"; value: 3066; color: Settings.darkGreen; borderColor: "#163430" } - PieSlice { label: "Logistics"; value: 6111; color: Settings.mediumGreen; borderColor: "#163430" } + PieSlice { label: "Materials"; value: 10334; color: _mediumGreen; borderColor: "#163430" } + PieSlice { label: "Employee"; value: 3066; color: _darkGreen; borderColor: "#163430" } + PieSlice { label: "Logistics"; value: 6111; color: _mediumGreen; borderColor: "#163430" } PieSlice { label: "Materials"; value: 7371; color: mediumGrey2; borderColor: "#3B391C" } PieSlice { label: "Employee"; value: 2443; color: mediumGrey; borderColor: "#3B391C" } PieSlice { label: "Logistics"; value: 1291; color: mediumGrey2; borderColor: "#3B391C" } - PieSlice { label: "Materials"; value: 4022; color: Settings.secondaryGrey; borderColor: "#13060C" } + PieSlice { label: "Materials"; value: 4022; color: _secondaryGrey; borderColor: "#13060C" } PieSlice { label: "Employee"; value: 3998; color: darkGrey; borderColor: "#13060C" } - PieSlice { label: "Logistics"; value: 1332; color: Settings.secondaryGrey; borderColor: "#13060C" } + PieSlice { label: "Logistics"; value: 1332; color: _secondaryGrey; borderColor: "#13060C" } } } diff --git a/basicsuite/enterprise-charts/View2.qml b/basicsuite/enterprise-charts/View2.qml index dbf8813..8f201a6 100644 --- a/basicsuite/enterprise-charts/View2.qml +++ b/basicsuite/enterprise-charts/View2.qml @@ -50,7 +50,6 @@ import QtQuick 2.0 import QtCharts 2.0 -import "settings.js" as Settings Item { anchors.fill: parent @@ -60,7 +59,7 @@ Item { anchors.fill: parent LineSeries { name: "LineSeries" - color: Settings.primaryGreen + color: _primaryGreen XYPoint { x: 0; y: 0 } XYPoint { x: 1.1; y: 2.1 } XYPoint { x: 1.9; y: 3.3 } diff --git a/basicsuite/enterprise-charts/View3.qml b/basicsuite/enterprise-charts/View3.qml index a0894fe..3211e9e 100644 --- a/basicsuite/enterprise-charts/View3.qml +++ b/basicsuite/enterprise-charts/View3.qml @@ -50,7 +50,6 @@ import QtQuick 2.0 import QtCharts 2.0 -import "settings.js" as Settings Item { anchors.fill: parent @@ -60,7 +59,7 @@ Item { anchors.fill: parent SplineSeries { name: "SplineSeries" - color: Settings.primaryGreen + color: _primaryGreen XYPoint { x: 0; y: 0.0 } XYPoint { x: 1.1; y: 3.2 } XYPoint { x: 1.9; y: 2.4 } diff --git a/basicsuite/enterprise-charts/View4.qml b/basicsuite/enterprise-charts/View4.qml index 7b0b823..442d231 100644 --- a/basicsuite/enterprise-charts/View4.qml +++ b/basicsuite/enterprise-charts/View4.qml @@ -50,7 +50,6 @@ import QtQuick 2.0 import QtCharts 2.0 -import "settings.js" as Settings Item { anchors.fill: parent @@ -69,7 +68,7 @@ Item { AreaSeries { name: "Russian" color: mediumGrey2 - borderColor: Settings.darkGreen + borderColor: _darkGreen borderWidth: 3 axisX: valueAxis upperSeries: LineSeries { @@ -92,7 +91,7 @@ Item { AreaSeries { name: "Swedish" color: lightGrey - borderColor: Settings.mediumGreen + borderColor: _mediumGreen borderWidth: 3 axisX: valueAxis upperSeries: LineSeries { @@ -113,8 +112,8 @@ Item { AreaSeries { name: "Finnish" - color: Settings.secondaryGrey - borderColor: Settings.primaryGreen + color: _secondaryGrey + borderColor: _primaryGreen borderWidth: 3 axisX: valueAxis upperSeries: LineSeries { diff --git a/basicsuite/enterprise-charts/View5.qml b/basicsuite/enterprise-charts/View5.qml index 9b8ba09..be7794b 100644 --- a/basicsuite/enterprise-charts/View5.qml +++ b/basicsuite/enterprise-charts/View5.qml @@ -50,7 +50,6 @@ import QtQuick 2.0 import QtCharts 2.0 -import "settings.js" as Settings Item { anchors.fill: parent @@ -61,7 +60,7 @@ Item { ScatterSeries { id: scatter1 name: "Scatter1" - color: Settings.primaryGreen + color: _primaryGreen XYPoint { x: 1.5; y: 1.5 } XYPoint { x: 1.5; y: 1.6 } XYPoint { x: 1.57; y: 1.55 } @@ -73,7 +72,7 @@ Item { ScatterSeries { name: "Scatter2" - color: Settings.primaryGrey + color: _primaryGrey //![1] XYPoint { x: 2.0; y: 2.0 } XYPoint { x: 2.0; y: 2.1 } diff --git a/basicsuite/enterprise-charts/View6.qml b/basicsuite/enterprise-charts/View6.qml index b2ee347..a104b8a 100644 --- a/basicsuite/enterprise-charts/View6.qml +++ b/basicsuite/enterprise-charts/View6.qml @@ -50,7 +50,6 @@ import QtQuick 2.0 import QtCharts 2.0 -import "settings.js" as Settings Item { anchors.fill: parent @@ -61,9 +60,9 @@ Item { BarSeries { id: mySeries axisX: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] } - BarSet { label: "Bob"; color: Settings.primaryGreen; values: [2, 2, 3, 4, 5, 6] } - BarSet { label: "Susan"; color: Settings.primaryGrey; values: [5, 1, 2, 4, 1, 7] } - BarSet { label: "James"; color: Settings.secondaryGrey; values: [3, 5, 8, 13, 5, 8] } + BarSet { label: "Bob"; color: _primaryGreen; values: [2, 2, 3, 4, 5, 6] } + BarSet { label: "Susan"; color: _primaryGrey; values: [5, 1, 2, 4, 1, 7] } + BarSet { label: "James"; color: _secondaryGrey; values: [3, 5, 8, 13, 5, 8] } } Component.onCompleted: { diff --git a/basicsuite/enterprise-charts/View7.qml b/basicsuite/enterprise-charts/View7.qml index afcfd03..78e5350 100644 --- a/basicsuite/enterprise-charts/View7.qml +++ b/basicsuite/enterprise-charts/View7.qml @@ -50,7 +50,6 @@ import QtQuick 2.0 import QtCharts 2.0 -import "settings.js" as Settings Item { anchors.fill: parent @@ -61,9 +60,9 @@ Item { StackedBarSeries { id: mySeries axisX: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] } - BarSet { label: "Bob"; color: Settings.primaryGreen; values: [2, 2, 3, 4, 5, 6] } - BarSet { label: "Susan"; color: Settings.primaryGrey; values: [5, 1, 2, 4, 1, 7] } - BarSet { label: "James"; color: Settings.secondaryGrey; values: [3, 5, 8, 13, 5, 8] } + BarSet { label: "Bob"; color: _primaryGreen; values: [2, 2, 3, 4, 5, 6] } + BarSet { label: "Susan"; color: _primaryGrey; values: [5, 1, 2, 4, 1, 7] } + BarSet { label: "James"; color: _secondaryGrey; values: [3, 5, 8, 13, 5, 8] } } Component.onCompleted: { axes[0].labelsColor = "white"; diff --git a/basicsuite/enterprise-charts/View8.qml b/basicsuite/enterprise-charts/View8.qml index 81fc60a..803b6cd 100644 --- a/basicsuite/enterprise-charts/View8.qml +++ b/basicsuite/enterprise-charts/View8.qml @@ -50,7 +50,6 @@ import QtQuick 2.0 import QtCharts 2.0 -import "settings.js" as Settings Item { anchors.fill: parent @@ -60,9 +59,9 @@ Item { anchors.fill: parent PercentBarSeries { axisX: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] } - BarSet { label: "Bob"; color: Settings.primaryGreen; values: [2, 2, 3, 4, 5, 6] } - BarSet { label: "Susan"; color: Settings.primaryGrey; values: [5, 1, 2, 4, 1, 7] } - BarSet { label: "James"; color: Settings.secondaryGrey; values: [3, 5, 8, 13, 5, 8] } + BarSet { label: "Bob"; color: _primaryGreen; values: [2, 2, 3, 4, 5, 6] } + BarSet { label: "Susan"; color: _primaryGrey; values: [5, 1, 2, 4, 1, 7] } + BarSet { label: "James"; color: _secondaryGrey; values: [3, 5, 8, 13, 5, 8] } } Component.onCompleted: { diff --git a/basicsuite/enterprise-charts/View9.qml b/basicsuite/enterprise-charts/View9.qml index ab68c5c..a85711e 100644 --- a/basicsuite/enterprise-charts/View9.qml +++ b/basicsuite/enterprise-charts/View9.qml @@ -50,7 +50,6 @@ import QtQuick 2.0 import QtCharts 2.0 -import "settings.js" as Settings Item { anchors.fill: parent @@ -60,9 +59,9 @@ Item { anchors.fill: parent HorizontalBarSeries { axisY: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] } - BarSet { label: "Bob"; color: Settings.primaryGreen; values: [2, 2, 3, 4, 5, 6] } - BarSet { label: "Susan"; color: Settings.primaryGrey; values: [5, 1, 2, 4, 1, 7] } - BarSet { label: "James"; color: Settings.secondaryGrey; values: [3, 5, 8, 13, 5, 8] } + BarSet { label: "Bob"; color: _primaryGreen; values: [2, 2, 3, 4, 5, 6] } + BarSet { label: "Susan"; color: _primaryGrey; values: [5, 1, 2, 4, 1, 7] } + BarSet { label: "James"; color: _secondaryGrey; values: [3, 5, 8, 13, 5, 8] } } Component.onCompleted: { diff --git a/basicsuite/enterprise-charts/enterprise-charts.pro b/basicsuite/enterprise-charts/enterprise-charts.pro index cef306b..b71e6eb 100644 --- a/basicsuite/enterprise-charts/enterprise-charts.pro +++ b/basicsuite/enterprise-charts/enterprise-charts.pro @@ -19,7 +19,6 @@ content.files = \ View7.qml \ View8.qml \ View9.qml \ - ../shared/settings.js content.path = $$DESTPATH diff --git a/basicsuite/enterprise-charts/main.qml b/basicsuite/enterprise-charts/main.qml index 03b822e..5fadbbd 100644 --- a/basicsuite/enterprise-charts/main.qml +++ b/basicsuite/enterprise-charts/main.qml @@ -51,13 +51,12 @@ //![1] import QtQuick 2.0 //![1] -import "settings.js" as Settings Rectangle { width: 600 height: 400 property bool sourceLoaded: false - color: Settings.backgroundColor + color: _backgroundColor property string darkGrey: "#222840" property string darkGrey2: "#53586b" diff --git a/basicsuite/graphicaleffects/graphicaleffects.pro b/basicsuite/graphicaleffects/graphicaleffects.pro index 3fe7c51..da9e8a3 100644 --- a/basicsuite/graphicaleffects/graphicaleffects.pro +++ b/basicsuite/graphicaleffects/graphicaleffects.pro @@ -18,7 +18,6 @@ content.files = \ effect_ThresholdMask.qml \ main.qml \ images \ - ../shared/settings.js content.path = $$DESTPATH diff --git a/basicsuite/graphicaleffects/main.qml b/basicsuite/graphicaleffects/main.qml index 9da3676..4eb694d 100644 --- a/basicsuite/graphicaleffects/main.qml +++ b/basicsuite/graphicaleffects/main.qml @@ -48,7 +48,6 @@ ** ****************************************************************************/ import QtQuick 2.0 -import "settings.js" as Settings Item { id: root @@ -74,7 +73,7 @@ Item { anchors.right: checkers.left anchors.top: parent.top anchors.bottom: parent.bottom - color: Settings.backgroundColor + color: _backgroundColor } ListModel { @@ -121,7 +120,7 @@ Item { property bool isSelected: list.currentIndex == index Text { - color: parent.isSelected ? Settings.primaryGreen : "white" + color: parent.isSelected ? _primaryGreen : "white" font.pixelSize: parent.height * 0.625 font.family: appFont font.styleName: parent.isSelected ? "Bold" : "Regular" @@ -159,7 +158,7 @@ Item { var margin = canvas.padding; var segmentSize = 4 - ctx.strokeStyle = Settings.primaryGrey + ctx.strokeStyle = _primaryGrey ctx.beginPath(); ctx.moveTo(margin, margin); ctx.lineTo(margin, h-margin); @@ -179,7 +178,7 @@ Item { } Rectangle { - color: Settings.primaryGreen + color: _primaryGreen width: parent.width / 20 height: width radius: width / 2 diff --git a/basicsuite/mediaplayer/ControlBar.qml b/basicsuite/mediaplayer/ControlBar.qml index fed8a77..e4f0665 100644 --- a/basicsuite/mediaplayer/ControlBar.qml +++ b/basicsuite/mediaplayer/ControlBar.qml @@ -50,12 +50,11 @@ import QtQuick 2.0 import QtMultimedia 5.0 -import "settings.js" as Settings Rectangle { id: controlBar height: parent.height * 0.225 - color: Settings.backgroundColor + color: _backgroundColor property MediaPlayer mediaPlayer: null property bool isMouseAbove: false diff --git a/basicsuite/mediaplayer/EffectSelectionPanel.qml b/basicsuite/mediaplayer/EffectSelectionPanel.qml index 4daded0..0af10a5 100644 --- a/basicsuite/mediaplayer/EffectSelectionPanel.qml +++ b/basicsuite/mediaplayer/EffectSelectionPanel.qml @@ -48,11 +48,10 @@ ** ****************************************************************************/ import QtQuick 2.0 -import "settings.js" as Settings Rectangle { id: root - color: Settings.backgroundColor + color: _backgroundColor height: 78 property int itemHeight: 25 property string effectSource: "" @@ -159,7 +158,7 @@ Rectangle { width: parent.width property bool isSelected: list.currentIndex == index Text { - color: parent.isSelected ? Settings.primaryGreen : "white" + color: parent.isSelected ? _primaryGreen : "white" text: name anchors.centerIn: parent font.pixelSize: 20 diff --git a/basicsuite/mediaplayer/FileBrowser.qml b/basicsuite/mediaplayer/FileBrowser.qml index aae608f..da51001 100644 --- a/basicsuite/mediaplayer/FileBrowser.qml +++ b/basicsuite/mediaplayer/FileBrowser.qml @@ -51,7 +51,6 @@ import QtQuick 2.0 import Qt.labs.folderlistmodel 2.0 import QtQuick.Controls 1.4 import QtDeviceUtilities.QtButtonImageProvider 1.0 -import "settings.js" as Settings Item { id: fileBrowser @@ -79,7 +78,7 @@ Item { Rectangle { id: root - color: Settings.backgroundColor + color: _backgroundColor property alias folder: folders.folder FolderListModel { @@ -113,7 +112,7 @@ Item { text: fileName font.pixelSize: parent.height * .1 font.family: appFont - color: view.currentIndex === index ? Settings.primaryGreen : "white" + color: view.currentIndex === index ? _primaryGreen : "white" elide: Text.ElideRight } @@ -185,7 +184,7 @@ Item { Rectangle { width: parent.width; height: 70 - color: Settings.backgroundColor + color: _backgroundColor id: titleBar QtButton { @@ -195,6 +194,7 @@ Item { anchors.leftMargin: parent.width * .05 anchors.verticalCenter: parent.verticalCenter onClicked: up() + fillColor: _primaryGreen } Text { @@ -220,13 +220,14 @@ Item { anchors.rightMargin: parent.width * .05 anchors.verticalCenter: parent.verticalCenter onClicked: fileBrowser.selectFile("") + fillColor: _primaryGreen } Rectangle { width: parent.width anchors.bottom: parent.bottom height: 2 - color: Settings.primaryGrey + color: _primaryGrey } } diff --git a/basicsuite/mediaplayer/ImageButton.qml b/basicsuite/mediaplayer/ImageButton.qml index 982cc49..cb4dcb4 100644 --- a/basicsuite/mediaplayer/ImageButton.qml +++ b/basicsuite/mediaplayer/ImageButton.qml @@ -50,7 +50,6 @@ import QtQuick 2.0 import QtGraphicalEffects 1.0 -import "settings.js" as Settings Item { id: root @@ -81,7 +80,7 @@ Item { id: glowEffect anchors.fill: image source: image - color: pressed ? "#22000000" : checked ? Settings.primaryGreen : "white" + color: pressed ? "#22000000" : checked ? _primaryGreen : "white" visible: checked || hover || pressed } diff --git a/basicsuite/mediaplayer/MetadataView.qml b/basicsuite/mediaplayer/MetadataView.qml index d6f45d8..34b53b4 100644 --- a/basicsuite/mediaplayer/MetadataView.qml +++ b/basicsuite/mediaplayer/MetadataView.qml @@ -49,7 +49,6 @@ ****************************************************************************/ import QtQuick 2.0 import QtMultimedia 5.0 -import "settings.js" as Settings Rectangle { id: root @@ -64,11 +63,11 @@ Rectangle { Rectangle { height: column.height + 30 width: 500 - color: Settings.backgroundColor + color: _backgroundColor opacity: 0.9 anchors.centerIn: parent anchors.verticalCenterOffset: -50 - border.color: Settings.primaryGrey + border.color: _primaryGrey border.width: 2 Column { diff --git a/basicsuite/mediaplayer/ParameterPanel.qml b/basicsuite/mediaplayer/ParameterPanel.qml index 1378827..81bba63 100644 --- a/basicsuite/mediaplayer/ParameterPanel.qml +++ b/basicsuite/mediaplayer/ParameterPanel.qml @@ -48,12 +48,11 @@ ** ****************************************************************************/ import QtQuick 2.0 -import "settings.js" as Settings Rectangle { id: root height: view.model.count * sliderHeight - color: Settings.backgroundColor + color: _backgroundColor property color lineColor: "black" property real spacing: 10 property real sliderHeight: 50 diff --git a/basicsuite/mediaplayer/PlaybackControl.qml b/basicsuite/mediaplayer/PlaybackControl.qml index 7c90fa6..99b1d5c 100644 --- a/basicsuite/mediaplayer/PlaybackControl.qml +++ b/basicsuite/mediaplayer/PlaybackControl.qml @@ -50,7 +50,6 @@ import QtQuick 2.0 import QtDeviceUtilities.QtButtonImageProvider 1.0 -import "settings.js" as Settings Row { anchors.leftMargin: parent.width * 0.02 @@ -73,7 +72,7 @@ Row { height: width anchors.bottom: parent.bottom anchors.bottomMargin: root.spacing - fillColor: Settings.primaryGreen + fillColor: _primaryGreen Image{ anchors.centerIn: parent width: parent.width * 0.5 @@ -92,7 +91,7 @@ Row { height: width anchors.bottom: parent.bottom anchors.bottomMargin: root.spacing - fillColor: Settings.primaryGreen + fillColor: _primaryGreen Image{ anchors.centerIn: parent width: parent.width * 0.5 diff --git a/basicsuite/mediaplayer/PlayerSlider.qml b/basicsuite/mediaplayer/PlayerSlider.qml index 68c21e1..0ec52b5 100644 --- a/basicsuite/mediaplayer/PlayerSlider.qml +++ b/basicsuite/mediaplayer/PlayerSlider.qml @@ -48,7 +48,6 @@ ** ****************************************************************************/ import QtQuick 2.0 -import "settings.js" as Settings Item { id: slider @@ -82,7 +81,7 @@ Item { width: slider.width anchors.verticalCenter: slider.verticalCenter height: 5 - color: Settings.primaryGrey + color: _primaryGrey radius: 2 MouseArea { @@ -129,7 +128,7 @@ Item { width: 40 height: width radius: width / 2 - color: Settings.primaryGreen + color: _primaryGreen antialiasing: true anchors.centerIn: handle visible: true diff --git a/basicsuite/mediaplayer/UrlBar.qml b/basicsuite/mediaplayer/UrlBar.qml index cb822ff..73e9cc5 100644 --- a/basicsuite/mediaplayer/UrlBar.qml +++ b/basicsuite/mediaplayer/UrlBar.qml @@ -49,7 +49,6 @@ ****************************************************************************/ import QtQuick 2.0 import QtQuick.Controls 2.0 -import "settings.js" as Settings Rectangle { id: root @@ -93,9 +92,9 @@ Rectangle { font.family: appFont font.styleName: "Light" background: Rectangle { - color: Settings.backgroundColor + color: _backgroundColor opacity: 0.8 - border.color: Settings.primaryGrey + border.color: _primaryGrey border.width: 2 } onAccepted: root.urlAccepted(urlInput.text); @@ -107,7 +106,7 @@ Rectangle { anchors.verticalCenter: urlBar.verticalCenter height: 70 width: 70 - color: Settings.primaryGrey + color: _primaryGrey MouseArea { anchors.fill: parent onClicked: { urlInput.text = ""; urlInput.paste(); } diff --git a/basicsuite/mediaplayer/VolumeControl.qml b/basicsuite/mediaplayer/VolumeControl.qml index 9536d12..4369d04 100644 --- a/basicsuite/mediaplayer/VolumeControl.qml +++ b/basicsuite/mediaplayer/VolumeControl.qml @@ -51,7 +51,6 @@ import QtQuick 2.0 import QtDeviceUtilities.QtButtonImageProvider 1.0 import QtQuick.Controls 2.2 -import "settings.js" as Settings Item { id: root @@ -69,7 +68,7 @@ Item { anchors.bottom: parent.bottom anchors.bottomMargin: controlBar.width * 0.02 anchors.horizontalCenter: parent.horizontalCenter - fillColor: Settings.primaryGreen + fillColor: _primaryGreen Image{ anchors.centerIn: parent @@ -104,7 +103,7 @@ Item { width: controlBar.width * 0.06 height: width anchors.bottom: parent.bottom - fillColor: Settings.primaryGrey + fillColor: _primaryGrey borderColor: "transparent" Image{ anchors.centerIn: parent @@ -140,7 +139,7 @@ Item { Rectangle{ height: volumeSlider.visualPosition * parent.height width: parent.width - color: Settings.primaryGrey + color: _primaryGrey radius: 2 } } @@ -150,7 +149,7 @@ Item { width: sliderBackground.width * 7 height: width radius: height * 0.5 - color: Settings.primaryGreen + color: _primaryGreen } } diff --git a/basicsuite/mediaplayer/main.qml b/basicsuite/mediaplayer/main.qml index ec8719d..527e735 100644 --- a/basicsuite/mediaplayer/main.qml +++ b/basicsuite/mediaplayer/main.qml @@ -51,7 +51,6 @@ import QtQuick 2.0 import QtMultimedia 5.0 import QtDeviceUtilities.QtButtonImageProvider 1.0 -import "settings.js" as Settings FocusScope { id: applicationWindow diff --git a/basicsuite/mediaplayer/mediaplayer.pro b/basicsuite/mediaplayer/mediaplayer.pro index 1487620..c56ba88 100644 --- a/basicsuite/mediaplayer/mediaplayer.pro +++ b/basicsuite/mediaplayer/mediaplayer.pro @@ -20,8 +20,7 @@ content.files = \ UrlBar.qml \ VolumeControl.qml \ Effects \ - images \ - ../shared/settings.js + images content.path = $$DESTPATH -- cgit v1.2.3 From e81384c45e5c0b90e07057abd2a8788272d14c0f Mon Sep 17 00:00:00 2001 From: Juho Annunen Date: Mon, 6 Aug 2018 09:10:39 +0300 Subject: Remove confusing highlighting on media player file browser Task-number: QTBUG-62791 Change-Id: Ic7e4db3278bf9df28f2d5cb0f1a4d0aa50aade2d Reviewed-by: Samuli Piippo Reviewed-by: Teemu Holappa --- basicsuite/mediaplayer/FileBrowser.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basicsuite/mediaplayer/FileBrowser.qml b/basicsuite/mediaplayer/FileBrowser.qml index da51001..a2028f4 100644 --- a/basicsuite/mediaplayer/FileBrowser.qml +++ b/basicsuite/mediaplayer/FileBrowser.qml @@ -112,7 +112,7 @@ Item { text: fileName font.pixelSize: parent.height * .1 font.family: appFont - color: view.currentIndex === index ? _primaryGreen : "white" + color: mouseRegion.pressed ? _primaryGreen : "white" elide: Text.ElideRight } -- cgit v1.2.3 From 3594ea2a2dec8a74c2e8baf307c13671ebbdf18c Mon Sep 17 00:00:00 2001 From: Juho Annunen Date: Tue, 21 Aug 2018 14:44:48 +0300 Subject: Fix scaling, video path & focusing issues on mediaplayer demo Task-number: QTBUG-62791 Change-Id: I8ea9bcc27fcf0b2d4fb9f7b8ada165f7a5a5d7c8 Reviewed-by: Teemu Holappa --- basicsuite/mediaplayer/ControlBar.qml | 5 +- basicsuite/mediaplayer/EffectSelectionPanel.qml | 7 +-- basicsuite/mediaplayer/FileBrowser.qml | 2 +- basicsuite/mediaplayer/ImageButton.qml | 2 + basicsuite/mediaplayer/ParameterPanel.qml | 14 ++--- basicsuite/mediaplayer/VolumeControl.qml | 5 +- basicsuite/mediaplayer/main.qml | 74 ++++++++++++++++--------- basicsuite/shared/main.cpp | 6 ++ 8 files changed, 71 insertions(+), 44 deletions(-) diff --git a/basicsuite/mediaplayer/ControlBar.qml b/basicsuite/mediaplayer/ControlBar.qml index e4f0665..cdf27f2 100644 --- a/basicsuite/mediaplayer/ControlBar.qml +++ b/basicsuite/mediaplayer/ControlBar.qml @@ -164,14 +164,13 @@ Rectangle { anchors.right: volumeControl.left anchors.rightMargin: 15 anchors.bottom: seekControl.top - spacing: 22 - + spacing: itemMargin + height: parent.height * 0.275 ImageButton { id: fxButton imageSource: "images/FXButton.png" checkable: true checked: effectSelectionPanel.visible - onClicked: { openFX(); } diff --git a/basicsuite/mediaplayer/EffectSelectionPanel.qml b/basicsuite/mediaplayer/EffectSelectionPanel.qml index 0af10a5..9aee910 100644 --- a/basicsuite/mediaplayer/EffectSelectionPanel.qml +++ b/basicsuite/mediaplayer/EffectSelectionPanel.qml @@ -52,7 +52,6 @@ import QtQuick 2.0 Rectangle { id: root color: _backgroundColor - height: 78 property int itemHeight: 25 property string effectSource: "" property bool isMouseAbove: mouseAboveMonitor.containsMouse @@ -141,7 +140,7 @@ Rectangle { id: list anchors.fill: parent clip: true - anchors.margins: 14 + anchors.margins: itemMargin model: sources focus: root.visible && root.opacity && urlBar.opacity === 0 @@ -154,14 +153,14 @@ Rectangle { } delegate: Item { - height: 40 + height: itemHeight width: parent.width property bool isSelected: list.currentIndex == index Text { color: parent.isSelected ? _primaryGreen : "white" text: name anchors.centerIn: parent - font.pixelSize: 20 + font.pixelSize: defaultFontSize font.family: appFont font.styleName: parent.isSelected ? "Bold" : "Regular" } diff --git a/basicsuite/mediaplayer/FileBrowser.qml b/basicsuite/mediaplayer/FileBrowser.qml index a2028f4..a111177 100644 --- a/basicsuite/mediaplayer/FileBrowser.qml +++ b/basicsuite/mediaplayer/FileBrowser.qml @@ -55,7 +55,7 @@ import QtDeviceUtilities.QtButtonImageProvider 1.0 Item { id: fileBrowser - property string folder: "file:///data/videos" + property string folder: VideosLocation signal fileSelected(string file) diff --git a/basicsuite/mediaplayer/ImageButton.qml b/basicsuite/mediaplayer/ImageButton.qml index cb4dcb4..66888ef 100644 --- a/basicsuite/mediaplayer/ImageButton.qml +++ b/basicsuite/mediaplayer/ImageButton.qml @@ -74,6 +74,8 @@ Item { visible: true opacity: pressed ? 0.6 : 1 smooth: true + height: toolbarMenuButtons.height + width: height } ColorOverlay { diff --git a/basicsuite/mediaplayer/ParameterPanel.qml b/basicsuite/mediaplayer/ParameterPanel.qml index 81bba63..b67381a 100644 --- a/basicsuite/mediaplayer/ParameterPanel.qml +++ b/basicsuite/mediaplayer/ParameterPanel.qml @@ -51,11 +51,10 @@ import QtQuick 2.0 Rectangle { id: root - height: view.model.count * sliderHeight color: _backgroundColor property color lineColor: "black" property real spacing: 10 - property real sliderHeight: 50 + property real sliderHeight: height * 0.4 property bool isMouseAbove: mouseAboveMonitor.containsMouse property ListModel model: ListModel { } @@ -82,15 +81,16 @@ Rectangle { anchors { top: parent.top bottom: parent.bottom - leftMargin: 15 + leftMargin: itemMargin left: parent.left } horizontalAlignment: Text.AlignRight verticalAlignment: Text.AlignVCenter - font.pixelSize: 20 + font.pixelSize: defaultFontSize font.capitalization: Font.Capitalize font.family: appFont - width: 90 + width: root.width * 0.2 + fontSizeMode: Text.Fit } PlayerSlider { @@ -98,9 +98,9 @@ Rectangle { verticalCenter: text.verticalCenter verticalCenterOffset: 3 left: text.right - leftMargin: 20 + leftMargin: itemMargin right: parent.right - rightMargin: 20 + rightMargin: itemMargin } value: model.value onValueChanged: view.model.setProperty(index, "value", value) diff --git a/basicsuite/mediaplayer/VolumeControl.qml b/basicsuite/mediaplayer/VolumeControl.qml index 4369d04..ab8bec8 100644 --- a/basicsuite/mediaplayer/VolumeControl.qml +++ b/basicsuite/mediaplayer/VolumeControl.qml @@ -59,7 +59,6 @@ Item { property alias volume: volumeSlider.value property bool muted: root.volume == 0.0 property bool volumeItemUp: volumeItem.y == (volumeItem.height + volumeItem.height * 0.05) - //Volume Controls QtButton{ id: toggleVolumeButton @@ -85,7 +84,7 @@ Item { volumeItem.opacity = 0; if (volumeItem.y === 0) - volumeItem.y -= (volumeItem.height + volumeItem.height * 0.05); + volumeItem.y -= (volumeItem.height + itemMargin); else if (volumeItem !== 0) volumeItem.y = 0; } @@ -121,7 +120,7 @@ Item { Slider { id: volumeSlider anchors.bottom: muteVolumeButton.top - anchors.bottomMargin: parent.height * 0.05 + anchors.bottomMargin: itemMargin anchors.top: parent.top anchors.horizontalCenter: muteVolumeButton.horizontalCenter orientation: Qt.Vertical diff --git a/basicsuite/mediaplayer/main.qml b/basicsuite/mediaplayer/main.qml index 527e735..741309d 100644 --- a/basicsuite/mediaplayer/main.qml +++ b/basicsuite/mediaplayer/main.qml @@ -57,6 +57,8 @@ FocusScope { focus: true property real buttonHeight: height * 0.05 + property real itemMargin: Math.min(width * 0.025, height * 0.025) + property real defaultFontSize: height * 0.0375 MouseArea { id: mouseActivityMonitor @@ -119,35 +121,55 @@ FocusScope { } } - ParameterPanel { - id: parameterPanel - opacity: controlBar.opacity * 0.9 - visible: effectSelectionPanel.visible && model.count !== 0 - height: 116 - width: 500 + Rectangle { + id: effectsWrapper + color: "transparent" + Behavior on opacity { NumberAnimation { } } anchors { - bottomMargin: 15 + top: parent.top bottom: controlBar.top - right: effectSelectionPanel.left - rightMargin: 15 + bottomMargin: itemMargin + right: parent.right + left: parent.left } - } + visible: opacity > 0 + opacity: 0 - EffectSelectionPanel { - id: effectSelectionPanel - visible: false - opacity: controlBar.opacity * 0.9 - anchors { - bottom: controlBar.top - right: controlBar.right - bottomMargin: 15 + ParameterPanel { + id: parameterPanel + opacity: controlBar.opacity * 0.9 + visible: effectSelectionPanel.visible && model.count !== 0 + height: parent.height * 0.15 + width: parent.width * 0.4 + anchors { + bottom: parent.bottom + right: effectSelectionPanel.left + rightMargin: itemMargin + } + z: 10 } - width: 250 - height: 350 - itemHeight: 80 - onEffectSourceChanged: { - content.effectSource = effectSource - parameterPanel.model = content.effect.parameters + + EffectSelectionPanel { + id: effectSelectionPanel + opacity: controlBar.opacity * 0.9 + width: parent.width * 0.225 + height: parent.height * 0.7 + anchors { + right: parent.right + bottom: parent.bottom + } + z: 10 + onEffectSourceChanged: { + content.effectSource = effectSource + parameterPanel.model = content.effect.parameters + } + itemHeight: height / 8 + } + + MouseArea{ + anchors.fill: parent + onClicked: effectsWrapper.opacity = 0 + enabled: effectsWrapper.opacity !== 0 } } @@ -234,7 +256,7 @@ FocusScope { function init() { content.init() - content.openVideo("file:///data/videos/Qt_video_720p.webm"); + content.openVideo(DefaultVideoUrl); } function openVideo() { @@ -250,7 +272,7 @@ FocusScope { } function openFX() { - effectSelectionPanel.visible = !effectSelectionPanel.visible; + effectsWrapper.opacity = effectsWrapper.opacity === 0 ? 1 : 0 } function close() { diff --git a/basicsuite/shared/main.cpp b/basicsuite/shared/main.cpp index 58ff00f..4afbbe4 100644 --- a/basicsuite/shared/main.cpp +++ b/basicsuite/shared/main.cpp @@ -135,6 +135,10 @@ int main(int argc, char **argv) QGuiApplication::setFont(font); } + QString videosPath = QStringLiteral("file://"); + QString defaultVideoUrl = QStringLiteral("file:///data/videos/Qt_video_720p.webm"); + videosPath.append("/data/videos"); + QSettings styleSettings; QString style = styleSettings.value("style").toString(); if (style.isEmpty() || style == "Default") @@ -149,6 +153,8 @@ int main(int argc, char **argv) applicationengine.rootContext()->setContextProperty("appFont", appFont); applicationengine.rootContext()->setContextProperty("availableStyles", QQuickStyle::availableStyles()); + applicationengine.rootContext()->setContextProperty("VideosLocation", videosPath); + applicationengine.rootContext()->setContextProperty("DefaultVideoUrl", defaultVideoUrl); QSettings themeColorSettings("QtLauncher", "colorSettings"); -- cgit v1.2.3