nodeview: prelim work towards show all functionality

This commit is contained in:
itsmattkc
2021-07-16 20:30:46 -07:00
parent a341fb1a1a
commit 07c841f76d
2 changed files with 106 additions and 102 deletions
+105 -101
View File
@@ -101,7 +101,7 @@ void NodeView::SetGraph(NodeGraph *graph, const QVector<Node*> &nodes)
if (graph_changed) {
if (graph_) {
// Disconnect from current graph
disconnect(graph_, &NodeGraph::NodeAdded, this, &NodeView::AddNode);
//disconnect(graph_, &NodeGraph::NodeAdded, this, &NodeView::AddNode);
disconnect(graph_, &NodeGraph::NodeRemoved, this, &NodeView::RemoveNode);
disconnect(graph_, &NodeGraph::InputConnected, this, &NodeView::AddEdge);
disconnect(graph_, &NodeGraph::InputDisconnected, this, &NodeView::RemoveEdge);
@@ -113,7 +113,7 @@ void NodeView::SetGraph(NodeGraph *graph, const QVector<Node*> &nodes)
if (graph_) {
// Connect to new graph
connect(graph_, &NodeGraph::NodeAdded, this, &NodeView::AddNode);
//connect(graph_, &NodeGraph::NodeAdded, this, &NodeView::AddNode);
connect(graph_, &NodeGraph::NodeRemoved, this, &NodeView::RemoveNode);
connect(graph_, &NodeGraph::InputConnected, this, &NodeView::AddEdge);
connect(graph_, &NodeGraph::InputDisconnected, this, &NodeView::RemoveEdge);
@@ -122,47 +122,50 @@ void NodeView::SetGraph(NodeGraph *graph, const QVector<Node*> &nodes)
}
}
if (context_changed) {
if (context_changed && filter_mode_ == kFilterShowSelective) {
filter_nodes_ = nodes;
}
if (refresh_required && nodes_visible) {
if (filter_mode_ == kFilterShowAll) {
/* = WIP =
for (auto it=graph_->GetPositionMap().cbegin(); it!=graph_->GetPositionMap().cend(); it++) {
// Determine which contexts in the graph have no outputs, these are considered "root-level"
filter_nodes_.clear();
for (auto it=graph->GetPositionMap().cbegin(); it!=graph->GetPositionMap().cend(); it++) {
Node *context = it.key();
const NodeGraph::PositionMap &map = it.value();
for (auto jt=map.cbegin(); jt!=map.cend(); jt++) {
if (context->output_connections().empty()) {
filter_nodes_.append(context);
}
}*/
} else {
// Reserve an arbitrary number to reduce the amount of reallocations
qreal last_offset = 0;
int additional_spacing = 0;
}
}
foreach (Node *n, filter_nodes_) {
const NodeGraph::PositionMap &map = graph_->GetNodesForContext(n);
// Standard root-level positioning code
qreal last_offset = 0;
int additional_spacing = 0;
// First determine the total "height" of this graph and how much we need to offset it
qreal top = 0;
qreal bottom = 0;
for (auto it=map.cbegin(); it!=map.cend(); it++) {
const QPointF &node_pos_in_context = it.value();
top = qMin(node_pos_in_context.y(), top);
bottom = qMax(node_pos_in_context.y(), bottom);
}
// Contexts may be added to this later, so to ensure we only process the root-level nodes we
// found above, we'll store the current size and stop iterating after that
int sz = filter_nodes_.size();
for (int i=0; i<sz; i++) {
Node *n = filter_nodes_.at(i);
const NodeGraph::PositionMap &map = graph_->GetNodesForContext(n);
last_offset += (additional_spacing + (bottom - top));
additional_spacing = 1;
context_offsets_.insert(n, QPointF(0, last_offset));
// First determine the total "height" of this graph and how much we need to offset it
qreal top = 0;
qreal bottom = 0;
for (auto it=map.cbegin(); it!=map.cend(); it++) {
const QPointF &node_pos_in_context = it.value();
top = qMin(node_pos_in_context.y(), top);
bottom = qMax(node_pos_in_context.y(), bottom);
}
// Finally add all nodes
for (auto it=map.cbegin(); it!=map.cend(); it++) {
AddNodePosition(it.key(), n);
}
last_offset += (additional_spacing + (bottom - top));
additional_spacing = 1;
context_offsets_.insert(n, QPointF(0, last_offset));
// Finally add all nodes
for (auto it=map.cbegin(); it!=map.cend(); it++) {
AddNodePosition(it.key(), n);
}
}
@@ -994,13 +997,9 @@ void NodeView::ShowContextMenu(const QPoint &pos)
Menu* filter_menu = new Menu(tr("Filter"), &m);
m.addMenu(filter_menu);
filter_menu->AddActionWithData(tr("Show All Nodes"),
kFilterShowAll,
filter_mode_);
filter_menu->AddActionWithData(tr("Show All Nodes"), kFilterShowAll, filter_mode_);
filter_menu->AddActionWithData(tr("Show Selected"),
kFilterShowSelective,
filter_mode_);
filter_menu->AddActionWithData(tr("Show Selected"), kFilterShowSelective, filter_mode_);
connect(filter_menu, &Menu::triggered, this, &NodeView::ContextMenuFilterChanged);
@@ -1098,12 +1097,15 @@ void NodeView::OpenSelectedNodeInViewer()
}
}
void NodeView::AddNode(Node *node)
{
if (filter_mode_ == kFilterShowAll) {
scene_.AddNode(node);
}
}
// Commenting out because there shouldn't be any situations where a node would be added without
// being in a context. We're keeping RemoveNode as a fail-safe because it could provide crash
// resistance where RemoveNodePosition might be missed.
//void NodeView::AddNode(Node *node)
//{
// if (filter_mode_ == kFilterShowAll) {
// scene_.AddNode(node);
// }
//}
void NodeView::RemoveNode(Node *node)
{
@@ -1112,15 +1114,11 @@ void NodeView::RemoveNode(Node *node)
void NodeView::AddEdge(const NodeOutput &output, const NodeInput &input)
{
if (filter_mode_ == kFilterShowAll) {
scene_.AddEdge(output, input);
} else if (filter_mode_ == kFilterShowSelective) {
Node *output_node = output.node();
Node *input_node = input.node();
Node *output_node = output.node();
Node *input_node = input.node();
if (scene_.item_map().contains(output_node) && scene_.item_map().contains(input_node)) {
scene_.AddEdge(output, input);
}
if (scene_.item_map().contains(output_node) && scene_.item_map().contains(input_node)) {
scene_.AddEdge(output, input);
}
}
@@ -1131,74 +1129,80 @@ void NodeView::RemoveEdge(const NodeOutput &output, const NodeInput &input)
void NodeView::AddNodePosition(Node *node, Node *relative)
{
if (filter_mode_ == kFilterShowSelective) {
if (filter_nodes_.contains(relative)) {
// Get UI item or create if it doesn't exist
NodeViewItem *item = scene_.item_map().value(node);
if (!item) {
item = scene_.AddNode(node);
if (filter_nodes_.contains(relative)) {
// Get UI item or create if it doesn't exist
NodeViewItem *item = scene_.item_map().value(node);
if (!item) {
item = scene_.AddNode(node);
for (auto it=node->input_connections().cbegin(); it!=node->input_connections().cend(); it++) {
if (scene_.item_map().contains(it->second.node())) {
scene_.AddEdge(it->second, it->first);
}
}
for (auto it=node->output_connections().cbegin(); it!=node->output_connections().cend(); it++) {
if (scene_.item_map().contains(it->second.node())) {
scene_.AddEdge(it->first, it->second);
}
for (auto it=node->input_connections().cbegin(); it!=node->input_connections().cend(); it++) {
if (scene_.item_map().contains(it->second.node())) {
scene_.AddEdge(it->second, it->first);
}
}
// Determine "view" position by averaging the Y value and "min"ing the X value of all contexts
QPointF item_pos(DBL_MAX, 0.0);
int average_count = 0;
foreach (Node *context, filter_nodes_) {
if (graph_->GetNodesForContext(context).contains(node)) {
QPointF this_context_pos = graph_->GetNodePosition(node, context);
this_context_pos += context_offsets_.value(context);
item_pos.setX(qMin(item_pos.x(), this_context_pos.x()));
item_pos.setY(item_pos.y() + this_context_pos.y());
average_count++;
for (auto it=node->output_connections().cbegin(); it!=node->output_connections().cend(); it++) {
if (scene_.item_map().contains(it->second.node())) {
scene_.AddEdge(it->first, it->second);
}
}
item_pos.setY(item_pos.y() / average_count);
}
// Set position
item->SetNodePosition(item_pos);
positions_.insert(item, {node, item_pos});
// Determine "view" position by averaging the Y value and "min"ing the X value of all contexts
QPointF item_pos(DBL_MAX, 0.0);
int average_count = 0;
foreach (Node *context, filter_nodes_) {
if (graph_->GetNodesForContext(context).contains(node)) {
QPointF this_context_pos = graph_->GetNodePosition(node, context);
this_context_pos += context_offsets_.value(context);
item_pos.setX(qMin(item_pos.x(), this_context_pos.x()));
item_pos.setY(item_pos.y() + this_context_pos.y());
average_count++;
}
}
item_pos.setY(item_pos.y() / average_count);
// Set position
item->SetNodePosition(item_pos);
positions_.insert(item, {node, item_pos});
// For "show all" mode, we recursively add more nodes to the graph
if (filter_mode_ == kFilterShowAll && !filter_nodes_.contains(node) && graph_->GetPositionMap().contains(node)) {
filter_nodes_.append(node);
context_offsets_.insert(node, item_pos);
const NodeGraph::PositionMap &map = graph_->GetNodesForContext(node);
for (auto it=map.cbegin(); it!=map.cend(); it++) {
AddNodePosition(it.key(), node);
}
}
}
}
void NodeView::RemoveNodePosition(Node *node, Node *relative)
{
if (filter_mode_ == kFilterShowSelective) {
if (filter_nodes_.contains(relative)) {
NodeViewItem *item = scene_.item_map().value(node);
if (filter_nodes_.contains(relative)) {
NodeViewItem *item = scene_.item_map().value(node);
if (item && !item->GetPreventRemoving()) {
// Determine if any other contexts have this node
bool found = false;
if (item && !item->GetPreventRemoving()) {
// Determine if any other contexts have this node
bool found = false;
foreach (Node *context, filter_nodes_) {
if (graph_->ContextContainsNode(node, context)) {
found = true;
break;
}
foreach (Node *context, filter_nodes_) {
if (graph_->ContextContainsNode(node, context)) {
found = true;
break;
}
}
if (!found) {
foreach (const Node::OutputConnection &oc, node->output_connections()) {
scene_.RemoveEdge(oc.first, oc.second);
}
for (auto it=node->input_connections().cbegin(); it!=node->input_connections().cend(); it++) {
scene_.RemoveEdge(it->second, it->first);
}
positions_.remove(item);
scene_.RemoveNode(node);
if (!found) {
foreach (const Node::OutputConnection &oc, node->output_connections()) {
scene_.RemoveEdge(oc.first, oc.second);
}
for (auto it=node->input_connections().cbegin(); it!=node->input_connections().cend(); it++) {
scene_.RemoveEdge(it->second, it->first);
}
positions_.remove(item);
scene_.RemoveNode(node);
}
}
}
+1 -1
View File
@@ -268,7 +268,7 @@ private slots:
*/
void OpenSelectedNodeInViewer();
void AddNode(Node *node);
//void AddNode(Node *node);
void RemoveNode(Node *node);
void AddEdge(const NodeOutput& output, const NodeInput& input);
void RemoveEdge(const NodeOutput& output, const NodeInput& input);