From d72be9029f169788eb80e8d301834653a7a140a1 Mon Sep 17 00:00:00 2001 From: Ronan Le Tiec Date: Wed, 6 May 2020 15:05:01 +0200 Subject: [PATCH] improve multiple selection and add grainline to pieces --- src/app/puzzle/puzzlemainwindow.cpp | 36 ++++++---- src/app/puzzle/puzzlemainwindow.ui | 82 +++++++++++++++------- src/app/puzzle/vpiececarrousel.cpp | 6 ++ src/app/puzzle/vpiececarrousel.h | 5 +- src/app/puzzle/vpiececarrousellayer.cpp | 14 +++- src/app/puzzle/vpiececarrousellayer.h | 7 +- src/app/puzzle/vpiececarrouselpiece.cpp | 22 ++++-- src/app/puzzle/vpiececarrouselpiece.h | 7 +- src/app/puzzle/vpuzzlegraphicspiece.cpp | 60 +++++++++++----- src/app/puzzle/vpuzzlegraphicspiece.h | 1 + src/app/puzzle/vpuzzlelayout.cpp | 9 +++ src/app/puzzle/vpuzzlelayout.h | 6 ++ src/app/puzzle/vpuzzlemaingraphicsview.cpp | 3 + src/app/puzzle/vpuzzlepiece.cpp | 41 ++++++++++- src/app/puzzle/vpuzzlepiece.h | 40 +++++++++++ 15 files changed, 266 insertions(+), 73 deletions(-) diff --git a/src/app/puzzle/puzzlemainwindow.cpp b/src/app/puzzle/puzzlemainwindow.cpp index 7c2571619..ef3e8d775 100644 --- a/src/app/puzzle/puzzlemainwindow.cpp +++ b/src/app/puzzle/puzzlemainwindow.cpp @@ -184,9 +184,17 @@ VPuzzlePiece* PuzzleMainWindow::CreatePiece(const VLayoutPiece &rawPiece) VPuzzlePiece *piece = new VPuzzlePiece(); piece->SetName(rawPiece.GetName()); piece->SetUuid(rawPiece.GetUUID()); + piece->SetCuttingLine(rawPiece.GetMappedSeamAllowancePoints()); piece->SetSeamLine(rawPiece.GetMappedContourPoints()); + piece->SetIsGrainlineEnabled(rawPiece.IsGrainlineEnabled()); + if(rawPiece.IsGrainlineEnabled()) + { + piece->SetGrainlineAngle(rawPiece.GrainlineAngle()); + piece->SetGrainline(rawPiece.GetGrainline()); + } + // TODO : set all the information we need for the piece! // @@ -339,16 +347,20 @@ void PuzzleMainWindow::SetPropertyTabCurrentPieceData() { if(m_selectedPieces.count() == 0) { - // TODO : update current piece data to show a "no current piece selected" + // show the content "no piece selected" + ui->containerCurrentPieceNoData->setVisible(true); ui->containerCurrentPieceData->setVisible(false); + ui->containerCurrentPieceMultipleData->setVisible(false); } else if(m_selectedPieces.count() == 1) { - VPuzzlePiece *selectedPiece = m_selectedPieces.first(); - + // show the content "selected piece data" ui->containerCurrentPieceNoData->setVisible(false); ui->containerCurrentPieceData->setVisible(true); + ui->containerCurrentPieceMultipleData->setVisible(false); + + VPuzzlePiece *selectedPiece = m_selectedPieces.first(); // set the value to the current piece ui->lineEditCurrentPieceName->setText(selectedPiece->GetName()); @@ -364,7 +376,13 @@ void PuzzleMainWindow::SetPropertyTabCurrentPieceData() } else { - // TODO in the future + // show the content "multiple pieces selected" + + ui->containerCurrentPieceNoData->setVisible(false); + ui->containerCurrentPieceData->setVisible(false); + ui->containerCurrentPieceMultipleData->setVisible(true); + + // if needed in the future, we can show some properties that coul be edited for all the pieces } } @@ -864,16 +882,6 @@ void PuzzleMainWindow::on_PieceCarrouselLocationChanged(Qt::DockWidgetArea area) //--------------------------------------------------------------------------------------------------------------------- void PuzzleMainWindow::on_PieceSelectionChanged() { - // for now we have only single selection - // FIXME / TODO : To be updated when we support multiple selection. - - for (auto piece : m_selectedPieces) - { - if(piece->GetIsSelected()) - { - piece->SetIsSelected(false); - } - } m_selectedPieces = m_layout->GetSelectedPieces(); // update the property of the piece currently selected diff --git a/src/app/puzzle/puzzlemainwindow.ui b/src/app/puzzle/puzzlemainwindow.ui index 22e8d7fbc..7d6205696 100644 --- a/src/app/puzzle/puzzlemainwindow.ui +++ b/src/app/puzzle/puzzlemainwindow.ui @@ -228,9 +228,9 @@ 0 - 0 + -542 342 - 894 + 1302 @@ -250,31 +250,6 @@ - - - - - 0 - - - - - - 0 - 400 - - - - No piece selected - - - Qt::AlignCenter - - - - - - @@ -380,6 +355,9 @@ + + -10000.000000000000000 + 10000.000000000000000 @@ -397,6 +375,9 @@ + + -10000.000000000000000 + 10000.000000000000000 @@ -411,6 +392,53 @@ + + + + + 0 + + + + + + 0 + 400 + + + + No piece selected + + + Qt::AlignCenter + + + + + + + + + + + + + + 0 + 400 + + + + Multiple pieces selected + + + Qt::AlignCenter + + + + + + diff --git a/src/app/puzzle/vpiececarrousel.cpp b/src/app/puzzle/vpiececarrousel.cpp index 224bea4ec..991c51100 100644 --- a/src/app/puzzle/vpiececarrousel.cpp +++ b/src/app/puzzle/vpiececarrousel.cpp @@ -221,3 +221,9 @@ void VPieceCarrousel::RefreshOrientation() // FIXME: find a nicer way than putting directly the 120 width of the piece } } + +//--------------------------------------------------------------------------------------------------------------------- +void VPieceCarrousel::ClearSelection() +{ + m_layout->ClearSelection(); +} diff --git a/src/app/puzzle/vpiececarrousel.h b/src/app/puzzle/vpiececarrousel.h index 294db69ba..1459a24a2 100644 --- a/src/app/puzzle/vpiececarrousel.h +++ b/src/app/puzzle/vpiececarrousel.h @@ -72,10 +72,9 @@ public: void Clear(); /** - * @brief SelectPiece Updates the carrousel so that the given piece is selected - * @param piece the piece to select + * @brief ClearSelection Clears the selection of the carrousel. */ - void SelectPiece(VPuzzlePiece* piece); + void ClearSelection(); private: diff --git a/src/app/puzzle/vpiececarrousellayer.cpp b/src/app/puzzle/vpiececarrousellayer.cpp index 36b3b4e0d..d7435af52 100644 --- a/src/app/puzzle/vpiececarrousellayer.cpp +++ b/src/app/puzzle/vpiececarrousellayer.cpp @@ -27,6 +27,8 @@ *************************************************************************/ #include "vpiececarrousellayer.h" +#include "vpiececarrousel.h" + #include @@ -35,9 +37,9 @@ Q_LOGGING_CATEGORY(pCarrouselLayer, "p.carrouselLayer") //--------------------------------------------------------------------------------------------------------------------- -VPieceCarrouselLayer::VPieceCarrouselLayer(VPuzzleLayer *layer, QWidget *parent) : - QWidget(parent), +VPieceCarrouselLayer::VPieceCarrouselLayer(VPuzzleLayer *layer, VPieceCarrousel *carrousel) : m_layer(layer), + m_carrousel(carrousel), m_carrouselPieces(QList()) { Init(); @@ -80,7 +82,7 @@ void VPieceCarrouselLayer::Refresh() { // qCDebug(pCarrouselLayer, "piece name : %s", piece->GetName().toStdString().c_str()); - VPieceCarrouselPiece *carrouselPiece = new VPieceCarrouselPiece(piece); + VPieceCarrouselPiece *carrouselPiece = new VPieceCarrouselPiece(piece, this); m_carrouselPieces.append(carrouselPiece); layout()->addWidget(carrouselPiece); @@ -98,3 +100,9 @@ QList VPieceCarrouselLayer::GetCarrouselPieces() return m_carrouselPieces; } +//--------------------------------------------------------------------------------------------------------------------- +VPieceCarrousel* VPieceCarrouselLayer::GetCarrousel() +{ + return m_carrousel; +} + diff --git a/src/app/puzzle/vpiececarrousellayer.h b/src/app/puzzle/vpiececarrousellayer.h index 08d46a093..07f59eb2d 100644 --- a/src/app/puzzle/vpiececarrousellayer.h +++ b/src/app/puzzle/vpiececarrousellayer.h @@ -33,11 +33,13 @@ #include "vpuzzlelayer.h" #include "vpiececarrouselpiece.h" +class VPieceCarrousel; + class VPieceCarrouselLayer : public QWidget { Q_OBJECT public: - explicit VPieceCarrouselLayer(VPuzzleLayer *layer, QWidget *parent = nullptr); + VPieceCarrouselLayer(VPuzzleLayer *layer, VPieceCarrousel *carrousel); ~VPieceCarrouselLayer(); void Init(); @@ -45,10 +47,13 @@ public: QList GetCarrouselPieces(); + VPieceCarrousel* GetCarrousel(); + private: Q_DISABLE_COPY(VPieceCarrouselLayer) VPuzzleLayer *m_layer; + VPieceCarrousel *m_carrousel; QList m_carrouselPieces; private slots: diff --git a/src/app/puzzle/vpiececarrouselpiece.cpp b/src/app/puzzle/vpiececarrouselpiece.cpp index 27299cdd3..5ce09a63e 100644 --- a/src/app/puzzle/vpiececarrouselpiece.cpp +++ b/src/app/puzzle/vpiececarrouselpiece.cpp @@ -37,6 +37,8 @@ #include #include "vpuzzlemimedatapiece.h" +#include "vpiececarrousellayer.h" +#include "vpiececarrousel.h" #include @@ -44,9 +46,10 @@ Q_LOGGING_CATEGORY(pCarrouselPiece, "p.carrouselPiece") //--------------------------------------------------------------------------------------------------------------------- -VPieceCarrouselPiece::VPieceCarrouselPiece(VPuzzlePiece *piece, QWidget *parent) : - QFrame(parent), - m_piece(piece) +VPieceCarrouselPiece::VPieceCarrouselPiece(VPuzzlePiece *piece, VPieceCarrouselLayer *carrouselLayer) : + m_piece(piece), + m_carrouselLayer(carrouselLayer), + m_dragStart(QPoint()) { Init(); } @@ -169,10 +172,16 @@ void VPieceCarrouselPiece::mousePressEvent(QMouseEvent *event) if (event->button() == Qt::LeftButton) { - if(!m_piece->GetIsSelected()) + if(!(event->modifiers() & Qt::ControlModifier)) { + m_carrouselLayer->GetCarrousel()->ClearSelection(); m_piece->SetIsSelected(true); } + else + { + m_piece->SetIsSelected(!m_piece->GetIsSelected()); + } + m_dragStart = event->pos(); } } @@ -190,6 +199,11 @@ void VPieceCarrouselPiece::mouseMoveEvent(QMouseEvent *event) return; } + // make sure the multiple selection is removed + m_carrouselLayer->GetCarrousel()->ClearSelection(); + m_piece->SetIsSelected(true); + + // starts the dragging QDrag *drag = new QDrag(this); VPuzzleMimeDataPiece *mimeData = new VPuzzleMimeDataPiece(); mimeData->SetPiecePtr(m_piece); diff --git a/src/app/puzzle/vpiececarrouselpiece.h b/src/app/puzzle/vpiececarrouselpiece.h index 72d75e639..ecbf24095 100644 --- a/src/app/puzzle/vpiececarrouselpiece.h +++ b/src/app/puzzle/vpiececarrouselpiece.h @@ -37,11 +37,13 @@ #include "vpiececarrouselpiecepreview.h" +class VPieceCarrouselLayer; + class VPieceCarrouselPiece : public QFrame { Q_OBJECT public: - explicit VPieceCarrouselPiece(VPuzzlePiece *piece, QWidget *parent = nullptr); + explicit VPieceCarrouselPiece(VPuzzlePiece *piece, VPieceCarrouselLayer *carrouselLayer); ~VPieceCarrouselPiece(); void Init(); @@ -70,6 +72,9 @@ private: Q_DISABLE_COPY(VPieceCarrouselPiece) VPuzzlePiece *m_piece; + + VPieceCarrouselLayer *m_carrouselLayer; + QLabel *m_label{nullptr}; VPieceCarrouselPiecePreview *m_piecePreview{nullptr}; diff --git a/src/app/puzzle/vpuzzlegraphicspiece.cpp b/src/app/puzzle/vpuzzlegraphicspiece.cpp index 70b5d9156..6a9060214 100644 --- a/src/app/puzzle/vpuzzlegraphicspiece.cpp +++ b/src/app/puzzle/vpuzzlegraphicspiece.cpp @@ -45,7 +45,8 @@ VPuzzleGraphicsPiece::VPuzzleGraphicsPiece(VPuzzlePiece *piece, QGraphicsItem *p QGraphicsObject(parent), m_piece(piece), m_cuttingLine(QPainterPath()), - m_seamLine(QPainterPath()) + m_seamLine(QPainterPath()), + m_grainline(QPainterPath()) { Init(); } @@ -63,9 +64,6 @@ void VPuzzleGraphicsPiece::Init() setFlags(ItemIsSelectable | ItemIsMovable | ItemSendsGeometryChanges); setCursor(QCursor(Qt::OpenHandCursor)); - //setAcceptHoverEvents(true); // maybe we can do some stuff with this - - // initialises the seam line QVector seamLinePoints = m_piece->GetSeamLine(); m_seamLine.moveTo(seamLinePoints.first()); @@ -78,8 +76,14 @@ void VPuzzleGraphicsPiece::Init() for (int i = 1; i < cuttingLinepoints.size(); ++i) m_cuttingLine.lineTo(cuttingLinepoints.at(i)); + // initialises the grainline + QVector grainLinepoints = m_piece->GetGrainline(); + m_grainline.moveTo(grainLinepoints.first()); + for (int i = 1; i < grainLinepoints.size(); ++i) + m_grainline.lineTo(grainLinepoints.at(i)); - // TODO : initialises the other elements like grain line, labels, passmarks etc. + + // TODO : initialises the other elements labels, passmarks etc. // Initialises the connectors connect(m_piece, &VPuzzlePiece::SelectionChanged, this, &VPuzzleGraphicsPiece::on_PieceSelectionChanged); @@ -126,47 +130,69 @@ void VPuzzleGraphicsPiece::paint(QPainter *painter, const QStyleOptionGraphicsIt painter->setPen(pen); painter->setBrush(noBrush); + // paint the cutting line if(!m_cuttingLine.isEmpty()) { painter->drawPath(m_cuttingLine); } + // paint the seam line if(!m_seamLine.isEmpty()) { painter->drawPath(m_seamLine); } + + // paint the grainline + if(!m_grainline.isEmpty()) + { + painter->drawPath(m_grainline); + } } //--------------------------------------------------------------------------------------------------------------------- void VPuzzleGraphicsPiece::mousePressEvent(QGraphicsSceneMouseEvent *event) { + bool selectionState = isSelected(); //perform the default behaviour QGraphicsItem::mousePressEvent(event); // change the cursor when clicking left button - if (!(event->buttons() & Qt::LeftButton)) + if (event->button() == Qt::LeftButton) { - return; + setSelected(true); + setCursor(Qt::ClosedHandCursor); + + if (event->modifiers() & Qt::ControlModifier) + { + setSelected(!selectionState); + } + else + { + setSelected(true); + } } - - setSelected(true); - - setCursor(Qt::ClosedHandCursor); } //--------------------------------------------------------------------------------------------------------------------- void VPuzzleGraphicsPiece::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { + bool selectionState = isSelected(); + //perform the default behaviour QGraphicsItem::mouseReleaseEvent(event); - // change the cursor when clicking left button - if (!(event->buttons() & Qt::LeftButton)) - { - return; - } + qCDebug(pGraphicsPiece, "piiiiieeece --- mouse release"); - setCursor(Qt::OpenHandCursor); + // change the cursor when clicking left button + + if (event->button() == Qt::LeftButton) + { + setCursor(Qt::OpenHandCursor); + + qCDebug(pGraphicsPiece, "piiiiieeece --- left button"); + + setSelected(selectionState); + } } diff --git a/src/app/puzzle/vpuzzlegraphicspiece.h b/src/app/puzzle/vpuzzlegraphicspiece.h index ef585d9cb..dd467acfa 100644 --- a/src/app/puzzle/vpuzzlegraphicspiece.h +++ b/src/app/puzzle/vpuzzlegraphicspiece.h @@ -68,6 +68,7 @@ private: QPainterPath m_cuttingLine; QPainterPath m_seamLine; + QPainterPath m_grainline; }; #endif // VPUZZLEGRAPHICSPIECE_H diff --git a/src/app/puzzle/vpuzzlelayout.cpp b/src/app/puzzle/vpuzzlelayout.cpp index 49d75a662..51ed0e5ce 100644 --- a/src/app/puzzle/vpuzzlelayout.cpp +++ b/src/app/puzzle/vpuzzlelayout.cpp @@ -268,3 +268,12 @@ bool VPuzzleLayout::GetStickyEdges() const { return m_stickyEdges; } + +//--------------------------------------------------------------------------------------------------------------------- +void VPuzzleLayout::ClearSelection() +{ + for(auto piece : GetSelectedPieces()) + { + piece->SetIsSelected(false); + } +} diff --git a/src/app/puzzle/vpuzzlelayout.h b/src/app/puzzle/vpuzzlelayout.h index e404f3025..a057b7c62 100644 --- a/src/app/puzzle/vpuzzlelayout.h +++ b/src/app/puzzle/vpuzzlelayout.h @@ -194,6 +194,12 @@ public: void SetStickyEdges(bool state); bool GetStickyEdges() const; + /** + * @brief ClearSelection goes through the layers & pieces and calls + * SetIsSelected(false) for the pieces that were selected. + */ + void ClearSelection(); + private: Q_DISABLE_COPY(VPuzzleLayout) VPuzzleLayer *m_unplacedPiecesLayer; diff --git a/src/app/puzzle/vpuzzlemaingraphicsview.cpp b/src/app/puzzle/vpuzzlemaingraphicsview.cpp index 9d1a8238f..bf620cb9f 100644 --- a/src/app/puzzle/vpuzzlemaingraphicsview.cpp +++ b/src/app/puzzle/vpuzzlemaingraphicsview.cpp @@ -142,4 +142,7 @@ void VPuzzleMainGraphicsView::AddPiece(VPuzzlePiece *piece, QPointF pos) item->blockSignals(true); piece->SetPosition(pos); item->blockSignals(false); + + + } diff --git a/src/app/puzzle/vpuzzlepiece.cpp b/src/app/puzzle/vpuzzlepiece.cpp index 66b3d377a..93058c960 100644 --- a/src/app/puzzle/vpuzzlepiece.cpp +++ b/src/app/puzzle/vpuzzlepiece.cpp @@ -152,9 +152,11 @@ qreal VPuzzlePiece::GetRotation() //--------------------------------------------------------------------------------------------------------------------- void VPuzzlePiece::SetIsSelected(bool value) { - m_isSelected = value; - - emit SelectionChanged(); + if(m_isSelected != value) + { + m_isSelected = value; + emit SelectionChanged(); + } } //--------------------------------------------------------------------------------------------------------------------- @@ -163,5 +165,38 @@ bool VPuzzlePiece::GetIsSelected() return m_isSelected; } +//--------------------------------------------------------------------------------------------------------------------- +void VPuzzlePiece::SetIsGrainlineEnabled(bool value) +{ + m_isGrainlineEnabled = value; +} +//--------------------------------------------------------------------------------------------------------------------- +bool VPuzzlePiece::GetIsGrainlineEnabled() +{ + return m_isGrainlineEnabled; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPuzzlePiece::SetGrainlineAngle(qreal value) +{ + m_grainlineAngle = value; +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VPuzzlePiece::GetGrainlineAngle() +{ + return m_grainlineAngle; +} +//--------------------------------------------------------------------------------------------------------------------- +void VPuzzlePiece::SetGrainline(QVector grainline) +{ + m_grainline = grainline; +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector VPuzzlePiece::GetGrainline() +{ + return m_grainline; +} diff --git a/src/app/puzzle/vpuzzlepiece.h b/src/app/puzzle/vpuzzlepiece.h index 4f5b37b11..00e9925b6 100644 --- a/src/app/puzzle/vpuzzlepiece.h +++ b/src/app/puzzle/vpuzzlepiece.h @@ -147,6 +147,42 @@ public: */ bool GetIsSelected(); + /** + * @brief SetIsGrainlineEnabled Wether the piece has a grainline or not + * @param value true or false + */ + void SetIsGrainlineEnabled(bool value); + + /** + * @brief GetIsGrainlineEnabled Returns wether the grainline is enabled for this piece + * @return true if enabled + */ + bool GetIsGrainlineEnabled(); + + /** + * @brief SetGrainlineAngle Sets the angle of the grainline + * @param value + */ + void SetGrainlineAngle(qreal value); + + /** + * @brief GetGrainlineAngle Returns the angle of the grainline for this piece + * @return the angle + */ + qreal GetGrainlineAngle(); + + /** + * @brief SetGrainline Sets the grainline to the given vector of points + * @param grainline the grainline + */ + void SetGrainline(QVector grainline); + + /** + * @brief GetGrainline Returns the grainline for this piece + * @return the vector + */ + QVector GetGrainline(); + signals: /** @@ -184,6 +220,10 @@ private: QVector m_cuttingLine{QVector()}; QVector m_seamLine{QVector()}; + QVector m_grainline{QVector()}; + bool m_isGrainlineEnabled{false}; + qreal m_grainlineAngle{0}; + QTransform m_transform{QTransform()}; bool m_showSeamline{true};