added new node auto-positioning for items

This commit is contained in:
itsmattkc
2021-03-14 21:09:00 +11:00
parent 500fb58d49
commit 2a9513e56a
6 changed files with 224 additions and 4 deletions
+43 -1
View File
@@ -1803,11 +1803,20 @@ const QPointF &Node::GetPosition() const
return position_;
}
void Node::SetPosition(const QPointF &pos)
void Node::SetPosition(const QPointF &pos, bool move_dependencies_relatively_too)
{
position_ = pos;
emit PositionChanged(position_);
if (move_dependencies_relatively_too) {
QPointF difference = pos - GetPosition();
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)
@@ -2252,4 +2261,37 @@ Project *Node::ArrayResizeCommand::GetRelevantProject() const
return node_->project();
}
void NodeSetPositionAndShiftSurroundingsCommand::redo()
{
if (commands_.isEmpty()) {
// Move first node
NodeSetPositionCommand* set_pos_command = new NodeSetPositionCommand(node_, position_, move_dependencies_);
set_pos_command->redo();
commands_.append(set_pos_command);
// Get bounding rect
QRectF bounding_rect(position_.x() - 0.5, position_.y() - 0.5, 1, 1);
// Start moving other nodes
foreach (Node* surrounding, node_->parent()->nodes()) {
if (bounding_rect.contains(surrounding->GetPosition()) && surrounding != node_) {
QPointF new_pos = surrounding->GetPosition();
if (surrounding->GetPosition().y() > position_.y()) {
new_pos.setY(new_pos.y() + 0.5);
} else {
new_pos.setY(new_pos.y() - 0.5);
}
auto sur_command = new NodeSetPositionAndShiftSurroundingsCommand(surrounding, new_pos, true);
sur_command->redo();
commands_.append(sur_command);
}
}
} else {
for (int i=0; i<commands_.size(); i++) {
commands_.at(i)->redo();
}
}
}
}
+139 -1
View File
@@ -707,7 +707,7 @@ public:
const QPointF& GetPosition() const;
void SetPosition(const QPointF& pos);
void SetPosition(const QPointF& pos, bool move_dependencies_relatively_too = false);
virtual bool HasGizmos() const;
@@ -1257,6 +1257,144 @@ QVector<T *> Node::FindOutputNode()
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)
{
}
virtual Project * GetRelevantProject() const override
{
return node_->project();
}
virtual void redo() override
{
old_pos_ = node_->GetPosition();
node_->SetPosition(new_pos_, move_deps_);
}
virtual void undo() override
{
node_->SetPosition(old_pos_, move_deps_);
}
private:
Node* node_;
QPointF new_pos_;
QPointF old_pos_;
bool move_deps_;
};
class NodeSetPositionAndShiftSurroundingsCommand : public UndoCommand
{
public:
NodeSetPositionAndShiftSurroundingsCommand(Node* node, const QPointF& pos, bool move_dependencies_relatively) :
node_(node),
position_(pos),
move_dependencies_(move_dependencies_relatively)
{}
virtual ~NodeSetPositionAndShiftSurroundingsCommand() override
{
qDeleteAll(commands_);
}
virtual Project * GetRelevantProject() const override
{
return node_->project();
}
virtual void redo() override;
virtual void undo() override
{
for (int i=commands_.size()-1; i>=0; i--) {
commands_.at(i)->undo();
}
}
private:
Node* node_;
QPointF position_;
bool move_dependencies_;
QVector<UndoCommand*> commands_;
};
class NodeSetPositionAsChildCommand : public UndoCommand
{
public:
NodeSetPositionAsChildCommand(Node* node, Node* parent, int this_index, int child_count, bool shift_surroundings) :
node_(node),
parent_(parent),
this_index_(this_index),
child_count_(child_count),
shift_surroundings_(shift_surroundings),
sub_command_(nullptr)
{
}
virtual ~NodeSetPositionAsChildCommand() override
{
delete sub_command_;
}
virtual Project * GetRelevantProject() const override
{
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 undo() override
{
sub_command_->undo();
}
private:
Node* node_;
Node* parent_;
int this_index_;
int child_count_;
bool shift_surroundings_;
UndoCommand* sub_command_;
};
}
#endif // NODE_H
+19 -1
View File
@@ -115,10 +115,16 @@ void Folder::InputDisconnectedEvent(const QString &input, int element, const Nod
FolderAddChild::FolderAddChild(Folder *folder, Node *child, bool autoposition) :
folder_(folder),
child_(child),
autoposition_(autoposition)
autoposition_(autoposition),
position_command_(nullptr)
{
}
FolderAddChild::~FolderAddChild()
{
delete position_command_;
}
Project *FolderAddChild::GetRelevantProject() const
{
return folder_->project();
@@ -129,10 +135,22 @@ void FolderAddChild::redo()
int array_index = folder_->InputArraySize(Folder::kChildInput);
folder_->InputArrayAppend(Folder::kChildInput, false);
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_->redo();
}
}
void FolderAddChild::undo()
{
if (position_command_) {
position_command_->undo();
}
Node::DisconnectEdge(child_, NodeInput(folder_, Folder::kChildInput, folder_->InputArraySize(Folder::kChildInput)-1));
folder_->InputArrayRemoveLast(Folder::kChildInput);
}
+4
View File
@@ -160,6 +160,8 @@ class FolderAddChild : public UndoCommand
public:
FolderAddChild(Folder* folder, Node* child, bool autoposition = true);
virtual ~FolderAddChild() override;
virtual Project * GetRelevantProject() const override;
virtual void redo() override;
@@ -175,6 +177,8 @@ private:
QPointF old_position_;
NodeSetPositionAsChildCommand* position_command_;
};
}
+4
View File
@@ -39,16 +39,20 @@ 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));
AddDefaultNode(color_manager_);
// Same with project settings
settings_ = new ProjectSettingsNode();
settings_->setParent(this);
settings_->SetPosition(QPointF(2, 0));
AddDefaultNode(settings_);
// Viewer node for connecting with the footage viewer
footage_viewer_ = new ViewerOutput();
footage_viewer_->setParent(this);
footage_viewer_->SetLabel(tr("Footage Viewer"));
footage_viewer_->SetPosition(QPointF(3, 0));
AddDefaultNode(footage_viewer_);
// Folder root for project
+15 -1
View File
@@ -1309,7 +1309,8 @@ private:
class TimelineAddTrackCommand : public UndoCommand {
public:
TimelineAddTrackCommand(TrackList *timeline) :
timeline_(timeline)
timeline_(timeline),
position_command_(nullptr)
{
track_ = new Track();
track_->setParent(&memory_manager_);
@@ -1330,6 +1331,11 @@ public:
}
}
virtual ~TimelineAddTrackCommand() override
{
delete position_command_;
}
Track* track() const
{
return track_;
@@ -1345,6 +1351,11 @@ public:
// Add track
track_->setParent(timeline_->GetParentGraph());
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_->redo();
Node::ConnectEdge(track_, timeline_->track_input(timeline_->ArraySize() - 1));
// Add merge if applicable
@@ -1414,6 +1425,7 @@ public:
// Remove track
Node::DisconnectEdge(track_, timeline_->track_input(timeline_->ArraySize() - 1));
position_command_->undo();
timeline_->ArrayRemoveLast();
track_->setParent(&memory_manager_);
}
@@ -1428,6 +1440,8 @@ private:
NodeInput direct_;
NodeSetPositionAsChildCommand* position_command_;
QObject memory_manager_;
};