872 lines
31 KiB
QML
872 lines
31 KiB
QML
/*
|
|
blueROCK - for digital rock
|
|
Copyright (C) 2019 Dorian Zedler
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
import QtQuick 2.9
|
|
import QtQuick.Controls 2.5
|
|
import QtQuick.Layouts 1.3
|
|
import QtGraphicalEffects 1.0
|
|
import QtQuick.Controls.Material 2.3
|
|
//import QtLocation 5.13
|
|
|
|
import QtPurchasing 1.12
|
|
|
|
import "../Components"
|
|
BRWidgetPage {
|
|
id: control
|
|
ready: true
|
|
title: data.name
|
|
titleIsPageTitle: true
|
|
subTitle: data.currentCategory.currentRound.name + " " + data.currentCategory.name + " " + qsTr("(Results)")
|
|
|
|
headerComponent: RowLayout {
|
|
id: headerComponent
|
|
|
|
height: parent.height
|
|
|
|
spacing: 0
|
|
|
|
ToolButton {
|
|
id: flowToolBt
|
|
|
|
visible: false //speedFlowChart.enabled
|
|
|
|
enabled: true // TODO control.data.currentCategory.currentRound.getId() === -1 && Object.keys(control.widgetData['route_names']).length > 2
|
|
|
|
onClicked: {
|
|
if(speedFlowChartBackgroundRect.state === "hidden"){
|
|
speedFlowChartBackgroundRect.state ="visible"
|
|
control.positionViewAtBeginning()
|
|
}
|
|
else {
|
|
speedFlowChartBackgroundRect.state = "hidden"
|
|
}
|
|
}
|
|
|
|
icon.name: "flowchart"
|
|
}
|
|
|
|
ToolButton {
|
|
id: moreToolBt
|
|
|
|
onClicked: {
|
|
control.changeCategory()
|
|
}
|
|
|
|
icon.name: "menu"
|
|
}
|
|
}
|
|
|
|
onLoadingFinished: {
|
|
return;
|
|
if(resultLv.model.length > 0){
|
|
control.ready = true
|
|
control.status = 200
|
|
}
|
|
else {
|
|
control.ready = false
|
|
control.status = 901
|
|
}
|
|
|
|
if(!control.ready)
|
|
return
|
|
}
|
|
|
|
onSelectionFinished: {
|
|
if(data.task === "category"){
|
|
loadingDl.open()
|
|
control.data.currentCategory = data.category
|
|
control.data.load()
|
|
loadingDl.close()
|
|
}
|
|
else if(data.task === "season"){
|
|
loadingDl.open()
|
|
control.data.currentSeason = data.season
|
|
loadingDl.close()
|
|
}
|
|
else if(data.task === "cup1"){
|
|
control.openCup(data)
|
|
}
|
|
else if(data.task === "cup2"){
|
|
app.openWidget({cup: data.cup, cat: data.cat})
|
|
}
|
|
}
|
|
|
|
function changeCategory(){
|
|
var selectOptions = []
|
|
var categories = control.data.categories
|
|
for(var i = 0; i < categories.length; i++){
|
|
if(categories[i] === control.data.currentCategory)
|
|
continue
|
|
selectOptions.push({text: categories[i].name, data:{task: "category", category: categories[i]}})
|
|
}
|
|
|
|
selector.appear(selectOptions, qsTr("select cat"))
|
|
}
|
|
|
|
function changeRound(round) {
|
|
loadingDl.open()
|
|
control.data.currentCategory.currentRound = round
|
|
control.data.load()
|
|
loadingDl.close()
|
|
}
|
|
|
|
DataListView {
|
|
id: resultLv
|
|
|
|
anchors {
|
|
top: parent.top
|
|
topMargin: 0
|
|
left: parent.left
|
|
right: parent.right
|
|
bottom: routeSelectTb.top
|
|
}
|
|
|
|
model: control.data.results
|
|
|
|
onRefresh: {
|
|
control.data.load()
|
|
}
|
|
|
|
/* TODO onWidgetDataChanged: {
|
|
console.log("widget data changed")
|
|
|
|
if(control.widgetData['discipline'] === 'speed' && control.widgetData['route_order'] === "-1" && Object.keys(control.widgetData['route_names']).length > 2){
|
|
speedFlowChart.flowchartData = ({})
|
|
speedFlowChart.enabled = true
|
|
speedFlowChart.flowchartData = control.widgetData
|
|
}
|
|
else {
|
|
speedFlowChart.enabled = false
|
|
speedFlowChart.flowchartData = ({})
|
|
}
|
|
}*/
|
|
|
|
onContentYChanged: {
|
|
if(contentY > 0 && speedFlowChartBackgroundRect.state === "visible"){
|
|
resultLv.positionViewAtBeginning()
|
|
}
|
|
}
|
|
|
|
header: Item {}
|
|
|
|
delegate: ItemDelegate {
|
|
id: partDel
|
|
|
|
property int ind: index
|
|
property var thisData: modelData
|
|
|
|
enabled: speedFlowChartBackgroundRect.state === "hidden"
|
|
|
|
width: resultLv.width
|
|
height: 70
|
|
|
|
text: ""
|
|
|
|
opacity: 0
|
|
scale: 0.9
|
|
|
|
onThisDataChanged: {
|
|
fadeInPa.start()
|
|
}
|
|
|
|
onClicked: {
|
|
app.openWidget({person:thisData["PerId"]})
|
|
}
|
|
|
|
ParallelAnimation {
|
|
id: fadeInPa
|
|
NumberAnimation { target: partDel; property: "opacity"; from: 0; to: 1.0; duration: 400 }
|
|
NumberAnimation { target: partDel; property: "scale"; from: 0.8; to: 1.0; duration: 400 }
|
|
}
|
|
|
|
Rectangle {
|
|
id: partDelBackgroundRect
|
|
anchors.fill: parent
|
|
|
|
width: partDel.width
|
|
|
|
color: partDel.ind % 2 == 0 ? "white":"lightgrey"
|
|
|
|
opacity: 0.2
|
|
}
|
|
|
|
Column {
|
|
id: partDelCol
|
|
|
|
anchors.fill: parent
|
|
anchors.margins: 5
|
|
|
|
Row {
|
|
id: partDelFirstRow
|
|
|
|
width: parent.width
|
|
height: parent.height - partDelSecondRow.height
|
|
|
|
Label {
|
|
height: parent.height
|
|
width: text === "" ? parent.width * 0.08:parent.width * 0.1
|
|
|
|
fontSizeMode: Text.Fit
|
|
font.bold: true
|
|
font.pixelSize: height * 0.6//Math.abs( partDelSecondRow.height > 0 ? height * 0.6:height * 0.4 )
|
|
verticalAlignment: Text.AlignVCenter
|
|
horizontalAlignment: Text.AlignHCenter
|
|
|
|
text: partDel.thisData.rank
|
|
}
|
|
|
|
Label {
|
|
height: parent.height
|
|
width: parent.width * 0.5
|
|
|
|
fontSizeMode: Text.Fit
|
|
font.bold: true
|
|
font.pixelSize: height * 0.6//Math.abs( partDelSecondRow.height > 0 ? height * 0.6:height * 0.4 )
|
|
verticalAlignment: Text.AlignVCenter
|
|
horizontalAlignment: Text.AlignLeft
|
|
|
|
text: partDel.thisData.athlete.firstName + " " + partDel.thisData.athlete.lastName + (partDel.thisData["start_number"] !== undefined ? (" (" + partDel.thisData["start_number"] + ")"):"")
|
|
}
|
|
|
|
Label {
|
|
height: parent.height
|
|
width: parent.width * 0.4
|
|
|
|
fontSizeMode: Text.Fit
|
|
font.bold: false
|
|
font.pixelSize: height * 0.6 //Math.abs( partDelSecondRow.height > 0 ? height * 0.4:height * 0.3 )
|
|
minimumPixelSize: height * 0.3 < 1 ? 1:height * 0.3
|
|
|
|
elide: "ElideRight"
|
|
|
|
verticalAlignment: Text.AlignVCenter
|
|
horizontalAlignment: Text.AlignHCenter
|
|
|
|
text: "<html>(<a href=\"" + (partDel.thisData.athlete.federationUrl === undefined ? "":partDel.thisData.athlete.federationUrl).toString() + "\">" + partDel.thisData.athlete.federation + "</a>)</html>"
|
|
|
|
onLinkActivated: {
|
|
Qt.openUrlExternally(link)
|
|
}
|
|
}
|
|
}
|
|
|
|
Row {
|
|
id: partDelSecondRow
|
|
|
|
width: parent.width
|
|
height: resultLa.acitve ? parent.height / 2 : 0 // TODO multiResRow.active || multiGenResRow.active || resultLa.acitve ? parent.height / 2 : 0
|
|
/*
|
|
Row {
|
|
id: multiResRow
|
|
|
|
property bool active: false // TODO parseInt(widgetData[ "route_order" ]) > -1 && boulderResRep.model > 0
|
|
|
|
height: parent.height
|
|
width: active ? parent.width * 0.75:0
|
|
|
|
enabled: parseInt(widgetData[ "route_order" ]) > -1 && boulderResRep.model > 0
|
|
|
|
Repeater {
|
|
id: boulderResRep
|
|
model: parseInt(widgetData[ "route_num_problems" ])
|
|
|
|
function getDataForIcon(index){
|
|
var resultString = widgetData[ "participants" ][partDel.ind]["boulder"+(index+1)]
|
|
|
|
var resultList = []
|
|
|
|
if( resultString !== undefined){
|
|
resultString = resultString.replace("t", "")
|
|
resultString = resultString.replace("z", "")
|
|
resultString = resultString.replace("b", "")
|
|
resultList = resultString.split(" ")
|
|
|
|
while (resultList.length < 2){
|
|
resultList.unshift(0)
|
|
}
|
|
}
|
|
else {
|
|
resultList = [-1,-1]
|
|
}
|
|
|
|
return resultList
|
|
}
|
|
|
|
delegate: Item {
|
|
id: boulderResItm
|
|
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
|
|
width: parent.width / ( boulderResRep.model )
|
|
height: parent.height
|
|
|
|
Canvas {
|
|
id: boulderResCv
|
|
|
|
property var resultData: boulderResRep.getDataForIcon(index)
|
|
|
|
onResultDataChanged: {
|
|
boulderResCv.requestPaint()
|
|
}
|
|
|
|
anchors.centerIn: parent
|
|
|
|
height: parent.height > parent.width ? parent.width * 0.9:parent.height * 0.9
|
|
width: height
|
|
|
|
onPaint: {
|
|
var width = 24//boulderResCv.width * 0.9
|
|
var height = width
|
|
|
|
var radius = width * 0.3
|
|
|
|
var offsetX = width * 0.05
|
|
var offsetY = height * 0.05
|
|
|
|
//console.log("drawing result rect with width: " + width + " and height: " + height)
|
|
|
|
var context = getContext("2d");
|
|
|
|
// clear all remainings from other routes
|
|
context.clearRect(0, 0, width, height);
|
|
|
|
context.beginPath();
|
|
|
|
context.moveTo(0 + offsetX + radius, 0 + offsetY);
|
|
|
|
// top line
|
|
context.lineTo(width - radius + offsetX, 0 + offsetY);
|
|
// top right corner
|
|
context.arc(width-radius + offsetX, radius + offsetY, radius, 1.5 * Math.PI, 0);
|
|
// right line
|
|
context.lineTo(width + offsetX, height - radius + offsetY);
|
|
// bottom right corner
|
|
context.arc(width-radius + offsetX, height - radius + offsetY, radius, 0, 0.5 * Math.PI);
|
|
// bottom line
|
|
context.lineTo(0 + radius + offsetX, height + offsetY);
|
|
// bottom left corner
|
|
context.arc(radius + offsetY, height - radius + offsetY, radius, 0.5 * Math.PI, Math.PI);
|
|
// left line
|
|
context.lineTo(0 + offsetX, radius + offsetY);
|
|
// top left corner
|
|
context.arc(radius + offsetX, radius + offsetY, radius, Math.PI, 1.5 * Math.PI);
|
|
|
|
// fill
|
|
if(resultData[0] !== -1) {
|
|
// if there is a result available -> draw background
|
|
context.fillStyle = "#b7b7b7";
|
|
}
|
|
else {
|
|
context.fillStyle = "transparent";
|
|
}
|
|
|
|
context.fill();
|
|
|
|
// outline
|
|
context.lineWidth = 1;
|
|
context.strokeStyle = '#424242';
|
|
context.stroke();
|
|
|
|
if(resultData[1] > 0){
|
|
|
|
// the first triangle
|
|
context.beginPath();
|
|
|
|
// top right corner
|
|
context.arc(width-radius + offsetX, radius + offsetY, radius, 1.75 * Math.PI, 0);
|
|
|
|
// right line
|
|
context.lineTo(width + offsetX, height - radius + offsetY);
|
|
|
|
// bottom right corner
|
|
context.arc(width-radius + offsetX, height - radius + offsetY, radius, 0, 0.5 * Math.PI);
|
|
|
|
// bottom line
|
|
context.lineTo(0 + radius + offsetX, height + offsetY);
|
|
// bottom left corner
|
|
context.arc(radius + offsetX, height - radius + offsetY, radius, 0.5 * Math.PI, 0.75 * Math.PI);
|
|
context.closePath();
|
|
|
|
context.fillStyle = "#44ed38";
|
|
context.fill();
|
|
|
|
// outline
|
|
context.lineWidth = 1;
|
|
context.strokeStyle = '#424242';
|
|
context.stroke();
|
|
|
|
|
|
if(resultData[0] > 0){
|
|
// the second triangle
|
|
context.beginPath();
|
|
// bottom left corner
|
|
context.arc(radius + offsetX, height - radius + offsetY, radius, 0.75 * Math.PI, 1 * Math.PI);
|
|
// left line
|
|
context.lineTo(0 + offsetX, radius + offsetY);
|
|
// top left corner
|
|
context.arc(radius + offsetX, radius + offsetY, radius, Math.PI, 1.5 * Math.PI);
|
|
// top line
|
|
context.lineTo(width - radius + offsetX, 0 + offsetY);
|
|
// top right corner
|
|
context.arc(width-radius + offsetX, radius + offsetY, radius, 1.5 * Math.PI, 1.75 * Math.PI);
|
|
|
|
context.closePath();
|
|
|
|
context.fillStyle = "#44ed38";
|
|
context.fill();
|
|
|
|
// outline
|
|
context.lineWidth = 1;
|
|
context.strokeStyle = '#424242';
|
|
context.stroke();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
Label {
|
|
id: boulderResZoneLa
|
|
|
|
anchors {
|
|
right: parent.right
|
|
bottom: parent.bottom
|
|
margins: boulderResCv.height * 0.05
|
|
}
|
|
|
|
height: parent.height / 2
|
|
width: parent.width / 2
|
|
|
|
visible: parseInt(text) > 0
|
|
|
|
fontSizeMode: Text.Fit
|
|
font.pixelSize: height
|
|
minimumPixelSize: 1
|
|
|
|
verticalAlignment: Text.AlignVCenter
|
|
horizontalAlignment: Text.AlignHCenter
|
|
|
|
text: boulderResCv.resultData[1]
|
|
}
|
|
|
|
Label {
|
|
id: boulderResTopLa
|
|
|
|
anchors {
|
|
left: parent.left
|
|
top: parent.top
|
|
margins: boulderResCv.height * 0.05
|
|
}
|
|
|
|
height: parent.height / 2
|
|
width: parent.width / 2
|
|
|
|
visible: parseInt(text) > 0
|
|
|
|
fontSizeMode: Text.Fit
|
|
font.pixelSize: height
|
|
minimumPixelSize: 1
|
|
|
|
verticalAlignment: Text.AlignVCenter
|
|
horizontalAlignment: Text.AlignHCenter
|
|
|
|
text: boulderResCv.resultData[0]
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Row {
|
|
id: multiGenResRow
|
|
|
|
property bool active: false // TODO ((parseInt(widgetData[ "route_order" ]) === -1) && (generalResRep.model > 0)) ? true:false
|
|
|
|
height: parent.height
|
|
width: active ? parent.width - resultLa.width:0
|
|
|
|
enabled: ((parseInt(widgetData[ "route_order" ]) === -1) && (generalResRep.model > 0)) ? true:false
|
|
|
|
Repeater {
|
|
id: generalResRep
|
|
|
|
property var routes: getRoutes()
|
|
model: routes.length
|
|
|
|
function getRoutes() {
|
|
|
|
var obj = widgetData["route_names"]
|
|
var routes = []
|
|
|
|
for(var prop in obj) {
|
|
// go through the whole array and search for data keys
|
|
if (obj.hasOwnProperty(prop) && prop > -1) {
|
|
routes.push([prop, obj[prop]])
|
|
//console.log("found " + obj[prop] + " at index " + prop)
|
|
}
|
|
}
|
|
|
|
routes.sort(function(a, b) {
|
|
return a[0] - b[0];
|
|
});
|
|
|
|
return routes
|
|
}
|
|
|
|
delegate: Item {
|
|
id: boulderGenResItm
|
|
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
|
|
width: parent.width / ( generalResRep.model )
|
|
height: parent.height
|
|
|
|
visible: multiGenResRow.active
|
|
|
|
Rectangle {
|
|
|
|
anchors {
|
|
left: parent.left
|
|
}
|
|
|
|
width: 1
|
|
height: parent.height
|
|
|
|
visible: index === 0
|
|
|
|
color: "grey"
|
|
}
|
|
|
|
Rectangle {
|
|
anchors {
|
|
right: parent.right
|
|
}
|
|
|
|
width: 1
|
|
height: parent.height
|
|
|
|
color: "grey"
|
|
}
|
|
|
|
Label {
|
|
id: boulderGenResLa
|
|
anchors.centerIn: parent
|
|
|
|
height: parent.height
|
|
width: parent.width * 0.9
|
|
|
|
fontSizeMode: Text.Fit
|
|
font.pixelSize: Math.abs( height * 0.6 )
|
|
minimumPixelSize: 1
|
|
verticalAlignment: Text.AlignVCenter
|
|
horizontalAlignment: Text.AlignHCenter
|
|
|
|
text: widgetData[ "participants" ][partDel.ind]["result"+(generalResRep.routes[index][0])] === undefined ? "":widgetData[ "participants" ][partDel.ind]["result"+(generalResRep.routes[index][0])]
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
*/
|
|
Label {
|
|
id: resultLa
|
|
|
|
property bool acitve: true // TODO ( boulderResRep.model > 0 || widgetData["discipline"] !== "boulder" ) && parseInt(widgetData[ "route_order" ]) > -1
|
|
|
|
width: enabled ? parent.width * 0.75:0
|
|
height: enabled ? parent.height:0
|
|
|
|
enabled: true //( boulderResRep.model > 0 || widgetData["discipline"] !== "boulder" ) && parseInt(widgetData[ "route_order" ]) > -1
|
|
|
|
verticalAlignment: Text.AlignVCenter
|
|
horizontalAlignment: Text.AlignLeft
|
|
|
|
fontSizeMode: Text.Fit
|
|
font.pixelSize: Math.abs( height * 0.6 )
|
|
minimumPixelSize: 1
|
|
|
|
text: partDel.thisData.details.string()
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
PullRefresher {
|
|
target: resultLv
|
|
|
|
postRefreshDelay: 0
|
|
|
|
busyIndicator: FancyBusyIndicator {}
|
|
refreshPosition: height * 1.3
|
|
|
|
onRefreshRequested: {
|
|
resultLv.refresh()
|
|
}
|
|
}
|
|
}
|
|
|
|
RectangularGlow {
|
|
id: toolBarEffect
|
|
glowRadius: 3
|
|
spread: 0.2
|
|
color: "black"
|
|
opacity: 0.3
|
|
anchors.fill: routeSelectTb
|
|
}
|
|
|
|
TabBar {
|
|
id: routeSelectTb
|
|
|
|
property var tabs: control.data.currentCategory.rounds
|
|
property var tabIndexes: []
|
|
|
|
enabled: speedFlowChartBackgroundRect.state === "hidden"
|
|
|
|
anchors {
|
|
left: parent.left
|
|
right: parent.right
|
|
bottom: parent.bottom
|
|
}
|
|
|
|
height: tabs.length > 1 ? 50:0
|
|
width: parent.width
|
|
|
|
position: TabBar.Footer
|
|
|
|
currentIndex: tabs.indexOf(control.data.currentCategory.currentRound)
|
|
|
|
onTabsChanged: {
|
|
console.log("tabs: " + tabs + " rounds: " + control.data.currentCategory.rounds)
|
|
}
|
|
|
|
Repeater {
|
|
id: routeSelectButtonRep
|
|
|
|
model: routeSelectTb.tabs
|
|
|
|
onModelChanged: {
|
|
//routeSelectTb.setCurrentIndex(routeSelectTb.tabs.indexOf(control.data.currentCategory.currentRound))
|
|
}
|
|
|
|
delegate: TabButton {
|
|
text: modelData.name
|
|
|
|
width: Math.max(150, routeSelectTb.width / routeSelectButtonRep.model.length) //text.length * font.pixelSize
|
|
|
|
onClicked: {
|
|
control.changeRound(modelData)
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
id: speedFlowChartBackgroundRect
|
|
|
|
state: "hidden"
|
|
|
|
anchors {
|
|
top: control.top
|
|
bottom: control.bottom
|
|
left: control.right
|
|
}
|
|
|
|
width: control.width
|
|
height: control.height
|
|
|
|
color: Material.background
|
|
|
|
SpeedFlowChart {
|
|
id: speedFlowChart
|
|
|
|
anchors.fill: parent
|
|
|
|
enabled: false
|
|
|
|
flowchartData: ({})
|
|
|
|
onEnabledChanged: {
|
|
if(!enabled){
|
|
speedFlowChartBackgroundRect.state = 'hidden'
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
id: speedFlowChartLockedOverlay
|
|
|
|
state: appSettings.read("speedBackendPurchase") === "1" ? "unlocked":"locked"
|
|
|
|
anchors.fill: parent
|
|
anchors.margins: -20
|
|
|
|
color: "white"
|
|
|
|
Connections {
|
|
target: speedFlowChartProduct
|
|
function onPurchaseRestored() {
|
|
speedFlowChartLockedOverlay.state = appSettings.read("speedBackendPurchase") === "1" ? "unlocked":"locked"
|
|
}
|
|
|
|
function onPurchaseSucceeded() {
|
|
speedFlowChartLockedOverlay.state = appSettings.read("speedBackendPurchase") === "1" ? "unlocked":"locked"
|
|
}
|
|
|
|
function onPurchaseFailed() {
|
|
purchaseBt.text = qsTr("Purchase failed")
|
|
purchaseBt.enabled = false
|
|
buttonTextResetTimer.start()
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
id: buttonTextResetTimer
|
|
interval: 2000
|
|
running: false
|
|
repeat: false
|
|
onTriggered: {
|
|
purchaseBt.text = (speedFlowChartProduct.status === Product.Registered
|
|
? "Buy now for " + speedFlowChartProduct.price
|
|
: qsTr("this item is currently unavailable"))
|
|
purchaseBt.enabled = true
|
|
}
|
|
}
|
|
|
|
ColumnLayout {
|
|
id: lockedLayout
|
|
|
|
anchors {
|
|
fill: parent
|
|
topMargin: parent.height * 0.05
|
|
bottomMargin: parent.height * 0.1
|
|
rightMargin: parent.width * 0.1 + 20
|
|
leftMargin: parent.width * 0.1 + 20
|
|
}
|
|
|
|
//spacing: parent.height * 0.05
|
|
|
|
Image {
|
|
id: name
|
|
|
|
Layout.alignment: Layout.Center
|
|
Layout.preferredHeight: height
|
|
Layout.preferredWidth: width
|
|
|
|
width: lockedLayout.height * 0.1
|
|
height: width
|
|
|
|
mipmap: true
|
|
|
|
source: "qrc:/icons/lock.png"
|
|
}
|
|
|
|
Text {
|
|
Layout.fillWidth: true
|
|
|
|
height: parent.height * 0.05
|
|
|
|
text: qsTr("This is a premium feature.")
|
|
|
|
font.bold: true
|
|
font.pixelSize: parent.height * 0.05
|
|
fontSizeMode: Text.Fit
|
|
|
|
minimumPixelSize: 1
|
|
|
|
horizontalAlignment: Text.AlignHCenter
|
|
|
|
}
|
|
|
|
SwipeGallery {
|
|
Layout.fillHeight: true
|
|
Layout.fillWidth: true
|
|
|
|
images: ["qrc:/screenshots/SpeedFlowchartDemo/1.png","qrc:/screenshots/SpeedFlowchartDemo/2.png","qrc:/screenshots/SpeedFlowchartDemo/3.png"]
|
|
}
|
|
|
|
Button {
|
|
id: purchaseBt
|
|
Layout.alignment: Layout.Center
|
|
enabled: speedFlowChartProduct.status === Product.Registered
|
|
text: speedFlowChartProduct.status === Product.Registered
|
|
? "Buy now for " + speedFlowChartProduct.price
|
|
: qsTr("this item is currently unavailable")
|
|
icon.name: "buy"
|
|
//display: AbstractButton.TextBesideIcon
|
|
onClicked: speedFlowChartProduct.purchase()
|
|
}
|
|
|
|
}
|
|
|
|
states: [
|
|
State {
|
|
name: "unlocked"
|
|
PropertyChanges {
|
|
target: speedFlowChartLockedOverlay
|
|
visible: false
|
|
}
|
|
},
|
|
State {
|
|
name: "locked"
|
|
PropertyChanges {
|
|
target: speedFlowChartLockedOverlay
|
|
visible: true
|
|
}
|
|
}
|
|
]
|
|
}
|
|
|
|
}
|
|
|
|
states: [
|
|
State {
|
|
name: "hidden"
|
|
PropertyChanges {
|
|
target: speedFlowChartBackgroundRect
|
|
opacity: 0
|
|
anchors.leftMargin: 0
|
|
}
|
|
},
|
|
|
|
State {
|
|
name: "visible"
|
|
PropertyChanges {
|
|
target: speedFlowChartBackgroundRect
|
|
opacity: 1
|
|
anchors.leftMargin: -parent.width
|
|
}
|
|
}
|
|
]
|
|
|
|
transitions: [
|
|
Transition {
|
|
NumberAnimation {
|
|
properties: "opacity,scale,anchors.leftMargin"
|
|
duration: 200
|
|
easing.type: Easing.InOutQuad
|
|
}
|
|
}
|
|
]
|
|
}
|
|
|
|
|
|
}
|