Many small and big improvements, see change log for details
This commit is contained in:
parent
121589bf29
commit
f9f6dd7f5d
20 changed files with 1281 additions and 1191 deletions
13
CHANGELOG.md
13
CHANGELOG.md
|
@ -4,10 +4,19 @@ All notable changes to this project will be documented in this file.
|
||||||
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
||||||
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
# [0.03.1] - UR
|
# [0.05] - UR
|
||||||
### Changed
|
### Changed
|
||||||
- the boulder result rect doesn't have a background if there is no result now
|
- the boulder result rect doesn't have a background if there is no result now
|
||||||
- the selected route is kept when changing cats
|
- the selected route is kept when changing cats
|
||||||
|
- the boulder result rect now shows the number of tries when there is not zone or top yet
|
||||||
|
- the speed flowchart now blocks the back key from closing the competition and instead closes itself
|
||||||
|
- redesigned start page
|
||||||
|
- added disclaimer regarding IFSC results
|
||||||
|
- some internal refactoring
|
||||||
|
- the calendar now scrolls less far down
|
||||||
|
- improoved layout in landscape mode
|
||||||
|
- some design changes in profile page and speed flowchart
|
||||||
|
- added second link for "further infos" in calendar
|
||||||
|
|
||||||
# [0.03.0] - 2019-07-11
|
# [0.03.0] - 2019-07-11
|
||||||
### Added
|
### Added
|
||||||
|
@ -21,7 +30,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||||
- event website url is now present in the cat select dialog if available
|
- event website url is now present in the cat select dialog if available
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- competitons are clickable if there is a infosheet or event website url available event when they don't have any categories
|
- competitons are clickable if there is a infosheet or event website url available even when they don't have any categories
|
||||||
|
|
||||||
# [0.01.6] - 2019-06-15
|
# [0.01.6] - 2019-06-15
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
@ -50,9 +50,7 @@ DISTFILES += \
|
||||||
android-sources/gradle/wrapper/gradle-wrapper.properties \
|
android-sources/gradle/wrapper/gradle-wrapper.properties \
|
||||||
android-sources/gradlew \
|
android-sources/gradlew \
|
||||||
android-sources/gradlew.bat \
|
android-sources/gradlew.bat \
|
||||||
android-sources/res/values/libs.xml \
|
android-sources/res/values/libs.xml
|
||||||
resources/shared/icons/bluerock/index.theme \
|
|
||||||
$$files(resources/shared/icons/*.png, true)
|
|
||||||
|
|
||||||
android {
|
android {
|
||||||
QT += androidextras
|
QT += androidextras
|
||||||
|
|
32
resources/qml/Components/BlueRockBadge.qml
Normal file
32
resources/qml/Components/BlueRockBadge.qml
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
import QtQuick 2.9
|
||||||
|
import QtQuick.Controls 2.4
|
||||||
|
import QtQuick.Layouts 1.0
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: control
|
||||||
|
|
||||||
|
Image {
|
||||||
|
Layout.preferredHeight: parent.height
|
||||||
|
Layout.preferredWidth: height
|
||||||
|
Layout.alignment: Layout.Center
|
||||||
|
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
mipmap: true
|
||||||
|
|
||||||
|
source: "qrc:/icons/blueRockHold.png"
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.preferredHeight: parent.height
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Layout.Center
|
||||||
|
|
||||||
|
fontSizeMode: Text.Fit
|
||||||
|
font.pixelSize: parent.height * 0.6
|
||||||
|
font.bold: true
|
||||||
|
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
|
||||||
|
text: "blueROCK"
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,10 +32,10 @@ Item {
|
||||||
property int postRefreshDelay: 1000 // delay after reload funcion has finished
|
property int postRefreshDelay: 1000 // delay after reload funcion has finished
|
||||||
property int preRefreshDelay: 1000 // delay before reload funcion is called
|
property int preRefreshDelay: 1000 // delay before reload funcion is called
|
||||||
|
|
||||||
property int refreshPosition: height * 1.2 // position of the item when refreshing
|
property int refreshPosition: height * 1.7 // position of the item when refreshing
|
||||||
property int dragOutPosition: height * 1.8 // maximum drag out
|
property int dragOutPosition: height * 1.8 // maximum drag out
|
||||||
|
|
||||||
property double dragRefreshPositionMultiplier: 0.5 // position of the item when starting to refresh
|
property double dragRefreshPositionMultiplier: 0.6 // position of the item when starting to refresh
|
||||||
|
|
||||||
property color backgroundColor: "white" // color for the pre-defined background
|
property color backgroundColor: "white" // color for the pre-defined background
|
||||||
property color pullIndicatorColor: "black" // color for the pre-defined pull indicator
|
property color pullIndicatorColor: "black" // color for the pre-defined pull indicator
|
||||||
|
|
484
resources/qml/Components/ResultDelegate.qml
Normal file
484
resources/qml/Components/ResultDelegate.qml
Normal file
|
@ -0,0 +1,484 @@
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
|
ItemDelegate {
|
||||||
|
id: partDel
|
||||||
|
|
||||||
|
property int ind: index
|
||||||
|
property var thisData: widgetData[ "participants" ][partDel.ind]
|
||||||
|
|
||||||
|
width: control.width
|
||||||
|
height: app.landscape() ? 40: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
|
||||||
|
}
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
id: partDelCol
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 5
|
||||||
|
|
||||||
|
columns: app.landscape() ? 2:1
|
||||||
|
rows: app.landscape()? 1:2
|
||||||
|
|
||||||
|
columnSpacing: height * 0.2
|
||||||
|
rowSpacing: 0
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: partDelFirstRow
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
Label {
|
||||||
|
height: parent.height
|
||||||
|
width: text === "" ? parent.width * 0.08:parent.width * 0.1
|
||||||
|
|
||||||
|
fontSizeMode: Text.Fit
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: Math.abs( partDelSecondRow.height > 0 ? height * 0.6:height * 0.4 )
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
|
||||||
|
text: partDel.thisData["result_rank"] === undefined ? "":partDel.thisData["result_rank"]
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
height: parent.height
|
||||||
|
width: parent.width * 0.5
|
||||||
|
|
||||||
|
fontSizeMode: Text.Fit
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: Math.abs( partDelSecondRow.height > 0 ? height * 0.6:height * 0.4 )
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
|
||||||
|
text: partDel.thisData["firstname"] + " " + partDel.thisData["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: 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["fed_url"] === undefined ? "":partDel.thisData["fed_url"]).toString() + "\">" + (widgetData[ "display_athlete" ] === "nation" ? partDel.thisData["nation"] : partDel.thisData["federation"]) + "</a>)</html>"
|
||||||
|
|
||||||
|
onLinkActivated: {
|
||||||
|
Qt.openUrlExternally(link)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: partDelSecondRow
|
||||||
|
|
||||||
|
Layout.preferredWidth: app.landscape() ? parent.width * 0.5 : parent.width
|
||||||
|
Layout.preferredHeight: app.landscape() ? parent.height : parent.height * 0.5
|
||||||
|
|
||||||
|
visible: multiResRow.active || multiGenResRow.active || resultLa.acitve
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: multiResRow
|
||||||
|
|
||||||
|
property bool active: 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){
|
||||||
|
// TODO: clean
|
||||||
|
var resultString = widgetData[ "participants" ][partDel.ind]["boulder"+(index+1)]
|
||||||
|
var numTrys = widgetData[ "participants" ][partDel.ind]["try"+(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]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numTrys !== undefined) {
|
||||||
|
resultList.push(numTrys)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
resultList.push(-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: boulderResTrysLa
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
height: parent.height / 2
|
||||||
|
width: parent.width / 2
|
||||||
|
|
||||||
|
visible: !boulderResZoneLa.visible && boulderResCv.resultData[2] > 0
|
||||||
|
|
||||||
|
fontSizeMode: Text.Fit
|
||||||
|
font.pixelSize: height
|
||||||
|
minimumPixelSize: 1
|
||||||
|
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
|
||||||
|
text: boulderResCv.resultData[2]
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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: ((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: ( boulderResRep.model > 0 || widgetData["discipline"] !== "boulder" ) && parseInt(widgetData[ "route_order" ]) > -1
|
||||||
|
|
||||||
|
width: enabled ? parent.width * 0.25:0
|
||||||
|
height: enabled ? parent.height:0
|
||||||
|
|
||||||
|
enabled: ( boulderResRep.model > 0 || widgetData["discipline"] !== "boulder" ) && parseInt(widgetData[ "route_order" ]) > -1
|
||||||
|
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
|
||||||
|
fontSizeMode: Text.Fit
|
||||||
|
font.pixelSize: Math.abs( height * 0.6 )
|
||||||
|
minimumPixelSize: 1
|
||||||
|
|
||||||
|
text: widgetData[ "participants" ][partDel.ind]["result"] === undefined ? "":widgetData[ "participants" ][partDel.ind]["result"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
139
resources/qml/Components/SelectorPopup.qml
Normal file
139
resources/qml/Components/SelectorPopup.qml
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
import QtQuick 2.9
|
||||||
|
import QtQuick.Controls 2.4
|
||||||
|
import QtQuick.Controls.Material 2.3
|
||||||
|
|
||||||
|
Dialog {
|
||||||
|
id: control
|
||||||
|
|
||||||
|
property var dataObj
|
||||||
|
property string subTitle: ""
|
||||||
|
property int implicitY: parent.height - implicitHeight
|
||||||
|
|
||||||
|
signal selectionFinished(int index, var data)
|
||||||
|
|
||||||
|
parent: Overlay.overlay
|
||||||
|
|
||||||
|
x: 0
|
||||||
|
y: parent.height - implicitHeight
|
||||||
|
|
||||||
|
opacity: 1
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
implicitWidth: width
|
||||||
|
contentHeight: Math.min(parent.height * 0.7, implicitContentHeight)
|
||||||
|
implicitHeight: contentHeight + topPadding + bottomPadding + header.height
|
||||||
|
padding: 30
|
||||||
|
|
||||||
|
modal: true
|
||||||
|
focus: true
|
||||||
|
|
||||||
|
title: ""
|
||||||
|
|
||||||
|
header: Column {
|
||||||
|
id: selectorPuHeaderCol
|
||||||
|
|
||||||
|
width: control.width
|
||||||
|
height: headerSubLa.text !== "" && headerLa.text !== "" ? 73 : 40
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: headerLa
|
||||||
|
|
||||||
|
visible: control.title
|
||||||
|
|
||||||
|
width: selectorPuHeaderCol.width
|
||||||
|
|
||||||
|
elide: "ElideRight"
|
||||||
|
padding: control.padding
|
||||||
|
bottomPadding: 0
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: 16
|
||||||
|
|
||||||
|
text: control.title
|
||||||
|
|
||||||
|
onLinkActivated: {
|
||||||
|
console.log("Opening " + link)
|
||||||
|
Qt.openUrlExternally(link)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: headerSubLa
|
||||||
|
|
||||||
|
visible: control.subTitle
|
||||||
|
|
||||||
|
width: selectorPuHeaderCol.width
|
||||||
|
|
||||||
|
elide: "ElideRight"
|
||||||
|
padding: control.padding
|
||||||
|
topPadding: 5
|
||||||
|
bottomPadding: 0
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: 16
|
||||||
|
|
||||||
|
text: control.subTitle
|
||||||
|
|
||||||
|
onLinkActivated: {
|
||||||
|
console.log("Opening " + link)
|
||||||
|
Qt.openUrlExternally(link)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Item {
|
||||||
|
Rectangle {
|
||||||
|
id: backgroundRect
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
bottomMargin: -radius
|
||||||
|
}
|
||||||
|
|
||||||
|
radius: control.leftPadding
|
||||||
|
|
||||||
|
color: control.Material.dialogColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function appear(dataObj, title, subTitle) {
|
||||||
|
|
||||||
|
if(dataObj.length > 0){
|
||||||
|
control.dataObj = dataObj
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
control.dataObj = undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
control.title = title
|
||||||
|
control.subTitle = subTitle === undefined ? "":subTitle
|
||||||
|
control.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
enter: Transition {
|
||||||
|
NumberAnimation {
|
||||||
|
property: "opacity";
|
||||||
|
from: 0
|
||||||
|
to: 1.0
|
||||||
|
easing.type: Easing.Linear
|
||||||
|
}
|
||||||
|
|
||||||
|
NumberAnimation {
|
||||||
|
property: "y"
|
||||||
|
from: control.parent.height - control.implicitHeight * 0.7
|
||||||
|
to: control.parent.height - control.implicitHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit: Transition {
|
||||||
|
NumberAnimation {
|
||||||
|
property: "opacity";
|
||||||
|
from: 1
|
||||||
|
to: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
NumberAnimation {
|
||||||
|
property: "y"
|
||||||
|
from: control.parent.height - control.implicitHeight
|
||||||
|
to: control.parent.height - control.implicitHeight * 0.7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,32 +20,24 @@ import QtQuick 2.10
|
||||||
import QtQuick.Controls 2.4
|
import QtQuick.Controls 2.4
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
import QtQuick.Controls.Material 2.1
|
import QtQuick.Controls.Material 2.1
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
ListView {
|
Item {
|
||||||
id: control
|
id: control
|
||||||
|
|
||||||
property var flowchartData
|
property var flowchartData
|
||||||
property var allFlowchartData
|
property var allFlowchartData
|
||||||
property int rounds: 0
|
property int rounds: 0
|
||||||
property int tileSize: app.height / 8 * 0.8
|
|
||||||
|
|
||||||
property int refreshes: 0
|
property int refreshes: 0
|
||||||
property int roundRefreshes: 1
|
property int roundRefreshes: 1
|
||||||
|
|
||||||
anchors.fill: parent
|
property int roundCount: 0
|
||||||
anchors.margins: 10
|
|
||||||
|
|
||||||
spacing: app.width * 0.1
|
|
||||||
|
|
||||||
orientation: ListView.LeftToRight
|
|
||||||
boundsBehavior: ListView.StopAtBounds
|
|
||||||
|
|
||||||
onFlowchartDataChanged: {
|
onFlowchartDataChanged: {
|
||||||
prepareData()
|
prepareData()
|
||||||
}
|
}
|
||||||
|
|
||||||
model: 0
|
|
||||||
|
|
||||||
function prepareData() {
|
function prepareData() {
|
||||||
|
|
||||||
if(!control.enabled || control.flowchartData === undefined || control.flowchartData['route_names'] === undefined)
|
if(!control.enabled || control.flowchartData === undefined || control.flowchartData['route_names'] === undefined)
|
||||||
|
@ -223,189 +215,273 @@ ListView {
|
||||||
}
|
}
|
||||||
|
|
||||||
control.allFlowchartData = allData
|
control.allFlowchartData = allData
|
||||||
control.model = (parseInt(Object.keys(control.flowchartData['route_names']).length > 2 ? control.flowchartData['route_names']["2"].includes("8") ? 2:1 : 0) + 2)
|
control.roundCount = (parseInt(Object.keys(control.flowchartData['route_names']).length > 2 ? control.flowchartData['route_names']["2"].includes("8") ? 2:1 : 0) + 2)
|
||||||
//console.log(JSON.stringify(allData))
|
//console.log(JSON.stringify(allData))
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate: Column {
|
ListView {
|
||||||
id: roundCol
|
id: roundListView
|
||||||
|
|
||||||
property int thisIndex: index
|
property int columnWidth: height * 0.3
|
||||||
property int thisRound: thisRoundIsValid ? control.allFlowchartData[roundCol.thisIndex][control.allFlowchartData[roundCol.thisIndex].length-2]:-1
|
property int columnHeight: height
|
||||||
property bool thisRoundIsValid: control.allFlowchartData !== undefined && control.allFlowchartData[roundCol.thisIndex] !== undefined && control.allFlowchartData[roundCol.thisIndex].length > 2
|
|
||||||
property bool thisIsLastRound: thisIndex === control.model - 1
|
|
||||||
|
|
||||||
width: app.width * 0.5
|
anchors {
|
||||||
height: control.height
|
top: parent.top
|
||||||
|
bottom: parent.bottom
|
||||||
//spacing: app.width * 0.1
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
Label {
|
|
||||||
id: roundNameLa
|
|
||||||
width: parent.width
|
|
||||||
height: control.height * 0.05
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
fontSizeMode: Text.Fit
|
|
||||||
font.pixelSize: height * 0.6
|
|
||||||
minimumPixelSize: 1
|
|
||||||
font.bold: true
|
|
||||||
text: roundCol.thisRoundIsValid && control.allFlowchartData[roundCol.thisIndex][control.allFlowchartData[roundCol.thisIndex].length-1] !== undefined ? control.allFlowchartData[roundCol.thisIndex][control.allFlowchartData[roundCol.thisIndex].length-1] : "-"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
width: Math.min((columnWidth + spacing) * model, control.width)
|
||||||
id: rectRep
|
|
||||||
model: Math.max( Math.pow(2, control.model-1) * Math.pow(0.5, (index)), 2)
|
|
||||||
delegate: Item {
|
|
||||||
id: matchItm
|
|
||||||
|
|
||||||
property bool lowerPart: (index%2 > 0)
|
spacing: app.height * 0.05
|
||||||
|
|
||||||
property var matchData: roundCol.thisRoundIsValid ? control.allFlowchartData[ thisIsSmallFinal ? roundCol.thisIndex+1 : roundCol.thisIndex][ thisIsSmallFinal ? 0:matchItm.thisIndex]:undefined
|
orientation: ListView.LeftToRight
|
||||||
|
boundsBehavior: ListView.StopAtBounds
|
||||||
|
|
||||||
property int thisIndex: index
|
model: control.roundCount
|
||||||
property int thisRound: parseInt(roundCol.thisRound) - (thisIsSmallFinal ? 1:0)
|
|
||||||
property var thisMatchData: thisMatchDataIsValid ? matchData:[]
|
|
||||||
|
|
||||||
property bool thisMatchDataIsValid: (matchData !== undefined && matchData !== null && typeof matchData === "object" && matchData.length > 0)
|
delegate: Item {
|
||||||
property bool thisMatchIsOver: thisMatchDataIsValid && thisMatchData[0]['result_rank'+thisRound] !== undefined && thisMatchData[1]['result_rank'+thisRound] !== undefined
|
id: roundItem
|
||||||
|
|
||||||
property bool thisIsFinal: roundCol.thisIsLastRound && thisIndex === rectRep.model - 2
|
property int thisIndex: index
|
||||||
property bool thisIsSmallFinal: roundCol.thisIsLastRound && thisIndex === rectRep.model - 1
|
property int thisRound: thisRoundIsValid ? control.allFlowchartData[roundItem.thisIndex][control.allFlowchartData[roundItem.thisIndex].length-2]:-1
|
||||||
|
property bool thisRoundIsValid: control.allFlowchartData !== undefined
|
||||||
|
&& control.allFlowchartData[roundItem.thisIndex] !== undefined
|
||||||
|
&& control.allFlowchartData[roundItem.thisIndex].length > 2
|
||||||
|
|
||||||
property int winnerIndex: thisMatchIsOver ? (parseInt(thisMatchData[0]['result_rank'+thisRound]) < parseInt(thisMatchData[1]['result_rank'+thisRound]) ? 0:1) : -1
|
property bool thisIsLastRound: thisIndex === control.roundCount - 1
|
||||||
|
property bool thisIsSemiFinal: thisIndex === control.roundCount - 2 && rectRep.model === 2
|
||||||
|
|
||||||
height: !roundCol.thisIsLastRound ? (roundCol.height - roundNameLa.height) / rectRep.model - roundCol.spacing : (thisIsFinal ? (roundCol.height - roundNameLa.height) * 0.5 + control.tileSize * 0.5 : (roundCol.height - roundNameLa.height) - (roundCol.height - roundNameLa.height) * 0.5 + control.tileSize * 0.5 )
|
property int tileSize: (roundItem.height / 8 - roundNameLa.height) * 1.45
|
||||||
width: parent.width
|
|
||||||
|
|
||||||
onMatchDataChanged: {
|
width: roundListView.columnWidth
|
||||||
fadeInPa.start()
|
height: roundListView.columnHeight
|
||||||
}
|
|
||||||
|
|
||||||
ParallelAnimation {
|
Column {
|
||||||
id: fadeInPa
|
id: roundCol
|
||||||
NumberAnimation { target: matchItm; property: "opacity"; from: 0; to: 1.0; duration: 400 }
|
|
||||||
NumberAnimation { target: matchItm; property: "scale"; from: 0.8; to: 1.0; duration: 400 }
|
|
||||||
}
|
|
||||||
|
|
||||||
Canvas {
|
anchors.fill: parent
|
||||||
id: lineCanvas
|
|
||||||
width: app.width; height: app.height
|
|
||||||
contextType: "2d"
|
|
||||||
|
|
||||||
visible: !roundCol.thisIsLastRound
|
Label {
|
||||||
|
id: roundNameLa
|
||||||
property int targetX: matchItm.width + control.spacing
|
|
||||||
property int targetY: matchItm.lowerPart ? 0:matchItm.height
|
|
||||||
|
|
||||||
Path {
|
|
||||||
id: myPath
|
|
||||||
startX: matchRect.x + matchRect.width * matchRect.scale ; startY: matchRect.y + matchRect.height * 0.5
|
|
||||||
|
|
||||||
PathCurve { x: lineCanvas.targetX ; y: lineCanvas.targetY }
|
|
||||||
}
|
|
||||||
|
|
||||||
onPaint: {
|
|
||||||
context.strokeStyle = Qt.rgba(.4,.6,.8);
|
|
||||||
context.path = myPath;
|
|
||||||
context.stroke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: matchRect
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
centerIn: !matchItm.thisIsFinal ? parent:undefined
|
|
||||||
bottom: matchItm.thisIsFinal ? parent.bottom:undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
//anchors.verticalCenterOffset: matchItm.lowerPart ? 10:10
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: control.tileSize
|
height: control.height * 0.05
|
||||||
//scale: 0.9
|
horizontalAlignment: Text.AlignHCenter
|
||||||
color: "white"
|
verticalAlignment: Text.AlignVCenter
|
||||||
border.color: "lightgrey"
|
fontSizeMode: Text.Fit
|
||||||
border.width: 1
|
font.pixelSize: height * 0.6
|
||||||
radius: height * 0.2
|
minimumPixelSize: 1
|
||||||
Material.elevation: 10
|
font.bold: true
|
||||||
|
text: roundItem.thisRoundIsValid
|
||||||
|
&& control.allFlowchartData[roundItem.thisIndex][control.allFlowchartData[roundItem.thisIndex].length-1] !== undefined ?
|
||||||
|
control.allFlowchartData[roundItem.thisIndex][control.allFlowchartData[roundItem.thisIndex].length-1] :
|
||||||
|
"-"
|
||||||
|
}
|
||||||
|
|
||||||
Grid {
|
Repeater {
|
||||||
columns: app.landscape() ? 2:0
|
id: rectRep
|
||||||
rows: app.landscape() ? 0:2
|
model: Math.max( Math.pow(2, control.roundCount-1) * Math.pow(0.5, (roundItem.thisIndex)), 2)
|
||||||
|
delegate: Item {
|
||||||
|
id: matchItm
|
||||||
|
|
||||||
spacing: app.landscape() ? height * 0.4:0
|
property bool lowerPart: (index%2 > 0)
|
||||||
|
|
||||||
anchors.fill: parent
|
property var matchData: roundItem.thisRoundIsValid ?
|
||||||
anchors.margins: matchRect.radius * 0.5
|
control.allFlowchartData[
|
||||||
|
thisIsSmallFinal ?
|
||||||
|
roundItem.thisIndex+1 :
|
||||||
|
roundItem.thisIndex
|
||||||
|
][ thisIsSmallFinal ? 0:matchItm.thisIndex]:
|
||||||
|
undefined
|
||||||
|
|
||||||
Repeater {
|
property int thisIndex: index
|
||||||
// for the two athletes
|
property int thisRound: parseInt(roundItem.thisRound) - (thisIsSmallFinal ? 1:0)
|
||||||
model: 2
|
property var thisMatchData: thisMatchDataIsValid ? matchData:[]
|
||||||
|
|
||||||
delegate: RowLayout {
|
property bool thisMatchDataIsValid: (matchData !== undefined && matchData !== null && typeof matchData === "object" && matchData.length > 0)
|
||||||
|
property bool thisMatchIsOver: thisMatchDataIsValid && thisMatchData[0]['result_rank'+thisRound] !== undefined && thisMatchData[1]['result_rank'+thisRound] !== undefined
|
||||||
|
|
||||||
height: app.landscape() ? parent.height:parent.height / 2 - parent.spacing
|
property bool thisIsFinal: roundItem.thisIsLastRound && thisIndex === rectRep.model - 2
|
||||||
width: app.landscape() ? parent.width / 2 - parent.spacing : parent.width
|
property bool thisIsSmallFinal: roundItem.thisIsLastRound && thisIndex === rectRep.model - 1
|
||||||
|
|
||||||
spacing: app.landscape() ? height * 0.1:height * 0.1
|
property int winnerIndex: thisMatchIsOver ? (parseInt(thisMatchData[0]['result_rank'+thisRound]) < parseInt(thisMatchData[1]['result_rank'+thisRound]) ? 0:1) : -1
|
||||||
|
|
||||||
Label {
|
height: !roundItem.thisIsLastRound ?
|
||||||
Layout.preferredHeight: parent.height
|
(roundItem.height - roundNameLa.height) / rectRep.model - roundCol.spacing :
|
||||||
|
(thisIsFinal ?
|
||||||
|
(roundItem.height - roundNameLa.height) * 0.5 + roundItem.tileSize * 0.5 :
|
||||||
|
(roundItem.height - roundNameLa.height) - (roundItem.height - roundNameLa.height) * 0.5 + roundItem.tileSize * 0.5
|
||||||
|
)
|
||||||
|
|
||||||
height: parent.height
|
width: roundItem.width
|
||||||
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
onMatchDataChanged: {
|
||||||
font.pixelSize: height * 0.7
|
fadeInPa.start()
|
||||||
fontSizeMode: Text.Fit
|
}
|
||||||
minimumPixelSize: 1
|
|
||||||
|
|
||||||
Layout.alignment: Layout.Left
|
ParallelAnimation {
|
||||||
|
id: fadeInPa
|
||||||
|
NumberAnimation { target: matchItm; property: "opacity"; from: 0; to: 1.0; duration: 400 }
|
||||||
|
NumberAnimation { target: matchItm; property: "scale"; from: 0.8; to: 1.0; duration: 400 }
|
||||||
|
}
|
||||||
|
|
||||||
text: matchItm.thisMatchData[index] !== undefined ? (parseInt(matchItm.thisMatchData[index]['result_rank0']) < 10 ?matchItm.thisMatchData[index]['result_rank0'] + " ":matchItm.thisMatchData[index]['result_rank0']): ""
|
Canvas {
|
||||||
|
id: lineCanvas
|
||||||
|
width: app.width; height: app.height
|
||||||
|
contextType: "2d"
|
||||||
|
|
||||||
|
visible: !roundItem.thisIsLastRound
|
||||||
|
|
||||||
|
property int targetYFactor: matchItm.lowerPart ? -1:1
|
||||||
|
|
||||||
|
Path {
|
||||||
|
id: firstPartPath
|
||||||
|
startX: matchItm.width
|
||||||
|
startY: matchItm.height * 0.5
|
||||||
|
|
||||||
|
PathQuad {
|
||||||
|
id: firstPartPathQuad
|
||||||
|
relativeX: roundListView.spacing * 0.5
|
||||||
|
relativeY: matchItm.height * 0.25 * lineCanvas.targetYFactor
|
||||||
|
relativeControlX: relativeX
|
||||||
|
relativeControlY: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
PathQuad {
|
||||||
Layout.preferredHeight: parent.height
|
relativeX: roundListView.spacing * 0.5
|
||||||
|
relativeY: matchItm.height * 0.25 * lineCanvas.targetYFactor
|
||||||
height: parent.height
|
relativeControlX: 0
|
||||||
|
relativeControlY: relativeY
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
//horizontalAlignment: app.landscape() ? Text.AlignLeft : Text.AlignLeft
|
|
||||||
font.pixelSize: app.landscape() ? height * 0.4 : height * 0.6
|
|
||||||
minimumPixelSize: (app.landscape() ? height * 0.35 : height * 0.5) < 1 ? 1 : (app.landscape() ? height * 0.35 : height * 0.5)
|
|
||||||
fontSizeMode: Text.Fit
|
|
||||||
font.bold: matchItm.winnerIndex === index
|
|
||||||
elide: "ElideRight"
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
color: matchItm.winnerIndex === index ? "green":"black"
|
|
||||||
|
|
||||||
text: matchItm.thisMatchData[index] !== undefined ? matchItm.thisMatchData[index]['firstname'] + " " + matchItm.thisMatchData[index]['lastname'] :"-"
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Label {
|
onPaint: {
|
||||||
Layout.preferredHeight: parent.height
|
context.strokeStyle = "lightgrey"
|
||||||
|
context.lineWidth = matchRect.height * 0.05
|
||||||
|
context.path = firstPartPath;
|
||||||
|
context.stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
height: parent.height
|
RectangularGlow {
|
||||||
|
id: effect
|
||||||
|
anchors.fill: matchRect
|
||||||
|
glowRadius: 0
|
||||||
|
spread: 0
|
||||||
|
opacity: 0.3
|
||||||
|
color: "black"
|
||||||
|
cornerRadius: matchRect.radius
|
||||||
|
}
|
||||||
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
Rectangle {
|
||||||
font.pixelSize: app.landscape() ? height * 0.35 : height * 0.5
|
id: matchRect
|
||||||
|
|
||||||
Layout.alignment: Layout.Right
|
anchors {
|
||||||
|
centerIn: !matchItm.thisIsFinal ? parent:undefined
|
||||||
|
bottom: matchItm.thisIsFinal ? parent.bottom:undefined
|
||||||
|
}
|
||||||
|
|
||||||
text: matchItm.thisMatchData[index] !== undefined && matchItm.thisMatchData[index]['result'+matchItm.thisRound] !== undefined ?
|
//anchors.verticalCenterOffset: matchItm.lowerPart ? 10:10
|
||||||
( parseFloat(matchItm.thisMatchData[index]['result'+matchItm.thisRound]) ?
|
width: parent.width
|
||||||
(parseFloat(matchItm.thisMatchData[index]['result'+matchItm.thisRound]).toFixed(2))
|
height: roundItem.tileSize
|
||||||
: matchItm.thisMatchData[index]['result'+matchItm.thisRound] )
|
//scale: 0.9
|
||||||
: "-"
|
color: "white"
|
||||||
|
border.color: "lightgrey"
|
||||||
|
border.width: 0
|
||||||
|
radius: height * 0.2
|
||||||
|
|
||||||
|
Column {
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: matchRect.radius * 0.5
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
// for the two athletes
|
||||||
|
model: 2
|
||||||
|
|
||||||
|
delegate: RowLayout {
|
||||||
|
|
||||||
|
height: parent.height / 2 - parent.spacing
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
spacing: height * 0.1
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.preferredHeight: parent.height
|
||||||
|
Layout.preferredWidth: parent.width * 0.15
|
||||||
|
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
font.pixelSize: height * 0.7
|
||||||
|
fontSizeMode: Text.Fit
|
||||||
|
minimumPixelSize: 1
|
||||||
|
|
||||||
|
text: matchItm.thisMatchData[index] !== undefined ?
|
||||||
|
(
|
||||||
|
parseInt(matchItm.thisMatchData[index]['result_rank0']) < 10 ?
|
||||||
|
matchItm.thisMatchData[index]['result_rank0'] + " ":
|
||||||
|
matchItm.thisMatchData[index]['result_rank0']
|
||||||
|
):
|
||||||
|
""
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.preferredHeight: parent.height
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
height: parent.height
|
||||||
|
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
font.pixelSize: height * 0.5
|
||||||
|
font.bold: matchItm.winnerIndex === index
|
||||||
|
elide: "ElideRight"
|
||||||
|
|
||||||
|
color: matchItm.winnerIndex === index ? "green":"black"
|
||||||
|
|
||||||
|
text: matchItm.thisMatchData[index] !== undefined ? matchItm.thisMatchData[index]['firstname'] + " " + matchItm.thisMatchData[index]['lastname'] :"-"
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.preferredHeight: parent.height
|
||||||
|
|
||||||
|
height: parent.height
|
||||||
|
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
font.pixelSize: height * 0.5
|
||||||
|
|
||||||
|
text: matchItm.thisMatchData[index] !== undefined && matchItm.thisMatchData[index]['result'+matchItm.thisRound] !== undefined ?
|
||||||
|
( parseFloat(matchItm.thisMatchData[index]['result'+matchItm.thisRound]) ?
|
||||||
|
(parseFloat(matchItm.thisMatchData[index]['result'+matchItm.thisRound]).toFixed(2))
|
||||||
|
: matchItm.thisMatchData[index]['result'+matchItm.thisRound] )
|
||||||
|
: "-"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: blueRockBadgeLoader
|
||||||
|
|
||||||
|
x: (parent.width - width) / 2
|
||||||
|
y: (parent.height - roundNameLa.height - height) / 2 + roundNameLa.height
|
||||||
|
|
||||||
|
sourceComponent: roundItem.thisIsSemiFinal ? blueRockBadgeComponent:undefined
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: blueRockBadgeComponent
|
||||||
|
|
||||||
|
BlueRockBadge {
|
||||||
|
width: roundItem.width
|
||||||
|
height: width * 0.25
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
101
resources/qml/Components/SpeedFlowChartLocker.qml
Normal file
101
resources/qml/Components/SpeedFlowChartLocker.qml
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
import QtPurchasing 1.12
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: speedFlowChartLockedOverlay
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: -20
|
||||||
|
|
||||||
|
color: "white"
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: speedFlowChartProduct
|
||||||
|
|
||||||
|
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"
|
||||||
|
onClicked: speedFlowChartProduct.purchase()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
116
resources/qml/Components/SpeedFlowChartPopup.qml
Normal file
116
resources/qml/Components/SpeedFlowChartPopup.qml
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import QtQuick.Controls.Material 2.15
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: control
|
||||||
|
|
||||||
|
property var flowchartData: ({})
|
||||||
|
|
||||||
|
// always unlock in debug mode
|
||||||
|
property bool unlocked: appSettings.read("speedBackendPurchase") === "1" || QT_DEBUG
|
||||||
|
|
||||||
|
state: "hidden"
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
top: parent.top
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: parent.right
|
||||||
|
}
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
|
||||||
|
color: Material.background
|
||||||
|
|
||||||
|
onStateChanged: {
|
||||||
|
if(state === "visible" && unlocked) {
|
||||||
|
speedFlowChartLoader.sourceComponent = speedFlowChartComponent
|
||||||
|
}
|
||||||
|
else if(state === "visible" && !unlocked) {
|
||||||
|
speedFlowChartLoader.sourceComponent = speedFlowChartLockerComponent
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
speedFlowChartLoader.sourceComponent = undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggle() {
|
||||||
|
if(control.state === "hidden"){
|
||||||
|
control.state = "visible"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
control.state = "hidden"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isVisible() {
|
||||||
|
return control.state === "visible"
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: speedFlowChartProduct
|
||||||
|
function onPurchaseRestored() {
|
||||||
|
control.unlocked = appSettings.read("speedBackendPurchase") === "1" ? "unlocked":"locked"
|
||||||
|
}
|
||||||
|
|
||||||
|
function onPurchaseSucceeded() {
|
||||||
|
control.unlocked = appSettings.read("speedBackendPurchase") === "1" ? "unlocked":"locked"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: speedFlowChartLoader
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: speedFlowChartComponent
|
||||||
|
SpeedFlowChart {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 10
|
||||||
|
|
||||||
|
flowchartData: control.flowchartData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: speedFlowChartLockerComponent
|
||||||
|
|
||||||
|
SpeedFlowChartLocker {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "hidden"
|
||||||
|
PropertyChanges {
|
||||||
|
target: control
|
||||||
|
opacity: 0
|
||||||
|
anchors.leftMargin: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
State {
|
||||||
|
name: "visible"
|
||||||
|
PropertyChanges {
|
||||||
|
target: control
|
||||||
|
opacity: 1
|
||||||
|
anchors.leftMargin: -parent.width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
transitions: [
|
||||||
|
Transition {
|
||||||
|
NumberAnimation {
|
||||||
|
properties: "opacity,scale,anchors.leftMargin"
|
||||||
|
duration: 200
|
||||||
|
easing.type: Easing.InOutQuad
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -29,9 +29,8 @@ Page {
|
||||||
|
|
||||||
signal headerComponentChanged()
|
signal headerComponentChanged()
|
||||||
|
|
||||||
RowLayout {
|
BlueRockBadge {
|
||||||
id: headerLayout
|
id: headerBadge
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
horizontalCenter: parent.horizontalCenter
|
horizontalCenter: parent.horizontalCenter
|
||||||
top: parent.top
|
top: parent.top
|
||||||
|
@ -40,28 +39,6 @@ Page {
|
||||||
|
|
||||||
height: menuGr.buttonSize * 0.3
|
height: menuGr.buttonSize * 0.3
|
||||||
spacing: anchors.topMargin * 0.5
|
spacing: anchors.topMargin * 0.5
|
||||||
|
|
||||||
Image {
|
|
||||||
Layout.preferredHeight: parent.height
|
|
||||||
Layout.preferredWidth: height
|
|
||||||
|
|
||||||
fillMode: Image.PreserveAspectFit
|
|
||||||
mipmap: true
|
|
||||||
|
|
||||||
source: "qrc:/icons/blueRockHold.png"
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
Layout.preferredHeight: parent.height
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
font.pixelSize: parent.height * 0.6
|
|
||||||
font.bold: true
|
|
||||||
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
|
|
||||||
text: "blueROCK"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Grid {
|
Grid {
|
||||||
|
@ -125,7 +102,7 @@ Page {
|
||||||
anchors {
|
anchors {
|
||||||
horizontalCenter: parent.horizontalCenter
|
horizontalCenter: parent.horizontalCenter
|
||||||
bottom: parent.bottom
|
bottom: parent.bottom
|
||||||
bottomMargin: headerLayout.anchors.topMargin
|
bottomMargin: headerBadge.anchors.topMargin
|
||||||
}
|
}
|
||||||
|
|
||||||
width: parent.width * 0.9
|
width: parent.width * 0.9
|
||||||
|
@ -161,6 +138,10 @@ Page {
|
||||||
|
|
||||||
contentItem: Label {
|
contentItem: Label {
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
|
|
||||||
|
width: ifscDisclaimerDialog.width * 0.8
|
||||||
|
height: implicitHeight
|
||||||
|
|
||||||
text:
|
text:
|
||||||
"Unfortunately, the IFSC has restricted the access to their data and <b>is not willing to share results with blueROCK anymore</b>. " +
|
"Unfortunately, the IFSC has restricted the access to their data and <b>is not willing to share results with blueROCK anymore</b>. " +
|
||||||
"Because of this, blueROCK is no longer able to access and display IFSC results.<br><br>" +
|
"Because of this, blueROCK is no longer able to access and display IFSC results.<br><br>" +
|
||||||
|
|
|
@ -245,107 +245,16 @@ Page {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Dialog {
|
SelectorPopup {
|
||||||
id: selectorPu
|
id: selectorPu
|
||||||
|
|
||||||
property var dataObj
|
contentItem: ListView {
|
||||||
property string subTitle: ""
|
|
||||||
|
|
||||||
signal selectionFinished(int index, var data)
|
|
||||||
|
|
||||||
x: 0 //root.width / 2 - width / 2
|
|
||||||
y: root.height - selectorPu.height * 0.7//root.height - height //root.height / 2 - height / 2
|
|
||||||
|
|
||||||
opacity: 0
|
|
||||||
|
|
||||||
width: root.width
|
|
||||||
height: selectorLv.implicitHeight
|
|
||||||
|
|
||||||
modal: true
|
|
||||||
focus: true
|
|
||||||
|
|
||||||
title: ""
|
|
||||||
|
|
||||||
header: Column {
|
|
||||||
id: selectorPuHeaderCol
|
|
||||||
|
|
||||||
width: parent.width
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: headerLa
|
|
||||||
|
|
||||||
visible: selectorPu.title
|
|
||||||
|
|
||||||
width: parent.width
|
|
||||||
|
|
||||||
elide: "ElideRight"
|
|
||||||
padding: 24
|
|
||||||
bottomPadding: 0
|
|
||||||
font.bold: true
|
|
||||||
font.pixelSize: 16
|
|
||||||
background: Rectangle {
|
|
||||||
radius: 2
|
|
||||||
color: selectorPu.Material.dialogColor
|
|
||||||
clip: true
|
|
||||||
}
|
|
||||||
|
|
||||||
text: selectorPu.title
|
|
||||||
|
|
||||||
onLinkActivated: {
|
|
||||||
Qt.openUrlExternally(link)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
id: headerSubLa
|
|
||||||
|
|
||||||
visible: selectorPu.subTitle
|
|
||||||
|
|
||||||
width: parent.width
|
|
||||||
|
|
||||||
elide: "ElideRight"
|
|
||||||
padding: 24
|
|
||||||
topPadding: 5
|
|
||||||
bottomPadding: 0
|
|
||||||
font.bold: true
|
|
||||||
font.pixelSize: 16
|
|
||||||
background: Rectangle {
|
|
||||||
radius: 2
|
|
||||||
color: selectorPu.Material.dialogColor
|
|
||||||
clip: true
|
|
||||||
}
|
|
||||||
|
|
||||||
text: selectorPu.subTitle
|
|
||||||
|
|
||||||
onLinkActivated: {
|
|
||||||
Qt.openUrlExternally(link)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function appear(dataObj, title, subTitle) {
|
|
||||||
if(dataObj.length > 0){
|
|
||||||
selectorPu.dataObj = dataObj
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
selectorPu.dataObj = undefined
|
|
||||||
}
|
|
||||||
selectorPu.title = title
|
|
||||||
selectorPu.subTitle = subTitle === undefined ? "":subTitle
|
|
||||||
selectorPu.open()
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ListView {
|
|
||||||
id: selectorLv
|
id: selectorLv
|
||||||
|
|
||||||
property int delegateHeight: 50
|
property int delegateHeight: 50
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
anchors.fill: parent
|
implicitHeight: model === 0 ? 0:(delegateHeight + spacing) * model
|
||||||
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: root.height * 0.7 < ( (delegateHeight + spacing) * model ) ? root.height * 0.7 : (delegateHeight + spacing) * model + 100
|
|
||||||
|
|
||||||
model: selectorPu.dataObj !== undefined ? selectorPu.dataObj.length:0
|
model: selectorPu.dataObj !== undefined ? selectorPu.dataObj.length:0
|
||||||
|
|
||||||
|
@ -377,32 +286,5 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enter: Transition {
|
|
||||||
NumberAnimation {
|
|
||||||
property: "opacity";
|
|
||||||
//from: 0.0;
|
|
||||||
to: 1.0
|
|
||||||
}
|
|
||||||
NumberAnimation {
|
|
||||||
property: "y"
|
|
||||||
//from: root.height - selectorPu.height * 0.7
|
|
||||||
to: root.height - selectorPu.height
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exit: Transition {
|
|
||||||
NumberAnimation {
|
|
||||||
property: "opacity";
|
|
||||||
//from: 1.0;
|
|
||||||
to: 0.0
|
|
||||||
}
|
|
||||||
NumberAnimation {
|
|
||||||
property: "y"
|
|
||||||
//from: root.height - selectorPu.height
|
|
||||||
to: root.height - selectorPu.height * 0.7
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,7 +150,7 @@ DataListView {
|
||||||
|
|
||||||
if(endDate.getTime() < new Date().getTime()){
|
if(endDate.getTime() < new Date().getTime()){
|
||||||
// end date is already over -> move the list view down!
|
// end date is already over -> move the list view down!
|
||||||
control.positionViewAtIndex(i, ListView.Top)
|
control.positionViewAtIndex(i - 2, ListView.Top)
|
||||||
//console.log("moving down!")
|
//console.log("moving down!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -400,114 +400,18 @@ DataListView {
|
||||||
delegate: CompetitionCalendarDelegate {
|
delegate: CompetitionCalendarDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
section.property: "month"
|
SelectorPopup {
|
||||||
section.delegate: ItemDelegate {
|
|
||||||
id: name
|
|
||||||
background: Rectangle {
|
|
||||||
color: "red"
|
|
||||||
}
|
|
||||||
|
|
||||||
width: parent.width
|
|
||||||
text: section
|
|
||||||
}
|
|
||||||
|
|
||||||
Dialog {
|
|
||||||
id: filterSelectPu
|
id: filterSelectPu
|
||||||
|
|
||||||
property var dataObj
|
contentItem: ListView {
|
||||||
property string subTitle: ""
|
|
||||||
|
|
||||||
signal selectionFinished(int index, var data)
|
|
||||||
|
|
||||||
x: 0 - control.anchors.leftMargin //root.width / 2 - width / 2
|
|
||||||
y: root.height - filterSelectPu.height * 0.7//root.height - height //root.height / 2 - height / 2
|
|
||||||
|
|
||||||
opacity: 0
|
|
||||||
|
|
||||||
width: control.width + control.anchors.leftMargin + control.anchors.rightMargin
|
|
||||||
height: selectorLv.implicitHeight
|
|
||||||
|
|
||||||
modal: true
|
|
||||||
focus: true
|
|
||||||
|
|
||||||
title: ""
|
|
||||||
|
|
||||||
function appear(dataObj, title, subTitle) {
|
|
||||||
if(dataObj.length > 0){
|
|
||||||
filterSelectPu.dataObj = dataObj
|
|
||||||
filterSelectPu.title = title
|
|
||||||
filterSelectPu.subTitle = subTitle === undefined ? "":subTitle
|
|
||||||
filterSelectPu.open()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
header: Column {
|
|
||||||
id: filterSelectPuHeaderCol
|
|
||||||
|
|
||||||
width: parent.width
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: headerLa
|
|
||||||
|
|
||||||
visible: filterSelectPu.title
|
|
||||||
|
|
||||||
width: parent.width
|
|
||||||
|
|
||||||
elide: "ElideRight"
|
|
||||||
padding: 24
|
|
||||||
bottomPadding: 0
|
|
||||||
font.bold: true
|
|
||||||
font.pixelSize: 16
|
|
||||||
background: Rectangle {
|
|
||||||
radius: 2
|
|
||||||
//color: filterSelectPu.Material.dialogColor
|
|
||||||
clip: true
|
|
||||||
}
|
|
||||||
|
|
||||||
text: filterSelectPu.title
|
|
||||||
|
|
||||||
onLinkActivated: {
|
|
||||||
Qt.openUrlExternally(link)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
id: headerSubLa
|
|
||||||
|
|
||||||
visible: filterSelectPu.subTitle
|
|
||||||
|
|
||||||
width: parent.width
|
|
||||||
|
|
||||||
elide: "ElideRight"
|
|
||||||
padding: 24
|
|
||||||
topPadding: 5
|
|
||||||
bottomPadding: 0
|
|
||||||
font.bold: true
|
|
||||||
font.pixelSize: 16
|
|
||||||
background: Rectangle {
|
|
||||||
radius: 2
|
|
||||||
//color: filterSelectPu.Material.dialogColor
|
|
||||||
clip: true
|
|
||||||
}
|
|
||||||
|
|
||||||
text: filterSelectPu.subTitle
|
|
||||||
|
|
||||||
onLinkActivated: {
|
|
||||||
Qt.openUrlExternally(link)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ListView {
|
|
||||||
id: selectorLv
|
id: selectorLv
|
||||||
|
|
||||||
property int delegateHeight: 50
|
property int delegateHeight: 50
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
anchors.fill: parent
|
clip: true
|
||||||
|
|
||||||
implicitWidth: parent.width
|
implicitHeight: model === 0 ? 0:(delegateHeight + spacing) * model
|
||||||
implicitHeight: root.height * 0.7 < ( (delegateHeight + spacing) * model ) ? root.height * 0.7 : (delegateHeight + spacing) * model + 100
|
|
||||||
|
|
||||||
model: filterSelectPu.dataObj !== undefined ? filterSelectPu.dataObj.length:0
|
model: filterSelectPu.dataObj !== undefined ? filterSelectPu.dataObj.length:0
|
||||||
|
|
||||||
|
@ -520,13 +424,12 @@ DataListView {
|
||||||
leftMargin: 3
|
leftMargin: 3
|
||||||
bottom: selectorLv.bottom
|
bottom: selectorLv.bottom
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate: CheckDelegate {
|
delegate: CheckDelegate {
|
||||||
id: catBt
|
id: catBt
|
||||||
|
|
||||||
width: parent.width
|
width: selectorLv.width
|
||||||
height: text !== "" ? selectorLv.delegateHeight:0
|
height: text !== "" ? selectorLv.delegateHeight:0
|
||||||
|
|
||||||
//flat: true
|
//flat: true
|
||||||
|
@ -567,31 +470,5 @@ DataListView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enter: Transition {
|
|
||||||
NumberAnimation {
|
|
||||||
property: "opacity";
|
|
||||||
//from: 0.0;
|
|
||||||
to: 1.0
|
|
||||||
}
|
|
||||||
NumberAnimation {
|
|
||||||
property: "y"
|
|
||||||
//from: root.height - filterSelectPu.height * 0.7
|
|
||||||
to: root.height - filterSelectPu.height
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exit: Transition {
|
|
||||||
NumberAnimation {
|
|
||||||
property: "opacity";
|
|
||||||
//from: 1.0;
|
|
||||||
to: 0.0
|
|
||||||
}
|
|
||||||
NumberAnimation {
|
|
||||||
property: "y"
|
|
||||||
//from: root.height - filterSelectPu.height
|
|
||||||
to: root.height - filterSelectPu.height * 0.7
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
import QtQuick 2.9
|
import QtQuick 2.9
|
||||||
import QtQuick.Controls 2.4
|
import QtQuick.Controls 2.4
|
||||||
import QtQuick.Controls.Material 2.3
|
import QtQuick.Controls.Material 2.3
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
import "../Components"
|
import "../Components"
|
||||||
|
|
||||||
|
@ -43,25 +44,11 @@ Page {
|
||||||
id: mainSv
|
id: mainSv
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 10
|
anchors.margins: 20
|
||||||
anchors.rightMargin: 14
|
|
||||||
|
|
||||||
contentWidth: parent.width - anchors.leftMargin - anchors.rightMargin
|
contentWidth: parent.width - anchors.margins * 2
|
||||||
|
|
||||||
ScrollBar.vertical: ScrollBar {
|
ScrollBar.vertical.policy: ScrollBar.AlwaysOff
|
||||||
|
|
||||||
anchors {
|
|
||||||
top: mainSv.top
|
|
||||||
left: mainSv.right
|
|
||||||
margins: 10
|
|
||||||
leftMargin: 3
|
|
||||||
bottom: mainSv.bottom
|
|
||||||
}
|
|
||||||
|
|
||||||
width: 8
|
|
||||||
|
|
||||||
active: true
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: mainCol
|
id: mainCol
|
||||||
|
@ -72,25 +59,61 @@ Page {
|
||||||
height: control.height * 0.3
|
height: control.height * 0.3
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
||||||
Image {
|
spacing: photoContainerItem.width * 0.1
|
||||||
id: photo
|
|
||||||
|
|
||||||
property bool ready: false
|
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: photoContainerItem
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
height: parent.height * 0.9
|
height: parent.height * 0.9
|
||||||
width: status === Image.Null || status === Image.Error ? 0:parent.width * 0.5
|
width: photo.status === Image.Null || photo.status === Image.Error ? 0:parent.width * 0.4
|
||||||
|
|
||||||
fillMode: Image.PreserveAspectFit
|
RectangularGlow {
|
||||||
|
id: effect
|
||||||
|
visible: photo.ready
|
||||||
|
anchors.fill: photo
|
||||||
|
glowRadius: 1
|
||||||
|
opacity: 0.4
|
||||||
|
color: "black"
|
||||||
|
cornerRadius: photo.width * 0.2
|
||||||
|
}
|
||||||
|
|
||||||
source: widgetData["photo"] === undefined ? "":widgetData["photo"].replace("https", "http").replace("www.digitalrock.de", "egw.ifsc-climbing.org")
|
Image {
|
||||||
asynchronous: true
|
id: photo
|
||||||
|
|
||||||
|
property bool ready: photo.status === Image.Ready
|
||||||
|
|
||||||
FancyBusyIndicator {
|
|
||||||
height: width
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
opacity: photo.status === Image.Loading
|
height: parent.height * 0.9
|
||||||
|
width: height * 0.7
|
||||||
|
|
||||||
|
fillMode: Image.PreserveAspectCrop
|
||||||
|
mipmap: true
|
||||||
|
|
||||||
|
source: widgetData["photo"] === undefined ?
|
||||||
|
"":
|
||||||
|
widgetData["photo"].replace("https", "http")
|
||||||
|
asynchronous: true
|
||||||
|
|
||||||
|
FancyBusyIndicator {
|
||||||
|
height: width
|
||||||
|
anchors.centerIn: parent
|
||||||
|
opacity: photo.status === Image.Loading
|
||||||
|
}
|
||||||
|
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: OpacityMask {
|
||||||
|
maskSource: Item {
|
||||||
|
width: photo.width
|
||||||
|
height: photo.height
|
||||||
|
Rectangle {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: photo.width
|
||||||
|
height: photo.height
|
||||||
|
radius: photo.width * 0.2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +122,7 @@ Page {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
height: parent.height * 0.9
|
height: parent.height * 0.9
|
||||||
width: parent.width - photo.width
|
width: parent.width - photoContainerItem.width * 1.1
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
|
|
||||||
|
@ -214,7 +237,9 @@ Page {
|
||||||
|
|
||||||
wrapMode: Label.Wrap
|
wrapMode: Label.Wrap
|
||||||
|
|
||||||
text: widgetData["freetext"] === undefined ? "":widgetData["freetext"]
|
text: widgetData["freetext"] === undefined ?
|
||||||
|
"":
|
||||||
|
(widgetData["freetext"] + "<br>")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +249,7 @@ Page {
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
height: 1
|
height: 1
|
||||||
width: parent.width * 0.9
|
width: parent.width
|
||||||
|
|
||||||
color: "black"
|
color: "black"
|
||||||
|
|
||||||
|
@ -307,6 +332,7 @@ Page {
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 50
|
height: 50
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
opacity: 0
|
opacity: 0
|
||||||
scale: 0.9
|
scale: 0.9
|
||||||
|
@ -324,11 +350,11 @@ Page {
|
||||||
Label {
|
Label {
|
||||||
id: bestResultRankLa
|
id: bestResultRankLa
|
||||||
|
|
||||||
width: parent.width * 0.2
|
width: parent.width * 0.1
|
||||||
height: parent.height
|
height: parent.height
|
||||||
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
|
||||||
fontSizeMode: Text.Fit
|
fontSizeMode: Text.Fit
|
||||||
minimumPixelSize: 1
|
minimumPixelSize: 1
|
||||||
|
@ -341,11 +367,11 @@ Page {
|
||||||
Label {
|
Label {
|
||||||
id: bestResultCompLa
|
id: bestResultCompLa
|
||||||
|
|
||||||
width: parent.width * 0.6
|
width: parent.width * 0.7
|
||||||
height: parent.height
|
height: parent.height
|
||||||
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
|
||||||
fontSizeMode: Text.Fit
|
fontSizeMode: Text.Fit
|
||||||
minimumPixelSize: height * 0.3
|
minimumPixelSize: height * 0.3
|
||||||
|
@ -370,7 +396,7 @@ Page {
|
||||||
scale: 0.8
|
scale: 0.8
|
||||||
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignRight
|
||||||
|
|
||||||
fontSizeMode: Text.Fit
|
fontSizeMode: Text.Fit
|
||||||
minimumPixelSize: 1
|
minimumPixelSize: 1
|
||||||
|
|
|
@ -35,7 +35,7 @@ DataListView {
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: selector
|
target: selector
|
||||||
onSelectionFinished: {
|
function onSelectionFinished(index, data) {
|
||||||
if(data.cat !== undefined){
|
if(data.cat !== undefined){
|
||||||
updateData({cat: data.cat}, true)
|
updateData({cat: data.cat}, true)
|
||||||
}
|
}
|
||||||
|
@ -64,12 +64,12 @@ DataListView {
|
||||||
delegate: ItemDelegate {
|
delegate: ItemDelegate {
|
||||||
id: partDel
|
id: partDel
|
||||||
|
|
||||||
property int ind: index
|
property int thisIndex: index
|
||||||
property var thisData: widgetData[ "participants" ][index]
|
property var thisData: widgetData[ "participants" ][index]
|
||||||
|
|
||||||
state: "closed"
|
state: "closed"
|
||||||
|
|
||||||
width: parent.width
|
width: control.width
|
||||||
height: 70
|
height: 70
|
||||||
|
|
||||||
opacity: 0
|
opacity: 0
|
||||||
|
@ -105,7 +105,7 @@ DataListView {
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: control
|
target: control
|
||||||
onCloseAll: {
|
function onCloseAll() {
|
||||||
partDel.state = "closed"
|
partDel.state = "closed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ DataListView {
|
||||||
|
|
||||||
width: partDel.width
|
width: partDel.width
|
||||||
|
|
||||||
color: partDel.ind % 2 == 0 ? "white":"lightgrey"
|
color: partDel.thisIndex % 2 == 0 ? "white":"lightgrey"
|
||||||
|
|
||||||
opacity: 0.2
|
opacity: 0.2
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,7 @@ DataListView {
|
||||||
font.pixelSize: Math.abs( height * 0.6 )
|
font.pixelSize: Math.abs( height * 0.6 )
|
||||||
minimumPixelSize: 1
|
minimumPixelSize: 1
|
||||||
|
|
||||||
text: widgetData[ "participants" ][partDel.ind]["points"] === undefined ? "":"points: "+widgetData[ "participants" ][partDel.ind]["points"]
|
text: widgetData[ "participants" ][partDel.thisIndex]["points"] === undefined ? "":"points: "+widgetData[ "participants" ][partDel.thisIndex]["points"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -333,7 +333,7 @@ DataListView {
|
||||||
|
|
||||||
for(var prop in obj) {
|
for(var prop in obj) {
|
||||||
// go through the whole array and search for data keys
|
// go through the whole array and search for data keys
|
||||||
if (obj.hasOwnProperty(prop) && control.widgetData["participants"][partDel.ind]["result" + prop.replace(" ", "")] !== undefined ) {
|
if (obj.hasOwnProperty(prop) && control.widgetData["participants"][partDel.thisIndex]["result" + prop.replace(" ", "")] !== undefined ) {
|
||||||
resultData.unshift([prop, obj[prop].replace("\n", " - ")])
|
resultData.unshift([prop, obj[prop].replace("\n", " - ")])
|
||||||
//console.log("found " + obj[prop] + " at index " + prop)
|
//console.log("found " + obj[prop] + " at index " + prop)
|
||||||
}
|
}
|
||||||
|
@ -382,7 +382,7 @@ DataListView {
|
||||||
horizontalAlignment: Text.AlignLeft
|
horizontalAlignment: Text.AlignLeft
|
||||||
minimumPixelSize: 1
|
minimumPixelSize: 1
|
||||||
|
|
||||||
text: control.widgetData["participants"][partDel.ind]["result"+detailResultRowRep.compResults[index][0].replace(" ", "")] === undefined ? "":control.widgetData["participants"][partDel.ind]["result"+detailResultRowRep.compResults[index][0].replace(" ", "")].replace("\n", " ")
|
text: control.widgetData["participants"][partDel.thisIndex]["result"+detailResultRowRep.compResults[index][0].replace(" ", "")] === undefined ? "":control.widgetData["participants"][partDel.thisIndex]["result"+detailResultRowRep.compResults[index][0].replace(" ", "")].replace("\n", " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on height {
|
Behavior on height {
|
||||||
|
|
|
@ -31,13 +31,13 @@ DataListView {
|
||||||
property bool titleIsPageTitle: true
|
property bool titleIsPageTitle: true
|
||||||
|
|
||||||
property Component headerComponent: ToolButton {
|
property Component headerComponent: ToolButton {
|
||||||
id: moreToolBt
|
id: moreToolBt
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
control.changeCat()
|
control.changeCat()
|
||||||
}
|
}
|
||||||
|
|
||||||
icon.name: "menu"
|
icon.name: "menu"
|
||||||
}
|
}
|
||||||
|
|
||||||
property var widgetData: currentWidgetData
|
property var widgetData: currentWidgetData
|
||||||
|
@ -111,7 +111,7 @@ DataListView {
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: selector
|
target: selector
|
||||||
onSelectionFinished: {
|
function onSelectionFinished(index, data) {
|
||||||
if(data.cat !== undefined){
|
if(data.cat !== undefined){
|
||||||
updateData({cat: data.cat}, true)
|
updateData({cat: data.cat}, true)
|
||||||
}
|
}
|
||||||
|
@ -140,10 +140,11 @@ DataListView {
|
||||||
delegate: ItemDelegate {
|
delegate: ItemDelegate {
|
||||||
id: partDel
|
id: partDel
|
||||||
|
|
||||||
|
property int thisIndex: index
|
||||||
property var thisData: widgetData[ "athletes" ][index]
|
property var thisData: widgetData[ "athletes" ][index]
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: parseInt(thisData.cat) === parseInt(params.cat) ? undefined:0
|
height: parseInt(thisData.cat) === parseInt(params.cat) ? 50:0
|
||||||
|
|
||||||
opacity: 0
|
opacity: 0
|
||||||
scale: 0.9
|
scale: 0.9
|
||||||
|
@ -164,16 +165,24 @@ DataListView {
|
||||||
|
|
||||||
text: ""
|
text: ""
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
width: partDel.width
|
||||||
|
|
||||||
|
color: partDel.thisIndex % 2 == 0 ? "white":"lightgrey"
|
||||||
|
|
||||||
|
opacity: 0.2
|
||||||
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: parent.width * 0.05
|
anchors.leftMargin: parent.width * 0.05
|
||||||
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
|
||||||
fontSizeMode: Text.Fit
|
|
||||||
font.bold: true
|
font.bold: true
|
||||||
font.pixelSize: Math.abs( height * 0.35 )
|
font.pixelSize: Math.abs( height * 0.3 )
|
||||||
minimumPixelSize: height * 0.3
|
|
||||||
|
|
||||||
elide: "ElideRight"
|
elide: "ElideRight"
|
||||||
|
|
||||||
|
|
|
@ -21,9 +21,7 @@ import QtQuick.Controls 2.4
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
import QtQuick.Controls.Material 2.3
|
import QtQuick.Controls.Material 2.3
|
||||||
//import QtLocation 5.13
|
import QtPurchasing 1.12
|
||||||
|
|
||||||
import QtPurchasing 1.12
|
|
||||||
|
|
||||||
import "../Components"
|
import "../Components"
|
||||||
|
|
||||||
|
@ -46,9 +44,7 @@ DataListView {
|
||||||
ToolButton {
|
ToolButton {
|
||||||
id: moreToolBt
|
id: moreToolBt
|
||||||
|
|
||||||
onClicked: {
|
onClicked: control.changeCat()
|
||||||
control.changeCat()
|
|
||||||
}
|
|
||||||
|
|
||||||
icon.name: "menu"
|
icon.name: "menu"
|
||||||
}
|
}
|
||||||
|
@ -56,11 +52,15 @@ DataListView {
|
||||||
ToolButton {
|
ToolButton {
|
||||||
id: flowToolBt
|
id: flowToolBt
|
||||||
|
|
||||||
visible: speedFlowChart.enabled
|
visible: speedFlowChartPopup.enabled
|
||||||
|
|
||||||
enabled: control.widgetData['route_order'] === "-1" && Object.keys(control.widgetData['route_names']).length > 2
|
enabled: control.widgetData['route_order'] === "-1" && Object.keys(control.widgetData['route_names']).length > 2
|
||||||
|
|
||||||
onClicked: speedFlowChartBackgroundRect.toggle()
|
onClicked: {
|
||||||
|
control.positionViewAtBeginning()
|
||||||
|
speedFlowChartPopup.toggle()
|
||||||
|
}
|
||||||
|
|
||||||
icon.name: "flowchart"
|
icon.name: "flowchart"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,21 +94,21 @@ DataListView {
|
||||||
console.log("widget data changed")
|
console.log("widget data changed")
|
||||||
|
|
||||||
if(control.widgetData['discipline'] === 'speed' && control.widgetData['route_order'] === "-1" && Object.keys(control.widgetData['route_names']).length > 2){
|
if(control.widgetData['discipline'] === 'speed' && control.widgetData['route_order'] === "-1" && Object.keys(control.widgetData['route_names']).length > 2){
|
||||||
speedFlowChart.flowchartData = ({})
|
speedFlowChartPopup.flowchartData = ({})
|
||||||
speedFlowChart.enabled = true
|
speedFlowChartPopup.flowchartData = control.widgetData
|
||||||
speedFlowChart.flowchartData = control.widgetData
|
speedFlowChartPopup.enabled = true
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
speedFlowChart.enabled = false
|
speedFlowChartPopup.flowchartData = ({})
|
||||||
speedFlowChart.flowchartData = ({})
|
speedFlowChartPopup.enabled = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onBackRequested() {
|
function onBackRequested() {
|
||||||
if(!speedFlowChartBackgroundRect.isVisible())
|
if(!speedFlowChartPopup.isVisible())
|
||||||
return true
|
return true
|
||||||
|
|
||||||
speedFlowChartBackgroundRect.toggle()
|
speedFlowChartPopup.toggle()
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,484 +168,13 @@ DataListView {
|
||||||
}
|
}
|
||||||
|
|
||||||
onContentYChanged: {
|
onContentYChanged: {
|
||||||
if(contentY > 0 && speedFlowChartBackgroundRect.state === "visible"){
|
if(contentY > 0 && speedFlowChartPopup.state === "visible"){
|
||||||
control.positionViewAtBeginning()
|
control.positionViewAtBeginning()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate: ItemDelegate {
|
delegate: ResultDelegate {
|
||||||
id: partDel
|
enabled: speedFlowChartPopup.state === "hidden"
|
||||||
|
|
||||||
property int ind: index
|
|
||||||
property var thisData: widgetData[ "participants" ][partDel.ind]
|
|
||||||
|
|
||||||
enabled: speedFlowChartBackgroundRect.state === "hidden"
|
|
||||||
|
|
||||||
width: control.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: Math.abs( partDelSecondRow.height > 0 ? height * 0.6:height * 0.4 )
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
|
|
||||||
text: partDel.thisData["result_rank"] === undefined ? "":partDel.thisData["result_rank"]
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
height: parent.height
|
|
||||||
width: parent.width * 0.5
|
|
||||||
|
|
||||||
fontSizeMode: Text.Fit
|
|
||||||
font.bold: true
|
|
||||||
font.pixelSize: Math.abs( partDelSecondRow.height > 0 ? height * 0.6:height * 0.4 )
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
|
||||||
|
|
||||||
text: partDel.thisData["firstname"] + " " + partDel.thisData["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: 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["fed_url"] === undefined ? "":partDel.thisData["fed_url"]).toString() + "\">" + (widgetData[ "display_athlete" ] === "nation" ? partDel.thisData["nation"] : partDel.thisData["federation"]) + "</a>)</html>"
|
|
||||||
|
|
||||||
onLinkActivated: {
|
|
||||||
Qt.openUrlExternally(link)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: partDelSecondRow
|
|
||||||
|
|
||||||
width: parent.width
|
|
||||||
height: multiResRow.active || multiGenResRow.active || resultLa.acitve ? parent.height / 2 : 0
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: multiResRow
|
|
||||||
|
|
||||||
property bool active: 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){
|
|
||||||
// TODO: clean
|
|
||||||
var resultString = widgetData[ "participants" ][partDel.ind]["boulder"+(index+1)]
|
|
||||||
var numTrys = widgetData[ "participants" ][partDel.ind]["try"+(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]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (numTrys !== undefined) {
|
|
||||||
resultList.push(numTrys)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
resultList.push(-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: boulderResTrysLa
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
|
|
||||||
height: parent.height / 2
|
|
||||||
width: parent.width / 2
|
|
||||||
|
|
||||||
visible: !boulderResZoneLa.visible
|
|
||||||
|
|
||||||
fontSizeMode: Text.Fit
|
|
||||||
font.pixelSize: height
|
|
||||||
minimumPixelSize: 1
|
|
||||||
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
|
|
||||||
text: boulderResCv.resultData[2]
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
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: ((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: ( boulderResRep.model > 0 || widgetData["discipline"] !== "boulder" ) && parseInt(widgetData[ "route_order" ]) > -1
|
|
||||||
|
|
||||||
width: enabled ? parent.width * 0.25:0
|
|
||||||
height: enabled ? parent.height:0
|
|
||||||
|
|
||||||
enabled: ( boulderResRep.model > 0 || widgetData["discipline"] !== "boulder" ) && parseInt(widgetData[ "route_order" ]) > -1
|
|
||||||
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
|
|
||||||
fontSizeMode: Text.Fit
|
|
||||||
font.pixelSize: Math.abs( height * 0.6 )
|
|
||||||
minimumPixelSize: 1
|
|
||||||
|
|
||||||
text: widgetData[ "participants" ][partDel.ind]["result"] === undefined ? "":widgetData[ "participants" ][partDel.ind]["result"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
footer: ItemDelegate {
|
footer: ItemDelegate {
|
||||||
|
@ -667,7 +196,7 @@ DataListView {
|
||||||
property var tabs: getTabs()
|
property var tabs: getTabs()
|
||||||
property var tabIndexes: []
|
property var tabIndexes: []
|
||||||
|
|
||||||
enabled: speedFlowChartBackgroundRect.state === "hidden"
|
enabled: speedFlowChartPopup.state === "hidden"
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
left: parent.left
|
left: parent.left
|
||||||
|
@ -747,209 +276,13 @@ DataListView {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
SpeedFlowChartPopup {
|
||||||
id: speedFlowChartBackgroundRect
|
id: speedFlowChartPopup
|
||||||
|
|
||||||
state: "hidden"
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
top: parent.top
|
|
||||||
bottom: parent.bottom
|
|
||||||
left: parent.right
|
|
||||||
}
|
|
||||||
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height
|
|
||||||
|
|
||||||
color: Material.background
|
|
||||||
|
|
||||||
function toggle() {
|
|
||||||
if(speedFlowChartBackgroundRect.state === "hidden"){
|
|
||||||
speedFlowChartBackgroundRect.state = "visible"
|
|
||||||
control.positionViewAtBeginning()
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
speedFlowChartBackgroundRect.state = "hidden"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function isVisible() {
|
|
||||||
return speedFlowChartBackgroundRect.state === "visible"
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PullRefresher {
|
PullRefresher {
|
||||||
|
// has to be placed here again,
|
||||||
|
// to be on top of the speed flowchart
|
||||||
target: control
|
target: control
|
||||||
|
|
||||||
postRefreshDelay: 0
|
postRefreshDelay: 0
|
||||||
|
@ -962,4 +295,5 @@ DataListView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ DataListView {
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: selector
|
target: selector
|
||||||
onSelectionFinished: {
|
function onSelectionFinished(index, data) {
|
||||||
if(data.cat !== undefined){
|
if(data.cat !== undefined){
|
||||||
updateData({cat: data.cat}, true)
|
updateData({cat: data.cat}, true)
|
||||||
}
|
}
|
||||||
|
@ -113,9 +113,11 @@ DataListView {
|
||||||
delegate: ItemDelegate {
|
delegate: ItemDelegate {
|
||||||
id: partDel
|
id: partDel
|
||||||
|
|
||||||
|
property int thisIndex: index
|
||||||
property var thisData: widgetData[ "participants" ][index]
|
property var thisData: widgetData[ "participants" ][index]
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
height: 50
|
||||||
|
|
||||||
opacity: 0
|
opacity: 0
|
||||||
scale: 0.9
|
scale: 0.9
|
||||||
|
@ -136,6 +138,16 @@ DataListView {
|
||||||
|
|
||||||
text: ""
|
text: ""
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
width: partDel.width
|
||||||
|
|
||||||
|
color: partDel.thisIndex % 2 == 0 ? "white":"lightgrey"
|
||||||
|
|
||||||
|
opacity: 0.2
|
||||||
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: partDelFirstRow
|
id: partDelFirstRow
|
||||||
|
|
||||||
|
@ -145,7 +157,7 @@ DataListView {
|
||||||
rightMargin: parent.width * 0.05
|
rightMargin: parent.width * 0.05
|
||||||
}
|
}
|
||||||
|
|
||||||
spacing: width * 0.1
|
spacing: width * 0.05
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
height: parent.height
|
height: parent.height
|
||||||
|
@ -153,7 +165,7 @@ DataListView {
|
||||||
|
|
||||||
fontSizeMode: Text.Fit
|
fontSizeMode: Text.Fit
|
||||||
font.bold: true
|
font.bold: true
|
||||||
font.pixelSize: Math.abs( height * 0.6 )
|
font.pixelSize: Math.abs( height * 0.4 )
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
|
||||||
|
@ -162,7 +174,7 @@ DataListView {
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
height: parent.height
|
height: parent.height
|
||||||
width: parent.width * 0.4
|
width: parent.width * 0.45
|
||||||
|
|
||||||
fontSizeMode: Text.Fit
|
fontSizeMode: Text.Fit
|
||||||
font.bold: true
|
font.bold: true
|
||||||
|
@ -178,10 +190,8 @@ DataListView {
|
||||||
height: parent.height
|
height: parent.height
|
||||||
width: parent.width * 0.3
|
width: parent.width * 0.3
|
||||||
|
|
||||||
fontSizeMode: Text.Fit
|
|
||||||
font.bold: false
|
font.bold: false
|
||||||
font.pixelSize: Math.abs( height * 0.4 )
|
font.pixelSize: height * 0.3
|
||||||
minimumPixelSize: height * 0.3
|
|
||||||
|
|
||||||
elide: "ElideRight"
|
elide: "ElideRight"
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import QtQuick 2.9
|
||||||
import QtQuick.Window 2.2
|
import QtQuick.Window 2.2
|
||||||
import QtQuick.Controls 2.4
|
import QtQuick.Controls 2.4
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
|
import QtQuick.Controls.Material 2.12
|
||||||
import QtPurchasing 1.12
|
import QtPurchasing 1.12
|
||||||
|
|
||||||
import com.itsblue.digitalRockRanking 1.0
|
import com.itsblue.digitalRockRanking 1.0
|
||||||
|
@ -39,7 +40,6 @@ Window {
|
||||||
property int errorCode: -1
|
property int errorCode: -1
|
||||||
|
|
||||||
// comp cats source:
|
// comp cats source:
|
||||||
// - https://github.com/ralfbecker/ranking/blob/master/sitemgr/digitalrock/icc_calendar.php
|
|
||||||
// - https://github.com/ralfbecker/ranking/blob/master/sitemgr/digitalrock/dav_calendar.php
|
// - https://github.com/ralfbecker/ranking/blob/master/sitemgr/digitalrock/dav_calendar.php
|
||||||
// - https://github.com/ralfbecker/ranking/blob/master/sitemgr/digitalrock/sac_calendar.php
|
// - https://github.com/ralfbecker/ranking/blob/master/sitemgr/digitalrock/sac_calendar.php
|
||||||
|
|
||||||
|
@ -120,12 +120,15 @@ Window {
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
//Material.theme: Material.Dark
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
//loadingDl.open()
|
//loadingDl.open()
|
||||||
//app.openAthlete(53139) // dorian: 53139 , rustam: 6933 , helen: 53300
|
//app.openAthlete() // dorian: 53139 , rustam: 6933 , helen: 53300
|
||||||
//openWidget({nation:'GER'})
|
//openWidget({nation:'GER'})
|
||||||
//mainStack.push("Pages/AthleteSearchPage.qml")
|
//mainStack.push("Pages/AthleteSearchPage.qml")
|
||||||
//openWidget({comp: 11651, cat: 25})
|
//openWidget({comp: 11651, cat: 26})
|
||||||
|
//openWidget({person: 6623})
|
||||||
}
|
}
|
||||||
|
|
||||||
Shortcut {
|
Shortcut {
|
||||||
|
@ -315,8 +318,10 @@ Window {
|
||||||
height: parent.height
|
height: parent.height
|
||||||
|
|
||||||
onItemChanged: {
|
onItemChanged: {
|
||||||
if(item === null)
|
if(item === null) {
|
||||||
|
extraComponentLoader.Layout.preferredWidth = 0
|
||||||
return
|
return
|
||||||
|
}
|
||||||
|
|
||||||
extraComponentLoader.item.width = extraComponentLoader.item.implicitWidth
|
extraComponentLoader.item.width = extraComponentLoader.item.implicitWidth
|
||||||
extraComponentLoader.Layout.preferredWidth = extraComponentLoader.item.width
|
extraComponentLoader.Layout.preferredWidth = extraComponentLoader.item.width
|
||||||
|
|
|
@ -20,5 +20,10 @@
|
||||||
<file>Components/SpeedFlowChart.qml</file>
|
<file>Components/SpeedFlowChart.qml</file>
|
||||||
<file>Components/SwipeGallery.qml</file>
|
<file>Components/SwipeGallery.qml</file>
|
||||||
<file>Components/CompetitionCalendarDelegate.qml</file>
|
<file>Components/CompetitionCalendarDelegate.qml</file>
|
||||||
|
<file>Components/SelectorPopup.qml</file>
|
||||||
|
<file>Components/ResultDelegate.qml</file>
|
||||||
|
<file>Components/SpeedFlowChartLocker.qml</file>
|
||||||
|
<file>Components/SpeedFlowChartPopup.qml</file>
|
||||||
|
<file>Components/BlueRockBadge.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -33,7 +33,6 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
QGuiApplication app(argc, argv);
|
QGuiApplication app(argc, argv);
|
||||||
|
|
||||||
qDebug() << QStyleFactory::keys();
|
|
||||||
QQuickStyle::setStyle("Material");
|
QQuickStyle::setStyle("Material");
|
||||||
QIcon::setFallbackSearchPaths(QIcon::fallbackSearchPaths() << ":/resources/shared/icons");
|
QIcon::setFallbackSearchPaths(QIcon::fallbackSearchPaths() << ":/resources/shared/icons");
|
||||||
QIcon::setThemeName("bluerock");
|
QIcon::setThemeName("bluerock");
|
||||||
|
@ -42,6 +41,13 @@ int main(int argc, char *argv[])
|
||||||
qmlRegisterType<AppSettings>("com.itsblue.digitalRockRanking", 1, 0, "AppSettings");
|
qmlRegisterType<AppSettings>("com.itsblue.digitalRockRanking", 1, 0, "AppSettings");
|
||||||
|
|
||||||
QQmlApplicationEngine engine;
|
QQmlApplicationEngine engine;
|
||||||
|
|
||||||
|
#ifdef QT_DEBUG
|
||||||
|
engine.rootContext()->setContextProperty("QT_DEBUG", true);
|
||||||
|
#else
|
||||||
|
engine.rootContext()->setContextProperty("QT_DEBUG", false);
|
||||||
|
#endif
|
||||||
|
|
||||||
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
|
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
|
||||||
if (engine.rootObjects().isEmpty())
|
if (engine.rootObjects().isEmpty())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
Loading…
Reference in a new issue