#include "BezierConnectionPainter.h" #include "WarpGraphModel.h" #include #include #include #include #include #include #include #include #include #include QPainterPath BezierConnectionPainter::cubicPath( QtNodes::ConnectionGraphicsObject const &cgo) const { QPointF const &in = cgo.endPoint(QtNodes::PortType::In); QPointF const &out = cgo.endPoint(QtNodes::PortType::Out); auto const c1c2 = cgo.pointsC1C2(); QPainterPath cubic(out); cubic.cubicTo(c1c2.first, c1c2.second, in); return cubic; } void BezierConnectionPainter::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 = cubicPath(cgo); float peakLevel = 0.0f; auto *scene = cgo.nodeScene(); if (scene) { auto *model = dynamic_cast(&scene->graphModel()); if (model) { auto cId = cgo.connectionId(); if (model->connectionExists(cId)) { peakLevel = model->nodePeakLevel(cId.outNodeId); if (peakLevel < 0.005f) { auto const *outData = model->warpNodeData(cId.outNodeId); if (outData && WarpGraphModel::classifyNode(outData->info) == WarpNodeType::kApplication) { peakLevel = std::max(peakLevel, model->nodePeakLevel(cId.inNodeId)); } } } } } auto activeColor = [&](QColor base) -> QColor { if (peakLevel < 0.005f) return base; float t = std::min(peakLevel * 2.0f, 1.0f); int r = static_cast(base.red() + t * (60 - base.red())); int g = static_cast(base.green() + t * (210 - base.green())); int b = static_cast(base.blue() + t * (80 - base.blue())); return QColor(std::clamp(r, 0, 255), std::clamp(g, 0, 255), std::clamp(b, 0, 255), base.alpha()); }; if (hovered || selected) { QPen pen; pen.setWidth(static_cast(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(style.constructionLineWidth())); pen.setColor(style.constructionColor()); pen.setStyle(Qt::DashLine); painter->setPen(pen); painter->setBrush(Qt::NoBrush); painter->drawPath(path); } else { QColor base = selected ? style.selectedColor() : style.normalColor(); QColor color = selected ? base : activeColor(base); float width = style.lineWidth(); if (!selected && peakLevel > 0.005f) width += peakLevel * 1.5f; QPen pen; pen.setWidthF(width); pen.setColor(color); 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 BezierConnectionPainter::getPainterStroke( QtNodes::ConnectionGraphicsObject const &cgo) const { auto cubic = cubicPath(cgo); QPointF const &out = cgo.endPoint(QtNodes::PortType::Out); QPainterPath result(out); unsigned int constexpr segments = 20; for (unsigned int i = 0; i < segments; ++i) { double ratio = double(i + 1) / segments; result.lineTo(cubic.pointAtPercent(ratio)); } QPainterPathStroker stroker; stroker.setWidth(10.0); return stroker.createStroke(result); }