6.5.3 clean

This commit is contained in:
kleuter
2023-11-01 18:02:52 +01:00
parent bbe896803b
commit 7018d9e6c8
2170 changed files with 57471 additions and 43550 deletions

View File

@ -0,0 +1,51 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(puzzle LANGUAGES CXX)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/draganddrop_puzzle")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
qt_standard_project_setup()
qt_add_executable(draganddrop_puzzle
main.cpp
mainwindow.cpp mainwindow.h
pieceslist.cpp pieceslist.h
puzzlewidget.cpp puzzlewidget.h
)
set_target_properties(draganddrop_puzzle PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
target_link_libraries(draganddrop_puzzle PRIVATE
Qt6::Core
Qt6::Gui
Qt6::Widgets
)
# Resources:
set(puzzle_resource_files
"example.jpg"
)
qt_add_resources(draganddrop_puzzle "puzzle"
PREFIX
"/images"
FILES
${puzzle_resource_files}
)
install(TARGETS draganddrop_puzzle
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -0,0 +1,15 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow window;
window.loadImage(QStringLiteral(":/images/example.jpg"));
window.show();
return app.exec();
}

View File

@ -0,0 +1,118 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "mainwindow.h"
#include "pieceslist.h"
#include "puzzlewidget.h"
#include <QtWidgets>
#include <stdlib.h>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
setupMenus();
setupWidgets();
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->width(),
puzzleWidget->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
piecesList->clear();
for (int y = 0; y < 5; ++y) {
for (int x = 0; x < 5; ++x) {
int pieceSize = puzzleWidget->pieceSize();
QPixmap pieceImage = puzzleImage.copy(x * pieceSize, y * pieceSize, pieceSize, pieceSize);
piecesList->addPiece(pieceImage, QPoint(x, y));
}
}
for (int i = 0; i < piecesList->count(); ++i) {
if (QRandomGenerator::global()->bounded(2) == 1) {
QListWidgetItem *item = piecesList->takeItem(i);
piecesList->insertItem(0, item);
}
}
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 PiecesList(puzzleWidget->pieceSize(), this);
connect(puzzleWidget, &PuzzleWidget::puzzleCompleted,
this, &MainWindow::setCompleted, Qt::QueuedConnection);
frameLayout->addWidget(piecesList);
frameLayout->addWidget(puzzleWidget);
setCentralWidget(frame);
}

View File

@ -0,0 +1,40 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPixmap>
class PiecesList;
class PuzzleWidget;
QT_BEGIN_NAMESPACE
class QListWidgetItem;
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
void loadImage(const QString &path);
public slots:
void openImage();
void setupPuzzle();
private slots:
void setCompleted();
private:
void setupMenus();
void setupWidgets();
QPixmap puzzleImage;
PiecesList *piecesList;
PuzzleWidget *puzzleWidget;
};
#endif // MAINWINDOW_H

View File

@ -0,0 +1,87 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "pieceslist.h"
#include <QDrag>
#include <QDragEnterEvent>
#include <QMimeData>
PiecesList::PiecesList(int pieceSize, QWidget *parent)
: QListWidget(parent), m_PieceSize(pieceSize)
{
setDragEnabled(true);
setViewMode(QListView::IconMode);
setIconSize(QSize(m_PieceSize, m_PieceSize));
setSpacing(10);
setAcceptDrops(true);
setDropIndicatorShown(true);
}
void PiecesList::dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasFormat(PiecesList::puzzleMimeType()))
event->accept();
else
event->ignore();
}
void PiecesList::dragMoveEvent(QDragMoveEvent *event)
{
if (event->mimeData()->hasFormat(PiecesList::puzzleMimeType())) {
event->setDropAction(Qt::MoveAction);
event->accept();
} else {
event->ignore();
}
}
void PiecesList::dropEvent(QDropEvent *event)
{
if (event->mimeData()->hasFormat(PiecesList::puzzleMimeType())) {
QByteArray pieceData = event->mimeData()->data(PiecesList::puzzleMimeType());
QDataStream dataStream(&pieceData, QIODevice::ReadOnly);
QPixmap pixmap;
QPoint location;
dataStream >> pixmap >> location;
addPiece(pixmap, location);
event->setDropAction(Qt::MoveAction);
event->accept();
} else {
event->ignore();
}
}
void PiecesList::addPiece(const QPixmap &pixmap, const QPoint &location)
{
QListWidgetItem *pieceItem = new QListWidgetItem(this);
pieceItem->setIcon(QIcon(pixmap));
pieceItem->setData(Qt::UserRole, QVariant(pixmap));
pieceItem->setData(Qt::UserRole+1, location);
pieceItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled);
}
void PiecesList::startDrag(Qt::DropActions /*supportedActions*/)
{
QListWidgetItem *item = currentItem();
QByteArray itemData;
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
QPixmap pixmap = qvariant_cast<QPixmap>(item->data(Qt::UserRole));
QPoint location = item->data(Qt::UserRole+1).toPoint();
dataStream << pixmap << location;
QMimeData *mimeData = new QMimeData;
mimeData->setData(PiecesList::puzzleMimeType(), itemData);
QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->setHotSpot(QPoint(pixmap.width()/2, pixmap.height()/2));
drag->setPixmap(pixmap);
if (drag->exec(Qt::MoveAction) == Qt::MoveAction)
delete takeItem(row(item));
}

View File

@ -0,0 +1,28 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef PIECESLIST_H
#define PIECESLIST_H
#include <QListWidget>
class PiecesList : public QListWidget
{
Q_OBJECT
public:
explicit PiecesList(int pieceSize, QWidget *parent = nullptr);
void addPiece(const QPixmap &pixmap, const QPoint &location);
static QString puzzleMimeType() { return QStringLiteral("image/x-puzzle-piece"); }
protected:
void dragEnterEvent(QDragEnterEvent *event) override;
void dragMoveEvent(QDragMoveEvent *event) override;
void dropEvent(QDropEvent *event) override;
void startDrag(Qt::DropActions supportedActions) override;
int m_PieceSize;
};
#endif // PIECESLIST_H

View File

@ -0,0 +1,17 @@
QT += widgets
requires(qtConfig(filedialog))
HEADERS = mainwindow.h \
pieceslist.h \
puzzlewidget.h
RESOURCES = puzzle.qrc
SOURCES = main.cpp \
mainwindow.cpp \
pieceslist.cpp \
puzzlewidget.cpp
QMAKE_PROJECT_NAME = dndpuzzle
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/draganddrop/puzzle
INSTALLS += target

View File

@ -0,0 +1,5 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/images">
<file>example.jpg</file>
</qresource>
</RCC>

View File

@ -0,0 +1,167 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "puzzlewidget.h"
#include "pieceslist.h"
#include <QDrag>
#include <QDragEnterEvent>
#include <QMimeData>
#include <QPainter>
PuzzleWidget::PuzzleWidget(int imageSize, QWidget *parent)
: QWidget(parent), m_ImageSize(imageSize)
{
setAcceptDrops(true);
setMinimumSize(m_ImageSize, m_ImageSize);
setMaximumSize(m_ImageSize, m_ImageSize);
}
void PuzzleWidget::clear()
{
pieces.clear();
highlightedRect = QRect();
inPlace = 0;
update();
}
void PuzzleWidget::dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasFormat(PiecesList::puzzleMimeType()))
event->accept();
else
event->ignore();
}
void PuzzleWidget::dragLeaveEvent(QDragLeaveEvent *event)
{
QRect updateRect = highlightedRect;
highlightedRect = QRect();
update(updateRect);
event->accept();
}
void PuzzleWidget::dragMoveEvent(QDragMoveEvent *event)
{
QRect updateRect = highlightedRect.united(targetSquare(event->position().toPoint()));
if (event->mimeData()->hasFormat(PiecesList::puzzleMimeType())
&& findPiece(targetSquare(event->position().toPoint())) == -1) {
highlightedRect = targetSquare(event->position().toPoint());
event->setDropAction(Qt::MoveAction);
event->accept();
} else {
highlightedRect = QRect();
event->ignore();
}
update(updateRect);
}
void PuzzleWidget::dropEvent(QDropEvent *event)
{
if (event->mimeData()->hasFormat(PiecesList::puzzleMimeType())
&& findPiece(targetSquare(event->position().toPoint())) == -1) {
QByteArray pieceData = event->mimeData()->data(PiecesList::puzzleMimeType());
QDataStream dataStream(&pieceData, QIODevice::ReadOnly);
Piece piece;
piece.rect = targetSquare(event->position().toPoint());
dataStream >> piece.pixmap >> piece.location;
pieces.append(piece);
highlightedRect = QRect();
update(piece.rect);
event->setDropAction(Qt::MoveAction);
event->accept();
if (piece.location == piece.rect.topLeft() / pieceSize()) {
inPlace++;
if (inPlace == 25)
emit puzzleCompleted();
}
} else {
highlightedRect = QRect();
event->ignore();
}
}
int PuzzleWidget::findPiece(const QRect &pieceRect) const
{
for (int i = 0, size = pieces.size(); i < size; ++i) {
if (pieces.at(i).rect == pieceRect)
return i;
}
return -1;
}
void PuzzleWidget::mousePressEvent(QMouseEvent *event)
{
QRect square = targetSquare(event->position().toPoint());
const int found = findPiece(square);
if (found == -1)
return;
Piece piece = pieces.takeAt(found);
if (piece.location == square.topLeft() / pieceSize())
inPlace--;
update(square);
QByteArray itemData;
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
dataStream << piece.pixmap << piece.location;
QMimeData *mimeData = new QMimeData;
mimeData->setData(PiecesList::puzzleMimeType(), itemData);
QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->setHotSpot(event->position().toPoint() - square.topLeft());
drag->setPixmap(piece.pixmap);
if (drag->exec(Qt::MoveAction) != Qt::MoveAction) {
pieces.insert(found, piece);
update(targetSquare(event->position().toPoint()));
if (piece.location == square.topLeft() / pieceSize())
inPlace++;
}
}
void PuzzleWidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.fillRect(event->rect(), Qt::white);
if (highlightedRect.isValid()) {
painter.setBrush(QColor("#ffcccc"));
painter.setPen(Qt::NoPen);
painter.drawRect(highlightedRect.adjusted(0, 0, -1, -1));
}
for (const Piece &piece : pieces)
painter.drawPixmap(piece.rect, piece.pixmap);
}
const QRect PuzzleWidget::targetSquare(const QPoint &position) const
{
QPoint topLeft = QPoint(position.x() / pieceSize(), position.y() / pieceSize()) * pieceSize();
return QRect(topLeft, QSize(pieceSize(), pieceSize()));
}
int PuzzleWidget::pieceSize() const
{
return m_ImageSize / 5;
}
int PuzzleWidget::imageSize() const
{
return m_ImageSize;
}

View File

@ -0,0 +1,56 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef PUZZLEWIDGET_H
#define PUZZLEWIDGET_H
#include <QPoint>
#include <QPixmap>
#include <QList>
#include <QWidget>
QT_BEGIN_NAMESPACE
class QDragEnterEvent;
class QDropEvent;
class QMouseEvent;
QT_END_NAMESPACE
class PuzzleWidget : public QWidget
{
Q_OBJECT
public:
explicit PuzzleWidget(int imageSize, QWidget *parent = nullptr);
void clear();
int pieceSize() const;
int imageSize() const;
signals:
void puzzleCompleted();
protected:
void dragEnterEvent(QDragEnterEvent *event) override;
void dragLeaveEvent(QDragLeaveEvent *event) override;
void dragMoveEvent(QDragMoveEvent *event) override;
void dropEvent(QDropEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void paintEvent(QPaintEvent *event) override;
private:
struct Piece {
QPixmap pixmap;
QRect rect;
QPoint location;
};
int findPiece(const QRect &pieceRect) const;
const QRect targetSquare(const QPoint &position) const;
QList<Piece> pieces;
QRect highlightedRect;
int inPlace;
int m_ImageSize;
};
#endif // PUZZLEWIDGET_H