From 6c35dfc78a94ef27f12e6743fda37c688de35c3c Mon Sep 17 00:00:00 2001 From: Ronan Le Tiec Date: Fri, 8 May 2020 23:49:41 +0200 Subject: [PATCH] Work on layer and graphics view behaviour --- src/app/puzzle/vpiececarrousel.cpp | 4 +- src/app/puzzle/vpiececarrousel.h | 6 +- src/app/puzzle/vpiececarrousellayer.cpp | 69 ++++++++++++++++---- src/app/puzzle/vpiececarrousellayer.h | 21 +++++++ src/app/puzzle/vpiececarrouselpiece.cpp | 12 +++- src/app/puzzle/vpuzzlegraphicslayout.cpp | 5 +- src/app/puzzle/vpuzzlegraphicspiece.cpp | 24 +++++-- src/app/puzzle/vpuzzlegraphicspiece.h | 6 ++ src/app/puzzle/vpuzzlelayer.cpp | 23 ++++++- src/app/puzzle/vpuzzlelayer.h | 28 ++++++++- src/app/puzzle/vpuzzlelayout.cpp | 43 ++++++++++++- src/app/puzzle/vpuzzlelayout.h | 35 ++++++++++- src/app/puzzle/vpuzzlemaingraphicsscene.cpp | 1 - src/app/puzzle/vpuzzlemaingraphicsscene.h | 1 + src/app/puzzle/vpuzzlemaingraphicsview.cpp | 70 ++++++++++++++++----- src/app/puzzle/vpuzzlemaingraphicsview.h | 14 ++++- src/app/puzzle/vpuzzlepiece.cpp | 21 +++++++ src/app/puzzle/vpuzzlepiece.h | 46 +++++++++----- 18 files changed, 363 insertions(+), 66 deletions(-) diff --git a/src/app/puzzle/vpiececarrousel.cpp b/src/app/puzzle/vpiececarrousel.cpp index 991c51100..65e46a410 100644 --- a/src/app/puzzle/vpiececarrousel.cpp +++ b/src/app/puzzle/vpiececarrousel.cpp @@ -93,8 +93,8 @@ void VPieceCarrousel::Init() mainLayout->addWidget(m_scrollArea); // ------ then we fill the carrousel with the layout content - Refresh(); -} + Refresh(); + } //--------------------------------------------------------------------------------------------------------------------- void VPieceCarrousel::Refresh() diff --git a/src/app/puzzle/vpiececarrousel.h b/src/app/puzzle/vpiececarrousel.h index 1459a24a2..a781b8ac2 100644 --- a/src/app/puzzle/vpiececarrousel.h +++ b/src/app/puzzle/vpiececarrousel.h @@ -76,7 +76,6 @@ public: */ void ClearSelection(); - private: Q_DISABLE_COPY(VPieceCarrousel) @@ -92,6 +91,11 @@ private: private slots: + + /** + * @brief on_ActiveLayerChanged Called when the active layer is changed + * @param index + */ void on_ActiveLayerChanged(int index); }; diff --git a/src/app/puzzle/vpiececarrousellayer.cpp b/src/app/puzzle/vpiececarrousellayer.cpp index d7435af52..03cdaab45 100644 --- a/src/app/puzzle/vpiececarrousellayer.cpp +++ b/src/app/puzzle/vpiececarrousellayer.cpp @@ -48,7 +48,7 @@ VPieceCarrouselLayer::VPieceCarrouselLayer(VPuzzleLayer *layer, VPieceCarrousel //--------------------------------------------------------------------------------------------------------------------- VPieceCarrouselLayer::~VPieceCarrouselLayer() { - // TODO + Clear(); } //--------------------------------------------------------------------------------------------------------------------- @@ -61,13 +61,16 @@ void VPieceCarrouselLayer::Init() // then refresh the content Refresh(); + + // add the connections + connect(m_layer, &VPuzzleLayer::PieceAdded, this, &VPieceCarrouselLayer::on_PieceAdded); + connect(m_layer, &VPuzzleLayer::PieceRemoved, this, &VPieceCarrouselLayer::on_PieceRemoved); } //--------------------------------------------------------------------------------------------------------------------- void VPieceCarrouselLayer::Refresh() { - // remove the existing carrousel pieces - // TODO + Clear(); // Updates the carrousel pieces from the pieces list QList pieces = m_layer->GetPieces(); @@ -78,20 +81,33 @@ void VPieceCarrouselLayer::Refresh() // create the corresponding carrousel pieces + bool _isVisible = isVisible(); + setVisible(true); for (auto piece : pieces) { -// qCDebug(pCarrouselLayer, "piece name : %s", piece->GetName().toStdString().c_str()); - VPieceCarrouselPiece *carrouselPiece = new VPieceCarrouselPiece(piece, this); m_carrouselPieces.append(carrouselPiece); layout()->addWidget(carrouselPiece); - - // FIXME? the fitInView inside the refresh of the piece doesn't workd properly. - // only by doing the following I did get it to work: - setVisible(true); - carrouselPiece->CleanPreview(); - setVisible(false); + carrouselPiece->CleanPreview(); // fitInView only works if the widget is displayed. } + setVisible(_isVisible); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPieceCarrouselLayer::Clear() +{ + // Removes and deletes the carrousel pieces from the layer + while (!m_carrouselPieces.isEmpty()) + { + VPieceCarrouselPiece *carrouselPiece = m_carrouselPieces.takeLast(); + + if(carrouselPiece != nullptr) + { + layout()->removeWidget(carrouselPiece); + delete carrouselPiece; + } + } + } //--------------------------------------------------------------------------------------------------------------------- @@ -106,3 +122,34 @@ VPieceCarrousel* VPieceCarrouselLayer::GetCarrousel() return m_carrousel; } +//--------------------------------------------------------------------------------------------------------------------- +VPuzzleLayer* VPieceCarrouselLayer::GetLayer() +{ + return m_layer; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPieceCarrouselLayer::on_PieceAdded(VPuzzlePiece* piece) +{ + Q_UNUSED(piece) + + // TODO/ FIXME: see if we find a solution more efficient refreshing the complete layout everytime. + + Refresh(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPieceCarrouselLayer::on_PieceRemoved(VPuzzlePiece* piece) +{ + for (auto carrouselPiece : m_carrouselPieces) + { + if(carrouselPiece->GetPiece() == piece) + { + m_carrouselPieces.removeAll(carrouselPiece); + layout()->removeWidget(carrouselPiece); + delete carrouselPiece; + + return; + } + } +} diff --git a/src/app/puzzle/vpiececarrousellayer.h b/src/app/puzzle/vpiececarrousellayer.h index 07f59eb2d..4c65455ae 100644 --- a/src/app/puzzle/vpiececarrousellayer.h +++ b/src/app/puzzle/vpiececarrousellayer.h @@ -45,10 +45,21 @@ public: void Init(); void Refresh(); + /** + * @brief Clear it clears the carrousel layer from its pieces + */ + void Clear(); + QList GetCarrouselPieces(); VPieceCarrousel* GetCarrousel(); + /** + * @brief GetPuzzleLayer Returns the corresponding VPuzzleLayer + * @return the VPuzzleLayer + */ + VPuzzleLayer* GetLayer(); + private: Q_DISABLE_COPY(VPieceCarrouselLayer) @@ -58,6 +69,16 @@ private: private slots: + /** + * @brief on_PieceUpdated This slot is called when a piece was added + */ + void on_PieceAdded(VPuzzlePiece* piece); + + /** + * @brief on_PieceUpdated This slot is called when a piece was removed + */ + void on_PieceRemoved(VPuzzlePiece* piece); + }; #endif // VPIECECARROUSELLAYER_H diff --git a/src/app/puzzle/vpiececarrouselpiece.cpp b/src/app/puzzle/vpiececarrouselpiece.cpp index 5ce09a63e..722b5752c 100644 --- a/src/app/puzzle/vpiececarrouselpiece.cpp +++ b/src/app/puzzle/vpiececarrouselpiece.cpp @@ -99,7 +99,6 @@ void VPieceCarrouselPiece::Init() // connect the signals connect(m_piece, &VPuzzlePiece::SelectionChanged, this, &VPieceCarrouselPiece::on_PieceSelectionChanged); - // then refresh the data Refresh(); } @@ -141,6 +140,9 @@ void VPieceCarrouselPiece::Refresh() // set the tooltip setToolTip(m_piece->GetName()); + + // set the selection state correctly. + on_PieceSelectionChanged(); } //--------------------------------------------------------------------------------------------------------------------- @@ -162,8 +164,6 @@ void VPieceCarrouselPiece::on_PieceSelectionChanged() } } - - //--------------------------------------------------------------------------------------------------------------------- void VPieceCarrouselPiece::mousePressEvent(QMouseEvent *event) { @@ -194,6 +194,12 @@ void VPieceCarrouselPiece::mouseMoveEvent(QMouseEvent *event) { return; } + + if(m_piece->GetLayer() != m_piece->GetLayer()->GetLayout()->GetUnplacedPiecesLayer()) + { + return; + } + if((event->pos() - m_dragStart).manhattanLength() < QApplication::startDragDistance()) { return; diff --git a/src/app/puzzle/vpuzzlegraphicslayout.cpp b/src/app/puzzle/vpuzzlegraphicslayout.cpp index 51a4b65dd..00185b9b5 100644 --- a/src/app/puzzle/vpuzzlegraphicslayout.cpp +++ b/src/app/puzzle/vpuzzlegraphicslayout.cpp @@ -31,9 +31,10 @@ //--------------------------------------------------------------------------------------------------------------------- VPuzzleGraphicsLayout::VPuzzleGraphicsLayout(VPuzzleLayout *layout, QGraphicsItem *parent): QGraphicsItem(parent), - m_layout(layout) + m_layout(layout), + m_boundingRect(GetLayoutRect()) { - m_boundingRect = GetLayoutRect(); + } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/app/puzzle/vpuzzlegraphicspiece.cpp b/src/app/puzzle/vpuzzlegraphicspiece.cpp index 6a9060214..26b90e42f 100644 --- a/src/app/puzzle/vpuzzlegraphicspiece.cpp +++ b/src/app/puzzle/vpuzzlegraphicspiece.cpp @@ -90,6 +90,11 @@ void VPuzzleGraphicsPiece::Init() connect(m_piece, &VPuzzlePiece::PositionChanged, this, &VPuzzleGraphicsPiece::on_PiecePositionChanged); } +//--------------------------------------------------------------------------------------------------------------------- +VPuzzlePiece* VPuzzleGraphicsPiece::GetPiece() +{ + return m_piece; +} //--------------------------------------------------------------------------------------------------------------------- QRectF VPuzzleGraphicsPiece::boundingRect() const @@ -120,20 +125,25 @@ void VPuzzleGraphicsPiece::paint(QPainter *painter, const QStyleOptionGraphicsIt Q_UNUSED(option); QPen pen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); - if(isSelected()) - { - pen.setColor(Qt::red); - } - QBrush noBrush(Qt::NoBrush); + QBrush selectionBrush(QColor(255,160,160,60)); painter->setPen(pen); - painter->setBrush(noBrush); + + if(isSelected()) + { + painter->setBrush(selectionBrush); + } + else + { + painter->setBrush(noBrush); + } // paint the cutting line if(!m_cuttingLine.isEmpty()) { painter->drawPath(m_cuttingLine); + painter->setBrush(noBrush); } // paint the seam line @@ -142,6 +152,8 @@ void VPuzzleGraphicsPiece::paint(QPainter *painter, const QStyleOptionGraphicsIt painter->drawPath(m_seamLine); } + painter->setBrush(noBrush); + // paint the grainline if(!m_grainline.isEmpty()) { diff --git a/src/app/puzzle/vpuzzlegraphicspiece.h b/src/app/puzzle/vpuzzlegraphicspiece.h index dd467acfa..a7aebe10b 100644 --- a/src/app/puzzle/vpuzzlegraphicspiece.h +++ b/src/app/puzzle/vpuzzlegraphicspiece.h @@ -41,6 +41,12 @@ public: ~VPuzzleGraphicsPiece(); void Init(); + /** + * @brief GetPiece Returns the piece that corresponds to the graphics piece + * @return the piece + */ + VPuzzlePiece* GetPiece(); + public slots: /** * @brief on_PieceSelectionChanged When the piece selection was changed diff --git a/src/app/puzzle/vpuzzlelayer.cpp b/src/app/puzzle/vpuzzlelayer.cpp index e70e33255..37a8cdec8 100644 --- a/src/app/puzzle/vpuzzlelayer.cpp +++ b/src/app/puzzle/vpuzzlelayer.cpp @@ -27,8 +27,15 @@ *************************************************************************/ #include "vpuzzlelayer.h" +#include "vpuzzlelayout.h" + +#include + +Q_LOGGING_CATEGORY(pLayer, "p.layer") + //--------------------------------------------------------------------------------------------------------------------- -VPuzzleLayer::VPuzzleLayer() +VPuzzleLayer::VPuzzleLayer(VPuzzleLayout *layout): + m_layout(layout) { } @@ -39,6 +46,12 @@ VPuzzleLayer::~VPuzzleLayer() } +//--------------------------------------------------------------------------------------------------------------------- +VPuzzleLayout* VPuzzleLayer::GetLayout() +{ + return m_layout; +} + //--------------------------------------------------------------------------------------------------------------------- QList VPuzzleLayer::GetPieces() { @@ -48,13 +61,21 @@ QList VPuzzleLayer::GetPieces() //--------------------------------------------------------------------------------------------------------------------- void VPuzzleLayer::AddPiece(VPuzzlePiece *piece) { + qCDebug(pLayer(), "piece -- %s -- added to %s", qUtf8Printable(piece->GetName()), qUtf8Printable(this->GetName())); + m_pieces.append(piece); + piece->SetLayer(this); + + emit PieceAdded(piece); } //--------------------------------------------------------------------------------------------------------------------- void VPuzzleLayer::RemovePiece(VPuzzlePiece *piece) { m_pieces.removeAll(piece); + piece->SetLayer(nullptr); + + emit PieceRemoved(piece); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/app/puzzle/vpuzzlelayer.h b/src/app/puzzle/vpuzzlelayer.h index 978393e0d..b35e9d669 100644 --- a/src/app/puzzle/vpuzzlelayer.h +++ b/src/app/puzzle/vpuzzlelayer.h @@ -31,10 +31,13 @@ #include #include "vpuzzlepiece.h" -class VPuzzleLayer +class VPuzzleLayout; + +class VPuzzleLayer : public QObject { + Q_OBJECT public: - VPuzzleLayer(); + VPuzzleLayer(VPuzzleLayout *layout); ~VPuzzleLayer(); QList GetPieces(); @@ -50,10 +53,31 @@ public: void SetIsVisible(bool value); bool GetIsVisible() const; + /** + * @brief GetLayout Returns the layout in which this layer is + * @return the layout of this layer + */ + VPuzzleLayout* GetLayout(); + +signals: + /** + * @brief PieceAdded The signal is emited when a piece was added + */ + void PieceAdded(VPuzzlePiece *piece); + + /** + * @brief PieceRemoved The signal is emited when a piece was removed + */ + void PieceRemoved(VPuzzlePiece *piece); + private: + Q_DISABLE_COPY(VPuzzleLayer) + QString m_name{}; QList m_pieces{}; + VPuzzleLayout *m_layout{nullptr}; + // control bool m_isVisible{true}; diff --git a/src/app/puzzle/vpuzzlelayout.cpp b/src/app/puzzle/vpuzzlelayout.cpp index 51ed0e5ce..9f18a10d7 100644 --- a/src/app/puzzle/vpuzzlelayout.cpp +++ b/src/app/puzzle/vpuzzlelayout.cpp @@ -31,14 +31,17 @@ //--------------------------------------------------------------------------------------------------------------------- VPuzzleLayout::VPuzzleLayout() : - m_unplacedPiecesLayer(new VPuzzleLayer()) + m_unplacedPiecesLayer(new VPuzzleLayer(this)) { m_unplacedPiecesLayer->SetName(QObject::tr("Unplaced pieces")); // create a standard default layer: - VPuzzleLayer *layer = new VPuzzleLayer(); + VPuzzleLayer *layer = new VPuzzleLayer(this); layer->SetName(QObject::tr("Layout")); AddLayer(layer); + + // sets the default active layer + SetFocusedLayer(); } //--------------------------------------------------------------------------------------------------------------------- @@ -57,7 +60,7 @@ VPuzzleLayer* VPuzzleLayout::GetUnplacedPiecesLayer() //--------------------------------------------------------------------------------------------------------------------- VPuzzleLayer* VPuzzleLayout::AddLayer() { - VPuzzleLayer *newLayer = new VPuzzleLayer(); + VPuzzleLayer *newLayer = new VPuzzleLayer(this); m_layers.append(newLayer); return newLayer; } @@ -277,3 +280,37 @@ void VPuzzleLayout::ClearSelection() piece->SetIsSelected(false); } } + +//--------------------------------------------------------------------------------------------------------------------- +void VPuzzleLayout::SetFocusedLayer(VPuzzleLayer* focusedLayer) +{ + if(focusedLayer == nullptr) + { + m_focusedLayer = m_layers.first(); + } + else + { + m_focusedLayer = focusedLayer; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +VPuzzleLayer* VPuzzleLayout::GetFocusedLayer() +{ + return m_focusedLayer; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPuzzleLayout::MovePieceToLayer(VPuzzlePiece* piece, VPuzzleLayer* layer) +{ + VPuzzleLayer* layerBefore = piece->GetLayer(); + + if(layerBefore != nullptr) + { + piece->GetLayer()->RemovePiece(piece); + } + layer->AddPiece(piece); + + // signal, that a piece was moved + emit PieceMovedToLayer(piece, layerBefore,layer); +} diff --git a/src/app/puzzle/vpuzzlelayout.h b/src/app/puzzle/vpuzzlelayout.h index a057b7c62..26ab1da3f 100644 --- a/src/app/puzzle/vpuzzlelayout.h +++ b/src/app/puzzle/vpuzzlelayout.h @@ -40,8 +40,9 @@ class VPuzzlePiece; // is this the right place for the definition? enum class FollowGrainline : qint8 { No = 0, Follow90 = 1, Follow180 = 2}; -class VPuzzleLayout +class VPuzzleLayout : public QObject { + Q_OBJECT public: VPuzzleLayout(); virtual ~VPuzzleLayout(); @@ -200,11 +201,43 @@ public: */ void ClearSelection(); + /** + * @brief SetFocusedLayer Sets the focused layer, to which pieces are added from the carrousel via drag + * and drop + * @param focusedLayer the new active layer. If nullptr, then it sets automaticaly the first layer from m_layers + */ + void SetFocusedLayer(VPuzzleLayer* focusedLayer = nullptr); + + /** + * @brief GetFocusedLayer Returns the focused layer, to which pieces are added from the carrousel via drag + * and drop + * @return the focused layer + */ + VPuzzleLayer* GetFocusedLayer(); + + /** + * @brief MovePieceToLayer Moves the given piece to the given layer + * @param piece the piece to move + * @param layer the layer to move the piece to + */ + void MovePieceToLayer(VPuzzlePiece* piece, VPuzzleLayer* layer); + +signals: + + void PieceMovedToLayer(VPuzzlePiece *piece, VPuzzleLayer *layerBefore, VPuzzleLayer *layerAfter); + private: Q_DISABLE_COPY(VPuzzleLayout) + VPuzzleLayer *m_unplacedPiecesLayer; QList m_layers{}; + /** + * @brief m_focusedLayer pointer the the focused layer, to which pieces will be + * added via drag and drop, or if no layer is defined. + */ + VPuzzleLayer *m_focusedLayer{nullptr}; + // format Unit m_unit{Unit::Cm}; /** diff --git a/src/app/puzzle/vpuzzlemaingraphicsscene.cpp b/src/app/puzzle/vpuzzlemaingraphicsscene.cpp index 37c75557e..5a4d1d17f 100644 --- a/src/app/puzzle/vpuzzlemaingraphicsscene.cpp +++ b/src/app/puzzle/vpuzzlemaingraphicsscene.cpp @@ -28,7 +28,6 @@ #include "vpuzzlemaingraphicsscene.h" - //--------------------------------------------------------------------------------------------------------------------- VPuzzleMainGraphicsScene::VPuzzleMainGraphicsScene(QObject *parent): QGraphicsScene(parent) { diff --git a/src/app/puzzle/vpuzzlemaingraphicsscene.h b/src/app/puzzle/vpuzzlemaingraphicsscene.h index 7fae7da73..199ed0e8f 100644 --- a/src/app/puzzle/vpuzzlemaingraphicsscene.h +++ b/src/app/puzzle/vpuzzlemaingraphicsscene.h @@ -38,6 +38,7 @@ class VPuzzleMainGraphicsScene : public QGraphicsScene Q_OBJECT public: VPuzzleMainGraphicsScene(QObject *parent = nullptr); + }; #endif // VPUZZLEMAINGRAPHICSSCENE_H diff --git a/src/app/puzzle/vpuzzlemaingraphicsview.cpp b/src/app/puzzle/vpuzzlemaingraphicsview.cpp index bf620cb9f..75d68e14f 100644 --- a/src/app/puzzle/vpuzzlemaingraphicsview.cpp +++ b/src/app/puzzle/vpuzzlemaingraphicsview.cpp @@ -30,8 +30,10 @@ #include #include +#include #include "vpuzzlemimedatapiece.h" +#include "vpuzzlelayer.h" #include @@ -41,6 +43,7 @@ Q_LOGGING_CATEGORY(pMainGraphicsView, "p.mainGraphicsView") //--------------------------------------------------------------------------------------------------------------------- VPuzzleMainGraphicsView::VPuzzleMainGraphicsView(VPuzzleLayout *layout, QWidget *parent) : QGraphicsView(parent), + m_layout(layout), m_graphicsPieces(QList()) { m_scene = new VPuzzleMainGraphicsScene(this); @@ -53,6 +56,9 @@ VPuzzleMainGraphicsView::VPuzzleMainGraphicsView(VPuzzleLayout *layout, QWidget setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); setAcceptDrops(true); + + // add the connections + connect(m_layout, &VPuzzleLayout::PieceMovedToLayer, this, &VPuzzleMainGraphicsView::on_PieceMovedToLayer); } //--------------------------------------------------------------------------------------------------------------------- @@ -119,30 +125,66 @@ void VPuzzleMainGraphicsView::dropEvent(QDropEvent *event) qCDebug(pMainGraphicsView(), "element dropped, %s", qUtf8Printable(piece->GetName())); event->acceptProposedAction(); - QPoint point = event->pos(); - QPointF scenePos = mapToScene(point); - // todo take the position into account - - AddPiece(piece, scenePos); + piece->SetPosition(mapToScene(point)); + // change the layer of the piece + VPuzzleLayer *focusedLayer = m_layout->GetFocusedLayer(); + if(focusedLayer != nullptr) + { + m_layout->MovePieceToLayer(piece, focusedLayer); + } } } } +//--------------------------------------------------------------------------------------------------------------------- +void VPuzzleMainGraphicsView::keyPressEvent(QKeyEvent *event) +{ + if(event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete) + { + for(auto graphicsPiece : m_graphicsPieces) + { + VPuzzlePiece *piece = graphicsPiece->GetPiece(); + + if(piece->GetIsSelected()) + { + m_layout->MovePieceToLayer(piece, m_layout->GetUnplacedPiecesLayer()); + } + } + } +} //--------------------------------------------------------------------------------------------------------------------- -void VPuzzleMainGraphicsView::AddPiece(VPuzzlePiece *piece, QPointF pos) +void VPuzzleMainGraphicsView::on_PieceMovedToLayer(VPuzzlePiece *piece, VPuzzleLayer *layerBefore, VPuzzleLayer *layerAfter) { - VPuzzleGraphicsPiece *item = new VPuzzleGraphicsPiece(piece); - m_scene->addItem(item); - item->setSelected(true); - item->setPos(pos); - - item->blockSignals(true); - piece->SetPosition(pos); - item->blockSignals(false); + Q_UNUSED(layerBefore) + VPuzzleGraphicsPiece *_graphicsPiece = nullptr; + for(auto graphicPiece : m_graphicsPieces) + { + if(graphicPiece->GetPiece() == piece) + { + _graphicsPiece = graphicPiece; + } + } + if(layerAfter == m_layout->GetUnplacedPiecesLayer() && _graphicsPiece != nullptr) + { + scene()->removeItem(_graphicsPiece); + m_graphicsPieces.removeAll(_graphicsPiece); + } + else if(layerAfter != m_layout->GetUnplacedPiecesLayer()) + { + if(_graphicsPiece == nullptr) + { + _graphicsPiece = new VPuzzleGraphicsPiece(piece); + m_graphicsPieces.append(_graphicsPiece); + } + scene()->addItem(_graphicsPiece); + _graphicsPiece->setPos(_graphicsPiece->GetPiece()->GetPosition()); + _graphicsPiece->setSelected(_graphicsPiece->GetPiece()->GetIsSelected()); + _graphicsPiece->update(); + } } diff --git a/src/app/puzzle/vpuzzlemaingraphicsview.h b/src/app/puzzle/vpuzzlemaingraphicsview.h index 4bf74cb15..623e47d13 100644 --- a/src/app/puzzle/vpuzzlemaingraphicsview.h +++ b/src/app/puzzle/vpuzzlemaingraphicsview.h @@ -50,14 +50,22 @@ public: */ void RefreshLayout(); - void AddPiece(VPuzzlePiece *piece, QPointF pos); - protected: void dragEnterEvent(QDragEnterEvent *event) override; void dragMoveEvent(QDragMoveEvent *event) override; void dragLeaveEvent(QDragLeaveEvent *event) override; void dropEvent(QDropEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; + +private slots: + /** + * @brief on_PieceMovedToLayer The slot is called when the given piece was moved from the given layer to the other given layer + * @param piece the piece that was moved + * @param layerBefore the layer before the move + * @param layerAfter the layer after the move + */ + void on_PieceMovedToLayer(VPuzzlePiece *piece, VPuzzleLayer *layerBefore, VPuzzleLayer *layerAfter); private: Q_DISABLE_COPY(VPuzzleMainGraphicsView) @@ -65,6 +73,8 @@ private: VPuzzleMainGraphicsScene *m_scene{nullptr}; VPuzzleGraphicsLayout *m_graphicsLayout{nullptr}; + VPuzzleLayout *m_layout{nullptr}; + QList m_graphicsPieces; }; diff --git a/src/app/puzzle/vpuzzlepiece.cpp b/src/app/puzzle/vpuzzlepiece.cpp index 93058c960..9b2a6908a 100644 --- a/src/app/puzzle/vpuzzlepiece.cpp +++ b/src/app/puzzle/vpuzzlepiece.cpp @@ -27,6 +27,12 @@ *************************************************************************/ #include "vpuzzlepiece.h" +#include "vpuzzlelayer.h" + +#include + +Q_LOGGING_CATEGORY(pPiece, "p.piece") + //--------------------------------------------------------------------------------------------------------------------- VPuzzlePiece::VPuzzlePiece() { @@ -200,3 +206,18 @@ QVector VPuzzlePiece::GetGrainline() return m_grainline; } +//--------------------------------------------------------------------------------------------------------------------- +VPuzzleLayer* VPuzzlePiece::GetLayer() +{ + return m_layer; +} + + +//--------------------------------------------------------------------------------------------------------------------- +void VPuzzlePiece::SetLayer(VPuzzleLayer* layer) +{ + if(layer != m_layer) + { + m_layer = layer; + } +} diff --git a/src/app/puzzle/vpuzzlepiece.h b/src/app/puzzle/vpuzzlepiece.h index 00e9925b6..f5dd3ef5f 100644 --- a/src/app/puzzle/vpuzzlepiece.h +++ b/src/app/puzzle/vpuzzlepiece.h @@ -33,6 +33,8 @@ #include #include +class VPuzzleLayer; + class VPuzzlePiece : public QObject { Q_OBJECT @@ -135,18 +137,6 @@ public: */ qreal GetRotation(); - /** - * @brief SetIsSelected Sets wether the piece is selected - * @param value true if the piece is selected - */ - void SetIsSelected(bool value); - - /** - * @brief GetIsSelected Returns wether the piece is selected - * @return true if the piece is selected - */ - bool GetIsSelected(); - /** * @brief SetIsGrainlineEnabled Wether the piece has a grainline or not * @param value true or false @@ -184,6 +174,30 @@ public: QVector GetGrainline(); + /** + * @brief SetIsSelected Sets wether the piece is selected + * @param value true if the piece is selected + */ + void SetIsSelected(bool value); + + /** + * @brief GetIsSelected Returns wether the piece is selected. It emit the signal SelectionChanged + * @return true if the piece is selected + */ + bool GetIsSelected(); + + /** + * @brief GetLayer Returns the layer in which the piece is. + * @return layer of the piece + */ + VPuzzleLayer* GetLayer(); + + /** + * @brief SetLayer Sets the layer of the piece to the given layer + * @param layer + */ + void SetLayer(VPuzzleLayer* layer); + signals: /** * @brief SelectionChanged emited when the selection of the piece was @@ -209,12 +223,8 @@ signals: */ void PropertiesChanged(); - /** - * @brief LayerChanged emited when the piece's layer was changed. - */ - void LayerChanged(); - private: + Q_DISABLE_COPY(VPuzzlePiece) QUuid m_uuid{QUuid()}; QString m_name{QString()}; QVector m_cuttingLine{QVector()}; @@ -228,7 +238,9 @@ private: bool m_showSeamline{true}; bool m_mirrorPiece{false}; + bool m_isSelected{false}; + VPuzzleLayer *m_layer{nullptr}; }; #endif // VPUZZLEPIECE_H