131 lines
4 KiB
C++
131 lines
4 KiB
C++
#include "BezierConnectionPainter.h"
|
|
#include "WarpGraphModel.h"
|
|
|
|
#include <QtNodes/internal/BasicGraphicsScene.hpp>
|
|
#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 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<WarpGraphModel *>(&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<int>(base.red() + t * (60 - base.red()));
|
|
int g = static_cast<int>(base.green() + t * (210 - base.green()));
|
|
int b = static_cast<int>(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<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 {
|
|
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);
|
|
}
|