/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** 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 https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** BSD License Usage ** Alternatively, you may use this file under the terms of the BSD license ** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of The Qt Company Ltd nor the names of its ** contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "mainwindow.h" #include "piecesmodel.h" #include "puzzlewidget.h" #include #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { setupMenus(); setupWidgets(); model = new PiecesModel(puzzleWidget->pieceSize(), this); piecesList->setModel(model); setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); setWindowTitle(tr("Puzzle")); } void MainWindow::openImage() { const QString directory = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).value(0, QDir::homePath()); QFileDialog dialog(this, tr("Open Image"), directory); dialog.setAcceptMode(QFileDialog::AcceptOpen); dialog.setFileMode(QFileDialog::ExistingFile); QStringList mimeTypeFilters; for (const QByteArray &mimeTypeName : QImageReader::supportedMimeTypes()) mimeTypeFilters.append(mimeTypeName); mimeTypeFilters.sort(); dialog.setMimeTypeFilters(mimeTypeFilters); dialog.selectMimeTypeFilter("image/jpeg"); if (dialog.exec() == QDialog::Accepted) loadImage(dialog.selectedFiles().constFirst()); } void MainWindow::loadImage(const QString &fileName) { QPixmap newImage; if (!newImage.load(fileName)) { QMessageBox::warning(this, tr("Open Image"), tr("The image file could not be loaded."), QMessageBox::Close); return; } puzzleImage = newImage; setupPuzzle(); } void MainWindow::setCompleted() { QMessageBox::information(this, tr("Puzzle Completed"), tr("Congratulations! You have completed the puzzle!\n" "Click OK to start again."), QMessageBox::Ok); setupPuzzle(); } void MainWindow::setupPuzzle() { int size = qMin(puzzleImage.width(), puzzleImage.height()); puzzleImage = puzzleImage.copy((puzzleImage.width() - size) / 2, (puzzleImage.height() - size) / 2, size, size).scaled(puzzleWidget->imageSize(), puzzleWidget->imageSize(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); model->addPieces(puzzleImage); puzzleWidget->clear(); } void MainWindow::setupMenus() { QMenu *fileMenu = menuBar()->addMenu(tr("&File")); QAction *openAction = fileMenu->addAction(tr("&Open..."), this, &MainWindow::openImage); openAction->setShortcuts(QKeySequence::Open); QAction *exitAction = fileMenu->addAction(tr("E&xit"), qApp, &QCoreApplication::quit); exitAction->setShortcuts(QKeySequence::Quit); QMenu *gameMenu = menuBar()->addMenu(tr("&Game")); gameMenu->addAction(tr("&Restart"), this, &MainWindow::setupPuzzle); } void MainWindow::setupWidgets() { QFrame *frame = new QFrame; QHBoxLayout *frameLayout = new QHBoxLayout(frame); puzzleWidget = new PuzzleWidget(400); piecesList = new QListView; piecesList->setDragEnabled(true); piecesList->setViewMode(QListView::IconMode); piecesList->setIconSize(QSize(puzzleWidget->pieceSize() - 20, puzzleWidget->pieceSize() - 20)); piecesList->setGridSize(QSize(puzzleWidget->pieceSize(), puzzleWidget->pieceSize())); piecesList->setSpacing(10); piecesList->setMovement(QListView::Snap); piecesList->setAcceptDrops(true); piecesList->setDropIndicatorShown(true); PiecesModel *model = new PiecesModel(puzzleWidget->pieceSize(), this); piecesList->setModel(model); connect(puzzleWidget, &PuzzleWidget::puzzleCompleted, this, &MainWindow::setCompleted, Qt::QueuedConnection); frameLayout->addWidget(piecesList); frameLayout->addWidget(puzzleWidget); setCentralWidget(frame); }