From c6ca99f84b3068d15581258b9adb9265b6426571 Mon Sep 17 00:00:00 2001 From: thomas_lucky13 Date: Thu, 18 Aug 2022 11:48:56 +0400 Subject: [PATCH] Draw dashed and dotted lines --- resources/OpenBoard.qrc | 3 + resources/forms/mainWindow.ui | 50 ++++- resources/images/toolbar/dashedLine.svg | 126 +++++++++++++ resources/images/toolbar/dottedLine.svg | 145 ++++++++++++++ resources/images/toolbar/solidLine.svg | 126 +++++++++++++ src/adaptors/UBCFFSubsetAdaptor.cpp | 108 +++++++++++ src/adaptors/UBCFFSubsetAdaptor.h | 1 + src/adaptors/UBSvgSubsetAdaptor.cpp | 239 ++++++++++++++++++++++++ src/adaptors/UBSvgSubsetAdaptor.h | 4 + src/board/UBBoardController.cpp | 64 ++++++- src/board/UBBoardController.h | 9 + src/board/UBBoardView.cpp | 4 +- src/board/UBDrawingController.cpp | 5 + src/board/UBDrawingController.h | 1 + src/core/UB.h | 11 ++ src/core/UBSettings.cpp | 35 ++++ src/core/UBSettings.h | 6 + src/domain/UBGraphicsLineItem.cpp | 191 +++++++++++++++++++ src/domain/UBGraphicsLineItem.h | 100 ++++++++++ src/domain/UBGraphicsScene.cpp | 136 +++++++++++--- src/domain/UBGraphicsScene.h | 5 + src/domain/UBItem.cpp | 3 + src/domain/domain.pri | 2 + 23 files changed, 1342 insertions(+), 32 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 create mode 100644 src/domain/UBGraphicsLineItem.cpp create mode 100644 src/domain/UBGraphicsLineItem.h diff --git a/resources/OpenBoard.qrc b/resources/OpenBoard.qrc index d1a5661f..155356b3 100644 --- a/resources/OpenBoard.qrc +++ b/resources/OpenBoard.qrc @@ -126,6 +126,9 @@ images/toolbar/eraserTool.png images/toolbar/lineTool.png images/toolbar/tools.png + images/toolbar/solidLine.svg + images/toolbar/dashedLine.svg + images/toolbar/dottedLine.svg images/stylusPalette/arrow.png images/stylusPalette/arrowOn.png images/stylusPalette/handPlay.png diff --git a/resources/forms/mainWindow.ui b/resources/forms/mainWindow.ui index a24810b4..3b63b316 100644 --- a/resources/forms/mainWindow.ui +++ b/resources/forms/mainWindow.ui @@ -7,7 +7,7 @@ 0 0 1342 - 223 + 268 @@ -1702,6 +1702,54 @@ Draw intermediate grid lines + + + true + + + + :/images/toolbar/solidLine.svg:/images/toolbar/solidLine.svg + + + Line Style + + + Solid Style + + + + + true + + + true + + + + :/images/toolbar/dashedLine.svg:/images/toolbar/dashedLine.svg + + + Line Style + + + Dashed Style + + + + + true + + + + :/images/toolbar/dottedLine.svg:/images/toolbar/dottedLine.svg + + + Line Style + + + Dotted Style + + 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/adaptors/UBCFFSubsetAdaptor.cpp b/src/adaptors/UBCFFSubsetAdaptor.cpp index 71991ca9..3769fd1c 100644 --- a/src/adaptors/UBCFFSubsetAdaptor.cpp +++ b/src/adaptors/UBCFFSubsetAdaptor.cpp @@ -38,6 +38,7 @@ #include "domain/UBItem.h" #include "domain/UBGraphicsPolygonItem.h" +#include "domain/UBGraphicsLineItem.h" #include "domain/UBGraphicsStroke.h" #include "domain/UBGraphicsTextItem.h" #include "domain/UBGraphicsSvgItem.h" @@ -74,6 +75,7 @@ static QString tG = "g"; static QString tSwitch = "switch"; static QString tPolygon = "polygon"; static QString tPolyline = "polyline"; +static QString tLine = "line"; static QString tRect = "rect"; static QString tSvg = "svg"; static QString tText = "text"; @@ -90,6 +92,8 @@ static QString aFill = "fill"; static QString aFillopacity = "fill-opacity"; static QString aX = "x"; static QString aY = "y"; +static QString aX2 = "x2"; +static QString aY2 = "y2"; static QString aWidth = "width"; static QString aHeight = "height"; static QString aStroke = "stroke"; @@ -115,6 +119,7 @@ static QString aHref = "href"; static QString aBackground = "background"; static QString aLocked = "locked"; static QString aEditable = "editable"; +static QString aLinestyle = "line-style"; //attributes part names static QString apRotate = "rotate"; @@ -581,6 +586,108 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgPolyline(const QDomElement & return true; } + +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgLine(const QDomElement &element) +{ + QString svgPoints = element.attribute(aPoints); + QLineF line; + + qreal x1 = element.attribute(aX).toDouble(); + qreal y1 = element.attribute(aY).toDouble(); + qreal x2 = element.attribute(aX2).toDouble(); + qreal y2 = element.attribute(aY2).toDouble(); + qreal width = element.attribute(aWidth).toDouble(); + qreal height = element.attribute(aHeight).toDouble(); + QString textStrokeColor = element.attribute(aStroke); + QString textStrokeWidth = element.attribute(aStrokewidth); + qreal style = element.attribute(aLinestyle).toDouble(); + + QColor strokeColor = !textStrokeColor.isNull() ? colorFromString(textStrokeColor) : QColor(); + int strokeWidth = textStrokeWidth.toInt(); + + width += strokeWidth; + height += strokeWidth; + + QPen pen; + if (strokeColor.isValid()) { + pen.setColor(strokeColor); + } + if (strokeWidth) + pen.setWidth(strokeWidth); + if (style == 2) + { + pen.setStyle(Qt::PenStyle::DotLine); + pen.setCapStyle(Qt::PenCapStyle::RoundCap); + } else if (style == 1) + { + pen.setStyle(Qt::PenStyle::DashLine); + } else + { + pen.setStyle(Qt::PenStyle::SolidLine); + } + QUuid itemUuid(element.attribute(aId).right(QUuid().toString().length())); + QUuid itemGroupUuid(element.attribute(aId).left(QUuid().toString().length()-1)); + if (!itemUuid.isNull() && (itemGroupUuid!=itemUuid)) // reimported from UBZ + { + UBGraphicsLineItem *graphicsLine = new UBGraphicsLineItem(line); + + UBGraphicsStroke *stroke = new UBGraphicsStroke(); + //graphicsLine->setStroke(stroke); + + graphicsLine->setPen(pen); + QTransform transform; + QString textTransform = element.attribute(aTransform); + + graphicsLine->resetTransform(); + if (!textTransform.isNull()) { + transform = transformFromString(textTransform, graphicsLine); + } + mCurrentScene->addItem(graphicsLine); + + graphicsLine->setUuid(itemUuid); + mRefToUuidMap.insert(element.attribute(aId), itemUuid.toString()); + + } + else // simple CFF + { + QSvgGenerator *generator = createSvgGenerator(width + pen.width(), height + pen.width()); + QPainter painter; + + painter.begin(generator); + painter.setPen(pen); + painter.drawLine(x1, y1, x2, y2); + painter.end(); + + + //add resulting svg file to scene + UBGraphicsSvgItem *svgItem = mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName())); + + QString uuid = QUuid::createUuid().toString(); + mRefToUuidMap.insert(element.attribute(aId), uuid); + svgItem->setUuid(QUuid(uuid)); + + QTransform transform; + QString textTransform = element.attribute(aTransform); + + svgItem->resetTransform(); + if (!textTransform.isNull()) { + transform = transformFromString(textTransform, svgItem); + } + repositionSvgItem(svgItem, width +strokeWidth, height + strokeWidth, x1 - strokeWidth/2 + transform.m31(), y1 + strokeWidth/2 + transform.m32(), transform); + hashSceneItem(element, svgItem); + + if (mGSectionContainer) + { + addItemToGSection(svgItem); + } + + delete generator; + } + + + return true; +} + void UBCFFSubsetAdaptor::UBCFFSubsetReader::parseTextAttributes(const QDomElement &element, qreal &fontSize, QColor &fontColor, QString &fontFamily, QString &fontStretch, bool &italic, int &fontWeight, @@ -1101,6 +1208,7 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvgElement(const QDomElement &p else if (tagName == tEllipse && !parseSvgEllipse(parent)) return false; else if (tagName == tPolygon && !parseSvgPolygon(parent)) return false; else if (tagName == tPolyline && !parseSvgPolyline(parent)) return false; + else if (tagName == tLine && !parseSvgLine(parent)) return false; else if (tagName == tText && !parseSvgText(parent)) return false; else if (tagName == tTextarea && !parseSvgTextarea(parent)) return false; else if (tagName == tImage && !parseSvgImage(parent)) return false; diff --git a/src/adaptors/UBCFFSubsetAdaptor.h b/src/adaptors/UBCFFSubsetAdaptor.h index 168eee27..96573fe3 100644 --- a/src/adaptors/UBCFFSubsetAdaptor.h +++ b/src/adaptors/UBCFFSubsetAdaptor.h @@ -110,6 +110,7 @@ private: inline bool parseSvgEllipse(const QDomElement &element); inline bool parseSvgPolygon(const QDomElement &element); inline bool parseSvgPolyline(const QDomElement &element); + inline bool parseSvgLine(const QDomElement &element); inline bool parseSvgText(const QDomElement &element); inline bool parseSvgTextarea(const QDomElement &element); inline bool parseSvgImage(const QDomElement &element); diff --git a/src/adaptors/UBSvgSubsetAdaptor.cpp b/src/adaptors/UBSvgSubsetAdaptor.cpp index d4b421eb..6966b051 100644 --- a/src/adaptors/UBSvgSubsetAdaptor.cpp +++ b/src/adaptors/UBSvgSubsetAdaptor.cpp @@ -40,6 +40,7 @@ #include "domain/UBGraphicsPixmapItem.h" #include "domain/UBGraphicsProxyWidget.h" #include "domain/UBGraphicsPolygonItem.h" +#include "domain/UBGraphicsLineItem.h" #include "domain/UBGraphicsMediaItem.h" #include "domain/UBGraphicsWidgetItem.h" #include "domain/UBGraphicsPDFItem.h" @@ -618,6 +619,46 @@ UBGraphicsScene* UBSvgSubsetAdaptor::UBSvgSubsetReader::loadScene(UBDocumentProx group->addToGroup(polygonItem); } } + else if (mXmlReader.name() == "lineL") + { + UBGraphicsLineItem* lineItem = 0; + + QString parentId = mXmlReader.attributes().value(mNamespaceUri, "parent").toString(); + + lineItem = lineItemFromLineSvg(mScene->isDarkBackground() ? Qt::white : Qt::black); + + if(parentId.isEmpty() && strokesGroup) + parentId = strokesGroup->uuid().toString(); + + if(parentId.isEmpty()) + parentId = QUuid::createUuid().toString(); + + if (lineItem) + { + lineItem->setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Graphic)); + + UBGraphicsStrokesGroup* group; + if(!mStrokesList.contains(parentId)){ + group = new UBGraphicsStrokesGroup(); + mStrokesList.insert(parentId,group); + group->setTransform(lineItem->transform()); + UBGraphicsItem::assignZValue(group, lineItem->zValue()); + } + else + group = mStrokesList.value(parentId); + + if (!currentStroke) + currentStroke = new UBGraphicsStroke(); + + if(lineItem->transform().isIdentity()) + lineItem->setTransform(group->transform()); + + group->addToGroup(lineItem); + + lineItem->show(); + group->addToGroup(lineItem); + } + } else if (mXmlReader.name() == "polyline") { QList polygonItems = polygonItemsFromPolylineSvg(mScene->isDarkBackground() ? Qt::white : Qt::black); @@ -1300,6 +1341,49 @@ bool UBSvgSubsetAdaptor::UBSvgSubsetWriter::persistScene(UBDocumentProxy* proxy, continue; } + // Is the item a line? + UBGraphicsLineItem *lineItem = qgraphicsitem_cast (item); + if (lineItem && lineItem->isVisible()) + { + + mXmlWriter.writeStartElement("g"); + + QColor colorOnDarkBackground = lineItem->colorOnDarkBackground(); + QColor colorOnLightBackground = lineItem->colorOnLightBackground(); + + if (colorOnDarkBackground.isValid() && colorOnLightBackground.isValid() && lineItem) + { + mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "z-value" + , QString("%1").arg(lineItem->zValue())); + + mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri + , "fill-on-dark-background", colorOnDarkBackground.name()); + mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri + , "fill-on-light-background", colorOnLightBackground.name()); + + mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "uuid", UBStringUtils::toCanonicalUuid(lineItem->uuid())); + + QVariant locked = lineItem->data(UBGraphicsItemData::ItemLocked); + if (!locked.isNull() && locked.toBool()) + mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "locked", xmlTrue); + + QVariant layer = lineItem->data(UBGraphicsItemData::ItemLayerType); + mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "layer", QString("%1").arg(layer.toInt())); + + QMatrix matrix = lineItem->sceneMatrix(); + if (!matrix.isIdentity()) + mXmlWriter.writeAttribute("transform", toSvgTransform(matrix)); + + qDebug() << "Attributes written"; + + groupHoldsInfo = true; + } + + lineItemToSvgLine(lineItem, groupHoldsInfo); + + continue; + } + if (openStroke) { mXmlWriter.writeEndElement(); //g @@ -1555,6 +1639,53 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::polygonItemToSvgLine(UBGraphicsPolyg } +void UBSvgSubsetAdaptor::UBSvgSubsetWriter::lineItemToSvgLine(UBGraphicsLineItem* lineItem, bool groupHoldsInfo) +{ + mXmlWriter.writeStartElement("lineL"); + + QLineF line = lineItem->originalLine(); + + mXmlWriter.writeAttribute("x1", QString::number(line.p1().x(), 'f', 2)); + mXmlWriter.writeAttribute("y1", QString::number(line.p1().y(), 'f', 2)); + + // SVG renderers (Chrome) do not like line where (x1, y1) == (x2, y2) + qreal x2 = line.p2().x(); + if (line.p1() == line.p2()) + x2 += 0.01; + + mXmlWriter.writeAttribute("x2", QString::number(x2, 'f', 2)); + mXmlWriter.writeAttribute("y2", QString::number(line.p2().y(), 'f', 2)); + + mXmlWriter.writeAttribute("stroke-width", QString::number(lineItem->originalWidth(), 'f', -1)); + mXmlWriter.writeAttribute("stroke", lineItem->pen().color().name()); + + qreal alpha = lineItem->pen().color().alphaF(); + if (alpha < 1.0) + mXmlWriter.writeAttribute("stroke-opacity", QString::number(alpha, 'f', 2)); + mXmlWriter.writeAttribute("stroke-linecap", "round"); + + switch (lineItem->style()) + { + case Qt::PenStyle::DotLine: + mXmlWriter.writeAttribute("line-style", "2"); + break; + case Qt::PenStyle::DashLine: + mXmlWriter.writeAttribute("line-style", "1"); + break; + default: + mXmlWriter.writeAttribute("line-style", "0"); + } + + if (!groupHoldsInfo) + { + mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "z-value", QString("%1").arg(lineItem->zValue())); + mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "fill-on-dark-background", lineItem->colorOnDarkBackground().name()); + mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "fill-on-light-background", lineItem->colorOnLightBackground().name()); + } + + mXmlWriter.writeEndElement(); + +} void UBSvgSubsetAdaptor::UBSvgSubsetWriter::strokeToSvgPolyline(UBGraphicsStroke* stroke, bool groupHoldsInfo) { @@ -1901,6 +2032,114 @@ UBGraphicsPolygonItem* UBSvgSubsetAdaptor::UBSvgSubsetReader::polygonItemFromLin return polygonItem; } +UBGraphicsLineItem* UBSvgSubsetAdaptor::UBSvgSubsetReader::lineItemFromLineSvg(const QColor& pDefaultColor) +{ + QStringRef svgX1 = mXmlReader.attributes().value("x1"); + QStringRef svgY1 = mXmlReader.attributes().value("y1"); + QStringRef svgX2 = mXmlReader.attributes().value("x2"); + QStringRef svgY2 = mXmlReader.attributes().value("y2"); + + qreal style = mXmlReader.attributes().value("line-style").toDouble(); + + QLineF line; + + if (!svgX1.isNull() && !svgY1.isNull() && !svgX2.isNull() && !svgY2.isNull()) + { + qreal x1 = svgX1.toString().toFloat(); + qreal y1 = svgY1.toString().toFloat(); + qreal x2 = svgX2.toString().toFloat(); + qreal y2 = svgY2.toString().toFloat(); + + line.setLine(x1, y1, x2, y2); + } + else + { + qWarning() << "cannot make sense of 'line' value"; + return 0; + } + + QStringRef strokeWidth = mXmlReader.attributes().value("stroke-width"); + + qreal lineWidth = 1.; + + if (!strokeWidth.isNull()) + { + lineWidth = strokeWidth.toString().toFloat(); + } + + UBGraphicsLineItem* lineItem = new UBGraphicsLineItem(line, lineWidth); + graphicsItemFromSvg(lineItem); + + QStringRef svgStroke = mXmlReader.attributes().value("stroke"); + + QColor penColor = pDefaultColor; + + if (!svgStroke.isNull()) + { + penColor.setNamedColor(svgStroke.toString()); + + } + + QStringRef svgStrokeOpacity = mXmlReader.attributes().value("stroke-opacity"); + qreal opacity = 1.0; + + if (!svgStrokeOpacity.isNull()) + { + opacity = svgStrokeOpacity.toString().toFloat(); + penColor.setAlphaF(opacity); + } + + lineItem->setColor(penColor); + if (style == 2) + { + lineItem->setStyle(Qt::PenStyle::DotLine); + } else if (style == 1) + { + lineItem->setStyle(Qt::PenStyle::DashLine); + } else + { + lineItem->setStyle(Qt::PenStyle::SolidLine); + } + QStringRef ubFillOnDarkBackground = mXmlReader.attributes().value(mNamespaceUri, "fill-on-dark-background"); + + if (!ubFillOnDarkBackground.isNull()) + { + QColor color; + color.setNamedColor(ubFillOnDarkBackground.toString()); + if (!color.isValid()) + color = Qt::white; + + color.setAlphaF(opacity); + lineItem->setColorOnDarkBackground(color); + } + else + { + QColor color = mGroupDarkBackgroundColor; + color.setAlphaF(opacity); + lineItem->setColorOnDarkBackground(color); + } + + QStringRef ubFillOnLightBackground = mXmlReader.attributes().value(mNamespaceUri, "fill-on-light-background"); + + if (!ubFillOnLightBackground.isNull()) + { + QColor color; + color.setNamedColor(ubFillOnLightBackground.toString()); + if (!color.isValid()) + color = Qt::black; + color.setAlphaF(opacity); + lineItem->setColorOnLightBackground(color); + } + else + { + QColor color = mGroupLightBackgroundColor; + color.setAlphaF(opacity); + lineItem->setColorOnLightBackground(color); + } + + return lineItem; +} + QList UBSvgSubsetAdaptor::UBSvgSubsetReader::polygonItemsFromPolylineSvg(const QColor& pDefaultColor) { QStringRef strokeWidth = mXmlReader.attributes().value("stroke-width"); diff --git a/src/adaptors/UBSvgSubsetAdaptor.h b/src/adaptors/UBSvgSubsetAdaptor.h index 25ccc9ef..3e025d86 100644 --- a/src/adaptors/UBSvgSubsetAdaptor.h +++ b/src/adaptors/UBSvgSubsetAdaptor.h @@ -38,6 +38,7 @@ class UBGraphicsSvgItem; class UBGraphicsPolygonItem; +class UBGraphicsLineItem; class UBGraphicsPixmapItem; class UBGraphicsPDFItem; class UBGraphicsWidgetItem; @@ -125,6 +126,8 @@ class UBSvgSubsetAdaptor QList polygonItemsFromPolylineSvg(const QColor& pDefaultColor); + UBGraphicsLineItem* lineItemFromLineSvg(const QColor& pDefaultPenColor); + UBGraphicsPixmapItem* pixmapItemFromSvg(); UBGraphicsSvgItem* svgItemFromSvg(); @@ -195,6 +198,7 @@ class UBSvgSubsetAdaptor void persistStrokeToDom(QGraphicsItem *strokeItem, QDomElement *curParent, QDomDocument *curDomDocument); void polygonItemToSvgPolygon(UBGraphicsPolygonItem* polygonItem, bool groupHoldsInfo); void polygonItemToSvgLine(UBGraphicsPolygonItem* polygonItem, bool groupHoldsInfo); + void lineItemToSvgLine(UBGraphicsLineItem* lineItem, bool groupHoldsInfo); void strokeToSvgPolyline(UBGraphicsStroke* stroke, bool groupHoldsInfo); void strokeToSvgPolygon(UBGraphicsStroke* stroke, bool groupHoldsInfo); diff --git a/src/board/UBBoardController.cpp b/src/board/UBBoardController.cpp index dd5afac5..21b2b861 100644 --- a/src/board/UBBoardController.cpp +++ b/src/board/UBBoardController.cpp @@ -300,6 +300,7 @@ QRectF UBBoardController::controlGeometry() void UBBoardController::setupToolbar() { + QAction* newPropertyPaletteWidget; UBSettings *settings = UBSettings::settings(); // Setup color choice widget @@ -314,7 +315,7 @@ void UBBoardController::setupToolbar() new UBToolbarButtonGroup(mMainWindow->boardToolBar, colorActions); colorChoice->setLabel(tr("Color")); - mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, colorChoice); + newPropertyPaletteWidget = mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, colorChoice); connect(settings->appToolBarDisplayText, SIGNAL(changed(QVariant)), colorChoice, SLOT(displayText(QVariant))); connect(colorChoice, SIGNAL(activated(int)), this, SLOT(setColorIndex(int))); @@ -327,6 +328,7 @@ void UBBoardController::setupToolbar() colorChoice->colorPaletteChanged(); colorChoice->setCurrentIndex(settings->penColorIndex()); colorActions.at(settings->penColorIndex())->setChecked(true); + mPropertyPaletteWidgets.insert(color, newPropertyPaletteWidget); // Setup line width choice widget QList lineWidthActions; @@ -349,7 +351,8 @@ void UBBoardController::setupToolbar() lineWidthChoice->setCurrentIndex(settings->penWidthIndex()); lineWidthActions.at(settings->penWidthIndex())->setChecked(true); - mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, lineWidthChoice); + newPropertyPaletteWidget = mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, lineWidthChoice); + mPropertyPaletteWidgets.insert(lineWidth, newPropertyPaletteWidget); //-----------------------------------------------------------// // Setup eraser width choice widget @@ -362,7 +365,7 @@ void UBBoardController::setupToolbar() UBToolbarButtonGroup *eraserWidthChoice = new UBToolbarButtonGroup(mMainWindow->boardToolBar, eraserWidthActions); - mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, eraserWidthChoice); + newPropertyPaletteWidget = mMainWindow->boardToolBar->insertWidget(mMainWindow->actionBackgrounds, eraserWidthChoice); connect(settings->appToolBarDisplayText, SIGNAL(changed(QVariant)), eraserWidthChoice, SLOT(displayText(QVariant))); connect(eraserWidthChoice, SIGNAL(activated(int)), UBDrawingController::drawingController(), SLOT(setEraserWidthIndex(int))); @@ -372,11 +375,32 @@ void UBBoardController::setupToolbar() eraserWidthActions.at(settings->eraserWidthIndex())->setChecked(true); mMainWindow->boardToolBar->insertSeparator(mMainWindow->actionBackgrounds); - + 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))); - UBApplication::app()->insertSpaceToToolbarBeforeAction(mMainWindow->boardToolBar, mMainWindow->actionBoard); + 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); UBApplication::app()->decorateActionMenu(mMainWindow->actionMenu); mMainWindow->actionBoard->setVisible(false); @@ -2185,9 +2209,9 @@ void UBBoardController::saveViewState() void UBBoardController::stylusToolChanged(int tool) { + UBStylusTool::Enum eTool = (UBStylusTool::Enum)tool; if (UBPlatformUtils::hasVirtualKeyboard() && mPaletteManager->mKeyboardPalette) { - UBStylusTool::Enum eTool = (UBStylusTool::Enum)tool; if(eTool != UBStylusTool::Selector && eTool != UBStylusTool::Text) { if(mPaletteManager->mKeyboardPalette->m_isVisible) @@ -2201,6 +2225,34 @@ void UBBoardController::stylusToolChanged(int tool) } } } + if (eTool == UBStylusTool::Pen || eTool == UBStylusTool::Marker) + { + 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 018026fd..f582d3a2 100644 --- a/src/board/UBBoardController.h +++ b/src/board/UBBoardController.h @@ -322,6 +322,15 @@ class UBBoardController : public UBDocumentContainer QTimer *mAutosaveTimer; + enum PropertyPalette + { + color, + lineWidth, + eraserWidth, + lineStyle + }; + QMap mPropertyPaletteWidgets; + private slots: void stylusToolDoubleClicked(int tool); void boardViewResized(QResizeEvent* event); diff --git a/src/board/UBBoardView.cpp b/src/board/UBBoardView.cpp index 3b404db6..84d56981 100644 --- a/src/board/UBBoardView.cpp +++ b/src/board/UBBoardView.cpp @@ -67,6 +67,7 @@ #include "domain/UBGraphicsWidgetItem.h" #include "domain/UBGraphicsPDFItem.h" #include "domain/UBGraphicsPolygonItem.h" +#include "domain/UBGraphicsLineItem.h" #include "domain/UBItem.h" #include "domain/UBGraphicsMediaItem.h" #include "domain/UBGraphicsSvgItem.h" @@ -1210,7 +1211,8 @@ void UBBoardView::mouseMoveEvent (QMouseEvent *event) || item->type() == UBGraphicsSvgItem::Type || item->type() == UBGraphicsTextItem::Type || item->type() == UBGraphicsStrokesGroup::Type - || item->type() == UBGraphicsGroupContainerItem::Type) { + || item->type() == UBGraphicsGroupContainerItem::Type + || item->type() == UBGraphicsLineItem::Type) { if (!mJustSelectedItems.contains(item)) { diff --git a/src/board/UBDrawingController.cpp b/src/board/UBDrawingController.cpp index b1843eb6..da105aa4 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 61d4ad82..4ed3b981 100644 --- a/src/board/UBDrawingController.h +++ b/src/board/UBDrawingController.h @@ -81,6 +81,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..c9bfa5cb 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 @@ -173,6 +183,7 @@ struct UBGraphicsItemType GraphicsWidgetItemType, //65556 UserTypesCount, //65557 AxesItemType, //65558 + LineItemType, //65559 SelectionFrameType // this line must be the last line in this enum because it is types counter. }; }; diff --git a/src/core/UBSettings.cpp b/src/core/UBSettings.cpp index 663c5582..09135e60 100644 --- a/src/core/UBSettings.cpp +++ b/src/core/UBSettings.cpp @@ -785,6 +785,41 @@ qreal UBSettings::currentEraserWidth() return width; } +//----------------------------------------// +// line +int UBSettings::lineStyleIndex() +{ + return value("Board/LineStyleIndex", 0).toInt(); +} + +void UBSettings::setLineStyleIndex(int index) +{ + setValue("Board/LineStyleIndex", index); +} +Qt::PenStyle UBSettings::currentLineStyle() +{ + Qt::PenStyle style = Qt::SolidLine; + + switch (lineStyleIndex()) + { + case UBLineStyle::Solid: + style = Qt::SolidLine; + break; + case UBLineStyle::Dotted: + style = Qt::DotLine; + break; + case UBLineStyle::Dashed: + style = Qt::DashLine; + break; + default: + Q_ASSERT(false); + style = Qt::SolidLine; + break; + } + + return style; +} + bool UBSettings::isDarkBackground() { return value("Board/DarkBackground", 0).toBool(); diff --git a/src/core/UBSettings.h b/src/core/UBSettings.h index 8d5909a3..77cefead 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(); + Qt::PenStyle 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/UBGraphicsLineItem.cpp b/src/domain/UBGraphicsLineItem.cpp new file mode 100644 index 00000000..8cbc0db6 --- /dev/null +++ b/src/domain/UBGraphicsLineItem.cpp @@ -0,0 +1,191 @@ +#include "UBGraphicsLineItem.h" + +#include "frameworks/UBGeometryUtils.h" +#include "UBGraphicsScene.h" +#include "core/memcheck.h" + + +UBGraphicsLineItem::UBGraphicsLineItem (QGraphicsItem * parent) + : QGraphicsLineItem(parent) + , mHasAlpha(false) + , mOriginalWidth(-1) + , mIsNominalLine(false) +{ + // NOOP + initialize(); +} + +UBGraphicsLineItem::UBGraphicsLineItem (const QLineF & line, QGraphicsItem * parent) + : QGraphicsLineItem(line, parent) + , mOriginalWidth(-1) + , mIsNominalLine(false) +{ + // NOOP + initialize(); +} + + +UBGraphicsLineItem::UBGraphicsLineItem (const QLineF& pLine, qreal pWidth) + : QGraphicsLineItem(pLine) + , mOriginalLine(pLine) + , mOriginalWidth(pWidth) + , mIsNominalLine(true) +{ + // NOOP + initialize(); +} + +UBGraphicsLineItem::UBGraphicsLineItem (const QLineF& pLine, qreal pStartWidth, qreal pEndWidth) + : QGraphicsLineItem(pLine) + , mOriginalLine(pLine) + , mOriginalWidth(pEndWidth) + , mIsNominalLine(true) +{ + // NOOP + initialize(); +} + + +void UBGraphicsLineItem::initialize() +{ + //setData(UBGraphicsItemData::itemLayerType, QVariant(itemLayerType::DrawingItem)); //Necessary to set if we want z value to be assigned correctly + setDelegate(new UBGraphicsItemDelegate(this, 0, GF_COMMON + | GF_RESPECT_RATIO + | GF_REVOLVABLE + | GF_FLIPPABLE_ALL_AXIS)); + setUuid(QUuid::createUuid()); + setData(UBGraphicsItemData::itemLayerType, QVariant(itemLayerType::ObjectItem)); //Necessary to set if we want z value to be assigned correctly + setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); + setFlag(QGraphicsItem::ItemIsSelectable, true); + setFlag(QGraphicsItem::ItemIsMovable, true); +} + +void UBGraphicsLineItem::setUuid(const QUuid &pUuid) +{ + UBItem::setUuid(pUuid); + setData(UBGraphicsItemData::ItemUuid, QVariant(pUuid)); //store item uuid inside the QGraphicsItem to fast operations with Items on the scene +} + +UBGraphicsLineItem::~UBGraphicsLineItem() +{ + +} + +void UBGraphicsLineItem::setColor(const QColor& pColor) +{ + QPen pen = QPen(pColor); + pen.setStyle(style()); + if (style()==Qt::PenStyle::DotLine) + { + pen.setCapStyle(Qt::PenCapStyle::RoundCap); + } + pen.setWidth(mOriginalWidth); + QGraphicsLineItem::setPen(pen); + + mHasAlpha = (pColor.alphaF() < 1.0); +} + + +QColor UBGraphicsLineItem::color() const +{ + return QGraphicsLineItem::pen().color(); +} + +void UBGraphicsLineItem::setStyle(const Qt::PenStyle& style) +{ + QPen pen = QPen(color()); + pen.setStyle(style); + if (style==Qt::PenStyle::DotLine) + { + pen.setCapStyle(Qt::PenCapStyle::RoundCap); + } + pen.setWidth(mOriginalWidth); + QGraphicsLineItem::setPen(pen); +} + +Qt::PenStyle UBGraphicsLineItem::style() const +{ + return QGraphicsLineItem::pen().style(); +} + +QList UBGraphicsLineItem::linePoints() +{ + QList points = QList(); + qreal incr = 1/line().length(); + if (incr<0) incr*=-1; + if (incr>0) + { + for (qreal t = 0; t <= 1; t+=incr) + { + points.push_back(line().pointAt(t)); + } + } + return points; +} + +UBItem* UBGraphicsLineItem::deepCopy() const +{ + UBGraphicsLineItem* copy = new UBGraphicsLineItem(line()); + copyItemParameters(copy); + return copy; +} + + +void UBGraphicsLineItem::copyItemParameters(UBItem *copy) const +{ + UBGraphicsLineItem *cp = dynamic_cast(copy); + if (cp) + { + cp->mOriginalLine = this->mOriginalLine; + cp->mOriginalWidth = this->mOriginalWidth; + cp->mIsNominalLine = this->mIsNominalLine; + + cp->setTransform(transform()); + cp->setPos(pos()); + cp->setPen(this->pen()); + cp->mHasAlpha = this->mHasAlpha; + + cp->setColorOnDarkBackground(this->colorOnDarkBackground()); + cp->setColorOnLightBackground(this->colorOnLightBackground()); + + cp->setFlag(QGraphicsItem::ItemIsMovable, true); + cp->setFlag(QGraphicsItem::ItemIsSelectable, true); + cp->setZValue(this->zValue()); + cp->setData(UBGraphicsItemData::ItemLayerType, this->data(UBGraphicsItemData::ItemLayerType)); + cp->setData(UBGraphicsItemData::ItemLocked, this->data(UBGraphicsItemData::ItemLocked)); + } +} + +void UBGraphicsLineItem::paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) +{ + QStyleOptionGraphicsItem styleOption = QStyleOptionGraphicsItem(*option); + if(mHasAlpha && scene() && scene()->isLightBackground()) + painter->setCompositionMode(QPainter::CompositionMode_SourceOver); + + painter->setRenderHints(QPainter::Antialiasing); + + QGraphicsLineItem::paint(painter, option, widget); + Delegate()->postpaint(painter, &styleOption, widget); +} + +UBGraphicsScene* UBGraphicsLineItem::scene() +{ + return qobject_cast(QGraphicsLineItem::scene()); +} + +void UBGraphicsLineItem::SetDelegate() +{ + Delegate()->createControls(); +} + +QVariant UBGraphicsLineItem::itemChange(GraphicsItemChange change, const QVariant &value) +{ + QVariant newValue = Delegate()->itemChange(change, value); + UBGraphicsItem *item = dynamic_cast(this); + if (item) + { + item->Delegate()->positionHandles(); + } + + return QGraphicsItem::itemChange(change, newValue); +} diff --git a/src/domain/UBGraphicsLineItem.h b/src/domain/UBGraphicsLineItem.h new file mode 100644 index 00000000..56d4b88d --- /dev/null +++ b/src/domain/UBGraphicsLineItem.h @@ -0,0 +1,100 @@ +#ifndef UBGRAPHICSLINEITEM_H +#define UBGRAPHICSLINEITEM_H + +#include +#include "core/UB.h" +#include "UBItem.h" + +class UBItem; +class UBGraphicsScene; + +class UBGraphicsLineItem : public QGraphicsLineItem, public UBItem, public UBGraphicsItem +{ + + public: + + UBGraphicsLineItem(QGraphicsItem * parent = 0 ); + UBGraphicsLineItem(const QLineF& line, qreal pWidth); + UBGraphicsLineItem(const QLineF& pLine, qreal pStartWidth, qreal pEndWidth); + UBGraphicsLineItem(const QLineF & line, QGraphicsItem * parent = 0); + + ~UBGraphicsLineItem(); + + void initialize(); + + void setUuid(const QUuid &pUuid); + + void setColor(const QColor& color); + void setStyle(const Qt::PenStyle& style); + + QColor color() const; + Qt::PenStyle style() const; + + virtual UBGraphicsScene* scene(); + + enum { Type = UBGraphicsItemType::LineItemType }; + + virtual int type() const + { + return Type; + } + + void setLine(const QLineF pLine) + { + mIsNominalLine = false; + QGraphicsLineItem::setLine(pLine); + } + + virtual UBItem* deepCopy() const; + + virtual void copyItemParameters(UBItem *copy) const; + + QLineF originalLine() { return mOriginalLine;} + qreal originalWidth() { return mOriginalWidth;} + bool isNominalLine() {return mIsNominalLine;} + + void setNominalLine(bool isNominalLine) { mIsNominalLine = isNominalLine; } + + QList linePoints(); + + QColor colorOnDarkBackground() const + { + return mColorOnDarkBackground; + } + + void setColorOnDarkBackground(QColor pColorOnDarkBackground) + { + mColorOnDarkBackground = pColorOnDarkBackground; + } + + QColor colorOnLightBackground() const + { + return mColorOnLightBackground; + } + + void setColorOnLightBackground(QColor pColorOnLightBackground) + { + mColorOnLightBackground = pColorOnLightBackground; + } + + void SetDelegate(); + + protected: + void paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget); + virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); + + private: + + bool mHasAlpha; + + QLineF mOriginalLine; + qreal mOriginalWidth; + bool mIsNominalLine; + + QColor mColorOnDarkBackground; + QColor mColorOnLightBackground; + +}; + +#endif // UBGRAPHICSLINEITEM_H + diff --git a/src/domain/UBGraphicsScene.cpp b/src/domain/UBGraphicsScene.cpp index 0b95a110..7ff28467 100644 --- a/src/domain/UBGraphicsScene.cpp +++ b/src/domain/UBGraphicsScene.cpp @@ -70,6 +70,7 @@ #include "UBGraphicsPixmapItem.h" #include "UBGraphicsSvgItem.h" #include "UBGraphicsPolygonItem.h" +#include "UBGraphicsLineItem.h" #include "UBGraphicsMediaItem.h" #include "UBGraphicsWidgetItem.h" #include "UBGraphicsPDFItem.h" @@ -541,23 +542,6 @@ bool UBGraphicsScene::inputDeviceMove(const QPointF& scenePos, const qreal& pres if (currentTool == UBStylusTool::Line || dc->activeRuler()) { - if (UBDrawingController::drawingController()->stylusTool() != UBStylusTool::Marker) - if(NULL != mpLastPolygon && NULL != mCurrentStroke && mAddedItems.size() > 0){ - UBCoreGraphicsScene::removeItemFromDeletion(mpLastPolygon); - mAddedItems.remove(mpLastPolygon); - mCurrentStroke->remove(mpLastPolygon); - if (mCurrentStroke->polygons().empty()){ - delete mCurrentStroke; - mCurrentStroke = NULL; - } - removeItem(mpLastPolygon); - mPreviousPolygonItems.removeAll(mpLastPolygon); - } - - // ------------------------------------------------------------------------ - // Here we wanna make sure that the Line will 'grip' at i*45, i*90 degrees - // ------------------------------------------------------------------------ - QLineF radius(mPreviousPoint, position); qreal angle = radius.angle(); angle = qRound(angle / 45) * 45; @@ -667,7 +651,16 @@ bool UBGraphicsScene::inputDeviceRelease(int tool) if (currentTool == UBStylusTool::Eraser) hideEraser(); + if(currentTool == UBStylusTool::Line) + { + if (mUndoRedoStackEnabled) + { //should be deleted after scene own undo stack implemented + UBGraphicsItemUndoCommand* uc = new UBGraphicsItemUndoCommand(this, NULL, mpLastLine); + UBApplication::undoStack->push(uc); + mAddedItems.clear(); + } + } else{ UBDrawingController *dc = UBDrawingController::drawingController(); @@ -741,6 +734,7 @@ bool UBGraphicsScene::inputDeviceRelease(int tool) mCurrentPolygon = 0; } } + } if (mRemovedItems.size() > 0 || mAddedItems.size() > 0) { @@ -943,8 +937,17 @@ void UBGraphicsScene::drawLineTo(const QPointF &pEndPoint, const qreal &startWid mAddedItems.clear(); } - UBGraphicsPolygonItem *polygonItem = lineToPolygonItem(QLineF(mPreviousPoint, pEndPoint), initialWidth, endWidth); - addPolygonItemToCurrentStroke(polygonItem); + if (UBDrawingController::drawingController()->stylusTool() != UBStylusTool::Line) + { + UBGraphicsPolygonItem *polygonItem = lineToPolygonItem(QLineF(mPreviousPoint, pEndPoint), initialWidth, endWidth); + addPolygonItemToCurrentStroke(polygonItem); + } else + { + UBGraphicsLineItem *lineItem = new UBGraphicsLineItem(QLineF(mPreviousPoint, pEndPoint), initialWidth, endWidth); + initLineItem(lineItem); + addLineItemToCurrentStroke(lineItem); + } + if (!bLineStyle) { mPreviousPoint = pEndPoint; @@ -998,6 +1001,20 @@ void UBGraphicsScene::addPolygonItemToCurrentStroke(UBGraphicsPolygonItem* polyg } +void UBGraphicsScene::addLineItemToCurrentStroke(UBGraphicsLineItem* lineItem) +{ + lineItem->setFlag(QGraphicsItem::ItemIsMovable, true); + lineItem->setFlag(QGraphicsItem::ItemIsSelectable, true); + lineItem->SetDelegate(); + + mpLastLine = lineItem; + mAddedItems.insert(lineItem); + + // Here we add the item to the scene + addItem(lineItem); + +} + void UBGraphicsScene::eraseLineTo(const QPointF &pEndPoint, const qreal &pWidth) { const QLineF line(mPreviousPoint, pEndPoint); @@ -1017,13 +1034,15 @@ void UBGraphicsScene::eraseLineTo(const QPointF &pEndPoint, const qreal &pWidth) typedef QList POLYGONSLIST; QList intersectedPolygons; + QList intersectedLineItems; + #pragma omp parallel for for(int i=0; i(collidItems[i]); - if(pi == NULL) - continue; - + UBGraphicsLineItem *li = qgraphicsitem_cast(collidItems[i]); + if(pi != NULL) + { QPainterPath itemPainterPath; itemPainterPath.addPolygon(pi->sceneTransform().map(pi->polygon())); @@ -1046,6 +1065,23 @@ void UBGraphicsScene::eraseLineTo(const QPointF &pEndPoint, const qreal &pWidth) intersectedPolygons << newPath.simplified().toFillPolygons(pi->sceneTransform().inverted()); } } + } else if (li != NULL) + { + QPainterPath itemPainterPath; + QList linePoints = li->linePoints(); + for (int i=0; i < linePoints.count(); ++i) + { + itemPainterPath.addEllipse(linePoints[i], 1, 1); + } + if (eraserPath.contains(itemPainterPath) || eraserPath.intersects(itemPainterPath)) + { + #pragma omp critical + { + // Compete remove item + intersectedLineItems << li; + } + } + } } for(int i=0; isetTransform(t); } - if (!intersectedItems.empty()) + for (int i=0; isetTransform(t); + } + } + + if (!intersectedItems.empty() || !intersectedLineItems.empty()) setModified(true); } @@ -1271,6 +1321,37 @@ void UBGraphicsScene::initPolygonItem(UBGraphicsPolygonItem* polygonItem) polygonItem->setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Graphic)); } +void UBGraphicsScene::initLineItem(UBGraphicsLineItem* lineItem) +{ + QColor colorOnDarkBG; + QColor colorOnLightBG; + + if (UBDrawingController::drawingController()->stylusTool() != UBStylusTool::Marker) + { + colorOnDarkBG = UBApplication::boardController->penColorOnDarkBackground(); + colorOnLightBG = UBApplication::boardController->penColorOnLightBackground(); + } + + if (mDarkBackground) + { + lineItem->setColor(colorOnDarkBG); + } + else + { + lineItem->setColor(colorOnLightBG); + } + + lineItem->setColorOnDarkBackground(colorOnDarkBG); + lineItem->setColorOnLightBackground(colorOnLightBG); + + lineItem->setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Graphic)); + lineItem->setStyle(UBSettings::settings()->currentLineStyle()); + + QPen linePen = lineItem->pen(); + linePen.setWidth(lineItem->originalWidth()); + lineItem->setPen(linePen); +} + UBGraphicsPolygonItem* UBGraphicsScene::arcToPolygonItem(const QLineF& pStartRadius, qreal pSpanAngle, qreal pWidth) { QPolygonF polygon = UBGeometryUtils::arcToPolygon(pStartRadius, pSpanAngle, pWidth); @@ -1491,7 +1572,7 @@ void UBGraphicsScene::clearContent(clearCase pCase) ? qgraphicsitem_cast(item->parentItem()) : 0; UBGraphicsItemDelegate *curDelegate = UBGraphicsItem::Delegate(item); - if (!curDelegate) { + if (!curDelegate && item->type() != UBGraphicsLineItem::Type) { continue; } @@ -1499,6 +1580,12 @@ void UBGraphicsScene::clearContent(clearCase pCase) bool isStrokesGroup = item->type() == UBGraphicsStrokesGroup::Type; bool shouldDelete = false; + if(item->type()==UBGraphicsLineItem::Type) + { + removedItems << item; + this->removeItem(item); + } else + { switch (static_cast(pCase)) { case clearAnnotations : shouldDelete = isStrokesGroup; @@ -1510,6 +1597,7 @@ void UBGraphicsScene::clearContent(clearCase pCase) shouldDelete = !isGroup && !isBackgroundObject(item); break; } + } if(shouldDelete) { if (itemGroup) { diff --git a/src/domain/UBGraphicsScene.h b/src/domain/UBGraphicsScene.h index 9e66d662..54483e75 100644 --- a/src/domain/UBGraphicsScene.h +++ b/src/domain/UBGraphicsScene.h @@ -41,6 +41,7 @@ class UBGraphicsPixmapItem; class UBGraphicsProxyWidget; class UBGraphicsSvgItem; class UBGraphicsPolygonItem; +class UBGraphicsLineItem; class UBGraphicsMediaItem; class UBGraphicsWidgetItem; class UBGraphicsW3CWidgetItem; @@ -400,8 +401,11 @@ public slots: UBGraphicsPolygonItem* curveToPolygonItem(const QList > &points); UBGraphicsPolygonItem* curveToPolygonItem(const QList &points, qreal startWidth, qreal endWidth); void addPolygonItemToCurrentStroke(UBGraphicsPolygonItem* polygonItem); + void addLineItemToCurrentStroke(UBGraphicsLineItem* lineItem); void initPolygonItem(UBGraphicsPolygonItem*); + void initLineItem(UBGraphicsLineItem*); + void drawEraser(const QPointF& pEndPoint, bool pressed = true); void redrawEraser(bool pressed); @@ -493,6 +497,7 @@ public slots: UBZLayerController *mZLayerController; UBGraphicsPolygonItem* mpLastPolygon; UBGraphicsPolygonItem* mTempPolygon; + UBGraphicsLineItem* mpLastLine; bool mDrawWithCompass; UBGraphicsPolygonItem *mCurrentPolygon; diff --git a/src/domain/UBItem.cpp b/src/domain/UBItem.cpp index 4ebbbeec..14348d4f 100644 --- a/src/domain/UBItem.cpp +++ b/src/domain/UBItem.cpp @@ -41,6 +41,7 @@ #include "domain/UBGraphicsScene.h" #include "tools/UBGraphicsCurtainItem.h" #include "domain/UBGraphicsItemDelegate.h" +#include "domain/UBGraphicsLineItem.h" UBItem::UBItem() : mUuid(QUuid()) @@ -135,6 +136,8 @@ UBGraphicsItemDelegate *UBGraphicsItem::Delegate(QGraphicsItem *pItem) case UBGraphicsCurtainItem::Type : result = (static_cast(pItem))->Delegate(); break; + case UBGraphicsLineItem::Type : + result = (static_cast(pItem))->Delegate(); } return result; diff --git a/src/domain/domain.pri b/src/domain/domain.pri index bfe9c11e..91206704 100644 --- a/src/domain/domain.pri +++ b/src/domain/domain.pri @@ -6,6 +6,7 @@ HEADERS += src/domain/UBGraphicsScene.h \ src/domain/UBPageSizeUndoCommand.h \ src/domain/UBGraphicsProxyWidget.h \ src/domain/UBGraphicsSvgItem.h \ + src/domain/UBGraphicsLineItem.h \ src/domain/UBGraphicsPolygonItem.h \ src/domain/UBItem.h \ src/domain/UBGraphicsWidgetItem.h \ @@ -35,6 +36,7 @@ SOURCES += src/domain/UBGraphicsScene.cpp \ src/domain/UBPageSizeUndoCommand.cpp \ src/domain/UBGraphicsProxyWidget.cpp \ src/domain/UBGraphicsSvgItem.cpp \ + src/domain/UBGraphicsLineItem.cpp \ src/domain/UBGraphicsPolygonItem.cpp \ src/domain/UBItem.cpp \ src/domain/UBGraphicsWidgetItem.cpp \