reimplemented edge connect/disconnect
This commit is contained in:
@@ -473,30 +473,27 @@ void NodeView::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (HandPress(event)) return;
|
||||
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
// See if we're dragging the arrow of an edge
|
||||
QPointF scene_pt = mapToScene(event->pos());
|
||||
QGraphicsItem* item = itemAt(event->pos());
|
||||
|
||||
for (NodeViewEdge *edge_item : scene_.edges()) {
|
||||
if (edge_item->arrow_bounding_rect().contains(scene_pt)) {
|
||||
create_edge_src_ = scene_.NodeToUIObject(edge_item->output());
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
// Determine if user clicked on a connector
|
||||
if (NodeViewItemConnector *connector = dynamic_cast<NodeViewItemConnector *>(item)) {
|
||||
NodeViewItem *attached_item = static_cast<NodeViewItem*>(connector->parentItem());
|
||||
if (connector->IsOutput()) {
|
||||
CreateNewEdge(attached_item, event->pos());
|
||||
return;
|
||||
} else {
|
||||
NodeViewEdge *edge_item = attached_item->GetEdgeFromInputConnector(connector);
|
||||
if (edge_item) {
|
||||
create_edge_src_ = edge_item->from_item();
|
||||
create_edge_ = edge_item;
|
||||
create_edge_already_exists_ = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// See if we're dragging the arrow of a node
|
||||
for (NodeViewItem *node_item : scene_.item_map()) {
|
||||
if (node_item->GetOutputTriangle().boundingRect().translated(node_item->pos()).contains(scene_pt)) {
|
||||
CreateNewEdge(node_item, event->pos());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QGraphicsItem* item = itemAt(event->pos());
|
||||
|
||||
if (event->button() == Qt::RightButton) {
|
||||
if (!item || !item->isSelected()) {
|
||||
// Qt doesn't do this by default for some reason
|
||||
@@ -668,13 +665,13 @@ void NodeView::mouseReleaseEvent(QMouseEvent *event)
|
||||
}
|
||||
|
||||
// Update contexts
|
||||
if (!removed_edges.empty()) {
|
||||
/*if (!removed_edges.empty()) {
|
||||
UpdateContextsFromEdgeRemove(command, removed_edges);
|
||||
}
|
||||
|
||||
if (added_edge.first) {
|
||||
UpdateContextsFromEdgeAdd(command, added_edge, removed_edges);
|
||||
}
|
||||
}*/
|
||||
|
||||
Core::instance()->undo_stack()->pushIfHasChildren(command);
|
||||
return;
|
||||
|
||||
@@ -126,13 +126,6 @@ void NodeViewEdge::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
|
||||
painter->setPen(QPen(edge_color, edge_width_));
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
painter->drawPath(path());
|
||||
|
||||
// Draw arrow
|
||||
if (!connected_) {
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->setBrush(edge_color);
|
||||
painter->drawPolygon(arrow_);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeViewEdge::Init()
|
||||
@@ -149,7 +142,6 @@ void NodeViewEdge::Init()
|
||||
|
||||
// Use font metrics to set edge width for basic high DPI support
|
||||
edge_width_ = QFontMetrics(QFont()).height() / 12;
|
||||
arrow_size_ = QFontMetrics(QFont()).height() / 2;
|
||||
}
|
||||
|
||||
void NodeViewEdge::UpdateCurve()
|
||||
@@ -185,7 +177,7 @@ void NodeViewEdge::UpdateCurve()
|
||||
path.cubicTo(cp1, cp2, end);
|
||||
|
||||
if (!qFuzzyCompare(start.x(), end.x())) {
|
||||
double continue_x = end.x() - qCos(angle)*arrow_size_;
|
||||
double continue_x = end.x() - qCos(angle);
|
||||
|
||||
double x1 = start.x();
|
||||
double x2 = cp1.x();
|
||||
@@ -215,18 +207,7 @@ void NodeViewEdge::UpdateCurve()
|
||||
|
||||
}
|
||||
|
||||
setPath(path);
|
||||
|
||||
const double arrow_angle = 150.0 * M_PI / 180.0;
|
||||
QVector<QPointF> arrow_points(4);
|
||||
arrow_points[0] = end;
|
||||
arrow_points[1] = end + QPointF(qCos(angle + arrow_angle) * arrow_size_, qSin(angle + arrow_angle) * arrow_size_);
|
||||
arrow_points[2] = end + QPointF(qCos(angle - arrow_angle) * arrow_size_, qSin(angle - arrow_angle) * arrow_size_);
|
||||
arrow_points[3] = end;
|
||||
|
||||
arrow_ = QPolygonF(arrow_points);
|
||||
arrow_bounding_rect_ = arrow_.boundingRect();
|
||||
arrow_bounding_rect_.adjust(-arrow_size_, -arrow_size_, arrow_size_, arrow_size_);
|
||||
setPath(mapFromScene(path));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -70,11 +70,6 @@ public:
|
||||
return to_item_;
|
||||
}
|
||||
|
||||
const QRectF arrow_bounding_rect() const
|
||||
{
|
||||
return arrow_bounding_rect_;
|
||||
}
|
||||
|
||||
void Adjust();
|
||||
|
||||
/**
|
||||
@@ -144,12 +139,6 @@ private:
|
||||
|
||||
bool curved_;
|
||||
|
||||
QPolygonF arrow_;
|
||||
|
||||
int arrow_size_;
|
||||
|
||||
QRectF arrow_bounding_rect_;
|
||||
|
||||
QPointF cached_start_;
|
||||
QPointF cached_end_;
|
||||
bool cached_input_is_expanded_;
|
||||
|
||||
@@ -67,7 +67,7 @@ NodeViewItem::NodeViewItem(QGraphicsItem *parent) :
|
||||
title_bar_rect_ = QRectF(-widget_width/2, -widget_height/2, widget_width, widget_height);
|
||||
setRect(title_bar_rect_);
|
||||
|
||||
output_connector_ = new NodeViewItemConnector(this);
|
||||
output_connector_ = new NodeViewItemConnector(true, this);
|
||||
}
|
||||
|
||||
QPointF NodeViewItem::GetNodePosition() const
|
||||
@@ -196,7 +196,7 @@ void NodeViewItem::RemoveEdge(NodeViewEdge *edge)
|
||||
|
||||
int NodeViewItem::GetIndexAt(QPointF pt) const
|
||||
{
|
||||
pt -= pos();
|
||||
pt -= this->scenePos();
|
||||
|
||||
for (int i=0; i<node_inputs_.size(); i++) {
|
||||
if (GetInputRect(i).contains(pt)) {
|
||||
@@ -217,8 +217,7 @@ void NodeViewItem::SetNode(Node *n)
|
||||
node_ = n;
|
||||
|
||||
node_inputs_.clear();
|
||||
|
||||
ClearInputConnectors();
|
||||
input_connectors_.clear();
|
||||
|
||||
if (node_) {
|
||||
node_->Retranslate();
|
||||
@@ -473,6 +472,17 @@ void NodeViewItem::DrawNodeTitle(QPainter* painter, QString text, const QRectF&
|
||||
text);
|
||||
}
|
||||
|
||||
NodeViewEdge *NodeViewItem::GetEdgeFromInputIndex(int index)
|
||||
{
|
||||
foreach (NodeViewEdge *edge, edges_) {
|
||||
if (edge->input().input() == node_inputs_.at(index)) {
|
||||
return edge;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void NodeViewItem::SetHighlightedIndex(int index)
|
||||
{
|
||||
if (highlighted_index_ == index) {
|
||||
@@ -491,6 +501,23 @@ void NodeViewItem::SetLabelAsOutput(bool e)
|
||||
update();
|
||||
}
|
||||
|
||||
NodeViewEdge *NodeViewItem::GetEdgeFromInputConnector(NodeViewItemConnector *connector)
|
||||
{
|
||||
ssize_t index = -1;
|
||||
for (ssize_t i=0; i<ssize_t(input_connectors_.size()); i++) {
|
||||
if (input_connectors_[i].get() == connector) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == -1) {
|
||||
return nullptr;
|
||||
} else {
|
||||
return GetEdgeFromInputIndex(index);
|
||||
}
|
||||
}
|
||||
|
||||
QRectF NodeViewItem::GetInputRect(int index) const
|
||||
{
|
||||
QRectF r = title_bar_rect_;
|
||||
@@ -514,12 +541,12 @@ QPointF NodeViewItem::GetInputPoint(const QString &input, int element) const
|
||||
return QPointF();
|
||||
}
|
||||
|
||||
return pos() + input_connectors_[index]->pos();
|
||||
return input_connectors_[index]->scenePos();
|
||||
}
|
||||
|
||||
QPointF NodeViewItem::GetOutputPoint() const
|
||||
{
|
||||
QPointF p = pos() + output_connector_->pos();
|
||||
QPointF p = output_connector_->scenePos();
|
||||
QRectF r = output_connector_->boundingRect();
|
||||
|
||||
switch (flow_dir_) {
|
||||
@@ -563,15 +590,10 @@ void NodeViewItem::UpdateInputConnectors()
|
||||
|
||||
input_connectors_.resize(node_inputs_.size());
|
||||
for (size_t i=old_sz; i<input_connectors_.size(); i++) {
|
||||
input_connectors_[i] = std::make_unique<NodeViewItemConnector>(this);
|
||||
input_connectors_[i] = std::make_unique<NodeViewItemConnector>(false, this);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeViewItem::ClearInputConnectors()
|
||||
{
|
||||
input_connectors_.clear();
|
||||
}
|
||||
|
||||
void NodeViewItem::UpdateConnectorPositions()
|
||||
{
|
||||
UpdateInputConnectorPositions();
|
||||
@@ -627,17 +649,14 @@ NodeViewCommon::FlowDirection NodeViewItem::GetFlowDirectionForInput(int index)
|
||||
if (!expanded_ || NodeViewCommon::IsFlowHorizontal(flow_dir_)) {
|
||||
return flow_dir_;
|
||||
} else {
|
||||
foreach (NodeViewEdge *edge, edges_) {
|
||||
if (edge->input().input() == node_inputs_.at(index)) {
|
||||
if (edge->from_item()->x() < this->x()) {
|
||||
NodeViewEdge *edge = GetEdgeFromInputIndex(index);
|
||||
|
||||
if (!edge || edge->from_item()->x() < this->x()) {
|
||||
return NodeViewCommon::kLeftToRight;
|
||||
} else {
|
||||
return NodeViewCommon::kRightToLeft;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NodeViewCommon::kLeftToRight;
|
||||
}
|
||||
}
|
||||
|
||||
void NodeViewItem::NodeAppearanceChanged()
|
||||
|
||||
@@ -127,13 +127,10 @@ public:
|
||||
return prevent_removing_;
|
||||
}
|
||||
|
||||
QPolygonF GetOutputTriangle() const
|
||||
{
|
||||
return output_connector_->polygon();
|
||||
}
|
||||
|
||||
void SetLabelAsOutput(bool e);
|
||||
|
||||
NodeViewEdge *GetEdgeFromInputConnector(NodeViewItemConnector *connector);
|
||||
|
||||
protected:
|
||||
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
|
||||
|
||||
@@ -151,6 +148,8 @@ private:
|
||||
|
||||
void DrawNodeTitle(QPainter *painter, QString text, const QRectF &rect, Qt::Alignment vertical_align, int icon_size, bool draw_arrow);
|
||||
|
||||
NodeViewEdge *GetEdgeFromInputIndex(int index);
|
||||
|
||||
/**
|
||||
* @brief Returns local rect of a NodeInput in array node_inputs_[index]
|
||||
*/
|
||||
@@ -163,8 +162,6 @@ private:
|
||||
|
||||
void UpdateInputConnectors();
|
||||
|
||||
void ClearInputConnectors();
|
||||
|
||||
void UpdateConnectorPositions();
|
||||
|
||||
void UpdateInputConnectorPositions();
|
||||
|
||||
@@ -29,8 +29,9 @@
|
||||
|
||||
namespace olive {
|
||||
|
||||
NodeViewItemConnector::NodeViewItemConnector(QGraphicsItem *parent) :
|
||||
QGraphicsPolygonItem(parent)
|
||||
NodeViewItemConnector::NodeViewItemConnector(bool is_output, QGraphicsItem *parent) :
|
||||
QGraphicsPolygonItem(parent),
|
||||
output_(is_output)
|
||||
{
|
||||
QColor c = qApp->palette().text().color();
|
||||
setPen(QPen(c, NodeViewItem::DefaultItemBorder()));
|
||||
|
||||
@@ -30,9 +30,18 @@ namespace olive {
|
||||
class NodeViewItemConnector : public QGraphicsPolygonItem
|
||||
{
|
||||
public:
|
||||
NodeViewItemConnector(QGraphicsItem *parent = nullptr);
|
||||
NodeViewItemConnector(bool is_output, QGraphicsItem *parent = nullptr);
|
||||
|
||||
void SetFlowDirection(NodeViewCommon::FlowDirection dir);
|
||||
|
||||
bool IsOutput() const
|
||||
{
|
||||
return output_;
|
||||
}
|
||||
|
||||
private:
|
||||
bool output_;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user