C
Qt Quick Ultralite chess Example
/****************************************************************************** ** ** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Quick Ultralite module. ** ** $QT_BEGIN_LICENSE:COMM$ ** ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see http://www.qt.io/terms-conditions. For further ** information use the contact form at http://www.qt.io/contact-us. ** ** $QT_END_LICENSE$ ** ******************************************************************************/import QtQuick 2.15 Rectangle { color: "#ffcccccc"; readonly property int squareSize: Math.min(width, height) / 8; property int hoverCol; property int hoverRow; // The chess board: simply 64 squares of different colors Repeater { model: 64 Rectangle { property int row: Math.floor(index/8); property int col: index % 8; z: 0; x: col * squareSize y: (7 - row) * squareSize height: squareSize width: squareSize color: { var even = ((row + col) % 2) == 0; if (!ChessModel.canDrop(col, row)) return even ? "#d18b47" : "#ffce9e"; if (row == hoverRow && col == hoverCol) return even ? "#d18bff" : "#ffceff"; return even ? "#ff8b47" : "#ffaa88"; } } } // The chess pieces: There are 32 chess pieces, the first 16 are white, and the // last 16 are black. Repeater { model: 32 Item { id: pieceText; visible: ChessModel.col(modelData) >= 0; x: squareSize * ChessModel.col(modelData); y: squareSize * (7 - ChessModel.row(modelData)); // Note: with QUL, the item in a repeater might not get the same order relative to // the item, so we use the z order to ensure that pieces are on top z: 1 height: squareSize width: squareSize Text { color: index < 16 ? "#eee" : "#444" text: { var p = index % 16; switch (p) { case 0: return "♚"; case 1: return "♛"; case 2: case 3: return "♜"; case 4: case 5: return "♝"; case 6: case 7: return "♞"; } return "♟"; } x: (pieceTouch.pressed ? pieceTouch.mouseX - pieceTouch.pressedX : 0); y: (pieceTouch.pressed ? pieceTouch.mouseY - pieceTouch.pressedY : 0); height: squareSize width: squareSize horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter } MouseArea { id: pieceTouch; anchors.fill: pieceText; property real pressedX: 0 property real pressedY: 0 onPressed: { pressedX = mouse.x pressedY = mouse.y } onPressedChanged: { if (pressed) { ChessModel.setActivePiece(modelData); } else { ChessModel.release(modelData, hoverCol, hoverRow); ChessModel.setActivePiece(-1); } } onMouseXChanged: hoverCol = (pieceText.x + pieceTouch.mouseX - pieceTouch.pressedX + squareSize / 2) / squareSize; onMouseYChanged: hoverRow = 7 - (pieceText.y + pieceTouch.mouseY - pieceTouch.pressedY - squareSize / 3) / squareSize; } } } // Some indicator to show whose turn it is Rectangle { color: ChessModel.whiteTurn ? "#eee" : "#444" width: squareSize; height: width / 2; anchors.top: parent.width > parent.height ? parent.top : parent.bottom anchors.topMargin: parent.width > parent.height ? 0 : -height anchors.right: parent.width > parent.height ? parent.right : parent.left anchors.rightMargin: parent.width > parent.height ? 0 : -width } Text { id: moveTime anchors.bottom: parent.bottom anchors.right: parent.right text: ChessModel.secondsSinceMove visible: ChessModel.secondsSinceMove >= 0 } Text { id: invalidLabel anchors.bottom: moveTime.top anchors.right: parent.right text: "Invalid Move!" visible: false } ChessModel.onInvalidMove: invalidLabel.visible = true ChessModel.onValidMove: { invalidLabel.visible = false; console.log("valid move ", col, row); } }