diff --git a/src/app/puzzle/layout/vplayoutsettings.cpp b/src/app/puzzle/layout/vplayoutsettings.cpp index a83b0d1a1..8c17f9e63 100644 --- a/src/app/puzzle/layout/vplayoutsettings.cpp +++ b/src/app/puzzle/layout/vplayoutsettings.cpp @@ -378,7 +378,7 @@ void VPLayoutSettings::SetShowWatermark(bool newShowWatermark) } //--------------------------------------------------------------------------------------------------------------------- -bool VPLayoutSettings::GetPrintTilesScheme() const +auto VPLayoutSettings::GetPrintTilesScheme() const -> bool { return m_printTilesScheme; } @@ -388,3 +388,15 @@ void VPLayoutSettings::SetPrintTilesScheme(bool newPrintTilesScheme) { m_printTilesScheme = newPrintTilesScheme; } + +//--------------------------------------------------------------------------------------------------------------------- +auto VPLayoutSettings::GetShowTileNumber() const -> bool +{ + return m_showTileNumbers; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPLayoutSettings::SetShowTileNumber(bool newTileNumbers) +{ + m_showTileNumbers = newTileNumbers; +} diff --git a/src/app/puzzle/layout/vplayoutsettings.h b/src/app/puzzle/layout/vplayoutsettings.h index 542519a05..207718d42 100644 --- a/src/app/puzzle/layout/vplayoutsettings.h +++ b/src/app/puzzle/layout/vplayoutsettings.h @@ -37,7 +37,7 @@ class VPLayoutSettings { - Q_DECLARE_TR_FUNCTIONS(VPLayoutSettings) + Q_DECLARE_TR_FUNCTIONS(VPLayoutSettings) // NOLINT public: VPLayoutSettings() = default; @@ -312,9 +312,12 @@ public: auto GetShowWatermark() const -> bool; void SetShowWatermark(bool newShowWatermark); - bool GetPrintTilesScheme() const; + auto GetPrintTilesScheme() const -> bool; void SetPrintTilesScheme(bool newPrintTilesScheme); + auto GetShowTileNumber() const -> bool; + void SetShowTileNumber(bool newTileNumbers); + private: Unit m_unit{Unit::Cm}; @@ -371,6 +374,8 @@ private: QString m_watermarkPath{}; bool m_printTilesScheme{false}; + + bool m_showTileNumbers{false}; }; #endif // VPLAYOUTSETTINGS_H diff --git a/src/app/puzzle/scene/vpgraphicstilegrid.cpp b/src/app/puzzle/scene/vpgraphicstilegrid.cpp index 56316094c..e153b75de 100644 --- a/src/app/puzzle/scene/vpgraphicstilegrid.cpp +++ b/src/app/puzzle/scene/vpgraphicstilegrid.cpp @@ -3,6 +3,7 @@ #include "../vptilefactory.h" #include "../layout/vplayout.h" #include "../layout/vpsheet.h" +#include "qnamespace.h" #include #include @@ -12,6 +13,74 @@ namespace { constexpr qreal penWidth = 1; + +//--------------------------------------------------------------------------------------------------------------------- +auto SheetMargins(const VPSheetPtr &sheet) -> QMarginsF +{ + if (not sheet.isNull() && not sheet->IgnoreMargins()) + { + return sheet->GetSheetMargins(); + } + + return {}; +} + +//--------------------------------------------------------------------------------------------------------------------- +auto OptimizeFontSizeToFitTextInRect(QPainter *painter, const QRectF &drawRect, const QString &text, + int flags = Qt::TextDontClip|Qt::TextWordWrap, double goalError = 0.01, + int maxIterationNumber=10) -> QFont +{ + painter->save(); + + QRect fontBoundRect; + QFont font; + double minError = std::numeric_limits::max(); + double error = std::numeric_limits::max(); + int iterationNumber=0; + while((error > goalError) && (iterationNumberfontMetrics().boundingRect(drawRect.toRect(), flags, text); + double xFactor = drawRect.width() / fontBoundRect.width(); + double yFactor = drawRect.height() / fontBoundRect.height(); + double factor; + if (xFactor<1 && yFactor<1) + { + factor = std::min(xFactor, yFactor); + } + else if (xFactor>1 && yFactor>1) + { + factor = std::max(xFactor, yFactor); + } + else if (xFactor<1 && yFactor>1) + { + factor = xFactor; + } + else + { + factor = yFactor; + } + + error = abs(factor-1); + if (factor > 1 ) + { + if (error < minError) + { + minError = error; + } + else + { + break; + } + } + font = painter->font(); + font.setPointSizeF(font.pointSizeF()*factor); + painter->setFont(font); + } + painter->restore(); + + return font; +} } // namespace //--------------------------------------------------------------------------------------------------------------------- @@ -61,70 +130,93 @@ void VPGraphicsTileGrid::paint(QPainter *painter, const QStyleOptionGraphicsItem Q_UNUSED(option); VPLayoutPtr layout = m_layout.toStrongRef(); - if(not layout.isNull() && layout->LayoutSettings().GetShowTiles()) + if(layout.isNull() || not layout->LayoutSettings().GetShowTiles()) { - VPSheetPtr sheet = layout->GetSheet(m_sheetUuid); + return; + } - QMarginsF sheetMargins; - if (not sheet.isNull() && not sheet->IgnoreMargins()) + QPen pen(QColor(255,0,0,127), penWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); + pen.setCosmetic(true); + pen.setStyle(Qt::DashLine); + QBrush noBrush(Qt::NoBrush); + painter->setPen(pen); + painter->setBrush(noBrush); + + qreal xScale = layout->LayoutSettings().HorizontalScale(); + qreal yScale = layout->LayoutSettings().VerticalScale(); + + const qreal width = (layout->TileFactory()->DrawingAreaWidth() - VPTileFactory::tileStripeWidth) / xScale; + const qreal height = (layout->TileFactory()->DrawingAreaHeight() - VPTileFactory::tileStripeWidth) / yScale; + + VPSheetPtr sheet = layout->GetSheet(m_sheetUuid); + QMarginsF sheetMargins = SheetMargins(sheet); + + const int nbCol = layout->TileFactory()->ColNb(sheet); + const int nbRow = layout->TileFactory()->RowNb(sheet); + + QFont font = OptimizeFontSizeToFitTextInRect(painter, + QRectF(sheetMargins.left(), sheetMargins.top(), width/3., height/3.), + QString::number(nbRow * nbCol)); + + VWatermarkData watermarkData = layout->TileFactory()->WatermarkData(); + + auto PaintWatermark = [painter, layout, xScale, yScale, watermarkData] + (const QRectF &img) + { + if (not layout->LayoutSettings().WatermarkPath().isEmpty() && + layout->LayoutSettings().GetShowWatermark() && watermarkData.opacity > 0) { - sheetMargins = sheet->GetSheetMargins(); - } - - QPen pen(QColor(255,0,0,127), penWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); - pen.setCosmetic(true); - pen.setStyle(Qt::DashLine); - QBrush noBrush(Qt::NoBrush); - painter->setPen(pen); - painter->setBrush(noBrush); - - qreal xScale = layout->LayoutSettings().HorizontalScale(); - qreal yScale = layout->LayoutSettings().VerticalScale(); - - const qreal width = (layout->TileFactory()->DrawingAreaWidth() - VPTileFactory::tileStripeWidth) / xScale; - const qreal height = (layout->TileFactory()->DrawingAreaHeight() - VPTileFactory::tileStripeWidth) / yScale; - - const int nbCol = layout->TileFactory()->ColNb(sheet); - const int nbRow = layout->TileFactory()->RowNb(sheet); - - VWatermarkData watermarkData = layout->TileFactory()->WatermarkData(); - - for(int j=0;j<=nbRow;++j) - { - // horizontal lines - painter->drawLine(QPointF(sheetMargins.left(), sheetMargins.top()+j*height), - QPointF(sheetMargins.left()+nbCol*width, sheetMargins.top()+j*height)); - - for(int i=0;i<=nbCol;++i) + if (watermarkData.showImage && not watermarkData.path.isEmpty()) { - // vertical lines - painter->drawLine(QPointF(sheetMargins.left()+i*width, sheetMargins.top()), - QPointF(sheetMargins.left()+i*width, sheetMargins.top() + nbRow*height)); + VPTileFactory::PaintWatermarkImage(painter, img, watermarkData, + layout->LayoutSettings().WatermarkPath(), + xScale, yScale); + } - if (j < nbRow && i < nbCol) - { - QRectF img(sheetMargins.left()+i*width, sheetMargins.top()+j*height, - width, height); + if (watermarkData.showText && not watermarkData.text.isEmpty()) + { + VPTileFactory::PaintWatermarkText(painter, img, watermarkData); + } + } + }; - if (not layout->LayoutSettings().WatermarkPath().isEmpty() && - layout->LayoutSettings().GetShowWatermark()) - { - if (watermarkData.opacity > 0) - { - if (watermarkData.showImage && not watermarkData.path.isEmpty()) - { - VPTileFactory::PaintWatermarkImage(painter, img, watermarkData, - layout->LayoutSettings().WatermarkPath(), - xScale, yScale); - } + auto PaintTileNumber = [painter, layout, nbCol, font] + (const QRectF &img, int i, int j) + { + if (layout->LayoutSettings().GetShowTileNumber()) + { + painter->save(); - if (watermarkData.showText && not watermarkData.text.isEmpty()) - { - VPTileFactory::PaintWatermarkText(painter, img, watermarkData); - } - } - } - } + painter->setFont(font); + + QPen pen = painter->pen(); + pen.setColor(Qt::black); + painter->setPen(pen); + + painter->drawText(img, Qt::AlignCenter, QString::number(j*nbCol + i+1)); + + painter->restore(); + } + }; + + for(int j=0;j<=nbRow;++j) + { + // horizontal lines + painter->drawLine(QPointF(sheetMargins.left(), sheetMargins.top()+j*height), + QPointF(sheetMargins.left()+nbCol*width, sheetMargins.top()+j*height)); + + for(int i=0;i<=nbCol;++i) + { + // vertical lines + painter->drawLine(QPointF(sheetMargins.left()+i*width, sheetMargins.top()), + QPointF(sheetMargins.left()+i*width, sheetMargins.top() + nbRow*height)); + + if (j < nbRow && i < nbCol) + { + QRectF img(sheetMargins.left()+i*width, sheetMargins.top()+j*height, width, height); + + PaintWatermark(img); + PaintTileNumber(img, i, j); } } } diff --git a/src/app/puzzle/scene/vpgraphicstilegrid.h b/src/app/puzzle/scene/vpgraphicstilegrid.h index b53980fb3..85a6b61b8 100644 --- a/src/app/puzzle/scene/vpgraphicstilegrid.h +++ b/src/app/puzzle/scene/vpgraphicstilegrid.h @@ -36,6 +36,10 @@ #include "../vmisc/def.h" #include "../layout/layoutdef.h" +#if QT_VERSION < QT_VERSION_CHECK(5, 13, 0) +#include "../vmisc/defglobal.h" +#endif // QT_VERSION < QT_VERSION_CHECK(5, 13, 0) + class VPTileFactory; class VPLayout; struct VWatermarkData; @@ -44,13 +48,13 @@ class VPGraphicsTileGrid : public QGraphicsItem { public: explicit VPGraphicsTileGrid(const VPLayoutPtr &layout, const QUuid &sheetUuid, QGraphicsItem *parent = nullptr); - ~VPGraphicsTileGrid()=default; + ~VPGraphicsTileGrid() override =default; - QRectF boundingRect() const override; + auto boundingRect() const -> QRectF override; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; private: - Q_DISABLE_COPY(VPGraphicsTileGrid) + Q_DISABLE_COPY_MOVE(VPGraphicsTileGrid) // NOLINT VPLayoutWeakPtr m_layout; QUuid m_sheetUuid; diff --git a/src/app/puzzle/vpmainwindow.cpp b/src/app/puzzle/vpmainwindow.cpp index 743325306..e4df365df 100644 --- a/src/app/puzzle/vpmainwindow.cpp +++ b/src/app/puzzle/vpmainwindow.cpp @@ -1082,6 +1082,16 @@ void VPMainWindow::InitPropertyTabTiles() LayoutWasSaved(false); } }); + + connect(ui->checkBoxShowTileNumber, &QCheckBox::toggled, this, [this](bool checked) + { + if (not m_layout.isNull()) + { + m_layout->LayoutSettings().SetShowTileNumber(checked); + LayoutWasSaved(false); + m_graphicsView->RefreshLayout(); + } + }); } //--------------------------------------------------------------------------------------------------------------------- @@ -1486,6 +1496,7 @@ void VPMainWindow::SetPropertyTabTilesData() SetCheckBoxValue(ui->checkBoxTilesShowTiles, m_layout->LayoutSettings().GetShowTiles()); SetCheckBoxValue(ui->checkBoxTilesShowWatermark, m_layout->LayoutSettings().GetShowWatermark()); SetCheckBoxValue(ui->checkBoxPrintTilesScheme, m_layout->LayoutSettings().GetPrintTilesScheme()); + SetCheckBoxValue(ui->checkBoxShowTileNumber, m_layout->LayoutSettings().GetShowTileNumber()); } else { diff --git a/src/app/puzzle/vpmainwindow.ui b/src/app/puzzle/vpmainwindow.ui index cf3cad2a4..a86a8e019 100644 --- a/src/app/puzzle/vpmainwindow.ui +++ b/src/app/puzzle/vpmainwindow.ui @@ -219,7 +219,7 @@ QTabWidget::Rounded - 0 + 2 @@ -1551,6 +1551,13 @@ + + + + Show tile number + + + diff --git a/src/app/puzzle/xml/vplayoutfilereader.cpp b/src/app/puzzle/xml/vplayoutfilereader.cpp index 21e1cc1ca..a6e25a4e2 100644 --- a/src/app/puzzle/xml/vplayoutfilereader.cpp +++ b/src/app/puzzle/xml/vplayoutfilereader.cpp @@ -322,6 +322,7 @@ void VPLayoutFileReader::ReadTiles(const VPLayoutPtr &layout) QXmlStreamAttributes attribs = attributes(); layout->LayoutSettings().SetShowTiles(ReadAttributeBool(attribs, ML::AttrVisible, falseStr)); layout->LayoutSettings().SetPrintTilesScheme(ReadAttributeBool(attribs, ML::AttrPrintScheme, falseStr)); + layout->LayoutSettings().SetShowTileNumber(ReadAttributeBool(attribs, ML::AttrTileNumber, falseStr)); // attribs.value(ML::AttrMatchingMarks); // TODO const QStringList tags diff --git a/src/app/puzzle/xml/vplayoutfilewriter.cpp b/src/app/puzzle/xml/vplayoutfilewriter.cpp index 31b0d77d0..8c2e88882 100644 --- a/src/app/puzzle/xml/vplayoutfilewriter.cpp +++ b/src/app/puzzle/xml/vplayoutfilewriter.cpp @@ -229,13 +229,13 @@ void VPLayoutFileWriter::WriteSheet(const VPSheetPtr &sheet) //--------------------------------------------------------------------------------------------------------------------- void VPLayoutFileWriter::WriteTiles(const VPLayoutPtr &layout) { - Q_UNUSED(layout); // to be removed - writeStartElement(ML::TagTiles); SetAttribute(ML::AttrVisible, layout->LayoutSettings().GetShowTiles()); SetAttribute(ML::AttrMatchingMarks, "standard"); // TODO / Fixme get the right value SetAttributeOrRemoveIf(ML::AttrPrintScheme, layout->LayoutSettings().GetPrintTilesScheme(), [](bool print) noexcept {return not print;}); + SetAttributeOrRemoveIf(ML::AttrTileNumber, layout->LayoutSettings().GetShowTileNumber(), + [](bool show) noexcept {return not show;}); WriteSize(layout->LayoutSettings().GetTilesSize()); WriteMargins(layout->LayoutSettings().GetTilesMargins(), layout->LayoutSettings().IgnoreTilesMargins()); diff --git a/src/app/puzzle/xml/vplayoutliterals.cpp b/src/app/puzzle/xml/vplayoutliterals.cpp index a4d11f82c..34a452008 100644 --- a/src/app/puzzle/xml/vplayoutliterals.cpp +++ b/src/app/puzzle/xml/vplayoutliterals.cpp @@ -105,6 +105,7 @@ const QString AttrYScale = QStringLiteral("yScale"); const QString AttrIgnoreMargins = QStringLiteral("ignoreMargins"); const QString AttrShowPreview = QStringLiteral("showPreview"); const QString AttrPrintScheme = QStringLiteral("printScheme"); +const QString AttrTileNumber = QStringLiteral("tileNumber"); const QString atFrontStr = QStringLiteral("atFront"); const QString atRearStr = QStringLiteral("atRear"); diff --git a/src/app/puzzle/xml/vplayoutliterals.h b/src/app/puzzle/xml/vplayoutliterals.h index e80d28439..a3c5c8a33 100644 --- a/src/app/puzzle/xml/vplayoutliterals.h +++ b/src/app/puzzle/xml/vplayoutliterals.h @@ -110,6 +110,7 @@ extern const QString AttrYScale; extern const QString AttrIgnoreMargins; extern const QString AttrShowPreview; extern const QString AttrPrintScheme; +extern const QString AttrTileNumber; extern const QString atFrontStr; extern const QString atRearStr; diff --git a/src/libs/ifc/schema/layout/v0.1.0.xsd b/src/libs/ifc/schema/layout/v0.1.0.xsd index 6dcc17583..2a646baea 100644 --- a/src/libs/ifc/schema/layout/v0.1.0.xsd +++ b/src/libs/ifc/schema/layout/v0.1.0.xsd @@ -39,6 +39,7 @@ +