347 lines
14 KiB
QML
347 lines
14 KiB
QML
/*
|
|
blueROCK - for digital rock
|
|
Copyright (C) 2019 Dorian Zedler
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
import QtQuick 2.10
|
|
import QtQuick.Controls 2.4
|
|
import QtQuick.Layouts 1.3
|
|
import QtQuick.Controls.Material 2.1
|
|
import QtGraphicalEffects 1.0
|
|
|
|
import "SpeedFlowChart.js" as SpeedFlowChart
|
|
|
|
Item {
|
|
id: control
|
|
|
|
property var flowchartData
|
|
property var allFlowchartData
|
|
property int rounds: 0
|
|
|
|
property int refreshes: 0
|
|
property int roundRefreshes: 1
|
|
|
|
onFlowchartDataChanged: {
|
|
prepareData()
|
|
}
|
|
|
|
function prepareData() {
|
|
|
|
if(!control.enabled || control.flowchartData === undefined || control.flowchartData['route_names'] === undefined)
|
|
return
|
|
|
|
var flowchartResult = SpeedFlowChart.convertResultsToSpeedFlowchartResult(control.flowchartData)
|
|
const l = flowchartResult.rounds.length;
|
|
const dummy = { dummy: true };
|
|
flowchartResult.rounds[l - 2].pairs = [
|
|
dummy,
|
|
...flowchartResult.rounds[l - 1].pairs,
|
|
...flowchartResult.rounds[l - 2].pairs,
|
|
];
|
|
flowchartResult.rounds[l - 2].roundName = `${
|
|
flowchartResult.rounds[l - 1].roundName
|
|
} / ${flowchartResult.rounds[l - 2].roundName}`;
|
|
flowchartResult.rounds.pop();
|
|
control.allFlowchartData = flowchartResult
|
|
}
|
|
|
|
ListView {
|
|
id: roundListView
|
|
|
|
property int columnWidth: height * 0.4
|
|
property int columnHeight: height
|
|
|
|
anchors {
|
|
top: parent.top
|
|
bottom: parent.bottom
|
|
horizontalCenter: parent.horizontalCenter
|
|
}
|
|
|
|
width: Math.min((columnWidth + spacing) * model, control.width)
|
|
|
|
spacing: app.height * 0.05
|
|
|
|
orientation: ListView.LeftToRight
|
|
boundsBehavior: ListView.StopAtBounds
|
|
|
|
model: control.allFlowchartData.rounds.length
|
|
|
|
delegate: Item {
|
|
id: roundItem
|
|
|
|
property int thisIndex: index
|
|
property var thisData: control.allFlowchartData.rounds[thisIndex]
|
|
|
|
property bool thisRoundIsValid: true
|
|
|
|
property bool thisIsLastRound: thisIndex === roundListView.model - 1
|
|
property bool thisIsSemiFinal: thisIndex === roundListView.model - 2
|
|
|
|
property int tileSize: (roundItem.height / 8 - roundNameLa.height) * 1.45
|
|
|
|
width: roundListView.columnWidth
|
|
height: roundListView.columnHeight
|
|
|
|
Column {
|
|
id: roundCol
|
|
|
|
anchors.fill: parent
|
|
|
|
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: roundItem.thisData.roundName ?
|
|
roundItem.thisData.roundName :
|
|
"-"
|
|
}
|
|
|
|
Repeater {
|
|
id: rectRep
|
|
model: roundItem.thisData.pairs.length
|
|
|
|
delegate: Item {
|
|
id: matchItm
|
|
|
|
property bool lowerPart: (index%2 > 0)
|
|
property var thisData: roundItem.thisData.pairs[index]
|
|
property int thisIndex: index
|
|
|
|
height: (roundItem.height - roundNameLa.height) / rectRep.model - roundCol.spacing
|
|
width: roundItem.width
|
|
|
|
onThisDataChanged: {
|
|
fadeInPa.start()
|
|
}
|
|
|
|
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 }
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
PathQuad {
|
|
relativeX: roundListView.spacing * 0.5
|
|
relativeY: matchItm.height * 0.25 * lineCanvas.targetYFactor
|
|
relativeControlX: 0
|
|
relativeControlY: relativeY
|
|
}
|
|
}
|
|
|
|
onPaint: {
|
|
context.strokeStyle = "lightgrey"
|
|
context.lineWidth = matchRect.height * 0.05
|
|
context.path = firstPartPath;
|
|
context.stroke();
|
|
}
|
|
}
|
|
|
|
RectangularGlow {
|
|
id: effect
|
|
visible: matchRect.visible
|
|
anchors.fill: matchRect
|
|
glowRadius: 0
|
|
spread: 0
|
|
opacity: 0.3
|
|
color: "black"
|
|
cornerRadius: matchRect.radius
|
|
}
|
|
|
|
Rectangle {
|
|
id: matchRect
|
|
|
|
anchors {
|
|
centerIn: !matchItm.thisIsFinal ? parent:undefined
|
|
bottom: matchItm.thisIsFinal ? parent.bottom:undefined
|
|
}
|
|
|
|
visible: !matchItm.thisData.dummy
|
|
|
|
width: parent.width
|
|
height: roundItem.tileSize
|
|
|
|
color: Material.dialogColor
|
|
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 {
|
|
id: laneRow
|
|
|
|
property var thisData: index === 0 ? matchItm.thisData.laneA : matchItm.thisData.laneB
|
|
property var participant: thisData ? thisData.participant : undefined
|
|
property var result: thisData ? thisData.result : undefined
|
|
property var lane: index === 0 ? "A":"B"
|
|
property bool isWinner: matchItm.thisData.winner === laneRow.lane
|
|
|
|
height: parent.height / 2 - parent.spacing
|
|
width: parent.width
|
|
|
|
spacing: height * 0.1
|
|
|
|
Label {
|
|
Layout.preferredHeight: parent.height
|
|
Layout.preferredWidth: parent.width * 0.08
|
|
|
|
height: parent.height
|
|
|
|
verticalAlignment: Text.AlignVCenter
|
|
horizontalAlignment: Text.AlignLeft
|
|
font.pixelSize: height * 0.4
|
|
font.bold: true
|
|
opacity: 0.7
|
|
|
|
text: laneRow.participant ?
|
|
(
|
|
laneRow.participant.results[0].rank < 10 ?
|
|
laneRow.participant.results[0].rank + " ":
|
|
laneRow.participant.results[0].rank
|
|
):
|
|
""
|
|
}
|
|
|
|
Label {
|
|
Layout.preferredHeight: parent.height
|
|
Layout.maximumWidth: parent.width * 0.6
|
|
|
|
|
|
height: parent.height
|
|
|
|
verticalAlignment: Text.AlignVCenter
|
|
horizontalAlignment: Text.AlignLeft
|
|
font.pixelSize: height * 0.5
|
|
font.bold: laneRow.isWinner
|
|
elide: "ElideRight"
|
|
|
|
color: laneRow.isWinner ? Material.color(Material.Green):Material.primaryTextColor
|
|
|
|
text: laneRow.participant ? laneRow.participant.firstName + " " + laneRow.participant.lastName :"-"
|
|
}
|
|
|
|
Rectangle {
|
|
Layout.preferredHeight: parent.height * 0.8
|
|
Layout.preferredWidth: parent.width * 0.13
|
|
|
|
visible: laneRow.participant && laneRow.participant.startNumber ? true:false
|
|
radius: height / 2
|
|
|
|
border.width: parent.height * 0.03
|
|
border.color: Material.frameColor
|
|
color: "transparent"
|
|
|
|
Label {
|
|
anchors.fill: parent
|
|
|
|
padding: parent.parent.height * 0.1
|
|
leftPadding: padding * 2
|
|
rightPadding: leftPadding
|
|
|
|
font.pixelSize: parent.height * 0.5
|
|
font.bold: true
|
|
verticalAlignment: Text.AlignVCenter
|
|
horizontalAlignment: Text.AlignHCenter
|
|
|
|
|
|
text: laneRow.participant ? laneRow.participant.startNumber:""
|
|
}
|
|
}
|
|
|
|
Item {
|
|
Layout.fillHeight: true
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
Label {
|
|
Layout.preferredHeight: parent.height
|
|
Layout.preferredWidth: parent.width * 0.15
|
|
|
|
height: parent.height
|
|
|
|
verticalAlignment: Text.AlignVCenter
|
|
horizontalAlignment: Text.AlignRight
|
|
font.pixelSize: height * 0.5
|
|
font.bold: laneRow.isWinner
|
|
|
|
color: laneRow.isWinner ? Material.color(Material.Green):Material.primaryTextColor
|
|
|
|
text: laneRow.result ? laneRow.result.result : ""
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
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 * 0.8
|
|
height: width * 0.25
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|