diff --git a/src/tools/UBGraphicsAristo.cpp b/src/tools/UBGraphicsAristo.cpp index fd91350e..b64197a5 100644 --- a/src/tools/UBGraphicsAristo.cpp +++ b/src/tools/UBGraphicsAristo.cpp @@ -13,37 +13,42 @@ * along with this program. If not, see . */ -#include -#include - -#include "tools/UBGraphicsAristo.h" -#include "core/UBApplication.h" +#include "UBGraphicsAristo.h" #include "board/UBBoardController.h" #include "board/UBDrawingController.h" +#include "core/UBApplication.h" #include "domain/UBGraphicsScene.h" +#include +#include +#include +#include +#include +#include +#include +#include + #include "core/memcheck.h" -const QRect UBGraphicsAristo::sDefaultRect = QRect(0, 0, 800, 400); -const UBGraphicsAristo::UBGraphicsAristoOrientation UBGraphicsAristo::sDefaultOrientation = UBGraphicsAristo::Bottom; +const QRectF UBGraphicsAristo::sDefaultRect = QRectF(0, 0, 800, 500); +const UBGraphicsAristo::Orientation UBGraphicsAristo::sDefaultOrientation = UBGraphicsAristo::Bottom; UBGraphicsAristo::UBGraphicsAristo() : UBAbstractDrawRuler() - , QGraphicsPolygonItem() - , angle(0) + , QGraphicsPathItem() + , mMarking(false) , mResizing(false) , mRotating(false) - , mMarking(false) - , mSpan(180) - , mStartAngle(0) + , mOrientation(Undefined) + , mAngle(0) , mCurrentAngle(0) - - + , mStartAngle(0) + , mSpan(180) + , mHFlipSvgItem(0) + , mMarkerSvgItem(0) + , mResizeSvgItem(0) + , mRotateSvgItem(0) { - setRect(sDefaultRect, sDefaultOrientation); - - create(*this); - mHFlipSvgItem = new QGraphicsSvgItem(":/images/vflipTool.svg", this); mHFlipSvgItem->setVisible(false); mHFlipSvgItem->setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Control)); @@ -59,163 +64,163 @@ UBGraphicsAristo::UBGraphicsAristo() mMarkerSvgItem = new QGraphicsSvgItem(":/images/angleMarker.svg", this); mMarkerSvgItem->setVisible(false); mMarkerSvgItem->setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Tool)); -} - -UBGraphicsAristo::~UBGraphicsAristo() -{ -} - -UBItem* UBGraphicsAristo::deepCopy(void) const -{ - UBGraphicsAristo* copy = new UBGraphicsAristo(); - copyItemParameters(copy); - return copy; -} + mMarkerSvgItem->setVisible(true); -void UBGraphicsAristo::copyItemParameters(UBItem *copy) const -{ - UBGraphicsAristo* cp = dynamic_cast(copy); - if (cp) - { - /* TODO: copy all members */ - cp->setPos(this->pos()); - cp->setPolygon(this->polygon()); - cp->setTransform(this->transform()); - } + create(*this); + setBoundingRect(sDefaultRect); + setOrientation(sDefaultOrientation); } -void UBGraphicsAristo::setRect(qreal x, qreal y, qreal w, qreal h, UBGraphicsAristoOrientation orientation) +UBGraphicsAristo::~UBGraphicsAristo() { - QPolygonF polygon; - polygon << QPointF(x, y) << QPoint(x, y + h) << QPoint(x+w, y + h); - setPolygon(polygon); - - setOrientation(orientation); + /* NOOP */ } -void UBGraphicsAristo::setOrientation(UBGraphicsAristoOrientation orientation) +/* + * setOrientation() modify the tool orientation. + * makeGeometryChange() is called so points are recomputed, control items are positionnated and shape is determined according to this modification. + */ +void UBGraphicsAristo::setOrientation(Orientation orientation) { mOrientation = orientation; - calculatePoints(rect()); - - QPolygonF polygon; - polygon << A << B << C; - setPolygon(polygon); -} - -UBGraphicsScene* UBGraphicsAristo::scene() const -{ - return static_cast(QGraphicsPolygonItem::scene()); + makeGeometryChange(); } /* calculatePoints() is used to calculate polygon's apexes coordinates. * This function handles orientation changes too. */ -void UBGraphicsAristo::calculatePoints(const QRectF& r) +void UBGraphicsAristo::calculatePoints() { - switch(mOrientation) - { + switch (mOrientation) { case Bottom: - A.setX(r.left()); A.setY(r.top()); - B.setX(r.right()); B.setY(r.top()); - C.setX(r.center().x()); C.setY(A.y() + r.width() / 2); + C.setX(boundingRect().center().x()); + C.setY(boundingRect().bottom()); + + A.setX(boundingRect().left()); + A.setY(boundingRect().bottom() - boundingRect().width() / 2); + + B.setX(boundingRect().right()); + B.setY(boundingRect().bottom() - boundingRect().width() / 2); break; case Top: - A.setX(r.left()); A.setY(r.bottom()); - B.setX(r.right()); B.setY(r.bottom()); - C.setX(r.center().x()); C.setY(A.y() - r.width() / 2); + C.setX(boundingRect().center().x()); + C.setY(boundingRect().top()); + + A.setX(boundingRect().left()); + A.setY(boundingRect().top() + boundingRect().width() / 2); + + B.setX(boundingRect().right()); + B.setY(boundingRect().top() + boundingRect().width() / 2); + break; + default: break; } } -void UBGraphicsAristo::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) +/* + * setItemsPos() places control items according to A, B and C positions. + * Call this function after A, B or C position modification, mostly after calling calculatePoints(). + * These positions has to be set when calling setPath() to allow hover events on items which are not into the main polygon. + */ +void UBGraphicsAristo::setItemsPos() { - QPolygonF polygon; + mCloseSvgItem->setPos(closeButtonRect().topLeft() + rotationCenter()); + mHFlipSvgItem->setPos(hFlipRect().topLeft() + rotationCenter()); + mRotateSvgItem->setPos(rotateRect().topLeft() + rotationCenter()); + mResizeSvgItem->setPos(resizeButtonRect().topLeft() + rotationCenter()); + mMarkerSvgItem->setPos(markerButtonRect().topLeft() + rotationCenter()); +} - painter->setBrush(fillBrush()); - painter->setPen(drawColor()); +/* + * determinePath() modify the shape according to apexes coordinates and control item positions. + * This is useful when orientation is modified. + * Returns the painter path corresponding to object parameters. + */ +QPainterPath UBGraphicsAristo::determinePath() +{ + QPainterPath path; + QPolygonF polygon; polygon << A << B << C; - painter->drawPolygon(polygon); - polygon.clear(); + path.addPolygon(polygon); - paintGraduations(painter); + path.addPath(mResizeSvgItem->shape().translated(mResizeSvgItem->pos())); + path.addPath(mMarkerSvgItem->shape().translated(mMarkerSvgItem->pos())); - mCloseSvgItem->setPos(closeButtonRect().topLeft() + rotationCenter()); - mHFlipSvgItem->setPos(hFlipRect().topLeft() + rotationCenter()); - mRotateSvgItem->setPos(rotateRect().topLeft() + rotationCenter()); - mResizeSvgItem->setPos(resizeButtonRect().topLeft() + rotationCenter()); + return path; +} +/* + * setBoundingRect() is a helper to set the given rectangle as the new shape to limit apexes coordinates. + * This is useful when instanciating or resizing the object. + * makeGeometryChange() is called so points are recomputed, control items are positionnated and shape is determined according to this modification. + * Setting bounds' width less than 300 is not allowed. + */ +void UBGraphicsAristo::setBoundingRect(QRectF boundingRect) +{ + if (boundingRect.width() < 300) + return; - paintMarker(painter); - mMarkerSvgItem->setVisible(true); + QPainterPath path; + path.addRect(boundingRect); + setPath(path); + if (mOrientation != Undefined) + makeGeometryChange(); } -QPainterPath UBGraphicsAristo::shape() const +void UBGraphicsAristo::makeGeometryChange() { - QPainterPath tShape; - QPolygonF tPolygon; + calculatePoints(); + setItemsPos(); + setPath(determinePath()); +} - tPolygon << A << B << C; - tShape.addPolygon(tPolygon); - tPolygon.clear(); - return tShape; +UBItem* UBGraphicsAristo::deepCopy(void) const +{ + UBGraphicsAristo* copy = new UBGraphicsAristo(); + copyItemParameters(copy); + return copy; } -/* paintMarker() adjust marker button according to the current angle, draw the line allowing user to set precisely the angle, and draw the current angle's value. */ -void UBGraphicsAristo::paintMarker(QPainter *painter) +void UBGraphicsAristo::copyItemParameters(UBItem *copy) const { - /* adjusting marker button */ - mMarkerSvgItem->setPos(markerButtonRect().topLeft() + rotationCenter()); - mMarkerSvgItem->resetTransform(); - mMarkerSvgItem->translate(-markerButtonRect().left(), -markerButtonRect().top()); - mMarkerSvgItem->rotate(mCurrentAngle); - mMarkerSvgItem->translate(markerButtonRect().left(), markerButtonRect().top()); - - - qreal co = cos((mCurrentAngle) * PI/180); - qreal si = sin((mCurrentAngle) * PI/180); - - /* Setting point composing the line (from point C) which intersects the line we want to draw. */ - QPointF referencePoint; - if (mOrientation == Bottom) { - if ((int)mCurrentAngle % 360 < 90) - referencePoint = B; - else - referencePoint = A; - } - else if (mOrientation == Top) { - if ((int)mCurrentAngle % 360 < 270 && (int)mCurrentAngle % 360 > 0) - referencePoint = A; - else - referencePoint = B; + UBGraphicsAristo* cp = dynamic_cast(copy); + if (cp) + { + /* TODO: copy all members */ + cp->setPos(this->pos()); + cp->setPath(this->path()); + cp->setTransform(this->transform()); } - - /* getting intersection point to draw the wanted line */ - QLineF intersectedLine(rotationCenter(), QPointF(rotationCenter().x()+co, rotationCenter().y()+si)); - QPointF intersectionPoint; - if (intersectedLine.intersect(QLineF(referencePoint, C), &intersectionPoint)) - painter->drawLine(QLineF(intersectionPoint, rotationCenter())); - - /* drawing angle value */ - qreal rightAngle = mOrientation == Bottom ? mCurrentAngle : 360 - mCurrentAngle; +} - QString angleText = QString("%1°").arg(rightAngle, 0, 'f', 1); +void UBGraphicsAristo::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) +{ + QPolygonF polygon; - QFont font1 = painter->font(); -#ifdef Q_WS_MAC - font1.setPointSizeF(font1.pointSizeF() - 3); -#endif - QFontMetricsF fm1(font1); + painter->setBrush(fillBrush()); + painter->setPen(drawColor()); - if (mOrientation == Bottom) - painter->drawText(rotationCenter().x() - fm1.width(angleText)/2 - radius()/8, rotationCenter().y() + radius()/8 - fm1.height()/2, fm1.width(angleText), fm1.height(), Qt::AlignCenter, angleText); - else - painter->drawText(rotationCenter().x() - fm1.width(angleText)/2 - radius()/8, rotationCenter().y() - radius()/8 - fm1.height()/2, fm1.width(angleText), fm1.height(), Qt::AlignCenter, angleText); + polygon << A << B << C; + painter->drawPolygon(polygon); + polygon.clear(); + paintGraduations(painter); + paintMarker(painter); +} +QBrush UBGraphicsAristo::fillBrush() const +{ + QColor fillColor = edgeFillColor();// scene()->isDarkBackground() ? sDarkBackgroundFillColor : sFillColor; + QColor fillColorCenter = middleFillColor();//scene()->isDarkBackground() ? sDarkBackgroundFillColorCenter : sFillColorCenter; + QColor transparentWhite = Qt::white; + transparentWhite.setAlpha(scene()->isDarkBackground() ? sDrawTransparency : sFillTransparency); + QRadialGradient radialGradient(boundingRect().center(), radius(), boundingRect().center()); + radialGradient.setColorAt(0, fillColorCenter); + radialGradient.setColorAt(1, fillColor); + return radialGradient; } /* paintGraduations() paints graduations on the ruler side (length graduations) and the two other sides (angle graduation) */ @@ -228,18 +233,18 @@ void UBGraphicsAristo::paintGraduations(QPainter *painter) void UBGraphicsAristo::paintRulerGraduations(QPainter *painter) { /* defining useful constants */ - const int centimeterGraduationHeight = 15; + const int centimeterGraduationHeight = 15; const int halfCentimeterGraduationHeight = 10; - const int millimeterGraduationHeight = 5; - const int millimetersPerCentimeter = 10; - const int millimetersPerHalfCentimeter = 5; + const int millimeterGraduationHeight = 5; + const int millimetersPerCentimeter = 10; + const int millimetersPerHalfCentimeter = 5; painter->save(); painter->setFont(font()); QFontMetricsF fontMetrics(painter->font()); /* Browsing milliters in half width of ruler side */ - for (int millimeters = 0; millimeters < (rect().width() / 2 - sLeftEdgeMargin - sRoundingRadius) / sPixelsPerMillimeter; millimeters++) + for (int millimeters = 0; millimeters < (boundingRect().width() / 2 - sLeftEdgeMargin - sRoundingRadius) / sPixelsPerMillimeter; millimeters++) { /* defining graduationHeight ; values are different to draw bigger lines if millimiter considered is a centimeter or a half centimeter */ int graduationHeight = (0 == millimeters % millimetersPerCentimeter) ? @@ -262,13 +267,13 @@ void UBGraphicsAristo::paintRulerGraduations(QPainter *painter) QString text = QString("%1").arg((int)(millimeters / millimetersPerCentimeter)); /* staying inside polygon */ - if (rotationCenter().x() + sPixelsPerMillimeter * millimeters + fontMetrics.width(text) / 2 < rect().right()) + if (rotationCenter().x() + sPixelsPerMillimeter * millimeters + fontMetrics.width(text) / 2 < boundingRect().right()) { qreal textWidth = fontMetrics.width(text); qreal textHeight = fontMetrics.tightBoundingRect(text).height() + 5; /* text y-coordinate is different according to tool's orientation */ - qreal textY = mOrientation == Bottom ? rect().top() + 5 + centimeterGraduationHeight : rect().bottom() - 5 - centimeterGraduationHeight + graduationHeight; + qreal textY = mOrientation == Bottom ? A.y() + 5 + centimeterGraduationHeight : A.y() - 5 - centimeterGraduationHeight + graduationHeight; /* if text's rect is not out of polygon's bounds, drawing value below or above graduation */ QPointF intersectionPoint; @@ -390,32 +395,73 @@ void UBGraphicsAristo::paintProtractorGraduations(QPainter* painter) painter->restore(); } -QBrush UBGraphicsAristo::fillBrush() const +/* paintMarker() adjust marker button according to the current angle, draw the line allowing user to set precisely the angle, and draw the current angle's value. */ +void UBGraphicsAristo::paintMarker(QPainter *painter) { - QColor fillColor = edgeFillColor();// scene()->isDarkBackground() ? sDarkBackgroundFillColor : sFillColor; - QColor fillColorCenter = middleFillColor();//scene()->isDarkBackground() ? sDarkBackgroundFillColorCenter : sFillColorCenter; - QColor transparentWhite = Qt::white; - transparentWhite.setAlpha(scene()->isDarkBackground() ? sDrawTransparency : sFillTransparency); - QRadialGradient radialGradient(rect().center(), radius(), rect().center()); - radialGradient.setColorAt(0, fillColorCenter); - radialGradient.setColorAt(1, fillColor); - return radialGradient; + /* adjusting marker button */ + mMarkerSvgItem->resetTransform(); + mMarkerSvgItem->translate(-markerButtonRect().left(), -markerButtonRect().top()); + mMarkerSvgItem->rotate(mCurrentAngle); + mMarkerSvgItem->translate(markerButtonRect().left(), markerButtonRect().top()); + + + qreal co = cos((mCurrentAngle) * PI/180); + qreal si = sin((mCurrentAngle) * PI/180); + + /* Setting point composing the line (from point C) which intersects the line we want to draw. */ + QPointF referencePoint; + if (mOrientation == Bottom) { + if ((int)mCurrentAngle % 360 < 90) + referencePoint = B; + else + referencePoint = A; + } + else if (mOrientation == Top) { + if ((int)mCurrentAngle % 360 < 270 && (int)mCurrentAngle % 360 > 0) + referencePoint = A; + else + referencePoint = B; + } + + /* getting intersection point to draw the wanted line */ + QLineF intersectedLine(rotationCenter(), QPointF(rotationCenter().x()+co, rotationCenter().y()+si)); + QPointF intersectionPoint; + if (intersectedLine.intersect(QLineF(referencePoint, C), &intersectionPoint)) + painter->drawLine(QLineF(intersectionPoint, rotationCenter())); + + /* drawing angle value */ + qreal rightAngle = mOrientation == Bottom ? mCurrentAngle : 360 - mCurrentAngle; + + + QString angleText = QString("%1°").arg(rightAngle, 0, 'f', 1); + + QFont font1 = painter->font(); +#ifdef Q_WS_MAC + font1.setPointSizeF(font1.pointSizeF() - 3); +#endif + QFontMetricsF fm1(font1); + + if (mOrientation == Bottom) + painter->drawText(rotationCenter().x() - fm1.width(angleText)/2 - radius()/8, rotationCenter().y() + radius()/8 - fm1.height()/2, fm1.width(angleText), fm1.height(), Qt::AlignCenter, angleText); + else + painter->drawText(rotationCenter().x() - fm1.width(angleText)/2 - radius()/8, rotationCenter().y() - radius()/8 - fm1.height()/2, fm1.width(angleText), fm1.height(), Qt::AlignCenter, angleText); } + void UBGraphicsAristo::rotateAroundCenter(qreal angle) { - qreal oldAngle = this->angle; - this->angle = angle; + qreal oldAngle = mAngle; + mAngle = angle; QTransform transform; rotateAroundCenter(transform, rotationCenter()); setTransform(transform, true); - this->angle = oldAngle + angle; // We have to store absolute value for FLIP case + mAngle = oldAngle + angle; // We have to store absolute value for FLIP case } void UBGraphicsAristo::rotateAroundCenter(QTransform& transform, QPointF center) { transform.translate(center.x(), center.y()); - transform.rotate(angle); + transform.rotate(mAngle); transform.translate(- center.x(), - center.y()); } @@ -441,11 +487,6 @@ QRectF UBGraphicsAristo::closeButtonRect() const return QRectF(- mCloseSvgItem->boundingRect().width() / 2, y, mCloseSvgItem->boundingRect().width(), mCloseSvgItem->boundingRect().height()); } -QRectF UBGraphicsAristo::resizeButtonRect() const -{ - return QRectF((B - rotationCenter()).x() - 100 - mResizeSvgItem->boundingRect().width()/2, - mResizeSvgItem->boundingRect().height()/2, mResizeSvgItem->boundingRect().width(), mResizeSvgItem->boundingRect().height()); -} - QRectF UBGraphicsAristo::hFlipRect() const { qreal y = radius() / 4; @@ -455,6 +496,16 @@ QRectF UBGraphicsAristo::hFlipRect() const return QRectF(- mHFlipSvgItem->boundingRect().width() / 2, y, mHFlipSvgItem->boundingRect().width(), mHFlipSvgItem->boundingRect().height()); } +QRectF UBGraphicsAristo::markerButtonRect() const +{ + return QRectF (radius()/2 - mMarkerSvgItem->boundingRect().width(), - mMarkerSvgItem->boundingRect().height()/2, mMarkerSvgItem->boundingRect().width(), mMarkerSvgItem->boundingRect().height()); +} + +QRectF UBGraphicsAristo::resizeButtonRect() const +{ + return QRectF((B - rotationCenter()).x() - 100 - mResizeSvgItem->boundingRect().width()/2, - mResizeSvgItem->boundingRect().height()/2, mResizeSvgItem->boundingRect().width(), mResizeSvgItem->boundingRect().height()); +} + QRectF UBGraphicsAristo::rotateRect() const { qreal y = radius() / 4 + hFlipRect().height() + 3; @@ -464,26 +515,22 @@ QRectF UBGraphicsAristo::rotateRect() const } -QRectF UBGraphicsAristo::markerButtonRect() const -{ - return QRectF (radius()/2 - mMarkerSvgItem->boundingRect().width(), - mMarkerSvgItem->boundingRect().height()/2, mMarkerSvgItem->boundingRect().width(), mMarkerSvgItem->boundingRect().height()); -} - QCursor UBGraphicsAristo::flipCursor() const { return Qt::ArrowCursor; } -QCursor UBGraphicsAristo::resizeCursor() const +QCursor UBGraphicsAristo::markerCursor() const { return Qt::ArrowCursor; } -QCursor UBGraphicsAristo::markerCursor() const +QCursor UBGraphicsAristo::resizeCursor() const { return Qt::ArrowCursor; } + void UBGraphicsAristo::mousePressEvent(QGraphicsSceneMouseEvent *event) { switch (toolFromPos(event->pos())) { @@ -530,7 +577,7 @@ void UBGraphicsAristo::mouseMoveEvent(QGraphicsSceneMouseEvent *event) } else if (mResizing) { QPointF delta = event->pos() - event->lastPos(); - setRect(QRectF(rect().topLeft(), QSizeF(rect().width() + delta.x(), rect().height() + delta.x() / 2)), mOrientation); + setBoundingRect(QRectF(boundingRect().topLeft(), QSizeF(boundingRect().width() + delta.x(), boundingRect().height() + delta.x()))); } else if(mMarking) { qreal angle = currentLine.angleTo(lastLine); @@ -584,6 +631,8 @@ void UBGraphicsAristo::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) case Top: setOrientation(Bottom); break; + default: + break; } default: QGraphicsItem::mouseReleaseEvent(event); @@ -700,7 +749,7 @@ UBGraphicsAristo::Tool UBGraphicsAristo::toolFromPos(QPointF pos) { pos = pos - rotationCenter(); - qreal rotationAngle = mOrientation == Bottom ? - mCurrentAngle : 360 * (int)(mCurrentAngle / 360 + 1) - mCurrentAngle; + qreal rotationAngle = mOrientation == Bottom ? - mCurrentAngle : Top ? 360 * (int)(mCurrentAngle / 360 + 1) - mCurrentAngle : 0; QTransform t; t.rotate(rotationAngle); @@ -722,6 +771,7 @@ UBGraphicsAristo::Tool UBGraphicsAristo::toolFromPos(QPointF pos) return None; } + void UBGraphicsAristo::StartLine(const QPointF &scenePos, qreal width) { QPointF itemPos = mapFromScene(scenePos); @@ -730,10 +780,10 @@ void UBGraphicsAristo::StartLine(const QPointF &scenePos, qreal width) y = rotationCenter().y(); - if (itemPos.x() < rect().x() + sLeftEdgeMargin) - itemPos.setX(rect().x() + sLeftEdgeMargin); - if (itemPos.x() > rect().x() + rect().width() - sLeftEdgeMargin) - itemPos.setX(rect().x() + rect().width() - sLeftEdgeMargin); + if (itemPos.x() < boundingRect().x() + sLeftEdgeMargin) + itemPos.setX(boundingRect().x() + sLeftEdgeMargin); + if (itemPos.x() > boundingRect().x() + boundingRect().width() - sLeftEdgeMargin) + itemPos.setX(boundingRect().x() + boundingRect().width() - sLeftEdgeMargin); itemPos.setY(y); itemPos = mapToScene(itemPos); @@ -750,10 +800,10 @@ void UBGraphicsAristo::DrawLine(const QPointF &scenePos, qreal width) y = rotationCenter().y(); - if (itemPos.x() < rect().x() + sLeftEdgeMargin) - itemPos.setX(rect().x() + sLeftEdgeMargin); - if (itemPos.x() > rect().x() + rect().width() - sLeftEdgeMargin) - itemPos.setX(rect().x() + rect().width() - sLeftEdgeMargin); + if (itemPos.x() < boundingRect().x() + sLeftEdgeMargin) + itemPos.setX(boundingRect().x() + sLeftEdgeMargin); + if (itemPos.x() > boundingRect().x() + boundingRect().width() - sLeftEdgeMargin) + itemPos.setX(boundingRect().x() + boundingRect().width() - sLeftEdgeMargin); itemPos.setY(y); itemPos = mapToScene(itemPos); @@ -765,4 +815,11 @@ void UBGraphicsAristo::DrawLine(const QPointF &scenePos, qreal width) void UBGraphicsAristo::EndLine() { + /* NOOP */ +} + + +UBGraphicsScene* UBGraphicsAristo::scene() const +{ + return static_cast(QGraphicsPathItem::scene()); } diff --git a/src/tools/UBGraphicsAristo.h b/src/tools/UBGraphicsAristo.h index 2dbfc53f..5f92d28f 100644 --- a/src/tools/UBGraphicsAristo.h +++ b/src/tools/UBGraphicsAristo.h @@ -16,150 +16,138 @@ #ifndef UBGRAPHICSARISTO_H_ #define UBGRAPHICSARISTO_H_ -#include -#include -#include - #include "core/UB.h" #include "domain/UBItem.h" #include "tools/UBAbstractDrawRuler.h" - -class UBGraphicsScene; -class UBItem; - -class UBGraphicsAristo : public UBAbstractDrawRuler, public QGraphicsPolygonItem, public UBItem +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class UBGraphicsAristo : public UBAbstractDrawRuler, public QGraphicsPathItem, public UBItem { - Q_OBJECT - - public: - UBGraphicsAristo(); - virtual ~UBGraphicsAristo(); - - enum { Type = UBGraphicsItemType::AristoItemType }; - enum Tool {None, Move, Resize, Rotate, Close, MoveMarker, HorizontalFlip}; - - virtual int type() const - { - return Type; - } - - virtual UBItem* deepCopy(void) const; - virtual void copyItemParameters(UBItem *copy) const; - - virtual void StartLine(const QPointF& scenePos, qreal width); - virtual void DrawLine(const QPointF& position, qreal width); - virtual void EndLine(); - - enum UBGraphicsAristoOrientation - { - Bottom = 0, - Top - }; - - static UBGraphicsAristoOrientation orientationFromStr(QStringRef& str) - { - if (str == "Bottom") return Bottom; - if (str == "Top") return Top; - return sDefaultOrientation; - } - static QString orientationToStr(UBGraphicsAristoOrientation orientation) - { - QString result; - if (orientation == 0) result = "Bottom"; - else if (orientation == 1) result = "Top"; - - return result; - } - - void setRect(const QRectF &rect, UBGraphicsAristoOrientation orientation) - { - setRect(rect.x(), rect.y(), rect.width(), rect.height(), orientation); - } - - void setRect(qreal x, qreal y, qreal w, qreal h, UBGraphicsAristoOrientation orientation); - - void setOrientation(UBGraphicsAristoOrientation orientation); - - UBGraphicsAristoOrientation getOrientation() const {return mOrientation;} - - QRectF rect() const {return boundingRect();} - - UBGraphicsScene* scene() const; - - protected: - - virtual void paint (QPainter *painter, const QStyleOptionGraphicsItem *styleOption, QWidget *widget); - virtual QPainterPath shape() const; - - virtual void rotateAroundCenter(qreal angle); - virtual void resize(qreal factor); - - virtual QPointF rotationCenter() const; - - virtual QRectF closeButtonRect() const; - QRectF resizeButtonRect () const; - QRectF hFlipRect() const; - QRectF rotateRect() const; - QRectF markerButtonRect() const; - - QCursor flipCursor() const; - QCursor resizeCursor() const; - QCursor markerCursor() const; - - virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); - virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); - virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); - virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event); - virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); - virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event); - - private: - UBGraphicsAristo::Tool toolFromPos(QPointF pos); - QTransform calculateRotationTransform(); - qreal angle; - - void rotateAroundCenter(QTransform& transform, QPointF center); - - bool mResizing; - bool mRotating; - bool mMarking; - QRect lastRect; - qreal mSpan; - - // Coordinates are transformed.... - QPoint lastPos; - QGraphicsSvgItem* mHFlipSvgItem; - QGraphicsSvgItem* mRotateSvgItem; - QGraphicsSvgItem* mResizeSvgItem; - QGraphicsSvgItem* mMarkerSvgItem; - qreal mStartAngle; - qreal mCurrentAngle; - - static const QRect sDefaultRect; - static const UBGraphicsAristoOrientation sDefaultOrientation; - - void paintGraduations(QPainter *painter); - void paintRulerGraduations(QPainter *painter); - void paintProtractorGraduations(QPainter* painter); - void paintMarker(QPainter *painter); - inline qreal radius () const - { - return sqrt(((B.x() - A.x())*(B.x() - A.x()))+((B.y() - A.y())*(B.y() - A.y()))) * 9 / 16 - 20; - } - QBrush fillBrush() const; - - UBGraphicsAristoOrientation mOrientation; - - void calculatePoints(const QRectF& rect); - - QPointF A, B, C; - - static const int d = 70; // width of triangle border - static const int sArrowLength = 30; - static const int sMinWidth = 380; - static const int sMinHeight = 200; - static const int sArcAngleMargin = 5; +Q_OBJECT + +public: + UBGraphicsAristo(); + virtual ~UBGraphicsAristo(); + + enum { + Type = UBGraphicsItemType::AristoItemType + }; + + enum Tool { + None, + Move, + Resize, + Rotate, + Close, + MoveMarker, + HorizontalFlip + }; + + enum Orientation + { + Bottom = 0, + Top, + Undefined + }; + + void setOrientation(Orientation orientation); + void setBoundingRect(QRectF boundingRect); + + virtual UBItem* deepCopy() const; + virtual void copyItemParameters(UBItem *copy) const; + + virtual void StartLine(const QPointF& scenePos, qreal width); + virtual void DrawLine(const QPointF& position, qreal width); + virtual void EndLine(); + + virtual int type() const + { + return Type; + } + UBGraphicsScene* scene() const; + +protected: + virtual void paint (QPainter *painter, const QStyleOptionGraphicsItem *styleOption, QWidget *widget); + + virtual void rotateAroundCenter(qreal angle); + virtual void resize(qreal factor); + + virtual QPointF rotationCenter() const; + + virtual QRectF closeButtonRect() const; + QRectF hFlipRect() const; + QRectF markerButtonRect() const; + QRectF resizeButtonRect () const; + QRectF rotateRect() const; + + QCursor flipCursor() const; + QCursor markerCursor() const; + QCursor resizeCursor() const; + + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event); + virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); + virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event); + +private: + Tool toolFromPos(QPointF pos); + + QTransform calculateRotationTransform(); + void rotateAroundCenter(QTransform& transform, QPointF center); + + void calculatePoints(); + QPainterPath determinePath(); + void setItemsPos(); + void makeGeometryChange(); + + QBrush fillBrush() const; + void paintGraduations(QPainter *painter); + void paintMarker(QPainter *painter); + void paintProtractorGraduations(QPainter* painter); + void paintRulerGraduations(QPainter *painter); + + inline qreal radius () const + { + return sqrt(((B.x() - A.x())*(B.x() - A.x()))+((B.y() - A.y())*(B.y() - A.y()))) * 9 / 16 - 20; + } + + bool mMarking; + bool mResizing; + bool mRotating; + + Orientation mOrientation; + + qreal mAngle; + qreal mCurrentAngle; + qreal mStartAngle; + + qreal mSpan; + + QGraphicsSvgItem* mHFlipSvgItem; + QGraphicsSvgItem* mMarkerSvgItem; + QGraphicsSvgItem* mResizeSvgItem; + QGraphicsSvgItem* mRotateSvgItem; + + QPointF A, B, C; + + static const int sArcAngleMargin = 5; + static const Orientation sDefaultOrientation; + static const QRectF sDefaultRect; }; #endif /* UBGRAPHICSARISTO_H_ */