QPainterPath UBGraphicsProtractor::shape() const
{
    QPainterPath path = QGraphicsEllipseItem::shape();
    QPainterPath buttonPath;
    QRectF markerRect = markerButtonRect();

    QPointF center = rect().center();
    qreal centerX = center.x();
    qreal centerY = center.y();

    buttonPath.addRect(resizeButtonRect().adjusted(centerX, centerY, centerX, centerY));
    if (!resizeButtonRect().contains(markerRect))
    {
        buttonPath.addRect(markerRect.adjusted(centerX - markerRect.left() * 2 - markerRect.width(), centerY
                                               , centerX - markerRect.left() * 2 - markerRect.width(), centerY));
        buttonPath.addRect(markerRect.adjusted(centerX, centerY, centerX, centerY));
    }
    buttonPath.addRect(closeButtonRect().adjusted(centerX, centerY, centerX, centerY));
    buttonPath.addRect(resetButtonRect().adjusted(centerX, centerY, centerX, centerY));
    QTransform t;
    t.translate(centerX, centerY);
    t.rotate(-mStartAngle);
    t.translate(-centerX, -centerY);
    buttonPath = t.map(buttonPath);
    buttonPath = buttonPath.subtracted(path);
    path.addPath(buttonPath);

    return path;
}
void UBGraphicsCompass::paint(QPainter *painter, const QStyleOptionGraphicsItem *styleOption, QWidget *widget)
{
    Q_UNUSED(styleOption);
    Q_UNUSED(widget);

    mAntiScaleRatio = 1 / (UBApplication::boardController->systemScaleFactor() * UBApplication::boardController->currentZoom());
    QTransform antiScaleTransform;
    antiScaleTransform.scale(mAntiScaleRatio, mAntiScaleRatio);

    mCloseSvgItem->setTransform(antiScaleTransform);
    mCloseSvgItem->setPos(
        closeButtonRect().center().x() - mCloseSvgItem->boundingRect().width() * mAntiScaleRatio / 2,
        closeButtonRect().center().y() - mCloseSvgItem->boundingRect().height() * mAntiScaleRatio / 2);

    mResizeSvgItem->setTransform(antiScaleTransform);
    mResizeSvgItem->setPos(
        resizeButtonRect().center().x() - mResizeSvgItem->boundingRect().width() * mAntiScaleRatio / 2,
        resizeButtonRect().center().y() - mResizeSvgItem->boundingRect().height() * mAntiScaleRatio / 2);

    painter->setPen(drawColor());
    painter->drawRoundedRect(hingeRect(), 4, 4);
    painter->fillPath(hingeShape(), middleFillColor());

    painter->fillPath(needleShape(), middleFillColor());
    painter->drawPath(needleShape());
    painter->fillPath(needleBaseShape(), middleFillColor());
    painter->drawPath(needleBaseShape());

    QLinearGradient needleArmLinearGradient(
        QPointF(rect().left() + sNeedleLength + sNeedleBaseLength, rect().center().y()),
        QPointF(hingeRect().left(), rect().center().y()));
    needleArmLinearGradient.setColorAt(0, edgeFillColor());
    needleArmLinearGradient.setColorAt(1, middleFillColor());
    painter->fillPath(needleArmShape(), needleArmLinearGradient);
    painter->drawPath(needleArmShape());

    QRectF hingeGripRect(rect().center().x() - 16, rect().center().y() - 16, 32, 32);
    painter->drawEllipse(hingeGripRect);
    if (mShowButtons)
        paintAngleDisplay(painter);

    QLinearGradient pencilArmLinearGradient(
        QPointF(hingeRect().right(), rect().center().y()),
        QPointF(rect().right() - sPencilLength - sPencilBaseLength, rect().center().y()));
    pencilArmLinearGradient.setColorAt(0, middleFillColor());
    pencilArmLinearGradient.setColorAt(1, edgeFillColor());
    painter->fillPath(pencilArmShape(), pencilArmLinearGradient);
    painter->drawPath(pencilArmShape());

    if (scene()->isDarkBackground())
        painter->fillPath(pencilShape(), UBApplication::boardController->penColorOnDarkBackground());
    else
        painter->fillPath(pencilShape(), UBApplication::boardController->penColorOnLightBackground());

    painter->fillPath(pencilBaseShape(), middleFillColor());
    painter->drawPath(pencilBaseShape());

    if (mResizing || mRotating || mDrawing || (mShowButtons && rect().width() > sDisplayRadiusOnPencilArmMinLength))
        paintRadiusDisplay(painter);
}
void UBGraphicsProtractor::paintButtons(QPainter *painter)
{
    Q_UNUSED(painter);

    if (mShowButtons)
    {
        qreal antiSc = antiScale();

        qreal scale = buttonSizeReference().width() / mCloseSvgItem->boundingRect().width();
        mCloseSvgItem->setPos(closeButtonRect().topLeft() + rect().center());
        mCloseSvgItem->resetTransform();
        mCloseSvgItem->translate(-closeButtonRect().left(),-closeButtonRect().top());
        mCloseSvgItem->rotate(-mStartAngle);
        mCloseSvgItem->translate(closeButtonRect().left(), closeButtonRect().top());
        mCloseSvgItem->scale(scale * antiSc, scale * antiSc);//this do not impact the bounding box of thr svg item...

        mResetSvgItem->setPos(resetButtonRect().topLeft() + rect().center());
        mResetSvgItem->resetTransform();
        mResetSvgItem->translate(-resetButtonRect().left(), -resetButtonRect().top());
        mResetSvgItem->rotate(-mStartAngle);
        mResetSvgItem->translate(resetButtonRect().left(), resetButtonRect().top());
        mResetSvgItem->scale(scale * antiSc, scale * antiSc);//this do not impact the bounding box of thr svg item...

        mResizeSvgItem->setPos(resizeButtonRect().topLeft() + rect().center());
        mResizeSvgItem->resetTransform();
        mResizeSvgItem->translate(-resizeButtonRect().left(), -resizeButtonRect().top());
        mResizeSvgItem->rotate(-mStartAngle);
        mResizeSvgItem->translate(resizeButtonRect().left(), resizeButtonRect().top());
        mResizeSvgItem->scale(scale * antiSc, scale * antiSc);//this do not impact the bounding box of thr svg item...

        mRotateSvgItem->setPos(rotateButtonRect().topLeft() + rect().center());
        mRotateSvgItem->resetTransform();
        mRotateSvgItem->translate(-rotateButtonRect().left(), -rotateButtonRect().top());
        mRotateSvgItem->rotate(-mStartAngle);
        mRotateSvgItem->translate(rotateButtonRect().left(), rotateButtonRect().top());
        mRotateSvgItem->scale(scale, scale);//this do not impact the bounding box of thr svg item...
    }

    qreal scale = markerSizeReference().width()/mMarkerSvgItem->boundingRect().width();
    mMarkerSvgItem->setPos(markerButtonRect().topLeft() + rect().center());
    mMarkerSvgItem->resetTransform();
    mMarkerSvgItem->translate(-markerButtonRect().left(), -markerButtonRect().top());
    mMarkerSvgItem->rotate(- mStartAngle - mCurrentAngle);
    mMarkerSvgItem->translate(markerButtonRect().left(), markerButtonRect().top());
    mMarkerSvgItem->scale(scale, scale);//this do not impact the bounding box of thr svg item...

    mCloseSvgItem->setVisible(mShowButtons);
    mResetSvgItem->setVisible(mShowButtons);
    mResizeSvgItem->setVisible(mShowButtons);
    mRotateSvgItem->setVisible(mShowButtons);
    mMarkerSvgItem->setVisible(true);

}
void UBGraphicsRuler::paint(QPainter *painter, const QStyleOptionGraphicsItem *styleOption, QWidget *widget)
{
    Q_UNUSED(styleOption);
    Q_UNUSED(widget);

	UBAbstractDrawRuler::paint();

	QTransform antiScaleTransform2;
    qreal ratio = mAntiScaleRatio > 1.0 ? mAntiScaleRatio : 1.0;
    antiScaleTransform2.scale(ratio, 1.0);

    mResizeSvgItem->setTransform(antiScaleTransform2);
    mResizeSvgItem->setPos(resizeButtonRect().topLeft());

    mRotateSvgItem->setTransform(antiScaleTransform2);
    mRotateSvgItem->setPos(rotateButtonRect().topLeft());



    painter->setPen(drawColor());
    painter->setRenderHint(QPainter::Antialiasing, true);
    painter->drawRoundedRect(rect(), sRoundingRadius, sRoundingRadius);
    fillBackground(painter);
    paintGraduations(painter);
    if (mRotating)
        paintRotationCenter(painter);
}
void UBGraphicsRuler::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
	UBStylusTool::Enum currentTool = (UBStylusTool::Enum)UBDrawingController::drawingController ()->stylusTool ();

	if (currentTool == UBStylusTool::Selector)
	{
		mCloseSvgItem->setVisible(mShowButtons);
		mResizeSvgItem->setVisible(mShowButtons);
		mRotateSvgItem->setVisible(mShowButtons);
		if (resizeButtonRect().contains(event->pos()))
			setCursor(resizeCursor());
		else if (closeButtonRect().contains(event->pos()))
			setCursor(closeCursor());
		else if (rotateButtonRect().contains(event->pos()))
			setCursor(rotateCursor());
		else
			setCursor(moveCursor());

		event->accept();
	}
	else if (UBDrawingController::drawingController()->isDrawingTool())
	{
		event->accept();
	}
}
UBGraphicsProtractor::Tool UBGraphicsProtractor::toolFromPos(QPointF pos)
{
    pos = pos - rect().center();
    QLineF line(QPointF(0,0), pos);
    QTransform t;
    t.rotate(mStartAngle);
    QPointF p1 = t.map(pos);
    t.rotate(mCurrentAngle);
    QPointF p2 = t.map(pos);

    if (resizeButtonRect().contains(p1))
        return Resize;
    else if (closeButtonRect().contains(p1))
        return Close;
    else if (resetButtonRect().contains(p1))
        return Reset;
    else if (rotateButtonRect().contains(p1))
        return Rotate;
    else if (markerButtonRect().contains(p2))
        return MoveMarker;
    else if (line.length() <= radius())
        return Move;
    else
        return None;
}
void UBGraphicsCompass::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
    if (UBDrawingController::drawingController ()->stylusTool() != UBStylusTool::Selector &&
        UBDrawingController::drawingController ()->stylusTool() != UBStylusTool::Play)
        return;

    mShowButtons = shape().contains(event->pos());
    mCloseSvgItem->setVisible(mShowButtons);
    mResizeSvgItem->setVisible(mShowButtons);
    if (mShowButtons)
    {
        if (hingeRect().contains(event->pos()))
            setCursor(rotateCursor());
        else if (event->pos().x() > rect().right() - sPencilLength - sPencilBaseLength)
            setCursor(drawCursor());
        else if (resizeButtonRect().contains(event->pos()))
            setCursor(resizeCursor());
        else if (closeButtonRect().contains(event->pos()))
            setCursor(closeCursor());
        else
            setCursor(moveCursor());
    }
    else
    {
        setCursor(mOuterCursor);
    }
    event->accept();
    update();
}
QRectF UBGraphicsRuler::rotateButtonRect() const
{
    QPixmap rotatePixmap(":/images/closeTool.svg");

    QSizeF rotateRectSize(
        rotatePixmap.width() * mAntiScaleRatio,
        rotatePixmap.height() * mAntiScaleRatio);

    int centimeters = (int)(rect().width() - sLeftEdgeMargin - resizeButtonRect().width()) / (int)(10 * sPixelsPerMillimeter);
    QPointF rotateRectCenter(
        rect().left() + sLeftEdgeMargin + (centimeters - 0.5) * 10 * sPixelsPerMillimeter,
        rect().center().y());

    QPointF rotateRectTopLeft(
        rotateRectCenter.x() - rotateRectSize.width() / 2,
        rotateRectCenter.y() - rotateRectSize.height() / 2);

    return QRectF(rotateRectTopLeft, rotateRectSize);
}
QRectF UBGraphicsProtractor::boundingRect() const
{
    QPointF center = rect().center();
    qreal centerX = center.x();
    qreal centerY = center.y();

    QRectF bounds = resizeButtonRect().adjusted(centerX, centerY, centerX, centerY);
    bounds = bounds.united(closeButtonRect().adjusted(centerX, centerY, centerX, centerY));
    bounds = bounds.united(resetButtonRect().adjusted(centerX, centerY, centerX, centerY));

    QTransform t;
    t.translate(centerX, centerY);
    t.rotate(-mStartAngle);
    t.translate(-centerX, -centerY);
    bounds = t.mapRect(bounds);

    bounds = bounds.united(QGraphicsEllipseItem::boundingRect());

    return bounds;
}
void UBGraphicsRuler::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    if (event->pos().x() > resizeButtonRect().left())
    {
        mResizing = true;
        event->accept();
    }
    else if (rotateButtonRect().contains(event->pos()))
    {
        mRotating = true;
        event->accept();
    }
    else
    {
        mResizeSvgItem->setVisible(false);
        mRotateSvgItem->setVisible(false);
		QGraphicsItem::mousePressEvent(event);
    }
    mResizeSvgItem->setVisible(mShowButtons && mResizing);
    mRotateSvgItem->setVisible(mShowButtons && mRotating);
    mCloseSvgItem->setVisible(false);
}
void UBGraphicsRuler::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
    UBStylusTool::Enum currentTool = (UBStylusTool::Enum)UBDrawingController::drawingController ()->stylusTool ();

    if (currentTool == UBStylusTool::Selector ||
        currentTool == UBStylusTool::Play)
    {
        mCloseSvgItem->setParentItem(this);
        mResizeSvgItem->setParentItem(this);
        mRotateSvgItem->setParentItem(this);

        mShowButtons = true;
        mCloseSvgItem->setVisible(mShowButtons);
        mResizeSvgItem->setVisible(mShowButtons);
        mRotateSvgItem->setVisible(mShowButtons);
        if (event->pos().x() >= resizeButtonRect().left())
        {
            setCursor(resizeCursor());
        }
        else
        {
            if (closeButtonRect().contains(event->pos()))
                setCursor(closeCursor());
            else if (rotateButtonRect().contains(event->pos()))
                setCursor(rotateCursor());
            else
                setCursor(moveCursor());
        }
        event->accept();
        update();
    }
    else if (UBDrawingController::drawingController()->isDrawingTool())
    {
        setCursor(drawRulerLineCursor());
        UBDrawingController::drawingController()->mActiveRuler = this;
        event->accept();
    }
}
void UBGraphicsCompass::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    if (UBDrawingController::drawingController ()->stylusTool() != UBStylusTool::Selector &&
        UBDrawingController::drawingController ()->stylusTool() != UBStylusTool::Play)
        return;

    bool closing = false;

    if (resizeButtonRect().contains(event->pos()))
    {
        mResizing = true;
        mRotating = false;
        event->accept();
    }
    else if (hingeRect().contains(event->pos()))
    {
        mRotating = true;
        mResizing = false;
        event->accept();
    }
    else if (!closeButtonRect().contains(event->pos()))
    {
        mDrawing = event->pos().x() > rect().right() - sPencilLength - sPencilBaseLength;
        if (mDrawing)
        {
            mSpanAngleInDegrees = 0;
            mSceneArcStartPoint = mapToScene(pencilPosition());
            scene()->initStroke();
            scene()->moveTo(mSceneArcStartPoint);
        }
        QGraphicsRectItem::mousePressEvent(event);
    }
    else 
        closing = true;

    mResizeSvgItem->setVisible(mShowButtons && mResizing);
    mCloseSvgItem->setVisible(mShowButtons && closing);
}