diff --git a/src/Base/diagramscene.cpp b/src/Base/diagramscene.cpp index 4f6baa8..5a1af6c 100644 --- a/src/Base/diagramscene.cpp +++ b/src/Base/diagramscene.cpp @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include #include #include @@ -140,14 +142,30 @@ void DiagramScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) break; case _Aggregation: + { + Aggregation *_aggregation = new Aggregation(_p2, _p1); + cmd->setItem(_aggregation); - break; + ObjectKeeper::instance()->createCommand(cmd); + addItem(_aggregation); + update(); + } + + break; case _Assosiation: break; case _Composition: + { + Composition *_composition = new Composition(_p2, _p1); + cmd->setItem(_composition); - break; + ObjectKeeper::instance()->createCommand(cmd); + addItem(_composition); + update(); + } + + break; case _Dependency: break; diff --git a/src/Diagrams/Class/classdiagram.cpp b/src/Diagrams/Class/classdiagram.cpp index 9942878..40dd27e 100644 --- a/src/Diagrams/Class/classdiagram.cpp +++ b/src/Diagrams/Class/classdiagram.cpp @@ -138,6 +138,11 @@ ClassDiagram::ClassDiagram() "

Composition

", nullptr)); + connect(act7, &QAction::triggered, this, []() + { + DiagramScene::instance()->setRelation(DiagramScene::_Composition); + }); + menuBar()->addToolButton(act7); @@ -149,6 +154,12 @@ ClassDiagram::ClassDiagram() "

Aggregation

", nullptr)); + connect(act8, &QAction::triggered, this, []() + { + DiagramScene::instance()->setRelation(DiagramScene::_Aggregation); + }); + + menuBar()->addToolButton(act8); cmd = new ShapeCommand(); diff --git a/src/Diagrams/Relations/aggregation.cpp b/src/Diagrams/Relations/aggregation.cpp index 30a4f4b..4af334e 100644 --- a/src/Diagrams/Relations/aggregation.cpp +++ b/src/Diagrams/Relations/aggregation.cpp @@ -1,6 +1,75 @@ #include "aggregation.h" -Aggregation::Aggregation(QObject *parent) : QObject(parent) +#include +#include +#include +#include + +Aggregation::Aggregation(QPointF startItem, QPointF endItem, QGraphicsItem *parent): + myStartItem(startItem), myEndItem(endItem) +{ + setAcceptHoverEvents(true); + setZValue(105); + setFlag(QGraphicsItem::ItemIsMovable); + setFlag(QGraphicsItem::ItemIsSelectable); + setFlag(QGraphicsItem::ItemIsFocusable); +} + +QRectF Aggregation::boundingRect() const +{ + return QRectF(myStartItem, myEndItem); +} + +QPainterPath Aggregation::shape() const +{ + QPainterPath path; + + path.addRect(boundingRect()); + + return path; +} + +void Aggregation::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { + Q_UNUSED(widget); + QPen myPen; + + myPen.setColor(myColor); + myPen.setWidth(2); + myPen.setCosmetic(true); + painter->setPen(myPen); + painter->setBrush(myColor); + + painter->save(); + + painter->setRenderHints(QPainter::Antialiasing); + + painter->setBrush(Qt::NoBrush); + + painter->drawLine(myStartItem, myEndItem); + painter->restore(); + + double angle = std::atan2(-(myEndItem.y() - myStartItem.y()), (myEndItem.x() - myStartItem.x())); + QPointF arrowP1 = myStartItem + QPointF(sin(angle + M_PI / 3) * 20, + cos(angle + M_PI / 3) * 20); + QPointF arrowP2 = myStartItem + QPointF(sin(angle + M_PI - M_PI / 3) * 20, + cos(angle + M_PI - M_PI / 3) * 20); + + arrowHead.clear(); + + painter->save(); + painter->setBrush(Qt::white); + QLineF tmp(myStartItem, myEndItem); + tmp.setLength(35); + auto test_point = tmp.p2(); + + arrowHead << myStartItem << arrowP1 << test_point << arrowP2; + painter->drawPolygon(arrowHead); + painter->restore(); +} + +void Aggregation::setMyColor(const QColor &value) +{ + myColor = value; } diff --git a/src/Diagrams/Relations/aggregation.h b/src/Diagrams/Relations/aggregation.h index d2b7952..51a02c8 100644 --- a/src/Diagrams/Relations/aggregation.h +++ b/src/Diagrams/Relations/aggregation.h @@ -2,15 +2,27 @@ #define AGGREGATION_H #include +#include -class Aggregation : public QObject +class Aggregation: public QGraphicsItem { - Q_OBJECT public: - explicit Aggregation(QObject *parent = nullptr); + explicit Aggregation(QPointF startItem, QPointF endItem, + QGraphicsItem *parent = nullptr); -signals: + QRectF boundingRect() const; + QPainterPath shape() const override; + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + + void setMyColor(const QColor &value); + +private: + QPointF myStartItem; + QPointF myEndItem; + QPolygonF arrowHead; + QColor myColor = Qt::black; }; #endif // AGGREGATION_H diff --git a/src/Diagrams/Relations/composition.cpp b/src/Diagrams/Relations/composition.cpp index 3a73e54..36ebcb5 100644 --- a/src/Diagrams/Relations/composition.cpp +++ b/src/Diagrams/Relations/composition.cpp @@ -1,6 +1,71 @@ #include "composition.h" +#include +#include +#include +#include -Composition::Composition(QObject *parent) : QObject(parent) +Composition::Composition(QPointF startItem, QPointF endItem, QGraphicsItem *parent): + myStartItem(startItem), myEndItem(endItem) { + setAcceptHoverEvents(true); + setZValue(105); + setFlag(QGraphicsItem::ItemIsMovable); + setFlag(QGraphicsItem::ItemIsSelectable); + setFlag(QGraphicsItem::ItemIsFocusable); +} + +QRectF Composition::boundingRect() const +{ + return QRectF(myStartItem, myEndItem); +} + +QPainterPath Composition::shape() const +{ + QPainterPath path; + + path.addRect(boundingRect()); + + return path; +} + +void Composition::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(widget); + + QPen myPen; + myPen.setColor(myColor); + myPen.setWidth(2); + myPen.setCosmetic(true); + painter->setPen(myPen); + painter->setBrush(myColor); + + painter->save(); + + painter->setRenderHints(QPainter::Antialiasing); + + painter->setBrush(Qt::NoBrush); + + painter->drawLine(myStartItem, myEndItem); + painter->restore(); + + double angle = std::atan2(-(myEndItem.y() - myStartItem.y()), (myEndItem.x() - myStartItem.x())); + QPointF arrowP1 = myStartItem + QPointF(sin(angle + M_PI / 3) * 20, + cos(angle + M_PI / 3) * 20); + QPointF arrowP2 = myStartItem + QPointF(sin(angle + M_PI - M_PI / 3) * 20, + cos(angle + M_PI - M_PI / 3) * 20); + + arrowHead.clear(); + + QLineF tmp(myStartItem, myEndItem); + tmp.setLength(35); + auto test_point = tmp.p2(); + + arrowHead << myStartItem << arrowP1 << test_point << arrowP2; + painter->drawPolygon(arrowHead); +} + +void Composition::setMyColor(const QColor &value) +{ + myColor = value; } diff --git a/src/Diagrams/Relations/composition.h b/src/Diagrams/Relations/composition.h index 724c058..a6df3ba 100644 --- a/src/Diagrams/Relations/composition.h +++ b/src/Diagrams/Relations/composition.h @@ -2,15 +2,27 @@ #define COMPOSITION_H #include +#include -class Composition : public QObject +class Composition: public QGraphicsItem { - Q_OBJECT public: - explicit Composition(QObject *parent = nullptr); + explicit Composition(QPointF startItem, QPointF endItem, + QGraphicsItem *parent = nullptr); -signals: + QRectF boundingRect() const; + QPainterPath shape() const override; + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + + void setMyColor(const QColor &value); + +private: + QPointF myStartItem; + QPointF myEndItem; + QPolygonF arrowHead; + QColor myColor = Qt::black; }; #endif // COMPOSITION_H