implemented node groups

This commit is contained in:
itsmattkc
2021-11-24 17:58:48 -08:00
parent a94c7169f2
commit 495b07fc55
29 changed files with 947 additions and 203 deletions
+87 -9
View File
@@ -21,16 +21,18 @@
#include "nodeview.h"
#include <QInputDialog>
#include <QMessageBox>
#include <QMouseEvent>
#include <QScrollBar>
#include <QToolTip>
#include "core.h"
#include "dialog/nodegroup/nodegroupdialog.h"
#include "nodeviewundo.h"
#include "node/audio/volume/volume.h"
#include "node/distort/transform/transformdistortnode.h"
#include "node/factory.h"
#include "node/group.h"
#include "node/group/group.h"
#include "node/traverser.h"
#include "widget/menu/menushared.h"
#include "widget/timebased/timebasedview.h"
@@ -638,6 +640,7 @@ void NodeView::UpdateSelectionCache()
if (current_selection.isEmpty()) {
// All nodes that were selected have been deselected, so we'll just set them all to `deselected`
deselected = selected_nodes_;
selected_nodes_.clear();
} else {
foreach (Node* n, selected_nodes_) {
bool still_selected = false;
@@ -649,20 +652,20 @@ void NodeView::UpdateSelectionCache()
}
}
if (still_selected) {
if (!still_selected) {
deselected.append(n);
selected_nodes_.removeOne(n);
}
}
}
if (!selected.isEmpty()) {
emit NodesSelected(selected);
}
if (!deselected.isEmpty()) {
emit NodesDeselected(deselected);
}
if (!selected.isEmpty()) {
emit NodesSelected(selected);
}
}
void NodeView::ShowContextMenu(const QPoint &pos)
@@ -1082,13 +1085,88 @@ void NodeView::PositionNewEdge(const QPoint &pos)
void NodeView::GroupNodes()
{
/*NodeGroup *group = new NodeGroup();
selected_nodes_*/
// Get items
QVector<NodeViewItem*> items = scene_.GetSelectedItems();
if (items.isEmpty()) {
return;
}
// Get node context
Node *context = items.first()->GetContext();
QPointF avg_pos = items.first()->GetNodePosition();
for (int i=1; i<items.size(); i++) {
if (items.at(i)->GetContext() != context) {
QMessageBox::critical(this, tr("Failed to group nodes"), tr("Nodes can only be grouped if they're in the same context."));
return;
}
avg_pos += items.at(i)->GetNodePosition();
}
avg_pos /= items.size();
// Create group
NodeGroup *group = new NodeGroup();
// Add group to graph and context
MultiUndoCommand *command = new MultiUndoCommand();
command->add_child(new NodeAddCommand(context->parent(), group));
command->add_child(new NodeSetPositionCommand(group, context, avg_pos));
// Add nodes to group
QVector<Node*> nodes_to_group = selected_nodes_;
DeselectAll();
foreach (Node *n, nodes_to_group) {
for (auto it=n->input_connections().cbegin(); it!=n->input_connections().cend(); it++) {
Node *output = it->second;
const NodeInput &input = it->first;
if (!nodes_to_group.contains(output)) {
command->add_child(new NodeEdgeRemoveCommand(output, input));
command->add_child(new NodeEdgeAddCommand(output, NodeInput(group, input.input(), input.element())));
}
}
for (auto it=n->output_connections().cbegin(); it!=n->output_connections().cend(); it++) {
Node *output = it->first;
const NodeInput &input = it->second;
if (!nodes_to_group.contains(input.node())) {
command->add_child(new NodeEdgeRemoveCommand(output, input));
command->add_child(new NodeEdgeAddCommand(group, input));
}
}
command->add_child(new NodeRemovePositionFromContextCommand(n, context));
command->add_child(new NodeAddToGroupCommand(n, group));
command->add_child(new NodeSetPositionCommand(n, group, scene_.context_map().value(context)->GetItemFromMap(n)->GetNodePosition()));
for (auto it=n->inputs().cbegin(); it!=n->inputs().cend(); it++) {
NodeInput input(n, *it, -1);
if (!input.IsConnected() || !nodes_to_group.contains(input.GetConnectedOutput())) {
command->add_child(new NodeGroupAddInputPassthrough(group, input));
}
}
}
// Do command
command->redo_now();
NodeGroupDialog ngd(group, this);
if (ngd.exec() == QDialog::Accepted) {
// Push to stack so it can be undone (MultiUndoCommand will ignore the request to redo again)
Core::instance()->undo_stack()->push(command);
} else {
// Undo command and delete
command->undo_now();
delete command;
}
}
void NodeView::UngroupNodes()
{
//static_cast<NodeGroup*>(selected_nodes_.first());
//NodeGroup *group = static_cast<NodeGroup*>(selected_nodes_.first());
}
void NodeView::PasteNodesInternal(const QVector<Node *> &duplicate_nodes)