diff options
author | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2023-06-26 15:23:00 +0200 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2023-06-29 14:49:13 +0200 |
commit | 40dbee13ebf8a8d2fdd2fe2fbd82b42ef413a8fd (patch) | |
tree | f15e6f166c6a5b976c057f62a23b8d1c55e9d190 /examples/widgets | |
parent | 89b463ac2facc1b4fdcf3dcae612a4d8f9109b2c (diff) |
Move tetrix example to manual test
Pick-to: 6.5 6.6
Change-Id: Ie73d9e35df8513d05d55ffbad1f02584359e3bd0
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'examples/widgets')
-rw-r--r-- | examples/widgets/doc/src/tetrix.qdoc | 407 | ||||
-rw-r--r-- | examples/widgets/widgets/CMakeLists.txt | 1 | ||||
-rw-r--r-- | examples/widgets/widgets/tetrix/CMakeLists.txt | 39 | ||||
-rw-r--r-- | examples/widgets/widgets/tetrix/main.cpp | 14 | ||||
-rw-r--r-- | examples/widgets/widgets/tetrix/tetrix.pro | 13 | ||||
-rw-r--r-- | examples/widgets/widgets/tetrix/tetrixboard.cpp | 371 | ||||
-rw-r--r-- | examples/widgets/widgets/tetrix/tetrixboard.h | 79 | ||||
-rw-r--r-- | examples/widgets/widgets/tetrix/tetrixpiece.cpp | 106 | ||||
-rw-r--r-- | examples/widgets/widgets/tetrix/tetrixpiece.h | 38 | ||||
-rw-r--r-- | examples/widgets/widgets/tetrix/tetrixwindow.cpp | 82 | ||||
-rw-r--r-- | examples/widgets/widgets/tetrix/tetrixwindow.h | 38 | ||||
-rw-r--r-- | examples/widgets/widgets/widgets.pro | 1 |
12 files changed, 0 insertions, 1189 deletions
diff --git a/examples/widgets/doc/src/tetrix.qdoc b/examples/widgets/doc/src/tetrix.qdoc deleted file mode 100644 index 1f6ed76047..0000000000 --- a/examples/widgets/doc/src/tetrix.qdoc +++ /dev/null @@ -1,407 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only - -/*! - \example widgets/tetrix - \title Tetrix Example - \ingroup examples-widgets - \brief The Tetrix example is a Qt version of the classic Tetrix game. - - \borderedimage tetrix-example.png - - The object of the game is to stack pieces dropped from the top of the - playing area so that they fill entire rows at the bottom of the playing area. - - When a row is filled, all the blocks on that row are removed, the player earns - a number of points, and the pieces above are moved down to occupy that row. - If more than one row is filled, the blocks on each row are removed, and the - player earns extra points. - - The \uicontrol{Left} cursor key moves the current piece one space to the left, the - \uicontrol{Right} cursor key moves it one space to the right, the \uicontrol{Up} cursor - key rotates the piece counter-clockwise by 90 degrees, and the \uicontrol{Down} - cursor key rotates the piece clockwise by 90 degrees. - - To avoid waiting for a piece to fall to the bottom of the board, press \uicontrol{D} - to immediately move the piece down by one row, or press the \uicontrol{Space} key to - drop it as close to the bottom of the board as possible. - - This example shows how a simple game can be created using only three classes: - - \list - \li The \c TetrixWindow class is used to display the player's score, number of - lives, and information about the next piece to appear. - \li The \c TetrixBoard class contains the game logic, handles keyboard input, and - displays the pieces on the playing area. - \li The \c TetrixPiece class contains information about each piece. - \endlist - - In this approach, the \c TetrixBoard class is the most complex class, since it - handles the game logic and rendering. One benefit of this is that the - \c TetrixWindow and \c TetrixPiece classes are very simple and contain only a - minimum of code. - - \section1 TetrixWindow Class Definition - - The \c TetrixWindow class is used to display the game information and contains - the playing area: - - \snippet widgets/tetrix/tetrixwindow.h 0 - - We use private member variables for the board, various display widgets, and - buttons to allow the user to start a new game, pause the current game, and quit. - - Although the window inherits QWidget, the constructor does not provide an - argument to allow a parent widget to be specified. This is because the window - will always be used as a top-level widget. - - \section1 TetrixWindow Class Implementation - - The constructor sets up the user interface elements for the game: - - \snippet widgets/tetrix/tetrixwindow.cpp 0 - - We begin by constructing a \c TetrixBoard instance for the playing area and a - label that shows the next piece to be dropped into the playing area; the label - is initially empty. - - Three QLCDNumber objects are used to display the score, number of lives, and - lines removed. These initially show default values, and will be filled in - when a game begins: - - \snippet widgets/tetrix/tetrixwindow.cpp 1 - - Three buttons with shortcuts are constructed so that the user can start a - new game, pause the current game, and quit the application: - - \snippet widgets/tetrix/tetrixwindow.cpp 2 - \snippet widgets/tetrix/tetrixwindow.cpp 3 - - These buttons are configured so that they never receive the keyboard focus; - we want the keyboard focus to remain with the \c TetrixBoard instance so that - it receives all the keyboard events. Nonetheless, the buttons will still respond - to \uicontrol{Alt} key shortcuts. - - We connect \l{QAbstractButton::}{clicked()} signals from the \uicontrol{Start} - and \uicontrol{Pause} buttons to the board, and from the \uicontrol{Quit} button to the - application's \l{QCoreApplication::quit()} slot. - - \snippet widgets/tetrix/tetrixwindow.cpp 4 - \snippet widgets/tetrix/tetrixwindow.cpp 5 - - Signals from the board are also connected to the LCD widgets for the purpose of - updating the score, number of lives, and lines removed from the playing area. - - We place the label, LCD widgets, and the board into a QGridLayout - along with some labels that we create with the \c createLabel() convenience - function: - - \snippet widgets/tetrix/tetrixwindow.cpp 6 - - Finally, we set the grid layout on the widget, give the window a title, and - resize it to an appropriate size. - - The \c createLabel() convenience function simply creates a new label on the - heap, gives it an appropriate alignment, and returns it to the caller: - - \snippet widgets/tetrix/tetrixwindow.cpp 7 - - Since each label will be used in the widget's layout, it will become a child - of the \c TetrixWindow widget and, as a result, it will be deleted when the - window is deleted. - - \section1 TetrixPiece Class Definition - - The \c TetrixPiece class holds information about a piece in the game's - playing area, including its shape, position, and the range of positions it can - occupy on the board: - - \snippet widgets/tetrix/tetrixpiece.h 0 - - Each shape contains four blocks, and these are defined by the \c coords private - member variable. Additionally, each piece has a high-level description that is - stored internally in the \c pieceShape variable. - - The constructor is written inline in the definition, and simply ensures that - each piece is initially created with no shape. The \c shape() function simply - returns the contents of the \c pieceShape variable, and the \c x() and \c y() - functions return the x and y-coordinates of any given block in the shape. - - \section1 TetrixPiece Class Implementation - - The \c setRandomShape() function is used to select a random shape for a piece: - - \snippet widgets/tetrix/tetrixpiece.cpp 0 - - For convenience, it simply chooses a random shape from the \c TetrixShape enum - and calls the \c setShape() function to perform the task of positioning the - blocks. - - The \c setShape() function uses a look-up table of pieces to associate each - shape with an array of block positions: - - \snippet widgets/tetrix/tetrixpiece.cpp 1 - \snippet widgets/tetrix/tetrixpiece.cpp 2 - - These positions are read from the table into the piece's own array of positions, - and the piece's internal shape information is updated to use the new shape. - - The \c x() and \c y() functions are implemented inline in the class definition, - returning positions defined on a grid that extends horizontally and vertically - with coordinates from -2 to 2. Although the predefined coordinates for each - piece only vary horizontally from -1 to 1 and vertically from -1 to 2, each - piece can be rotated by 90, 180, and 270 degrees. - - The \c minX() and \c maxX() functions return the minimum and maximum horizontal - coordinates occupied by the blocks that make up the piece: - - \snippet widgets/tetrix/tetrixpiece.cpp 3 - \snippet widgets/tetrix/tetrixpiece.cpp 4 - - Similarly, the \c minY() and \c maxY() functions return the minimum and maximum - vertical coordinates occupied by the blocks: - - \snippet widgets/tetrix/tetrixpiece.cpp 5 - \snippet widgets/tetrix/tetrixpiece.cpp 6 - - The \c rotatedLeft() function returns a new piece with the same shape as an - existing piece, but rotated counter-clockwise by 90 degrees: - - \snippet widgets/tetrix/tetrixpiece.cpp 7 - - Similarly, the \c rotatedRight() function returns a new piece with the same - shape as an existing piece, but rotated clockwise by 90 degrees: - - \snippet widgets/tetrix/tetrixpiece.cpp 9 - - These last two functions enable each piece to create rotated copies of itself. - - \section1 TetrixBoard Class Definition - - The \c TetrixBoard class inherits from QFrame and contains the game logic and display features: - - \snippet widgets/tetrix/tetrixboard.h 0 - - Apart from the \c setNextPieceLabel() function and the \c start() and \c pause() - public slots, we only provide public functions to reimplement QWidget::sizeHint() - and QWidget::minimumSizeHint(). The signals are used to communicate changes to - the player's information to the \c TetrixWindow instance. - - The rest of the functionality is provided by reimplementations of protected event - handlers and private functions: - - \snippet widgets/tetrix/tetrixboard.h 1 - - The board is composed of a fixed-size array whose elements correspond to - spaces for individual blocks. Each element in the array contains a \c TetrixShape - value corresponding to the type of shape that occupies that element. - - Each shape on the board will occupy four elements in the array, and these will - all contain the enum value that corresponds to the type of the shape. - - We use a QBasicTimer to control the rate at which pieces fall toward the bottom - of the playing area. This allows us to provide an implementation of - \l{QObject::}{timerEvent()} that we can use to update the widget. - - \section1 TetrixBoard Class Implementation - - In the constructor, we customize the frame style of the widget, ensure that - keyboard input will be received by the widget by using Qt::StrongFocus for the - focus policy, and initialize the game state: - - \snippet widgets/tetrix/tetrixboard.cpp 0 - - The first (next) piece is also set up with a random shape. - - The \c setNextPieceLabel() function is used to pass in an externally-constructed - label to the board, so that it can be shown alongside the playing area: - - \snippet widgets/tetrix/tetrixboard.cpp 1 - - We provide a reasonable size hint and minimum size hint for the board, based on - the size of the space for each block in the playing area: - - \snippet widgets/tetrix/tetrixboard.cpp 2 - \snippet widgets/tetrix/tetrixboard.cpp 3 - - By using a minimum size hint, we indicate to the layout in the parent widget - that the board should not shrink below a minimum size. - - A new game is started when the \c start() slot is called. This resets the - game's state, the player's score and level, and the contents of the board: - - \snippet widgets/tetrix/tetrixboard.cpp 4 - - We also emit signals to inform other components of these changes before creating - a new piece that is ready to be dropped into the playing area. We start the - timer that determines how often the piece drops down one row on the board. - - The \c pause() slot is used to temporarily stop the current game by stopping the - internal timer: - - \snippet widgets/tetrix/tetrixboard.cpp 5 - \snippet widgets/tetrix/tetrixboard.cpp 6 - - We perform checks to ensure that the game can only be paused if it is already - running and not already paused. - - The \c paintEvent() function is straightforward to implement. We begin by - calling the base class's implementation of \l{QWidget::}{paintEvent()} before - constructing a QPainter for use on the board: - - \snippet widgets/tetrix/tetrixboard.cpp 7 - - Since the board is a subclass of QFrame, we obtain a QRect that covers the area - \e inside the frame decoration before drawing our own content. - - If the game is paused, we want to hide the existing state of the board and - show some text. We achieve this by painting text onto the widget and returning - early from the function. The rest of the painting is performed after this point. - - The position of the top of the board is found by subtracting the total height - of each space on the board from the bottom of the frame's internal rectangle. - For each space on the board that is occupied by a piece, we call the - \c drawSquare() function to draw a block at that position. - - \snippet widgets/tetrix/tetrixboard.cpp 8 - \snippet widgets/tetrix/tetrixboard.cpp 9 - - Spaces that are not occupied by blocks are left blank. - - Unlike the existing pieces on the board, the current piece is drawn - block-by-block at its current position: - - \snippet widgets/tetrix/tetrixboard.cpp 10 - \snippet widgets/tetrix/tetrixboard.cpp 11 - \snippet widgets/tetrix/tetrixboard.cpp 12 - - The \c keyPressEvent() handler is called whenever the player presses a key while - the \c TetrixBoard widget has the keyboard focus. - - \snippet widgets/tetrix/tetrixboard.cpp 13 - - If there is no current game, the game is running but paused, or if there is no - current shape to control, we simply pass on the event to the base class. - - We check whether the event is about any of the keys that the player uses to - control the current piece and, if so, we call the relevant function to handle - the input: - - \snippet widgets/tetrix/tetrixboard.cpp 14 - - In the case where the player presses a key that we are not interested in, we - again pass on the event to the base class's implementation of - \l{QWidget::}{keyPressEvent()}. - - The \c timerEvent() handler is called every time the class's QBasicTimer - instance times out. We need to check that the event we receive corresponds to - our timer. If it does, we can update the board: - - \snippet widgets/tetrix/tetrixboard.cpp 15 - \snippet widgets/tetrix/tetrixboard.cpp 16 - \snippet widgets/tetrix/tetrixboard.cpp 17 - - If a row (or line) has just been filled, we create a new piece and reset the - timer; otherwise we move the current piece down by one row. We let the base - class handle other timer events that we receive. - - The \c clearBoard() function simply fills the board with the - \c TetrixShape::NoShape value: - - \snippet widgets/tetrix/tetrixboard.cpp 18 - - The \c dropDown() function moves the current piece down as far as possible on - the board, either until it is touching the bottom of the playing area or it is - stacked on top of another piece: - - \snippet widgets/tetrix/tetrixboard.cpp 19 - \snippet widgets/tetrix/tetrixboard.cpp 20 - - The number of rows the piece has dropped is recorded and passed to the - \c pieceDropped() function so that the player's score can be updated. - - The \c oneLineDown() function is used to move the current piece down by one row - (line), either when the user presses the \uicontrol{D} key or when the piece is - scheduled to move: - - \snippet widgets/tetrix/tetrixboard.cpp 21 - - If the piece cannot drop down by one line, we call the \c pieceDropped() function - with zero as the argument to indicate that it cannot fall any further, and that - the player should receive no extra points for the fall. - - The \c pieceDropped() function itself is responsible for awarding points to the - player for positioning the current piece, checking for full rows on the board - and, if no lines have been removed, creating a new piece to replace the current - one: - - \snippet widgets/tetrix/tetrixboard.cpp 22 - \snippet widgets/tetrix/tetrixboard.cpp 23 - - We call \c removeFullLines() each time a piece has been dropped. This scans - the board from bottom to top, looking for blank spaces on each row. - - \snippet widgets/tetrix/tetrixboard.cpp 24 - \snippet widgets/tetrix/tetrixboard.cpp 25 - \snippet widgets/tetrix/tetrixboard.cpp 26 - \snippet widgets/tetrix/tetrixboard.cpp 27 - - If a row contains no blank spaces, the rows above it are copied down by one row - to compress the stack of pieces, the top row on the board is cleared, and the - number of full lines found is incremented. - - \snippet widgets/tetrix/tetrixboard.cpp 28 - \snippet widgets/tetrix/tetrixboard.cpp 29 - - If some lines have been removed, the player's score and the total number of lines - removed are updated. The \c linesRemoved() and \c scoreChanged() signals are - emitted to send these new values to other widgets in the window. - - Additionally, we set the timer to elapse after half a second, set the - \c isWaitingAfterLine flag to indicate that lines have been removed, unset - the piece's shape to ensure that it is not drawn, and update the widget. - The next time that the \c timerEvent() handler is called, a new piece will be - created and the game will continue. - - The \c newPiece() function places the next available piece at the top of the - board, and creates a new piece with a random shape: - - \snippet widgets/tetrix/tetrixboard.cpp 30 - \snippet widgets/tetrix/tetrixboard.cpp 31 - - We place a new piece in the middle of the board at the top. The game is over if - the piece can't move, so we unset its shape to prevent it from being drawn, stop - the timer, and unset the \c isStarted flag. - - The \c showNextPiece() function updates the label that shows the next piece to - be dropped: - - \snippet widgets/tetrix/tetrixboard.cpp 32 - \snippet widgets/tetrix/tetrixboard.cpp 33 - - We draw the piece's component blocks onto a pixmap that is then set on the label. - - The \c tryMove() function is used to determine whether a piece can be positioned - at the specified coordinates: - - \snippet widgets/tetrix/tetrixboard.cpp 34 - - We examine the spaces on the board that the piece needs to occupy and, if they - are already occupied by other pieces, we return \c false to indicate that the - move has failed. - - \snippet widgets/tetrix/tetrixboard.cpp 35 - - If the piece could be placed on the board at the desired location, we update the - current piece and its position, update the widget, and return \c true to indicate - success. - - The \c drawSquare() function draws the blocks (normally squares) that make up - each piece using different colors for pieces with different shapes: - - \snippet widgets/tetrix/tetrixboard.cpp 36 - - We obtain the color to use from a look-up table that relates each shape to an - RGB value, and use the painter provided to draw the block at the specified - coordinates. -*/ diff --git a/examples/widgets/widgets/CMakeLists.txt b/examples/widgets/widgets/CMakeLists.txt index d548c63ff8..6b6a7760b7 100644 --- a/examples/widgets/widgets/CMakeLists.txt +++ b/examples/widgets/widgets/CMakeLists.txt @@ -12,6 +12,5 @@ qt_internal_add_example(shortcuteditor) qt_internal_add_example(sliders) qt_internal_add_example(spinboxes) qt_internal_add_example(tablet) -qt_internal_add_example(tetrix) qt_internal_add_example(tooltips) qt_internal_add_example(windowflags) diff --git a/examples/widgets/widgets/tetrix/CMakeLists.txt b/examples/widgets/widgets/tetrix/CMakeLists.txt deleted file mode 100644 index 4b649e1d8e..0000000000 --- a/examples/widgets/widgets/tetrix/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright (C) 2022 The Qt Company Ltd. -# SPDX-License-Identifier: BSD-3-Clause - -cmake_minimum_required(VERSION 3.16) -project(tetrix LANGUAGES CXX) - -if(NOT DEFINED INSTALL_EXAMPLESDIR) - set(INSTALL_EXAMPLESDIR "examples") -endif() - -set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/widgets/tetrix") - -find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets) - -qt_standard_project_setup() - -qt_add_executable(tetrix - main.cpp - tetrixboard.cpp tetrixboard.h - tetrixpiece.cpp tetrixpiece.h - tetrixwindow.cpp tetrixwindow.h -) - -set_target_properties(tetrix PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) - -target_link_libraries(tetrix PRIVATE - Qt6::Core - Qt6::Gui - Qt6::Widgets -) - -install(TARGETS tetrix - RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" - BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" - LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" -) diff --git a/examples/widgets/widgets/tetrix/main.cpp b/examples/widgets/widgets/tetrix/main.cpp deleted file mode 100644 index 24791bde26..0000000000 --- a/examples/widgets/widgets/tetrix/main.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause - -#include "tetrixwindow.h" - -#include <QApplication> - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - TetrixWindow window; - window.show(); - return app.exec(); -} diff --git a/examples/widgets/widgets/tetrix/tetrix.pro b/examples/widgets/widgets/tetrix/tetrix.pro deleted file mode 100644 index bb9f855fb0..0000000000 --- a/examples/widgets/widgets/tetrix/tetrix.pro +++ /dev/null @@ -1,13 +0,0 @@ -QT += widgets - -HEADERS = tetrixboard.h \ - tetrixpiece.h \ - tetrixwindow.h -SOURCES = main.cpp \ - tetrixboard.cpp \ - tetrixpiece.cpp \ - tetrixwindow.cpp - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/widgets/widgets/tetrix -INSTALLS += target diff --git a/examples/widgets/widgets/tetrix/tetrixboard.cpp b/examples/widgets/widgets/tetrix/tetrixboard.cpp deleted file mode 100644 index 0c5771ad89..0000000000 --- a/examples/widgets/widgets/tetrix/tetrixboard.cpp +++ /dev/null @@ -1,371 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause - -#include "tetrixboard.h" - -#include <QKeyEvent> -#include <QLabel> -#include <QPainter> - -//! [0] -TetrixBoard::TetrixBoard(QWidget *parent) - : QFrame(parent), isStarted(false), isPaused(false) -{ - setFrameStyle(QFrame::Panel | QFrame::Sunken); - setFocusPolicy(Qt::StrongFocus); - clearBoard(); - - nextPiece.setRandomShape(); -} -//! [0] - -//! [1] -void TetrixBoard::setNextPieceLabel(QLabel *label) -{ - nextPieceLabel = label; -} -//! [1] - -//! [2] -QSize TetrixBoard::sizeHint() const -{ - return QSize(BoardWidth * 15 + frameWidth() * 2, - BoardHeight * 15 + frameWidth() * 2); -} - -QSize TetrixBoard::minimumSizeHint() const -//! [2] //! [3] -{ - return QSize(BoardWidth * 5 + frameWidth() * 2, - BoardHeight * 5 + frameWidth() * 2); -} -//! [3] - -//! [4] -void TetrixBoard::start() -{ - if (isPaused) - return; - - isStarted = true; - isWaitingAfterLine = false; - numLinesRemoved = 0; - numPiecesDropped = 0; - score = 0; - level = 1; - clearBoard(); - - emit linesRemovedChanged(numLinesRemoved); - emit scoreChanged(score); - emit levelChanged(level); - - newPiece(); - timer.start(timeoutTime(), this); -} -//! [4] - -//! [5] -void TetrixBoard::pause() -{ - if (!isStarted) - return; - - isPaused = !isPaused; - if (isPaused) { - timer.stop(); - } else { - timer.start(timeoutTime(), this); - } - update(); -//! [5] //! [6] -} -//! [6] - -//! [7] -void TetrixBoard::paintEvent(QPaintEvent *event) -{ - QFrame::paintEvent(event); - - QPainter painter(this); - QRect rect = contentsRect(); -//! [7] - - if (isPaused) { - painter.drawText(rect, Qt::AlignCenter, tr("Pause")); - return; - } - -//! [8] - int boardTop = rect.bottom() - BoardHeight*squareHeight(); - - for (int i = 0; i < BoardHeight; ++i) { - for (int j = 0; j < BoardWidth; ++j) { - TetrixShape shape = shapeAt(j, BoardHeight - i - 1); - if (shape != NoShape) - drawSquare(painter, rect.left() + j * squareWidth(), - boardTop + i * squareHeight(), shape); - } -//! [8] //! [9] - } -//! [9] - -//! [10] - if (curPiece.shape() != NoShape) { - for (int i = 0; i < 4; ++i) { - int x = curX + curPiece.x(i); - int y = curY - curPiece.y(i); - drawSquare(painter, rect.left() + x * squareWidth(), - boardTop + (BoardHeight - y - 1) * squareHeight(), - curPiece.shape()); - } -//! [10] //! [11] - } -//! [11] //! [12] -} -//! [12] - -//! [13] -void TetrixBoard::keyPressEvent(QKeyEvent *event) -{ - if (!isStarted || isPaused || curPiece.shape() == NoShape) { - QFrame::keyPressEvent(event); - return; - } -//! [13] - -//! [14] - switch (event->key()) { - case Qt::Key_Left: - tryMove(curPiece, curX - 1, curY); - break; - case Qt::Key_Right: - tryMove(curPiece, curX + 1, curY); - break; - case Qt::Key_Down: - tryMove(curPiece.rotatedRight(), curX, curY); - break; - case Qt::Key_Up: - tryMove(curPiece.rotatedLeft(), curX, curY); - break; - case Qt::Key_Space: - dropDown(); - break; - case Qt::Key_D: - oneLineDown(); - break; - default: - QFrame::keyPressEvent(event); - } -//! [14] -} - -//! [15] -void TetrixBoard::timerEvent(QTimerEvent *event) -{ - if (event->timerId() == timer.timerId()) { - if (isWaitingAfterLine) { - isWaitingAfterLine = false; - newPiece(); - timer.start(timeoutTime(), this); - } else { - oneLineDown(); - } - } else { - QFrame::timerEvent(event); -//! [15] //! [16] - } -//! [16] //! [17] -} -//! [17] - -//! [18] -void TetrixBoard::clearBoard() -{ - for (int i = 0; i < BoardHeight * BoardWidth; ++i) - board[i] = NoShape; -} -//! [18] - -//! [19] -void TetrixBoard::dropDown() -{ - int dropHeight = 0; - int newY = curY; - while (newY > 0) { - if (!tryMove(curPiece, curX, newY - 1)) - break; - --newY; - ++dropHeight; - } - pieceDropped(dropHeight); -//! [19] //! [20] -} -//! [20] - -//! [21] -void TetrixBoard::oneLineDown() -{ - if (!tryMove(curPiece, curX, curY - 1)) - pieceDropped(0); -} -//! [21] - -//! [22] -void TetrixBoard::pieceDropped(int dropHeight) -{ - for (int i = 0; i < 4; ++i) { - int x = curX + curPiece.x(i); - int y = curY - curPiece.y(i); - shapeAt(x, y) = curPiece.shape(); - } - - ++numPiecesDropped; - if (numPiecesDropped % 25 == 0) { - ++level; - timer.start(timeoutTime(), this); - emit levelChanged(level); - } - - score += dropHeight + 7; - emit scoreChanged(score); - removeFullLines(); - - if (!isWaitingAfterLine) - newPiece(); -//! [22] //! [23] -} -//! [23] - -//! [24] -void TetrixBoard::removeFullLines() -{ - int numFullLines = 0; - - for (int i = BoardHeight - 1; i >= 0; --i) { - bool lineIsFull = true; - - for (int j = 0; j < BoardWidth; ++j) { - if (shapeAt(j, i) == NoShape) { - lineIsFull = false; - break; - } - } - - if (lineIsFull) { -//! [24] //! [25] - ++numFullLines; - for (int k = i; k < BoardHeight - 1; ++k) { - for (int j = 0; j < BoardWidth; ++j) - shapeAt(j, k) = shapeAt(j, k + 1); - } -//! [25] //! [26] - for (int j = 0; j < BoardWidth; ++j) - shapeAt(j, BoardHeight - 1) = NoShape; - } -//! [26] //! [27] - } -//! [27] - -//! [28] - if (numFullLines > 0) { - numLinesRemoved += numFullLines; - score += 10 * numFullLines; - emit linesRemovedChanged(numLinesRemoved); - emit scoreChanged(score); - - timer.start(500, this); - isWaitingAfterLine = true; - curPiece.setShape(NoShape); - update(); - } -//! [28] //! [29] -} -//! [29] - -//! [30] -void TetrixBoard::newPiece() -{ - curPiece = nextPiece; - nextPiece.setRandomShape(); - showNextPiece(); - curX = BoardWidth / 2 + 1; - curY = BoardHeight - 1 + curPiece.minY(); - - if (!tryMove(curPiece, curX, curY)) { - curPiece.setShape(NoShape); - timer.stop(); - isStarted = false; - } -//! [30] //! [31] -} -//! [31] - -//! [32] -void TetrixBoard::showNextPiece() -{ - if (!nextPieceLabel) - return; - - int dx = nextPiece.maxX() - nextPiece.minX() + 1; - int dy = nextPiece.maxY() - nextPiece.minY() + 1; - - QPixmap pixmap(dx * squareWidth(), dy * squareHeight()); - QPainter painter(&pixmap); - painter.fillRect(pixmap.rect(), nextPieceLabel->palette().window()); - - for (int i = 0; i < 4; ++i) { - int x = nextPiece.x(i) - nextPiece.minX(); - int y = nextPiece.y(i) - nextPiece.minY(); - drawSquare(painter, x * squareWidth(), y * squareHeight(), - nextPiece.shape()); - } - nextPieceLabel->setPixmap(pixmap); -//! [32] //! [33] -} -//! [33] - -//! [34] -bool TetrixBoard::tryMove(const TetrixPiece &newPiece, int newX, int newY) -{ - for (int i = 0; i < 4; ++i) { - int x = newX + newPiece.x(i); - int y = newY - newPiece.y(i); - if (x < 0 || x >= BoardWidth || y < 0 || y >= BoardHeight) - return false; - if (shapeAt(x, y) != NoShape) - return false; - } -//! [34] - -//! [35] - curPiece = newPiece; - curX = newX; - curY = newY; - update(); - return true; -} -//! [35] - -//! [36] -void TetrixBoard::drawSquare(QPainter &painter, int x, int y, TetrixShape shape) -{ - static constexpr QRgb colorTable[8] = { - 0x000000, 0xCC6666, 0x66CC66, 0x6666CC, - 0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00 - }; - - QColor color = colorTable[int(shape)]; - painter.fillRect(x + 1, y + 1, squareWidth() - 2, squareHeight() - 2, - color); - - painter.setPen(color.lighter()); - painter.drawLine(x, y + squareHeight() - 1, x, y); - painter.drawLine(x, y, x + squareWidth() - 1, y); - - painter.setPen(color.darker()); - painter.drawLine(x + 1, y + squareHeight() - 1, - x + squareWidth() - 1, y + squareHeight() - 1); - painter.drawLine(x + squareWidth() - 1, y + squareHeight() - 1, - x + squareWidth() - 1, y + 1); -} -//! [36] diff --git a/examples/widgets/widgets/tetrix/tetrixboard.h b/examples/widgets/widgets/tetrix/tetrixboard.h deleted file mode 100644 index c2fe3fd01e..0000000000 --- a/examples/widgets/widgets/tetrix/tetrixboard.h +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause - -#ifndef TETRIXBOARD_H -#define TETRIXBOARD_H - -#include <QBasicTimer> -#include <QFrame> -#include <QPointer> - -#include "tetrixpiece.h" - -QT_BEGIN_NAMESPACE -class QLabel; -QT_END_NAMESPACE - -//! [0] -class TetrixBoard : public QFrame -{ - Q_OBJECT - -public: - TetrixBoard(QWidget *parent = nullptr); - - void setNextPieceLabel(QLabel *label); - QSize sizeHint() const override; - QSize minimumSizeHint() const override; - -public slots: - void start(); - void pause(); - -signals: - void scoreChanged(int score); - void levelChanged(int level); - void linesRemovedChanged(int numLines); - -protected: - void paintEvent(QPaintEvent *event) override; - void keyPressEvent(QKeyEvent *event) override; - void timerEvent(QTimerEvent *event) override; -//! [0] - -//! [1] -private: - enum { BoardWidth = 10, BoardHeight = 22 }; - - TetrixShape &shapeAt(int x, int y) { return board[(y * BoardWidth) + x]; } - int timeoutTime() { return 1000 / (1 + level); } - int squareWidth() { return contentsRect().width() / BoardWidth; } - int squareHeight() { return contentsRect().height() / BoardHeight; } - void clearBoard(); - void dropDown(); - void oneLineDown(); - void pieceDropped(int dropHeight); - void removeFullLines(); - void newPiece(); - void showNextPiece(); - bool tryMove(const TetrixPiece &newPiece, int newX, int newY); - void drawSquare(QPainter &painter, int x, int y, TetrixShape shape); - - QBasicTimer timer; - QPointer<QLabel> nextPieceLabel; - bool isStarted; - bool isPaused; - bool isWaitingAfterLine; - TetrixPiece curPiece; - TetrixPiece nextPiece; - int curX; - int curY; - int numLinesRemoved; - int numPiecesDropped; - int score; - int level; - TetrixShape board[BoardWidth * BoardHeight]; -}; -//! [1] - -#endif diff --git a/examples/widgets/widgets/tetrix/tetrixpiece.cpp b/examples/widgets/widgets/tetrix/tetrixpiece.cpp deleted file mode 100644 index 5dc9e11c49..0000000000 --- a/examples/widgets/widgets/tetrix/tetrixpiece.cpp +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause - -#include "tetrixpiece.h" - -#include <QtCore> - -//! [0] -void TetrixPiece::setRandomShape() -{ - setShape(TetrixShape(QRandomGenerator::global()->bounded(7) + 1)); -} -//! [0] - -//! [1] -void TetrixPiece::setShape(TetrixShape shape) -{ - static constexpr int coordsTable[8][4][2] = { - { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }, - { { 0, -1 }, { 0, 0 }, { -1, 0 }, { -1, 1 } }, - { { 0, -1 }, { 0, 0 }, { 1, 0 }, { 1, 1 } }, - { { 0, -1 }, { 0, 0 }, { 0, 1 }, { 0, 2 } }, - { { -1, 0 }, { 0, 0 }, { 1, 0 }, { 0, 1 } }, - { { 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 } }, - { { -1, -1 }, { 0, -1 }, { 0, 0 }, { 0, 1 } }, - { { 1, -1 }, { 0, -1 }, { 0, 0 }, { 0, 1 } } - }; - - for (int i = 0; i < 4 ; i++) { - for (int j = 0; j < 2; ++j) - coords[i][j] = coordsTable[shape][i][j]; - } - pieceShape = shape; -//! [1] //! [2] -} -//! [2] - -//! [3] -int TetrixPiece::minX() const -{ - int min = coords[0][0]; - for (int i = 1; i < 4; ++i) - min = qMin(min, coords[i][0]); - return min; -} - -int TetrixPiece::maxX() const -//! [3] //! [4] -{ - int max = coords[0][0]; - for (int i = 1; i < 4; ++i) - max = qMax(max, coords[i][0]); - return max; -} -//! [4] - -//! [5] -int TetrixPiece::minY() const -{ - int min = coords[0][1]; - for (int i = 1; i < 4; ++i) - min = qMin(min, coords[i][1]); - return min; -} - -int TetrixPiece::maxY() const -//! [5] //! [6] -{ - int max = coords[0][1]; - for (int i = 1; i < 4; ++i) - max = qMax(max, coords[i][1]); - return max; -} -//! [6] - -//! [7] -TetrixPiece TetrixPiece::rotatedLeft() const -{ - if (pieceShape == SquareShape) - return *this; - - TetrixPiece result; - result.pieceShape = pieceShape; - for (int i = 0; i < 4; ++i) { - result.setX(i, y(i)); - result.setY(i, -x(i)); - } -//! [7] - return result; -} - -//! [9] -TetrixPiece TetrixPiece::rotatedRight() const -{ - if (pieceShape == SquareShape) - return *this; - - TetrixPiece result; - result.pieceShape = pieceShape; - for (int i = 0; i < 4; ++i) { - result.setX(i, -y(i)); - result.setY(i, x(i)); - } -//! [9] - return result; -} diff --git a/examples/widgets/widgets/tetrix/tetrixpiece.h b/examples/widgets/widgets/tetrix/tetrixpiece.h deleted file mode 100644 index 86a513a76e..0000000000 --- a/examples/widgets/widgets/tetrix/tetrixpiece.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause - -#ifndef TETRIXPIECE_H -#define TETRIXPIECE_H - -enum TetrixShape { NoShape, ZShape, SShape, LineShape, TShape, SquareShape, - LShape, MirroredLShape }; - -//! [0] -class TetrixPiece -{ -public: - TetrixPiece() { setShape(NoShape); } - - void setRandomShape(); - void setShape(TetrixShape shape); - - TetrixShape shape() const { return pieceShape; } - int x(int index) const { return coords[index][0]; } - int y(int index) const { return coords[index][1]; } - int minX() const; - int maxX() const; - int minY() const; - int maxY() const; - TetrixPiece rotatedLeft() const; - TetrixPiece rotatedRight() const; - -private: - void setX(int index, int x) { coords[index][0] = x; } - void setY(int index, int y) { coords[index][1] = y; } - - TetrixShape pieceShape; - int coords[4][2]; -}; -//! [0] - -#endif diff --git a/examples/widgets/widgets/tetrix/tetrixwindow.cpp b/examples/widgets/widgets/tetrix/tetrixwindow.cpp deleted file mode 100644 index ae10a778e7..0000000000 --- a/examples/widgets/widgets/tetrix/tetrixwindow.cpp +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause - -#include "tetrixboard.h" -#include "tetrixwindow.h" - -#include <QCoreApplication> -#include <QGridLayout> -#include <QLabel> -#include <QLCDNumber> -#include <QPushButton> - -//! [0] -TetrixWindow::TetrixWindow(QWidget *parent) - : QWidget(parent), board(new TetrixBoard) -{ -//! [0] - nextPieceLabel = new QLabel; - nextPieceLabel->setFrameStyle(QFrame::Box | QFrame::Raised); - nextPieceLabel->setAlignment(Qt::AlignCenter); - board->setNextPieceLabel(nextPieceLabel); -//! [1] - scoreLcd = new QLCDNumber(5); - scoreLcd->setSegmentStyle(QLCDNumber::Filled); -//! [1] - levelLcd = new QLCDNumber(2); - levelLcd->setSegmentStyle(QLCDNumber::Filled); - linesLcd = new QLCDNumber(5); - linesLcd->setSegmentStyle(QLCDNumber::Filled); - -//! [2] - startButton = new QPushButton(tr("&Start")); - startButton->setFocusPolicy(Qt::NoFocus); - quitButton = new QPushButton(tr("&Quit")); - quitButton->setFocusPolicy(Qt::NoFocus); - pauseButton = new QPushButton(tr("&Pause")); -//! [2] //! [3] - pauseButton->setFocusPolicy(Qt::NoFocus); -//! [3] //! [4] - - connect(startButton, &QPushButton::clicked, board, &TetrixBoard::start); -//! [4] //! [5] - connect(quitButton , &QPushButton::clicked, qApp, &QCoreApplication::quit); - connect(pauseButton, &QPushButton::clicked, board, &TetrixBoard::pause); - connect(board, &TetrixBoard::scoreChanged, - scoreLcd, qOverload<int>(&QLCDNumber::display)); - connect(board, &TetrixBoard::levelChanged, - levelLcd, qOverload<int>(&QLCDNumber::display)); - connect(board, &TetrixBoard::linesRemovedChanged, - linesLcd, qOverload<int>(&QLCDNumber::display)); -//! [5] - -//! [6] - QGridLayout *layout = new QGridLayout; - layout->addWidget(createLabel(tr("NEXT")), 0, 0); - layout->addWidget(nextPieceLabel, 1, 0); - layout->addWidget(createLabel(tr("LEVEL")), 2, 0); - layout->addWidget(levelLcd, 3, 0); - layout->addWidget(startButton, 4, 0); - layout->addWidget(board, 0, 1, 6, 1); - layout->addWidget(createLabel(tr("SCORE")), 0, 2); - layout->addWidget(scoreLcd, 1, 2); - layout->addWidget(createLabel(tr("LINES REMOVED")), 2, 2); - layout->addWidget(linesLcd, 3, 2); - layout->addWidget(quitButton, 4, 2); - layout->addWidget(pauseButton, 5, 2); - setLayout(layout); - - setWindowTitle(tr("Tetrix")); - resize(550, 370); -} -//! [6] - -//! [7] -QLabel *TetrixWindow::createLabel(const QString &text) -{ - QLabel *label = new QLabel(text); - label->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); - return label; -} -//! [7] - diff --git a/examples/widgets/widgets/tetrix/tetrixwindow.h b/examples/widgets/widgets/tetrix/tetrixwindow.h deleted file mode 100644 index 2ed468717d..0000000000 --- a/examples/widgets/widgets/tetrix/tetrixwindow.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause - -#ifndef TETRIXWINDOW_H -#define TETRIXWINDOW_H - -#include <QWidget> - -QT_BEGIN_NAMESPACE -class QLCDNumber; -class QLabel; -class QPushButton; -QT_END_NAMESPACE -class TetrixBoard; - -//! [0] -class TetrixWindow : public QWidget -{ - Q_OBJECT - -public: - TetrixWindow(QWidget *parent = nullptr); - -private: - QLabel *createLabel(const QString &text); - - TetrixBoard *board; - QLabel *nextPieceLabel; - QLCDNumber *scoreLcd; - QLCDNumber *levelLcd; - QLCDNumber *linesLcd; - QPushButton *startButton; - QPushButton *quitButton; - QPushButton *pauseButton; -}; -//! [0] - -#endif diff --git a/examples/widgets/widgets/widgets.pro b/examples/widgets/widgets/widgets.pro index dbfffab4c4..7384b69743 100644 --- a/examples/widgets/widgets/widgets.pro +++ b/examples/widgets/widgets/widgets.pro @@ -9,6 +9,5 @@ SUBDIRS = analogclock \ sliders \ spinboxes \ tablet \ - tetrix \ tooltips \ windowflags |