initial commit

This commit is contained in:
itsmattkc
2021-05-16 09:58:57 +10:00
parent a675e0ccbb
commit 8e9859b2b3
21 changed files with 439 additions and 248 deletions
+12
View File
@@ -75,6 +75,18 @@ void NodeGraph::childEvent(QChildEvent *event)
emit NodeRemoved(node);
emit node->RemovedFromGraph(this);
for (auto it=position_map_.begin(); it!=position_map_.end(); it++) {
PositionMap &map = it.value();
for (auto jt=map.begin(); jt!=map.end(); ) {
if (jt.key() == node) {
jt = map.erase(jt);
emit NodePositionRemoved(node, it.key());
} else {
jt++;
}
}
}
}
}
}
+41
View File
@@ -63,6 +63,39 @@ public:
return default_nodes_;
}
bool NodeMapContainsNode(Node* node, void* relative) const
{
return position_map_.value(relative).contains(node);
}
QPointF GetNodePosition(Node* node, void* relative)
{
return position_map_.value(relative).value(node);
}
void SetNodePosition(Node* node, void* relative, const QPointF& pos)
{
position_map_[relative].insert(node, pos);
emit NodePositionAdded(node, relative, pos);
}
void RemoveNodePosition(Node* node, void* relative)
{
PositionMap& map = position_map_[relative];
map.remove(node);
if (map.isEmpty()) {
position_map_.remove(relative);
}
emit NodePositionRemoved(node, relative);;
}
using PositionMap = QMap<Node*, QPointF>;
const PositionMap &GetNodesForRelative(void *relative)
{
return position_map_[relative];
}
signals:
/**
* @brief Signal emitted when a Node is added to the graph
@@ -80,6 +113,10 @@ signals:
void ValueChanged(const NodeInput& input);
void NodePositionAdded(Node *node, void *relative, const QPointF &position);
void NodePositionRemoved(Node *node, void *relative);
protected:
void AddDefaultNode(Node* n)
{
@@ -93,6 +130,10 @@ private:
QVector<Node*> default_nodes_;
QMap<void *, PositionMap> position_map_;
PositionMap root_position_map_;
};
}
+68 -48
View File
@@ -91,20 +91,6 @@ void Node::Load(QXmlStreamReader *reader, XMLNodeData& xml_node_data, uint versi
LoadInput(reader, xml_node_data, cancelled);
} else if (reader->name() == QStringLiteral("ptr")) {
xml_node_data.node_ptrs.insert(reader->readElementText().toULongLong(), this);
} else if (reader->name() == QStringLiteral("pos")) {
QPointF p;
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("x")) {
p.setX(reader->readElementText().toDouble());
} else if (reader->name() == QStringLiteral("y")) {
p.setY(reader->readElementText().toDouble());
} else {
reader->skipCurrentElement();
}
}
SetPosition(p);
} else if (reader->name() == QStringLiteral("label")) {
SetLabel(reader->readElementText());
} else if (reader->name() == QStringLiteral("color")) {
@@ -166,11 +152,6 @@ void Node::Save(QXmlStreamWriter *writer) const
{
writer->writeTextElement(QStringLiteral("ptr"), QString::number(reinterpret_cast<quintptr>(this)));
writer->writeStartElement(QStringLiteral("pos"));
writer->writeTextElement(QStringLiteral("x"), QString::number(GetPosition().x()));
writer->writeTextElement(QStringLiteral("y"), QString::number(GetPosition().y()));
writer->writeEndElement(); // pos
writer->writeTextElement(QStringLiteral("label"), GetLabel());
writer->writeTextElement(QStringLiteral("color"), QString::number(override_color_));
@@ -1483,7 +1464,6 @@ void Node::CopyInputs(const Node *source, Node *destination, bool include_connec
CopyInput(source, destination, input, include_connections, true);
}
destination->SetPosition(source->GetPosition());
destination->SetLabel(source->GetLabel());
destination->SetOverrideColor(source->GetOverrideColor());
}
@@ -1832,29 +1812,6 @@ QVariant Node::PtrToValue(void *ptr)
return reinterpret_cast<quintptr>(ptr);
}
const QPointF &Node::GetPosition() const
{
return position_;
}
void Node::SetPosition(const QPointF &pos, bool move_dependencies_relatively_too)
{
QPointF old_pos = position_;
position_ = pos;
emit PositionChanged(position_);
if (move_dependencies_relatively_too) {
QPointF difference = pos - old_pos;
for (auto it=input_connections_.cbegin(); it!=input_connections_.cend(); it++) {
Node* c = it->second.node();
c->SetPosition(c->GetPosition() + difference, true);
}
}
}
void Node::ParameterValueChanged(const QString& input, int element, const TimeRange& range)
{
UpdateLastChangedTime();
@@ -2303,7 +2260,7 @@ void NodeSetPositionAndShiftSurroundingsCommand::redo()
{
if (commands_.isEmpty()) {
// Move first node
NodeSetPositionCommand* set_pos_command = new NodeSetPositionCommand(node_, position_, move_dependencies_);
NodeSetPositionCommand* set_pos_command = new NodeSetPositionCommand(node_, relative_, position_, move_dependencies_);
set_pos_command->redo();
commands_.append(set_pos_command);
@@ -2312,18 +2269,19 @@ void NodeSetPositionAndShiftSurroundingsCommand::redo()
// Start moving other nodes
foreach (Node* surrounding, node_->parent()->nodes()) {
if (bounding_rect.contains(surrounding->GetPosition()) && surrounding != node_) {
QPointF new_pos = surrounding->GetPosition();
QPointF surrounding_position = node_->parent()->GetNodePosition(surrounding, relative_);
if (bounding_rect.contains(surrounding_position) && surrounding != node_) {
QPointF new_pos = surrounding_position;
qreal move_rate = 0.50;
if (surrounding->GetPosition().y() < position_.y()) {
if (surrounding_position.y() < position_.y()) {
move_rate = -move_rate;
}
new_pos.setY(new_pos.y() + move_rate);
auto sur_command = new NodeSetPositionAndShiftSurroundingsCommand(surrounding, new_pos, true);
auto sur_command = new NodeSetPositionAndShiftSurroundingsCommand(surrounding, relative_, new_pos, true);
sur_command->redo();
commands_.append(sur_command);
}
@@ -2335,4 +2293,66 @@ void NodeSetPositionAndShiftSurroundingsCommand::redo()
}
}
void NodeSetPositionCommand::redo()
{
NodeGraph* graph = node_->parent();
if (!(added_ = !graph->NodeMapContainsNode(node_, relevant_))) {
old_pos_ = graph->GetNodePosition(node_, relevant_);
}
graph->SetNodePosition(node_, relevant_, pos_);
}
void NodeSetPositionCommand::undo()
{
NodeGraph* graph = node_->parent();
if (added_) {
graph->RemoveNodePosition(node_, relevant_);
} else {
graph->SetNodePosition(node_, relevant_, old_pos_);
}
}
void NodeSetPositionAsChildCommand::redo()
{
if (!sub_command_) {
// Calculate position of node
NodeGraph *graph = parent_->parent();
QPointF pos = graph->GetNodePosition(parent_, relative_);
// This is a dependency, so we'll place it one X before
pos.setX(pos.x() - 1);
// The Y will be calculated using the index and child count
pos.setY(pos.y() - (double(child_count_)*0.5) + this_index_ + 0.5);
sub_command_ = new MultiUndoCommand();
if (shift_surroundings_) {
if (relative_) {
sub_command_->add_child(new NodeSetPositionAndShiftSurroundingsCommand(node_, relative_, pos, true));
}
sub_command_->add_child(new NodeSetPositionAndShiftSurroundingsCommand(node_, nullptr, pos, true));
} else {
if (relative_) {
sub_command_->add_child(new NodeSetPositionCommand(node_, relative_, pos, true));
}
sub_command_->add_child(new NodeSetPositionCommand(node_, nullptr, pos, true));
}
}
sub_command_->redo();
}
void NodeSetPositionToOffsetOfAnotherNodeCommand::redo()
{
NodeGraph *graph = node_->parent();
old_pos_ = graph->GetNodePosition(node_, relative_);
graph->SetNodePosition(node_, relative_, graph->GetNodePosition(other_node_, relative_) + offset_);
}
void NodeSetPositionToOffsetOfAnotherNodeCommand::undo()
{
NodeGraph *graph = node_->parent();
graph->SetNodePosition(node_, relative_, old_pos_);
}
}
+26 -59
View File
@@ -718,10 +718,6 @@ public:
*/
virtual NodeValueTable Value(const QString &output, NodeValueDatabase& value) const;
const QPointF& GetPosition() const;
void SetPosition(const QPointF& pos, bool move_dependencies_relatively_too = false);
virtual bool HasGizmos() const;
virtual void DrawGizmos(NodeValueDatabase& db, QPainter* p);
@@ -1180,11 +1176,6 @@ private:
*/
bool can_be_deleted_;
/**
* @brief UI position for NodeViews
*/
QPointF position_;
/**
* @brief Custom user label for node
*/
@@ -1312,35 +1303,29 @@ using NodePtr = std::shared_ptr<Node>;
class NodeSetPositionCommand : public UndoCommand
{
public:
NodeSetPositionCommand(Node* node, const QPointF& position, bool move_dependencies_relatively) :
node_(node),
new_pos_(position),
move_deps_(move_dependencies_relatively)
NodeSetPositionCommand(Node* node, void* relevant, const QPointF& pos, bool move_dependencies_relatively)
{
node_ = node;
relevant_ = relevant;
pos_ = pos;
move_deps_ = move_dependencies_relatively;
}
virtual Project * GetRelevantProject() const override
virtual Project* GetRelevantProject() const override
{
return node_->project();
}
virtual void redo() override
{
old_pos_ = node_->GetPosition();
node_->SetPosition(new_pos_, move_deps_);
}
virtual void redo() override;
virtual void undo() override
{
node_->SetPosition(old_pos_, move_deps_);
}
virtual void undo() override;
private:
Node* node_;
QPointF new_pos_;
void* relevant_;
QPointF pos_;
QPointF old_pos_;
bool added_;
bool move_deps_;
};
@@ -1348,8 +1333,9 @@ private:
class NodeSetPositionAndShiftSurroundingsCommand : public UndoCommand
{
public:
NodeSetPositionAndShiftSurroundingsCommand(Node* node, const QPointF& pos, bool move_dependencies_relatively) :
NodeSetPositionAndShiftSurroundingsCommand(Node* node, void *relative, const QPointF& pos, bool move_dependencies_relatively) :
node_(node),
relative_(relative),
position_(pos),
move_dependencies_(move_dependencies_relatively)
{}
@@ -1376,6 +1362,8 @@ public:
private:
Node* node_;
void *relative_;
QPointF position_;
bool move_dependencies_;
@@ -1387,9 +1375,10 @@ private:
class NodeSetPositionAsChildCommand : public UndoCommand
{
public:
NodeSetPositionAsChildCommand(Node* node, Node* parent, int this_index, int child_count, bool shift_surroundings) :
NodeSetPositionAsChildCommand(Node* node, Node* parent, void *relative, int this_index, int child_count, bool shift_surroundings) :
node_(node),
parent_(parent),
relative_(relative),
this_index_(this_index),
child_count_(child_count),
shift_surroundings_(shift_surroundings),
@@ -1407,27 +1396,7 @@ public:
return node_->project();
}
virtual void redo() override
{
if (!sub_command_) {
// Calculate position of node
QPointF pos = parent_->GetPosition();
// This is a dependency, so we'll place it one X before
pos.setX(pos.x() - 1);
// The Y will be calculated using the index and child count
pos.setY(pos.y() - (double(child_count_)*0.5) + this_index_ + 0.5);
if (shift_surroundings_) {
sub_command_ = new NodeSetPositionAndShiftSurroundingsCommand(node_, pos, true);
} else {
sub_command_ = new NodeSetPositionCommand(node_, pos, true);
}
}
sub_command_->redo();
}
virtual void redo() override;
virtual void undo() override
{
@@ -1437,22 +1406,24 @@ public:
private:
Node* node_;
Node* parent_;
void *relative_;
int this_index_;
int child_count_;
bool shift_surroundings_;
UndoCommand* sub_command_;
MultiUndoCommand* sub_command_;
};
class NodeSetPositionToOffsetOfAnotherNodeCommand : public UndoCommand
{
public:
NodeSetPositionToOffsetOfAnotherNodeCommand(Node* node, Node* other_node, const QPointF& offset) :
NodeSetPositionToOffsetOfAnotherNodeCommand(Node* node, Node* other_node, void *relative, const QPointF& offset) :
node_(node),
other_node_(other_node),
relative_(relative),
offset_(offset)
{}
@@ -1461,20 +1432,16 @@ public:
return node_->project();
}
virtual void redo() override
{
node_->SetPosition(other_node_->GetPosition() + offset_);
}
virtual void redo() override;
virtual void undo() override
{
node_->SetPosition(other_node_->GetPosition() - offset_);
}
virtual void undo() override;
private:
Node* node_;
Node* other_node_;
void *relative_;
QPointF offset_;
QPointF old_pos_;
};
+1 -2
View File
@@ -137,9 +137,8 @@ void FolderAddChild::redo()
Node::ConnectEdge(child_, NodeInput(folder_, Folder::kChildInput, array_index));
if (autoposition_) {
old_position_ = child_->GetPosition();
if (!position_command_) {
position_command_ = new NodeSetPositionAsChildCommand(child_, folder_, array_index, array_index+1, true);
position_command_ = new NodeSetPositionAsChildCommand(child_, folder_, folder_->project(), array_index, array_index+1, true);
}
position_command_->redo();
}
-2
View File
@@ -180,8 +180,6 @@ private:
bool autoposition_;
QPointF old_position_;
NodeSetPositionAsChildCommand* position_command_;
};
+3 -2
View File
@@ -42,14 +42,14 @@ Project::Project() :
// Adds a color manager "node" to this project so that it synchronizes
color_manager_ = new ColorManager();
color_manager_->setParent(this);
color_manager_->SetPosition(QPointF(1, 0));
SetNodePosition(color_manager_, this, QPointF(1, 0));
color_manager_->SetCanBeDeleted(false);
AddDefaultNode(color_manager_);
// Same with project settings
settings_ = new ProjectSettingsNode();
settings_->setParent(this);
settings_->SetPosition(QPointF(2, 0));
SetNodePosition(settings_, this, QPointF(2, 0));
settings_->SetCanBeDeleted(false);
AddDefaultNode(settings_);
@@ -58,6 +58,7 @@ Project::Project() :
root_->setParent(this);
root_->SetLabel(tr("Root"));
root_->SetCanBeDeleted(false);
SetNodePosition(root_, this, QPointF(0, 0));
connect(color_manager(), &ColorManager::ValueChanged,
this, &Project::ColorManagerValueChanged);
+7 -16
View File
@@ -40,9 +40,14 @@ public:
return node_view_->GetGraph();
}
void SetGraph(NodeGraph *graph)
void SetGraph(NodeGraph *graph, const QVector<void*> &nodes)
{
node_view_->SetGraph(graph);
node_view_->SetGraph(graph, nodes);
}
void ClearGraph()
{
node_view_->ClearGraph();
}
virtual void SelectAll() override
@@ -106,20 +111,6 @@ public slots:
node_view_->SelectWithDependencies(nodes);
}
void SelectBlocks(const QVector<Block*>& blocks)
{
QVector<Node*> nodes(blocks.size());
memcpy(nodes.data(), blocks.constData(), blocks.size() * sizeof(Block*));
node_view_->SelectWithDependencies(nodes);
}
void DeselectBlocks(const QVector<Block*>& nodes)
{
Q_UNUSED(nodes)
qDebug() << "Stub";
//node_view_->DeselectBlocks(nodes);
}
signals:
void NodesSelected(const QVector<Node*>& nodes);
+5
View File
@@ -89,6 +89,11 @@ public:
void OverwriteFootageAtPlayhead(const QVector<ViewerOutput *> &footage);
const QVector<Block*>& GetSelectedBlocks() const
{
return static_cast<TimelineWidget*>(GetTimeBasedWidget())->GetSelectedBlocks();
}
protected:
virtual void Retranslate() override;
+11
View File
@@ -24,18 +24,29 @@
namespace olive {
MultiUndoCommand::MultiUndoCommand() :
done_(false)
{
}
void MultiUndoCommand::redo()
{
if (!done_) {
for (auto it=children_.cbegin(); it!=children_.cend(); it++) {
(*it)->redo_and_set_modified();
}
done_ = true;
}
}
void MultiUndoCommand::undo()
{
if (done_) {
for (auto it=children_.crbegin(); it!=children_.crend(); it++) {
(*it)->undo_and_set_modified();
}
done_ = false;
}
}
void UndoCommand::redo_and_set_modified()
+3 -1
View File
@@ -71,7 +71,7 @@ private:
class MultiUndoCommand : public UndoCommand
{
public:
MultiUndoCommand() = default;
MultiUndoCommand();
virtual void redo() override;
virtual void undo() override;
@@ -99,6 +99,8 @@ public:
private:
std::vector<UndoCommand*> children_;
bool done_;
};
}
+196 -43
View File
@@ -44,7 +44,8 @@ NodeView::NodeView(QWidget *parent) :
create_edge_(nullptr),
create_edge_dst_(nullptr),
create_edge_dst_temp_expanded_(false),
filter_mode_(kFilterShowSelectedBlocks),
paste_command_(nullptr),
filter_mode_(kFilterShowSelective),
scale_(1.0)
{
setScene(&scene_);
@@ -59,47 +60,44 @@ NodeView::NodeView(QWidget *parent) :
ConnectSelectionChangedSignal();
SetFlowDirection(NodeViewCommon::kTopToBottom);
// Set massive scene rect and hide the scrollbars to create an "infinite space" effect
scene_.setSceneRect(-1000000, -1000000, 2000000, 2000000);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
}
NodeView::~NodeView()
{
// Unset the current graph
SetGraph(nullptr);
ClearGraph();
}
void NodeView::SetGraph(NodeGraph *graph)
void NodeView::SetGraph(NodeGraph *graph, const QVector<void*> &nodes)
{
if (graph_ == graph) {
return;
}
// Handle potentially changing graph
if (graph_ != graph) {
if (graph_) {
disconnect(graph_, &NodeGraph::NodeAdded, &scene_, &NodeViewScene::AddNode);
disconnect(graph_, &NodeGraph::NodeRemoved, &scene_, &NodeViewScene::RemoveNode);
disconnect(graph_, &NodeGraph::InputConnected, &scene_, &NodeViewScene::AddEdge);
disconnect(graph_, &NodeGraph::InputDisconnected, &scene_, &NodeViewScene::RemoveEdge);
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);
disconnect(graph_, &NodeGraph::NodePositionAdded, this, &NodeView::AddNodePosition);
disconnect(graph_, &NodeGraph::NodePositionRemoved, this, &NodeView::RemoveNodePosition);
if (filter_mode_ == kFilterShowAll) {
// Switching graphs, close all nodes
DeselectAll();
// Clear the scene of all UI objects
scene_.clear();
}
}
// Set reference to the graph
graph_ = graph;
// If the graph is valid, add UI objects for each of its Nodes
if (graph_) {
connect(graph_, &NodeGraph::NodeAdded, &scene_, &NodeViewScene::AddNode);
connect(graph_, &NodeGraph::NodeRemoved, &scene_, &NodeViewScene::RemoveNode);
connect(graph_, &NodeGraph::InputConnected, &scene_, &NodeViewScene::AddEdge);
connect(graph_, &NodeGraph::InputDisconnected, &scene_, &NodeViewScene::RemoveEdge);
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);
connect(graph_, &NodeGraph::NodePositionAdded, this, &NodeView::AddNodePosition);
connect(graph_, &NodeGraph::NodePositionRemoved, this, &NodeView::RemoveNodePosition);
if (filter_mode_ == kFilterShowAll) {
foreach (Node* n, graph_->nodes()) {
scene_.AddNode(n);
}
@@ -110,6 +108,30 @@ void NodeView::SetGraph(NodeGraph *graph)
}
}
}
}
}
// Handle changing nodes
if (filter_nodes_ != nodes) {
DeselectAll();
scene_.clear();
filter_nodes_ = nodes;
foreach (void *n, filter_nodes_) {
const NodeGraph::PositionMap &map = graph_->GetNodesForRelative(n);
for (auto it=map.cbegin(); it!=map.cend(); it++) {
NodeViewItem *item = scene_.AddNode(it.key());
item->SetNodePosition(it.value());
}
}
}
}
void NodeView::ClearGraph()
{
SetGraph(nullptr, QVector<void*>());
}
void NodeView::DeleteSelected()
@@ -295,15 +317,15 @@ void NodeView::Paste()
return;
}
MultiUndoCommand* command = new MultiUndoCommand();
paste_command_ = new MultiUndoCommand();
QVector<Node*> pasted_nodes = PasteNodesFromClipboard(graph_, command);
QVector<Node*> pasted_nodes = PasteNodesFromClipboard(graph_, paste_command_);
if (!pasted_nodes.isEmpty()) {
command->add_child(new NodeViewAttachNodesToCursor(this, pasted_nodes));
paste_command_->add_child(new NodeViewAttachNodesToCursor(this, pasted_nodes));
}
Core::instance()->undo_stack()->pushIfHasChildren(command);
paste_command_->redo();
}
void NodeView::Duplicate()
@@ -318,15 +340,15 @@ void NodeView::Duplicate()
return;
}
MultiUndoCommand* command = new MultiUndoCommand();
paste_command_ = new MultiUndoCommand();
QVector<Node*> duplicated_nodes = Node::CopyDependencyGraph(selected, command);
QVector<Node*> duplicated_nodes = Node::CopyDependencyGraph(selected, paste_command_);
if (!duplicated_nodes.isEmpty()) {
command->add_child(new NodeViewAttachNodesToCursor(this, duplicated_nodes));
paste_command_->add_child(new NodeViewAttachNodesToCursor(this, duplicated_nodes));
}
Core::instance()->undo_stack()->pushIfHasChildren(command);
paste_command_->redo();
}
void NodeView::SetColorLabel(int index)
@@ -346,6 +368,59 @@ void NodeView::ZoomOut()
ZoomFromKeyboard(0.8);
}
/*void NodeView::AddNodesToFilter(const QVector<Node *> &nodes)
{
// Determine new nodes
QVector<Node*> multiple_sources;
foreach (Node* node, nodes) {
// Node is new and being added
scene_.AddNode(node);
QList<Node*> visible = graph_->GetNodesForRelative(node);
foreach (Node* v, visible) {
if (scene_.NodeToUIObject(v)) {
multiple_sources.append(v);
} else {
NodeViewItem* item = scene_.AddNode(v);
item->SetNodePosition(graph_->GetNodePosition(v, node));
}
}
}
filter_nodes_.append(nodes);
}
void NodeView::RemoveNodesFromFilter(const QVector<Node *> &nodes)
{
// Determine old nodes
foreach (Node* node, nodes) {
// Node is old and being removed
QList<Node*> visible = graph_->GetNodesForRelative(node);
foreach (Node* v, visible) {
bool found = false;
foreach (Node* n, filter_nodes_) {
if (node != n) {
QList<Node*> other_deps = graph_->GetNodesForRelative(n);
if (other_deps.contains(v)) {
found = true;
break;
}
}
}
if (!found) {
scene_.RemoveNode(v);
}
}
scene_.RemoveNode(node);
filter_nodes_.removeOne(node);
}
}*/
void NodeView::keyPressEvent(QKeyEvent *event)
{
super::keyPressEvent(event);
@@ -354,8 +429,11 @@ void NodeView::keyPressEvent(QKeyEvent *event)
DetachItemsFromCursor();
// We undo the last action which SHOULD be adding the node
// FIXME: Possible danger of this not being the case?
Core::instance()->undo_stack()->undo();
if (paste_command_) {
paste_command_->undo();
delete paste_command_;
paste_command_ = nullptr;
}
}
}
@@ -596,27 +674,34 @@ void NodeView::mouseReleaseEvent(QMouseEvent *event)
}
if (!attached_items_.isEmpty()) {
MultiUndoCommand* command = new MultiUndoCommand();
if (paste_command_) {
// We've already "done" this command, but MultiUndoCommand prevents "redoing" twice, so we
// add it to this command (which may have extra commands added too) so that it all gets undone
// in the same action
command->add_child(paste_command_);
paste_command_ = nullptr;
}
if (attached_items_.size() == 1) {
Node* dropping_node = attached_items_.first().item->GetNode();
if (drop_edge_) {
// We have everything we need to place the node in between
MultiUndoCommand* command = new MultiUndoCommand();
// Remove old edge
command->add_child(new NodeEdgeRemoveCommand(drop_edge_->output(), drop_edge_->input()));
// Place new edges
command->add_child(new NodeEdgeAddCommand(drop_edge_->output(), drop_input_));
command->add_child(new NodeEdgeAddCommand(dropping_node, drop_edge_->input()));
Core::instance()->undo_stack()->push(command);
}
drop_edge_ = nullptr;
}
DetachItemsFromCursor();
Core::instance()->undo_stack()->push(command);
}
super::mouseReleaseEvent(event);
@@ -718,12 +803,12 @@ void NodeView::ShowContextMenu(const QPoint &pos)
Menu* filter_menu = new Menu(tr("Filter"), &m);
m.addMenu(filter_menu);
filter_menu->AddActionWithData(tr("Show All"),
filter_menu->AddActionWithData(tr("Show All Nodes"),
kFilterShowAll,
filter_mode_);
filter_menu->AddActionWithData(tr("Show Selected Blocks Only"),
kFilterShowSelectedBlocks,
filter_menu->AddActionWithData(tr("Show Selected"),
kFilterShowSelective,
filter_mode_);
connect(filter_menu, &Menu::triggered, this, &NodeView::ContextMenuFilterChanged);
@@ -791,7 +876,22 @@ void NodeView::AutoPositionDescendents()
void NodeView::ContextMenuFilterChanged(QAction *action)
{
Q_UNUSED(action)
FilterMode mode = static_cast<FilterMode>(action->data().toInt());
if (filter_mode_ != mode) {
// Store temporary graph variables
NodeGraph *graph = graph_;
QVector<void*> nodes = filter_nodes_;
// Unset graph with current filter mode
ClearGraph();
// Change filter mode
filter_mode_ = mode;
// Re-set graph with new filter mode
SetGraph(graph, nodes);
}
}
void NodeView::OpenSelectedNodeInViewer()
@@ -804,6 +904,59 @@ void NodeView::OpenSelectedNodeInViewer()
}
}
void NodeView::AddNode(Node *node)
{
if (filter_mode_ == kFilterShowAll) {
scene_.AddNode(node);
}
}
void NodeView::RemoveNode(Node *node)
{
if (filter_mode_ == kFilterShowAll) {
scene_.RemoveNode(node);
}
}
void NodeView::AddEdge(const NodeOutput &output, const NodeInput &input)
{
if (filter_mode_ == kFilterShowAll) {
scene_.AddEdge(output, input);
}
}
void NodeView::RemoveEdge(const NodeOutput &output, const NodeInput &input)
{
if (filter_mode_ == kFilterShowAll) {
scene_.RemoveEdge(output, input);
}
}
void NodeView::AddNodePosition(Node *node, void *relative, const QPointF &pos)
{
if (filter_mode_ == kFilterShowSelective) {
if (filter_nodes_.contains(relative)) {
NodeViewItem *item = scene_.item_map().value(node);
if (!item) {
item = scene_.AddNode(node);
}
item->SetNodePosition(pos);
}
}
}
void NodeView::RemoveNodePosition(Node *node, void *relative)
{
if (filter_mode_ == kFilterShowSelective) {
if (filter_nodes_.contains(relative)) {
NodeViewItem *item = scene_.item_map().value(node);
delete item;
}
}
}
void NodeView::AttachNodesToCursor(const QVector<Node *> &nodes)
{
QVector<NodeViewItem*> items(nodes.size());
+16 -7
View File
@@ -51,10 +51,9 @@ public:
return graph_;
}
/**
* @brief Sets the graph to view
*/
void SetGraph(NodeGraph* graph);
void SetGraph(NodeGraph *graph, const QVector<void *> &nodes);
void ClearGraph();
/**
* @brief Delete selected nodes from graph (user-friendly/undoable)
@@ -147,17 +146,19 @@ private:
NodeViewScene scene_;
QVector<Node*> selected_nodes_;
MultiUndoCommand* paste_command_;
QVector<Block*> selected_blocks_;
QVector<Node*> selected_nodes_;
enum FilterMode {
kFilterShowAll,
kFilterShowSelectedBlocks
kFilterShowSelective
};
FilterMode filter_mode_;
QVector<void*> filter_nodes_;
double scale_;
bool create_edge_already_exists_;
@@ -200,6 +201,14 @@ private slots:
*/
void OpenSelectedNodeInViewer();
void AddNode(Node *node);
void RemoveNode(Node *node);
void AddEdge(const NodeOutput& output, const NodeInput& input);
void RemoveEdge(const NodeOutput& output, const NodeInput& input);
void AddNodePosition(Node *node, void *relative, const QPointF &pos);
void RemoveNodePosition(Node *node, void *relative);
};
}
-6
View File
@@ -192,8 +192,6 @@ void NodeViewItem::SetNode(Node *n)
node_inputs_.append(input);
}
}
SetNodePosition(node_->GetPosition());
}
update();
@@ -352,10 +350,6 @@ void NodeViewItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
QVariant NodeViewItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
{
if (change == ItemPositionHasChanged && node_) {
node_->blockSignals(true);
node_->SetPosition(GetNodePosition());
node_->blockSignals(false);
ReadjustAllEdges();
}
+5 -12
View File
@@ -43,9 +43,6 @@ void NodeViewScene::SetFlowDirection(NodeViewCommon::FlowDirection direction)
QHash<Node*, NodeViewItem*>::const_iterator i;
for (i=item_map_.constBegin(); i!=item_map_.constEnd(); i++) {
i.value()->SetFlowDirection(direction_);
// Update position too
i.value()->SetNodePosition(i.key()->GetPosition());
}
}
@@ -150,7 +147,7 @@ QVector<NodeViewEdge *> NodeViewScene::GetSelectedEdges() const
return edges;
}
void NodeViewScene::AddNode(Node* node)
NodeViewItem* NodeViewScene::AddNode(Node* node)
{
NodeViewItem* item = new NodeViewItem();
@@ -160,16 +157,16 @@ void NodeViewScene::AddNode(Node* node)
addItem(item);
item_map_.insert(node, item);
connect(node, &Node::PositionChanged, this, &NodeViewScene::NodePositionChanged);
connect(node, &Node::LabelChanged, this, &NodeViewScene::NodeAppearanceChanged);
connect(node, &Node::ColorChanged, this, &NodeViewScene::NodeAppearanceChanged);
return item;
}
void NodeViewScene::RemoveNode(Node *node)
{
disconnect(node, &Node::ColorChanged, this, &NodeViewScene::NodeAppearanceChanged);
disconnect(node, &Node::LabelChanged, this, &NodeViewScene::NodeAppearanceChanged);
disconnect(node, &Node::PositionChanged, this, &NodeViewScene::NodePositionChanged);
delete item_map_.take(node);
}
@@ -229,6 +226,7 @@ NodeViewCommon::FlowDirection NodeViewScene::GetFlowDirection() const
void NodeViewScene::ReorganizeFrom(Node* n)
{
/*
QVector<Node*> immediates = n->GetImmediateDependencies();
if (immediates.isEmpty()) {
@@ -258,6 +256,7 @@ void NodeViewScene::ReorganizeFrom(Node* n)
ReorganizeFrom(i);
}
}
*/
}
void NodeViewScene::SetEdgesAreCurved(bool curved)
@@ -271,12 +270,6 @@ void NodeViewScene::SetEdgesAreCurved(bool curved)
}
}
void NodeViewScene::NodePositionChanged(const QPointF &pos)
{
// Update node's internal position
item_map_.value(static_cast<Node*>(sender()))->SetNodePosition(pos);
}
void NodeViewScene::NodeAppearanceChanged()
{
// Force item to update
+1 -6
View File
@@ -88,7 +88,7 @@ public slots:
* This should NEVER be called directly, only connected to a NodeGraph. To add a Node to the NodeGraph
* use NodeGraph::AddNode().
*/
void AddNode(Node* node);
NodeViewItem *AddNode(Node* node);
/**
* @brief Slot when a Node is removed from a graph (SetGraph() connects this)
@@ -122,11 +122,6 @@ private:
bool curved_edges_;
private slots:
/**
* @brief Receiver for whenever a node position changes
*/
void NodePositionChanged(const QPointF& pos);
/**
* @brief Receiver for when a node's label has changed
*/
+1 -1
View File
@@ -260,7 +260,7 @@ void TrackReplaceBlockWithGapCommand::redo()
track_->ReplaceBlock(block_, our_gap_);
if (!position_command_) {
position_command_ = new NodeSetPositionAsChildCommand(our_gap_, track_, our_gap_->index(), track_->Blocks().size(), true);
position_command_ = new NodeSetPositionAsChildCommand(our_gap_, track_, track_, our_gap_->index(), track_->Blocks().size(), true);
}
position_command_->redo();
}
+5 -5
View File
@@ -372,7 +372,7 @@ public:
// Position the block
if (!position_command_) {
position_command_ = new NodeSetPositionAsChildCommand(new_block(), track, new_block()->index(), track->Blocks().size(), true);
position_command_ = new NodeSetPositionAsChildCommand(new_block(), track, nullptr, new_block()->index(), track->Blocks().size(), true);
}
position_command_->redo();
@@ -1198,7 +1198,7 @@ public:
timeline_->ArrayAppend();
int track_total_index = timeline_->parent()->GetTracks().size();
if (!position_command_) {
position_command_ = new NodeSetPositionAsChildCommand(track_, timeline_->parent(), track_total_index, track_total_index + 1, true);
position_command_ = new NodeSetPositionAsChildCommand(track_, timeline_->parent(), timeline_->parent(), track_total_index, track_total_index + 1, true);
}
position_command_->redo();
Node::ConnectEdge(track_, timeline_->track_input(timeline_->ArraySize() - 1));
@@ -1385,9 +1385,9 @@ public:
if (position_commands_.isEmpty()) {
// Create position commands for insert and gap if necessary
if (gap_) {
position_commands_.append(new NodeSetPositionAsChildCommand(gap_, track, gap_->index(), track->Blocks().size(), true));
position_commands_.append(new NodeSetPositionAsChildCommand(gap_, track, track, gap_->index(), track->Blocks().size(), true));
}
position_commands_.append(new NodeSetPositionAsChildCommand(insert_, track, insert_->index(), track->Blocks().size(), true));
position_commands_.append(new NodeSetPositionAsChildCommand(insert_, track, track, insert_->index(), track->Blocks().size(), true));
}
} else {
// Place the Block at this point
@@ -1401,7 +1401,7 @@ public:
track->InsertBlockAfter(insert_, ripple_remove_command_->GetInsertionIndex());
if (position_commands_.isEmpty()) {
position_commands_.append(new NodeSetPositionAsChildCommand(insert_, track, insert_->index(), track->Blocks().size(), true));
position_commands_.append(new NodeSetPositionAsChildCommand(insert_, track, track, insert_->index(), track->Blocks().size(), true));
}
}
+2 -2
View File
@@ -121,7 +121,7 @@ void AddTool::MouseRelease(TimelineViewMouseEvent *event)
solid));
command->add_child(new NodeEdgeAddCommand(solid, NodeInput(clip, ClipBlock::kBufferIn)));
command->add_child(new NodeSetPositionToOffsetOfAnotherNodeCommand(solid, clip, extra_node_offset));
command->add_child(new NodeSetPositionToOffsetOfAnotherNodeCommand(solid, clip, clip, extra_node_offset));
break;
}
case olive::Tool::kAddableTitle:
@@ -132,7 +132,7 @@ void AddTool::MouseRelease(TimelineViewMouseEvent *event)
text));
command->add_child(new NodeEdgeAddCommand(text, NodeInput(clip, ClipBlock::kBufferIn)));
command->add_child(new NodeSetPositionToOffsetOfAnotherNodeCommand(text, clip, extra_node_offset));
command->add_child(new NodeSetPositionToOffsetOfAnotherNodeCommand(text, clip, clip, extra_node_offset));
break;
}
case olive::Tool::kAddableBars:
+5 -3
View File
@@ -387,7 +387,9 @@ void ImportTool::DropGhosts(bool insert)
clip->set_length_and_media_out(ghost->GetLength());
clip->SetLabel(footage_stream.footage->GetLabel());
command->add_child(new NodeAddCommand(dst_graph, clip));
command->add_child(new NodeSetPositionToOffsetOfAnotherNodeCommand(clip, footage_stream.footage, QPointF(2, 0)));
command->add_child(new NodeSetPositionToOffsetOfAnotherNodeCommand(clip, footage_stream.footage, clip, QPointF(2, 0)));
command->add_child(new NodeSetPositionCommand(footage_stream.footage, clip, QPointF(-2, 0), false));
switch (Track::Reference::TypeFromString(footage_stream.output)) {
case Track::kVideo:
@@ -397,7 +399,7 @@ void ImportTool::DropGhosts(bool insert)
command->add_child(new NodeEdgeAddCommand(corresponding_output, NodeInput(transform, TransformDistortNode::kTextureInput)));
command->add_child(new NodeEdgeAddCommand(transform, NodeInput(clip, ClipBlock::kBufferIn)));
command->add_child(new NodeSetPositionToOffsetOfAnotherNodeCommand(transform, clip, QPointF(-1, 0)));
command->add_child(new NodeSetPositionCommand(transform, clip, QPointF(-1, 0), false));
break;
}
case Track::kAudio:
@@ -407,7 +409,7 @@ void ImportTool::DropGhosts(bool insert)
command->add_child(new NodeEdgeAddCommand(corresponding_output, NodeInput(volume_node, VolumeNode::kSamplesInput)));
command->add_child(new NodeEdgeAddCommand(volume_node, NodeInput(clip, ClipBlock::kBufferIn)));
command->add_child(new NodeSetPositionToOffsetOfAnotherNodeCommand(volume_node, clip, QPointF(-1, 0)));
command->add_child(new NodeSetPositionCommand(volume_node, clip, QPointF(-1, 0), false));
break;
}
default:
+11 -13
View File
@@ -385,7 +385,7 @@ void MainWindow::ProjectClose(Project *p)
// Close project from NodeView
if (node_panel_->GetGraph() == p) {
node_panel_->SetGraph(nullptr);
node_panel_->ClearGraph();
}
}
@@ -539,8 +539,6 @@ TimelinePanel* MainWindow::AppendTimelinePanel()
connect(panel, &TimelinePanel::TimeChanged, param_panel_, &ParamPanel::SetTimestamp);
connect(panel, &TimelinePanel::TimeChanged, table_panel_, &NodeTablePanel::SetTimestamp);
connect(panel, &TimelinePanel::TimeChanged, sequence_viewer_panel_, &SequenceViewerPanel::SetTimestamp);
connect(panel, &TimelinePanel::BlocksSelected, node_panel_, &NodePanel::SelectBlocks);
connect(panel, &TimelinePanel::BlocksDeselected, node_panel_, &NodePanel::DeselectBlocks);
connect(param_panel_, &ParamPanel::TimeChanged, panel, &TimelinePanel::SetTimestamp);
connect(curve_panel_, &ParamPanel::TimeChanged, panel, &TimelinePanel::SetTimestamp);
connect(sequence_viewer_panel_, &SequenceViewerPanel::TimeChanged, panel, &TimelinePanel::SetTimestamp);
@@ -698,24 +696,24 @@ void MainWindow::UpdateAudioMonitorParams(ViewerOutput *viewer)
void MainWindow::FocusedPanelChanged(PanelWidget *panel)
{
// Update audio monitor panel
TimeBasedPanel* tbp = dynamic_cast<TimeBasedPanel*>(panel);
if (tbp) {
if (TimeBasedPanel* tbp = dynamic_cast<TimeBasedPanel*>(panel)) {
UpdateAudioMonitorParams(tbp->GetConnectedViewer());
}
if (TimelinePanel* timeline = dynamic_cast<TimelinePanel*>(panel)) {
// Signal timeline focus
TimelinePanel* timeline = dynamic_cast<TimelinePanel*>(panel);
if (timeline) {
TimelineFocused(timeline->GetConnectedViewer());
return;
}
NodeGraph *graph = timeline->GetConnectedViewer() ? timeline->GetConnectedViewer()->parent() : nullptr;
QVector<void*> n(timeline->GetSelectedBlocks().size());
for (int j=0; j<n.size(); j++) {
n[j] = timeline->GetSelectedBlocks().at(j);
}
node_panel_->SetGraph(graph, n);
} else if (ProjectPanel* project = dynamic_cast<ProjectPanel*>(panel)) {
// Signal project panel focus
ProjectPanel* project = dynamic_cast<ProjectPanel*>(panel);
if (project) {
UpdateTitle();
node_panel_->SetGraph(project->project());
return;
node_panel_->SetGraph(project->project(), {project->project()});
}
}