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
+
+
+ :/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("")
+ .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