diff --git a/CHANGELOG.md b/CHANGELOG.md
index 00b9c7a..f4bf88b 100644
--- a/CHANGELOG.md
+++ b/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/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
-# [0.03.1] - UR
+# [0.05] - UR
### Changed
- the boulder result rect doesn't have a background if there is no result now
- 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
### 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
### 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
### Fixed
diff --git a/blueROCK.pro b/blueROCK.pro
index b5292dd..120941a 100644
--- a/blueROCK.pro
+++ b/blueROCK.pro
@@ -50,9 +50,7 @@ DISTFILES += \
android-sources/gradle/wrapper/gradle-wrapper.properties \
android-sources/gradlew \
android-sources/gradlew.bat \
- android-sources/res/values/libs.xml \
- resources/shared/icons/bluerock/index.theme \
- $$files(resources/shared/icons/*.png, true)
+ android-sources/res/values/libs.xml
android {
QT += androidextras
diff --git a/resources/qml/Components/BlueRockBadge.qml b/resources/qml/Components/BlueRockBadge.qml
new file mode 100644
index 0000000..0fce454
--- /dev/null
+++ b/resources/qml/Components/BlueRockBadge.qml
@@ -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"
+ }
+}
diff --git a/resources/qml/Components/PullRefresher.qml b/resources/qml/Components/PullRefresher.qml
index 1e72f89..9004143 100644
--- a/resources/qml/Components/PullRefresher.qml
+++ b/resources/qml/Components/PullRefresher.qml
@@ -32,10 +32,10 @@ Item {
property int postRefreshDelay: 1000 // delay after reload funcion has finished
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 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 pullIndicatorColor: "black" // color for the pre-defined pull indicator
diff --git a/resources/qml/Components/ResultDelegate.qml b/resources/qml/Components/ResultDelegate.qml
new file mode 100644
index 0000000..4d77a0d
--- /dev/null
+++ b/resources/qml/Components/ResultDelegate.qml
@@ -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: "(" + (widgetData[ "display_athlete" ] === "nation" ? partDel.thisData["nation"] : partDel.thisData["federation"]) + ")"
+
+ 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"]
+ }
+ }
+ }
+ }
diff --git a/resources/qml/Components/SelectorPopup.qml b/resources/qml/Components/SelectorPopup.qml
new file mode 100644
index 0000000..f9dcd4d
--- /dev/null
+++ b/resources/qml/Components/SelectorPopup.qml
@@ -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
+ }
+ }
+}
diff --git a/resources/qml/Components/SpeedFlowChart.qml b/resources/qml/Components/SpeedFlowChart.qml
index 499fd54..520852b 100644
--- a/resources/qml/Components/SpeedFlowChart.qml
+++ b/resources/qml/Components/SpeedFlowChart.qml
@@ -20,32 +20,24 @@ import QtQuick 2.10
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.3
import QtQuick.Controls.Material 2.1
+import QtGraphicalEffects 1.0
-ListView {
+Item {
id: control
property var flowchartData
property var allFlowchartData
property int rounds: 0
- property int tileSize: app.height / 8 * 0.8
property int refreshes: 0
property int roundRefreshes: 1
- anchors.fill: parent
- anchors.margins: 10
-
- spacing: app.width * 0.1
-
- orientation: ListView.LeftToRight
- boundsBehavior: ListView.StopAtBounds
+ property int roundCount: 0
onFlowchartDataChanged: {
prepareData()
}
- model: 0
-
function prepareData() {
if(!control.enabled || control.flowchartData === undefined || control.flowchartData['route_names'] === undefined)
@@ -223,189 +215,273 @@ ListView {
}
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))
}
- delegate: Column {
- id: roundCol
+ ListView {
+ id: roundListView
- property int thisIndex: index
- property int thisRound: thisRoundIsValid ? control.allFlowchartData[roundCol.thisIndex][control.allFlowchartData[roundCol.thisIndex].length-2]:-1
- property bool thisRoundIsValid: control.allFlowchartData !== undefined && control.allFlowchartData[roundCol.thisIndex] !== undefined && control.allFlowchartData[roundCol.thisIndex].length > 2
- property bool thisIsLastRound: thisIndex === control.model - 1
+ property int columnWidth: height * 0.3
+ property int columnHeight: height
- width: app.width * 0.5
- height: control.height
-
- //spacing: app.width * 0.1
-
- 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] : "-"
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ horizontalCenter: parent.horizontalCenter
}
- Repeater {
- id: rectRep
- model: Math.max( Math.pow(2, control.model-1) * Math.pow(0.5, (index)), 2)
- delegate: Item {
- id: matchItm
+ width: Math.min((columnWidth + spacing) * model, control.width)
- 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
- property int thisRound: parseInt(roundCol.thisRound) - (thisIsSmallFinal ? 1:0)
- property var thisMatchData: thisMatchDataIsValid ? matchData:[]
+ model: control.roundCount
- 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
+ delegate: Item {
+ id: roundItem
- property bool thisIsFinal: roundCol.thisIsLastRound && thisIndex === rectRep.model - 2
- property bool thisIsSmallFinal: roundCol.thisIsLastRound && thisIndex === rectRep.model - 1
+ property int thisIndex: index
+ 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 )
- width: parent.width
+ property int tileSize: (roundItem.height / 8 - roundNameLa.height) * 1.45
- onMatchDataChanged: {
- fadeInPa.start()
- }
+ width: roundListView.columnWidth
+ height: roundListView.columnHeight
- 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 }
- }
+ Column {
+ id: roundCol
- Canvas {
- id: lineCanvas
- width: app.width; height: app.height
- contextType: "2d"
+ anchors.fill: parent
- visible: !roundCol.thisIsLastRound
-
- 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
+ Label {
+ id: roundNameLa
width: parent.width
- height: control.tileSize
- //scale: 0.9
- color: "white"
- border.color: "lightgrey"
- border.width: 1
- radius: height * 0.2
- Material.elevation: 10
+ 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: roundItem.thisRoundIsValid
+ && control.allFlowchartData[roundItem.thisIndex][control.allFlowchartData[roundItem.thisIndex].length-1] !== undefined ?
+ control.allFlowchartData[roundItem.thisIndex][control.allFlowchartData[roundItem.thisIndex].length-1] :
+ "-"
+ }
- Grid {
- columns: app.landscape() ? 2:0
- rows: app.landscape() ? 0:2
+ Repeater {
+ id: rectRep
+ 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
- anchors.margins: matchRect.radius * 0.5
+ property var matchData: roundItem.thisRoundIsValid ?
+ control.allFlowchartData[
+ thisIsSmallFinal ?
+ roundItem.thisIndex+1 :
+ roundItem.thisIndex
+ ][ thisIsSmallFinal ? 0:matchItm.thisIndex]:
+ undefined
- Repeater {
- // for the two athletes
- model: 2
+ property int thisIndex: index
+ property int thisRound: parseInt(roundItem.thisRound) - (thisIsSmallFinal ? 1:0)
+ 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
- width: app.landscape() ? parent.width / 2 - parent.spacing : parent.width
+ property bool thisIsFinal: roundItem.thisIsLastRound && thisIndex === rectRep.model - 2
+ 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 {
- Layout.preferredHeight: parent.height
+ height: !roundItem.thisIsLastRound ?
+ (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
- font.pixelSize: height * 0.7
- fontSizeMode: Text.Fit
- minimumPixelSize: 1
+ onMatchDataChanged: {
+ fadeInPa.start()
+ }
- 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 {
- Layout.preferredHeight: parent.height
-
- height: parent.height
-
- 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'] :"-"
+ PathQuad {
+ relativeX: roundListView.spacing * 0.5
+ relativeY: matchItm.height * 0.25 * lineCanvas.targetYFactor
+ relativeControlX: 0
+ relativeControlY: relativeY
}
+ }
- Label {
- Layout.preferredHeight: parent.height
+ onPaint: {
+ 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
- font.pixelSize: app.landscape() ? height * 0.35 : height * 0.5
+ Rectangle {
+ 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 ?
- ( parseFloat(matchItm.thisMatchData[index]['result'+matchItm.thisRound]) ?
- (parseFloat(matchItm.thisMatchData[index]['result'+matchItm.thisRound]).toFixed(2))
- : matchItm.thisMatchData[index]['result'+matchItm.thisRound] )
- : "-"
+ //anchors.verticalCenterOffset: matchItm.lowerPart ? 10:10
+ width: parent.width
+ height: roundItem.tileSize
+ //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
+ }
+ }
}
}
}
diff --git a/resources/qml/Components/SpeedFlowChartLocker.qml b/resources/qml/Components/SpeedFlowChartLocker.qml
new file mode 100644
index 0000000..b72ea2d
--- /dev/null
+++ b/resources/qml/Components/SpeedFlowChartLocker.qml
@@ -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()
+ }
+
+ }
+}
diff --git a/resources/qml/Components/SpeedFlowChartPopup.qml b/resources/qml/Components/SpeedFlowChartPopup.qml
new file mode 100644
index 0000000..fcd8297
--- /dev/null
+++ b/resources/qml/Components/SpeedFlowChartPopup.qml
@@ -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
+ }
+ }
+ ]
+}
diff --git a/resources/qml/Pages/StartPage.qml b/resources/qml/Pages/StartPage.qml
index faa3c70..0d3ce8e 100644
--- a/resources/qml/Pages/StartPage.qml
+++ b/resources/qml/Pages/StartPage.qml
@@ -29,9 +29,8 @@ Page {
signal headerComponentChanged()
- RowLayout {
- id: headerLayout
-
+ BlueRockBadge {
+ id: headerBadge
anchors {
horizontalCenter: parent.horizontalCenter
top: parent.top
@@ -40,28 +39,6 @@ Page {
height: menuGr.buttonSize * 0.3
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 {
@@ -125,7 +102,7 @@ Page {
anchors {
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
- bottomMargin: headerLayout.anchors.topMargin
+ bottomMargin: headerBadge.anchors.topMargin
}
width: parent.width * 0.9
@@ -161,6 +138,10 @@ Page {
contentItem: Label {
wrapMode: Text.Wrap
+
+ width: ifscDisclaimerDialog.width * 0.8
+ height: implicitHeight
+
text:
"Unfortunately, the IFSC has restricted the access to their data and is not willing to share results with blueROCK anymore. " +
"Because of this, blueROCK is no longer able to access and display IFSC results.
" +
diff --git a/resources/qml/Pages/WidgetPage.qml b/resources/qml/Pages/WidgetPage.qml
index 5e56bb9..5f01e5b 100644
--- a/resources/qml/Pages/WidgetPage.qml
+++ b/resources/qml/Pages/WidgetPage.qml
@@ -245,107 +245,16 @@ Page {
}
- Dialog {
+ SelectorPopup {
id: selectorPu
- property var dataObj
- 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 {
+ contentItem: ListView {
id: selectorLv
property int delegateHeight: 50
+ spacing: 10
- anchors.fill: parent
-
- implicitWidth: parent.width
- implicitHeight: root.height * 0.7 < ( (delegateHeight + spacing) * model ) ? root.height * 0.7 : (delegateHeight + spacing) * model + 100
+ implicitHeight: model === 0 ? 0:(delegateHeight + spacing) * model
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
- }
- }
}
-
}
diff --git a/resources/qml/Widgets/CalendarWidget.qml b/resources/qml/Widgets/CalendarWidget.qml
index f569c88..f9785c1 100644
--- a/resources/qml/Widgets/CalendarWidget.qml
+++ b/resources/qml/Widgets/CalendarWidget.qml
@@ -150,7 +150,7 @@ DataListView {
if(endDate.getTime() < new Date().getTime()){
// 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!")
}
}
@@ -400,114 +400,18 @@ DataListView {
delegate: CompetitionCalendarDelegate {
}
- section.property: "month"
- section.delegate: ItemDelegate {
- id: name
- background: Rectangle {
- color: "red"
- }
-
- width: parent.width
- text: section
- }
-
- Dialog {
+ SelectorPopup {
id: filterSelectPu
- property var dataObj
- 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 {
+ contentItem: ListView {
id: selectorLv
property int delegateHeight: 50
+ spacing: 10
- anchors.fill: parent
+ clip: true
- implicitWidth: parent.width
- implicitHeight: root.height * 0.7 < ( (delegateHeight + spacing) * model ) ? root.height * 0.7 : (delegateHeight + spacing) * model + 100
+ implicitHeight: model === 0 ? 0:(delegateHeight + spacing) * model
model: filterSelectPu.dataObj !== undefined ? filterSelectPu.dataObj.length:0
@@ -520,13 +424,12 @@ DataListView {
leftMargin: 3
bottom: selectorLv.bottom
}
-
}
delegate: CheckDelegate {
id: catBt
- width: parent.width
+ width: selectorLv.width
height: text !== "" ? selectorLv.delegateHeight:0
//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
- }
- }
}
}
diff --git a/resources/qml/Widgets/ProfileWidget.qml b/resources/qml/Widgets/ProfileWidget.qml
index fb928b8..83526ea 100644
--- a/resources/qml/Widgets/ProfileWidget.qml
+++ b/resources/qml/Widgets/ProfileWidget.qml
@@ -19,6 +19,7 @@
import QtQuick 2.9
import QtQuick.Controls 2.4
import QtQuick.Controls.Material 2.3
+import QtGraphicalEffects 1.0
import "../Components"
@@ -43,25 +44,11 @@ Page {
id: mainSv
anchors.fill: parent
- anchors.margins: 10
- anchors.rightMargin: 14
+ anchors.margins: 20
- contentWidth: parent.width - anchors.leftMargin - anchors.rightMargin
+ contentWidth: parent.width - anchors.margins * 2
- ScrollBar.vertical: ScrollBar {
-
- anchors {
- top: mainSv.top
- left: mainSv.right
- margins: 10
- leftMargin: 3
- bottom: mainSv.bottom
- }
-
- width: 8
-
- active: true
- }
+ ScrollBar.vertical.policy: ScrollBar.AlwaysOff
Column {
id: mainCol
@@ -72,25 +59,61 @@ Page {
height: control.height * 0.3
width: parent.width
- Image {
- id: photo
-
- property bool ready: false
+ spacing: photoContainerItem.width * 0.1
+ Item {
+ id: photoContainerItem
anchors.verticalCenter: parent.verticalCenter
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")
- asynchronous: true
+ Image {
+ id: photo
+
+ property bool ready: photo.status === Image.Ready
- FancyBusyIndicator {
- height: width
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
height: parent.height * 0.9
- width: parent.width - photo.width
+ width: parent.width - photoContainerItem.width * 1.1
Label {
@@ -214,7 +237,9 @@ Page {
wrapMode: Label.Wrap
- text: widgetData["freetext"] === undefined ? "":widgetData["freetext"]
+ text: widgetData["freetext"] === undefined ?
+ "":
+ (widgetData["freetext"] + "
")
}
@@ -224,7 +249,7 @@ Page {
anchors.horizontalCenter: parent.horizontalCenter
height: 1
- width: parent.width * 0.9
+ width: parent.width
color: "black"
@@ -307,6 +332,7 @@ Page {
width: parent.width
height: 50
+ spacing: 0
opacity: 0
scale: 0.9
@@ -324,11 +350,11 @@ Page {
Label {
id: bestResultRankLa
- width: parent.width * 0.2
+ width: parent.width * 0.1
height: parent.height
verticalAlignment: Text.AlignVCenter
- horizontalAlignment: Text.AlignHCenter
+ horizontalAlignment: Text.AlignLeft
fontSizeMode: Text.Fit
minimumPixelSize: 1
@@ -341,11 +367,11 @@ Page {
Label {
id: bestResultCompLa
- width: parent.width * 0.6
+ width: parent.width * 0.7
height: parent.height
verticalAlignment: Text.AlignVCenter
- horizontalAlignment: Text.AlignHCenter
+ horizontalAlignment: Text.AlignLeft
fontSizeMode: Text.Fit
minimumPixelSize: height * 0.3
@@ -370,7 +396,7 @@ Page {
scale: 0.8
verticalAlignment: Text.AlignVCenter
- horizontalAlignment: Text.AlignHCenter
+ horizontalAlignment: Text.AlignRight
fontSizeMode: Text.Fit
minimumPixelSize: 1
diff --git a/resources/qml/Widgets/RankingWidget.qml b/resources/qml/Widgets/RankingWidget.qml
index 6892306..7a3acd8 100644
--- a/resources/qml/Widgets/RankingWidget.qml
+++ b/resources/qml/Widgets/RankingWidget.qml
@@ -35,7 +35,7 @@ DataListView {
Connections {
target: selector
- onSelectionFinished: {
+ function onSelectionFinished(index, data) {
if(data.cat !== undefined){
updateData({cat: data.cat}, true)
}
@@ -64,12 +64,12 @@ DataListView {
delegate: ItemDelegate {
id: partDel
- property int ind: index
+ property int thisIndex: index
property var thisData: widgetData[ "participants" ][index]
state: "closed"
- width: parent.width
+ width: control.width
height: 70
opacity: 0
@@ -105,7 +105,7 @@ DataListView {
Connections {
target: control
- onCloseAll: {
+ function onCloseAll() {
partDel.state = "closed"
}
}
@@ -115,7 +115,7 @@ DataListView {
width: partDel.width
- color: partDel.ind % 2 == 0 ? "white":"lightgrey"
+ color: partDel.thisIndex % 2 == 0 ? "white":"lightgrey"
opacity: 0.2
}
@@ -221,7 +221,7 @@ DataListView {
font.pixelSize: Math.abs( height * 0.6 )
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) {
// 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", " - ")])
//console.log("found " + obj[prop] + " at index " + prop)
}
@@ -382,7 +382,7 @@ DataListView {
horizontalAlignment: Text.AlignLeft
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 {
diff --git a/resources/qml/Widgets/RegistrationWidget.qml b/resources/qml/Widgets/RegistrationWidget.qml
index 4ca9569..106d27e 100644
--- a/resources/qml/Widgets/RegistrationWidget.qml
+++ b/resources/qml/Widgets/RegistrationWidget.qml
@@ -31,13 +31,13 @@ DataListView {
property bool titleIsPageTitle: true
property Component headerComponent: ToolButton {
- id: moreToolBt
+ id: moreToolBt
- onClicked: {
- control.changeCat()
- }
+ onClicked: {
+ control.changeCat()
+ }
- icon.name: "menu"
+ icon.name: "menu"
}
property var widgetData: currentWidgetData
@@ -111,7 +111,7 @@ DataListView {
Connections {
target: selector
- onSelectionFinished: {
+ function onSelectionFinished(index, data) {
if(data.cat !== undefined){
updateData({cat: data.cat}, true)
}
@@ -140,10 +140,11 @@ DataListView {
delegate: ItemDelegate {
id: partDel
+ property int thisIndex: index
property var thisData: widgetData[ "athletes" ][index]
width: parent.width
- height: parseInt(thisData.cat) === parseInt(params.cat) ? undefined:0
+ height: parseInt(thisData.cat) === parseInt(params.cat) ? 50:0
opacity: 0
scale: 0.9
@@ -164,16 +165,24 @@ DataListView {
text: ""
+ Rectangle {
+ anchors.fill: parent
+
+ width: partDel.width
+
+ color: partDel.thisIndex % 2 == 0 ? "white":"lightgrey"
+
+ opacity: 0.2
+ }
+
Label {
anchors.fill: parent
anchors.leftMargin: parent.width * 0.05
verticalAlignment: Text.AlignVCenter
- fontSizeMode: Text.Fit
font.bold: true
- font.pixelSize: Math.abs( height * 0.35 )
- minimumPixelSize: height * 0.3
+ font.pixelSize: Math.abs( height * 0.3 )
elide: "ElideRight"
diff --git a/resources/qml/Widgets/ResultWidget.qml b/resources/qml/Widgets/ResultWidget.qml
index 01101b6..b44c2f4 100644
--- a/resources/qml/Widgets/ResultWidget.qml
+++ b/resources/qml/Widgets/ResultWidget.qml
@@ -21,9 +21,7 @@ import QtQuick.Controls 2.4
import QtQuick.Layouts 1.3
import QtGraphicalEffects 1.0
import QtQuick.Controls.Material 2.3
- //import QtLocation 5.13
-
- import QtPurchasing 1.12
+import QtPurchasing 1.12
import "../Components"
@@ -46,9 +44,7 @@ DataListView {
ToolButton {
id: moreToolBt
- onClicked: {
- control.changeCat()
- }
+ onClicked: control.changeCat()
icon.name: "menu"
}
@@ -56,11 +52,15 @@ DataListView {
ToolButton {
id: flowToolBt
- visible: speedFlowChart.enabled
+ visible: speedFlowChartPopup.enabled
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"
}
}
@@ -94,21 +94,21 @@ DataListView {
console.log("widget data changed")
if(control.widgetData['discipline'] === 'speed' && control.widgetData['route_order'] === "-1" && Object.keys(control.widgetData['route_names']).length > 2){
- speedFlowChart.flowchartData = ({})
- speedFlowChart.enabled = true
- speedFlowChart.flowchartData = control.widgetData
+ speedFlowChartPopup.flowchartData = ({})
+ speedFlowChartPopup.flowchartData = control.widgetData
+ speedFlowChartPopup.enabled = true
}
else {
- speedFlowChart.enabled = false
- speedFlowChart.flowchartData = ({})
+ speedFlowChartPopup.flowchartData = ({})
+ speedFlowChartPopup.enabled = false
}
}
function onBackRequested() {
- if(!speedFlowChartBackgroundRect.isVisible())
+ if(!speedFlowChartPopup.isVisible())
return true
- speedFlowChartBackgroundRect.toggle()
+ speedFlowChartPopup.toggle()
return false
}
@@ -168,484 +168,13 @@ DataListView {
}
onContentYChanged: {
- if(contentY > 0 && speedFlowChartBackgroundRect.state === "visible"){
+ if(contentY > 0 && speedFlowChartPopup.state === "visible"){
control.positionViewAtBeginning()
}
}
- delegate: ItemDelegate {
- id: partDel
-
- 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: "(" + (widgetData[ "display_athlete" ] === "nation" ? partDel.thisData["nation"] : partDel.thisData["federation"]) + ")"
-
- 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"]
- }
- }
- }
+ delegate: ResultDelegate {
+ enabled: speedFlowChartPopup.state === "hidden"
}
footer: ItemDelegate {
@@ -667,7 +196,7 @@ DataListView {
property var tabs: getTabs()
property var tabIndexes: []
- enabled: speedFlowChartBackgroundRect.state === "hidden"
+ enabled: speedFlowChartPopup.state === "hidden"
anchors {
left: parent.left
@@ -747,209 +276,13 @@ DataListView {
}
- Rectangle {
- id: speedFlowChartBackgroundRect
-
- 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
- }
- }
- ]
+ SpeedFlowChartPopup {
+ id: speedFlowChartPopup
}
PullRefresher {
+ // has to be placed here again,
+ // to be on top of the speed flowchart
target: control
postRefreshDelay: 0
@@ -962,4 +295,5 @@ DataListView {
}
}
+
}
diff --git a/resources/qml/Widgets/StartlistWidget.qml b/resources/qml/Widgets/StartlistWidget.qml
index 4f9b6b8..90959d1 100644
--- a/resources/qml/Widgets/StartlistWidget.qml
+++ b/resources/qml/Widgets/StartlistWidget.qml
@@ -82,7 +82,7 @@ DataListView {
Connections {
target: selector
- onSelectionFinished: {
+ function onSelectionFinished(index, data) {
if(data.cat !== undefined){
updateData({cat: data.cat}, true)
}
@@ -113,9 +113,11 @@ DataListView {
delegate: ItemDelegate {
id: partDel
+ property int thisIndex: index
property var thisData: widgetData[ "participants" ][index]
width: parent.width
+ height: 50
opacity: 0
scale: 0.9
@@ -136,6 +138,16 @@ DataListView {
text: ""
+ Rectangle {
+ anchors.fill: parent
+
+ width: partDel.width
+
+ color: partDel.thisIndex % 2 == 0 ? "white":"lightgrey"
+
+ opacity: 0.2
+ }
+
Row {
id: partDelFirstRow
@@ -145,7 +157,7 @@ DataListView {
rightMargin: parent.width * 0.05
}
- spacing: width * 0.1
+ spacing: width * 0.05
Label {
height: parent.height
@@ -153,7 +165,7 @@ DataListView {
fontSizeMode: Text.Fit
font.bold: true
- font.pixelSize: Math.abs( height * 0.6 )
+ font.pixelSize: Math.abs( height * 0.4 )
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
@@ -162,7 +174,7 @@ DataListView {
Label {
height: parent.height
- width: parent.width * 0.4
+ width: parent.width * 0.45
fontSizeMode: Text.Fit
font.bold: true
@@ -178,10 +190,8 @@ DataListView {
height: parent.height
width: parent.width * 0.3
- fontSizeMode: Text.Fit
font.bold: false
- font.pixelSize: Math.abs( height * 0.4 )
- minimumPixelSize: height * 0.3
+ font.pixelSize: height * 0.3
elide: "ElideRight"
diff --git a/resources/qml/main.qml b/resources/qml/main.qml
index 488d0e2..e0f650f 100644
--- a/resources/qml/main.qml
+++ b/resources/qml/main.qml
@@ -20,6 +20,7 @@ import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.3
+import QtQuick.Controls.Material 2.12
import QtPurchasing 1.12
import com.itsblue.digitalRockRanking 1.0
@@ -39,7 +40,6 @@ Window {
property int errorCode: -1
// 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/sac_calendar.php
@@ -120,12 +120,15 @@ Window {
anchors.fill: parent
+ //Material.theme: Material.Dark
+
Component.onCompleted: {
//loadingDl.open()
- //app.openAthlete(53139) // dorian: 53139 , rustam: 6933 , helen: 53300
+ //app.openAthlete() // dorian: 53139 , rustam: 6933 , helen: 53300
//openWidget({nation:'GER'})
//mainStack.push("Pages/AthleteSearchPage.qml")
- //openWidget({comp: 11651, cat: 25})
+ //openWidget({comp: 11651, cat: 26})
+ //openWidget({person: 6623})
}
Shortcut {
@@ -315,8 +318,10 @@ Window {
height: parent.height
onItemChanged: {
- if(item === null)
+ if(item === null) {
+ extraComponentLoader.Layout.preferredWidth = 0
return
+ }
extraComponentLoader.item.width = extraComponentLoader.item.implicitWidth
extraComponentLoader.Layout.preferredWidth = extraComponentLoader.item.width
diff --git a/resources/qml/qml.qrc b/resources/qml/qml.qrc
index e19b2bf..2305758 100644
--- a/resources/qml/qml.qrc
+++ b/resources/qml/qml.qrc
@@ -20,5 +20,10 @@
Components/SpeedFlowChart.qml
Components/SwipeGallery.qml
Components/CompetitionCalendarDelegate.qml
+ Components/SelectorPopup.qml
+ Components/ResultDelegate.qml
+ Components/SpeedFlowChartLocker.qml
+ Components/SpeedFlowChartPopup.qml
+ Components/BlueRockBadge.qml
diff --git a/sources/main.cpp b/sources/main.cpp
index df5e095..193c314 100644
--- a/sources/main.cpp
+++ b/sources/main.cpp
@@ -33,7 +33,6 @@ int main(int argc, char *argv[])
QGuiApplication app(argc, argv);
- qDebug() << QStyleFactory::keys();
QQuickStyle::setStyle("Material");
QIcon::setFallbackSearchPaths(QIcon::fallbackSearchPaths() << ":/resources/shared/icons");
QIcon::setThemeName("bluerock");
@@ -42,6 +41,13 @@ int main(int argc, char *argv[])
qmlRegisterType("com.itsblue.digitalRockRanking", 1, 0, "AppSettings");
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")));
if (engine.rootObjects().isEmpty())
return -1;