Skip to content

Commit

Permalink
start using source file for timelineundo again
Browse files Browse the repository at this point in the history
Less recompiling than having it all in a header
  • Loading branch information
itsmattkc committed Apr 22, 2021
1 parent f230bed commit 46e457f
Show file tree
Hide file tree
Showing 3 changed files with 252 additions and 194 deletions.
1 change: 1 addition & 0 deletions app/widget/timelinewidget/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ set(OLIVE_SOURCES
${OLIVE_SOURCES}
widget/timelinewidget/timelineandtrackview.cpp
widget/timelinewidget/timelineandtrackview.h
widget/timelinewidget/timelineundo.cpp
widget/timelinewidget/timelineundo.h
widget/timelinewidget/timelinewidget.cpp
widget/timelinewidget/timelinewidget.h
Expand Down
203 changes: 203 additions & 0 deletions app/widget/timelinewidget/timelineundo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2021 Olive Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/

#include "timelineundo.h"

namespace olive {

BlockTrimCommand::BlockTrimCommand(Track *track, Block* block, rational new_length, Timeline::MovementMode mode) :
prepped_(false),
track_(track),
block_(block),
new_length_(new_length),
mode_(mode),
deleted_adjacent_command_(nullptr),
trim_is_a_roll_edit_(false)
{
}

void BlockTrimCommand::redo()
{
if (!prepped_) {
prep();
prepped_ = true;
}

if (doing_nothing_) {
return;
}

// Begin an operation since we'll be doing a lot
track_->BeginOperation();

// Determine how much time to invalidate
TimeRange invalidate_range;

if (mode_ == Timeline::kTrimIn) {
invalidate_range = TimeRange(block_->in(), block_->in() + trim_diff_);
block_->set_length_and_media_in(new_length_);
} else {
invalidate_range = TimeRange(block_->out(), block_->out() - trim_diff_);
block_->set_length_and_media_out(new_length_);
}

if (needs_adjacent_) {
if (we_created_adjacent_) {
// Add adjacent and insert it
adjacent_->setParent(track_->parent());

if (mode_ == Timeline::kTrimIn) {
track_->InsertBlockBefore(adjacent_, block_);
} else {
track_->InsertBlockAfter(adjacent_, block_);
}
} else if (we_removed_adjacent_) {
track_->RippleRemoveBlock(adjacent_);

// It no longer inputs/outputs anything, remove it
if (remove_block_from_graph_ && NodeCanBeRemoved(adjacent_)) {
if (!deleted_adjacent_command_) {
deleted_adjacent_command_ = CreateAndRunRemoveCommand(adjacent_);
} else {
deleted_adjacent_command_->redo();
}
}
} else {
rational adjacent_length = adjacent_->length() + trim_diff_;

if (mode_ == Timeline::kTrimIn) {
adjacent_->set_length_and_media_out(adjacent_length);
} else {
adjacent_->set_length_and_media_in(adjacent_length);
}
}
}

track_->EndOperation();

if (dynamic_cast<TransitionBlock*>(block_)) {
// Whole transition needs to be invalidated
invalidate_range = block_->range();
}

track_->Node::InvalidateCache(invalidate_range, Track::kBlockInput);
}

void BlockTrimCommand::undo()
{
if (doing_nothing_) {
return;
}

track_->BeginOperation();

// Will be POSITIVE if trimming shorter and NEGATIVE if trimming longer
if (needs_adjacent_) {
if (we_created_adjacent_) {
// Adjacent is ours, just delete it
track_->RippleRemoveBlock(adjacent_);
adjacent_->setParent(&memory_manager_);
} else {
if (we_removed_adjacent_) {
if (deleted_adjacent_command_) {
// We deleted adjacent, restore it now
deleted_adjacent_command_->undo();
}

if (mode_ == Timeline::kTrimIn) {
track_->InsertBlockBefore(adjacent_, block_);
} else {
track_->InsertBlockAfter(adjacent_, block_);
}
} else {
rational adjacent_length = adjacent_->length() - trim_diff_;

if (mode_ == Timeline::kTrimIn) {
adjacent_->set_length_and_media_out(adjacent_length);
} else {
adjacent_->set_length_and_media_in(adjacent_length);
}
}
}
}

TimeRange invalidate_range;

if (mode_ == Timeline::kTrimIn) {
block_->set_length_and_media_in(old_length_);

invalidate_range = TimeRange(block_->in(), block_->in() + trim_diff_);
} else {
block_->set_length_and_media_out(old_length_);

invalidate_range = TimeRange(block_->out(), block_->out() - trim_diff_);
}

if (dynamic_cast<TransitionBlock*>(block_)) {
// Whole transition needs to be invalidated
invalidate_range = block_->range();
}

track_->EndOperation();

track_->Node::InvalidateCache(invalidate_range, Track::kBlockInput);
}

void BlockTrimCommand::prep()
{
// Store old length
old_length_ = block_->length();

// Determine if the length isn't changing, in which case we set a flag to do nothing
if ((doing_nothing_ = (old_length_ == new_length_))) {
return;
}

// Will be POSITIVE if trimming shorter and NEGATIVE if trimming longer
trim_diff_ = old_length_ - new_length_;

// Retrieve our adjacent block (or nullptr if none)
if (mode_ == Timeline::kTrimIn) {
adjacent_ = block_->previous();
} else {
adjacent_ = block_->next();
}

// Ignore when trimming the out with no adjacent, because the user must have trimmed the end
// of the last block in the track, so we don't need to do anything elses
needs_adjacent_ = (mode_ == Timeline::kTrimIn || adjacent_);

if (needs_adjacent_) {
// If we're trimming shorter, we need an adjacent, so check if we have a viable one.
we_created_adjacent_ = (trim_diff_ > 0 && (!adjacent_ || (!dynamic_cast<GapBlock*>(adjacent_) && !trim_is_a_roll_edit_)));

if (we_created_adjacent_) {
// We shortened but don't have a viable adjacent to lengthen, so we create one
adjacent_ = new GapBlock();
adjacent_->set_length_and_media_out(trim_diff_);
} else {
// Determine if we're removing the adjacent
rational adjacent_length = adjacent_->length() + trim_diff_;
we_removed_adjacent_ = adjacent_length.isNull();
}
}
}

}
Loading

0 comments on commit 46e457f

Please sign in to comment.