some timeline refactoring, preparing for rewrites

This commit is contained in:
itsmattkc
2021-01-09 11:41:33 +11:00
parent 3337be07e5
commit 8f729203fc
62 changed files with 638 additions and 1180 deletions
+63 -78
View File
@@ -29,85 +29,85 @@
namespace olive {
const double TrackOutput::kTrackHeightDefault = 3.0;
const double TrackOutput::kTrackHeightMinimum = 1.5;
const double TrackOutput::kTrackHeightInterval = 0.5;
const double Track::kTrackHeightDefault = 3.0;
const double Track::kTrackHeightMinimum = 1.5;
const double Track::kTrackHeightInterval = 0.5;
TrackOutput::TrackOutput() :
track_type_(Timeline::kTrackTypeNone),
Track::Track() :
track_type_(Track::kNone),
index_(-1),
locked_(false)
{
block_input_ = new NodeInput(this, QStringLiteral("block_in"), NodeValue::kNone);
block_input_->SetKeyframable(false);
connect(block_input_, &NodeInput::InputConnected, this, &TrackOutput::BlockConnected);
connect(block_input_, &NodeInput::InputDisconnected, this, &TrackOutput::BlockDisconnected);
connect(block_input_, &NodeInput::InputConnected, this, &Track::BlockConnected);
connect(block_input_, &NodeInput::InputDisconnected, this, &Track::BlockDisconnected);
// Since blocks are time based, we can handle the invalidate timing a little more intelligently
// on our end
IgnoreConnectionSignalsFrom(block_input_);
IgnoreInvalidationsFrom(block_input_);
muted_input_ = new NodeInput(this, QStringLiteral("muted_in"), NodeValue::kBoolean);
muted_input_->SetKeyframable(false);
connect(muted_input_, &NodeInput::ValueChanged, this, &TrackOutput::MutedInputValueChanged);
connect(muted_input_, &NodeInput::ValueChanged, this, &Track::MutedInputValueChanged);
// Set default height
track_height_ = kTrackHeightDefault;
}
TrackOutput::~TrackOutput()
Track::~Track()
{
DisconnectAll();
}
void TrackOutput::set_track_type(const Timeline::TrackType &track_type)
void Track::set_track_type(const Type &track_type)
{
track_type_ = track_type;
}
const Timeline::TrackType& TrackOutput::track_type() const
const Track::Type& Track::track_type() const
{
return track_type_;
}
Node *TrackOutput::copy() const
Node *Track::copy() const
{
return new TrackOutput();
return new Track();
}
QString TrackOutput::Name() const
QString Track::Name() const
{
return tr("Track");
}
QString TrackOutput::id() const
QString Track::id() const
{
return QStringLiteral("org.olivevideoeditor.Olive.track");
}
QVector<Node::CategoryID> TrackOutput::Category() const
QVector<Node::CategoryID> Track::Category() const
{
return {kCategoryTimeline};
}
QString TrackOutput::Description() const
QString Track::Description() const
{
return tr("Node for representing and processing a single array of Blocks sorted by time. Also represents the end of "
"a Sequence.");
}
const double &TrackOutput::GetTrackHeight() const
const double &Track::GetTrackHeight() const
{
return track_height_;
}
void TrackOutput::SetTrackHeight(const double &height)
void Track::SetTrackHeight(const double &height)
{
track_height_ = height;
emit TrackHeightChangedInPixels(GetTrackHeightInPixels());
}
void TrackOutput::LoadInternal(QXmlStreamReader *reader, XMLNodeData &)
void Track::LoadInternal(QXmlStreamReader *reader, XMLNodeData &)
{
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("height")) {
@@ -118,12 +118,12 @@ void TrackOutput::LoadInternal(QXmlStreamReader *reader, XMLNodeData &)
}
}
void TrackOutput::SaveInternal(QXmlStreamWriter *writer) const
void Track::SaveInternal(QXmlStreamWriter *writer) const
{
writer->writeTextElement(QStringLiteral("height"), QString::number(GetTrackHeight()));
}
void TrackOutput::Retranslate()
void Track::Retranslate()
{
Node::Retranslate();
@@ -131,19 +131,19 @@ void TrackOutput::Retranslate()
muted_input_->set_name(tr("Muted"));
}
const int &TrackOutput::Index()
const int &Track::Index()
{
return index_;
}
void TrackOutput::SetIndex(const int &index)
void Track::SetIndex(const int &index)
{
index_ = index;
emit IndexChanged(index);
}
Block *TrackOutput::BlockContainingTime(const rational &time) const
Block *Track::BlockContainingTime(const rational &time) const
{
foreach (Block* block, block_cache_) {
if (block->in() < time && block->out() > time) {
@@ -156,7 +156,7 @@ Block *TrackOutput::BlockContainingTime(const rational &time) const
return nullptr;
}
Block *TrackOutput::NearestBlockBefore(const rational &time) const
Block *Track::NearestBlockBefore(const rational &time) const
{
foreach (Block* block, block_cache_) {
// Blocks are sorted by time, so the first Block who's out point is at/after this time is the correct Block
@@ -168,7 +168,7 @@ Block *TrackOutput::NearestBlockBefore(const rational &time) const
return nullptr;
}
Block *TrackOutput::NearestBlockBeforeOrAt(const rational &time) const
Block *Track::NearestBlockBeforeOrAt(const rational &time) const
{
foreach (Block* block, block_cache_) {
// Blocks are sorted by time, so the first Block who's out point is at/after this time is the correct Block
@@ -180,7 +180,7 @@ Block *TrackOutput::NearestBlockBeforeOrAt(const rational &time) const
return nullptr;
}
Block *TrackOutput::NearestBlockAfterOrAt(const rational &time) const
Block *Track::NearestBlockAfterOrAt(const rational &time) const
{
foreach (Block* block, block_cache_) {
// Blocks are sorted by time, so the first Block after this time is the correct Block
@@ -192,7 +192,7 @@ Block *TrackOutput::NearestBlockAfterOrAt(const rational &time) const
return nullptr;
}
Block *TrackOutput::NearestBlockAfter(const rational &time) const
Block *Track::NearestBlockAfter(const rational &time) const
{
foreach (Block* block, block_cache_) {
// Blocks are sorted by time, so the first Block after this time is the correct Block
@@ -204,7 +204,7 @@ Block *TrackOutput::NearestBlockAfter(const rational &time) const
return nullptr;
}
Block *TrackOutput::BlockAtTime(const rational &time) const
Block *Track::BlockAtTime(const rational &time) const
{
if (IsMuted()) {
return nullptr;
@@ -225,7 +225,7 @@ Block *TrackOutput::BlockAtTime(const rational &time) const
return nullptr;
}
QVector<Block *> TrackOutput::BlocksAtTimeRange(const TimeRange &range) const
QVector<Block *> Track::BlocksAtTimeRange(const TimeRange &range) const
{
QVector<Block*> list;
@@ -245,7 +245,7 @@ QVector<Block *> TrackOutput::BlocksAtTimeRange(const TimeRange &range) const
return list;
}
void TrackOutput::InvalidateCache(const TimeRange& range, const InputConnection& from)
void Track::InvalidateCache(const TimeRange& range, const InputConnection& from)
{
TimeRange limited;
@@ -267,12 +267,12 @@ void TrackOutput::InvalidateCache(const TimeRange& range, const InputConnection&
Node::InvalidateCache(limited, from);
}
void TrackOutput::InsertBlockBefore(Block* block, Block* after)
void Track::InsertBlockBefore(Block* block, Block* after)
{
InsertBlockAtIndex(block, block_cache_.indexOf(after));
}
void TrackOutput::InsertBlockAfter(Block *block, Block *before)
void Track::InsertBlockAfter(Block *block, Block *before)
{
int before_index = block_cache_.indexOf(before);
@@ -285,7 +285,7 @@ void TrackOutput::InsertBlockAfter(Block *block, Block *before)
}
}
void TrackOutput::PrependBlock(Block *block)
void Track::PrependBlock(Block *block)
{
BeginOperation();
@@ -298,7 +298,7 @@ void TrackOutput::PrependBlock(Block *block)
Node::InvalidateCache(TimeRange(0, track_length()), InputConnection());
}
void TrackOutput::InsertBlockAtIndex(Block *block, int index)
void Track::InsertBlockAtIndex(Block *block, int index)
{
BeginOperation();
@@ -311,7 +311,7 @@ void TrackOutput::InsertBlockAtIndex(Block *block, int index)
Node::InvalidateCache(TimeRange(block->in(), track_length()));
}
void TrackOutput::AppendBlock(Block *block)
void Track::AppendBlock(Block *block)
{
BeginOperation();
@@ -324,7 +324,7 @@ void TrackOutput::AppendBlock(Block *block)
Node::InvalidateCache(TimeRange(block->in(), track_length()));
}
void TrackOutput::RippleRemoveBlock(Block *block)
void Track::RippleRemoveBlock(Block *block)
{
BeginOperation();
@@ -338,7 +338,7 @@ void TrackOutput::RippleRemoveBlock(Block *block)
Node::InvalidateCache(TimeRange(remove_in, qMax(track_length(), remove_out)));
}
void TrackOutput::ReplaceBlock(Block *old, Block *replace)
void Track::ReplaceBlock(Block *old, Block *replace)
{
BeginOperation();
@@ -357,57 +357,44 @@ void TrackOutput::ReplaceBlock(Block *old, Block *replace)
}
}
TrackOutput *TrackOutput::TrackFromBlock(const Block *block)
{
foreach (const InputConnection& conn, block->edges()) {
TrackOutput* track = dynamic_cast<TrackOutput*>(conn.input->parent());
if (track) {
return track;
}
}
return nullptr;
}
const rational &TrackOutput::track_length() const
const rational &Track::track_length() const
{
return track_length_;
}
QString TrackOutput::GetDefaultTrackName(Timeline::TrackType type, int index)
QString Track::GetDefaultTrackName(Track::Type type, int index)
{
// Starts tracks at 1 rather than 0
int user_friendly_index = index+1;
switch (type) {
case Timeline::kTrackTypeVideo: return tr("Video %1").arg(user_friendly_index);
case Timeline::kTrackTypeAudio: return tr("Audio %1").arg(user_friendly_index);
case Timeline::kTrackTypeSubtitle: return tr("Subtitle %1").arg(user_friendly_index);
case Timeline::kTrackTypeNone:
case Timeline::kTrackTypeCount:
case Track::kVideo: return tr("Video %1").arg(user_friendly_index);
case Track::kAudio: return tr("Audio %1").arg(user_friendly_index);
case Track::kSubtitle: return tr("Subtitle %1").arg(user_friendly_index);
case Track::kNone:
case Track::kCount:
break;
}
return tr("Track %1").arg(user_friendly_index);
}
bool TrackOutput::IsMuted() const
bool Track::IsMuted() const
{
return muted_input_->GetStandardValue().toBool();
}
bool TrackOutput::IsLocked() const
bool Track::IsLocked() const
{
return locked_;
}
NodeInput *TrackOutput::block_input() const
NodeInput *Track::block_input() const
{
return block_input_;
}
void TrackOutput::Hash(QCryptographicHash &hash, const rational &time) const
void Track::Hash(QCryptographicHash &hash, const rational &time) const
{
Block* b = BlockAtTime(time);
@@ -417,18 +404,18 @@ void TrackOutput::Hash(QCryptographicHash &hash, const rational &time) const
}
}
void TrackOutput::SetMuted(bool e)
void Track::SetMuted(bool e)
{
muted_input_->SetStandardValue(e);
Node::InvalidateCache(TimeRange(0, track_length()));
}
void TrackOutput::SetLocked(bool e)
void Track::SetLocked(bool e)
{
locked_ = e;
}
void TrackOutput::UpdateInOutFrom(int index)
void Track::UpdateInOutFrom(int index)
{
// Find block just before this one to find the last out point
rational last_out = (index == 0) ? 0 : block_cache_.at(index - 1)->out();
@@ -442,20 +429,18 @@ void TrackOutput::UpdateInOutFrom(int index)
last_out += b->length();
b->set_out(last_out);
emit b->Refreshed();
}
// Update track length
SetLengthInternal(last_out);
}
int TrackOutput::GetInputIndexFromCacheIndex(int cache_index)
int Track::GetInputIndexFromCacheIndex(int cache_index)
{
return GetInputIndexFromCacheIndex(block_cache_.at(cache_index));
}
int TrackOutput::GetInputIndexFromCacheIndex(Block *block)
int Track::GetInputIndexFromCacheIndex(Block *block)
{
for (int i=0; i<block_input_->ArraySize(); i++) {
if (block_input_->GetConnectedNode(i) == block) {
@@ -466,7 +451,7 @@ int TrackOutput::GetInputIndexFromCacheIndex(Block *block)
return -1;
}
void TrackOutput::SetLengthInternal(const rational &r, bool invalidate)
void Track::SetLengthInternal(const rational &r, bool invalidate)
{
if (r != track_length_) {
TimeRange invalidate_range(track_length_, r);
@@ -480,7 +465,7 @@ void TrackOutput::SetLengthInternal(const rational &r, bool invalidate)
}
}
void TrackOutput::BlockConnected(Node *node, int element)
void Track::BlockConnected(Node *node, int element)
{
if (element == -1) {
// User has replaced the entire array, we will invalidate everything
@@ -541,7 +526,7 @@ void TrackOutput::BlockConnected(Node *node, int element)
UpdateInOutFrom(cache_index);
// Connect to the block
connect(block, &Block::LengthChanged, this, &TrackOutput::BlockLengthChanged);
connect(block, &Block::LengthChanged, this, &Track::BlockLengthChanged);
// Invalidate cache now that block should have an in point
Node::InvalidateCache(TimeRange(block->in(), track_length()));
@@ -550,7 +535,7 @@ void TrackOutput::BlockConnected(Node *node, int element)
emit BlockAdded(block);
}
void TrackOutput::BlockDisconnected(Node* node, int element)
void Track::BlockDisconnected(Node* node, int element)
{
if (element == -1) {
// User has replaced the entire array, we will invalidate everything
@@ -592,14 +577,14 @@ void TrackOutput::BlockDisconnected(Node* node, int element)
SetLengthInternal(block_cache_.last()->out());
}
disconnect(b, &Block::LengthChanged, this, &TrackOutput::BlockLengthChanged);
disconnect(b, &Block::LengthChanged, this, &Track::BlockLengthChanged);
emit BlockRemoved(b);
Node::InvalidateCache(invalidate_range);
}
void TrackOutput::BlockLengthChanged()
void Track::BlockLengthChanged()
{
// Assumes sender is a Block
Block* b = static_cast<Block*>(sender());
@@ -615,7 +600,7 @@ void TrackOutput::BlockLengthChanged()
Node::InvalidateCache(invalidate_region);
}
void TrackOutput::MutedInputValueChanged()
void Track::MutedInputValueChanged()
{
emit MutedChanged(IsMuted());
}
+15 -9
View File
@@ -30,16 +30,24 @@ namespace olive {
/**
* @brief A time traversal Node for sorting through one channel/track of Blocks
*/
class TrackOutput : public Node
class Track : public Node
{
Q_OBJECT
public:
TrackOutput();
enum Type {
kNone = -1,
kVideo,
kAudio,
kSubtitle,
kCount
};
virtual ~TrackOutput() override;
Track();
const Timeline::TrackType& track_type() const;
void set_track_type(const Timeline::TrackType& track_type);
virtual ~Track() override;
const Track::Type& track_type() const;
void set_track_type(const Track::Type& track_type);
virtual Node* copy() const override;
@@ -199,11 +207,9 @@ public:
*/
void ReplaceBlock(Block* old, Block* replace);
static TrackOutput* TrackFromBlock(const Block *block);
const rational& track_length() const;
static QString GetDefaultTrackName(Timeline::TrackType type, int index);
static QString GetDefaultTrackName(Track::Type type, int index);
bool IsMuted() const;
@@ -282,7 +288,7 @@ private:
NodeInput* muted_input_;
Timeline::TrackType track_type_;
Track::Type track_type_;
rational track_length_;
+20 -20
View File
@@ -27,7 +27,7 @@
namespace olive {
TrackList::TrackList(ViewerOutput *parent, const Timeline::TrackType &type, NodeInput *track_input) :
TrackList::TrackList(ViewerOutput *parent, const Track::Type &type, NodeInput *track_input) :
QObject(parent),
track_input_(track_input),
type_(type)
@@ -36,14 +36,14 @@ TrackList::TrackList(ViewerOutput *parent, const Timeline::TrackType &type, Node
connect(track_input_, &NodeInput::InputDisconnected, this, &TrackList::TrackDisconnected);
}
const Timeline::TrackType &TrackList::type() const
const Track::Type &TrackList::type() const
{
return type_;
}
void TrackList::TrackAddedBlock(Block *block)
{
emit BlockAdded(block, static_cast<TrackOutput*>(sender())->Index());
emit BlockAdded(block, static_cast<Track*>(sender())->Index());
}
void TrackList::TrackRemovedBlock(Block *block)
@@ -51,12 +51,12 @@ void TrackList::TrackRemovedBlock(Block *block)
emit BlockRemoved(block);
}
const QVector<TrackOutput *> &TrackList::GetTracks() const
const QVector<Track *> &TrackList::GetTracks() const
{
return track_cache_;
}
TrackOutput *TrackList::GetTrackAt(int index) const
Track *TrackList::GetTrackAt(int index) const
{
if (index < track_cache_.size()) {
return track_cache_.at(index);
@@ -83,16 +83,16 @@ void TrackList::TrackConnected(Node *node, int element)
return;
}
TrackOutput* track = dynamic_cast<TrackOutput*>(node);
Track* track = dynamic_cast<Track*>(node);
if (!track) {
return;
}
// Find "real" index
TrackOutput* next = nullptr;
Track* next = nullptr;
for (int i=element+1; i<track_input_->ArraySize(); i++) {
next = dynamic_cast<TrackOutput*>(track_input_->GetConnectedNode(i));
next = dynamic_cast<Track*>(track_input_->GetConnectedNode(i));
if (next) {
break;
@@ -114,10 +114,10 @@ void TrackList::TrackConnected(Node *node, int element)
// Update track indexes in the list (including this track)
UpdateTrackIndexesFrom(track_index);
connect(track, &TrackOutput::BlockAdded, this, &TrackList::TrackAddedBlock);
connect(track, &TrackOutput::BlockRemoved, this, &TrackList::TrackRemovedBlock);
connect(track, &TrackOutput::TrackLengthChanged, this, &TrackList::UpdateTotalLength);
connect(track, &TrackOutput::TrackHeightChangedInPixels, this, &TrackList::TrackHeightChangedSlot);
connect(track, &Track::BlockAdded, this, &TrackList::TrackAddedBlock);
connect(track, &Track::BlockRemoved, this, &TrackList::TrackRemovedBlock);
connect(track, &Track::TrackLengthChanged, this, &TrackList::UpdateTotalLength);
connect(track, &Track::TrackHeightChangedInPixels, this, &TrackList::TrackHeightChangedSlot);
track->set_track_type(type_);
@@ -134,7 +134,7 @@ void TrackList::TrackDisconnected(Node *node, int element)
{
Q_UNUSED(element)
TrackOutput* track = dynamic_cast<TrackOutput*>(node);
Track* track = dynamic_cast<Track*>(node);
if (!track) {
return;
@@ -150,12 +150,12 @@ void TrackList::TrackDisconnected(Node *node, int element)
emit TrackRemoved(track);
track->SetIndex(-1);
track->set_track_type(Timeline::kTrackTypeNone);
track->set_track_type(Track::kNone);
disconnect(track, &TrackOutput::BlockAdded, this, &TrackList::TrackAddedBlock);
disconnect(track, &TrackOutput::BlockRemoved, this, &TrackList::TrackRemovedBlock);
disconnect(track, &TrackOutput::TrackLengthChanged, this, &TrackList::UpdateTotalLength);
disconnect(track, &TrackOutput::TrackHeightChangedInPixels, this, &TrackList::TrackHeightChangedSlot);
disconnect(track, &Track::BlockAdded, this, &TrackList::TrackAddedBlock);
disconnect(track, &Track::BlockRemoved, this, &TrackList::TrackRemovedBlock);
disconnect(track, &Track::TrackLengthChanged, this, &TrackList::UpdateTotalLength);
disconnect(track, &Track::TrackHeightChangedInPixels, this, &TrackList::TrackHeightChangedSlot);
emit TrackListChanged();
@@ -178,7 +178,7 @@ void TrackList::UpdateTotalLength()
{
total_length_ = 0;
foreach (TrackOutput* track, track_cache_) {
foreach (Track* track, track_cache_) {
if (track) {
total_length_ = qMax(total_length_, track->track_length());
}
@@ -189,7 +189,7 @@ void TrackList::UpdateTotalLength()
void TrackList::TrackHeightChangedSlot(int height)
{
emit TrackHeightChanged(static_cast<TrackOutput*>(sender())->Index(), height);
emit TrackHeightChanged(static_cast<Track*>(sender())->Index(), height);
}
}
+8 -8
View File
@@ -35,13 +35,13 @@ class TrackList : public QObject
{
Q_OBJECT
public:
TrackList(ViewerOutput *parent, const Timeline::TrackType& type, NodeInput* track_input);
TrackList(ViewerOutput *parent, const Track::Type& type, NodeInput* track_input);
const Timeline::TrackType& type() const;
const Track::Type& type() const;
const QVector<TrackOutput*>& GetTracks() const;
const QVector<Track*>& GetTracks() const;
TrackOutput* GetTrackAt(int index) const;
Track* GetTrackAt(int index) const;
const rational& GetTotalLength() const;
@@ -59,9 +59,9 @@ signals:
void BlockRemoved(Block* block);
void TrackAdded(TrackOutput* track);
void TrackAdded(Track* track);
void TrackRemoved(TrackOutput* track);
void TrackRemoved(Track* track);
void TrackListChanged();
@@ -75,13 +75,13 @@ private:
/**
* @brief A cache of connected Tracks
*/
QVector<TrackOutput*> track_cache_;
QVector<Track*> track_cache_;
NodeInput* track_input_;
rational total_length_;
enum Timeline::TrackType type_;
enum Track::Type type_;
private slots:
/**