diff --git a/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.cpp b/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.cpp index 6dc87c051..7b3bb4353 100644 --- a/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.cpp +++ b/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.cpp @@ -87,7 +87,6 @@ QVector QetGraphicsHandlerUtility::pointsForArc(const QRectF &rect, path.arcTo(rect, start_angle, span_angle); vector.append(path.currentPosition()); return vector; - } /** @@ -187,6 +186,52 @@ QRectF QetGraphicsHandlerUtility::mirrorRectForPosAtIndex( return rect; } +/** + * @brief QetGraphicsHandlerUtility::rectForArc + * @param rect : the rect where the arc is defined + * @param start_angle : start angle in degree + * @param span_angle : span angle in degree + * @return Return the rect that bound the arc. + */ +QRectF QetGraphicsHandlerUtility::rectForArc(const QRectF &rect, qreal start_angle, qreal span_angle) +{ + auto point = pointsForArc (rect, start_angle, span_angle); + auto end_angle =start_angle + span_angle; + auto normalized_end_angle = end_angle; + if (normalized_end_angle > 360) + normalized_end_angle -= 360; + + QPointF top_left; + if ((start_angle <= 180 && normalized_end_angle >= 180) || + (end_angle > 360 && normalized_end_angle >= 180)) { + top_left.setX(rect.left()); + } else { + top_left.setX(std::min(point[0].x(), point[1].x())); + } + if ((start_angle <= 90 && end_angle >= 90) || + (start_angle > 90 && end_angle > 360 && normalized_end_angle >= 90)) { + top_left.setY(rect.top()); + } else { + top_left.setY(std::min(point[0].y(), point[1].y())); + } + + + QPointF bottom_right; + if (end_angle >= 360) { + bottom_right.setX(rect.right()); + } else { + bottom_right.setX(std::max(point[0].x(), point[1].x())); + } + if ((start_angle <= 270 && end_angle >= 270) || + (end_angle > 360 && normalized_end_angle >= 270)) { + bottom_right.setY(rect.bottom()); + } else { + bottom_right.setY(std::max(point[0].y(), point[1].y())); + } + + return QRectF(top_left, bottom_right); +} + /** @brief QetGraphicsHandlerUtility::lineForPosAtIndex Return a line after modification of pos at index index of old_line. diff --git a/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.h b/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.h index 950f27fa4..59527ca2b 100644 --- a/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.h +++ b/sources/QetGraphicsItemModeler/qetgraphicshandlerutility.h @@ -39,6 +39,7 @@ class QetGraphicsHandlerUtility static QVector pointsForArc (const QRectF &rect, qreal start_angle, qreal span_angle); static QRectF rectForPosAtIndex (const QRectF &old_rect, const QPointF &pos, int index); static QRectF mirrorRectForPosAtIndex (const QRectF &old_rect, const QPointF &pos, int index); + static QRectF rectForArc (const QRectF &rect, qreal start_angle, qreal span_angle); static QLineF lineForPosAtIndex (const QLineF &old_line, const QPointF &pos, int index); static QPolygonF polygonForInsertPoint(const QPolygonF &old_polygon, bool closed, const QPointF &pos); static QVector pointForRadiusRect (const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode = Qt::AbsoluteSize); diff --git a/sources/editor/graphicspart/partarc.cpp b/sources/editor/graphicspart/partarc.cpp index 0129ff920..c58b2c8ec 100644 --- a/sources/editor/graphicspart/partarc.cpp +++ b/sources/editor/graphicspart/partarc.cpp @@ -54,7 +54,7 @@ PartArc::~PartArc() */ void PartArc::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) { - Q_UNUSED(widget); + Q_UNUSED(widget) applyStylesToQPainter(*painter); @@ -80,7 +80,7 @@ void PartArc::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, painter -> setPen(t); } - painter -> drawArc(m_rect, m_start_angle, m_span_angle); + painter->drawArc(m_rect, m_start_angle, m_span_angle); if (m_hovered) drawShadowShape(painter); @@ -155,6 +155,20 @@ QPainterPath PartArc::shadowShape() const return (pps.createStroke(shape)); } +/** + * @brief PartArc::sceneGeometricRect + * @return the minimum, + * margin-less rectangle this part can fit into in scene coordinates. + * It is different from boundingRect() because it is not supposed + * to imply any margin, + * and it is different from shape because it is a regular + * rectangle, not a complex shape. + */ +QRectF PartArc::sceneGeometricRect() const +{ + return mapToScene(QetGraphicsHandlerUtility::rectForArc(m_rect, m_start_angle/16, m_span_angle/16)).boundingRect(); +} + /** @brief PartArc::mouseReleaseEvent Handle mouse release event @@ -314,14 +328,14 @@ void PartArc::adjusteHandlerPos() */ void PartArc::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event) { - Q_UNUSED(qghi); - Q_UNUSED(event); + Q_UNUSED(qghi) + Q_UNUSED(event) if (m_resize_mode == 3) //Resize angle { if (m_vector_index == 0) { - m_span_point = QetGraphicsHandlerUtility::pointsForArc(m_rect, m_start_angle /16, m_span_angle /16).at(1); + m_span_point = QetGraphicsHandlerUtility::pointsForArc(m_rect, m_start_angle/16, m_span_angle/16).at(1); m_undo_command = new QPropertyUndoCommand(this, "startAngle", QVariant(m_start_angle)); m_undo_command->setText(tr("Modifier un arc")); @@ -353,7 +367,7 @@ void PartArc::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsScen */ void PartArc::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event) { - Q_UNUSED(qghi); + Q_UNUSED(qghi) QPointF new_pos = event->scenePos(); if (event->modifiers() != Qt::ControlModifier) @@ -387,8 +401,8 @@ void PartArc::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsScene */ void PartArc::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event) { - Q_UNUSED(qghi); - Q_UNUSED(event); + Q_UNUSED(qghi) + Q_UNUSED(event) if (m_resize_mode == 3) { diff --git a/sources/editor/graphicspart/partarc.h b/sources/editor/graphicspart/partarc.h index 29a3c93e0..9026f833f 100644 --- a/sources/editor/graphicspart/partarc.h +++ b/sources/editor/graphicspart/partarc.h @@ -59,6 +59,7 @@ class PartArc : public AbstractPartEllipse void setRect(const QRectF &rect) override {AbstractPartEllipse::setRect(rect); adjusteHandlerPos();} void setStartAngle(const int &start_angle) override {AbstractPartEllipse::setStartAngle(start_angle); adjusteHandlerPos();} void setSpanAngle(const int &span_angle) override {AbstractPartEllipse::setSpanAngle(span_angle); adjusteHandlerPos();} + QRectF sceneGeometricRect() const override; protected: void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;