From 7b40574a5be8ff74c41a093380c38a7d7890ee0e Mon Sep 17 00:00:00 2001 From: shibakaneki Date: Wed, 9 May 2012 11:00:15 +0200 Subject: [PATCH] Backup of the strokes as object --- src/board/UBBoardView.cpp | 4 +- src/board/UBDrawingController.cpp | 10 +- src/board/UBDrawingController.h | 2 + src/domain/UBGraphicsPolygonItem.cpp | 7 +- src/domain/UBGraphicsPolygonItem.h | 4 + src/domain/UBGraphicsScene.cpp | 202 +++++++++++++++++---------- src/domain/UBGraphicsStrokesGroup.h | 5 + src/frameworks/UBGeometryUtils.cpp | 3 +- 8 files changed, 159 insertions(+), 78 deletions(-) diff --git a/src/board/UBBoardView.cpp b/src/board/UBBoardView.cpp index 3dd30148..05c16943 100644 --- a/src/board/UBBoardView.cpp +++ b/src/board/UBBoardView.cpp @@ -50,6 +50,7 @@ #include "domain/UBGraphicsVideoItem.h" #include "domain/UBGraphicsAudioItem.h" #include "domain/UBGraphicsSvgItem.h" +#include "domain/UBGraphicsStrokesGroup.h" #include "document/UBDocumentProxy.h" @@ -563,7 +564,8 @@ UBBoardView::mouseMoveEvent (QMouseEvent *event) || item->type() == UBGraphicsPixmapItem::Type || item->type() == UBGraphicsVideoItem::Type || item->type() == UBGraphicsAudioItem::Type - || item->type() == UBGraphicsSvgItem::Type) { + || item->type() == UBGraphicsSvgItem::Type + || item->type() == UBGraphicsStrokesGroup::Type) { if (!mJustSelectedItems.contains(item)) { item->setSelected(true); diff --git a/src/board/UBDrawingController.cpp b/src/board/UBDrawingController.cpp index 2390cded..e03ef408 100644 --- a/src/board/UBDrawingController.cpp +++ b/src/board/UBDrawingController.cpp @@ -45,7 +45,7 @@ UBDrawingController::UBDrawingController(QObject * parent) , mActiveRuler(NULL) , mStylusTool((UBStylusTool::Enum)-1) , mLatestDrawingTool((UBStylusTool::Enum)-1) - //, mDrawingMode(eDrawingMode_Vector) + , mDrawingMode(DRAWING_MODE) { connect(UBSettings::settings(), SIGNAL(colorContextChanged()), this, SIGNAL(colorPaletteChanged())); @@ -106,10 +106,16 @@ void UBDrawingController::setStylusTool(int tool) mStylusTool = (UBStylusTool::Enum)tool; + if(eDrawingMode_Vector == DRAWING_MODE){ + mDrawingMode = eDrawingMode_Vector; + } + if (mStylusTool == UBStylusTool::Pen) UBApplication::mainWindow->actionPen->setChecked(true); - else if (mStylusTool == UBStylusTool::Eraser) + else if (mStylusTool == UBStylusTool::Eraser){ UBApplication::mainWindow->actionEraser->setChecked(true); + mDrawingMode = eDrawingMode_Artistic; + } else if (mStylusTool == UBStylusTool::Marker) UBApplication::mainWindow->actionMarker->setChecked(true); else if (mStylusTool == UBStylusTool::Selector) diff --git a/src/board/UBDrawingController.h b/src/board/UBDrawingController.h index 302800dd..21d4f78d 100644 --- a/src/board/UBDrawingController.h +++ b/src/board/UBDrawingController.h @@ -27,6 +27,8 @@ typedef enum{ eDrawingMode_Vector }eDrawingMode; +#define DRAWING_MODE eDrawingMode_Artistic + class UBDrawingController : public QObject { Q_OBJECT; diff --git a/src/domain/UBGraphicsPolygonItem.cpp b/src/domain/UBGraphicsPolygonItem.cpp index f05dd1e9..9c6dee10 100644 --- a/src/domain/UBGraphicsPolygonItem.cpp +++ b/src/domain/UBGraphicsPolygonItem.cpp @@ -39,6 +39,7 @@ UBGraphicsPolygonItem::UBGraphicsPolygonItem (const QPolygonF & polygon, QGraphi , mOriginalWidth(-1) , mIsNominalLine(false) , mStroke(0) + , mpGroup(NULL) { // NOOP initialize(); @@ -77,6 +78,10 @@ UBGraphicsPolygonItem::~UBGraphicsPolygonItem() clearStroke(); } +void UBGraphicsPolygonItem::setStrokesGroup(UBGraphicsStrokesGroup *group) +{ + mpGroup = group; +} void UBGraphicsPolygonItem::setStroke(UBGraphicsStroke* stroke) { @@ -156,7 +161,7 @@ UBGraphicsPolygonItem* UBGraphicsPolygonItem::deepCopy(const QPolygonF& pol) con copy->mIsNominalLine = false; copy->setStroke(this->stroke()); - copy->setGroup(this->group()); + copy->setStrokesGroup(this->strokesGroup()); copy->setBrush(this->brush()); copy->setPen(this->pen()); copy->mHasAlpha = this->mHasAlpha; diff --git a/src/domain/UBGraphicsPolygonItem.h b/src/domain/UBGraphicsPolygonItem.h index 2934b66b..851092b2 100644 --- a/src/domain/UBGraphicsPolygonItem.h +++ b/src/domain/UBGraphicsPolygonItem.h @@ -19,6 +19,7 @@ #include "core/UB.h" #include "UBItem.h" +#include "UBGraphicsStrokesGroup.h" class UBItem; class UBGraphicsScene; @@ -37,6 +38,8 @@ class UBGraphicsPolygonItem : public QGraphicsPolygonItem, public UBItem void initialize(); + void setStrokesGroup(UBGraphicsStrokesGroup* group); + UBGraphicsStrokesGroup* strokesGroup() const{return mpGroup;} void setColor(const QColor& color); QColor color() const; @@ -132,6 +135,7 @@ class UBGraphicsPolygonItem : public QGraphicsPolygonItem, public UBItem QColor mColorOnLightBackground; UBGraphicsStroke* mStroke; + UBGraphicsStrokesGroup* mpGroup; }; diff --git a/src/domain/UBGraphicsScene.cpp b/src/domain/UBGraphicsScene.cpp index 1494ce85..f6f10436 100644 --- a/src/domain/UBGraphicsScene.cpp +++ b/src/domain/UBGraphicsScene.cpp @@ -567,7 +567,7 @@ bool UBGraphicsScene::inputDeviceRelease() } }else if (mCurrentStroke) { - if(eDrawingMode_Vector == dc->drawingMode()){ + if(eDrawingMode_Vector == DRAWING_MODE){ UBGraphicsStrokesGroup* pStrokes = new UBGraphicsStrokesGroup(); // Remove the strokes that were just drawn here and replace them by a stroke item @@ -575,6 +575,7 @@ bool UBGraphicsScene::inputDeviceRelease() mPreviousPolygonItems.removeAll(poly); removeItem(poly); UBCoreGraphicsScene::removeItemFromDeletion(poly); + poly->setStrokesGroup(pStrokes); pStrokes->addToGroup(poly); } @@ -756,114 +757,169 @@ void UBGraphicsScene::eraseLineTo(const QPointF &pEndPoint, const qreal &pWidth) eraserPathVar.addPolygon(eraserPolygon); const QPainterPath eraserPath = eraserPathVar; + // Get all the items that are intersecting with the eraser path QList collidItems = items(eraserBoundingRect, Qt::IntersectsItemBoundingRect); - QSet toBeAddedItems; - QSet toBeRemovedItems; - - int collidItemsSize = collidItems.size(); + if(eDrawingMode_Vector == UBDrawingController::drawingController()->drawingMode()){ + // NOTE: I decided to reuse the 'artistic' eraser all the time in order to have a better eraser + // For this reason, the following code is not used but we will keep it for now, in case of + // futur requirements. + foreach(QGraphicsItem* poly, collidItems){ + UBGraphicsStrokesGroup* pGroup = dynamic_cast(poly); + if(NULL != pGroup){ + // TODO: Ungroup the item, put back the polygons on the scene, deal with the + // eraser's bounding rect, remove the polygons that must be removed + // then create new groups. + + // Get all substrokes and verify if they are part of the eraserpath then deal with it + foreach(QGraphicsItem* item, poly->childItems()){ + UBGraphicsPolygonItem* polygon = dynamic_cast(item); + if(NULL != polygon){ + if(eraserBoundingRect.intersects(polygon->boundingRect())){ + pGroup->removeFromGroup(polygon); + removeItem(polygon); + } + } + } + } + } - toBeAddedItems.reserve(collidItemsSize); - toBeRemovedItems.reserve(collidItemsSize); + }else{ + QSet toBeAddedItems; + QSet toBeRemovedItems; + int collidItemsSize = collidItems.size(); + toBeAddedItems.reserve(collidItemsSize); + toBeRemovedItems.reserve(collidItemsSize); - if (mShouldUseOMP) - { -#pragma omp parallel for - for (int i = 0; i < collidItemsSize; i++) + if (mShouldUseOMP) { - UBGraphicsPolygonItem *collidingPolygonItem - = qgraphicsitem_cast (collidItems.at(i)); - - if (collidingPolygonItem) + #pragma omp parallel for + for (int i = 0; i < collidItemsSize; i++) { - if(eraserInnerRect.contains(collidingPolygonItem->boundingRect())) - { -#pragma omp critical - toBeRemovedItems << collidingPolygonItem; - } - else - { - QPolygonF collidingPolygon = collidingPolygonItem->polygon(); - QPainterPath collidingPath; - collidingPath.addPolygon(collidingPolygon); + UBGraphicsPolygonItem *collidingPolygonItem = dynamic_cast(collidItems.at(i)); - QPainterPath croppedPath = collidingPath.subtracted(eraserPath); - QPainterPath croppedPathSimplified = croppedPath.simplified(); + if (NULL != collidingPolygonItem) + { + UBGraphicsStrokesGroup* pGroup = collidingPolygonItem->strokesGroup(); - if (croppedPath == collidingPath) + if(eraserInnerRect.contains(collidingPolygonItem->boundingRect())) { - // NOOP - } - else if (croppedPathSimplified.isEmpty()) - { -#pragma omp critical + #pragma omp critical + // Put the entire polygon into the remove list toBeRemovedItems << collidingPolygonItem; } else { - foreach(const QPolygonF &pol, croppedPathSimplified.toFillPolygons()) + // Here we get the polygon of the colliding item + QPolygonF collidingPolygon = collidingPolygonItem->polygon(); + QPainterPath collidingPath; + collidingPath.addPolygon(collidingPolygon); + + // Then we substract the eraser path to the polygon and we simplify it + QPainterPath croppedPath = collidingPath.subtracted(eraserPath); + QPainterPath croppedPathSimplified = croppedPath.simplified(); + + if (croppedPath == collidingPath) { - UBGraphicsPolygonItem* croppedPolygonItem = collidingPolygonItem->deepCopy(pol); -#pragma omp critical - toBeAddedItems << croppedPolygonItem; + // NOOP + } + else if (croppedPathSimplified.isEmpty()) + { + #pragma omp critical + // Put the entire polygon into the remove list if the eraser removes all its visible content + toBeRemovedItems << collidingPolygonItem; + } + else + { + // Then we convert the remaining path to a list of polygons that will be converted in + // UBGraphicsPolygonItems and added to the scene + foreach(const QPolygonF &pol, croppedPathSimplified.toFillPolygons()) + { + UBGraphicsPolygonItem* croppedPolygonItem = collidingPolygonItem->deepCopy(pol); + #pragma omp critical + // Add this new polygon to the 'added' list + toBeAddedItems << croppedPolygonItem; + if(NULL != pGroup){ + croppedPolygonItem->setStrokesGroup(pGroup); + } + } + #pragma omp critical + // Remove the original polygonitem because it has been replaced by many smaller polygons + toBeRemovedItems << collidingPolygonItem; } -#pragma omp critical - toBeRemovedItems << collidingPolygonItem; } } } } - } - else - { - for (int i = 0; i < collidItemsSize; i++) + else { - UBGraphicsPolygonItem *collidingPolygonItem - = qgraphicsitem_cast (collidItems.at(i)); - - if (collidingPolygonItem) + for (int i = 0; i < collidItemsSize; i++) { - if(eraserInnerRect.contains(collidingPolygonItem->boundingRect())) - { - toBeRemovedItems << collidingPolygonItem; - } - else - { - QPolygonF collidingPolygon = collidingPolygonItem->polygon(); - QPainterPath collidingPath; - collidingPath.addPolygon(collidingPolygon); + UBGraphicsPolygonItem *collidingPolygonItem + = qgraphicsitem_cast (collidItems.at(i)); - QPainterPath croppedPath = collidingPath.subtracted(eraserPath); - QPainterPath croppedPathSimplified = croppedPath.simplified(); - - if (croppedPath == collidingPath) - { - // NOOP - } - else if (croppedPathSimplified.isEmpty()) + if (collidingPolygonItem) + { + if(eraserInnerRect.contains(collidingPolygonItem->boundingRect())) { toBeRemovedItems << collidingPolygonItem; } else { - foreach(const QPolygonF &pol, croppedPathSimplified.toFillPolygons()) + QPolygonF collidingPolygon = collidingPolygonItem->polygon(); + QPainterPath collidingPath; + collidingPath.addPolygon(collidingPolygon); + + QPainterPath croppedPath = collidingPath.subtracted(eraserPath); + QPainterPath croppedPathSimplified = croppedPath.simplified(); + + if (croppedPath == collidingPath) { - UBGraphicsPolygonItem* croppedPolygonItem = collidingPolygonItem->deepCopy(pol); - toBeAddedItems << croppedPolygonItem; + // NOOP } + else if (croppedPathSimplified.isEmpty()) + { + toBeRemovedItems << collidingPolygonItem; + } + else + { + foreach(const QPolygonF &pol, croppedPathSimplified.toFillPolygons()) + { + UBGraphicsPolygonItem* croppedPolygonItem = collidingPolygonItem->deepCopy(pol); + toBeAddedItems << croppedPolygonItem; + } - toBeRemovedItems << collidingPolygonItem; + toBeRemovedItems << collidingPolygonItem; + } } } } } - } - addItems(toBeAddedItems); - mAddedItems += toBeAddedItems; + addItems(toBeAddedItems); + mAddedItems += toBeAddedItems; - removeItems(toBeRemovedItems); - mRemovedItems += toBeRemovedItems; + if(eDrawingMode_Vector == DRAWING_MODE){ + foreach(QGraphicsItem* item, toBeAddedItems){ + UBGraphicsPolygonItem* poly = dynamic_cast(item); + if(NULL != poly && NULL != poly->strokesGroup()){ + poly->strokesGroup()->addToGroup(poly); + } + } + } + + removeItems(toBeRemovedItems); + mRemovedItems += toBeRemovedItems; + + if(eDrawingMode_Vector == DRAWING_MODE){ + foreach(QGraphicsItem* item, toBeRemovedItems){ + UBGraphicsPolygonItem* poly = dynamic_cast(item); + if(NULL != poly && NULL != poly->strokesGroup()){ + poly->strokesGroup()->removeFromGroup(poly); + } + } + } + } mPreviousPoint = pEndPoint; } diff --git a/src/domain/UBGraphicsStrokesGroup.h b/src/domain/UBGraphicsStrokesGroup.h index 7eecd900..0d117c3a 100644 --- a/src/domain/UBGraphicsStrokesGroup.h +++ b/src/domain/UBGraphicsStrokesGroup.h @@ -16,6 +16,11 @@ public: virtual UBItem* deepCopy() const; virtual void remove(); virtual UBGraphicsItemDelegate* Delegate() const {return mDelegate;} + enum { Type = UBGraphicsItemType::StrokeItemType }; + virtual int type() const + { + return Type; + } protected: virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); diff --git a/src/frameworks/UBGeometryUtils.cpp b/src/frameworks/UBGeometryUtils.cpp index 68c6f1b5..22bfda50 100644 --- a/src/frameworks/UBGeometryUtils.cpp +++ b/src/frameworks/UBGeometryUtils.cpp @@ -198,8 +198,9 @@ QRectF UBGeometryUtils::lineToInnerRect(const QLineF& pLine, const qreal& pWidth qreal centerX = (pLine.x1() + pLine.x2()) / 2; qreal centerY = (pLine.y1() + pLine.y2()) / 2; + // Please put a fucking comment here qreal side = sqrt((pWidth * pWidth) / 2); - qreal halfSide = side / 2; + qreal halfSide = side / 2; return QRectF(centerX - halfSide, centerY - halfSide, side, side); }