implemented media out value to allow speed changes in clips
This commit is contained in:
@@ -38,6 +38,11 @@ Block::Block() :
|
||||
media_in_input_->SetConnectable(false);
|
||||
media_in_input_->set_data_type(NodeParam::kRational);
|
||||
AddInput(media_in_input_);
|
||||
|
||||
media_out_input_ = new NodeInput("media_out_in");
|
||||
media_out_input_->SetConnectable(false);
|
||||
media_out_input_->set_data_type(NodeParam::kRational);
|
||||
AddInput(media_out_input_);
|
||||
}
|
||||
|
||||
QString Block::Category() const
|
||||
@@ -81,12 +86,31 @@ void Block::set_length(const rational &length)
|
||||
length_input_->set_value_at_time(0, QVariant::fromValue(length));
|
||||
}
|
||||
|
||||
void Block::set_length_and_media_out(const rational &length)
|
||||
{
|
||||
Q_ASSERT(length > 0);
|
||||
|
||||
if (length == this->length()) {
|
||||
return;
|
||||
}
|
||||
|
||||
set_media_out(media_out() + (length - this->length()));
|
||||
|
||||
set_length(length);
|
||||
}
|
||||
|
||||
void Block::set_length_and_media_in(const rational &length)
|
||||
{
|
||||
Q_ASSERT(length > 0);
|
||||
|
||||
if (length == this->length()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate media_in adjustment
|
||||
set_media_in(media_in() + (this->length() - length));
|
||||
|
||||
// Set the length
|
||||
// Set the length without setting media out
|
||||
set_length(length);
|
||||
}
|
||||
|
||||
@@ -120,6 +144,21 @@ void Block::set_media_in(const rational &media_in)
|
||||
media_in_input_->set_value_at_time(0, QVariant::fromValue(media_in));
|
||||
}
|
||||
|
||||
rational Block::media_out() const
|
||||
{
|
||||
return media_out_input_->get_value_at_time(0).value<rational>();
|
||||
}
|
||||
|
||||
void Block::set_media_out(const rational &media_out)
|
||||
{
|
||||
media_out_input_->set_value_at_time(0, QVariant::fromValue(media_out));
|
||||
}
|
||||
|
||||
rational Block::media_length() const
|
||||
{
|
||||
return media_out() - media_in();
|
||||
}
|
||||
|
||||
const QString &Block::block_name() const
|
||||
{
|
||||
return block_name_;
|
||||
@@ -137,7 +176,7 @@ rational Block::SequenceToMediaTime(const rational &sequence_time) const
|
||||
return sequence_time;
|
||||
}
|
||||
|
||||
return sequence_time - in() + media_in();
|
||||
return (sequence_time - in() + media_in()) * media_length() / length();
|
||||
}
|
||||
|
||||
rational Block::MediaToSequenceTime(const rational &media_time) const
|
||||
@@ -147,7 +186,7 @@ rational Block::MediaToSequenceTime(const rational &media_time) const
|
||||
return media_time;
|
||||
}
|
||||
|
||||
return media_time - media_in() + in();
|
||||
return media_time * length() / media_length() - media_in() + in();
|
||||
}
|
||||
|
||||
void Block::CopyParameters(const Block *source, Block *dest)
|
||||
@@ -161,7 +200,7 @@ void Block::CopyParameters(const Block *source, Block *dest)
|
||||
|
||||
dst_t->set_in_and_out_offset(src_t->in_offset(), src_t->out_offset());
|
||||
} else {
|
||||
dest->set_length(source->length());
|
||||
dest->set_length_and_media_out(source->length());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ public:
|
||||
|
||||
rational length() const;
|
||||
virtual void set_length(const rational &length);
|
||||
virtual void set_length_and_media_out(const rational &length);
|
||||
virtual void set_length_and_media_in(const rational &length);
|
||||
|
||||
Block* previous();
|
||||
@@ -67,6 +68,11 @@ public:
|
||||
rational media_in() const;
|
||||
void set_media_in(const rational& media_in);
|
||||
|
||||
rational media_out() const;
|
||||
void set_media_out(const rational& media_out);
|
||||
|
||||
rational media_length() const;
|
||||
|
||||
const QString& block_name() const;
|
||||
void set_block_name(const QString& name);
|
||||
|
||||
@@ -106,6 +112,7 @@ protected:
|
||||
private:
|
||||
NodeInput* length_input_;
|
||||
NodeInput* media_in_input_;
|
||||
NodeInput* media_out_input_;
|
||||
|
||||
rational in_point_;
|
||||
rational out_point_;
|
||||
|
||||
@@ -37,7 +37,7 @@ void TransitionBlock::Retranslate()
|
||||
in_block_input_->set_name(tr("To"));
|
||||
}
|
||||
|
||||
void TransitionBlock::set_length(const rational &length)
|
||||
void TransitionBlock::set_length_and_media_out(const rational &length)
|
||||
{
|
||||
Q_UNUSED(length)
|
||||
qCritical() << "Set length is not permitted on a transition";
|
||||
@@ -70,5 +70,5 @@ void TransitionBlock::set_in_and_out_offset(const rational &in_offset, const rat
|
||||
|
||||
void TransitionBlock::RecalculateLength()
|
||||
{
|
||||
Block::set_length(in_offset_ + out_offset_);
|
||||
Block::set_length_and_media_out(in_offset_ + out_offset_);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ public:
|
||||
|
||||
virtual void Retranslate() override;
|
||||
|
||||
virtual void set_length(const rational &length) override;
|
||||
virtual void set_length_and_media_out(const rational &length) override;
|
||||
virtual void set_length_and_media_in(const rational &length) override;
|
||||
|
||||
const rational& in_offset() const;
|
||||
|
||||
@@ -404,7 +404,7 @@ void TimelineWidget::DeleteSelectedInternal(const QList<Block *> blocks, bool re
|
||||
} else if (!previous_is_gap && !next_is_gap) {
|
||||
// Make new gap and replace old Block with it for now
|
||||
GapBlock* gap = new GapBlock();
|
||||
gap->set_length(b->length());
|
||||
gap->set_length_and_media_out(b->length());
|
||||
|
||||
new NodeAddCommand(static_cast<NodeGraph*>(b->parent()),
|
||||
gap,
|
||||
@@ -536,7 +536,7 @@ void TimelineWidget::RippleEditTo(olive::timeline::MovementMode mode, bool inser
|
||||
GapBlock* gap = nullptr;
|
||||
if (insert_gaps) {
|
||||
gap = new GapBlock();
|
||||
gap->set_length(ripple_length);
|
||||
gap->set_length_and_media_out(ripple_length);
|
||||
new NodeAddCommand(static_cast<NodeGraph*>(track->parent()), gap, command);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ void TimelineWidget::AddTool::MouseRelease(TimelineViewMouseEvent *event)
|
||||
QUndoCommand* command = new QUndoCommand();
|
||||
|
||||
ClipBlock* clip = new ClipBlock();
|
||||
clip->set_length(ghost_->AdjustedLength());
|
||||
clip->set_length_and_media_out(ghost_->AdjustedLength());
|
||||
new NodeAddCommand(static_cast<NodeGraph*>(parent()->timeline_node_->parent()),
|
||||
clip,
|
||||
command);
|
||||
|
||||
@@ -217,7 +217,7 @@ void TimelineWidget::ImportTool::DragDrop(TimelineViewMouseEvent *event)
|
||||
StreamPtr footage_stream = ghost->data(TimelineViewGhostItem::kAttachedFootage).value<StreamPtr>();
|
||||
|
||||
ClipBlock* clip = new ClipBlock();
|
||||
clip->set_length(ghost->Length());
|
||||
clip->set_length_and_media_out(ghost->Length());
|
||||
clip->set_block_name(footage_stream->footage()->name());
|
||||
new NodeAddCommand(dst_graph, clip, command);
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ void TimelineWidget::RippleTool::MouseReleaseInternal(TimelineViewMouseEvent *ev
|
||||
// Make sure there's actually a gap being created
|
||||
if (ghost->AdjustedLength() > 0) {
|
||||
GapBlock* gap = new GapBlock();
|
||||
gap->set_length(ghost->AdjustedLength());
|
||||
gap->set_length_and_media_out(ghost->AdjustedLength());
|
||||
new NodeAddCommand(static_cast<NodeGraph*>(parent()->timeline_node_->parent()), gap, command);
|
||||
|
||||
Block* block_to_append_gap_to = Node::ValueToPtr<Block>(ghost->data(TimelineViewGhostItem::kReferenceBlock));
|
||||
|
||||
@@ -43,7 +43,7 @@ void TimelineWidget::RollingTool::MouseReleaseInternal(TimelineViewMouseEvent *e
|
||||
if (b->previous() == nullptr) {
|
||||
// We'll need to insert a gap here, so we'll do a Place command instead
|
||||
GapBlock* gap = new GapBlock();
|
||||
gap->set_length(ghost->Length());
|
||||
gap->set_length_and_media_out(ghost->Length());
|
||||
new NodeAddCommand(static_cast<NodeGraph*>(b->parent()),
|
||||
gap,
|
||||
command);
|
||||
|
||||
@@ -46,7 +46,7 @@ void TimelineWidget::SlideTool::MouseReleaseInternal(TimelineViewMouseEvent *eve
|
||||
new BlockResizeCommand(b, ghost->AdjustedLength(), command);
|
||||
} else if (ghost->mode() == olive::timeline::kMove && b->previous() == nullptr) {
|
||||
GapBlock* gap = new GapBlock();
|
||||
gap->set_length(ghost->InAdjustment());
|
||||
gap->set_length_and_media_out(ghost->InAdjustment());
|
||||
new NodeAddCommand(static_cast<NodeGraph*>(b->parent()), gap, command);
|
||||
new TrackPrependBlockCommand(parent()->GetTrackFromReference(ghost->Track()), gap, command);
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ void TimelineWidget::SlipTool::MouseReleaseInternal(TimelineViewMouseEvent *even
|
||||
Block* b = Node::ValueToPtr<Block>(ghost->data(TimelineViewGhostItem::kAttachedBlock));
|
||||
|
||||
new BlockSetMediaInCommand(b, ghost->GetAdjustedMediaIn(), command);
|
||||
new BlockSetMediaOutCommand(b, ghost->GetAdjustedMediaIn() + b->media_length(), command);
|
||||
}
|
||||
|
||||
olive::undo_stack.pushIfHasChildren(command);
|
||||
|
||||
@@ -49,12 +49,12 @@ BlockResizeCommand::BlockResizeCommand(Block *block, rational new_length, QUndoC
|
||||
|
||||
void BlockResizeCommand::redo()
|
||||
{
|
||||
block_->set_length(new_length_);
|
||||
block_->set_length_and_media_out(new_length_);
|
||||
}
|
||||
|
||||
void BlockResizeCommand::undo()
|
||||
{
|
||||
block_->set_length(old_length_);
|
||||
block_->set_length_and_media_out(old_length_);
|
||||
}
|
||||
|
||||
BlockResizeWithMediaInCommand::BlockResizeWithMediaInCommand(Block *block, rational new_length, QUndoCommand *parent) :
|
||||
@@ -93,6 +93,24 @@ void BlockSetMediaInCommand::undo()
|
||||
block_->set_media_in(old_media_in_);
|
||||
}
|
||||
|
||||
BlockSetMediaOutCommand::BlockSetMediaOutCommand(Block *block, rational new_media_out, QUndoCommand *parent) :
|
||||
QUndoCommand(parent),
|
||||
block_(block),
|
||||
old_media_out_(block->media_out()),
|
||||
new_media_out_(new_media_out)
|
||||
{
|
||||
}
|
||||
|
||||
void BlockSetMediaOutCommand::redo()
|
||||
{
|
||||
block_->set_media_in(new_media_out_);
|
||||
}
|
||||
|
||||
void BlockSetMediaOutCommand::undo()
|
||||
{
|
||||
block_->set_media_in(old_media_out_);
|
||||
}
|
||||
|
||||
TrackRippleRemoveBlockCommand::TrackRippleRemoveBlockCommand(TrackOutput *track, Block *block, QUndoCommand *parent) :
|
||||
QUndoCommand(parent),
|
||||
track_(track),
|
||||
@@ -186,7 +204,7 @@ void TrackRippleRemoveAreaCommand::redo()
|
||||
Block* copy = CreateSplitBlock(splice_, out_);
|
||||
|
||||
splice_original_length_ = splice_->length();
|
||||
splice_->set_length(out_ - splice_->in());
|
||||
splice_->set_length_and_media_out(out_ - splice_->in());
|
||||
|
||||
static_cast<NodeGraph*>(track_->parent())->AddNode(copy);
|
||||
Node::CopyInputs(splice_, copy);
|
||||
@@ -224,7 +242,7 @@ void TrackRippleRemoveAreaCommand::redo()
|
||||
|
||||
// If we picked up a block to trim the out point of
|
||||
if (trim_out_old_length_ != trim_out_new_length_) {
|
||||
trim_out_->set_length(trim_out_new_length_);
|
||||
trim_out_->set_length_and_media_out(trim_out_new_length_);
|
||||
}
|
||||
|
||||
// If we were given a block to insert, insert it here
|
||||
@@ -257,7 +275,7 @@ void TrackRippleRemoveAreaCommand::undo()
|
||||
|
||||
// If we picked up a block to trim the out point of
|
||||
if (trim_out_old_length_ != trim_out_new_length_) {
|
||||
trim_out_->set_length(trim_out_old_length_);
|
||||
trim_out_->set_length_and_media_out(trim_out_old_length_);
|
||||
}
|
||||
|
||||
// Remove all blocks that are flagged for removal
|
||||
@@ -281,7 +299,7 @@ void TrackRippleRemoveAreaCommand::undo()
|
||||
// Remove node
|
||||
TakeNodeFromParentGraph(trim_in_, &memory_manager_);
|
||||
|
||||
splice_->set_length(splice_original_length_);
|
||||
splice_->set_length_and_media_out(splice_original_length_);
|
||||
}
|
||||
|
||||
track_->UnblockInvalidateCache();
|
||||
@@ -318,7 +336,7 @@ void TrackPlaceBlockCommand::redo()
|
||||
if (in_ > track_->track_length()) {
|
||||
// If so, insert a gap here
|
||||
gap_ = new GapBlock();
|
||||
gap_->set_length(in_ - track_->track_length());
|
||||
gap_->set_length_and_media_out(in_ - track_->track_length());
|
||||
static_cast<NodeGraph*>(track_->parent())->AddNode(gap_);
|
||||
track_->AppendBlock(gap_);
|
||||
}
|
||||
@@ -376,7 +394,7 @@ void BlockSplitCommand::redo()
|
||||
{
|
||||
track_->BlockInvalidateCache();
|
||||
|
||||
block_->set_length(new_length_);
|
||||
block_->set_length_and_media_out(new_length_);
|
||||
|
||||
static_cast<NodeGraph*>(block_->parent())->AddNode(new_block_);
|
||||
Node::CopyInputs(block_, new_block_);
|
||||
@@ -396,7 +414,7 @@ void BlockSplitCommand::undo()
|
||||
{
|
||||
track_->BlockInvalidateCache();
|
||||
|
||||
block_->set_length(old_length_);
|
||||
block_->set_length_and_media_out(old_length_);
|
||||
track_->RippleRemoveBlock(new_block_);
|
||||
|
||||
TakeNodeFromParentGraph(new_block_, &memory_manager_);
|
||||
|
||||
@@ -67,6 +67,19 @@ private:
|
||||
rational new_media_in_;
|
||||
};
|
||||
|
||||
class BlockSetMediaOutCommand : public QUndoCommand {
|
||||
public:
|
||||
BlockSetMediaOutCommand(Block* block, rational new_media_out, QUndoCommand* parent = nullptr);
|
||||
|
||||
virtual void redo() override;
|
||||
virtual void undo() override;
|
||||
|
||||
private:
|
||||
Block* block_;
|
||||
rational old_media_out_;
|
||||
rational new_media_out_;
|
||||
};
|
||||
|
||||
class TrackRippleRemoveBlockCommand : public QUndoCommand {
|
||||
public:
|
||||
TrackRippleRemoveBlockCommand(TrackOutput* track, Block* block, QUndoCommand* parent = nullptr);
|
||||
|
||||
Reference in New Issue
Block a user