summaryrefslogtreecommitdiffstats
path: root/examples/widgets/itemviews/puzzle
diff options
context:
space:
mode:
Diffstat (limited to 'examples/widgets/itemviews/puzzle')
-rw-r--r--examples/widgets/itemviews/puzzle/example.jpgbin0 -> 42654 bytes
-rw-r--r--examples/widgets/itemviews/puzzle/main.cpp54
-rw-r--r--examples/widgets/itemviews/puzzle/mainwindow.cpp149
-rw-r--r--examples/widgets/itemviews/puzzle/mainwindow.h77
-rw-r--r--examples/widgets/itemviews/puzzle/piecesmodel.cpp203
-rw-r--r--examples/widgets/itemviews/puzzle/piecesmodel.h82
-rw-r--r--examples/widgets/itemviews/puzzle/puzzle.desktop11
-rw-r--r--examples/widgets/itemviews/puzzle/puzzle.pro22
-rw-r--r--examples/widgets/itemviews/puzzle/puzzle.qrc5
-rw-r--r--examples/widgets/itemviews/puzzle/puzzlewidget.cpp214
-rw-r--r--examples/widgets/itemviews/puzzle/puzzlewidget.h89
11 files changed, 906 insertions, 0 deletions
diff --git a/examples/widgets/itemviews/puzzle/example.jpg b/examples/widgets/itemviews/puzzle/example.jpg
new file mode 100644
index 0000000000..e09fb70757
--- /dev/null
+++ b/examples/widgets/itemviews/puzzle/example.jpg
Binary files differ
diff --git a/examples/widgets/itemviews/puzzle/main.cpp b/examples/widgets/itemviews/puzzle/main.cpp
new file mode 100644
index 0000000000..31b7142819
--- /dev/null
+++ b/examples/widgets/itemviews/puzzle/main.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 Nokia Corporation and its Subsidiary(-ies) 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 <QApplication>
+
+#include "mainwindow.h"
+
+int main(int argc, char *argv[])
+{
+ Q_INIT_RESOURCE(puzzle);
+
+ QApplication app(argc, argv);
+ MainWindow window;
+ window.openImage(":/images/example.jpg");
+ window.show();
+ return app.exec();
+}
diff --git a/examples/widgets/itemviews/puzzle/mainwindow.cpp b/examples/widgets/itemviews/puzzle/mainwindow.cpp
new file mode 100644
index 0000000000..4b9b10946a
--- /dev/null
+++ b/examples/widgets/itemviews/puzzle/mainwindow.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 Nokia Corporation and its Subsidiary(-ies) 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 <QtWidgets>
+#include <stdlib.h>
+
+#include "mainwindow.h"
+#include "piecesmodel.h"
+#include "puzzlewidget.h"
+
+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 &path)
+{
+ QString fileName = path;
+
+ if (fileName.isNull())
+ fileName = QFileDialog::getOpenFileName(this,
+ tr("Open Image"), "", tr("Image Files (*.png *.jpg *.bmp)"));
+
+ if (!fileName.isEmpty()) {
+ QPixmap newImage;
+ if (!newImage.load(fileName)) {
+ QMessageBox::warning(this, tr("Open Image"),
+ tr("The image file could not be loaded."),
+ QMessageBox::Cancel);
+ 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);
+
+ qsrand(QCursor::pos().x() ^ QCursor::pos().y());
+
+ model->addPieces(puzzleImage);
+ puzzleWidget->clear();
+}
+
+void MainWindow::setupMenus()
+{
+ QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
+
+ QAction *openAction = fileMenu->addAction(tr("&Open..."));
+ openAction->setShortcuts(QKeySequence::Open);
+
+ QAction *exitAction = fileMenu->addAction(tr("E&xit"));
+ exitAction->setShortcuts(QKeySequence::Quit);
+
+ QMenu *gameMenu = menuBar()->addMenu(tr("&Game"));
+
+ QAction *restartAction = gameMenu->addAction(tr("&Restart"));
+
+ connect(openAction, SIGNAL(triggered()), this, SLOT(openImage()));
+ connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
+ connect(restartAction, SIGNAL(triggered()), this, SLOT(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, SIGNAL(puzzleCompleted()),
+ this, SLOT(setCompleted()), Qt::QueuedConnection);
+
+ frameLayout->addWidget(piecesList);
+ frameLayout->addWidget(puzzleWidget);
+ setCentralWidget(frame);
+}
diff --git a/examples/widgets/itemviews/puzzle/mainwindow.h b/examples/widgets/itemviews/puzzle/mainwindow.h
new file mode 100644
index 0000000000..83704d9932
--- /dev/null
+++ b/examples/widgets/itemviews/puzzle/mainwindow.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 Nokia Corporation and its Subsidiary(-ies) 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$
+**
+****************************************************************************/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QPixmap>
+#include <QMainWindow>
+
+class PuzzleWidget;
+class PiecesModel;
+QT_BEGIN_NAMESPACE
+class QListView;
+QT_END_NAMESPACE
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ MainWindow(QWidget *parent = 0);
+
+public slots:
+ void openImage(const QString &path = QString());
+ void setupPuzzle();
+
+private slots:
+ void setCompleted();
+
+private:
+ void setupMenus();
+ void setupWidgets();
+
+ QPixmap puzzleImage;
+ QListView *piecesList;
+ PuzzleWidget *puzzleWidget;
+ PiecesModel *model;
+};
+
+#endif
diff --git a/examples/widgets/itemviews/puzzle/piecesmodel.cpp b/examples/widgets/itemviews/puzzle/piecesmodel.cpp
new file mode 100644
index 0000000000..68574606e2
--- /dev/null
+++ b/examples/widgets/itemviews/puzzle/piecesmodel.cpp
@@ -0,0 +1,203 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 Nokia Corporation and its Subsidiary(-ies) 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 <QtWidgets>
+
+#include "piecesmodel.h"
+
+PiecesModel::PiecesModel(int pieceSize, QObject *parent)
+ : QAbstractListModel(parent), m_PieceSize(pieceSize)
+{
+}
+
+QVariant PiecesModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid())
+ return QVariant();
+
+ if (role == Qt::DecorationRole)
+ return QIcon(pixmaps.value(index.row()).scaled(m_PieceSize, m_PieceSize,
+ Qt::KeepAspectRatio, Qt::SmoothTransformation));
+ else if (role == Qt::UserRole)
+ return pixmaps.value(index.row());
+ else if (role == Qt::UserRole + 1)
+ return locations.value(index.row());
+
+ return QVariant();
+}
+
+void PiecesModel::addPiece(const QPixmap &pixmap, const QPoint &location)
+{
+ int row;
+ if (int(2.0*qrand()/(RAND_MAX+1.0)) == 1)
+ row = 0;
+ else
+ row = pixmaps.size();
+
+ beginInsertRows(QModelIndex(), row, row);
+ pixmaps.insert(row, pixmap);
+ locations.insert(row, location);
+ endInsertRows();
+}
+
+Qt::ItemFlags PiecesModel::flags(const QModelIndex &index) const
+{
+ if (index.isValid())
+ return (Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled);
+
+ return Qt::ItemIsDropEnabled;
+}
+
+bool PiecesModel::removeRows(int row, int count, const QModelIndex &parent)
+{
+ if (parent.isValid())
+ return false;
+
+ if (row >= pixmaps.size() || row + count <= 0)
+ return false;
+
+ int beginRow = qMax(0, row);
+ int endRow = qMin(row + count - 1, pixmaps.size() - 1);
+
+ beginRemoveRows(parent, beginRow, endRow);
+
+ while (beginRow <= endRow) {
+ pixmaps.removeAt(beginRow);
+ locations.removeAt(beginRow);
+ ++beginRow;
+ }
+
+ endRemoveRows();
+ return true;
+}
+
+QStringList PiecesModel::mimeTypes() const
+{
+ QStringList types;
+ types << "image/x-puzzle-piece";
+ return types;
+}
+
+QMimeData *PiecesModel::mimeData(const QModelIndexList &indexes) const
+{
+ QMimeData *mimeData = new QMimeData();
+ QByteArray encodedData;
+
+ QDataStream stream(&encodedData, QIODevice::WriteOnly);
+
+ foreach (QModelIndex index, indexes) {
+ if (index.isValid()) {
+ QPixmap pixmap = qvariant_cast<QPixmap>(data(index, Qt::UserRole));
+ QPoint location = data(index, Qt::UserRole+1).toPoint();
+ stream << pixmap << location;
+ }
+ }
+
+ mimeData->setData("image/x-puzzle-piece", encodedData);
+ return mimeData;
+}
+
+bool PiecesModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
+ int row, int column, const QModelIndex &parent)
+{
+ if (!data->hasFormat("image/x-puzzle-piece"))
+ return false;
+
+ if (action == Qt::IgnoreAction)
+ return true;
+
+ if (column > 0)
+ return false;
+
+ int endRow;
+
+ if (!parent.isValid()) {
+ if (row < 0)
+ endRow = pixmaps.size();
+ else
+ endRow = qMin(row, pixmaps.size());
+ } else
+ endRow = parent.row();
+
+ QByteArray encodedData = data->data("image/x-puzzle-piece");
+ QDataStream stream(&encodedData, QIODevice::ReadOnly);
+
+ while (!stream.atEnd()) {
+ QPixmap pixmap;
+ QPoint location;
+ stream >> pixmap >> location;
+
+ beginInsertRows(QModelIndex(), endRow, endRow);
+ pixmaps.insert(endRow, pixmap);
+ locations.insert(endRow, location);
+ endInsertRows();
+
+ ++endRow;
+ }
+
+ return true;
+}
+
+int PiecesModel::rowCount(const QModelIndex &parent) const
+{
+ if (parent.isValid())
+ return 0;
+ else
+ return pixmaps.size();
+}
+
+Qt::DropActions PiecesModel::supportedDropActions() const
+{
+ return Qt::CopyAction | Qt::MoveAction;
+}
+
+void PiecesModel::addPieces(const QPixmap& pixmap)
+{
+ beginRemoveRows(QModelIndex(), 0, 24);
+ pixmaps.clear();
+ locations.clear();
+ endRemoveRows();
+ for (int y = 0; y < 5; ++y) {
+ for (int x = 0; x < 5; ++x) {
+ QPixmap pieceImage = pixmap.copy(x*m_PieceSize, y*m_PieceSize, m_PieceSize, m_PieceSize);
+ addPiece(pieceImage, QPoint(x, y));
+ }
+ }
+}
diff --git a/examples/widgets/itemviews/puzzle/piecesmodel.h b/examples/widgets/itemviews/puzzle/piecesmodel.h
new file mode 100644
index 0000000000..e8fa45a9a0
--- /dev/null
+++ b/examples/widgets/itemviews/puzzle/piecesmodel.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 Nokia Corporation and its Subsidiary(-ies) 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$
+**
+****************************************************************************/
+
+#ifndef PIECESLIST_H
+#define PIECESLIST_H
+
+#include <QAbstractListModel>
+#include <QList>
+#include <QPixmap>
+#include <QPoint>
+#include <QStringList>
+
+QT_BEGIN_NAMESPACE
+class QMimeData;
+QT_END_NAMESPACE
+
+class PiecesModel : public QAbstractListModel
+{
+ Q_OBJECT
+
+public:
+ PiecesModel(int pieceSize, QObject *parent = 0);
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+ bool removeRows(int row, int count, const QModelIndex &parent);
+
+ bool dropMimeData(const QMimeData *data, Qt::DropAction action,
+ int row, int column, const QModelIndex &parent);
+ QMimeData *mimeData(const QModelIndexList &indexes) const;
+ QStringList mimeTypes() const;
+ int rowCount(const QModelIndex &parent) const;
+ Qt::DropActions supportedDropActions() const;
+
+ void addPiece(const QPixmap &pixmap, const QPoint &location);
+ void addPieces(const QPixmap& pixmap);
+
+private:
+ QList<QPoint> locations;
+ QList<QPixmap> pixmaps;
+
+ int m_PieceSize;
+};
+
+#endif
diff --git a/examples/widgets/itemviews/puzzle/puzzle.desktop b/examples/widgets/itemviews/puzzle/puzzle.desktop
new file mode 100644
index 0000000000..d493e7dd41
--- /dev/null
+++ b/examples/widgets/itemviews/puzzle/puzzle.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Name=Item Views Puzzle
+Exec=/opt/usr/bin/puzzle
+Icon=puzzle
+X-Window-Icon=
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
diff --git a/examples/widgets/itemviews/puzzle/puzzle.pro b/examples/widgets/itemviews/puzzle/puzzle.pro
new file mode 100644
index 0000000000..3f76bd8fd5
--- /dev/null
+++ b/examples/widgets/itemviews/puzzle/puzzle.pro
@@ -0,0 +1,22 @@
+HEADERS = mainwindow.h \
+ piecesmodel.h \
+ puzzlewidget.h
+RESOURCES = puzzle.qrc
+SOURCES = main.cpp \
+ mainwindow.cpp \
+ piecesmodel.cpp \
+ puzzlewidget.cpp
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/itemviews/puzzle
+sources.files = $$SOURCES $$HEADERS $$RESOURCES *.pro *.jpg
+sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/itemviews/puzzle
+INSTALLS += target sources
+
+
+wince* {
+ DEPLOYMENT_PLUGIN += qjpeg qgif
+}
+
+QT += widgets
+
diff --git a/examples/widgets/itemviews/puzzle/puzzle.qrc b/examples/widgets/itemviews/puzzle/puzzle.qrc
new file mode 100644
index 0000000000..4076cec026
--- /dev/null
+++ b/examples/widgets/itemviews/puzzle/puzzle.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/images">
+ <file>example.jpg</file>
+</qresource>
+</RCC>
diff --git a/examples/widgets/itemviews/puzzle/puzzlewidget.cpp b/examples/widgets/itemviews/puzzle/puzzlewidget.cpp
new file mode 100644
index 0000000000..96d8c6068f
--- /dev/null
+++ b/examples/widgets/itemviews/puzzle/puzzlewidget.cpp
@@ -0,0 +1,214 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 Nokia Corporation and its Subsidiary(-ies) 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 <QtWidgets>
+
+#include "puzzlewidget.h"
+
+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()
+{
+ pieceLocations.clear();
+ piecePixmaps.clear();
+ pieceRects.clear();
+ highlightedRect = QRect();
+ inPlace = 0;
+ update();
+}
+
+void PuzzleWidget::dragEnterEvent(QDragEnterEvent *event)
+{
+ if (event->mimeData()->hasFormat("image/x-puzzle-piece"))
+ 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->pos()));
+
+ if (event->mimeData()->hasFormat("image/x-puzzle-piece")
+ && findPiece(targetSquare(event->pos())) == -1) {
+
+ highlightedRect = targetSquare(event->pos());
+ event->setDropAction(Qt::MoveAction);
+ event->accept();
+ } else {
+ highlightedRect = QRect();
+ event->ignore();
+ }
+
+ update(updateRect);
+}
+
+void PuzzleWidget::dropEvent(QDropEvent *event)
+{
+ if (event->mimeData()->hasFormat("image/x-puzzle-piece")
+ && findPiece(targetSquare(event->pos())) == -1) {
+
+ QByteArray pieceData = event->mimeData()->data("image/x-puzzle-piece");
+ QDataStream stream(&pieceData, QIODevice::ReadOnly);
+ QRect square = targetSquare(event->pos());
+ QPixmap pixmap;
+ QPoint location;
+ stream >> pixmap >> location;
+
+ pieceLocations.append(location);
+ piecePixmaps.append(pixmap);
+ pieceRects.append(square);
+
+ highlightedRect = QRect();
+ update(square);
+
+ event->setDropAction(Qt::MoveAction);
+ event->accept();
+
+ if (location == QPoint(square.x()/pieceSize(), square.y()/pieceSize())) {
+ inPlace++;
+ if (inPlace == 25)
+ emit puzzleCompleted();
+ }
+ } else {
+ highlightedRect = QRect();
+ event->ignore();
+ }
+}
+
+int PuzzleWidget::findPiece(const QRect &pieceRect) const
+{
+ for (int i = 0; i < pieceRects.size(); ++i) {
+ if (pieceRect == pieceRects[i]) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+void PuzzleWidget::mousePressEvent(QMouseEvent *event)
+{
+ QRect square = targetSquare(event->pos());
+ int found = findPiece(square);
+
+ if (found == -1)
+ return;
+
+ QPoint location = pieceLocations[found];
+ QPixmap pixmap = piecePixmaps[found];
+ pieceLocations.removeAt(found);
+ piecePixmaps.removeAt(found);
+ pieceRects.removeAt(found);
+
+ if (location == QPoint(square.x()/pieceSize(), square.y()/pieceSize()))
+ inPlace--;
+
+ update(square);
+
+ QByteArray itemData;
+ QDataStream dataStream(&itemData, QIODevice::WriteOnly);
+
+ dataStream << pixmap << location;
+
+ QMimeData *mimeData = new QMimeData;
+ mimeData->setData("image/x-puzzle-piece", itemData);
+
+ QDrag *drag = new QDrag(this);
+ drag->setMimeData(mimeData);
+ drag->setHotSpot(event->pos() - square.topLeft());
+ drag->setPixmap(pixmap);
+
+ if (drag->start(Qt::MoveAction) == 0) {
+ pieceLocations.insert(found, location);
+ piecePixmaps.insert(found, pixmap);
+ pieceRects.insert(found, square);
+ update(targetSquare(event->pos()));
+
+ if (location == QPoint(square.x()/pieceSize(), square.y()/pieceSize()))
+ inPlace++;
+ }
+}
+
+void PuzzleWidget::paintEvent(QPaintEvent *event)
+{
+ QPainter painter;
+ painter.begin(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 (int i = 0; i < pieceRects.size(); ++i) {
+ painter.drawPixmap(pieceRects[i], piecePixmaps[i]);
+ }
+ painter.end();
+}
+
+const QRect PuzzleWidget::targetSquare(const QPoint &position) const
+{
+ return QRect(position.x()/pieceSize() * pieceSize(), position.y()/pieceSize() * pieceSize(), pieceSize(), pieceSize());
+}
+
+int PuzzleWidget::pieceSize() const
+{
+ return m_ImageSize / 5;
+}
+
+int PuzzleWidget::imageSize() const
+{
+ return m_ImageSize;
+}
diff --git a/examples/widgets/itemviews/puzzle/puzzlewidget.h b/examples/widgets/itemviews/puzzle/puzzlewidget.h
new file mode 100644
index 0000000000..1c0fc77a5f
--- /dev/null
+++ b/examples/widgets/itemviews/puzzle/puzzlewidget.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 Nokia Corporation and its Subsidiary(-ies) 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$
+**
+****************************************************************************/
+
+#ifndef PUZZLEWIDGET_H
+#define PUZZLEWIDGET_H
+
+#include <QList>
+#include <QPoint>
+#include <QPixmap>
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+class QDragEnterEvent;
+class QDropEvent;
+class QMouseEvent;
+QT_END_NAMESPACE
+
+class PuzzleWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ PuzzleWidget(int imageSize, QWidget *parent = 0);
+ void clear();
+
+ int pieceSize() const;
+ int imageSize() const;
+
+signals:
+ void puzzleCompleted();
+
+protected:
+ void dragEnterEvent(QDragEnterEvent *event);
+ void dragLeaveEvent(QDragLeaveEvent *event);
+ void dragMoveEvent(QDragMoveEvent *event);
+ void dropEvent(QDropEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void paintEvent(QPaintEvent *event);
+
+private:
+ int findPiece(const QRect &pieceRect) const;
+ const QRect targetSquare(const QPoint &position) const;
+
+ QList<QPixmap> piecePixmaps;
+ QList<QRect> pieceRects;
+ QList<QPoint> pieceLocations;
+ QRect highlightedRect;
+ int inPlace;
+ int m_ImageSize;
+};
+
+#endif