app/resources/qml/Widgets/RankingWidget.qml

387 lines
12 KiB
QML

/*
blueROCK - for digital rock
Copyright (C) 2019 Dorian Zedler
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.9
import QtQuick.Controls 2.4
import "../Components"
DataListView {
id: control
property string title: control.widgetData['comp_name']
property string subTitle: qsTr("(Ranking)") + " after " + control.widgetData['route_name']
property bool titleIsPageTitle: true
property var widgetData: ({})
signal closeAll()
Connections {
target: selector
onSelectionFinished: {
if(data.cat !== undefined){
updateData({cat: data.cat}, true)
}
}
}
onWidgetDataChanged: {
model = widgetData[ "participants" ] === undefined ? 0:widgetData[ "participants" ].length
}
model: widgetData[ "participants" ] === undefined ? 0:widgetData[ "participants" ].length
delegate: ItemDelegate {
id: partDel
property int ind: index
property var thisData: widgetData[ "participants" ][index]
state: "closed"
width: parent.width
height: 70
opacity: 0
scale: 0.9
onThisDataChanged: {
fadeInPa.start()
}
onPressAndHold: {
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 }
}
text: ""
onClicked: {
if(state === "closed"){
// close all other delegates
control.closeAll()
state = "opened"
}
else {
state = "closed"
}
}
Connections {
target: control
onCloseAll: {
partDel.state = "closed"
}
}
Rectangle {
anchors.fill: parent
width: partDel.width
color: partDel.ind % 2 == 0 ? "white":"lightgrey"
opacity: 0.2
}
Column {
id: partDelCol
anchors {
top: parent.top
left: parent.left
right: parent.right
margins: 5
}
height: 70 - 2 * anchors.margins
Row {
id: partDelFirstRow
width: parent.width
height: parent.height - partDelSecondRow.height
Label {
id: resultRankLa
height: parent.height
width: parent.width * 0.1
enabled: text !== ""
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: widgetData[ "participants" ][index]["result_rank"] === undefined ? "":widgetData[ "participants" ][index]["result_rank"]
}
Label {
id: nameLa
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
minimumPixelSize: 1
text: widgetData[ "participants" ][index]["firstname"] + " " + widgetData[ "participants" ][index]["lastname"]
}
Label {
id: fedLa
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
elide: "ElideRight"
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
text: "<html>(<a href=\"" + (widgetData[ "participants" ][index]["fed_url"] === undefined ? "":widgetData[ "participants" ][index]["fed_url"]).toString() + "\">" + (widgetData[ "display_athlete" ] === "nation" ? widgetData[ "participants" ][index]["nation"] : widgetData[ "participants" ][index]["federation"]) + "</a>)</html>"
onLinkActivated: {
Qt.openUrlExternally(link)
}
}
}
Row {
id: partDelSecondRow
width: parent.width
height: pointsLa.enabled ? parent.height / 2:0
Item {
id: spacer
height: parent.height
width: resultRankLa.width
}
Label {
id: pointsLa
width: enabled ? parent.width * 0.25:0
height: enabled ? parent.height:0
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignLeft
fontSizeMode: Text.Fit
font.pixelSize: Math.abs( height * 0.6 )
minimumPixelSize: 1
text: widgetData[ "participants" ][partDel.ind]["points"] === undefined ? "":"points: "+widgetData[ "participants" ][partDel.ind]["points"]
}
}
}
Item {
id: detailResultsItm
anchors {
top: partDelCol.bottom
left: parent.left
right: parent.right
margins: 5
}
height: detailResultsLd.status === Loader.Ready && detailResultsLd.enabled ? ( 20 + detailResultsLd.item.spacing ) * detailResultsLd.item.model:0
Loader {
id: detailResultsLd
property alias partDel: partDel
property alias partDelSecondRow: partDelSecondRow
onEnabledChanged: {
if(enabled){
sourceComponent = detailResultsComp
}
else {
hideDelayPa.start()
}
}
anchors.fill: parent
height: parent.height
PauseAnimation {
id: hideDelayPa
duration: 200
onRunningChanged: {
if(!running && !detailResultsLd.enabled){
detailResultsLd.sourceComponent = undefined
}
}
}
}
}
states: [
State {
name: "closed"
PropertyChanges {
target: partDel
height: 70
}
PropertyChanges {
target: detailResultsLd
enabled: false
}
},
State {
name: "opened"
PropertyChanges {
target: partDel
height: 70 + detailResultsLd.height
}
PropertyChanges {
target: detailResultsLd
enabled: true
}
}
]
transitions: [
Transition {
from: "*"
to: "*"
NumberAnimation {
properties: "height"
duration: 200
}
}
]
}
Component {
id: detailResultsComp
Column {
id: detailResultsCol
property alias model: detailResultRowRep.model
Repeater {
id: detailResultRowRep
property var compResults: getCompResults()
model: compResults.length
function getCompResults() {
var obj = control.widgetData["route_names"]
var resultData = []
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 ) {
resultData.unshift([prop, obj[prop].replace("\n", " - ")])
//console.log("found " + obj[prop] + " at index " + prop)
}
}
return resultData
}
delegate: Row {
height: detailResultsCol.height / detailResultRowRep.model - detailResultsCol.spacing
width: parent.width
visible: height > 0
Item {
id: spacer_
height: parent.height
width: parent.width * 0.15
}
Label {
height: parent.height
width: parent.width / 2
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
minimumPixelSize: 1
text: detailResultRowRep.compResults[index][1]
}
Label {
id: detailResultListLa
height: parent.height
width: parent.width * 0.35
fontSizeMode: Text.Fit
font.pixelSize: Math.abs( partDelSecondRow.height > 0 ? height * 0.6:height * 0.4 )
verticalAlignment: Text.AlignVCenter
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", " ")
}
Behavior on height {
NumberAnimation {
duration: 200
}
}
}
}
}
}
}