* Added TrailLayouter with Sugiyama dependency layouting * Layouter supports horizontal and vertical layouts * Added basic ui to graph view for showing incoming and outgoing paths * Added depth slider, with infinity at maximum * Disable trail ui when not available * Added trail messages to undo stack and only use last one when undoing * Added QtGraphLineBezier for trail graphs and refactored other line types * Disabled edge activation for trail layouts, shown only visually * Highlight all connected edges when hovering a node in trail layout * Use different color when highlighting call edges for better contrast * Fixed BucketLayouter issue when edge does not leave node * Increased click area for angled edges bug id = 249 337 fortune cookie message = Answer just what the heart prompts to you.
144 lines
2.8 KiB
C++
144 lines
2.8 KiB
C++
#include "qt/graphics/QtLineItemBezier.h"
|
|
|
|
#include <QPainter>
|
|
|
|
QtLineItemBezier::QtLineItemBezier(QGraphicsItem* parent)
|
|
: QtLineItemBase(parent)
|
|
{
|
|
}
|
|
|
|
QtLineItemBezier::~QtLineItemBezier()
|
|
{
|
|
}
|
|
|
|
QPainterPath QtLineItemBezier::shape() const
|
|
{
|
|
QPainterPathStroker stroker;
|
|
stroker.setWidth(10);
|
|
stroker.setJoinStyle(Qt::MiterJoin);
|
|
|
|
QPainterPath path = stroker.createStroke(getCurve());
|
|
if (m_showArrow)
|
|
{
|
|
path.addRect(getArrowBoundingRect(QtLineItemBase::getPath()).adjusted(-3, -3, 3, 3));
|
|
}
|
|
return path;
|
|
}
|
|
|
|
void QtLineItemBezier::paint(QPainter* painter, const QStyleOptionGraphicsItem* options, QWidget* widget)
|
|
{
|
|
QPainterPath path = getCurve();
|
|
|
|
if (m_showArrow)
|
|
{
|
|
drawArrow(QtLineItemBase::getPath(), &path);
|
|
}
|
|
|
|
painter->setPen(pen());
|
|
painter->drawPath(path);
|
|
}
|
|
|
|
QPolygon QtLineItemBezier::getPath() const
|
|
{
|
|
QPolygon poly = QtLineItemBase::getPath();
|
|
QPolygon newPoly;
|
|
|
|
QPoint tip = poly.at(0);
|
|
|
|
if (m_showArrow && m_style.arrowClosed)
|
|
{
|
|
int dir = getDirection(poly.at(1), poly.at(0));
|
|
|
|
switch (dir)
|
|
{
|
|
case 0:
|
|
tip.ry() += m_style.arrowLength;
|
|
break;
|
|
case 1:
|
|
tip.rx() -= m_style.arrowLength;
|
|
break;
|
|
case 2:
|
|
tip.ry() -= m_style.arrowLength;
|
|
break;
|
|
case 3:
|
|
tip.rx() += m_style.arrowLength;
|
|
break;
|
|
}
|
|
}
|
|
|
|
newPoly << tip;
|
|
|
|
QRect rect(poly.at(0), poly.at(3));
|
|
|
|
if (!rect.contains(poly.at(1)))
|
|
{
|
|
if (m_route == ROUTE_HORIZONTAL)
|
|
{
|
|
int diff;
|
|
if (std::abs(poly.at(1).x() - poly.at(0).x()) < std::abs(poly.at(2).x() - poly.at(3).x()))
|
|
{
|
|
diff = poly.at(1).x() - poly.at(0).x();
|
|
}
|
|
else
|
|
{
|
|
diff = poly.at(2).x() - poly.at(3).x();
|
|
}
|
|
|
|
newPoly << QPoint(poly.at(1).x() + diff, poly.at(1).y());
|
|
newPoly << QPoint(poly.at(2).x() + diff, poly.at(2).y());
|
|
}
|
|
else
|
|
{
|
|
int diff;
|
|
if (std::abs(poly.at(1).y() - poly.at(0).y()) < std::abs(poly.at(2).y() - poly.at(3).y()))
|
|
{
|
|
diff = poly.at(1).y() - poly.at(0).y();
|
|
}
|
|
else
|
|
{
|
|
diff = poly.at(2).y() - poly.at(3).y();
|
|
}
|
|
|
|
newPoly << QPoint(poly.at(1).x(), poly.at(1).y() + diff);
|
|
newPoly << QPoint(poly.at(2).x(), poly.at(2).y() + diff);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (m_route == ROUTE_HORIZONTAL)
|
|
{
|
|
newPoly << QPoint((poly.at(3).x() + poly.at(0).x()) / 2, poly.at(0).y());
|
|
newPoly << QPoint((poly.at(3).x() + poly.at(0).x()) / 2, poly.at(3).y());
|
|
}
|
|
else
|
|
{
|
|
newPoly << QPoint(poly.at(0).x(), (poly.at(3).y() + poly.at(0).y()) / 2);
|
|
newPoly << QPoint(poly.at(3).x(), (poly.at(3).y() + poly.at(0).y()) / 2);
|
|
}
|
|
}
|
|
|
|
newPoly << poly.at(3);
|
|
return newPoly;
|
|
}
|
|
|
|
QPainterPath QtLineItemBezier::getCurve() const
|
|
{
|
|
QPolygon poly = getPath();
|
|
|
|
QPainterPath path;
|
|
path.moveTo(poly.at(3));
|
|
path.cubicTo(
|
|
poly.at(2),
|
|
poly.at(1),
|
|
poly.at(0)
|
|
);
|
|
|
|
// QPainterPath path;
|
|
// path.moveTo(poly.at(3));
|
|
// path.lineTo(poly.at(2));
|
|
// path.lineTo(poly.at(1));
|
|
// path.lineTo(poly.at(0));
|
|
|
|
return path;
|
|
}
|