more work
This commit is contained in:
@@ -116,7 +116,7 @@ void AddTool::MouseRelease(TimelineViewMouseEvent *event)
|
||||
NodeGraph* graph = static_cast<NodeGraph*>(parent()->GetConnectedNode()->parent());
|
||||
|
||||
command->add_child(new NodeAddCommand(graph, clip));
|
||||
command->add_child(new NodeSetPositionCommand(clip, clip, QPointF(0, 0), false));
|
||||
command->add_child(new NodeSetPositionCommand(clip, clip, QPointF(0, 0)));
|
||||
command->add_child(new TrackPlaceBlockCommand(sequence()->track_list(track.type()),
|
||||
track.index(),
|
||||
clip,
|
||||
@@ -155,10 +155,10 @@ void AddTool::MouseRelease(TimelineViewMouseEvent *event)
|
||||
}
|
||||
|
||||
if (node_to_add) {
|
||||
QPointF extra_node_offset(-1, 0);
|
||||
QPointF extra_node_offset(kDefaultDistanceFromOutput, 0);
|
||||
command->add_child(new NodeAddCommand(graph, node_to_add));
|
||||
command->add_child(new NodeEdgeAddCommand(node_to_add, NodeInput(clip, ClipBlock::kBufferIn)));
|
||||
command->add_child(new NodeSetPositionCommand(node_to_add, clip, extra_node_offset, false));
|
||||
command->add_child(new NodeSetPositionCommand(node_to_add, clip, extra_node_offset));
|
||||
}
|
||||
|
||||
Core::instance()->undo_stack()->push(command);
|
||||
|
||||
@@ -355,7 +355,7 @@ void ImportTool::DropGhosts(bool insert)
|
||||
|
||||
command->add_child(new NodeAddCommand(dst_graph, new_sequence));
|
||||
command->add_child(new FolderAddChild(Core::instance()->GetSelectedFolderInActiveProject(), new_sequence));
|
||||
command->add_child(new NodeSetPositionCommand(new_sequence, new_sequence, QPointF(0, 0), false));
|
||||
command->add_child(new NodeSetPositionCommand(new_sequence, new_sequence, QPointF(0, 0)));
|
||||
new_sequence->add_default_nodes(command);
|
||||
|
||||
FootageToGhosts(0, dragged_footage_, new_sequence->GetVideoParams().time_base(), 0);
|
||||
@@ -394,10 +394,14 @@ void ImportTool::DropGhosts(bool insert)
|
||||
command->add_child(new NodeAddCommand(dst_graph, clip));
|
||||
|
||||
// Position clip in its own context
|
||||
command->add_child(new NodeSetPositionCommand(clip, clip, QPointF(0, 0), false));
|
||||
command->add_child(new NodeSetPositionCommand(clip, clip, QPointF(0, 0)));
|
||||
|
||||
int dep_pos = kDefaultDistanceFromOutput;
|
||||
|
||||
// Position footage in its context
|
||||
command->add_child(new NodeSetPositionCommand(footage_stream.footage, clip, QPointF(-3, 0), false));
|
||||
command->add_child(new NodeSetPositionCommand(footage_stream.footage, clip, QPointF(dep_pos, 0)));
|
||||
|
||||
dep_pos++;
|
||||
|
||||
switch (Track::Reference::TypeFromString(footage_stream.output)) {
|
||||
case Track::kVideo:
|
||||
@@ -409,7 +413,7 @@ void ImportTool::DropGhosts(bool insert)
|
||||
|
||||
command->add_child(new NodeEdgeAddCommand(footage_stream.footage, NodeInput(transform, TransformDistortNode::kTextureInput)));
|
||||
command->add_child(new NodeEdgeAddCommand(transform, NodeInput(clip, ClipBlock::kBufferIn)));
|
||||
command->add_child(new NodeSetPositionCommand(transform, clip, QPointF(-2, 0), false));
|
||||
command->add_child(new NodeSetPositionCommand(transform, clip, QPointF(dep_pos, 0)));
|
||||
break;
|
||||
}
|
||||
case Track::kAudio:
|
||||
@@ -421,7 +425,7 @@ void ImportTool::DropGhosts(bool insert)
|
||||
|
||||
command->add_child(new NodeEdgeAddCommand(footage_stream.footage, NodeInput(volume_node, VolumeNode::kSamplesInput)));
|
||||
command->add_child(new NodeEdgeAddCommand(volume_node, NodeInput(clip, ClipBlock::kBufferIn)));
|
||||
command->add_child(new NodeSetPositionCommand(volume_node, clip, QPointF(-2, 0), false));
|
||||
command->add_child(new NodeSetPositionCommand(volume_node, clip, QPointF(dep_pos, 0)));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
namespace olive {
|
||||
|
||||
const int TimelineTool::kDefaultDistanceFromOutput = -4;
|
||||
|
||||
TimelineTool::TimelineTool(TimelineWidget *parent) :
|
||||
dragging_(false),
|
||||
parent_(parent)
|
||||
|
||||
@@ -84,6 +84,8 @@ protected:
|
||||
|
||||
TimelineCoordinate drag_start_;
|
||||
|
||||
static const int kDefaultDistanceFromOutput;
|
||||
|
||||
private:
|
||||
TimelineWidget* parent_;
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ void TransitionTool::MouseRelease(TimelineViewMouseEvent *event)
|
||||
command->add_child(new NodeAddCommand(static_cast<NodeGraph*>(parent()->GetConnectedNode()->parent()),
|
||||
transition));
|
||||
|
||||
command->add_child(new NodeSetPositionCommand(transition, transition, QPointF(0, 0), false));
|
||||
command->add_child(new NodeSetPositionCommand(transition, transition, QPointF(0, 0)));
|
||||
|
||||
command->add_child(new TrackPlaceBlockCommand(sequence()->track_list(track.type()),
|
||||
track.index(),
|
||||
@@ -138,8 +138,8 @@ void TransitionTool::MouseRelease(TimelineViewMouseEvent *event)
|
||||
command->add_child(new NodeEdgeAddCommand(in_block,
|
||||
NodeInput(transition, TransitionBlock::kInBlockInput)));
|
||||
|
||||
command->add_child(new NodeSetPositionCommand(out_block, transition, QPointF(-1, -0.5), false));
|
||||
command->add_child(new NodeSetPositionCommand(in_block, transition, QPointF(-1, 0.5), false));
|
||||
command->add_child(new NodeSetPositionCommand(out_block, transition, QPointF(-1, -0.5)));
|
||||
command->add_child(new NodeSetPositionCommand(in_block, transition, QPointF(-1, 0.5)));
|
||||
} else {
|
||||
Block* block_to_transition = Node::ValueToPtr<Block>(ghost_->GetData(TimelineViewGhostItem::kAttachedBlock));
|
||||
QString transition_input_to_connect;
|
||||
@@ -154,7 +154,7 @@ void TransitionTool::MouseRelease(TimelineViewMouseEvent *event)
|
||||
command->add_child(new NodeEdgeAddCommand(block_to_transition,
|
||||
NodeInput(transition, transition_input_to_connect)));
|
||||
|
||||
command->add_child(new NodeSetPositionCommand(block_to_transition, transition, QPointF(-1, 0), false));
|
||||
command->add_child(new NodeSetPositionCommand(block_to_transition, transition, QPointF(-1, 0)));
|
||||
}
|
||||
|
||||
Core::instance()->undo_stack()->push(command);
|
||||
|
||||
@@ -73,131 +73,121 @@ void BlockSetMediaInCommand::undo()
|
||||
//
|
||||
// TimelineAddTrackCommand
|
||||
//
|
||||
TimelineAddTrackCommand::TimelineAddTrackCommand(TrackList *timeline, bool automerge_tracks)
|
||||
TimelineAddTrackCommand::TimelineAddTrackCommand(TrackList *timeline, bool automerge_tracks) :
|
||||
timeline_(timeline),
|
||||
merge_(nullptr),
|
||||
position_command_(nullptr)
|
||||
{
|
||||
timeline_ = timeline;
|
||||
position_command_ = nullptr;
|
||||
|
||||
// Create new track
|
||||
track_ = new Track();
|
||||
track_->setParent(&memory_manager_);
|
||||
|
||||
if (timeline->GetTrackCount() > 0 && automerge_tracks) {
|
||||
if (timeline_->type() == Track::kVideo) {
|
||||
merge_ = new MergeNode();
|
||||
base_ = NodeInput(merge_, MergeNode::kBaseIn);
|
||||
blend_ = NodeInput(merge_, MergeNode::kBlendIn);
|
||||
} else if (timeline_->type() == Track::kAudio) {
|
||||
merge_ = new MathNode();
|
||||
base_ = NodeInput(merge_, MathNode::kParamAIn);
|
||||
blend_ = NodeInput(merge_, MathNode::kParamBIn);
|
||||
} else {
|
||||
merge_ = nullptr;
|
||||
}
|
||||
} else {
|
||||
merge_ = nullptr;
|
||||
// Determine what input to connect it to
|
||||
QString relevant_input;
|
||||
|
||||
if (timeline_->type() == Track::kVideo) {
|
||||
relevant_input = Sequence::kTextureInput;
|
||||
} else if (timeline_->type() == Track::kAudio) {
|
||||
relevant_input = Sequence::kSamplesInput;
|
||||
}
|
||||
|
||||
if (merge_) {
|
||||
merge_->setParent(&memory_manager_);
|
||||
// If we have an input to connect to, set it as our `direct` connection
|
||||
if (!relevant_input.isEmpty()) {
|
||||
direct_ = NodeInput(timeline_->parent(), relevant_input);
|
||||
|
||||
// If we're automerging and something is already connected, determine if/how to merge it
|
||||
if (automerge_tracks && direct_.IsConnected()) {
|
||||
if (timeline_->type() == Track::kVideo) {
|
||||
// Use merge for video
|
||||
merge_ = new MergeNode();
|
||||
base_ = NodeInput(merge_, MergeNode::kBaseIn);
|
||||
blend_ = NodeInput(merge_, MergeNode::kBlendIn);
|
||||
} else if (timeline_->type() == Track::kAudio) {
|
||||
// Use math (add) for audio
|
||||
merge_ = new MathNode();
|
||||
base_ = NodeInput(merge_, MathNode::kParamAIn);
|
||||
blend_ = NodeInput(merge_, MathNode::kParamBIn);
|
||||
}
|
||||
|
||||
if (merge_) {
|
||||
// If we got created a merge node, ensure it's parented
|
||||
merge_->setParent(&memory_manager_);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineAddTrackCommand::redo()
|
||||
{
|
||||
// Add track
|
||||
// Get sequence
|
||||
Sequence* sequence = timeline_->parent();
|
||||
|
||||
// Add track to sequence
|
||||
track_->setParent(timeline_->GetParentGraph());
|
||||
timeline_->ArrayAppend();
|
||||
Node::ConnectEdge(track_, timeline_->track_input(timeline_->ArraySize() - 1));
|
||||
|
||||
qreal position_factor = 0.5;
|
||||
if (timeline_->type() == Track::kVideo) {
|
||||
position_factor = -position_factor;
|
||||
}
|
||||
bool create_pos_command = (!position_command_ && (timeline_->type() == Track::kVideo || timeline_->type() == Track::kAudio));
|
||||
if (create_pos_command) {
|
||||
position_command_ = new MultiUndoCommand();
|
||||
}
|
||||
|
||||
// Add merge if applicable
|
||||
Track* last_track = nullptr;
|
||||
if (merge_) {
|
||||
// Determine what was previously connected
|
||||
Node *previous_connection = direct_.GetConnectedOutput();
|
||||
|
||||
// Add merge to graph
|
||||
merge_->setParent(timeline_->GetParentGraph());
|
||||
|
||||
last_track = timeline_->GetTrackAt(timeline_->GetTrackCount()-2);
|
||||
|
||||
// Whatever this track used to be connected to, connect the merge instead
|
||||
const Node::OutputConnections edges = last_track->output_connections();
|
||||
for (const Node::OutputConnection& ic : edges) {
|
||||
const NodeInput& i = ic.second;
|
||||
|
||||
// Ignore the track input, but funnel everything else through our merge
|
||||
if (i.node() != timeline_->parent() || i.input() != timeline_->track_input()) {
|
||||
Node::DisconnectEdge(last_track, i);
|
||||
Node::ConnectEdge(merge_, i);
|
||||
}
|
||||
}
|
||||
|
||||
// Connect this as the "blend" track
|
||||
// Connect merge between what used to be here
|
||||
Node::DisconnectEdge(previous_connection, direct_);
|
||||
Node::ConnectEdge(merge_, direct_);
|
||||
Node::ConnectEdge(previous_connection, base_);
|
||||
Node::ConnectEdge(track_, blend_);
|
||||
Node::ConnectEdge(last_track, base_);
|
||||
} else if (timeline_->GetTrackCount() == 1) {
|
||||
// If this was the first track we added,
|
||||
QString relevant_input;
|
||||
|
||||
if (timeline_->type() == Track::kVideo) {
|
||||
relevant_input = ViewerOutput::kTextureInput;
|
||||
} else if (timeline_->type() == Track::kAudio) {
|
||||
relevant_input = ViewerOutput::kSamplesInput;
|
||||
if (create_pos_command) {
|
||||
position_command_->add_child(new NodeSetPositionCommand(track_, sequence, sequence->GetNodePositionInContext(sequence) + QPointF(-1, -position_factor)));
|
||||
position_command_->add_child(new NodeSetPositionCommand(merge_, sequence, sequence->GetNodePositionInContext(sequence)));
|
||||
position_command_->add_child(new NodeSetPositionCommand(merge_, sequence, sequence->GetNodePositionInContext(sequence) + QPointF(-1, position_factor * timeline_->GetTrackCount()), true));
|
||||
}
|
||||
} else if (direct_.IsValid() && !direct_.IsConnected()) {
|
||||
// If no merge, we have a direct connection, and nothing else is connected, connect this
|
||||
Node::ConnectEdge(track_, direct_);
|
||||
|
||||
if (!relevant_input.isEmpty() && !timeline_->parent()->IsInputConnected(relevant_input)) {
|
||||
direct_ = NodeInput(timeline_->parent(), relevant_input);
|
||||
|
||||
Node::ConnectEdge(track_, direct_);
|
||||
} else {
|
||||
direct_ = NodeInput();
|
||||
if (create_pos_command) {
|
||||
// Just position directly next to the context node
|
||||
position_command_->add_child(new NodeSetPositionCommand(track_, sequence, sequence->GetNodePositionInContext(sequence) + QPointF(-1, position_factor)));
|
||||
}
|
||||
}
|
||||
|
||||
// Position track in context
|
||||
if (!position_command_) {
|
||||
int track_count = timeline_->parent()->GetTracks().size();
|
||||
position_command_ = new MultiUndoCommand();
|
||||
|
||||
// Position either the merge or the track as an "element"
|
||||
Node *node_to_position = merge_ ? merge_ : track_;
|
||||
double node_index = track_count - 1;
|
||||
if (merge_) {
|
||||
node_index -= 1;
|
||||
position_command_->add_child(new NodeRemovePositionFromContextCommand(last_track, timeline_->parent()));
|
||||
}
|
||||
|
||||
position_command_->add_child(new NodeSetPositionAsChildCommand(node_to_position, timeline_->parent(), timeline_->parent(), node_index, track_count, true));
|
||||
|
||||
// If we positioned a merge, position the tracks as children of the merge
|
||||
if (merge_) {
|
||||
// `last_track` should be non-null if `merge_` is non-null
|
||||
position_command_->add_child(new NodeSetPositionAsChildCommand(last_track, merge_, timeline_->parent(), 0, 2, true));
|
||||
position_command_->add_child(new NodeSetPositionAsChildCommand(track_, merge_, timeline_->parent(), 1, 2, true));
|
||||
}
|
||||
// Run position command if we created one
|
||||
if (position_command_) {
|
||||
position_command_->redo_now();
|
||||
}
|
||||
position_command_->redo_now();
|
||||
}
|
||||
|
||||
void TimelineAddTrackCommand::undo()
|
||||
{
|
||||
position_command_->undo_now();
|
||||
if (position_command_) {
|
||||
position_command_->undo_now();
|
||||
}
|
||||
|
||||
// Remove merge if applicable
|
||||
if (merge_) {
|
||||
// Assume whatever this merge is connected to USED to be connected to the last track
|
||||
Track* last_track = timeline_->GetTrackAt(timeline_->GetTrackCount()-2);
|
||||
Node *previous_connection = base_.GetConnectedOutput();
|
||||
|
||||
Node::DisconnectEdge(track_, blend_);
|
||||
Node::DisconnectEdge(last_track, base_);
|
||||
|
||||
// Make copy of edges since the node's internal array will change as we disconnect things
|
||||
const Node::OutputConnections edges = merge_->output_connections();
|
||||
for (const Node::OutputConnection& ic : edges) {
|
||||
const NodeInput& i = ic.second;
|
||||
|
||||
Node::DisconnectEdge(merge_, i);
|
||||
Node::ConnectEdge(last_track, i);
|
||||
}
|
||||
Node::DisconnectEdge(previous_connection, base_);
|
||||
Node::DisconnectEdge(merge_, direct_);
|
||||
Node::ConnectEdge(previous_connection, direct_);
|
||||
|
||||
merge_->setParent(&memory_manager_);
|
||||
} else if (direct_.IsValid()) {
|
||||
} else if (direct_.IsValid() && direct_.GetConnectedOutput() == track_) {
|
||||
Node::DisconnectEdge(track_, direct_);
|
||||
}
|
||||
|
||||
@@ -496,11 +486,6 @@ void TrackReplaceBlockWithGapCommand::redo()
|
||||
|
||||
our_gap_->setParent(track_->parent());
|
||||
track_->ReplaceBlock(block_, our_gap_);
|
||||
|
||||
if (!position_command_) {
|
||||
position_command_ = new NodeSetPositionAsChildCommand(our_gap_, track_, track_, our_gap_->index(), track_->Blocks().size(), true);
|
||||
}
|
||||
position_command_->redo_now();
|
||||
}
|
||||
|
||||
track_->EndOperation();
|
||||
@@ -533,8 +518,6 @@ void TrackReplaceBlockWithGapCommand::undo()
|
||||
track_->ReplaceBlock(our_gap_, block_);
|
||||
our_gap_->setParent(&memory_manager_);
|
||||
|
||||
position_command_->undo_now();
|
||||
|
||||
} else {
|
||||
|
||||
// If we're here, assume that we extended an existing gap
|
||||
|
||||
@@ -203,16 +203,10 @@ public:
|
||||
existing_gap_(nullptr),
|
||||
existing_merged_gap_(nullptr),
|
||||
our_gap_(nullptr),
|
||||
handle_transitions_(handle_transitions),
|
||||
position_command_(nullptr)
|
||||
handle_transitions_(handle_transitions)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~TrackReplaceBlockWithGapCommand() override
|
||||
{
|
||||
delete position_command_;
|
||||
}
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
return block_->project();
|
||||
@@ -236,8 +230,6 @@ private:
|
||||
|
||||
bool handle_transitions_;
|
||||
|
||||
NodeSetPositionAsChildCommand* position_command_;
|
||||
|
||||
QObject memory_manager_;
|
||||
|
||||
QVector<TransitionRemoveCommand*> transition_remove_commands_;
|
||||
|
||||
@@ -324,7 +324,6 @@ TrackPlaceBlockCommand::~TrackPlaceBlockCommand()
|
||||
{
|
||||
delete ripple_remove_command_;
|
||||
qDeleteAll(add_track_commands_);
|
||||
qDeleteAll(position_commands_);
|
||||
}
|
||||
|
||||
void TrackPlaceBlockCommand::redo()
|
||||
@@ -367,14 +366,6 @@ void TrackPlaceBlockCommand::redo()
|
||||
}
|
||||
|
||||
track->AppendBlock(insert_);
|
||||
|
||||
if (position_commands_.isEmpty()) {
|
||||
// Create position commands for insert and gap if necessary
|
||||
if (gap_) {
|
||||
position_commands_.append(new NodeSetPositionAsChildCommand(gap_, track, track, gap_->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
|
||||
if (!ripple_remove_command_) {
|
||||
@@ -384,10 +375,6 @@ void TrackPlaceBlockCommand::redo()
|
||||
|
||||
ripple_remove_command_->redo_now();
|
||||
track->InsertBlockAfter(insert_, ripple_remove_command_->GetInsertionIndex());
|
||||
|
||||
if (position_commands_.isEmpty()) {
|
||||
position_commands_.append(new NodeSetPositionAsChildCommand(insert_, track, track, insert_->index(), track->Blocks().size(), true));
|
||||
}
|
||||
}
|
||||
|
||||
track->EndOperation();
|
||||
@@ -397,18 +384,10 @@ void TrackPlaceBlockCommand::redo()
|
||||
foreach (const TimeRange &r, ranges_to_invalidate) {
|
||||
track->Node::InvalidateCache(r, Track::kBlockInput);
|
||||
}
|
||||
|
||||
for (int i=0; i<position_commands_.size(); i++) {
|
||||
position_commands_.at(i)->redo_now();
|
||||
}
|
||||
}
|
||||
|
||||
void TrackPlaceBlockCommand::undo()
|
||||
{
|
||||
for (int i=position_commands_.size()-1; i>=0; i--) {
|
||||
position_commands_.at(i)->undo_now();
|
||||
}
|
||||
|
||||
Track* t = timeline_->GetTrackAt(track_index_);
|
||||
|
||||
TimeRange insert_range(insert_->in(), insert_->out());
|
||||
|
||||
@@ -198,7 +198,6 @@ private:
|
||||
QVector<TimelineAddTrackCommand*> add_track_commands_;
|
||||
QObject memory_manager_;
|
||||
TrackRippleRemoveAreaCommand* ripple_remove_command_;
|
||||
QVector<NodeSetPositionAsChildCommand*> position_commands_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -61,12 +61,6 @@ void BlockSplitCommand::redo()
|
||||
// Insert new block
|
||||
track->InsertBlockAfter(new_block(), block_);
|
||||
|
||||
// Position the block
|
||||
if (!position_command_) {
|
||||
position_command_ = new NodeSetPositionAsChildCommand(new_block(), track, track, new_block()->index(), track->Blocks().size(), true);
|
||||
}
|
||||
position_command_->redo_now();
|
||||
|
||||
// If the block had an out transition, we move it to the new block
|
||||
moved_transition_ = NodeInput();
|
||||
|
||||
@@ -96,8 +90,6 @@ void BlockSplitCommand::undo()
|
||||
Node::ConnectEdge(block_, moved_transition_);
|
||||
}
|
||||
|
||||
position_command_->undo_now();
|
||||
|
||||
block_->set_length_and_media_out(old_length_);
|
||||
track->RippleRemoveBlock(new_block());
|
||||
|
||||
|
||||
@@ -31,15 +31,13 @@ public:
|
||||
block_(block),
|
||||
new_block_(nullptr),
|
||||
point_(point),
|
||||
reconnect_tree_command_(nullptr),
|
||||
position_command_(nullptr)
|
||||
reconnect_tree_command_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~BlockSplitCommand() override
|
||||
{
|
||||
delete reconnect_tree_command_;
|
||||
delete position_command_;
|
||||
}
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
@@ -70,8 +68,6 @@ private:
|
||||
|
||||
NodeInput moved_transition_;
|
||||
|
||||
NodeSetPositionAsChildCommand* position_command_;
|
||||
|
||||
};
|
||||
|
||||
class BlockSplitPreservingLinksCommand : public UndoCommand {
|
||||
|
||||
Reference in New Issue
Block a user