From 1dfec70c06421a44452e8c0dc8033980a652be48 Mon Sep 17 00:00:00 2001 From: thomas_lucky13 Date: Thu, 24 Nov 2022 15:41:04 +0400 Subject: [PATCH] polygon_line_styles Adding a new characteristic for line tool for it style (it can be solid, dashed and dotted). --- resources/OpenBoard.qrc | 3 + resources/forms/mainWindow.ui | 56 ++++++++- resources/images/toolbar/dashedLine.svg | 126 ++++++++++++++++++++ resources/images/toolbar/dottedLine.svg | 145 +++++++++++++++++++++++ resources/images/toolbar/solidLine.svg | 126 ++++++++++++++++++++ src/board/UBBoardController.cpp | 23 ++++ src/board/UBBoardController.h | 1 + src/board/UBDrawingController.cpp | 5 + src/board/UBDrawingController.h | 1 + src/core/UB.h | 10 ++ src/core/UBSettings.cpp | 32 ++++++ src/core/UBSettings.h | 6 + src/domain/UBGraphicsPolygonItem.cpp | 12 ++ src/domain/UBGraphicsPolygonItem.h | 1 + src/domain/UBGraphicsScene.cpp | 19 ++- src/domain/UBGraphicsScene.h | 1 + src/frameworks/UBGeometryUtils.cpp | 146 ++++++++++++++++++++++++ src/frameworks/UBGeometryUtils.h | 6 + 18 files changed, 717 insertions(+), 2 deletions(-) create mode 100644 resources/images/toolbar/dashedLine.svg create mode 100644 resources/images/toolbar/dottedLine.svg create mode 100644 resources/images/toolbar/solidLine.svg diff --git a/resources/OpenBoard.qrc b/resources/OpenBoard.qrc index d1a5661f..d655e4ac 100644 --- a/resources/OpenBoard.qrc +++ b/resources/OpenBoard.qrc @@ -628,5 +628,8 @@ images/toolbar/record.svg images/toolbar/updates.svg images/toolbar/tutorial.svg + images/toolbar/solidLine.svg + images/toolbar/dottedLine.svg + images/toolbar/dashedLine.svg diff --git a/resources/forms/mainWindow.ui b/resources/forms/mainWindow.ui index a24810b4..66ac731d 100644 --- a/resources/forms/mainWindow.ui +++ b/resources/forms/mainWindow.ui @@ -1702,6 +1702,60 @@ Draw intermediate grid lines + + + true + + + true + + + + :/images/toolbar/solidLine.svg:/images/toolbar/solidLine.svg + + + Line Style + + + Solid Line + + + + + true + + + true + + + + :/images/toolbar/dashedLine.svg:/images/toolbar/dashedLine.svg + + + Line Style + + + Dashed Line + + + + + true + + + true + + + + :/images/toolbar/dottedLine.svg:/images/toolbar/dottedLine.svg + + + Line Style + + + Dotted Line + + diff --git a/resources/images/toolbar/dashedLine.svg b/resources/images/toolbar/dashedLine.svg new file mode 100644 index 00000000..b523d91e --- /dev/null +++ b/resources/images/toolbar/dashedLine.svg @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/resources/images/toolbar/dottedLine.svg b/resources/images/toolbar/dottedLine.svg new file mode 100644 index 00000000..7124cd1e --- /dev/null +++ b/resources/images/toolbar/dottedLine.svg @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/resources/images/toolbar/solidLine.svg b/resources/images/toolbar/solidLine.svg new file mode 100644 index 00000000..45e714e5 --- /dev/null +++ b/resources/images/toolbar/solidLine.svg @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/src/board/UBBoardController.cpp b/src/board/UBBoardController.cpp index 080036ec..3c95cd4a 100644 --- a/src/board/UBBoardController.cpp +++ b/src/board/UBBoardController.cpp @@ -378,6 +378,25 @@ void UBBoardController::setupToolbar() mPropertyPaletteWidgets.insert(eraserWidth, newPropertyPaletteWidget); //-----------------------------------------------------------// + // Setup line style choice widget + QList lineStyleActions; + lineStyleActions.append(mMainWindow->actionLineSolid); + lineStyleActions.append(mMainWindow->actionLineDashed); + lineStyleActions.append(mMainWindow->actionLineDotted); + + UBToolbarButtonGroup *lineStyleChoice = + new UBToolbarButtonGroup(mMainWindow->boardToolBar, lineStyleActions); + + connect(settings->appToolBarDisplayText, SIGNAL(changed(QVariant)), lineStyleChoice, SLOT(displayText(QVariant))); + + connect(lineStyleChoice, SIGNAL(activated(int)), + UBDrawingController::drawingController(), SLOT(setLineStyleIndex(int))); + lineStyleChoice->displayText(QVariant(settings->appToolBarDisplayText->get().toBool())); + newPropertyPaletteWidget = mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, lineStyleChoice); + lineStyleChoice->setCurrentIndex(settings->lineStyleIndex()); + lineStyleActions.at(settings->lineStyleIndex())->setChecked(true); + mPropertyPaletteWidgets.insert(lineStyle, newPropertyPaletteWidget); + //-----------------------------------------------------------// UBApplication::app()->insertSpaceToToolbarBeforeAction(mMainWindow->boardToolBar, mMainWindow->actionBackgrounds); UBApplication::app()->insertSpaceToToolbarBeforeAction(mMainWindow->boardToolBar, mMainWindow->actionBoard, 40); @@ -2211,23 +2230,27 @@ void UBBoardController::stylusToolChanged(int tool) mPropertyPaletteWidgets[color]->setVisible(true); mPropertyPaletteWidgets[lineWidth]->setVisible(true); mPropertyPaletteWidgets[eraserWidth]->setVisible(false); + mPropertyPaletteWidgets[lineStyle]->setVisible(false); } else if (eTool == UBStylusTool::Eraser) { mPropertyPaletteWidgets[color]->setVisible(false); mPropertyPaletteWidgets[lineWidth]->setVisible(false); mPropertyPaletteWidgets[eraserWidth]->setVisible(true); + mPropertyPaletteWidgets[lineStyle]->setVisible(false); } else if (eTool == UBStylusTool::Line) { mPropertyPaletteWidgets[color]->setVisible(true); mPropertyPaletteWidgets[lineWidth]->setVisible(true); mPropertyPaletteWidgets[eraserWidth]->setVisible(false); + mPropertyPaletteWidgets[lineStyle]->setVisible(true); } else { mPropertyPaletteWidgets[color]->setVisible(false); mPropertyPaletteWidgets[lineWidth]->setVisible(false); mPropertyPaletteWidgets[eraserWidth]->setVisible(false); + mPropertyPaletteWidgets[lineStyle]->setVisible(false); } } diff --git a/src/board/UBBoardController.h b/src/board/UBBoardController.h index 0ad946aa..8e6618f2 100644 --- a/src/board/UBBoardController.h +++ b/src/board/UBBoardController.h @@ -326,6 +326,7 @@ class UBBoardController : public UBDocumentContainer { color, lineWidth, + lineStyle, eraserWidth }; QMap mPropertyPaletteWidgets; diff --git a/src/board/UBDrawingController.cpp b/src/board/UBDrawingController.cpp index 705e1d18..ab6b39d4 100644 --- a/src/board/UBDrawingController.cpp +++ b/src/board/UBDrawingController.cpp @@ -279,6 +279,11 @@ void UBDrawingController::setEraserWidthIndex(int index) UBSettings::settings()->setEraserWidthIndex(index); } +void UBDrawingController::setLineStyleIndex(int index) +{ + UBSettings::settings()->setLineStyleIndex(index); +} + void UBDrawingController::setPenColor(bool onDarkBackground, const QColor& color, int pIndex) { if (onDarkBackground) diff --git a/src/board/UBDrawingController.h b/src/board/UBDrawingController.h index 01c11187..617bc824 100644 --- a/src/board/UBDrawingController.h +++ b/src/board/UBDrawingController.h @@ -80,6 +80,7 @@ class UBDrawingController : public QObject void setLineWidthIndex(int index); void setColorIndex(int index); void setEraserWidthIndex(int index); + void setLineStyleIndex(int index); signals: void stylusToolChanged(int tool, int previousTool = -1); diff --git a/src/core/UB.h b/src/core/UB.h index 8b9b1c7f..9c5552b4 100644 --- a/src/core/UB.h +++ b/src/core/UB.h @@ -84,6 +84,16 @@ struct UBWidth }; }; +struct UBLineStyle +{ + enum Enum + { + Solid = 0, + Dashed = 1, + Dotted = 2 + }; +}; + struct UBZoom { enum Enum diff --git a/src/core/UBSettings.cpp b/src/core/UBSettings.cpp index 663c5582..994b51d8 100644 --- a/src/core/UBSettings.cpp +++ b/src/core/UBSettings.cpp @@ -785,6 +785,38 @@ qreal UBSettings::currentEraserWidth() return width; } +//----------------------------------------// +// line +int UBSettings::lineStyleIndex() +{ + return value("Board/LineStyleIndex", 0).toInt(); +} + +void UBSettings::setLineStyleIndex(int index) +{ + setValue("Board/LineStyleIndex", index); +} + +UBLineStyle::Enum UBSettings::currentLineStyle() +{ + Qt::PenStyle style = Qt::SolidLine; + + switch (lineStyleIndex()) + { + case UBLineStyle::Solid: + return UBLineStyle::Solid; + case UBLineStyle::Dotted: + return UBLineStyle::Dotted; + case UBLineStyle::Dashed: + return UBLineStyle::Dashed; + default: + Q_ASSERT(false); + style = Qt::SolidLine; + break; + } + + return UBLineStyle::Solid; +} bool UBSettings::isDarkBackground() { return value("Board/DarkBackground", 0).toBool(); diff --git a/src/core/UBSettings.h b/src/core/UBSettings.h index 8d5909a3..02a5366f 100644 --- a/src/core/UBSettings.h +++ b/src/core/UBSettings.h @@ -85,6 +85,10 @@ class UBSettings : public QObject qreal eraserStrongWidth(); qreal currentEraserWidth(); + // Line related + int lineStyleIndex(); + UBLineStyle::Enum currentLineStyle(); + // Background related bool isDarkBackground(); UBPageBackground pageBackground(); @@ -443,6 +447,8 @@ class UBSettings : public QObject void setEraserMediumWidth(qreal width); void setEraserStrongWidth(qreal width); + void setLineStyleIndex(int index); + void setStylusPaletteVisible(bool visible); void setPenPressureSensitive(bool sensitive); diff --git a/src/domain/UBGraphicsPolygonItem.cpp b/src/domain/UBGraphicsPolygonItem.cpp index bdd22757..65820f30 100644 --- a/src/domain/UBGraphicsPolygonItem.cpp +++ b/src/domain/UBGraphicsPolygonItem.cpp @@ -73,6 +73,18 @@ UBGraphicsPolygonItem::UBGraphicsPolygonItem (const QLineF& pLine, qreal pWidth) initialize(); } +UBGraphicsPolygonItem::UBGraphicsPolygonItem (const QLineF& pLine, qreal pWidth, UBLineStyle::Enum style) + : QGraphicsPolygonItem(UBGeometryUtils::lineToPolygon(pLine, pWidth, style)) + , mOriginalLine(pLine) + , mOriginalWidth(pWidth) + , mIsNominalLine(true) + , mStroke(0) + , mpGroup(NULL) +{ + // NOOP + initialize(); +} + UBGraphicsPolygonItem::UBGraphicsPolygonItem (const QLineF& pLine, qreal pStartWidth, qreal pEndWidth) : QGraphicsPolygonItem(UBGeometryUtils::lineToPolygon(pLine, pStartWidth, pEndWidth)) , mOriginalLine(pLine) diff --git a/src/domain/UBGraphicsPolygonItem.h b/src/domain/UBGraphicsPolygonItem.h index fc146c9c..fb7bdf9f 100644 --- a/src/domain/UBGraphicsPolygonItem.h +++ b/src/domain/UBGraphicsPolygonItem.h @@ -45,6 +45,7 @@ class UBGraphicsPolygonItem : public QGraphicsPolygonItem, public UBItem public: UBGraphicsPolygonItem(QGraphicsItem * parent = 0 ); + UBGraphicsPolygonItem(const QLineF& line, qreal pWidth, UBLineStyle::Enum style); UBGraphicsPolygonItem(const QLineF& line, qreal pWidth); UBGraphicsPolygonItem(const QLineF& pLine, qreal pStartWidth, qreal pEndWidth); UBGraphicsPolygonItem(const QPolygonF & polygon, QGraphicsItem * parent = 0); diff --git a/src/domain/UBGraphicsScene.cpp b/src/domain/UBGraphicsScene.cpp index e6ef1b3b..bccf4679 100644 --- a/src/domain/UBGraphicsScene.cpp +++ b/src/domain/UBGraphicsScene.cpp @@ -943,7 +943,15 @@ void UBGraphicsScene::drawLineTo(const QPointF &pEndPoint, const qreal &startWid mAddedItems.clear(); } - UBGraphicsPolygonItem *polygonItem = lineToPolygonItem(QLineF(mPreviousPoint, pEndPoint), initialWidth, endWidth); + UBGraphicsPolygonItem *polygonItem; + + if(UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Line) + { + polygonItem = lineToPolygonItem(QLineF(mPreviousPoint, pEndPoint), endWidth, UBSettings::settings()->currentLineStyle()); + } else + { + polygonItem = lineToPolygonItem(QLineF(mPreviousPoint, pEndPoint), initialWidth, endWidth); + } addPolygonItemToCurrentStroke(polygonItem); if (!bLineStyle) { @@ -1238,6 +1246,15 @@ UBGraphicsPolygonItem* UBGraphicsScene::lineToPolygonItem(const QLineF &pLine, c return polygonItem; } +UBGraphicsPolygonItem* UBGraphicsScene::lineToPolygonItem(const QLineF &pLine, const qreal &pWidth, UBLineStyle::Enum style) +{ + UBGraphicsPolygonItem *polygonItem = new UBGraphicsPolygonItem(pLine, pWidth, style); + + initPolygonItem(polygonItem); + + return polygonItem; +} + void UBGraphicsScene::initPolygonItem(UBGraphicsPolygonItem* polygonItem) { QColor colorOnDarkBG; diff --git a/src/domain/UBGraphicsScene.h b/src/domain/UBGraphicsScene.h index 9e66d662..3d934b53 100644 --- a/src/domain/UBGraphicsScene.h +++ b/src/domain/UBGraphicsScene.h @@ -395,6 +395,7 @@ public slots: UBGraphicsPolygonItem* lineToPolygonItem(const QLineF& pLine, const qreal& pWidth); UBGraphicsPolygonItem* lineToPolygonItem(const QLineF &pLine, const qreal &pStartWidth, const qreal &pEndWidth); + UBGraphicsPolygonItem* lineToPolygonItem(const QLineF &pLine, const qreal &pWidth, UBLineStyle::Enum style); UBGraphicsPolygonItem* arcToPolygonItem(const QLineF& pStartRadius, qreal pSpanAngle, qreal pWidth); UBGraphicsPolygonItem* curveToPolygonItem(const QList > &points); diff --git a/src/frameworks/UBGeometryUtils.cpp b/src/frameworks/UBGeometryUtils.cpp index 30bd3c35..53a6de2f 100644 --- a/src/frameworks/UBGeometryUtils.cpp +++ b/src/frameworks/UBGeometryUtils.cpp @@ -49,6 +49,19 @@ UBGeometryUtils::~UBGeometryUtils() // NOOP } +QPolygonF UBGeometryUtils::lineToPolygon(const QLineF& pLine, const qreal& pWidth, const UBLineStyle::Enum lineStyle) +{ + if (lineStyle == UBLineStyle::Dashed) //Dashed LineStyle + { + return dashedLineToPolygon(pLine, pWidth); + } + if (lineStyle == UBLineStyle::Dotted) //Dotted LineStyle + { + return dottedLineToPolygon(pLine, pWidth); + } + return lineToPolygon(pLine, pWidth); +} + QPolygonF UBGeometryUtils::lineToPolygon(const QLineF& pLine, const qreal& pWidth) { qreal x1 = pLine.x1(); @@ -467,3 +480,136 @@ QList UBGeometryUtils::quadraticBezier(const QPointF& p0, const QPointF return points; } + +QPolygonF UBGeometryUtils::dashedLineToPolygon(const QLineF& pLine, const qreal& pWidth) +{ + + qreal partLength = pWidth*4; + QList linePoints; + + int n = pLine.length()/partLength; + qreal partPrc; + if (n == 0) + { + partPrc = 0; + } else + { + partPrc = 1.0/n; + } + for (int i = 0; i < n; ++i) + { + linePoints.push_back(pLine.pointAt(i*partPrc)); + } + linePoints.push_back(pLine.p2()); + + QPainterPath painterPath; + + for(int i = 1; i < linePoints.count(); i+=2) + { + painterPath.addPolygon(lineToPolygon(QLineF(linePoints[i-1], linePoints[i]), pWidth)); + painterPath.closeSubpath(); + } + + // Use convertLineToPolygon to fix a problem with erasing + return convertLineToPolygon(painterPath.toFillPolygon()); +} + +QPolygonF UBGeometryUtils::dottedLineToPolygon(const QLineF& pLine, const qreal& pWidth) +{ + qreal partLength = pWidth; + QList linePoints; + + int n = pLine.length()/partLength; + qreal partPrc; + if (n == 0) + { + partPrc = 0; + } else + { + partPrc = 1.0/n; + } + for (int i = 0; i < n; ++i) + { + linePoints.push_back(pLine.pointAt(i*partPrc)); + } + linePoints.push_back(pLine.p2()); + + QPainterPath painterPath; + + for(int i = 1; i < linePoints.count(); i+=6) + { + painterPath.addEllipse(linePoints[i].x()-pWidth, linePoints[i].y()-pWidth, pWidth*2, pWidth*2); + painterPath.closeSubpath(); + } + // Use convertLineToPolygon to fix a problem with erasing + return convertLineToPolygon(painterPath.toFillPolygon()); +} + +QPolygonF UBGeometryUtils::convertLineToPolygon(const QPolygonF& pLine) +{ + /* + * Use this function to fix problems with erasing dashed and dotted lines + * Without this will be erased extra parts, that should not + */ + QPolygonF polygon = pLine; + int pointsCount = polygon.size(); + QString* points = new QString(); + if (pointsCount > 0) + { + QVector polygonPoints = polygon; + UBGeometryUtils::crashPointList(polygonPoints); + + int PolygonPointsCount = polygonPoints.size(); + QString* svgPoints = new QString(); + int length = 0; + QString sBuf; + for(int j = 0; j < PolygonPointsCount; j++) + { + sBuf = "%1,%2 "; + const QPointF & point = polygonPoints.at(j); + + QString temp1 = "%1", temp2 = "%2"; + + temp1 = temp1.arg(point.x()); + temp2 = temp2.arg(point.y()); + + QLocale loc(QLocale::C); + sBuf = sBuf.arg(loc.toFloat(temp1)).arg(loc.toFloat(temp2)); + + svgPoints->insert(length, sBuf); + length += sBuf.length(); + } + points = svgPoints; + } + QStringRef svgPoints = QStringRef(points); + + QPolygonF polygonRes; + + if (!svgPoints.isNull()) + { + QStringList ts = svgPoints.toString().split(QLatin1Char(' '), QString::SkipEmptyParts); + + foreach(const QString sPoint, ts) + { + QStringList sCoord = sPoint.split(QLatin1Char(','), QString::SkipEmptyParts); + + if (sCoord.size() == 2) + { + QPointF point; + point.setX(sCoord.at(0).toFloat()); + point.setY(sCoord.at(1).toFloat()); + polygonRes << point; + } + else if (sCoord.size() == 4){ + //This is the case on system were the "," is used to seperate decimal + QPointF point; + QString x = sCoord.at(0) + "." + sCoord.at(1); + QString y = sCoord.at(2) + "." + sCoord.at(3); + point.setX(x.toFloat()); + point.setY(y.toFloat()); + polygonRes << point; + } + } + } + return polygonRes; +} diff --git a/src/frameworks/UBGeometryUtils.h b/src/frameworks/UBGeometryUtils.h index f267f1f2..f2c70032 100644 --- a/src/frameworks/UBGeometryUtils.h +++ b/src/frameworks/UBGeometryUtils.h @@ -31,6 +31,7 @@ #define UBGEOMETRYUTILS_H_ #include +#include "core/UB.h" class UBGeometryUtils { @@ -39,10 +40,15 @@ class UBGeometryUtils virtual ~UBGeometryUtils(); public: + static QPolygonF lineToPolygon(const QLineF& pLine, const qreal& pWidth, const UBLineStyle::Enum lineStyle); static QPolygonF lineToPolygon(const QLineF& pLine, const qreal& pWidth); static QPolygonF lineToPolygon(const QLineF& pLine, const qreal& pStartWidth, const qreal& pEndWidth); static QRectF lineToInnerRect(const QLineF& pLine, const qreal& pWidth); + static QPolygonF dashedLineToPolygon(const QLineF& pLine, const qreal& pWidth); + static QPolygonF dottedLineToPolygon(const QLineF& pLine, const qreal& pWidth); + static QPolygonF convertLineToPolygon(const QPolygonF& pLine); + static QPolygonF arcToPolygon(const QLineF& startRadius, qreal spanAngle, qreal width); static QPolygonF lineToPolygon(const QPointF& pStart, const QPointF& pEnd, -- 2.33.0