diff options
-rw-r--r-- | databaserelationship.cpp | 103 | ||||
-rw-r--r-- | databaserelationship.h | 2 | ||||
-rw-r--r-- | range.h | 1 |
3 files changed, 86 insertions, 20 deletions
diff --git a/databaserelationship.cpp b/databaserelationship.cpp index 270d793..d7c3dd1 100644 --- a/databaserelationship.cpp +++ b/databaserelationship.cpp @@ -38,8 +38,11 @@ QPainterPath DatabaseRelationship::shape() const { QPainterPath path; - path.moveTo(m_line.p1()); - path.lineTo(m_line.p2()); + if (m_line.isEmpty()) + return path; + path.moveTo(m_line[0]); + for (int i = 1; i < m_line.size(); i++) + path.lineTo(m_line[i]); path.addPolygon(m_arrowHead); QPen pen(QPen(QColor(0, 0, 0), 1)); pen.setJoinStyle(Qt::MiterJoin); @@ -60,7 +63,7 @@ DatabaseRelationship::paint(QPainter *painter, const QStyleOptionGraphicsItem *o QPen pen(QPen(QColor(0, 0, 0), 1)); pen.setJoinStyle(Qt::MiterJoin); painter->setPen(pen); - painter->drawLine(m_line); + painter->drawPolyline(m_line); painter->setBrush(pen.color()); painter->drawPolygon(m_arrowHead); } @@ -98,23 +101,23 @@ DatabaseRelationship::updateLayout() bool haveLine = false; - Range<qreal> verticalIntersection = - Range<qreal>(rect1.top(), rect1.bottom()).intersected( - Range<qreal>(rect2.top(), rect2.bottom())); + Range<qreal> verticalRange1(rect1.top(), rect1.bottom()); + Range<qreal> verticalRange2(rect2.top(), rect2.bottom()); + Range<qreal> verticalIntersection = verticalRange1.intersected(verticalRange2); - Range<qreal> horizontalIntersection = - Range<qreal>(rect1.left(), rect1.right()).intersected( - Range<qreal>(rect2.left(), rect2.right())); + Range<qreal> horizontalRange1(rect1.left(), rect1.right()); + Range<qreal> horizontalRange2(rect2.left(), rect2.right()); + Range<qreal> horizontalIntersection = horizontalRange1.intersected(horizontalRange2); // Straight horizontal line if (!haveLine) { if (!verticalIntersection.isNull() && horizontalIntersection.isNull()) { qreal y = verticalIntersection.min() + verticalIntersection.length() / 2; if (rect1.right() < rect2.left()) { - m_line = QLineF(rect1.right(), y, rect2.left(), y); + m_line = QPolygonF() << QPointF(rect1.right(), y) << QPointF(rect2.left(), y); } else { - m_line = QLineF(rect1.left(), y, rect2.right(), y); + m_line = QPolygonF() << QPointF(rect1.left(), y) << QPointF(rect2.right(), y); } haveLine = true; } @@ -125,20 +128,78 @@ DatabaseRelationship::updateLayout() if (verticalIntersection.isNull() && !horizontalIntersection.isNull()) { qreal x = horizontalIntersection.min() + horizontalIntersection.length() / 2; if (rect1.bottom() < rect2.top()) { + m_line = QPolygonF() << QPointF(x, rect1.bottom()) << QPointF(x, rect2.top()); + } + else { + m_line = QPolygonF() << QPointF(x, rect1.top()) << QPointF(x, rect2.bottom()); + } + haveLine = true; + } + } + + // Two-segment line + if (!haveLine) { + + qreal x1, x2, x3, y1, y2, y3; + + if (rect1.right() < rect2.left()) { + x1 = rect1.right(); + y1 = verticalRange1.center(); + + x2 = horizontalRange2.center(); + y2 = verticalRange1.center(); + + if (rect1.bottom() < rect2.top()) { + x3 = horizontalRange2.center(); + y3 = rect2.top(); + } + else { + x3 = horizontalRange2.center(); + y3 = rect2.bottom(); + } + } + else { + x1 = rect1.left(); + y1 = verticalRange1.center(); + + x2 = horizontalRange2.center(); + y2 = verticalRange1.center(); + + if (rect1.bottom() < rect2.top()) { + x3 = horizontalRange2.center(); + y3 = rect2.top(); + } + else { + x3 = horizontalRange2.center(); + y3 = rect2.bottom(); + } + } + + m_line = QPolygonF() + << QPointF(x1, y1) + << QPointF(x2, y2) + << QPointF(x3, y3); + haveLine = true; + + +/* + if (verticalIntersection.isNull() && !horizontalIntersection.isNull()) { + qreal x = horizontalIntersection.min() + horizontalIntersection.length() / 2; + if (rect1.bottom() < rect2.top()) { m_line = QLineF(x, rect1.bottom(), x, rect2.top()); } else { m_line = QLineF(x, rect1.top(), x, rect2.bottom()); } haveLine = true; - } + }*/ } // Simple center<->center line if (!haveLine) { QPointF p1 = rect1.center(); QPointF p2 = rect2.center(); - m_line = QLineF(p1, p2); + QLineF finalLine = QLineF(p1, p2); QPolygonF polygon; @@ -146,8 +207,8 @@ DatabaseRelationship::updateLayout() for (int i = 0; i < 4; i++) { QLineF line(polygon[i], polygon[(i+1)%4]); QPointF intersectionPoint; - if (m_line.intersect(line, &intersectionPoint) == QLineF::BoundedIntersection) { - m_line.setP1(intersectionPoint); + if (finalLine.intersect(line, &intersectionPoint) == QLineF::BoundedIntersection) { + finalLine.setP1(intersectionPoint); break; } } @@ -156,23 +217,27 @@ DatabaseRelationship::updateLayout() for (int i = 0; i < 4; i++) { QLineF line(polygon[i], polygon[(i+1)%4]); QPointF intersectionPoint; - if (m_line.intersect(line, &intersectionPoint) == QLineF::BoundedIntersection) { - m_line.setP2(intersectionPoint); + if (finalLine.intersect(line, &intersectionPoint) == QLineF::BoundedIntersection) { + finalLine.setP2(intersectionPoint); break; } } + m_line = QPolygonF() << finalLine.p1() << finalLine.p2(); haveLine = true; } Q_ASSERT(haveLine); + int size = m_line.size(); + QLineF lastSegment(m_line[size-2], m_line[size-1]); + m_arrowHead.resize(3); m_arrowHead[0] = QPointF(0.0, 0.0); m_arrowHead[1] = QPointF(-4.5, 10.0); m_arrowHead[2] = QPointF(4.5, 10.0); QMatrix matrix; - matrix.rotate(-m_line.angle() + 90); + matrix.rotate(-lastSegment.angle() + 90); m_arrowHead = matrix.map(m_arrowHead); - m_arrowHead.translate(m_line.p2()); + m_arrowHead.translate(lastSegment.p2()); } diff --git a/databaserelationship.h b/databaserelationship.h index b2a7c3c..f0edd68 100644 --- a/databaserelationship.h +++ b/databaserelationship.h @@ -48,7 +48,7 @@ protected: QVariant itemChange(GraphicsItemChange change, const QVariant &value); private: - QLineF m_line; + QPolygonF m_line; QPolygonF m_arrowHead; }; @@ -33,6 +33,7 @@ public: bool isNull() const { return m_max == m_min; } T length() const { return m_max - m_min; } + T center() const { return m_min + length() / 2; } Range<T> intersected(const Range<T> &other) const { |