diff --git a/src/app/puzzle/puzzle.pri b/src/app/puzzle/puzzle.pri index 5c90f52f5..c0915d854 100644 --- a/src/app/puzzle/puzzle.pri +++ b/src/app/puzzle/puzzle.pri @@ -12,6 +12,7 @@ SOURCES += \ $$PWD/vpcommands.cpp \ $$PWD/vpgraphicspiece.cpp \ $$PWD/vpgraphicssheet.cpp \ + $$PWD/vpgraphicstilegrid.cpp \ $$PWD/vplayout.cpp \ $$PWD/vpmaingraphicsview.cpp \ $$PWD/vpmainwindow.cpp \ @@ -20,6 +21,7 @@ SOURCES += \ $$PWD/vppiecelist.cpp \ $$PWD/vpsettings.cpp \ $$PWD/vpsheet.cpp \ + $$PWD/vptilefactory.cpp \ $$PWD/xml/vplayoutfilereader.cpp \ $$PWD/xml/vplayoutfilewriter.cpp \ $$PWD/xml/vplayoutliterals.cpp @@ -36,6 +38,7 @@ HEADERS += \ $$PWD/vpcommands.h \ $$PWD/vpgraphicspiece.h \ $$PWD/vpgraphicssheet.h \ + $$PWD/vpgraphicstilegrid.h \ $$PWD/vplayout.h \ $$PWD/vpmaingraphicsview.h \ $$PWD/vpmainwindow.h \ @@ -45,6 +48,7 @@ HEADERS += \ $$PWD/vpsettings.h \ $$PWD/vpsheet.h \ $$PWD/vpstable.h \ + $$PWD/vptilefactory.h \ $$PWD/xml/vplayoutfilereader.h \ $$PWD/xml/vplayoutfilewriter.h \ $$PWD/xml/vplayoutliterals.h diff --git a/src/app/puzzle/puzzle.pro b/src/app/puzzle/puzzle.pro index 462579124..4d1e2fbd8 100644 --- a/src/app/puzzle/puzzle.pro +++ b/src/app/puzzle/puzzle.pro @@ -7,7 +7,7 @@ # File with common stuff for whole project include(../../../common.pri) -QT += core gui widgets network xml xmlpatterns printsupport concurrent +QT += core gui widgets network xml svg xmlpatterns printsupport concurrent # Name of binary file TARGET = puzzle diff --git a/src/app/puzzle/share/resources/puzzleicon.qrc b/src/app/puzzle/share/resources/puzzleicon.qrc index 809e972be..cf7527f52 100644 --- a/src/app/puzzle/share/resources/puzzleicon.qrc +++ b/src/app/puzzle/share/resources/puzzleicon.qrc @@ -9,6 +9,12 @@ puzzleicon/64x64/iconPortrait.png puzzleicon/64x64/iconGrainlineVertical.png puzzleicon/64x64/iconGrainlineHorizontal.png - puzzleicon/64x64/cursorRotate.png + puzzleicon/64x64/iconProperties.png + puzzleicon/svg/icon_scissors.svg + puzzleicon/svg/icon_scissors_vertical.svg + puzzleicon/svg/icon_scissors_horizontal.svg + puzzleicon/16x16/roll.png + puzzleicon/16x16/template.png + puzzleicon/svg/cursor_rotate.svg diff --git a/src/app/puzzle/share/resources/puzzleicon/16x16/roll.png b/src/app/puzzle/share/resources/puzzleicon/16x16/roll.png new file mode 100644 index 000000000..49c30dff1 Binary files /dev/null and b/src/app/puzzle/share/resources/puzzleicon/16x16/roll.png differ diff --git a/src/app/puzzle/share/resources/puzzleicon/16x16/template.png b/src/app/puzzle/share/resources/puzzleicon/16x16/template.png new file mode 100644 index 000000000..c29755d29 Binary files /dev/null and b/src/app/puzzle/share/resources/puzzleicon/16x16/template.png differ diff --git a/src/app/puzzle/share/resources/puzzleicon/64x64/cursorRotate.png b/src/app/puzzle/share/resources/puzzleicon/64x64/cursorRotate.png index a9ade2aee..831f77ed0 100644 Binary files a/src/app/puzzle/share/resources/puzzleicon/64x64/cursorRotate.png and b/src/app/puzzle/share/resources/puzzleicon/64x64/cursorRotate.png differ diff --git a/src/app/puzzle/share/resources/puzzleicon/64x64/cursorRotate@2x.png b/src/app/puzzle/share/resources/puzzleicon/64x64/cursorRotate@2x.png index 0bde89ddb..4cb07973b 100644 Binary files a/src/app/puzzle/share/resources/puzzleicon/64x64/cursorRotate@2x.png and b/src/app/puzzle/share/resources/puzzleicon/64x64/cursorRotate@2x.png differ diff --git a/src/app/puzzle/share/resources/puzzleicon/64x64/iconProperties.png b/src/app/puzzle/share/resources/puzzleicon/64x64/iconProperties.png new file mode 100644 index 000000000..0dc054e3f Binary files /dev/null and b/src/app/puzzle/share/resources/puzzleicon/64x64/iconProperties.png differ diff --git a/src/app/puzzle/share/resources/puzzleicon/64x64/iconProperties@2x.png b/src/app/puzzle/share/resources/puzzleicon/64x64/iconProperties@2x.png new file mode 100644 index 000000000..6648e784b Binary files /dev/null and b/src/app/puzzle/share/resources/puzzleicon/64x64/iconProperties@2x.png differ diff --git a/src/app/puzzle/share/resources/puzzleicon/svg/cursor_rotate.svg b/src/app/puzzle/share/resources/puzzleicon/svg/cursor_rotate.svg index f5b2423cb..2bc7aa1ac 100644 --- a/src/app/puzzle/share/resources/puzzleicon/svg/cursor_rotate.svg +++ b/src/app/puzzle/share/resources/puzzleicon/svg/cursor_rotate.svg @@ -1,6 +1,4 @@ - - - - + viewBox="0 0 128 128" + sodipodi:docname="cursor_rotate.svg" + inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)" + inkscape:export-filename="/home/ronan/Workspace_cpp/valentina/src/app/puzzle/share/resources/puzzleicon/64x64/cursorRotate@2x.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96"> + id="metadata899"> @@ -52,16 +29,38 @@ + + + inkscape:label="Image" + id="g901"> + id="path1502" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:16.112;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1" + d="M 67.494019,3 C 45.635979,3 26.4721,14.832798 15.842825,32.458789 L 0,20.886257 10.290418,67.03627 50.234036,44.059307 30.104959,39.845618 c 7.88695,-12.507886 21.673605,-20.733626 37.38906,-20.733626 24.548563,0 44.393991,20.068893 44.393991,45.180711 0,25.111817 -19.845428,45.178617 -44.393991,45.178617 -18.793455,0 -34.829896,-11.76047 -41.31635,-28.542147 -12.799702,5.691961 -3.295568,1.770075 -14.669238,6.556583 C 20.55829,109.77568 42.229103,125.58331 67.494019,125.58331 100.88055,125.58331 128,97.98361 128,64.292703 128,30.601797 100.88055,3 67.494019,3 Z" + sodipodi:nodetypes="scccccsssccsss" /> diff --git a/src/app/puzzle/share/resources/puzzleicon/svg/iconProperties.svg b/src/app/puzzle/share/resources/puzzleicon/svg/iconProperties.svg new file mode 100644 index 000000000..eb0cdd094 --- /dev/null +++ b/src/app/puzzle/share/resources/puzzleicon/svg/iconProperties.svg @@ -0,0 +1,136 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/src/app/puzzle/share/resources/puzzleicon/svg/icon_scissors.svg b/src/app/puzzle/share/resources/puzzleicon/svg/icon_scissors.svg new file mode 100644 index 000000000..fd1bd78c7 --- /dev/null +++ b/src/app/puzzle/share/resources/puzzleicon/svg/icon_scissors.svg @@ -0,0 +1,75 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/src/app/puzzle/share/resources/puzzleicon/svg/icon_scissors_horizontal.svg b/src/app/puzzle/share/resources/puzzleicon/svg/icon_scissors_horizontal.svg new file mode 100644 index 000000000..c6ed9f159 --- /dev/null +++ b/src/app/puzzle/share/resources/puzzleicon/svg/icon_scissors_horizontal.svg @@ -0,0 +1,77 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/src/app/puzzle/share/resources/puzzleicon/svg/icon_scissors_vertical.svg b/src/app/puzzle/share/resources/puzzleicon/svg/icon_scissors_vertical.svg new file mode 100644 index 000000000..8bc4994e4 --- /dev/null +++ b/src/app/puzzle/share/resources/puzzleicon/svg/icon_scissors_vertical.svg @@ -0,0 +1,77 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/src/app/puzzle/vpapplication.cpp b/src/app/puzzle/vpapplication.cpp index 9d6233713..e3233a2c0 100644 --- a/src/app/puzzle/vpapplication.cpp +++ b/src/app/puzzle/vpapplication.cpp @@ -363,6 +363,7 @@ VPMainWindow *VPApplication::NewMainWindow(const VPCommandLinePtr &cmd) { puzzle->show(); } + puzzle->InitZoom(); return puzzle; } diff --git a/src/app/puzzle/vpcarrousel.cpp b/src/app/puzzle/vpcarrousel.cpp index 072b3a528..87287c739 100644 --- a/src/app/puzzle/vpcarrousel.cpp +++ b/src/app/puzzle/vpcarrousel.cpp @@ -83,6 +83,15 @@ void VPCarrousel::Refresh() RefreshOrientation(); } +//--------------------------------------------------------------------------------------------------------------------- +void VPCarrousel::RefreshFocusedSheetName() +{ + // FIXME : This implementation will need a refactoring when we have multiple sheets, now it's not very nice!! + + ui->comboBoxPieceList->setItemText(1, tr("Pieces of ") + m_layout->GetFocusedSheet()->GetName()); +} + + //--------------------------------------------------------------------------------------------------------------------- void VPCarrousel::Clear() { diff --git a/src/app/puzzle/vpcarrousel.h b/src/app/puzzle/vpcarrousel.h index 4a3119a0e..2fb31a61b 100644 --- a/src/app/puzzle/vpcarrousel.h +++ b/src/app/puzzle/vpcarrousel.h @@ -65,6 +65,11 @@ public: */ void Refresh(); + /** + * @brief RefreshFocusedSheetName refreshes the name of the focused sheet + */ + void RefreshFocusedSheetName(); + /** * @brief Clear Clears the carrousel (removes everything) */ diff --git a/src/app/puzzle/vpcarrouselpiece.cpp b/src/app/puzzle/vpcarrouselpiece.cpp index c5e651546..7fc443003 100644 --- a/src/app/puzzle/vpcarrouselpiece.cpp +++ b/src/app/puzzle/vpcarrouselpiece.cpp @@ -74,7 +74,7 @@ void VPCarrouselPiece::RefreshSelection() } //--------------------------------------------------------------------------------------------------------------------- -QIcon VPCarrouselPiece::CreatePieceIcon(const QSize &size) const +QIcon VPCarrouselPiece::CreatePieceIcon(const QSize &size, bool isDragIcon) const { QVector points = m_piece->GetMappedContourPoints(); // seamline if(points.isEmpty()) @@ -92,31 +92,66 @@ QIcon VPCarrouselPiece::CreatePieceIcon(const QSize &size) const qreal dx = canvas.center().x() - boundingRect.center().x(); qreal dy = canvas.center().y() - boundingRect.center().y(); - QPixmap pixmap(size); - pixmap.fill(QColor("white")); + QVector iconModes; + iconModes.append(QIcon::Normal); - QPainter painter; - painter.begin(&pixmap); - painter.setRenderHint(QPainter::Antialiasing); - painter.setRenderHint(QPainter::SmoothPixmapTransform); - - int spacing = 2; - painter.translate(spacing, spacing); - - qreal scaleFactorX = canvasSize * 100 / (size.width() - spacing*2) / 100; - qreal scaleFactorY = canvasSize * 100 / (size.height() - spacing*2) / 100; - painter.scale(1./scaleFactorX, 1./scaleFactorY); - painter.setPen(QPen(Qt::black, 0.8*qMax(scaleFactorX, scaleFactorY))); - - painter.translate(dx, dy); - - painter.drawPolygon(shape); - painter.end(); + if(not isDragIcon) + { + iconModes.append(QIcon::Selected); + } QIcon icon; - icon.addPixmap(pixmap,QIcon::Normal); - icon.addPixmap(pixmap,QIcon::Selected); + for(auto iconMode : iconModes) + { + QPixmap pixmap(size); + + if(not isDragIcon) + { + pixmap.fill(QColor(Qt::white)); + } + else + { + pixmap.fill(QColor(Qt::transparent)); + } + + QPainter painter; + painter.begin(&pixmap); + painter.setRenderHint(QPainter::Antialiasing); + painter.setRenderHint(QPainter::SmoothPixmapTransform); + + int spacing = 2; + + painter.translate(spacing, spacing); + + qreal scaleFactorX = canvasSize * 100 / (size.width() - spacing*2) / 100; + qreal scaleFactorY = canvasSize * 100 / (size.height() - spacing*2) / 100; + painter.scale(1./scaleFactorX, 1./scaleFactorY); + painter.setPen(QPen(Qt::black, 0.8*qMax(scaleFactorX, scaleFactorY))); + + if(not isDragIcon) + { + painter.translate(dx, dy); + } + else + { + painter.translate(-boundingRect.topLeft().x()+spacing, -boundingRect.topLeft().y()+spacing); + } + + if(iconMode == QIcon::Selected) + { + painter.setBrush(QBrush(QColor(255,160,160,60))); + } + else + { + painter.setBrush(QBrush(Qt::white)); + } + + painter.drawPolygon(shape); + painter.end(); + + icon.addPixmap(pixmap,iconMode); + } return icon; } diff --git a/src/app/puzzle/vpcarrouselpiece.h b/src/app/puzzle/vpcarrouselpiece.h index 9be77a355..d9d0a83f4 100644 --- a/src/app/puzzle/vpcarrouselpiece.h +++ b/src/app/puzzle/vpcarrouselpiece.h @@ -56,7 +56,7 @@ public: * @param size of the icon * @return the created icon */ - QIcon CreatePieceIcon(const QSize &size) const; + QIcon CreatePieceIcon(const QSize &size, bool isDragIcon = false) const; private: diff --git a/src/app/puzzle/vpcarrouselpiecelist.cpp b/src/app/puzzle/vpcarrouselpiecelist.cpp index c782bfeb7..00ca57d9d 100644 --- a/src/app/puzzle/vpcarrouselpiecelist.cpp +++ b/src/app/puzzle/vpcarrouselpiecelist.cpp @@ -47,7 +47,7 @@ VPCarrouselPieceList::VPCarrouselPieceList(QWidget* parent) : QListWidget(parent), m_dragStart(QPoint()) { - setStyleSheet("QListWidget::item{border: 2px solid transparent; color: black;} QListWidget::item:selected {border: 2px solid red;}"); + setStyleSheet("QListWidget::item{border: 2px solid transparent; color: black;} QListWidget::item:selected {border: 2px solid rgb(255,160,160);}"); setContextMenuPolicy(Qt::DefaultContextMenu); setSelectionMode(QAbstractItemView::MultiSelection); setViewMode(QListView::IconMode); @@ -163,7 +163,7 @@ void VPCarrouselPieceList::startDrag(Qt::DropActions supportedActions) mimeData->SetPiecePtr(piece); mimeData->setObjectName("piecePointer"); - QPixmap pixmap = pieceItem->CreatePieceIcon(QSize(120,120)).pixmap(QSize(120,120)); + QPixmap pixmap = pieceItem->CreatePieceIcon(QSize(120,120), true).pixmap(QSize(120,120)); drag->setPixmap(pixmap); drag->setMimeData(mimeData); @@ -187,33 +187,42 @@ void VPCarrouselPieceList::dragMoveEvent(QDragMoveEvent* e) void VPCarrouselPieceList::contextMenuEvent(QContextMenuEvent *event) { QListWidgetItem* _item = currentItem(); - if(_item->type() == 1001) + if(_item != nullptr) { - VPCarrouselPiece *pieceItem = static_cast (_item); - - QMenu contextMenu; - - if(m_pieceList->GetSheet() == nullptr) + if(_item->type() == 1001) { - VPPieceList* sheetPieces = pieceItem->GetPiece()->GetPieceList()->GetLayout()->GetFocusedSheet()->GetPieceList(); - QAction *moveAction = contextMenu.addAction(tr("Move to Sheet")); - QVariant data = QVariant::fromValue(sheetPieces); - moveAction->setData(data); + VPCarrouselPiece *pieceItem = static_cast (_item); - connect(moveAction, &QAction::triggered, this, &VPCarrouselPieceList::on_ActionPieceMovedToPieceList); + QMenu contextMenu; + + if(m_pieceList->GetSheet() == nullptr) + { + VPPieceList* sheetPieces = pieceItem->GetPiece()->GetPieceList()->GetLayout()->GetFocusedSheet()->GetPieceList(); + QAction *moveAction = contextMenu.addAction(tr("Move to Sheet")); + QVariant moveData = QVariant::fromValue(sheetPieces); + moveAction->setData(moveData); + + VPPieceList* trashPieceList = pieceItem->GetPiece()->GetPieceList()->GetLayout()->GetTrashPieceList(); + QAction *deleteAction = contextMenu.addAction(tr("Delete")); + QVariant deleteData = QVariant::fromValue(trashPieceList); + deleteAction->setData(deleteData); + + connect(moveAction, &QAction::triggered, this, &VPCarrouselPieceList::on_ActionPieceMovedToPieceList); + connect(deleteAction, &QAction::triggered, this, &VPCarrouselPieceList::on_ActionPieceMovedToPieceList); + } + + // remove from piece list action + if(m_pieceList->GetSheet() != nullptr) + { + VPPieceList* unplacedPieces = pieceItem->GetPiece()->GetPieceList()->GetLayout()->GetUnplacedPieceList(); + QAction *removeAction = contextMenu.addAction(tr("Remove from Sheet")); + QVariant data = QVariant::fromValue(unplacedPieces); + removeAction->setData(data); + connect(removeAction, &QAction::triggered, this, &VPCarrouselPieceList::on_ActionPieceMovedToPieceList); + } + + contextMenu.exec(event->globalPos()); } - - // remove from piece list action - if(m_pieceList->GetSheet() != nullptr) - { - VPPieceList* unplacedPieces = pieceItem->GetPiece()->GetPieceList()->GetLayout()->GetUnplacedPieceList(); - QAction *removeAction = contextMenu.addAction(tr("Remove from Sheet")); - QVariant data = QVariant::fromValue(unplacedPieces); - removeAction->setData(data); - connect(removeAction, &QAction::triggered, this, &VPCarrouselPieceList::on_ActionPieceMovedToPieceList); - } - - contextMenu.exec(event->globalPos()); } } @@ -235,8 +244,6 @@ void VPCarrouselPieceList::on_ActionPieceMovedToPieceList() } } - - //--------------------------------------------------------------------------------------------------------------------- void VPCarrouselPieceList::on_PieceAdded(VPPiece* piece) { diff --git a/src/app/puzzle/vpcarrouselpiecelist.h b/src/app/puzzle/vpcarrouselpiecelist.h index 48d8cf5ce..26f65d957 100644 --- a/src/app/puzzle/vpcarrouselpiecelist.h +++ b/src/app/puzzle/vpcarrouselpiecelist.h @@ -108,7 +108,6 @@ private slots: * @brief on_ActionPieceMovedToPieceList when a piece is moved to another piece list via a context menu */ void on_ActionPieceMovedToPieceList(); - }; #endif // VPCARROUSELPIECELIST_H diff --git a/src/app/puzzle/vpgraphicspiece.cpp b/src/app/puzzle/vpgraphicspiece.cpp index d369e98ea..c0973ce34 100644 --- a/src/app/puzzle/vpgraphicspiece.cpp +++ b/src/app/puzzle/vpgraphicspiece.cpp @@ -31,19 +31,22 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include "vppiece.h" #include "vppiecelist.h" #include "vplayout.h" #include "vpsheet.h" +#include "vlayoutpiecepath.h" +#include "vplacelabelitem.h" + #include Q_LOGGING_CATEGORY(pGraphicsPiece, "p.graphicsPiece") @@ -54,8 +57,17 @@ VPGraphicsPiece::VPGraphicsPiece(VPPiece *piece, QGraphicsItem *parent) : m_cuttingLine(QPainterPath()), m_seamLine(QPainterPath()), m_grainline(QPainterPath()), - m_rotationStartPoint(QPointF()) + m_passmarks(QPainterPath()), + m_internalPaths(QVector()), + m_internalPathsPenStyle(QVector()), + m_placeLabels(QVector()), + m_rotationStartPoint(QPointF()), + m_rotateCursor(QCursor()) { + + QPixmap cursor_pixmap = QIcon("://puzzleicon/svg/cursor_rotate.svg").pixmap(QSize(32,32)); + m_rotateCursor= QCursor(cursor_pixmap, 16, 16); + Init(); } @@ -78,7 +90,7 @@ void VPGraphicsPiece::Init() if(!seamLinePoints.isEmpty()) { m_seamLine.moveTo(seamLinePoints.first()); - for (int i = 1; i < seamLinePoints.size(); ++i) + for (int i = 0; i < seamLinePoints.size(); i++) m_seamLine.lineTo(seamLinePoints.at(i)); } @@ -87,7 +99,7 @@ void VPGraphicsPiece::Init() if(!cuttingLinepoints.isEmpty()) { m_cuttingLine.moveTo(cuttingLinepoints.first()); - for (int i = 1; i < cuttingLinepoints.size(); ++i) + for (int i = 0; i < cuttingLinepoints.size(); i++) m_cuttingLine.lineTo(cuttingLinepoints.at(i)); } @@ -98,17 +110,49 @@ void VPGraphicsPiece::Init() if(!grainLinepoints.isEmpty()) { m_grainline.moveTo(grainLinepoints.first()); - for (int i = 1; i < grainLinepoints.size(); ++i) + for (int i = 0; i < grainLinepoints.size(); i++) m_grainline.lineTo(grainLinepoints.at(i)); } } - // TODO : initialises the other elements labels, passmarks etc. + // initialises the internal paths + QVector internalPaths = m_piece->GetInternalPaths(); + for (int i = 0; i < internalPaths.size(); i++) + { + VLayoutPiecePath piecePath = internalPaths.at(i); + QPainterPath path = m_piece->GetMatrix().map(piecePath.GetPainterPath()); + m_internalPaths.append(path); + m_internalPathsPenStyle.append(piecePath.PenStyle()); + } + + // initialises the passmarks + QVector passmarks = m_piece->GetPassmarks(); + for(auto &passmark : passmarks) + { + for (auto &line : passmark.lines) + { + m_passmarks.moveTo(line.p1()); + m_passmarks.lineTo(line.p2()); + } + } + + // initialises the place labels (buttons etc) + QVector placeLabels = m_piece->GetPlaceLabels(); + for(auto &placeLabel : placeLabels) + { + QPainterPath path = VPlaceLabelItem::LabelShapePath(placeLabel.shape); + m_placeLabels.append(path); + } + + // TODO : initialises the text labels + + // Initialises the connectors connect(m_piece, &VPPiece::SelectionChanged, this, &VPGraphicsPiece::on_PieceSelectionChanged); connect(m_piece, &VPPiece::PositionChanged, this, &VPGraphicsPiece::on_PiecePositionChanged); connect(m_piece, &VPPiece::RotationChanged, this, &VPGraphicsPiece::on_PieceRotationChanged); + connect(m_piece, &VPPiece::PropertiesChanged, this, &VPGraphicsPiece::on_PiecePropertiesChanged); } //--------------------------------------------------------------------------------------------------------------------- @@ -148,9 +192,11 @@ void VPGraphicsPiece::paint(QPainter *painter, const QStyleOptionGraphicsItem *o QPen pen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); QBrush noBrush(Qt::NoBrush); QBrush selectionBrush(QColor(255,160,160,60)); + QBrush blackBrush(Qt::black); painter->setPen(pen); + // selection if(isSelected()) { painter->setBrush(selectionBrush); @@ -168,7 +214,7 @@ void VPGraphicsPiece::paint(QPainter *painter, const QStyleOptionGraphicsItem *o } // paint the seam line - if(!m_seamLine.isEmpty()) + if(!m_seamLine.isEmpty() && m_piece->GetShowSeamLine()) { painter->drawPath(m_seamLine); } @@ -178,8 +224,54 @@ void VPGraphicsPiece::paint(QPainter *painter, const QStyleOptionGraphicsItem *o // paint the grainline if(!m_grainline.isEmpty()) { + // here to fill the grainlines arrow. Not wanted for mvp + // later maybe if it's configurable +// painter->setBrush(blackBrush); + painter->drawPath(m_grainline); } + + // paint the internal paths + painter->setBrush(noBrush); + if(!m_internalPaths.isEmpty()) + { + Qt::PenStyle penStyleTmp = pen.style(); + + for (int i = 0; i < m_internalPaths.size(); i++) + { + painter->setPen(m_internalPathsPenStyle.at(i)); + painter->drawPath(m_internalPaths.at(i)); + } + painter->setPen(penStyleTmp); + } + + // paint the passmarks + if(!m_passmarks.isEmpty()) + { + painter->drawPath(m_passmarks); + } + + // paint the place labels (buttons etc) + if(!m_placeLabels.isEmpty()) + { + for(auto &placeLabel : m_placeLabels) + { + painter->drawPath(placeLabel); + } + } + + + // TODO Detail & Piece Label + +// QPointF position = m_piece->GetPatternTextPosition(); +// QStringList texts = m_piece->GetPatternText(); + +// painter->drawText(); + + + + // when using m_piece->GetItem(), the results were quite bad + } //--------------------------------------------------------------------------------------------------------------------- @@ -189,11 +281,24 @@ void VPGraphicsPiece::mousePressEvent(QGraphicsSceneMouseEvent *event) //perform the default behaviour QGraphicsItem::mousePressEvent(event); - // change the cursor when clicking left button + // change the cursor when clicking the left button + if((event->button() == Qt::LeftButton)) + { + if(event->modifiers() & Qt::AltModifier) + { + setCursor(m_rotateCursor); + } + else + { + setCursor(Qt::ClosedHandCursor); + } + } + + + // change the selected state when clicking left button if (event->button() == Qt::LeftButton) { setSelected(true); - setCursor(Qt::ClosedHandCursor); if (event->modifiers() & Qt::ControlModifier) { @@ -208,12 +313,6 @@ void VPGraphicsPiece::mousePressEvent(QGraphicsSceneMouseEvent *event) if((event->button() == Qt::LeftButton) && (event->modifiers() & Qt::AltModifier)) { m_rotationStartPoint = event->scenePos(); - - QPixmap cursor_pixmap = QPixmap(":/cursor_rotate"); - cursor_pixmap = cursor_pixmap.scaledToWidth(32); - QCursor cursor_rotate = QCursor(cursor_pixmap, 16, 16); - - setCursor(cursor_rotate); } } @@ -222,6 +321,8 @@ void VPGraphicsPiece::mouseMoveEvent(QGraphicsSceneMouseEvent * event) { if((event->buttons() == Qt::LeftButton) && (event->modifiers() & Qt::AltModifier)) { + //FIXME: it flickers between the arrow cursor and the rotate cursor + setCursor(m_rotateCursor); QPointF rotationNewPoint = event->scenePos(); QPointF rotationCenter = sceneBoundingRect().center(); @@ -278,20 +379,14 @@ void VPGraphicsPiece::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) //--------------------------------------------------------------------------------------------------------------------- void VPGraphicsPiece::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { - if(event->modifiers() & Qt::AltModifier) { - // TODO FIXME: find a more efficient way - - QPixmap cursor_pixmap = QPixmap(":/cursor_rotate"); - cursor_pixmap = cursor_pixmap.scaledToWidth(32); - QCursor cursor_rotate = QCursor(cursor_pixmap, 16, 16); - - setCursor(cursor_rotate); + //FIXME: it flickers between the arrow cursor and the rotate cursor + setCursor(m_rotateCursor); } else { - setCursor(QCursor(Qt::OpenHandCursor)); + setCursor(Qt::OpenHandCursor); } } @@ -370,6 +465,15 @@ void VPGraphicsPiece::on_PieceRotationChanged() setRotation(-m_piece->GetRotation()); } +//--------------------------------------------------------------------------------------------------------------------- +void VPGraphicsPiece::on_PiecePropertiesChanged() +{ + if(scene()) + { + scene()->update(); + } +} + //--------------------------------------------------------------------------------------------------------------------- QVariant VPGraphicsPiece::itemChange(GraphicsItemChange change, const QVariant &value) { diff --git a/src/app/puzzle/vpgraphicspiece.h b/src/app/puzzle/vpgraphicspiece.h index 858c4a177..f7238a759 100644 --- a/src/app/puzzle/vpgraphicspiece.h +++ b/src/app/puzzle/vpgraphicspiece.h @@ -30,6 +30,7 @@ #define VPGRAPHICSPIECE_H #include +#include class VPPiece; @@ -63,6 +64,11 @@ public slots: */ void on_PieceRotationChanged(); + /** + * @brief on_PiecePropertiesChanged Slot called when the showSeamline / mirrored was changed + */ + void on_PiecePropertiesChanged(); + protected: QRectF boundingRect() const override; QPainterPath shape() const override; @@ -92,9 +98,16 @@ private: QPainterPath m_cuttingLine; QPainterPath m_seamLine; QPainterPath m_grainline; + QPainterPath m_passmarks; + + QVector m_internalPaths; + QVector m_internalPathsPenStyle; + + QVector m_placeLabels; QPointF m_rotationStartPoint; + QCursor m_rotateCursor; }; #endif // VPGRAPHICSPIECE_H diff --git a/src/app/puzzle/vpgraphicssheet.cpp b/src/app/puzzle/vpgraphicssheet.cpp index 42ed505d1..5c9638faf 100644 --- a/src/app/puzzle/vpgraphicssheet.cpp +++ b/src/app/puzzle/vpgraphicssheet.cpp @@ -27,6 +27,8 @@ *************************************************************************/ #include "vpgraphicssheet.h" +#include "vplayout.h" +#include //--------------------------------------------------------------------------------------------------------------------- VPGraphicsSheet::VPGraphicsSheet(VPSheet *sheet, QGraphicsItem *parent): @@ -55,12 +57,18 @@ void VPGraphicsSheet::paint(QPainter *painter, const QStyleOptionGraphicsItem *o painter->setPen(pen); painter->setBrush(noBrush); - painter->drawRect(GetMarginsRect()); + if(m_showMargin) + { + painter->drawRect(GetMarginsRect()); + } - pen.setColor(Qt::black); + if(m_showBorder) + { + pen.setColor(Qt::black); - painter->setPen(pen); - painter->drawRect(GetSheetRect()); + painter->setPen(pen); + painter->drawRect(GetSheetRect()); + } m_boundingRect = GetSheetRect(); } @@ -96,6 +104,18 @@ QRectF VPGraphicsSheet::GetMarginsRect() const return rect; } +//--------------------------------------------------------------------------------------------------------------------- +void VPGraphicsSheet::SetShowMargin(bool value) +{ + m_showMargin = value; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPGraphicsSheet::SetShowBorder(bool value) +{ + m_showBorder = value; +} + //--------------------------------------------------------------------------------------------------------------------- QRectF VPGraphicsSheet::boundingRect() const diff --git a/src/app/puzzle/vpgraphicssheet.h b/src/app/puzzle/vpgraphicssheet.h index 4ee8b4329..0cbef3a41 100644 --- a/src/app/puzzle/vpgraphicssheet.h +++ b/src/app/puzzle/vpgraphicssheet.h @@ -47,12 +47,28 @@ public: QRectF GetSheetRect() const; QRectF GetMarginsRect() const; + /** + * @brief ShowMargin Sets Wether we see the margin + * @param value true to show the margin + */ + void SetShowMargin(bool value); + + /** + * @brief ShowBorder Sets whether we see the border of the sheet + * @param value true to show the border + */ + void SetShowBorder(bool value); + + private: Q_DISABLE_COPY(VPGraphicsSheet) VPSheet *m_sheet{nullptr}; QRectF m_boundingRect; + + bool m_showMargin{true}; + bool m_showBorder{true}; }; #endif // VPGRAPHICSSHEET_H diff --git a/src/app/puzzle/vpgraphicstilegrid.cpp b/src/app/puzzle/vpgraphicstilegrid.cpp new file mode 100644 index 000000000..45e905bd9 --- /dev/null +++ b/src/app/puzzle/vpgraphicstilegrid.cpp @@ -0,0 +1,78 @@ +#include "vpgraphicstilegrid.h" + +#include "vptilefactory.h" +#include "vplayout.h" + +//--------------------------------------------------------------------------------------------------------------------- +VPGraphicsTileGrid::VPGraphicsTileGrid(VPLayout *layout, VPTileFactory *tileFactory,QGraphicsItem *parent): + QGraphicsItem(parent), + m_tileFactory(tileFactory), + m_layout(layout) +{ + +} + +//--------------------------------------------------------------------------------------------------------------------- +VPGraphicsTileGrid::~VPGraphicsTileGrid() +{ + +} + +//--------------------------------------------------------------------------------------------------------------------- +QRectF VPGraphicsTileGrid::boundingRect() const +{ + if(m_layout->GetShowTiles()) + { + return QRectF(0, + 0, + m_tileFactory->getColNb()* m_tileFactory->getDrawingAreaWidth(), + m_tileFactory->getRowNb()* m_tileFactory->getDrawingAreaHeight() + ); + } + else + { + return QRectF(0,0,0,0); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPGraphicsTileGrid::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(widget); + Q_UNUSED(option); + + if(m_layout->GetShowTiles()) + { + QPen pen(QColor(255,0,0,127), 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); + pen.setCosmetic(true); + pen.setStyle(Qt::DashLine); + QBrush noBrush(Qt::NoBrush); + painter->setPen(pen); + painter->setBrush(noBrush); + + for(int i=0;i<=m_tileFactory->getColNb();i++) + { + painter->drawLine(QPointF( + i*m_tileFactory->getDrawingAreaWidth(), + 0), + QPointF( + i*m_tileFactory->getDrawingAreaWidth(), + m_tileFactory->getRowNb()*m_tileFactory->getDrawingAreaHeight() + ) + ); + } + + for(int j=0;j<=m_tileFactory->getRowNb();j++) + { + painter->drawLine(QPointF( + 0, + j*m_tileFactory->getDrawingAreaHeight() + ), + QPointF( + m_tileFactory->getColNb()*m_tileFactory->getDrawingAreaWidth(), + j*m_tileFactory->getDrawingAreaHeight() + ) + ); + } + } +} diff --git a/src/app/puzzle/vpgraphicstilegrid.h b/src/app/puzzle/vpgraphicstilegrid.h new file mode 100644 index 000000000..9559f3e55 --- /dev/null +++ b/src/app/puzzle/vpgraphicstilegrid.h @@ -0,0 +1,57 @@ +/************************************************************************ + ** + ** @file vpgraphicstilegrid.h + ** @author Ronan Le Tiec + ** @date 19 11, 2020 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentina project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2020 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef VPGRAPHICSTILEGRID_H +#define VPGRAPHICSTILEGRID_H + +#include +#include + +#include "../vmisc/def.h" + +class VPTileFactory; +class VPLayout; + +class VPGraphicsTileGrid : public QGraphicsItem +{ +public: + explicit VPGraphicsTileGrid(VPLayout* layout, VPTileFactory *tileFactory, QGraphicsItem *parent = nullptr); + ~VPGraphicsTileGrid(); + + QRectF boundingRect() const override; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; + + +private: + Q_DISABLE_COPY(VPGraphicsTileGrid) + + VPTileFactory *m_tileFactory{nullptr}; + VPLayout *m_layout{nullptr}; +}; + +#endif // VPGRAPHICSTILEGRID_H diff --git a/src/app/puzzle/vplayout.cpp b/src/app/puzzle/vplayout.cpp index fe77d2959..539bc9e0c 100644 --- a/src/app/puzzle/vplayout.cpp +++ b/src/app/puzzle/vplayout.cpp @@ -38,6 +38,7 @@ Q_LOGGING_CATEGORY(pLayout, "p.layout") //--------------------------------------------------------------------------------------------------------------------- VPLayout::VPLayout() : m_unplacedPieceList(new VPPieceList(this)), + m_trashPieceList(new VPPieceList(this)), m_sheets(QList()) { m_unplacedPieceList->SetName(QObject::tr("Unplaced pieces")); @@ -48,6 +49,7 @@ VPLayout::~VPLayout() { qDeleteAll(m_sheets); delete m_unplacedPieceList; + delete m_trashPieceList; } //--------------------------------------------------------------------------------------------------------------------- @@ -56,6 +58,12 @@ VPPieceList* VPLayout::GetUnplacedPieceList() return m_unplacedPieceList; } +//--------------------------------------------------------------------------------------------------------------------- +VPPieceList* VPLayout::GetTrashPieceList() +{ + return m_trashPieceList; +} + //--------------------------------------------------------------------------------------------------------------------- VPSheet* VPLayout::AddSheet() { @@ -141,6 +149,31 @@ bool VPLayout::GetWarningPiecesOutOfBound() const return m_warningPiecesOutOfBound; } +//--------------------------------------------------------------------------------------------------------------------- +void VPLayout::SetTitle(QString title) +{ + m_title = title; +} + +//--------------------------------------------------------------------------------------------------------------------- +QString VPLayout::GetTitle() const +{ + return m_title; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPLayout::SetDescription(QString description) +{ + m_description = description; +} + +//--------------------------------------------------------------------------------------------------------------------- +QString VPLayout::GetDescription() const +{ + return m_description; +} + + //--------------------------------------------------------------------------------------------------------------------- void VPLayout::ClearSelection() { @@ -183,7 +216,7 @@ void VPLayout::MovePieceToPieceList(VPPiece* piece, VPPieceList* pieceList) pieceList->AddPiece(piece); // signal, that a piece was moved - emit PieceMovedToPieceList(piece, pieceListBefore,pieceList); + emit PieceMovedToPieceList(piece, pieceListBefore, pieceList); } @@ -205,3 +238,132 @@ VPSheet* VPLayout::GetFocusedSheet() { return m_focusedSheet; } + + +//--------------------------------------------------------------------------------------------------------------------- +void VPLayout::SetTilesSize(qreal width, qreal height) +{ + m_tilesSize.setWidth(width); + m_tilesSize.setHeight(height); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPLayout::SetTilesSizeConverted(qreal width, qreal height) +{ + m_tilesSize.setWidth(UnitConvertor(width, GetUnit(), Unit::Px)); + m_tilesSize.setHeight(UnitConvertor(height, GetUnit(), Unit::Px)); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPLayout::SetTilesSize(const QSizeF &size) +{ + m_tilesSize = size; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPLayout::SetTilesSizeConverted(const QSizeF &size) +{ + m_tilesSize = QSizeF( + UnitConvertor(size.width(), GetUnit(), Unit::Px), + UnitConvertor(size.height(), GetUnit(), Unit::Px) + ); +} + +//--------------------------------------------------------------------------------------------------------------------- +QSizeF VPLayout::GetTilesSize() const +{ + return m_tilesSize; +} + +//--------------------------------------------------------------------------------------------------------------------- +QSizeF VPLayout::GetTilesSize(Unit unit) const +{ + QSizeF convertedSize = QSizeF( + UnitConvertor(m_tilesSize.width(), Unit::Px, unit), + UnitConvertor(m_tilesSize.height(), Unit::Px, unit) + ); + + return convertedSize; +} + +//--------------------------------------------------------------------------------------------------------------------- +QSizeF VPLayout::GetTilesSizeConverted() const +{ + return GetTilesSize(GetUnit()); +} + +//--------------------------------------------------------------------------------------------------------------------- +PageOrientation VPLayout::GetTilesOrientation() +{ + return m_tilesOrientation; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPLayout::SetTilesOrientation(PageOrientation orientation) +{ + if(orientation != m_tilesOrientation) + { + m_tilesOrientation = orientation; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPLayout::SetTilesMargins(qreal left, qreal top, qreal right, qreal bottom) +{ + m_tilesMargins.setLeft(left); + m_tilesMargins.setTop(top); + m_tilesMargins.setRight(right); + m_tilesMargins.setBottom(bottom); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPLayout::SetTilesMarginsConverted(qreal left, qreal top, qreal right, qreal bottom) +{ + m_tilesMargins.setLeft(UnitConvertor(left, GetUnit(), Unit::Px)); + m_tilesMargins.setTop(UnitConvertor(top, GetUnit(), Unit::Px)); + m_tilesMargins.setRight(UnitConvertor(right, GetUnit(), Unit::Px)); + m_tilesMargins.setBottom(UnitConvertor(bottom, GetUnit(), Unit::Px)); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPLayout::SetTilesMargins(const QMarginsF &margins) +{ + m_tilesMargins = margins; +} + + +//--------------------------------------------------------------------------------------------------------------------- +void VPLayout::SetTilesMarginsConverted(const QMarginsF &margins) +{ + m_tilesMargins = UnitConvertor(margins, GetUnit(), Unit::Px); +} + +//--------------------------------------------------------------------------------------------------------------------- +QMarginsF VPLayout::GetTilesMargins() const +{ + return m_tilesMargins; +} + +//--------------------------------------------------------------------------------------------------------------------- +QMarginsF VPLayout::GetTilesMargins(Unit unit) const +{ + return UnitConvertor(m_tilesMargins, Unit::Px, unit); +} + +//--------------------------------------------------------------------------------------------------------------------- +QMarginsF VPLayout::GetTilesMarginsConverted() const +{ + return UnitConvertor(m_tilesMargins, Unit::Px, GetUnit()); +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VPLayout::GetShowTiles() +{ + return m_showTiles; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPLayout::SetShowTiles(bool value) +{ + m_showTiles = value; +} diff --git a/src/app/puzzle/vplayout.h b/src/app/puzzle/vplayout.h index a81017bb8..f8ff3a7ee 100644 --- a/src/app/puzzle/vplayout.h +++ b/src/app/puzzle/vplayout.h @@ -50,6 +50,12 @@ public: */ VPPieceList* GetUnplacedPieceList(); + /** + * @brief GetTrashPieceList Returns the piece list of the trash + * @return the pieces list of trashed pieces. + */ + VPPieceList* GetTrashPieceList(); + VPSheet* AddSheet(); VPSheet* AddSheet(VPSheet *sheet); QList GetSheets(); @@ -78,6 +84,30 @@ public: void SetWarningPiecesOutOfBound(bool state); bool GetWarningPiecesOutOfBound() const; + /** + * @brief SetTitle Sets the title of the layout to the given value + * @param title the title of the layout + */ + void SetTitle(QString title); + + /** + * @brief GetTitle Returns the title of the layout + * @return + */ + QString GetTitle() const; + + /** + * @brief SetDescription Sets the description of the layout to the given value + * @param description the description of the layout + */ + void SetDescription(QString description); + + /** + * @brief GetDescription Returns the description of the layout. + * @return + */ + QString GetDescription() const; + /** * @brief ClearSelection goes through the unplaced pieces and through the sheets and calls * SetIsSelected(false) for the pieces that were selected. @@ -114,6 +144,124 @@ public: VPSheet* GetFocusedSheet(); + /** + * @brief SetTilesSize sets the size of the tiles, the values have to be in Unit::Px + * @param width tiles width + * @param height tiles height + */ + void SetTilesSize(qreal width, qreal height); + + /** + * @brief SetTilesSizeConverted sets the size of the sheet, the values have to be in the layout's unit + * @param width tiles width + * @param height tiles height + */ + void SetTilesSizeConverted(qreal width, qreal height); + + /** + * @brief SetTilesSize sets the size of the tiles, the values have to be in Unit::Px + * @param size tiles size + */ + void SetTilesSize(const QSizeF &size); + /** + * @brief SetTilesSizeConverted sets the size of the tiles, the values have to be in the layout's unit + * @param size tiles size + */ + void SetTilesSizeConverted(const QSizeF &size); + + /** + * @brief GetTilesSize Returns the size of the tiles in Unit::Px + * @return tiles size in Unit::Px + */ + QSizeF GetTilesSize() const; + + /** + * @brief GetTilesSize Returns the size of the tiles in given Unit + * @return tiles size + */ + QSizeF GetTilesSize(Unit unit) const; + + /** + * @brief GetTilesSizeConverted Returns the size of the tiles in the layout's unit + * @return the size in the layout's unit + */ + QSizeF GetTilesSizeConverted() const; + + /** + * @brief GetOrientation Returns the orientation of the tiles + * @return orientation of the tiles + */ + PageOrientation GetTilesOrientation(); + + /** + * @brief SetOrientation Sets the orientation of the tiles to the given value + * @param orientation the new tiles orientation + */ + void SetTilesOrientation(PageOrientation orientation); + + /** + * @brief SetTilesMargins, set the margins of the tiles, the values have to be in Unit::Px + * @param left in Unit::Px + * @param top in Unit::Px + * @param right in Unit::Px + * @param bottom in Unit::Px + */ + void SetTilesMargins(qreal left, qreal top, qreal right, qreal bottom); + + /** + * @brief SetSheetMargins, set the margins of the tiles, the values have to be in the unit of the layout + * @param left in Unit::Px + * @param top in Unit::Px + * @param right in Unit::Px + * @param bottom in Unit::Px + */ + void SetTilesMarginsConverted(qreal left, qreal top, qreal right, qreal bottom); + + /** + * @brief SetTilesMargins set the margins of the tiles, the values have to be in Unit::Px + * @param margins tiles margins + */ + void SetTilesMargins(const QMarginsF &margins); + + /** + * @brief SetTilesMarginsConverted set the margins of the tiles, the values have to be in the unit of the layout + * @param margins tiles margins + */ + void SetTilesMarginsConverted(const QMarginsF &margins); + + /** + * @brief GetTilesMargins Returns margins of the tiles in Unit::Px + * @return the margins in Unit::Px + */ + QMarginsF GetTilesMargins() const; + + /** + * @brief GetTilesMargins Returns margins of the tiles in the given unit + * @param unit the unit in which we want the margins + * @return the margins in the given unit + */ + QMarginsF GetTilesMargins(Unit unit) const; + + /** + * @brief GetTilesMarginsConverted Returns the margins of the tiles in the layout's unit + * @return the margins in the tiles's unit + */ + QMarginsF GetTilesMarginsConverted() const; + + /** + * @brief GetShowTiles Returns true if the tiles has to be shown on the current sheet + * @return + */ + bool GetShowTiles(); + + /** + * @brief SetShowTiles Sets wether to show the tiles on the current sheet or not + * @param value true to show the tiles + */ + void SetShowTiles(bool value); + + + signals: void PieceMovedToPieceList(VPPiece *piece, VPPieceList *pieceListBefore, VPPieceList *pieceListAfter); @@ -123,16 +271,12 @@ private: VPPieceList *m_unplacedPieceList; - QList m_sheets; - /** - TODO : To be replaced by m_focusedSheet - * @brief m_focusedPieceList pointer the the focused piece list, to which pieces will be - * added via drag and drop, or if no piece list is defined. + * @brief m_trashPieceList Holds the pieces that were deleted */ - VPPieceList *m_focusedPieceList{nullptr}; - + VPPieceList *m_trashPieceList; + QList m_sheets; VPSheet *m_focusedSheet{nullptr}; // format @@ -141,7 +285,27 @@ private: bool m_warningSuperpositionOfPieces{false}; bool m_warningPiecesOutOfBound{false}; + QString m_title{}; + QString m_description{}; + + /** + * @brief m_size the Size of the tiles in Unit::Px + */ + QSizeF m_tilesSize{}; + + /** + * @brief holds the orientation of the tiles + */ + PageOrientation m_tilesOrientation {PageOrientation::Portrait}; + + // margins + /** + * @brief m_margins the margins of the tiles in Unit::Px + */ + QMarginsF m_tilesMargins{}; + + bool m_showTiles{false}; }; #endif // VPLAYOUT_H diff --git a/src/app/puzzle/vpmaingraphicsview.cpp b/src/app/puzzle/vpmaingraphicsview.cpp index a114a8ff0..17a246d96 100644 --- a/src/app/puzzle/vpmaingraphicsview.cpp +++ b/src/app/puzzle/vpmaingraphicsview.cpp @@ -37,6 +37,7 @@ #include "vplayout.h" #include "vpsheet.h" #include "../vwidgets/vmaingraphicsscene.h" +#include "vptilefactory.h" #include @@ -44,7 +45,7 @@ Q_LOGGING_CATEGORY(pMainGraphicsView, "p.mainGraphicsView") //--------------------------------------------------------------------------------------------------------------------- -VPMainGraphicsView::VPMainGraphicsView(VPLayout *layout, QWidget *parent) : +VPMainGraphicsView::VPMainGraphicsView(VPLayout *layout, VPTileFactory *tileFactory, QWidget *parent) : VMainGraphicsView(parent), m_layout(layout) { @@ -58,6 +59,9 @@ VPMainGraphicsView::VPMainGraphicsView(VPLayout *layout, QWidget *parent) : setAcceptDrops(true); + m_graphicsTileGrid = new VPGraphicsTileGrid(layout, tileFactory); + m_scene->addItem(m_graphicsTileGrid); + // add the connections connect(m_layout, &VPLayout::PieceMovedToPieceList, this, &VPMainGraphicsView::on_PieceMovedToPieceList); connect(m_scene, &VMainGraphicsScene::selectionChanged, this, @@ -71,9 +75,44 @@ void VPMainGraphicsView::RefreshLayout() m_graphicsSheet->update(); + m_graphicsTileGrid->update(); + m_scene->update(); } +//--------------------------------------------------------------------------------------------------------------------- +VMainGraphicsScene* VPMainGraphicsView::GetScene() +{ + return m_scene; +} + + +//--------------------------------------------------------------------------------------------------------------------- +void VPMainGraphicsView::PrepareForExport() +{ + m_layout->ClearSelection(); + + m_graphicsSheet->SetShowBorder(false); + m_graphicsSheet->SetShowMargin(false); + + m_showTilesTmp = m_layout->GetShowTiles(); + m_layout->SetShowTiles(false); + + RefreshLayout(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPMainGraphicsView::CleanAfterExport() +{ + m_graphicsSheet->SetShowBorder(true); + m_graphicsSheet->SetShowMargin(true); + + m_layout->SetShowTiles(m_showTilesTmp); + + RefreshLayout(); +} + + //--------------------------------------------------------------------------------------------------------------------- void VPMainGraphicsView::dragEnterEvent(QDragEnterEvent *event) { @@ -174,7 +213,7 @@ void VPMainGraphicsView::on_PieceMovedToPieceList(VPPiece *piece, VPPieceList *p scene()->removeItem(_graphicsPiece); m_graphicsPieces.removeAll(_graphicsPiece); } - else if(pieceListAfter != m_layout->GetUnplacedPieceList()) + else if(pieceListAfter != m_layout->GetUnplacedPieceList() && pieceListAfter != m_layout->GetTrashPieceList()) { if(_graphicsPiece == nullptr) { @@ -193,9 +232,22 @@ void VPMainGraphicsView::on_PieceMovedToPieceList(VPPiece *piece, VPPieceList *p //--------------------------------------------------------------------------------------------------------------------- void VPMainGraphicsView::on_SceneSelectionChanged() { - // most of the selection behaviour taks place automatically + // most of the selection behaviour takes place automatically // but we need to make sure that the unplaced pieces are unselected when the scene selection has changed // because as they are not part of the scene, they are not updated - m_layout->GetUnplacedPieceList()->ClearSelection(); + + + // make sure, that the selected items are on top + // FIXME: maybe there is a more proper way to do it + for(auto graphicPiece : m_graphicsPieces) + { + if(!graphicPiece->GetPiece()->GetIsSelected()) + { + if(!m_scene->selectedItems().isEmpty()) + { + graphicPiece->stackBefore(m_scene->selectedItems().first()); + } + } + } } diff --git a/src/app/puzzle/vpmaingraphicsview.h b/src/app/puzzle/vpmaingraphicsview.h index 15709c520..b1c84bc90 100644 --- a/src/app/puzzle/vpmaingraphicsview.h +++ b/src/app/puzzle/vpmaingraphicsview.h @@ -31,16 +31,19 @@ #include "vpgraphicssheet.h" #include "vpgraphicspiece.h" +#include "vptilefactory.h" +#include "vpgraphicstilegrid.h" #include "../vwidgets/vmaingraphicsview.h" class VMainGraphicsScene; +class VPTileFactory; class VPMainGraphicsView : public VMainGraphicsView { Q_OBJECT public: - VPMainGraphicsView(VPLayout *layout, QWidget *parent); + VPMainGraphicsView(VPLayout *layout, VPTileFactory *tileFactory, QWidget *parent); ~VPMainGraphicsView() = default; /** @@ -48,6 +51,24 @@ public: */ void RefreshLayout(); + + /** + * @brief GetScene Returns the scene of the view + * @return + */ + VMainGraphicsScene* GetScene(); + + /** + * @brief PrepareForExport prepares the graphic for an export (i.e hide margin etc) + */ + void PrepareForExport(); + + /** + * @brief CleanAfterExport cleans the graphic for an export (i.e show margin etc) + */ + void CleanAfterExport(); + + protected: void dragEnterEvent(QDragEnterEvent *event) override; void dragMoveEvent(QDragMoveEvent *event) override; @@ -56,6 +77,8 @@ protected: void keyPressEvent(QKeyEvent *event) override; + void drawTilesLine(); + private slots: /** * @brief on_PieceMovedToPieceList The slot is called when the given piece was moved from the given piece list to the other @@ -77,10 +100,18 @@ private: VMainGraphicsScene *m_scene{nullptr}; VPGraphicsSheet *m_graphicsSheet{nullptr}; + + VPGraphicsTileGrid *m_graphicsTileGrid{nullptr}; + VPLayout *m_layout{nullptr}; QList m_graphicsPieces{}; + /** + * variable to hold temporarly hte value of the show tiles + */ + bool m_showTilesTmp{false}; + }; #endif // VPMAINGRAPHICSVIEW_H diff --git a/src/app/puzzle/vpmainwindow.cpp b/src/app/puzzle/vpmainwindow.cpp index 863da9047..6a6efa726 100644 --- a/src/app/puzzle/vpmainwindow.cpp +++ b/src/app/puzzle/vpmainwindow.cpp @@ -29,6 +29,8 @@ #include #include +#include +#include #include "ui_vpmainwindow.h" #include "dialogs/vpdialogabout.h" @@ -40,6 +42,7 @@ #include "../vmisc/projectversion.h" #include "../ifc/xml/vlayoutconverter.h" #include "../ifc/exception/vexception.h" +#include "../vwidgets/vmaingraphicsscene.h" #include "vpsheet.h" #include @@ -73,19 +76,35 @@ VPMainWindow::VPMainWindow(const VPCommandLinePtr &cmd, QWidget *parent) : m_layout->SetUnit(Unit::Cm); m_layout->SetWarningSuperpositionOfPieces(true); + m_layout->SetTitle(QString("My Test Layout")); + m_layout->SetDescription(QString("Description of my Layout")); + + m_layout->SetTilesSizeConverted(21,29.7); + m_layout->SetTilesOrientation(PageOrientation::Portrait); + m_layout->SetTilesMarginsConverted(1,1,1,1); + m_layout->SetShowTiles(true); + // -------------------------------------------------------- ui->setupUi(this); + // init the tile factory + m_tileFactory = new VPTileFactory(m_layout, qApp->Settings()); + m_tileFactory->refreshTileInfos(); + InitMenuBar(); InitProperties(); InitCarrousel(); + InitMainGraphics(); + InitZoomToolBar(); SetPropertiesData(); ReadSettings(); + + } //--------------------------------------------------------------------------------------------------------------------- @@ -183,6 +202,12 @@ void VPMainWindow::ImportRawLayouts(const QStringList &rawLayouts) } } +//--------------------------------------------------------------------------------------------------------------------- +void VPMainWindow::InitZoom() +{ + m_graphicsView->ZoomFitBest(); +} + //--------------------------------------------------------------------------------------------------------------------- VPPiece* VPMainWindow::CreatePiece(const VLayoutPiece &rawPiece) { @@ -231,6 +256,7 @@ void VPMainWindow::InitMenuBar() void VPMainWindow::InitProperties() { InitPropertyTabCurrentPiece(); + InitPropertyTabCurrentSheet(); InitPropertyTabLayout(); InitPropertyTabTiles(); } @@ -238,6 +264,10 @@ void VPMainWindow::InitProperties() //--------------------------------------------------------------------------------------------------------------------- void VPMainWindow::InitPropertyTabCurrentPiece() { + // FIXME ---- For MVP we hide a few things. To be displayed when functions there + ui->groupBoxLayoutControl->hide(); + ui->groupBoxCurrentPieceGeometry->hide(); + // ------------------------------ placement ----------------------------------- connect(ui->doubleSpinBoxCurrentPieceBoxPositionX, QOverload::of(&QDoubleSpinBox::valueChanged), this, @@ -246,21 +276,12 @@ void VPMainWindow::InitPropertyTabCurrentPiece() &VPMainWindow::on_CurrentPiecePositionEdited); } - //--------------------------------------------------------------------------------------------------------------------- -void VPMainWindow::InitPropertyTabLayout() +void VPMainWindow::InitPropertyTabCurrentSheet() { - // -------------------- init the unit combobox --------------------- - ui->comboBoxLayoutUnit->addItem(tr("Centimeters"), QVariant(UnitsToStr(Unit::Cm))); - ui->comboBoxLayoutUnit->addItem(tr("Millimiters"), QVariant(UnitsToStr(Unit::Mm))); - ui->comboBoxLayoutUnit->addItem(tr("Inches"), QVariant(UnitsToStr(Unit::Inch))); - - // set default unit - TODO when we have the setting for the unit -// const qint32 indexUnit = -1;//ui->comboBoxLayoutUnit->findData(qApp->ValentinaSettings()->GetUnit()); -// if (indexUnit != -1) -// { -// ui->comboBoxLayoutUnit->setCurrentIndex(indexUnit); -// } + // FIXME ---- For MVP we hide a few things. To be displayed when functions there + ui->pushButtonSheetRemoveUnusedLength->hide(); + ui->groupBoxSheetControl->hide(); // some of the UI Elements are connected to the slots via auto-connect // see https://doc.qt.io/qt-5/designer-using-a-ui-file.html#widgets-and-dialogs-with-auto-connect @@ -293,18 +314,96 @@ void VPMainWindow::InitPropertyTabLayout() connect(ui->radioButtonSheetFollowGrainlineHorizontal, QOverload::of(&QRadioButton::clicked), this, &VPMainWindow::on_SheetFollowGrainlineChanged); - // -------------------- export --------------------------- + // -------------------- sheet template --------------------------- - // TODO init the file format export combobox + // FIXME: find a nicer way to initiliase it + QVector sheetTemplates = QVector(); + sheetTemplates.append(PaperSizeTemplate::A0); + sheetTemplates.append(PaperSizeTemplate::A1); + sheetTemplates.append(PaperSizeTemplate::A2); + sheetTemplates.append(PaperSizeTemplate::A3); + sheetTemplates.append(PaperSizeTemplate::A4); + sheetTemplates.append(PaperSizeTemplate::Letter); + sheetTemplates.append(PaperSizeTemplate::Legal); + sheetTemplates.append(PaperSizeTemplate::Tabloid); + sheetTemplates.append(PaperSizeTemplate::Roll24in); + sheetTemplates.append(PaperSizeTemplate::Roll30in); + sheetTemplates.append(PaperSizeTemplate::Roll36in); + sheetTemplates.append(PaperSizeTemplate::Roll42in); + sheetTemplates.append(PaperSizeTemplate::Roll44in); + sheetTemplates.append(PaperSizeTemplate::Roll48in); + sheetTemplates.append(PaperSizeTemplate::Roll62in); + sheetTemplates.append(PaperSizeTemplate::Roll72in); + sheetTemplates.append(PaperSizeTemplate::Custom); + ui->comboBoxSheetTemplate->blockSignals(true); + VPSheet::PopulateComboBox(&sheetTemplates, ui->comboBoxSheetTemplate); + ui->comboBoxSheetTemplate->blockSignals(false); + + ui->comboBoxSheetTemplate->setCurrentIndex(0); } //--------------------------------------------------------------------------------------------------------------------- void VPMainWindow::InitPropertyTabTiles() { - // for the MVP we don't want the tiles tab. - // we remove it. As soon as we need it, update this code - ui->tabWidgetProperties->removeTab(2); // remove tiles + // -------------------- layout width, length, orientation ------------------------ + connect(ui->doubleSpinBoxTilesWidth, QOverload::of(&QDoubleSpinBox::valueChanged), this, + &VPMainWindow::on_TilesSizeChanged); + connect(ui->doubleSpinBoxTilesLength, QOverload::of(&QDoubleSpinBox::valueChanged), this, + &VPMainWindow::on_TilesSizeChanged); + connect(ui->radioButtonTilesPortrait, QOverload::of(&QRadioButton::clicked), this, + &VPMainWindow::on_TilesOrientationChanged); + connect(ui->radioButtonTilesLandscape, QOverload::of(&QRadioButton::clicked), this, + &VPMainWindow::on_TilesOrientationChanged); + + // -------------------- tiles template + QVector tilesTemplates = QVector(); + tilesTemplates.append(PaperSizeTemplate::A0); + tilesTemplates.append(PaperSizeTemplate::A1); + tilesTemplates.append(PaperSizeTemplate::A2); + tilesTemplates.append(PaperSizeTemplate::A3); + tilesTemplates.append(PaperSizeTemplate::A4); + tilesTemplates.append(PaperSizeTemplate::Letter); + tilesTemplates.append(PaperSizeTemplate::Legal); + tilesTemplates.append(PaperSizeTemplate::Custom); + + ui->comboBoxTilesTemplate->blockSignals(true); + VPSheet::PopulateComboBox(&tilesTemplates, ui->comboBoxTilesTemplate); + ui->comboBoxTilesTemplate->blockSignals(false); + + ui->comboBoxTilesTemplate->setCurrentIndex(4); //A4 + + + // -------------------- margins ------------------------ + connect(ui->doubleSpinBoxTilesMarginTop, QOverload::of(&QDoubleSpinBox::valueChanged), this, + &VPMainWindow::on_TilesMarginChanged); + connect(ui->doubleSpinBoxTilesMarginRight, QOverload::of(&QDoubleSpinBox::valueChanged), this, + &VPMainWindow::on_TilesMarginChanged); + connect(ui->doubleSpinBoxTilesMarginBottom, QOverload::of(&QDoubleSpinBox::valueChanged), this, + &VPMainWindow::on_TilesMarginChanged); + connect(ui->doubleSpinBoxTilesMarginLeft, QOverload::of(&QDoubleSpinBox::valueChanged), this, + &VPMainWindow::on_TilesMarginChanged); +} + + +//--------------------------------------------------------------------------------------------------------------------- +void VPMainWindow::InitPropertyTabLayout() +{ + + // FIXME ---- For MVP we hide a few things. To be displayed when functions there + ui->groupBoxLayoutControl->hide(); + + // -------------------- init the unit combobox --------------------- + ui->comboBoxLayoutUnit->addItem(tr("Centimeters"), QVariant(UnitsToStr(Unit::Cm))); + ui->comboBoxLayoutUnit->addItem(tr("Millimiters"), QVariant(UnitsToStr(Unit::Mm))); + ui->comboBoxLayoutUnit->addItem(tr("Inches"), QVariant(UnitsToStr(Unit::Inch))); + + // set default unit - TODO when we have the setting for the unit +// const qint32 indexUnit = -1;//ui->comboBoxLayoutUnit->findData(qApp->ValentinaSettings()->GetUnit()); +// if (indexUnit != -1) +// { +// ui->comboBoxLayoutUnit->setCurrentIndex(indexUnit); +// } } //--------------------------------------------------------------------------------------------------------------------- @@ -356,6 +455,7 @@ void VPMainWindow::SetPropertyTabCurrentPieceData() // set the value to the current piece ui->lineEditCurrentPieceName->setText(selectedPiece->GetName()); + ui->plainTextEditCurrentPieceUUID->setPlainText(selectedPiece->GetUUID().toString()); ui->checkBoxCurrentPieceShowSeamline->setChecked(selectedPiece->GetShowSeamLine()); ui->checkBoxCurrentPieceMirrorPiece->setChecked(selectedPiece->GetPieceMirrored()); @@ -393,7 +493,7 @@ void VPMainWindow::SetPropertyTabSheetData() SetDoubleSpinBoxValue(ui->doubleSpinBoxSheetLength, size.height()); // Set Orientation - if(size.width() <= size.height()) + if(m_layout->GetFocusedSheet()->GetOrientation() == PageOrientation::Portrait) { ui->radioButtonSheetPortrait->setChecked(true); } @@ -416,10 +516,42 @@ void VPMainWindow::SetPropertyTabSheetData() SetCheckBoxValue(ui->checkBoxSheetStickyEdges, m_layout->GetFocusedSheet()->GetStickyEdges()); } + +//--------------------------------------------------------------------------------------------------------------------- +void VPMainWindow::SetPropertyTabTilesData() +{ + // set Width / Length + QSizeF size = m_layout->GetTilesSizeConverted(); + SetDoubleSpinBoxValue(ui->doubleSpinBoxTilesWidth, size.width()); + SetDoubleSpinBoxValue(ui->doubleSpinBoxTilesLength, size.height()); + + // Set Orientation + if(m_layout->GetTilesOrientation() == PageOrientation::Portrait) + { + ui->radioButtonSheetPortrait->setChecked(true); + } + else + { + ui->radioButtonSheetLandscape->setChecked(true); + } + + // set margins + QMarginsF margins = m_layout->GetTilesMarginsConverted(); + SetDoubleSpinBoxValue(ui->doubleSpinBoxTilesMarginLeft, margins.left()); + SetDoubleSpinBoxValue(ui->doubleSpinBoxTilesMarginTop, margins.top()); + SetDoubleSpinBoxValue(ui->doubleSpinBoxTilesMarginRight, margins.right()); + SetDoubleSpinBoxValue(ui->doubleSpinBoxTilesMarginBottom, margins.bottom()); + + // set "show tiles" checkbox + SetCheckBoxValue(ui->checkBoxTilesShowTiles, m_layout->GetShowTiles()); +} + //--------------------------------------------------------------------------------------------------------------------- void VPMainWindow::SetPropertyTabLayoutData() { - // TODO FIXME : Set name and description + // set the title and description + ui->lineEditLayoutName->setText(m_layout->GetTitle()); + ui->plainTextEditLayoutDescription->setPlainText(m_layout->GetDescription()); // set Unit int index = ui->comboBoxLayoutUnit->findData(QVariant(UnitsToStr(m_layout->GetUnit()))); @@ -435,21 +567,78 @@ void VPMainWindow::SetPropertyTabLayoutData() SetCheckBoxValue(ui->checkBoxLayoutWarningPiecesSuperposition, m_layout->GetWarningSuperpositionOfPieces()); } -//--------------------------------------------------------------------------------------------------------------------- -void VPMainWindow::SetPropertyTabTilesData() -{ -} //--------------------------------------------------------------------------------------------------------------------- void VPMainWindow::InitMainGraphics() { - m_graphicsView = new VPMainGraphicsView(m_layout, this); + m_graphicsView = new VPMainGraphicsView(m_layout, m_tileFactory, this); ui->centralWidget->layout()->addWidget(m_graphicsView); m_graphicsView->RefreshLayout(); + + connect(m_graphicsView, &VPMainGraphicsView::ScaleChanged, this, &VPMainWindow::on_ScaleChanged); + connect(m_graphicsView->GetScene(), &VMainGraphicsScene::mouseMove, this, &VPMainWindow::on_MouseMoved); } +//--------------------------------------------------------------------------------------------------------------------- +void VPMainWindow::InitZoomToolBar() +{ + if (not m_doubleSpinBoxScale.isNull()) + { + delete m_doubleSpinBoxScale; + } + + if (m_mouseCoordinate != nullptr) + { + delete m_mouseCoordinate; + } + + // connect the zoom buttons and shortcuts to the slots + QList zoomInShortcuts; + zoomInShortcuts.append(QKeySequence(QKeySequence::ZoomIn)); + zoomInShortcuts.append(QKeySequence(Qt::ControlModifier + Qt::Key_Plus + Qt::KeypadModifier)); + ui->actionZoomIn->setShortcuts(zoomInShortcuts); + connect(ui->actionZoomIn, &QAction::triggered, m_graphicsView, &VPMainGraphicsView::ZoomIn); + + QList zoomOutShortcuts; + zoomOutShortcuts.append(QKeySequence(QKeySequence::ZoomOut)); + zoomOutShortcuts.append(QKeySequence(Qt::ControlModifier + Qt::Key_Minus + Qt::KeypadModifier)); + ui->actionZoomOut->setShortcuts(zoomOutShortcuts); + connect(ui->actionZoomOut, &QAction::triggered, m_graphicsView, &VPMainGraphicsView::ZoomOut); + + QList zoomOriginalShortcuts; + zoomOriginalShortcuts.append(QKeySequence(Qt::ControlModifier + Qt::Key_0)); + zoomOriginalShortcuts.append(QKeySequence(Qt::ControlModifier + Qt::Key_0 + Qt::KeypadModifier)); + ui->actionZoomOriginal->setShortcuts(zoomOriginalShortcuts); + connect(ui->actionZoomOriginal, &QAction::triggered, m_graphicsView, &VPMainGraphicsView::ZoomOriginal); + + QList zoomFitBestShortcuts; + zoomFitBestShortcuts.append(QKeySequence(Qt::ControlModifier + Qt::Key_Equal)); + ui->actionZoomFitBest->setShortcuts(zoomFitBestShortcuts); + connect(ui->actionZoomFitBest, &QAction::triggered, m_graphicsView, &VPMainGraphicsView::ZoomFitBest); + + // defined the scale + ui->toolBarZoom->addSeparator(); + QLabel* zoomScale = new QLabel(tr("Scale:"), this); + ui->toolBarZoom->addWidget(zoomScale); + + m_doubleSpinBoxScale = new QDoubleSpinBox(this); + m_doubleSpinBoxScale->setDecimals(1); + m_doubleSpinBoxScale->setSuffix("%"); + on_ScaleChanged(m_graphicsView->transform().m11()); + connect(m_doubleSpinBoxScale.data(), QOverload::of(&QDoubleSpinBox::valueChanged), + this, [this](double d){m_graphicsView->Zoom(d/100.0);}); + ui->toolBarZoom->addWidget(m_doubleSpinBoxScale); + + + // define the mouse position + ui->toolBarZoom->addSeparator(); + + m_mouseCoordinate = new QLabel(QString("0, 0 (%1)").arg(UnitsToStr(m_layout->GetUnit(), true))); + ui->toolBarZoom->addWidget(m_mouseCoordinate); + ui->toolBarZoom->addSeparator(); +} //--------------------------------------------------------------------------------------------------------------------- void VPMainWindow::SetDoubleSpinBoxValue(QDoubleSpinBox *spinBox, qreal value) @@ -560,6 +749,81 @@ bool VPMainWindow::MaybeSave() return true; } +//--------------------------------------------------------------------------------------------------------------------- +void VPMainWindow::generateTiledPdf(QString fileName) +{ + if(not fileName.isEmpty()) + { + m_graphicsView->PrepareForExport(); + m_tileFactory->refreshTileInfos(); + + PageOrientation tilesOrientation = m_layout->GetTilesOrientation(); + + // ------------- Set up the printer + QPrinter* printer = new QPrinter(); + + printer->setCreator(QGuiApplication::applicationDisplayName()+QChar(QChar::Space)+ + QCoreApplication::applicationVersion()); + printer->setOrientation(QPrinter::Portrait); // in the pdf file the pages should always be in portrait + + // here we might need to so some rounding for the size. + printer->setPageSize(QPageSize(m_layout->GetTilesSize(Unit::Mm), + QPageSize::Millimeter)); + printer->setFullPage(true); + + #ifdef Q_OS_MAC + printer->setOutputFormat(QPrinter::NativeFormat); + #else + printer->setOutputFormat(QPrinter::PdfFormat); + #endif + + printer->setOutputFileName(fileName); + printer->setResolution(static_cast(PrintDPI)); + printer->setDocName("Test"); // FIXME + + // ------------- Set up the painter + QPainter painter; + if (not painter.begin(printer)) + { // failed to open file + qCritical() << tr("Failed to open file, is it writable?"); + return; + } + painter.setFont( QFont( QStringLiteral("Arial"), 8, QFont::Normal ) ); + painter.setRenderHint(QPainter::Antialiasing, true); + painter.setBrush ( QBrush ( Qt::NoBrush ) ); + + if(tilesOrientation == PageOrientation::Landscape) + { + // The landscape tiles have to be rotated, because the pages + // stay portrait in the pdf + painter.rotate(90); + painter.translate(0, -ToPixel(printer->pageRect(QPrinter::Millimeter).width(), Unit::Mm)); + } + + for(int row=0;rowgetRowNb();row++) // for each row of the tiling grid + { + for(int col=0;colgetColNb();col++) // for each column of tiling grid + { + if(not (row == 0 && col == 0)) + { + if (not printer->newPage()) + { + qWarning("failed in flushing page to disk, disk full?"); + return; + } + } + + m_tileFactory->drawTile(&painter, m_graphicsView, row, col); + } + } + + painter.end(); + + m_graphicsView->CleanAfterExport(); + } +} + + //--------------------------------------------------------------------------------------------------------------------- void VPMainWindow::on_actionNew_triggered() { @@ -669,7 +933,8 @@ void VPMainWindow::on_actionSave_triggered() //--------------------------------------------------------------------------------------------------------------------- void VPMainWindow::on_actionSaveAs_triggered() { - // TODO / FIXME : See valentina how the save is done over there. we need to add the extension .vlt, check for empty file names etc. + // TODO / FIXME : See valentina how the save is done over there. we need to add the + // extension .vlt, check for empty file names etc. //Get list last open files QStringList recentFiles = qApp->PuzzleSettings()->GetRecentFileList(); @@ -771,29 +1036,66 @@ void VPMainWindow::on_comboBoxLayoutUnit_currentIndexChanged(int index) m_layout->SetUnit(Unit::Inch); } - SetPropertyTabSheetData(); SetPropertyTabCurrentPieceData(); + SetPropertyTabSheetData(); + SetPropertyTabTilesData(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPMainWindow::on_lineEditSheetName_textChanged(const QString &text) +{ + m_layout->GetFocusedSheet()->SetName(text); + + if(m_carrousel != nullptr) + { + m_carrousel->RefreshFocusedSheetName(); + } } //--------------------------------------------------------------------------------------------------------------------- void VPMainWindow::on_comboBoxSheetTemplate_currentIndexChanged(int index) { - // just for test purpuses, to be removed: - QMessageBox msgBox; - msgBox.setText("TODO VPMainWindow::SheetTemplateChanged"); - int ret = msgBox.exec(); + PaperSizeTemplate tmpl = static_cast( + ui->comboBoxSheetTemplate->itemData(index).toInt() + ); - Q_UNUSED(index); - Q_UNUSED(ret); + QSizeF tmplSize = VPSheet::GetTemplateSize(tmpl); + if(!tmplSize.isEmpty()) + { + ui->doubleSpinBoxSheetWidth->blockSignals(true); + ui->doubleSpinBoxSheetLength->blockSignals(true); + ui->doubleSpinBoxSheetWidth->setValue(UnitConvertor(tmplSize.width(), Unit::Px, m_layout->GetUnit())); + ui->doubleSpinBoxSheetLength->setValue(UnitConvertor(tmplSize.height(), Unit::Px, m_layout->GetUnit())); - // TODO + on_SheetSizeChanged(false); + + ui->doubleSpinBoxSheetWidth->blockSignals(false); + ui->doubleSpinBoxSheetLength->blockSignals(false); + } } //--------------------------------------------------------------------------------------------------------------------- -void VPMainWindow::on_SheetSizeChanged() +void VPMainWindow::on_SheetSizeChanged(bool changedViaSizeCombobox) { - m_layout->GetFocusedSheet()->SetSheetSizeConverted(ui->doubleSpinBoxSheetWidth->value(), ui->doubleSpinBoxSheetLength->value()); + m_layout->GetFocusedSheet()->SetSheetSizeConverted( + ui->doubleSpinBoxSheetWidth->value(), + ui->doubleSpinBoxSheetLength->value() + ); + + if(changedViaSizeCombobox) + { + ui->comboBoxSheetTemplate->blockSignals(true); + + // we don't try to get the right size, because it doesn't work well because of mm / inch conversion + int index = ui->comboBoxSheetTemplate->findData( + QVariant(static_cast(PaperSizeTemplate::Custom))); + + ui->comboBoxSheetTemplate->setCurrentIndex(index); + ui->comboBoxSheetTemplate->blockSignals(false); + } + + m_tileFactory->refreshTileInfos(); // TODO Undo / Redo @@ -812,6 +1114,7 @@ void VPMainWindow::on_SheetOrientationChanged() { m_layout->GetFocusedSheet()->SetOrientation(PageOrientation::Landscape); } + m_tileFactory->refreshTileInfos(); // TODO Undo / Redo @@ -847,6 +1150,120 @@ void VPMainWindow::on_SheetMarginChanged() m_graphicsView->RefreshLayout(); } +//--------------------------------------------------------------------------------------------------------------------- +void VPMainWindow::on_comboBoxTilesTemplate_currentIndexChanged(int index) +{ + PaperSizeTemplate tmpl = static_cast( + ui->comboBoxTilesTemplate->itemData(index).toInt() + ); + + QSizeF tmplSize = VPSheet::GetTemplateSize(tmpl); + if(!tmplSize.isEmpty()) + { + ui->doubleSpinBoxTilesWidth->blockSignals(true); + ui->doubleSpinBoxTilesLength->blockSignals(true); + + ui->doubleSpinBoxTilesWidth->setValue(UnitConvertor(tmplSize.width(), Unit::Px, m_layout->GetUnit())); + ui->doubleSpinBoxTilesLength->setValue(UnitConvertor(tmplSize.height(), Unit::Px, m_layout->GetUnit())); + + on_TilesSizeChanged(false); + + ui->doubleSpinBoxTilesWidth->blockSignals(false); + ui->doubleSpinBoxTilesLength->blockSignals(false); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPMainWindow::on_TilesSizeChanged(bool changedViaSizeCombobox) +{ + m_layout->SetTilesSizeConverted(ui->doubleSpinBoxTilesWidth->value(), ui->doubleSpinBoxTilesLength->value()); + m_tileFactory->refreshTileInfos(); + + if(changedViaSizeCombobox) + { + ui->comboBoxTilesTemplate->blockSignals(true); + + // we don't try to get the right size, because it doesn't work well because of mm / inch conversion + int index = ui->comboBoxTilesTemplate->findData( + QVariant(static_cast(PaperSizeTemplate::Custom))); + + ui->comboBoxTilesTemplate->setCurrentIndex(index); + ui->comboBoxTilesTemplate->blockSignals(false); + } + + // TODO Undo / Redo + + if(m_graphicsView != nullptr) + { + m_graphicsView->RefreshLayout(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPMainWindow::on_TilesOrientationChanged() +{ + // Updates the orientation + if(ui->radioButtonTilesPortrait->isChecked()) + { + m_layout->SetTilesOrientation(PageOrientation::Portrait); + } + else + { + m_layout->SetTilesOrientation(PageOrientation::Landscape); + } + m_tileFactory->refreshTileInfos(); + + // TODO Undo / Redo + + m_graphicsView->RefreshLayout(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPMainWindow::on_TilesMarginChanged() +{ + m_layout->SetTilesMarginsConverted( + ui->doubleSpinBoxTilesMarginLeft->value(), + ui->doubleSpinBoxTilesMarginTop->value(), + ui->doubleSpinBoxTilesMarginRight->value(), + ui->doubleSpinBoxTilesMarginBottom->value() + ); + m_tileFactory->refreshTileInfos(); + + // TODO Undo / Redo + + m_graphicsView->RefreshLayout(); +} + + +//--------------------------------------------------------------------------------------------------------------------- +void VPMainWindow::on_checkBoxTilesShowTiles_toggled(bool checked) +{ + m_layout->SetShowTiles(checked); + + // TODO Undo / Redo + + m_graphicsView->RefreshLayout(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPMainWindow::on_pushButtonTilesExport_clicked() +{ + // svg export to do some test for the first test + + QString dir = QDir::homePath(); + QString filters(tr("PDF Files") + QLatin1String("(*.pdf)")); + QString fileName = QFileDialog::getSaveFileName(this, tr("Save as"), + dir + QLatin1String("/") + tr("Layout") + QLatin1String(".pdf"), + filters, nullptr +#ifdef Q_OS_LINUX + , QFileDialog::DontUseNativeDialog +#endif + ); + + generateTiledPdf(fileName); +} + + //--------------------------------------------------------------------------------------------------------------------- void VPMainWindow::on_SheetFollowGrainlineChanged() @@ -901,14 +1318,43 @@ void VPMainWindow::on_checkBoxSheetStickyEdges_toggled(bool checked) //--------------------------------------------------------------------------------------------------------------------- void VPMainWindow::on_pushButtonSheetExport_clicked() { - // just for test purpuses, to be removed: - QMessageBox msgBox; - msgBox.setText("TODO VPMainWindow::on_pushButtonSheetExport_clicked"); - int ret = msgBox.exec(); + // svg export to do some test for the first test - Q_UNUSED(ret); + QString dir = QDir::homePath(); + QString filters(tr("SVG Files") + QLatin1String("(*.svg)")); + QString fileName = QFileDialog::getSaveFileName(this, tr("Save as"), + dir + QLatin1String("/") + tr("Layout") + QLatin1String(".svg"), + filters, nullptr +#ifdef Q_OS_LINUX + , QFileDialog::DontUseNativeDialog +#endif + ); - // TODO + if(not fileName.isEmpty()) + { + m_graphicsView->PrepareForExport(); + + const QSizeF s = m_layout->GetFocusedSheet()->GetSheetSize(); + const QRectF r = QRectF(0, 0, s.width(), s.height()); + + QSvgGenerator generator; + generator.setFileName(fileName); + generator.setSize(QSize(qFloor(s.width()),qFloor(s.height()))); + generator.setViewBox(r); + generator.setTitle(tr("Pattern")); + generator.setDescription(m_layout->GetDescription().toHtmlEscaped()); + generator.setResolution(static_cast(PrintDPI)); + + QPainter painter; + painter.begin(&generator); + painter.setRenderHint(QPainter::Antialiasing, true); + painter.setPen(QPen(Qt::black, qApp->Settings()->WidthHairLine(), Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); + painter.setBrush ( QBrush ( Qt::NoBrush ) ); + m_graphicsView->GetScene()->render(&painter, r, r, Qt::IgnoreAspectRatio); + painter.end(); + + m_graphicsView->CleanAfterExport(); + } } @@ -1002,3 +1448,30 @@ void VPMainWindow::on_PieceRotationChanged() SetDoubleSpinBoxValue(ui->doubleSpinBoxCurrentPieceAngle, angle); } } + + +//--------------------------------------------------------------------------------------------------------------------- +void VPMainWindow::on_ScaleChanged(qreal scale) +{ + if (not m_doubleSpinBoxScale.isNull()) + { + m_doubleSpinBoxScale->blockSignals(true); + m_doubleSpinBoxScale->setMaximum(qFloor(VPMainGraphicsView::MaxScale()*1000)/10.0); + m_doubleSpinBoxScale->setMinimum(qFloor(VPMainGraphicsView::MinScale()*1000)/10.0); + m_doubleSpinBoxScale->setValue(qFloor(scale*1000)/10.0); + m_doubleSpinBoxScale->setSingleStep(1); + m_doubleSpinBoxScale->blockSignals(false); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPMainWindow::on_MouseMoved(const QPointF &scenePos) +{ + if (m_mouseCoordinate != nullptr) + { + m_mouseCoordinate->setText(QStringLiteral("%1, %2 (%3)") + .arg(static_cast(FromPixel(scenePos.x(), m_layout->GetUnit()))) + .arg(static_cast(FromPixel(scenePos.y(), m_layout->GetUnit()))) + .arg(UnitsToStr(m_layout->GetUnit(), true))); + } +} diff --git a/src/app/puzzle/vpmainwindow.h b/src/app/puzzle/vpmainwindow.h index 65380c4dc..aaf5bd0c0 100644 --- a/src/app/puzzle/vpmainwindow.h +++ b/src/app/puzzle/vpmainwindow.h @@ -31,6 +31,7 @@ #include #include #include +#include #include "../vmisc/def.h" #include "vpcarrousel.h" @@ -38,7 +39,9 @@ #include "vplayout.h" #include "vppiece.h" #include "../vlayout/vlayoutpiece.h" +#include "vptilefactory.h" #include "vpcommandline.h" +#include "../vlayout/vlayoutdef.h" namespace Ui { @@ -74,6 +77,11 @@ public: */ void ImportRawLayouts(const QStringList &rawLayouts); + /** + * @brief InitZoom Initialises the zoom to fit best + */ + void InitZoom(); + public slots: /** * @brief on_actionNew_triggered When the menu action File > New @@ -98,6 +106,18 @@ private: VPLayout *m_layout{nullptr}; QListm_selectedPieces{QList()}; + VPTileFactory *m_tileFactory{nullptr}; + + /** + * @brief spin box with the scale factor of the graphic view + */ + QPointer m_doubleSpinBoxScale{nullptr}; + + /** + * @brief mouseCoordinate pointer to label who show mouse coordinate. + */ + QLabel* m_mouseCoordinate{nullptr}; + /** * @brief CreatePiece creates a piece from the given VLayoutPiece data * @param rawPiece the raw piece data @@ -119,6 +139,11 @@ private: */ void InitPropertyTabCurrentPiece(); + /** + * @brief InitPropertyTabCurrentSheet Inits the current sheet tab in the properties; + */ + void InitPropertyTabCurrentSheet(); + /** * @brief InitPropertyTabLayout Inits the layout tab in the properties */ @@ -139,6 +164,11 @@ private: */ void InitMainGraphics(); + /** + * @brief InitToolBar Initialises the tool bar + */ + void InitZoomToolBar(); + /** * @brief SetPropertiesData Sets the values of UI elements * in all the property tabs to the values saved in m_layout @@ -190,6 +220,13 @@ private: bool MaybeSave(); + /** + * @brief generateTiledPdf Generates the tiled Pdf in the given filename + * @param filename + */ + void generateTiledPdf(QString fileName); + + private slots: /** * @brief on_actionOpen_triggered When the menu action File > Open is @@ -248,42 +285,50 @@ private slots: */ void on_comboBoxLayoutUnit_currentIndexChanged(int index); + /** + * @brief on_lineEditSheetName_textChanged When the name of the sheet is changed + * in the sheet layout tab + * @param text + */ + void on_lineEditSheetName_textChanged(const QString &text); + /** * @brief on_comboBoxLayoutTemplate_currentIndexChanged When the template is - * changed in the layout property tab. + * changed in the sheet property tab. * The slot is automatically connected through name convention. * @param index the index of the selected templated */ void on_comboBoxSheetTemplate_currentIndexChanged(int index); /** - * @brief LayoutSizeChanged When the width or the length has been changed in - * the layout property tab + * @brief on_SheetSizeChanged When the width or the length has been changed in + * the sheet property tab + * @param changedViaSizeCombobox true if the change happened through the combobox */ - void on_SheetSizeChanged(); + void on_SheetSizeChanged(bool changedViaSizeCombobox = true); /** - * @brief LayoutOrientationChanged When one of the radio boxes for the layout + * @brief on_SheetOrientationChanged When one of the radio boxes for the sheet * orientation has been clicked */ void on_SheetOrientationChanged(); /** * @brief on_pushButtonLayoutRemoveUnusedLength_clicked When the button - * "Remove unused length" in the layout property tab is clicked. + * "Remove unused length" in the sheet property tab is clicked. * The slot is automatically connected through name convention. */ void on_pushButtonSheetRemoveUnusedLength_clicked(); /** - * @brief on_LayoutMarginChanged When one of the margin values has been changed - * in the layout property tab. + * @brief on_SheetMarginChanged When one of the margin values has been changed + * in the sheet property tab. */ void on_SheetMarginChanged(); /** * @brief LayoutFollowGrainlineChanged When one of the radio boxes for the - * "Follow grainline" has been clicked in the layout property tab. + * "Follow grainline" has been clicked in the sheet property tab. */ void on_SheetFollowGrainlineChanged(); @@ -295,6 +340,45 @@ private slots: */ void on_doubleSpinBoxSheetPiecesGap_valueChanged(double value); + /** + * @brief on_comboBoxTilesTemplate_currentIndexChanged When the template is + * changed in the tiles property tab. + * The slot is automatically connected through name convention. + * @param index the index of the selected templated + */ + void on_comboBoxTilesTemplate_currentIndexChanged(int index); + + /** + * @brief on_TilesSizeChanged When the width or the length has been changed in + * the tiles property tab + * @param changedViaSizeCombobox true if the change happened through the combobox + */ + void on_TilesSizeChanged(bool changedViaSizeCombobox = true); + + /** + * @brief on_TilesOrientationChanged When one of the radio boxes for the tiles + * orientation has been clicked + */ + void on_TilesOrientationChanged(); + + /** + * @brief on_TilesMarginChanged When one of the margin values has been changed + * in the tiles property tab. + */ + void on_TilesMarginChanged(); + + /** + * @brief on_checkBoxTilesShowTiles_toggled When the checkbox "show tiles" is + * clicked + * @param checkedĀ“ + */ + void on_checkBoxTilesShowTiles_toggled(bool checked); + + /** + * @brief on_pushButtonTilesExport_clicked When the export tiles button is clicked + */ + void on_pushButtonTilesExport_clicked(); + /** * @brief on_checkBoxLayoutWarningPiecesSuperposition_toggled When the * "Warning when pieces superposition" checkbox value in the layout @@ -380,6 +464,16 @@ private slots: */ void on_PieceRotationChanged(); + /** + * @brief on_ScaleChanged When the scale of the graphic view is changed + */ + void on_ScaleChanged(qreal scale); + + /** + * @brief mouseMove save mouse position and show user. + * @param scenePos position mouse. + */ + void on_MouseMoved(const QPointF &scenePos); }; #endif // VPMAINWINDOW_H diff --git a/src/app/puzzle/vpmainwindow.ui b/src/app/puzzle/vpmainwindow.ui index 4684fbd66..7d73aa8d2 100644 --- a/src/app/puzzle/vpmainwindow.ui +++ b/src/app/puzzle/vpmainwindow.ui @@ -36,7 +36,7 @@ 0 0 1427 - 21 + 22 @@ -176,7 +176,7 @@ QTabWidget::Rounded - 0 + 1 @@ -234,7 +234,7 @@ 0 0 342 - 1252 + 1318 @@ -275,6 +275,13 @@ Infos + + + + Name: + + + @@ -285,10 +292,26 @@ - - + + - Name: + UUID: + + + + + + + + 16777215 + 48 + + + + true + + + {7b2ce4ae-96f5-4905-bb34-405cb40ca208} @@ -507,7 +530,7 @@ - Layout properties + Sheet properties @@ -541,8 +564,8 @@ 0 0 - 356 - 761 + 342 + 731 @@ -609,6 +632,9 @@ + + 2 + 100000.000000000000000 @@ -623,6 +649,9 @@ + + 2 + 100000.000000000000000 @@ -958,7 +987,7 @@ 0 0 356 - 761 + 717 @@ -968,13 +997,221 @@ font-weight: bold; - Tiles of current sheet + Tiled Pdf Export Qt::AlignCenter + + + + Format + + + + + + + + Width + + + + + + + 100000.000000000000000 + + + + + + + Length + + + + + + + 100000.000000000000000 + + + + + + + Orientation + + + + + + + + + + + + + :/puzzleicon/64x64/iconPortrait.png:/puzzleicon/64x64/iconPortrait.png + + + + 32 + 32 + + + + true + + + + + + + + + + + :/puzzleicon/64x64/iconLandscape.png:/puzzleicon/64x64/iconLandscape.png + + + + 32 + 32 + + + + + + + + + + Template + + + + + + + + + + + + + + + Margins + + + + + + Right: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Left: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 0.100000000000000 + + + + + + + 0.100000000000000 + + + + + + + Top: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 0.100000000000000 + + + + + + + Bottom: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 0.100000000000000 + + + + + + + + + + Control + + + + + + Show Tiles on sheet + + + + + + + + + + Export + + + + + + Export Tiled Pdf + + + + + + @@ -995,8 +1232,15 @@ + + + :/puzzleicon/64x64/iconProperties.png:/puzzleicon/64x64/iconProperties.png + - Prop. + + + + Layout properties @@ -1031,7 +1275,7 @@ 0 0 356 - 761 + 717 @@ -1066,7 +1310,7 @@ - My layout + @@ -1155,6 +1399,24 @@ + + + toolBar + + + Qt::ToolButtonTextUnderIcon + + + TopToolBarArea + + + false + + + + + + &Open @@ -1233,15 +1495,93 @@ Properties + + + + .. + + + Zoom in + + + + + + .. + + + Zoom out + + + + + + .. + + + Zoom 1:1 + + + + + + .. + + + Zoom fit best + + + Zoom sheet + + + tabWidgetProperties + scrollAreaCurrentPiece scrollAreaSheet + scrollAreaTiles + scrollAreaLayout + lineEditCurrentPieceName + plainTextEditCurrentPieceUUID + checkBoxCurrentPieceShowSeamline + checkBoxCurrentPieceMirrorPiece + doubleSpinBoxCurrentPieceAngle + doubleSpinBoxCurrentPieceBoxPositionX + doubleSpinBoxCurrentPieceBoxPositionY + lineEditSheetName + comboBoxSheetTemplate + doubleSpinBoxSheetWidth + doubleSpinBoxSheetLength + radioButtonSheetPortrait + radioButtonSheetLandscape + pushButtonSheetRemoveUnusedLength doubleSpinBoxSheetMarginTop doubleSpinBoxSheetMarginLeft doubleSpinBoxSheetMarginRight doubleSpinBoxSheetMarginBottom - scrollAreaTiles + radioButtonSheetFollowGrainlineNo + radioButtonSheetFollowGrainlineVertical + radioButtonSheetFollowGrainlineHorizontal + doubleSpinBoxSheetPiecesGap + checkBoxSheetStickyEdges + comboBoxSheetExportFormat + pushButtonSheetExport + doubleSpinBoxTilesWidth + doubleSpinBoxTilesLength + radioButtonTilesPortrait + radioButtonTilesLandscape + doubleSpinBoxTilesMarginTop + doubleSpinBoxTilesMarginLeft + doubleSpinBoxTilesMarginRight + doubleSpinBoxTilesMarginBottom + checkBoxTilesShowTiles + pushButtonTilesExport + lineEditLayoutName + plainTextEditLayoutDescription + comboBoxLayoutUnit + checkBoxLayoutWarningPiecesSuperposition + checkBoxLayoutWarningPiecesOutOfBound diff --git a/src/app/puzzle/vpsheet.cpp b/src/app/puzzle/vpsheet.cpp index 591194813..96796a0c1 100644 --- a/src/app/puzzle/vpsheet.cpp +++ b/src/app/puzzle/vpsheet.cpp @@ -43,6 +43,255 @@ VPSheet::~VPSheet() delete m_pieceList; } +//--------------------------------------------------------------------------------------------------------------------- +QSizeF VPSheet::GetTemplateSize(PaperSizeTemplate tmpl) +{ + qreal height = 0; + qreal width = 0; + + switch (tmpl) + { + case PaperSizeTemplate::A0: + width = UnitConvertor(841, Unit::Mm, Unit::Px); + height = UnitConvertor(1189, Unit::Mm, Unit::Px); + break; + + case PaperSizeTemplate::A1: + width = UnitConvertor(594, Unit::Mm, Unit::Px); + height = UnitConvertor(841, Unit::Mm, Unit::Px); + break; + + case PaperSizeTemplate::A2: + width = UnitConvertor(420, Unit::Mm, Unit::Px); + height = UnitConvertor(594, Unit::Mm, Unit::Px); + break; + + case PaperSizeTemplate::A3: + width = UnitConvertor(297, Unit::Mm, Unit::Px); + height = UnitConvertor(420, Unit::Mm, Unit::Px); + break; + + case PaperSizeTemplate::A4: + width = UnitConvertor(210, Unit::Mm, Unit::Px); + height = UnitConvertor(297, Unit::Mm, Unit::Px); + break; + + case PaperSizeTemplate::Letter: + width = UnitConvertor(8.5, Unit::Inch, Unit::Px); + height = UnitConvertor(11, Unit::Inch, Unit::Px); + break; + + case PaperSizeTemplate::Legal: + width = UnitConvertor(8.5, Unit::Inch, Unit::Px); + height = UnitConvertor(14, Unit::Inch, Unit::Px); + break; + + case PaperSizeTemplate::Tabloid: + width = UnitConvertor(11, Unit::Inch, Unit::Px); + height = UnitConvertor(17, Unit::Inch, Unit::Px); + break; + + case PaperSizeTemplate::Roll24in: + width = UnitConvertor(24, Unit::Inch, Unit::Px); + height = UnitConvertor(48, Unit::Inch, Unit::Px); + break; + + case PaperSizeTemplate::Roll30in: + width = UnitConvertor(30, Unit::Inch, Unit::Px); + height = UnitConvertor(60, Unit::Inch, Unit::Px); + break; + + case PaperSizeTemplate::Roll36in: + width = UnitConvertor(36, Unit::Inch, Unit::Px); + height = UnitConvertor(72, Unit::Inch, Unit::Px); + break; + + case PaperSizeTemplate::Roll42in: + width = UnitConvertor(42, Unit::Inch, Unit::Px); + height = UnitConvertor(84, Unit::Inch, Unit::Px); + break; + + case PaperSizeTemplate::Roll44in: + width = UnitConvertor(44, Unit::Inch, Unit::Px); + height = UnitConvertor(88, Unit::Inch, Unit::Px); + break; + + case PaperSizeTemplate::Roll48in: + width = UnitConvertor(48, Unit::Inch, Unit::Px); + height = UnitConvertor(96, Unit::Inch, Unit::Px); + break; + + case PaperSizeTemplate::Roll62in: + width = UnitConvertor(62, Unit::Inch, Unit::Px); + height = UnitConvertor(124, Unit::Inch, Unit::Px); + break; + + case PaperSizeTemplate::Roll72in: + width = UnitConvertor(72, Unit::Inch, Unit::Px); + height = UnitConvertor(144, Unit::Inch, Unit::Px); + break; + + default: + break; + } + + return QSizeF(width, height); +} + +//--------------------------------------------------------------------------------------------------------------------- +QString VPSheet::GetTemplateName(PaperSizeTemplate tmpl) +{ + QString tmplName; + switch (tmpl) + { + case PaperSizeTemplate::A0: + tmplName = QString("A0"); + break; + + case PaperSizeTemplate::A1: + tmplName = QString("A1"); + break; + + case PaperSizeTemplate::A2: + tmplName = QString("A2"); + break; + + case PaperSizeTemplate::A3: + tmplName = QString("A3"); + break; + + case PaperSizeTemplate::A4: + tmplName = QString("A4"); + break; + + case PaperSizeTemplate::Letter: + tmplName = tr("Letter"); + break; + + case PaperSizeTemplate::Legal: + tmplName = tr("Legal"); + break; + + case PaperSizeTemplate::Tabloid: + tmplName = tr("Tabloid"); + break; + + case PaperSizeTemplate::Roll24in: + tmplName = tr("Roll 24in"); + break; + + case PaperSizeTemplate::Roll30in: + tmplName = tr("Roll 30in"); + break; + + case PaperSizeTemplate::Roll36in: + tmplName = tr("Roll 36in"); + break; + + case PaperSizeTemplate::Roll42in: + tmplName = tr("Roll 42in"); + break; + + case PaperSizeTemplate::Roll44in: + tmplName = tr("Roll 44in"); + break; + + case PaperSizeTemplate::Roll48in: + tmplName = tr("Roll 48in"); + break; + + case PaperSizeTemplate::Roll62in: + tmplName = tr("Roll 62in"); + break; + + case PaperSizeTemplate::Roll72in: + tmplName = tr("Roll 72in"); + break; + + case PaperSizeTemplate::Custom: + tmplName = tr("Custom"); + break; + + default: + break; + } + + if(not tmplName.isEmpty()) + { + tmplName += " " + QStringLiteral("(%1ppi)").arg(PrintDPI); + } + + return tmplName; +} + +//--------------------------------------------------------------------------------------------------------------------- +PaperSizeTemplate VPSheet::GetTemplate(QSizeF size) +{ + Q_UNUSED(size); + // TODO, float comparision not safe and problems with + // inch / cm + +// const int max = static_cast(PaperSizeTemplate::Custom); + +// for (int i=0; i < max; i++) +// { +// PaperSizeTemplate tmpl = static_cast(i); +// const QSizeF tmplSize = GetTemplateSize(tmpl); + +// if(size.width() == tmplSize.width()) +// { +// if(isRollTemplate(tmpl)) +// { +// return tmpl; +// } +// else if(size.height() == tmplSize.height()) +// { +// return tmpl; +// } +// } +// } + + return PaperSizeTemplate::Custom; +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VPSheet::isRollTemplate(PaperSizeTemplate tmpl) +{ + switch (tmpl) { + case PaperSizeTemplate::Roll24in: + case PaperSizeTemplate::Roll30in: + case PaperSizeTemplate::Roll36in: + case PaperSizeTemplate::Roll42in: + case PaperSizeTemplate::Roll44in: + case PaperSizeTemplate::Roll48in: + case PaperSizeTemplate::Roll62in: + case PaperSizeTemplate::Roll72in: + return true; + default: + return false; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPSheet::PopulateComboBox(QVector *tmpls, QComboBox* comboBox) +{ + const QIcon icoPaper("://puzzleicon/16x16/template.png"); + const QIcon icoRoll("://puzzleicon/16x16/roll.png"); + + QIcon icon; + for (auto tmpl : *tmpls) + { + icon = (isRollTemplate(tmpl))? icoRoll : icoPaper; + comboBox->addItem(icon, GetTemplateName(tmpl), QVariant(static_cast(tmpl))); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +VPLayout* VPSheet::GetLayout() +{ + return m_layout; +} + //--------------------------------------------------------------------------------------------------------------------- VPPieceList* VPSheet::GetPieceList() { diff --git a/src/app/puzzle/vpsheet.h b/src/app/puzzle/vpsheet.h index 47c62d819..39fa05268 100644 --- a/src/app/puzzle/vpsheet.h +++ b/src/app/puzzle/vpsheet.h @@ -32,11 +32,36 @@ #include #include #include +#include #include "def.h" // is this the right place for the definition? -enum class FollowGrainline : qint8 { No = 0, Follow90 = 1, Follow180 = 2}; +enum class FollowGrainline : qint8 { + No = 0, + Follow90 = 1, + Follow180 = 2 +}; + +enum class PaperSizeTemplate : qint8 { + A0 = 0, + A1, + A2, + A3, + A4, + Letter, + Legal, + Tabloid, + Roll24in, + Roll30in, + Roll36in, + Roll42in, + Roll44in, + Roll48in, + Roll62in, + Roll72in, + Custom +}; class VPLayout; class VPPieceList; @@ -45,10 +70,53 @@ class VPSheet : public QObject { Q_OBJECT public: + + explicit VPSheet(VPLayout* layout); ~VPSheet(); + /** + * @brief GetTemplateSize Returns the size in Px of the given template + * @param tmpl + * @return the size in Px + */ + static QSizeF GetTemplateSize(PaperSizeTemplate tmpl); + + /** + * @brief GetTemplateName Returns the name of the given template + * @param tmpl + * @return + */ + static QString GetTemplateName(PaperSizeTemplate tmpl); + + /** + * @brief GetTemplate GetTemplate Returns the template that corresponds to the given size + * @param size the Size in Px + * @return + */ + static PaperSizeTemplate GetTemplate(QSizeF size); + + /** + * @brief PopulateComboBox Populates the given combo with the given templates + * @param tmpls + * @param comboBox + */ + static void PopulateComboBox(QVector *tmpls, QComboBox* comboBox); + + /** + * @brief isRollTemplate Returns wether the given template is a roll or not. + * @param tmpl + * @return + */ + static bool isRollTemplate(PaperSizeTemplate tmpl); + + /** + * @brief GetLayout Returns the Layout of the sheet + * @return + */ + VPLayout* GetLayout(); + /** * @brief GetPieceList returns the piece list of the sheet * @return piece list @@ -203,6 +271,7 @@ public: void SetStickyEdges(bool state); bool GetStickyEdges() const; + private: Q_DISABLE_COPY(VPSheet) diff --git a/src/app/puzzle/vptilefactory.cpp b/src/app/puzzle/vptilefactory.cpp new file mode 100644 index 000000000..a929de02f --- /dev/null +++ b/src/app/puzzle/vptilefactory.cpp @@ -0,0 +1,315 @@ +#include "vptilefactory.h" + +#include + +#include "../vwidgets/vmaingraphicsscene.h" +#include "vpsheet.h" +#include "vpmaingraphicsview.h" + + +//--------------------------------------------------------------------------------------------------------------------- +VPTileFactory::VPTileFactory(VPLayout *layout, VCommonSettings *commonSettings): + m_layout(layout), + m_commonSettings(commonSettings) +{ + m_infoStripeWidth = UnitConvertor(1, Unit::Cm, Unit::Px); +} + +//--------------------------------------------------------------------------------------------------------------------- +VPTileFactory::~VPTileFactory() +{ + +} + + +//--------------------------------------------------------------------------------------------------------------------- +void VPTileFactory::refreshTileInfos() +{ + if(m_layout != nullptr) + { + PageOrientation tilesOrientation = m_layout->GetTilesOrientation(); + QSizeF tilesSize = m_layout->GetTilesSize(); + QMarginsF tilesMargins = m_layout->GetTilesMargins(); + + // sets the drawing height + m_drawingAreaHeight = (tilesOrientation == PageOrientation::Portrait)? + tilesSize.height() : tilesSize.width(); + m_drawingAreaHeight -= + tilesMargins.top() + tilesMargins.bottom() + m_infoStripeWidth; + + // sets the drawing width + m_drawingAreaWidth = (tilesOrientation == PageOrientation::Portrait)? + tilesSize.width() : tilesSize.height(); + m_drawingAreaWidth -= + tilesMargins.left() + tilesMargins.right() + m_infoStripeWidth; + + + QSizeF sheetSize = m_layout->GetFocusedSheet()->GetSheetSize(); + qreal totalDrawingWidth = 0; + qreal totaldrawingHeight = 0; + + if(m_layout->GetFocusedSheet()->GetOrientation() == PageOrientation::Portrait) + { + totalDrawingWidth = sheetSize.width(); + totaldrawingHeight = sheetSize.height(); + } + else + { + totalDrawingWidth = sheetSize.height(); + totaldrawingHeight = sheetSize.width(); + } + + m_nbCol = qCeil(totalDrawingWidth/m_drawingAreaWidth); + m_nbRow = qCeil(totaldrawingHeight/m_drawingAreaHeight); + } +} + + +//--------------------------------------------------------------------------------------------------------------------- +void VPTileFactory::drawTile(QPainter *painter, VPMainGraphicsView *graphicsView, int row, int col) +{ + QMarginsF tilesMargins = m_layout->GetTilesMargins(); + QPen penTileInfos = QPen(QColor(180,180,180), m_commonSettings->WidthHairLine(), Qt::DashLine, Qt::RoundCap, Qt::RoundJoin); + QPen penTileDrawing = QPen(Qt::black, m_commonSettings->WidthMainLine(), Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); + + QSvgRenderer* svgRenderer = new QSvgRenderer(); + + // ------------- prepare triangles for position marks + QRectF rectBasic = QRectF(-UnitConvertor(0.5, Unit::Cm, Unit::Px), + 0, + UnitConvertor(1, Unit::Cm, Unit::Px), + UnitConvertor(0.5, Unit::Cm, Unit::Px) + ); + QPainterPath triangleBasic; + triangleBasic.moveTo(rectBasic.topLeft()); + triangleBasic.lineTo(rectBasic.topRight()); + triangleBasic.lineTo(rectBasic.left() + (rectBasic.width() / 2), rectBasic.bottom()); + triangleBasic.lineTo(rectBasic.topLeft()); + + QBrush triangleBush = QBrush(QColor(200,200,200)); + + + // add the tiles decorations (cutting and gluing lines, scissors, infos etc.) + painter->setPen(penTileInfos); + + if(row > 0) + { + // add top triangle + QPainterPath triangleTop = + QTransform() + .translate(tilesMargins.left()+m_drawingAreaWidth/2, tilesMargins.top()) + .map(triangleBasic); + painter->fillPath(triangleTop, triangleBush); + + // scissors along the top line + svgRenderer->load(QStringLiteral("://puzzleicon/svg/icon_scissors_horizontal.svg")); + svgRenderer->render(painter, QRectF(tilesMargins.left() + m_drawingAreaWidth, + tilesMargins.top(), + UnitConvertor(1, Unit::Cm, Unit::Px), + UnitConvertor(0.56, Unit::Cm, Unit::Px) + )); + + // dashed top line (for cutting) + penTileInfos.setStyle(Qt::DashLine); + painter->setPen(penTileInfos); + painter->drawLine(QPointF(tilesMargins.left(), + tilesMargins.top()), + QPointF(tilesMargins.left() + m_drawingAreaWidth + m_infoStripeWidth, + tilesMargins.top()) + ); + } + else + { + // solid top line stopping at the edge + penTileInfos.setStyle(Qt::SolidLine); + painter->setPen(penTileInfos); + painter->drawLine(QPointF(tilesMargins.left(), + tilesMargins.top()), + QPointF(tilesMargins.left() + m_drawingAreaWidth + ((col < m_nbCol-1)? m_infoStripeWidth : 0), + tilesMargins.top()) + ); + } + + if(col > 0) + { + // add left triangle + QPainterPath triangleLeft = + QTransform() + .translate(tilesMargins.left(), tilesMargins.top()+ m_drawingAreaHeight/2) + .rotate(-90) + .map(triangleBasic); + painter->fillPath(triangleLeft, triangleBush); + + // scissors along the left line + svgRenderer->load(QStringLiteral("://puzzleicon/svg/icon_scissors_vertical.svg")); + svgRenderer->render(painter, QRectF(tilesMargins.left(), + tilesMargins.top()+m_drawingAreaHeight, + UnitConvertor(0.56, Unit::Cm, Unit::Px), + UnitConvertor(1, Unit::Cm, Unit::Px) + )); + + // dashed left line (for cutting) + penTileInfos.setStyle(Qt::DashLine); + painter->setPen(penTileInfos); + painter->drawLine(QPointF(tilesMargins.left(), + tilesMargins.top()), + QPointF(tilesMargins.left(), + tilesMargins.top() + m_drawingAreaHeight + m_infoStripeWidth) + ); + } + else + { + // solid left line at the edge + penTileInfos.setStyle(Qt::SolidLine); + painter->setPen(penTileInfos); + painter->drawLine(QPointF(tilesMargins.left(), + tilesMargins.top()), + QPointF(tilesMargins.left(), + tilesMargins.top() + m_drawingAreaHeight + ((row < m_nbRow-1)? m_infoStripeWidth : 0)) + ); + } + + if(row < m_nbRow-1) + { + // add bottom triangle + QPainterPath triangleBottom = + QTransform() + .translate(tilesMargins.left()+ m_drawingAreaWidth/2, tilesMargins.top()+ m_drawingAreaHeight) + .rotate(180) + .map(triangleBasic); + + painter->fillPath(triangleBottom, triangleBush); + + // dotted bottom line (for glueing) + penTileInfos.setStyle(Qt::DotLine); + painter->setPen(penTileInfos); + painter->drawLine(QPointF(tilesMargins.left(), + tilesMargins.top() + m_drawingAreaHeight), + QPointF(tilesMargins.left() + m_drawingAreaWidth + m_infoStripeWidth, + tilesMargins.top() + m_drawingAreaHeight) + ); + } else + { + // solid bottom line at the edge + penTileInfos.setStyle(Qt::SolidLine); + painter->setPen(penTileInfos); + painter->drawLine(QPointF(tilesMargins.left(), + tilesMargins.top() + m_drawingAreaHeight), + QPointF(tilesMargins.left() + m_drawingAreaWidth + ((col < m_nbCol-1)? m_infoStripeWidth : 0), + tilesMargins.top() + m_drawingAreaHeight) + ); + } + + if(col < m_nbCol-1) + { + // add right triangle + QPainterPath triangleRight = + QTransform() + .translate(tilesMargins.left()+ m_drawingAreaWidth, tilesMargins.top()+ m_drawingAreaHeight/2) + .rotate(90) + .map(triangleBasic); + painter->fillPath(triangleRight, triangleBush); + + // dotted right line (for glueing) + penTileInfos.setStyle(Qt::DotLine); + painter->setPen(penTileInfos); + painter->drawLine(QPointF(tilesMargins.left() + m_drawingAreaWidth, + tilesMargins.top()), + QPointF(tilesMargins.left() + m_drawingAreaWidth, + tilesMargins.top()+ m_drawingAreaHeight + m_infoStripeWidth) + ); + } + else + { + // solid right line at the edge + penTileInfos.setStyle(Qt::SolidLine); + painter->setPen(penTileInfos); + painter->drawLine(QPointF(tilesMargins.left() + m_drawingAreaWidth, + tilesMargins.top()), + QPointF(tilesMargins.left() + m_drawingAreaWidth, + tilesMargins.top()+ m_drawingAreaHeight + ((row < m_nbRow-1) ? m_infoStripeWidth : 0)) + ); + } + + // paint the content of the page + QRectF source = QRectF(col*m_drawingAreaWidth, + row*m_drawingAreaHeight, + m_drawingAreaWidth + m_infoStripeWidth, + m_drawingAreaHeight + m_infoStripeWidth + ); + QRectF target = QRectF(tilesMargins.left(), + tilesMargins.top(), + source.width(), + source.height() + ); + + painter->setPen(penTileDrawing); + graphicsView->GetScene()->render(painter, target, source, Qt::IgnoreAspectRatio); + + // prepare the painting for the text information + QTextDocument td; + td.setPageSize(QSizeF( + m_drawingAreaWidth - UnitConvertor(2, Unit::Cm, Unit::Px), + m_drawingAreaHeight + )); + + // paint the grid information + const QString grid = tr("Grid ( %1 , %2 )").arg(row+1).arg(col+1); + + td.setHtml(QString("" + "" + "" + "" + "
%1
") + .arg(grid)); + painter->setPen(penTileInfos); + painter->save(); + painter->translate(QPointF(tilesMargins.left()+ UnitConvertor(1, Unit::Cm, Unit::Px), + m_drawingAreaHeight + tilesMargins.top() + )); + td.drawContents(painter); + painter->restore(); + + // paint the page information + const QString page = tr("Page %1 of %2").arg(row*m_nbCol+col+1).arg(m_nbCol*m_nbRow); + + td.setPageSize(QSizeF(m_drawingAreaHeight - UnitConvertor(2, Unit::Cm, Unit::Px), m_drawingAreaWidth)); + td.setHtml(QString("" + "" + "" + "" + "
%1 - %2
") + .arg(page).arg(m_layout->GetFocusedSheet()->GetName())); + painter->save(); + painter->rotate(-90); + painter->translate(QPointF(-(m_drawingAreaHeight+tilesMargins.top()) + UnitConvertor(1, Unit::Cm, Unit::Px), + m_drawingAreaWidth + tilesMargins.left() + )); + td.drawContents(painter); + painter->restore(); + +} + +//--------------------------------------------------------------------------------------------------------------------- +int VPTileFactory::getRowNb() +{ + return m_nbRow; +} + +//--------------------------------------------------------------------------------------------------------------------- +int VPTileFactory::getColNb() +{ + return m_nbCol; +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VPTileFactory::getDrawingAreaHeight() +{ + return m_drawingAreaHeight; +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VPTileFactory::getDrawingAreaWidth() +{ + return m_drawingAreaWidth; +} diff --git a/src/app/puzzle/vptilefactory.h b/src/app/puzzle/vptilefactory.h new file mode 100644 index 000000000..7b78a36f7 --- /dev/null +++ b/src/app/puzzle/vptilefactory.h @@ -0,0 +1,121 @@ +/************************************************************************ + ** + ** @file vptilefactory.h + ** @author Ronan Le Tiec + ** @date 19 11, 2020 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentina project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2020 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef VPTILEFACTORY_H +#define VPTILEFACTORY_H + +#include +#include + +#include "vplayout.h" +#include "../vmisc/def.h" +#include "vcommonsettings.h" + +class VPMainGraphicsView; + +class VPTileFactory : QObject +{ + Q_OBJECT + +public: + VPTileFactory(VPLayout *layout, VCommonSettings *settings); + + ~VPTileFactory(); + + /** + * @brief drawTile draws the tile of given coordinate (row, col) from the + * current sheet of the layout with the given painter + * @param painter + * @param row + * @param col + */ + void drawTile(QPainter *painter, VPMainGraphicsView *graphicsView, int row, int col); + + /** + * @brief refreshTileInfos Resfreshes the tile infos (m_nbCol, m_nbRow, m_drawingAreaHeight, m_drawingAreaWidth) + */ + void refreshTileInfos(); + + /** + * @brief getRowNb Returns the number of row pages + * @return + */ + int getRowNb(); + + /** + * @brief getColNb Returns the number of col pages + * @return + */ + int getColNb(); + + /** + * @brief getDrawingAreaHeight Returns the usable height of the tile in Px + * @return + */ + qreal getDrawingAreaHeight(); + + /** + * @brief getDrawingAreaWidth Returns the usable width of the tile in Px + * @return + */ + qreal getDrawingAreaWidth(); + +private: + Q_DISABLE_COPY(VPTileFactory) + + VPLayout *m_layout{nullptr}; + VCommonSettings *m_commonSettings{nullptr}; + + /** + * @brief m_nbCol the number of column-pages for the current sheet of the layout + */ + int m_nbCol{0}; + + /** + * @brief m_nbRow the number of row-pages for the current sheet of the layout + */ + int m_nbRow{0}; + + /** + * @brief m_drawingAreaHeight the height of the drawing area + */ + qreal m_drawingAreaHeight{0}; + + /** + * @brief m_drawingAreaWidth the width of the drawing area + */ + qreal m_drawingAreaWidth{0}; + + /** + * @brief m_infoStripeWidth the width of the info / glueing stripe in Px + */ + qreal m_infoStripeWidth{0}; + +}; + +#endif // VPTILEFACTORY_H