116 lines
3.3 KiB
C++
116 lines
3.3 KiB
C++
#include "SquareConnectionPainter.h"
|
|
|
|
#include <QtNodes/internal/ConnectionGraphicsObject.hpp>
|
|
#include <QtNodes/internal/ConnectionState.hpp>
|
|
#include <QtNodes/internal/Definitions.hpp>
|
|
#include <QtNodes/StyleCollection>
|
|
|
|
#include <QPainter>
|
|
#include <QPainterPath>
|
|
#include <QPainterPathStroker>
|
|
|
|
#include <algorithm>
|
|
#include <cmath>
|
|
|
|
QPainterPath SquareConnectionPainter::orthogonalPath(
|
|
QtNodes::ConnectionGraphicsObject const &cgo) const {
|
|
QPointF out = cgo.endPoint(QtNodes::PortType::Out);
|
|
QPointF in = cgo.endPoint(QtNodes::PortType::In);
|
|
|
|
constexpr double kRadius = 5.0;
|
|
constexpr double kSpacing = 8.0;
|
|
constexpr double kMinStub = 20.0;
|
|
|
|
auto cId = cgo.connectionId();
|
|
double spread = static_cast<double>(cId.outPortIndex) * kSpacing;
|
|
|
|
double dy = in.y() - out.y();
|
|
|
|
if (std::abs(dy) < 0.5 && in.x() > out.x()) {
|
|
QPainterPath path(out);
|
|
path.lineTo(in);
|
|
return path;
|
|
}
|
|
|
|
double midX = (out.x() + in.x()) / 2.0 + spread;
|
|
midX = std::max(midX, out.x() + kMinStub);
|
|
if (in.x() > out.x())
|
|
midX = std::min(midX, in.x() - kMinStub);
|
|
|
|
double r = std::min({kRadius, std::abs(dy) / 2.0,
|
|
std::abs(midX - out.x()),
|
|
std::abs(in.x() - midX)});
|
|
r = std::max(r, 0.0);
|
|
|
|
double sy = (dy > 0) ? 1.0 : -1.0;
|
|
double hDir = (in.x() >= midX) ? 1.0 : -1.0;
|
|
|
|
QPainterPath path(out);
|
|
|
|
if (r > 0.5) {
|
|
path.lineTo(midX - r, out.y());
|
|
path.quadTo(QPointF(midX, out.y()), QPointF(midX, out.y() + sy * r));
|
|
path.lineTo(midX, in.y() - sy * r);
|
|
path.quadTo(QPointF(midX, in.y()), QPointF(midX + hDir * r, in.y()));
|
|
} else {
|
|
path.lineTo(midX, out.y());
|
|
path.lineTo(midX, in.y());
|
|
}
|
|
|
|
path.lineTo(in);
|
|
return path;
|
|
}
|
|
|
|
void SquareConnectionPainter::paint(
|
|
QPainter *painter,
|
|
QtNodes::ConnectionGraphicsObject const &cgo) const {
|
|
auto const &style = QtNodes::StyleCollection::connectionStyle();
|
|
|
|
bool const hovered = cgo.connectionState().hovered();
|
|
bool const selected = cgo.isSelected();
|
|
bool const sketch = cgo.connectionState().requiresPort();
|
|
|
|
auto path = orthogonalPath(cgo);
|
|
|
|
if (hovered || selected) {
|
|
QPen pen;
|
|
pen.setWidth(static_cast<int>(2 * style.lineWidth()));
|
|
pen.setColor(selected ? style.selectedHaloColor() : style.hoveredColor());
|
|
painter->setPen(pen);
|
|
painter->setBrush(Qt::NoBrush);
|
|
painter->drawPath(path);
|
|
}
|
|
|
|
if (sketch) {
|
|
QPen pen;
|
|
pen.setWidth(static_cast<int>(style.constructionLineWidth()));
|
|
pen.setColor(style.constructionColor());
|
|
pen.setStyle(Qt::DashLine);
|
|
painter->setPen(pen);
|
|
painter->setBrush(Qt::NoBrush);
|
|
painter->drawPath(path);
|
|
} else {
|
|
QPen pen;
|
|
pen.setWidth(style.lineWidth());
|
|
pen.setColor(selected ? style.selectedColor() : style.normalColor());
|
|
painter->setPen(pen);
|
|
painter->setBrush(Qt::NoBrush);
|
|
painter->drawPath(path);
|
|
}
|
|
|
|
double const pointRadius = style.pointDiameter() / 2.0;
|
|
painter->setPen(style.constructionColor());
|
|
painter->setBrush(style.constructionColor());
|
|
painter->drawEllipse(cgo.out(), pointRadius, pointRadius);
|
|
painter->drawEllipse(cgo.in(), pointRadius, pointRadius);
|
|
}
|
|
|
|
QPainterPath SquareConnectionPainter::getPainterStroke(
|
|
QtNodes::ConnectionGraphicsObject const &cgo) const {
|
|
auto path = orthogonalPath(cgo);
|
|
|
|
QPainterPathStroker stroker;
|
|
stroker.setWidth(10.0);
|
|
|
|
return stroker.createStroke(path);
|
|
}
|