nodeviewedge: use bezier curves instead of straight lines

This commit is contained in:
itsmattkc
2020-02-26 01:07:53 +11:00
parent 785160b86b
commit 7e7ff49777
3 changed files with 50 additions and 37 deletions
+32 -26
View File
@@ -20,6 +20,7 @@
#include "nodeviewedge.h"
#include <QApplication>
#include <QDebug>
#include <QGraphicsSceneMouseEvent>
@@ -28,10 +29,10 @@
#include "nodeview.h"
NodeViewEdge::NodeViewEdge(QGraphicsItem *parent) :
QGraphicsLineItem(parent),
QGraphicsPathItem(parent),
edge_(nullptr),
connected_(false),
highlighted_(false)
color_group_(QPalette::Active),
color_role_(QPalette::Text)
{
// Ensures this UI object is drawn behind other objects
setZValue(-1);
@@ -93,39 +94,44 @@ void NodeViewEdge::Adjust()
input_point.setY(CalculateEdgeYPoint(input, edge_->input(), output));
// Draw a line between the two
setLine(QLineF(
output_point,
input_point
));
SetPoints(output_point, input_point);
}
void NodeViewEdge::SetConnected(bool c)
{
connected_ = c;
update();
if (c) {
color_group_ = QPalette::Active;
} else {
color_group_ = QPalette::Disabled;
}
UpdatePen();
}
void NodeViewEdge::SetHighlighted(bool e)
{
highlighted_ = e;
update();
if (e) {
color_role_ = QPalette::Highlight;
} else {
color_role_ = QPalette::Text;
}
UpdatePen();
}
void NodeViewEdge::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
void NodeViewEdge::SetPoints(const QPointF &start, const QPointF &end)
{
QPalette::ColorGroup color_group = QPalette::Active;
QPalette::ColorRole color_role = QPalette::Text;
if (highlighted_) {
color_role = QPalette::Highlight;
}
if (!connected_) {
color_group = QPalette::Disabled;
}
setPen(QPen(widget->palette().color(color_group, color_role), edge_width_));
QGraphicsLineItem::paint(painter, option, widget);
QPainterPath path;
float half_x = lerp(start.x(), end.x(), 0.5f);
path.moveTo(start);
path.cubicTo(QPointF(half_x, start.y()), QPointF(half_x, end.y()), end);
setPath(path);
}
void NodeViewEdge::UpdatePen()
{
setPen(QPen(qApp->palette().color(color_group_, color_role_), edge_width_));
//update();
}
+11 -6
View File
@@ -21,7 +21,8 @@
#ifndef NODEEDGEITEM_H
#define NODEEDGEITEM_H
#include <QGraphicsLineItem>
#include <QGraphicsPathItem>
#include <QPalette>
#include "node/edge.h"
@@ -30,7 +31,7 @@
*
* A fairly simple line widget use to visualize a connection between two node parameters (a NodeEdge).
*/
class NodeViewEdge : public QGraphicsLineItem
class NodeViewEdge : public QGraphicsPathItem
{
public:
NodeViewEdge(QGraphicsItem* parent = nullptr);
@@ -75,17 +76,21 @@ public:
*/
void SetHighlighted(bool e);
protected:
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
/**
* @brief Set points to create curve from
*/
void SetPoints(const QPointF& start, const QPointF& end);
private:
void UpdatePen();
NodeEdgePtr edge_;
int edge_width_;
bool connected_;
QPalette::ColorGroup color_group_;
bool highlighted_;
QPalette::ColorRole color_role_;
};
+7 -5
View File
@@ -332,11 +332,13 @@ void NodeViewItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
// (we use the current coordinates because a complex formula is used for the line's coords if the opposing
// node is collapsed, therefore it's easier to just retrieve it from line itself)
NodeViewEdge* existing_edge_ui = NodeView::EdgeToUIObject(scene(), edge);
QLineF existing_edge_line = existing_edge_ui->line();
if (existing_edge_ui->contains(existing_edge_line.p1())) {
dragging_edge_start_ = existing_edge_line.p1();
QPainterPath existing_edge_line = existing_edge_ui->path();
QPointF edge_start = existing_edge_line.pointAtPercent(0);
QPointF edge_end = existing_edge_line.pointAtPercent(1);
if (existing_edge_ui->contains(edge_start)) {
dragging_edge_start_ = edge_start;
} else {
dragging_edge_start_ = existing_edge_line.p2();
dragging_edge_start_ = edge_end;
}
@@ -429,7 +431,7 @@ void NodeViewItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
dragging_edge_->SetConnected(drag_dest_param_ != nullptr);
dragging_edge_->setLine(QLineF(dragging_edge_start_, end_point));
dragging_edge_->SetPoints(dragging_edge_start_, end_point);
return;
}