solitare/Main.qml

130 lines
4.3 KiB
QML
Raw Normal View History

2024-11-30 18:23:45 +00:00
import QtQuick
2024-11-30 19:56:20 +00:00
import QtQuick.Controls
import QtQuick.Layouts
2024-11-30 18:23:45 +00:00
2024-11-30 19:56:20 +00:00
ApplicationWindow {
2024-12-02 18:00:15 +00:00
width: 750
height: 650
2024-11-30 18:23:45 +00:00
visible: true
2024-12-02 18:00:15 +00:00
title: qsTr("Solitare")
2024-12-03 19:19:13 +00:00
color: "green"
2024-11-30 19:56:20 +00:00
ScoreBar {
id: scoreBar
height: 50
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
2024-11-30 19:56:20 +00:00
}
2024-12-01 00:01:37 +00:00
// Show the foundation piles, throwaway pile & the draw stack on the first row
Item {
2024-12-02 18:00:15 +00:00
id: firstRow
height: 120
anchors.top: scoreBar.bottom
anchors.left: parent.left
anchors.right: parent.right
Item {
anchors.fill: parent
anchors.margins: 10
// Left row (with the foundation piles)
Row {
spacing: 15
anchors.left: parent.left
Repeater {
model: 4 // Each of the 4 suits
CardModel {
required property int index; // passed from repeater
2024-12-03 14:32:30 +00:00
card: GameState.foundation[index].length > 0 ? GameState.foundation[index][0] : null
isFaceDown: false
}
}
}
// Spacer to push the second row to the right
Item {
Layout.fillWidth: true
}
// Right row (with throwaway and draw piles)
Row {
spacing: 20
anchors.right: parent.right
// Throwaway pile (last 3 cards visible with overlap)
Row {
// This allows makes the cards overlap
spacing: -60
Repeater {
2024-12-03 14:32:30 +00:00
model: Math.min(GameState.throwawayPile.length, 3)
delegate: CardModel {
required property int index // passed from repeater
2024-12-03 23:05:29 +00:00
property int reversedIndex: Math.min(GameState.throwawayPile.length, 3) - 1 - index;
card: GameState.throwawayPile[GameState.throwawayPile.length - 1 - reversedIndex]
isFaceDown: false
2024-12-03 23:05:29 +00:00
onClicked: {
// Only auto-move the last card in the throwaway pile
// cards below it are shown, but shouldn't have a click effect
if (reversedIndex == 0) {
GameState.autoMoveThrownCard()
}
}
}
}
}
// Draw pile (only the top card is shown)
CardModel {
2024-12-03 14:32:30 +00:00
card: GameState.drawPile.length > 0 ? GameState.drawPile[GameState.drawPile.length - 1] : null
isFaceDown: true
2024-12-03 23:05:29 +00:00
onClicked: {
GameState.drawNextCard()
}
}
}
}
2024-12-01 00:01:37 +00:00
}
2024-12-02 18:00:15 +00:00
// Second row, with the individual columns
Row {
spacing: 10
anchors.top: firstRow.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 50
Repeater {
2024-12-03 14:32:30 +00:00
model: GameState.columns.length
2024-12-04 18:08:02 +00:00
2024-12-02 18:00:15 +00:00
delegate: Column {
required property int index // passed from repeater
spacing: -80 // Overlap
Repeater {
2024-12-04 18:08:02 +00:00
model: GameState.columns[parent.index].length > 0
? GameState.columns[parent.index].length
: 1 // Render an empty slot for an empty column
2024-12-02 18:00:15 +00:00
delegate: CardModel {
required property int index
2024-12-04 18:08:02 +00:00
property ColumnSlot col: GameState.columns[parent.index].length > 0
? GameState.columns[parent.index][index]
: null // empty column (single empty slot)
2024-12-04 18:08:02 +00:00
card: col ? col.card : null
isFaceDown: col ? !col.revealed : false
2024-12-03 23:05:29 +00:00
onClicked: {
2024-12-04 18:08:02 +00:00
if (col && col.revealed) {
2024-12-03 23:05:29 +00:00
GameState.autoMoveColumnCard(parent.index, index)
}
}
2024-12-02 18:00:15 +00:00
}
}
}
}
}
2024-11-30 18:23:45 +00:00
}