solitare/qml/ScoreBar.qml

176 lines
5.5 KiB
QML

import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Solitare
Rectangle {
id: scoreBarRoot
property int score: 0
property int time: 0
property int moves: 0
color: "lightgray"
RoundButton {
onClicked: GameState.dealCards()
anchors.left: parent.left
anchors.leftMargin: parent.width * 0.02
anchors.verticalCenter: parent.verticalCenter
height: parent.height * 0.5
width: parent.width * 0.05
radius: Math.min(width, height) * 0.2
Image {
source: "qrc:/img/cards.svg"
width: parent.width * 0.7
height: parent.height * 0.7
anchors.centerIn: parent
anchors.margins: Math.min(width, height) * 0.06
// This makes sure the SVG scales properly, otherwise it would
// attempt to scale the image from the original source size, which
// can end up being blurry.
sourceSize: Qt.size(width, height)
fillMode: Image.PreserveAspectFit
}
}
Item {
id: firstRow
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: parent.height * 0.1
anchors.leftMargin: parent.width * 0.02
anchors.rightMargin: parent.width * 0.02
height: parent.height * 0.5
Row {
anchors.top: parent.top
height: parent.height
anchors.horizontalCenter: parent.horizontalCenter
spacing: parent.width * 0.05
ScoreItem {
title: "SCORE"
value: scoreBarRoot.score
height: parent.height
}
ScoreItem {
/**
* Formats a given time in seconds as a string in the format HH:MM:SS.
* If hours is 0, it will instead format as HH:SS.
*
* @param {number} seconds - The time in seconds to be formatted.
* @returns {string} The formatted time string.
*/
function formatTime(seconds) {
var hours = Math.floor(seconds / 3600);
var minutes = Math.floor((seconds % 3600) / 60);
var remainingSeconds = seconds % 60;
// Format with leading zeros
var formattedTime = "";
if (hours > 0)
formattedTime = (hours < 10 ? "0" : "") + hours + ":";
formattedTime += (minutes < 10 ? "0" : "") + minutes + ":" + (remainingSeconds < 10 ? "0" : "") + remainingSeconds;
return formattedTime;
}
title: "TIME"
value: formatTime(scoreBarRoot.time)
height: parent.height
}
ScoreItem {
title: "MOVES"
value: scoreBarRoot.moves
height: parent.height
}
}
}
Item {
id: statusRow
anchors.top: firstRow.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: parent.height * 0.1
anchors.bottomMargin: parent.height * 0.1
anchors.leftMargin: parent.width * 0.02
anchors.rightMargin: parent.height * 0.02
height: parent.height * 0.2
ScoreItem {
visible: GameState.isWinnable.winnable === false
title: "GAME LOST"
titleColor: "red"
anchors.fill: parent
}
ScoreItem {
visible: GameState.preliminaryWin === true && GameState.gameWon === false
title: "PRE-WON"
titleColor: "green"
anchors.fill: parent
}
ScoreItem {
visible: GameState.gameWon === true
title: "GAME WON"
titleColor: "green"
anchors.fill: parent
}
ScoreItem {
visible: GameState.gameWon === false && GameState.preliminaryWin === false && GameState.isWinnable.winnable === undefined
title: "PLAYING"
anchors.fill: parent
}
ScoreItem {
visible: GameState.gameWon === false && GameState.preliminaryWin === false && GameState.isWinnable.winnable === true
title: "WINNABLE IN " + GameState.isWinnable.depth
titleColor: "blue"
anchors.fill: parent
}
}
component ScoreItem: Column {
required property string title
property string value
property color titleColor
property color valueColor
property real fontHeight: height * 0.95 // Use 95% of the height for the font pixel size
property int titleFontSize: Math.round(value ? fontHeight * 0.3 : fontHeight) // 30% of the height, or full height if no value
property int valueFontSize: Math.round(fontHeight - titleFontSize) // Remaining height
spacing: height * 0.05 // Remaining 5% of the height for spacing between the title & value
Text {
text: parent.title
color: parent.titleColor
font.pixelSize: parent.titleFontSize
font.bold: true
horizontalAlignment: Text.AlignHCenter
anchors.horizontalCenter: parent.horizontalCenter
}
Text {
visible: parent.value
text: parent.value
color: parent.valueColor
font.pixelSize: parent.valueFontSize
horizontalAlignment: Text.AlignHCenter
anchors.horizontalCenter: parent.horizontalCenter
}
}
}