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,50 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(fridgemagnets LANGUAGES CXX)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/draganddrop/fridgemagnets")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
qt_standard_project_setup()
qt_add_executable(fridgemagnets
draglabel.cpp draglabel.h
dragwidget.cpp dragwidget.h
main.cpp
)
set_target_properties(fridgemagnets PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
target_link_libraries(fridgemagnets PRIVATE
Qt6::Core
Qt6::Gui
Qt6::Widgets
)
# Resources:
set(fridgemagnets_resource_files
"words.txt"
)
qt_add_resources(fridgemagnets "fridgemagnets"
PREFIX
"/dictionary"
FILES
${fridgemagnets_resource_files}
)
install(TARGETS fridgemagnets
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

View File

@ -0,0 +1,51 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "draglabel.h"
#include <QtWidgets>
//! [0]
DragLabel::DragLabel(const QString &text, QWidget *parent)
: QLabel(parent)
{
QFontMetrics metric(font());
QSize size = metric.size(Qt::TextSingleLine, text);
QImage image(size.width() + 12, size.height() + 12, QImage::Format_ARGB32_Premultiplied);
image.fill(qRgba(0, 0, 0, 0));
QFont font;
font.setStyleStrategy(QFont::ForceOutline);
//! [0]
//! [1]
QLinearGradient gradient(0, 0, 0, image.height()-1);
gradient.setColorAt(0.0, Qt::white);
gradient.setColorAt(0.2, QColor(200, 200, 255));
gradient.setColorAt(0.8, QColor(200, 200, 255));
gradient.setColorAt(1.0, QColor(127, 127, 200));
QPainter painter;
painter.begin(&image);
painter.setRenderHint(QPainter::Antialiasing);
painter.setBrush(gradient);
painter.drawRoundedRect(QRectF(0.5, 0.5, image.width()-1, image.height()-1),
25, 25, Qt::RelativeSize);
painter.setFont(font);
painter.setBrush(Qt::black);
painter.drawText(QRect(QPoint(6, 6), size), Qt::AlignCenter, text);
painter.end();
//! [1]
//! [2]
setPixmap(QPixmap::fromImage(image));
m_labelText = text;
}
//! [2]
QString DragLabel::labelText() const
{
return m_labelText;
}

View File

@ -0,0 +1,27 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef DRAGLABEL_H
#define DRAGLABEL_H
#include <QLabel>
QT_BEGIN_NAMESPACE
class QDragEnterEvent;
class QDragMoveEvent;
class QFrame;
QT_END_NAMESPACE
//! [0]
class DragLabel : public QLabel
{
public:
DragLabel(const QString &text, QWidget *parent);
QString labelText() const;
private:
QString m_labelText;
};
//! [0]
#endif // DRAGLABEL_H

View File

@ -0,0 +1,176 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "draglabel.h"
#include "dragwidget.h"
#include <QtWidgets>
static inline QString fridgetMagnetsMimeType() { return QStringLiteral("application/x-fridgemagnet"); }
//! [0]
DragWidget::DragWidget(QWidget *parent)
: QWidget(parent)
{
QFile dictionaryFile(QStringLiteral(":/dictionary/words.txt"));
dictionaryFile.open(QFile::ReadOnly);
QTextStream inputStream(&dictionaryFile);
//! [0]
//! [1]
int x = 5;
int y = 5;
while (!inputStream.atEnd()) {
QString word;
inputStream >> word;
if (!word.isEmpty()) {
DragLabel *wordLabel = new DragLabel(word, this);
wordLabel->move(x, y);
wordLabel->show();
wordLabel->setAttribute(Qt::WA_DeleteOnClose);
x += wordLabel->width() + 2;
if (x >= 245) {
x = 5;
y += wordLabel->height() + 2;
}
}
}
//! [1]
//! [2]
QPalette newPalette = palette();
newPalette.setColor(QPalette::Window, Qt::white);
setPalette(newPalette);
setMinimumSize(400, qMax(200, y));
setWindowTitle(tr("Fridge Magnets"));
//! [2] //! [3]
setAcceptDrops(true);
}
//! [3]
//! [4]
void DragWidget::dragEnterEvent(QDragEnterEvent *event)
{
//! [4] //! [5]
if (event->mimeData()->hasFormat(fridgetMagnetsMimeType())) {
if (children().contains(event->source())) {
event->setDropAction(Qt::MoveAction);
event->accept();
} else {
event->acceptProposedAction();
//! [5] //! [6]
}
//! [6] //! [7]
} else if (event->mimeData()->hasText()) {
event->acceptProposedAction();
} else {
event->ignore();
}
}
//! [7]
//! [8]
void DragWidget::dragMoveEvent(QDragMoveEvent *event)
{
if (event->mimeData()->hasFormat(fridgetMagnetsMimeType())) {
if (children().contains(event->source())) {
event->setDropAction(Qt::MoveAction);
event->accept();
} else {
event->acceptProposedAction();
}
} else if (event->mimeData()->hasText()) {
event->acceptProposedAction();
} else {
event->ignore();
}
}
//! [8]
//! [9]
void DragWidget::dropEvent(QDropEvent *event)
{
if (event->mimeData()->hasFormat(fridgetMagnetsMimeType())) {
const QMimeData *mime = event->mimeData();
//! [9] //! [10]
QByteArray itemData = mime->data(fridgetMagnetsMimeType());
QDataStream dataStream(&itemData, QIODevice::ReadOnly);
QString text;
QPoint offset;
dataStream >> text >> offset;
//! [10]
//! [11]
DragLabel *newLabel = new DragLabel(text, this);
newLabel->move(event->position().toPoint() - offset);
newLabel->show();
newLabel->setAttribute(Qt::WA_DeleteOnClose);
if (event->source() == this) {
event->setDropAction(Qt::MoveAction);
event->accept();
} else {
event->acceptProposedAction();
}
//! [11] //! [12]
} else if (event->mimeData()->hasText()) {
QStringList pieces = event->mimeData()->text().split(
QRegularExpression(QStringLiteral("\\s+")), Qt::SkipEmptyParts);
QPoint position = event->position().toPoint();
for (const QString &piece : pieces) {
DragLabel *newLabel = new DragLabel(piece, this);
newLabel->move(position);
newLabel->show();
newLabel->setAttribute(Qt::WA_DeleteOnClose);
position += QPoint(newLabel->width(), 0);
}
event->acceptProposedAction();
} else {
event->ignore();
}
}
//! [12]
//! [13]
void DragWidget::mousePressEvent(QMouseEvent *event)
{
//! [13]
//! [14]
DragLabel *child = static_cast<DragLabel*>(childAt(event->position().toPoint()));
if (!child)
return;
QPoint hotSpot = event->position().toPoint() - child->pos();
QByteArray itemData;
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
dataStream << child->labelText() << QPoint(hotSpot);
//! [14]
//! [15]
QMimeData *mimeData = new QMimeData;
mimeData->setData(fridgetMagnetsMimeType(), itemData);
mimeData->setText(child->labelText());
//! [15]
//! [16]
QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->setPixmap(child->pixmap());
drag->setHotSpot(hotSpot);
child->hide();
//! [16]
//! [17]
if (drag->exec(Qt::MoveAction | Qt::CopyAction, Qt::CopyAction) == Qt::MoveAction)
child->close();
else
child->show();
}
//! [17]

View File

@ -0,0 +1,28 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef DRAGWIDGET_H
#define DRAGWIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
class QDragEnterEvent;
class QDropEvent;
QT_END_NAMESPACE
//! [0]
class DragWidget : public QWidget
{
public:
explicit DragWidget(QWidget *parent = nullptr);
protected:
void dragEnterEvent(QDragEnterEvent *event) override;
void dragMoveEvent(QDragMoveEvent *event) override;
void dropEvent(QDropEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
};
//! [0]
#endif // DRAGWIDGET_H

View File

@ -0,0 +1,12 @@
QT += widgets
HEADERS = draglabel.h \
dragwidget.h
RESOURCES = fridgemagnets.qrc
SOURCES = draglabel.cpp \
dragwidget.cpp \
main.cpp
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/draganddrop/fridgemagnets
INSTALLS += target

View File

@ -0,0 +1,5 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/dictionary">
<file>words.txt</file>
</qresource>
</RCC>

View File

@ -0,0 +1,23 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QApplication>
#include "dragwidget.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
#ifdef QT_KEYPAD_NAVIGATION
QApplication::setNavigationMode(Qt::NavigationModeCursorAuto);
#endif
DragWidget window;
bool smallScreen = QApplication::arguments().contains(QStringLiteral("-small-screen"));
if (smallScreen)
window.showFullScreen();
else
window.show();
return app.exec();
}

View File

@ -0,0 +1,48 @@
Colorless
green
ideas
sleep
furiously
A
colorless
green
idea
is
a
new
untried
idea
that
is
without
vividness
dull
and
unexciting
To
sleep
furiously
may
seem
a
puzzling
turn
of
phrase
but
the
mind
in
sleep
often
indeed
moves
furiously
with
ideas
and
images
flickering
in
and
out

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