import QtQuick import QtQuick.Controls import QtQuick.Layouts import Solitare ApplicationWindow { id: app width: 750 height: 850 visible: true title: qsTr("Solitare") color: "#019934" // Card dimensions calculation: // // Horizontal space // ================ // The tableau columns take up at most 7*(w*1.125) = 7.875 widths. // // The first row: // * foundation piles: 4*w*1.2 = 4.8 widths. // * throwaway pile: 3*(w-w*0.75)+w = 1.75 widths. // * draw pile: 1 width // * spacing between throwaway & draw pile: 0.25 widths. // * spacing between foundations & throwaway pile: 0.25 widths // // Totalling at: 8.05 card widths. // // Vertical space // ============== // * The score bar takes up min(8% app height, 50). // * The first row takes up 1.35 card heights. // * Margin between first row & tableau: 0.5 card heights. // * The tableau height depends on the max amount of cards that can be in a single column. // Generally, the column will take up: ((maxCards - 1) * (h-h*0.8))+h = h(0.2 * maxCards + 0.8). // // A good base assumption is 14 cards, though the cards should dynamically rescale // if this amount is surpassed, which is very possible. // // Totalling at: (0.2 * maxCards + 2.65) card heights, filling up 100% - min(8%, 50) of screen height. // // // Aspect Ratio // ============ // Finally, we need to make sure that the card proportions are preserved, // with the height being 1.4x the width. property int maxCardsPerColumn: Math.max(GameState.columns.reduce((max, col) => Math.max(max, col.length), 0), 14) property real cardHeight: Math.min((app.height - Math.min(app.height * 0.08, 50)) / (maxCardsPerColumn * 0.2 + 2.65), (app.width / 8.05) * 1.4) property real cardWidth: cardHeight / 1.4 Timer { id: gameTimer interval: 1000 running: GameState.gameWon === false repeat: true onTriggered: scoreBar.time += 1 } ScoreBar { id: scoreBar moves: GameState.moveAmount score: GameState.score time: 0 height: Math.max(parent.height * 0.08, 50) anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right onRestart: time = 0 } // Show the foundation piles, throwaway pile & the draw stack on the first row Rectangle { id: firstRow height: app.cardHeight * 1.35 anchors.top: scoreBar.bottom anchors.left: parent.left anchors.right: parent.right color: "green" Item { anchors.fill: parent anchors.leftMargin: app.cardWidth * 0.125 anchors.rightMargin: app.cardWidth * 0.125 anchors.topMargin: app.cardHeight * 0.2 anchors.bottomMargin: app.cardHeight * 0.2 // Left side FoundationPiles { anchors.left: parent.left cardWidth: app.cardWidth cardHeight: app.cardHeight } // Right side Row { spacing: app.cardWidth * 0.25 anchors.right: parent.right ThrowawayPile { cardWidth: app.cardWidth cardHeight: app.cardHeight } DrawPile { cardWidth: app.cardWidth cardHeight: app.cardHeight } } } } Tableau { anchors.top: firstRow.bottom anchors.horizontalCenter: parent.horizontalCenter anchors.topMargin: app.cardHeight * 0.5 cardWidth: app.cardWidth cardHeight: app.cardHeight } WinOverlay { onRestart: { scoreBar.time = 0 } } }