further improved new node view

This commit is contained in:
itsmattkc
2021-11-12 11:06:06 -08:00
parent 0c92bc3f08
commit 3c6bc80c8f
7 changed files with 124 additions and 52 deletions
+1 -1
View File
@@ -1535,7 +1535,7 @@ void NodeView::PositionNewEdge(const QPoint &pos)
if (highlight_index >= 0) {
create_edge_dst_input_ = create_edge_dst_->GetInputAtIndex(highlight_index);
create_edge_->SetPoints(create_edge_src_->GetOutputPoint(),
create_edge_dst_->GetInputPoint(create_edge_dst_input_.input(), create_edge_dst_input_.element(), create_edge_src_->pos()),
create_edge_dst_->GetInputPoint(create_edge_dst_input_.input(), create_edge_dst_input_.element()),
true);
} else {
create_edge_dst_input_.Reset();
+10
View File
@@ -44,6 +44,16 @@ public:
}
}
static bool IsFlowVertical(FlowDirection dir)
{
return dir == kTopToBottom || dir == kBottomToTop;
}
static bool IsFlowHorizontal(FlowDirection dir)
{
return dir == kLeftToRight || dir == kRightToLeft;
}
static bool DirectionsAreOpposing(FlowDirection a, FlowDirection b) {
return ((a == NodeViewCommon::kLeftToRight && b == NodeViewCommon::kRightToLeft)
|| (a == NodeViewCommon::kRightToLeft && b == NodeViewCommon::kLeftToRight)
+15 -4
View File
@@ -3,6 +3,7 @@
#include <QBrush>
#include <QCoreApplication>
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QPen>
#include <QStyleOptionGraphicsItem>
@@ -21,9 +22,6 @@ namespace olive {
NodeViewContext::NodeViewContext(QGraphicsItem *item) :
super(item)
{
setFlag(ItemIsMovable);
setFlag(ItemIsSelectable);
// Set default label text
SetContext(nullptr);
}
@@ -101,10 +99,13 @@ void NodeViewContext::UpdateRect()
QFontMetricsF fm(f);
qreal lbl_offset = GetTextOffset(fm);
QRectF rect = childrenBoundingRect();
QRectF cbr = childrenBoundingRect();
QRectF rect = cbr;
int pad = NodeViewItem::DefaultItemHeight();
rect.adjust(-pad, - lbl_offset*2 - fm.height() - pad, pad, pad);
setRect(rect);
last_titlebar_height_ = rect.y() + (cbr.y() - rect.y());
}
void NodeViewContext::SetFlowDirection(NodeViewCommon::FlowDirection dir)
@@ -164,6 +165,16 @@ QVariant NodeViewContext::itemChange(GraphicsItemChange change, const QVariant &
return super::itemChange(change, value);
}
void NodeViewContext::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
bool clicked_inside_titlebar = (event->pos().y() < last_titlebar_height_);
setFlag(ItemIsMovable, clicked_inside_titlebar);
setFlag(ItemIsSelectable, clicked_inside_titlebar);
super::mousePressEvent(event);
}
NodeViewEdge* NodeViewContext::AddEdgeInternal(Node *output, const NodeInput& input, NodeViewItem *from, NodeViewItem *to)
{
NodeViewEdge* edge_ui = new NodeViewEdge(output, input, from, to, this);
+4
View File
@@ -30,6 +30,8 @@ public:
protected:
virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) override;
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
private:
NodeViewEdge *AddEdgeInternal(Node *output, const NodeInput& input, NodeViewItem *from, NodeViewItem *to);
@@ -41,6 +43,8 @@ private:
bool curved_edges_;
int last_titlebar_height_;
};
}
+1 -1
View File
@@ -60,7 +60,7 @@ void NodeViewEdge::Adjust()
{
// Draw a line between the two
SetPoints(from_item()->GetOutputPoint(),
to_item()->GetInputPoint(input_.input(), input_.element(), from_item()->pos()),
to_item()->GetInputPoint(input_.input(), input_.element()),
to_item()->IsExpanded());
}
+82 -39
View File
@@ -67,7 +67,6 @@ NodeViewItem::NodeViewItem(QGraphicsItem *parent) :
title_bar_rect_ = QRectF(-widget_width/2, -widget_height/2, widget_width, widget_height);
setRect(title_bar_rect_);
input_connector_ = new NodeViewItemConnector(this);
output_connector_ = new NodeViewItemConnector(this);
}
@@ -219,6 +218,8 @@ void NodeViewItem::SetNode(Node *n)
node_inputs_.clear();
ClearInputConnectors();
if (node_) {
node_->Retranslate();
@@ -228,7 +229,7 @@ void NodeViewItem::SetNode(Node *n)
}
}
input_connector_->setVisible(!node_inputs_.isEmpty());
UpdateInputConnectors();
connect(n, &Node::LabelChanged, this, &NodeViewItem::NodeAppearanceChanged);
connect(n, &Node::ColorChanged, this, &NodeViewItem::NodeAppearanceChanged);
@@ -246,7 +247,6 @@ void NodeViewItem::SetExpanded(bool e, bool hide_titlebar)
expanded_ = e;
hide_titlebar_ = hide_titlebar;
input_connector_->setVisible(!expanded_);
if (expanded_ && !node_inputs_.isEmpty()) {
// Create new rect
@@ -263,13 +263,15 @@ void NodeViewItem::SetExpanded(bool e, bool hide_titlebar)
setRect(title_bar_rect_);
}
update();
UpdateInputConnectorFlowDirections();
UpdateConnectorPositions();
ReadjustAllEdges();
UpdateContextRect();
update();
}
void NodeViewItem::ToggleExpanded()
@@ -403,6 +405,8 @@ QVariant NodeViewItem::itemChange(QGraphicsItem::GraphicsItemChange change, cons
void NodeViewItem::ReadjustAllEdges()
{
UpdateInputConnectorFlowDirections();
UpdateInputConnectorPositions();
foreach (NodeViewEdge* edge, edges_) {
edge->Adjust();
}
@@ -502,13 +506,15 @@ QRectF NodeViewItem::GetInputRect(int index) const
return r;
}
QPointF NodeViewItem::GetInputPoint(const QString &input, int element, const QPointF& source_pos) const
QPointF NodeViewItem::GetInputPoint(const QString &input, int element) const
{
if (expanded_) {
return pos() + GetInputPointInternal(node_inputs_.indexOf(input), source_pos);
} else {
return pos() + input_connector_->pos();
int index = node_inputs_.indexOf(input);
if (index < 0 || index >= int(input_connectors_.size())) {
return QPointF();
}
return pos() + input_connectors_[index]->pos();
}
QPointF NodeViewItem::GetOutputPoint() const
@@ -539,64 +545,101 @@ void NodeViewItem::SetFlowDirection(NodeViewCommon::FlowDirection dir)
{
flow_dir_ = dir;
input_connector_->SetFlowDirection(dir);
UpdateInputConnectorFlowDirections();
output_connector_->SetFlowDirection(dir);
UpdateConnectorPositions();
UpdateNodePosition();
}
QPointF NodeViewItem::GetInputPointInternal(int index, const QPointF& source_pos) const
{
QRectF input_rect = GetInputRect(index);
Qt::Orientation flow_orientation = NodeViewCommon::GetFlowOrientation(flow_dir_);
if (flow_orientation == Qt::Horizontal || IsExpanded()) {
if (flow_dir_ == NodeViewCommon::kLeftToRight
|| (flow_orientation == Qt::Vertical && source_pos.x() < pos().x())) {
return QPointF(input_rect.left(), input_rect.center().y());
} else {
return QPointF(input_rect.right(), input_rect.center().y());
}
} else {
if (flow_dir_ == NodeViewCommon::kTopToBottom) {
return QPointF(input_rect.center().x(), input_rect.top());
} else {
return QPointF(input_rect.center().x(), input_rect.bottom());
}
}
}
void NodeViewItem::UpdateNodePosition()
{
setPos(NodeToScreenPoint(cached_node_pos_, flow_dir_));
}
void NodeViewItem::UpdateInputConnectors()
{
int old_sz = input_connectors_.size();
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);
}
}
void NodeViewItem::ClearInputConnectors()
{
input_connectors_.clear();
}
void NodeViewItem::UpdateConnectorPositions()
{
QRectF output_rect = output_connector_->boundingRect();
UpdateInputConnectorPositions();
switch (flow_dir_) {
case NodeViewCommon::kLeftToRight:
input_connector_->setPos(rect().left() - output_rect.width(), rect().center().y());
output_connector_->setPos(rect().right(), rect().center().y());
output_connector_->setPos(rect().right(), title_bar_rect_.center().y());
break;
case NodeViewCommon::kRightToLeft:
input_connector_->setPos(rect().right() + output_rect.width(), rect().center().y());
output_connector_->setPos(rect().left(), rect().center().y());
output_connector_->setPos(rect().left(), title_bar_rect_.center().y());
break;
case NodeViewCommon::kTopToBottom:
input_connector_->setPos(rect().center().x(), rect().top() - output_rect.height());
output_connector_->setPos(rect().center().x(), rect().bottom());
break;
case NodeViewCommon::kBottomToTop:
input_connector_->setPos(rect().center().x(), rect().bottom() + output_rect.height());
output_connector_->setPos(rect().center().x(), rect().top());
break;
}
}
void NodeViewItem::UpdateInputConnectorPositions()
{
QRectF output_rect = output_connector_->boundingRect();
// Input connector flow directions change conditionally
for (size_t i=0; i<input_connectors_.size(); i++) {
switch (GetFlowDirectionForInput(i)) {
case NodeViewCommon::kLeftToRight:
input_connectors_[i]->setPos(rect().left() - output_rect.width(), GetInputRect(i).center().y());
break;
case NodeViewCommon::kRightToLeft:
input_connectors_[i]->setPos(rect().right() + output_rect.width(), GetInputRect(i).center().y());
break;
case NodeViewCommon::kTopToBottom:
input_connectors_[i]->setPos(rect().center().x(), rect().top() - output_rect.height());
break;
case NodeViewCommon::kBottomToTop:
input_connectors_[i]->setPos(rect().center().x(), rect().bottom() + output_rect.height());
break;
}
}
}
void NodeViewItem::UpdateInputConnectorFlowDirections()
{
for (size_t i=0; i<input_connectors_.size(); i++) {
input_connectors_[i]->SetFlowDirection(GetFlowDirectionForInput(i));
}
}
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()) {
return NodeViewCommon::kLeftToRight;
} else {
return NodeViewCommon::kRightToLeft;
}
}
}
return NodeViewCommon::kLeftToRight;
}
}
void NodeViewItem::NodeAppearanceChanged()
{
update();
+11 -7
View File
@@ -80,7 +80,7 @@ public:
/**
* @brief Returns GLOBAL point that edges should connect to for any NodeParam member of this object
*/
QPointF GetInputPoint(const QString& input, int element, const QPointF &source_pos) const;
QPointF GetInputPoint(const QString& input, int element) const;
QPointF GetOutputPoint() const;
@@ -156,18 +156,22 @@ private:
*/
QRectF GetInputRect(int index) const;
/**
* @brief Returns local point that edges should connect to for a NodeInput in array node_inputs_[index]
*/
QPointF GetInputPointInternal(int index, const QPointF &source_pos) const;
/**
* @brief Internal update function when logical position changes
*/
void UpdateNodePosition();
void UpdateInputConnectors();
void ClearInputConnectors();
void UpdateConnectorPositions();
void UpdateInputConnectorPositions();
void UpdateInputConnectorFlowDirections();
NodeViewCommon::FlowDirection GetFlowDirectionForInput(int index);
/**
* @brief Reference to attached Node
*/
@@ -203,7 +207,7 @@ private:
bool prevent_removing_;
NodeViewItemConnector *input_connector_;
std::vector<std::unique_ptr<NodeViewItemConnector> > input_connectors_;
NodeViewItemConnector *output_connector_;
bool label_as_output_;