implement entire project in nodes
Project items are now represented directly in nodes opening up more versatility and possibilities. This is the first iteration of this and will be buggy. Need to test thoroughly.
This commit is contained in:
@@ -66,7 +66,7 @@ public:
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
return block_->parent()->project();
|
||||
return block_->project();
|
||||
}
|
||||
|
||||
virtual void redo() override
|
||||
@@ -97,7 +97,7 @@ public:
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
return block_->parent()->project();
|
||||
return block_->project();
|
||||
}
|
||||
|
||||
virtual void redo() override
|
||||
@@ -147,7 +147,7 @@ public:
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
return track_->parent()->project();
|
||||
return track_->project();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -371,7 +371,7 @@ public:
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
return block_->parent()->project();
|
||||
return block_->project();
|
||||
}
|
||||
|
||||
virtual void redo() override
|
||||
@@ -401,7 +401,7 @@ public:
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
return track_->parent()->project();
|
||||
return track_->project();
|
||||
}
|
||||
|
||||
virtual void redo() override
|
||||
@@ -434,7 +434,7 @@ public:
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
return track_->parent()->project();
|
||||
return track_->project();
|
||||
}
|
||||
|
||||
virtual void redo() override
|
||||
@@ -463,7 +463,7 @@ public:
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
return block_->parent()->project();
|
||||
return block_->project();
|
||||
}
|
||||
|
||||
virtual void redo() override
|
||||
@@ -500,7 +500,7 @@ public:
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
return block_->parent()->project();
|
||||
return block_->project();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -652,7 +652,7 @@ public:
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
return blocks_.first()->parent()->project();
|
||||
return blocks_.first()->project();
|
||||
}
|
||||
|
||||
virtual void redo() override
|
||||
@@ -749,7 +749,7 @@ public:
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
return track_->parent()->project();
|
||||
return track_->project();
|
||||
}
|
||||
|
||||
virtual void redo() override
|
||||
@@ -815,7 +815,7 @@ public:
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
return track_->parent()->project();
|
||||
return track_->project();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1024,7 +1024,7 @@ public:
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
return static_cast<ViewerOutput*>(list_->parent())->parent()->project();
|
||||
return list_->parent()->project();
|
||||
}
|
||||
|
||||
virtual void redo() override
|
||||
@@ -1049,9 +1049,9 @@ public:
|
||||
// We can optimize here by simply shifting the whole cache forward instead of re-caching
|
||||
// everything following this time
|
||||
if (list_->type() == Track::kVideo) {
|
||||
static_cast<ViewerOutput*>(list_->parent())->ShiftVideoCache(out_, in_);
|
||||
list_->parent()->ShiftVideoCache(out_, in_);
|
||||
} else if (list_->type() == Track::kAudio) {
|
||||
static_cast<ViewerOutput*>(list_->parent())->ShiftAudioCache(out_, in_);
|
||||
list_->parent()->ShiftAudioCache(out_, in_);
|
||||
}
|
||||
|
||||
foreach (Track* track, working_tracks_) {
|
||||
@@ -1076,9 +1076,9 @@ public:
|
||||
// We can optimize here by simply shifting the whole cache forward instead of re-caching
|
||||
// everything following this time
|
||||
if (list_->type() == Track::kVideo) {
|
||||
static_cast<ViewerOutput*>(list_->parent())->ShiftVideoCache(in_, out_);
|
||||
list_->parent()->ShiftVideoCache(in_, out_);
|
||||
} else if (list_->type() == Track::kAudio) {
|
||||
static_cast<ViewerOutput*>(list_->parent())->ShiftAudioCache(in_, out_);
|
||||
list_->parent()->ShiftAudioCache(in_, out_);
|
||||
}
|
||||
|
||||
foreach (Track* track, working_tracks_) {
|
||||
@@ -1114,7 +1114,7 @@ private:
|
||||
|
||||
class TimelineRippleRemoveAreaCommand : public MultiUndoCommand {
|
||||
public:
|
||||
TimelineRippleRemoveAreaCommand(ViewerOutput* timeline, rational in, rational out) :
|
||||
TimelineRippleRemoveAreaCommand(Sequence* timeline, rational in, rational out) :
|
||||
timeline_(timeline)
|
||||
{
|
||||
for (int i=0; i<Track::kCount; i++) {
|
||||
@@ -1126,11 +1126,11 @@ public:
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
return timeline_->parent()->project();
|
||||
return timeline_->project();
|
||||
}
|
||||
|
||||
private:
|
||||
ViewerOutput* timeline_;
|
||||
Sequence* timeline_;
|
||||
|
||||
};
|
||||
|
||||
@@ -1155,7 +1155,7 @@ public:
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
return static_cast<ViewerOutput*>(track_list_->parent())->parent()->project();
|
||||
return track_list_->parent()->project();
|
||||
}
|
||||
|
||||
virtual void redo() override
|
||||
@@ -1325,9 +1325,9 @@ private:
|
||||
if (all_tracks_unlocked_) {
|
||||
// We rippled all the tracks, so we can shift the whole cache
|
||||
if (track_list_->type() == Track::kVideo) {
|
||||
static_cast<ViewerOutput*>(track_list_->parent())->ShiftVideoCache(pre_latest_out, post_latest_out);
|
||||
track_list_->parent()->ShiftVideoCache(pre_latest_out, post_latest_out);
|
||||
} else if (track_list_->type() == Track::kAudio) {
|
||||
static_cast<ViewerOutput*>(track_list_->parent())->ShiftAudioCache(pre_latest_out, post_latest_out);
|
||||
track_list_->parent()->ShiftAudioCache(pre_latest_out, post_latest_out);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1383,7 +1383,7 @@ public:
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
return timeline_->GetParentGraph()->project();
|
||||
return timeline_->parent()->project();
|
||||
}
|
||||
|
||||
virtual void redo() override
|
||||
@@ -1419,9 +1419,9 @@ public:
|
||||
QString relevant_input;
|
||||
|
||||
if (timeline_->type() == Track::kVideo) {
|
||||
relevant_input = ViewerOutput::kTextureInput;
|
||||
relevant_input = Sequence::kTextureInput;
|
||||
} else {
|
||||
relevant_input = ViewerOutput::kSamplesInput;
|
||||
relevant_input = Sequence::kSamplesInput;
|
||||
}
|
||||
|
||||
if (!timeline_->parent()->IsInputConnected(relevant_input)) {
|
||||
@@ -1505,7 +1505,7 @@ public:
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
return timeline_->GetParentGraph()->project();
|
||||
return timeline_->parent()->project();
|
||||
}
|
||||
|
||||
virtual void redo() override
|
||||
@@ -1604,7 +1604,7 @@ public:
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
return track_->parent()->project();
|
||||
return track_->project();
|
||||
}
|
||||
|
||||
virtual void redo() override
|
||||
@@ -1637,7 +1637,7 @@ public:
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
return block_->parent()->project();
|
||||
return block_->project();
|
||||
}
|
||||
|
||||
virtual void redo() override
|
||||
@@ -1784,7 +1784,7 @@ private:
|
||||
|
||||
class TimelineRippleDeleteGapsAtRegionsCommand : public UndoCommand {
|
||||
public:
|
||||
TimelineRippleDeleteGapsAtRegionsCommand(ViewerOutput* vo, const TimeRangeList& regions) :
|
||||
TimelineRippleDeleteGapsAtRegionsCommand(Sequence* vo, const TimeRangeList& regions) :
|
||||
timeline_(vo),
|
||||
regions_(regions)
|
||||
{
|
||||
@@ -1797,7 +1797,7 @@ public:
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
return timeline_->parent()->project();
|
||||
return timeline_->project();
|
||||
}
|
||||
|
||||
virtual void redo() override
|
||||
@@ -1851,7 +1851,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
ViewerOutput* timeline_;
|
||||
Sequence* timeline_;
|
||||
TimeRangeList regions_;
|
||||
|
||||
QVector<UndoCommand*> commands_;
|
||||
@@ -1941,7 +1941,7 @@ public:
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
return block_->parent()->project();
|
||||
return block_->project();
|
||||
}
|
||||
|
||||
virtual void redo() override
|
||||
@@ -1986,7 +1986,7 @@ public:
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
return track_->parent()->project();
|
||||
return track_->project();
|
||||
}
|
||||
|
||||
virtual void redo() override
|
||||
@@ -2153,7 +2153,7 @@ public:
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
return static_cast<ViewerOutput*>(track_list_->parent())->parent()->project();
|
||||
return track_list_->parent()->project();
|
||||
}
|
||||
|
||||
virtual void redo() override
|
||||
@@ -2166,9 +2166,9 @@ public:
|
||||
if (all_tracks_unlocked_) {
|
||||
// Optimize by shifting over since we have a constant amount of time being inserted
|
||||
if (track_list_->type() == Track::kVideo) {
|
||||
static_cast<ViewerOutput*>(track_list_->parent())->ShiftVideoCache(point_, point_ + length_);
|
||||
track_list_->parent()->ShiftVideoCache(point_, point_ + length_);
|
||||
} else if (track_list_->type() == Track::kAudio) {
|
||||
static_cast<ViewerOutput*>(track_list_->parent())->ShiftAudioCache(point_, point_ + length_);
|
||||
track_list_->parent()->ShiftAudioCache(point_, point_ + length_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2205,9 +2205,9 @@ public:
|
||||
if (all_tracks_unlocked_) {
|
||||
// Optimize by shifting over since we have a constant amount of time being inserted
|
||||
if (track_list_->type() == Track::kVideo) {
|
||||
static_cast<ViewerOutput*>(track_list_->parent())->ShiftVideoCache(point_ + length_, point_);
|
||||
track_list_->parent()->ShiftVideoCache(point_ + length_, point_);
|
||||
} else if (track_list_->type() == Track::kAudio) {
|
||||
static_cast<ViewerOutput*>(track_list_->parent())->ShiftAudioCache(point_ + length_, point_);
|
||||
track_list_->parent()->ShiftAudioCache(point_ + length_, point_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2326,7 +2326,7 @@ public:
|
||||
|
||||
virtual Project* GetRelevantProject() const override
|
||||
{
|
||||
return track_->parent()->project();
|
||||
return track_->project();
|
||||
}
|
||||
|
||||
virtual void redo() override
|
||||
|
||||
@@ -218,7 +218,7 @@ void TimelineWidget::ScaleChangedEvent(const double &scale)
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineWidget::ConnectNodeInternal(ViewerOutput *n)
|
||||
void TimelineWidget::ConnectNodeInternal(Sequence *n)
|
||||
{
|
||||
connect(n, &ViewerOutput::TrackAdded, this, &TimelineWidget::AddTrack);
|
||||
connect(n, &ViewerOutput::TrackRemoved, this, &TimelineWidget::RemoveTrack);
|
||||
@@ -229,23 +229,24 @@ void TimelineWidget::ConnectNodeInternal(ViewerOutput *n)
|
||||
SetTimebase(n->video_params().time_base());
|
||||
|
||||
for (int i=0;i<views_.size();i++) {
|
||||
Sequence* s = static_cast<Sequence*>(n);
|
||||
Track::Type track_type = static_cast<Track::Type>(i);
|
||||
TimelineView* view = views_.at(i)->view();
|
||||
TrackList* track_list = n->track_list(track_type);
|
||||
TrackList* track_list = s->track_list(track_type);
|
||||
TrackView* track_view = views_.at(i)->track_view();
|
||||
|
||||
track_view->ConnectTrackList(track_list);
|
||||
view->ConnectTrackList(track_list);
|
||||
|
||||
// Defer to the track to make all the block UI items necessary
|
||||
const QVector<Track*> tracks = n->track_list(track_type)->GetTracks();
|
||||
const QVector<Track*> tracks = s->track_list(track_type)->GetTracks();
|
||||
foreach (Track* track, tracks) {
|
||||
AddTrack(track);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineWidget::DisconnectNodeInternal(ViewerOutput *n)
|
||||
void TimelineWidget::DisconnectNodeInternal(Sequence *n)
|
||||
{
|
||||
disconnect(n, &ViewerOutput::TrackAdded, this, &TimelineWidget::AddTrack);
|
||||
disconnect(n, &ViewerOutput::TrackRemoved, this, &TimelineWidget::RemoveTrack);
|
||||
@@ -253,7 +254,8 @@ void TimelineWidget::DisconnectNodeInternal(ViewerOutput *n)
|
||||
|
||||
DeselectAll();
|
||||
|
||||
foreach (Track* track, n->GetTracks()) {
|
||||
Sequence* s = static_cast<Sequence*>(n);
|
||||
foreach (Track* track, s->GetTracks()) {
|
||||
RemoveTrack(track);
|
||||
}
|
||||
|
||||
@@ -383,7 +385,7 @@ void TimelineWidget::SplitAtPlayhead()
|
||||
bool some_blocks_are_selected = false;
|
||||
|
||||
// Get all blocks at the playhead
|
||||
foreach (Track* track, GetConnectedNode()->GetTracks()) {
|
||||
foreach (Track* track, sequence()->GetTracks()) {
|
||||
Block* b = track->BlockContainingTime(playhead_time);
|
||||
|
||||
if (b && b->type() == Block::kClip) {
|
||||
@@ -488,7 +490,7 @@ void TimelineWidget::DeleteSelected(bool ripple)
|
||||
range_list.insert(TimeRange(b->in(), b->out()));
|
||||
}
|
||||
|
||||
command->add_child(new TimelineRippleDeleteGapsAtRegionsCommand(GetConnectedNode(), range_list));
|
||||
command->add_child(new TimelineRippleDeleteGapsAtRegionsCommand(sequence(), range_list));
|
||||
}
|
||||
|
||||
Core::instance()->undo_stack()->pushIfHasChildren(command);
|
||||
@@ -501,7 +503,7 @@ void TimelineWidget::IncreaseTrackHeight()
|
||||
}
|
||||
|
||||
// Increase the height of each track by one "unit"
|
||||
foreach (Track* t, GetConnectedNode()->GetTracks()) {
|
||||
foreach (Track* t, sequence()->GetTracks()) {
|
||||
t->SetTrackHeight(t->GetTrackHeight() + Track::kTrackHeightInterval);
|
||||
}
|
||||
}
|
||||
@@ -513,7 +515,7 @@ void TimelineWidget::DecreaseTrackHeight()
|
||||
}
|
||||
|
||||
// Decrease the height of each track by one "unit"
|
||||
foreach (Track* t, GetConnectedNode()->GetTracks()) {
|
||||
foreach (Track* t, sequence()->GetTracks()) {
|
||||
t->SetTrackHeight(qMax(t->GetTrackHeight() - Track::kTrackHeightInterval, Track::kTrackHeightMinimum));
|
||||
}
|
||||
}
|
||||
@@ -614,7 +616,7 @@ void TimelineWidget::Paste(bool insert)
|
||||
|
||||
foreach (const BlockPasteData& bpd, paste_data) {
|
||||
qDebug() << "Placing" << bpd.block;
|
||||
command->add_child(new TrackPlaceBlockCommand(GetConnectedNode()->track_list(bpd.track_type),
|
||||
command->add_child(new TrackPlaceBlockCommand(sequence()->track_list(bpd.track_type),
|
||||
bpd.track_index,
|
||||
bpd.block,
|
||||
paste_start + bpd.in));
|
||||
@@ -635,12 +637,12 @@ void TimelineWidget::DeleteInToOut(bool ripple)
|
||||
|
||||
if (ripple) {
|
||||
|
||||
command->add_child(new TimelineRippleRemoveAreaCommand(GetConnectedNode(),
|
||||
command->add_child(new TimelineRippleRemoveAreaCommand(sequence(),
|
||||
GetConnectedTimelinePoints()->workarea()->in(),
|
||||
GetConnectedTimelinePoints()->workarea()->out()));
|
||||
|
||||
} else {
|
||||
QVector<Track*> unlocked_tracks = GetConnectedNode()->GetUnlockedTracks();
|
||||
QVector<Track*> unlocked_tracks = sequence()->GetUnlockedTracks();
|
||||
|
||||
foreach (Track* track, unlocked_tracks) {
|
||||
GapBlock* gap = new GapBlock();
|
||||
@@ -650,7 +652,7 @@ void TimelineWidget::DeleteInToOut(bool ripple)
|
||||
command->add_child(new NodeAddCommand(static_cast<NodeGraph*>(track->parent()),
|
||||
gap));
|
||||
|
||||
command->add_child(new TrackPlaceBlockCommand(GetConnectedNode()->track_list(track->type()),
|
||||
command->add_child(new TrackPlaceBlockCommand(sequence()->track_list(track->type()),
|
||||
track->Index(),
|
||||
gap,
|
||||
GetConnectedTimelinePoints()->workarea()->in()));
|
||||
@@ -698,7 +700,7 @@ void TimelineWidget::SetColorLabel(int index)
|
||||
void TimelineWidget::InsertGapsAt(const rational &earliest_point, const rational &insert_length, MultiUndoCommand *command)
|
||||
{
|
||||
for (int i=0;i<Track::kCount;i++) {
|
||||
command->add_child(new TrackListInsertGaps(GetConnectedNode()->track_list(static_cast<Track::Type>(i)),
|
||||
command->add_child(new TrackListInsertGaps(sequence()->track_list(static_cast<Track::Type>(i)),
|
||||
earliest_point,
|
||||
insert_length));
|
||||
}
|
||||
@@ -706,7 +708,7 @@ void TimelineWidget::InsertGapsAt(const rational &earliest_point, const rational
|
||||
|
||||
Track *TimelineWidget::GetTrackFromReference(const Track::Reference &ref) const
|
||||
{
|
||||
return GetConnectedNode()->track_list(ref.type())->GetTrackAt(ref.index());
|
||||
return sequence()->track_list(ref.type())->GetTrackAt(ref.index());
|
||||
}
|
||||
|
||||
int TimelineWidget::GetTrackY(const Track::Reference &ref)
|
||||
@@ -970,7 +972,7 @@ void TimelineWidget::ShowSequenceDialog()
|
||||
return;
|
||||
}
|
||||
|
||||
SequenceDialog sd(static_cast<Sequence*>(GetConnectedNode()->parent()), SequenceDialog::kExisting, this);
|
||||
SequenceDialog sd(sequence(), SequenceDialog::kExisting, this);
|
||||
sd.exec();
|
||||
}
|
||||
|
||||
@@ -1127,7 +1129,7 @@ QVector<Timeline::EditToInfo> TimelineWidget::GetEditToInfo(const rational& play
|
||||
Timeline::MovementMode mode)
|
||||
{
|
||||
// Get list of unlocked tracks
|
||||
QVector<Track*> tracks = GetConnectedNode()->GetUnlockedTracks();
|
||||
QVector<Track*> tracks = sequence()->GetUnlockedTracks();
|
||||
|
||||
// Create list to cache nearest times and the blocks at this point
|
||||
QVector<Timeline::EditToInfo> info_list(tracks.size());
|
||||
@@ -1206,7 +1208,7 @@ void TimelineWidget::RippleTo(Timeline::MovementMode mode)
|
||||
rational in_ripple = qMin(closest_point_to_playhead, playhead_time);
|
||||
rational out_ripple = qMax(closest_point_to_playhead, playhead_time);
|
||||
|
||||
TimelineRippleRemoveAreaCommand* c = new TimelineRippleRemoveAreaCommand(GetConnectedNode(),
|
||||
TimelineRippleRemoveAreaCommand* c = new TimelineRippleRemoveAreaCommand(sequence(),
|
||||
in_ripple,
|
||||
out_ripple);
|
||||
|
||||
@@ -1290,7 +1292,7 @@ QVector<Block *> TimelineWidget::GetBlocksInGlobalRect(const QPoint &p1, const Q
|
||||
mapped_rect = mapped_rect.normalized();
|
||||
|
||||
// Get tracks
|
||||
TrackList* track_list = GetConnectedNode()->track_list(static_cast<Track::Type>(i));
|
||||
TrackList* track_list = sequence()->track_list(static_cast<Track::Type>(i));
|
||||
|
||||
for (int j=0; j<track_list->GetTrackCount(); j++) {
|
||||
int track_top = view->GetTrackY(j);
|
||||
|
||||
@@ -91,6 +91,14 @@ public:
|
||||
|
||||
void SetColorLabel(int index);
|
||||
|
||||
/**
|
||||
* @brief Timelines should always be connected to sequences
|
||||
*/
|
||||
Sequence* sequence() const
|
||||
{
|
||||
return static_cast<Sequence*>(GetConnectedNode());
|
||||
}
|
||||
|
||||
const QVector<Block*>& GetSelectedBlocks() const
|
||||
{
|
||||
return selected_blocks_;
|
||||
@@ -237,8 +245,8 @@ protected:
|
||||
virtual void TimeChangedEvent(const int64_t &) override;
|
||||
virtual void ScaleChangedEvent(const double &) override;
|
||||
|
||||
virtual void ConnectNodeInternal(ViewerOutput* n) override;
|
||||
virtual void DisconnectNodeInternal(ViewerOutput* n) override;
|
||||
virtual void ConnectNodeInternal(Sequence* n) override;
|
||||
virtual void DisconnectNodeInternal(Sequence* n) override;
|
||||
|
||||
virtual void CopyNodesToClipboardInternal(QXmlStreamWriter *writer, void* userdata) override;
|
||||
virtual void PasteNodesFromClipboardInternal(QXmlStreamReader *reader, XMLNodeData &xml_node_data, void* userdata) override;
|
||||
|
||||
@@ -102,7 +102,7 @@ void AddTool::MouseRelease(TimelineViewMouseEvent *event)
|
||||
command->add_child(new NodeAddCommand(graph,
|
||||
clip));
|
||||
|
||||
command->add_child(new TrackPlaceBlockCommand(parent()->GetConnectedNode()->track_list(track.type()),
|
||||
command->add_child(new TrackPlaceBlockCommand(static_cast<Sequence*>(parent()->GetConnectedNode())->track_list(track.type()),
|
||||
track.index(),
|
||||
clip,
|
||||
ghost_->GetAdjustedIn()));
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#include "node/audio/volume/volume.h"
|
||||
#include "node/distort/transform/transformdistortnode.h"
|
||||
#include "node/generator/matrix/matrix.h"
|
||||
#include "node/input/media/media.h"
|
||||
#include "node/math/math/math.h"
|
||||
#include "project/item/sequence/sequence.h"
|
||||
#include "widget/nodeview/nodeviewundo.h"
|
||||
@@ -97,7 +96,7 @@ void ImportTool::DragEnter(TimelineViewMouseEvent *event)
|
||||
Item* item = reinterpret_cast<Item*>(item_ptr);
|
||||
|
||||
// Check if Item is Footage
|
||||
if (item->type() == Item::kFootage) {
|
||||
if (dynamic_cast<Footage*>(item)) {
|
||||
|
||||
Footage* f = static_cast<Footage*>(item);
|
||||
|
||||
@@ -225,8 +224,10 @@ void ImportTool::FootageToGhosts(rational ghost_start, const QVector<DraggedFoot
|
||||
quint64 enabled_streams = footage.streams();
|
||||
|
||||
// Loop through all streams in footage
|
||||
foreach (Stream* stream, footage.footage()->streams()) {
|
||||
Track::Type track_type = TrackTypeFromStreamType(stream->type());
|
||||
foreach (const QString& output, footage.footage()->outputs()) {
|
||||
Footage::StreamReference ref = footage.footage()->GetReferenceFromOutput(output);
|
||||
|
||||
Track::Type track_type = TrackTypeFromStreamType(ref.type());
|
||||
|
||||
quint64 cached_enabled_streams = enabled_streams;
|
||||
enabled_streams >>= 1;
|
||||
@@ -239,8 +240,10 @@ void ImportTool::FootageToGhosts(rational ghost_start, const QVector<DraggedFoot
|
||||
|
||||
TimelineViewGhostItem* ghost = new TimelineViewGhostItem();
|
||||
|
||||
if (stream->type() == Stream::kVideo
|
||||
&& static_cast<VideoStream*>(stream)->video_type() == VideoStream::kVideoTypeStill) {
|
||||
Stream stream = ref.GetStream();
|
||||
|
||||
if (ref.type() == Stream::kVideo
|
||||
&& stream.video_type() == Stream::kVideoTypeStill) {
|
||||
// Stream is essentially length-less - we may use the default still image length in config,
|
||||
// or we may use another stream's length depending on the circumstance
|
||||
contains_image_stream = true;
|
||||
@@ -251,7 +254,7 @@ void ImportTool::FootageToGhosts(rational ghost_start, const QVector<DraggedFoot
|
||||
footage_duration = qMax(footage_duration, footage.footage()->workarea()->range().length());
|
||||
ghost->SetMediaIn(footage.footage()->workarea()->in());
|
||||
} else {
|
||||
int64_t stream_duration = Timecode::rescale_timestamp_ceil(stream->duration(), stream->timebase(), dest_tb);
|
||||
int64_t stream_duration = Timecode::rescale_timestamp_ceil(stream.duration(), stream.timebase(), dest_tb);
|
||||
footage_duration = qMax(footage_duration, Timecode::timestamp_to_time(stream_duration, dest_tb));
|
||||
}
|
||||
}
|
||||
@@ -261,7 +264,7 @@ void ImportTool::FootageToGhosts(rational ghost_start, const QVector<DraggedFoot
|
||||
// Increment track count for this track type
|
||||
track_offsets[track_type]++;
|
||||
|
||||
ghost->SetData(TimelineViewGhostItem::kAttachedFootage, Node::PtrToValue(stream));
|
||||
ghost->SetData(TimelineViewGhostItem::kAttachedFootage, QVariant::fromValue(TimelineViewGhostItem::AttachedFootage({footage.footage(), output})));
|
||||
ghost->SetMode(Timeline::kMove);
|
||||
|
||||
footage_ghosts.append(ghost);
|
||||
@@ -310,12 +313,12 @@ void ImportTool::DropGhosts(bool insert)
|
||||
MultiUndoCommand* command = new MultiUndoCommand();
|
||||
|
||||
NodeGraph* dst_graph = nullptr;
|
||||
ViewerOutput* viewer_node = nullptr;
|
||||
Sequence* open_sequence = nullptr;
|
||||
Sequence* sequence = nullptr;
|
||||
bool open_sequence = false;
|
||||
|
||||
if (parent()->GetConnectedNode()) {
|
||||
viewer_node = parent()->GetConnectedNode();
|
||||
dst_graph = static_cast<NodeGraph*>(parent()->GetConnectedNode()->parent());
|
||||
sequence = parent()->GetConnectedNode();
|
||||
dst_graph = parent()->GetConnectedNode()->parent();
|
||||
} else {
|
||||
// There's no active timeline here, ask the user what to do
|
||||
|
||||
@@ -382,19 +385,18 @@ void ImportTool::DropGhosts(bool insert)
|
||||
}
|
||||
|
||||
if (sequence_is_valid) {
|
||||
new_sequence->add_default_nodes();
|
||||
dst_graph = Core::instance()->GetActiveProject();
|
||||
|
||||
command->add_child(new ProjectViewModel::AddItemCommand(Core::instance()->GetActiveProjectModel(),
|
||||
Core::instance()->GetSelectedFolderInActiveProject(),
|
||||
new_sequence));
|
||||
command->add_child(new NodeAddCommand(dst_graph, new_sequence));
|
||||
command->add_child(new NodeEdgeAddCommand(Core::instance()->GetSelectedFolderInActiveProject(), NodeInput(new_sequence, Item::kParentInput)));
|
||||
new_sequence->add_default_nodes(command);
|
||||
|
||||
FootageToGhosts(0, dragged_footage_, new_sequence->video_params().time_base(), 0);
|
||||
|
||||
dst_graph = new_sequence;
|
||||
viewer_node = new_sequence->viewer_output();
|
||||
sequence = new_sequence;
|
||||
|
||||
// Set this as the sequence to open
|
||||
open_sequence = new_sequence;
|
||||
open_sequence = true;
|
||||
} else {
|
||||
// If the sequence is valid, ownership is passed to AddItemCommand.
|
||||
// Otherwise, we're responsible for deleting it.
|
||||
@@ -416,38 +418,32 @@ void ImportTool::DropGhosts(bool insert)
|
||||
for (int i=0;i<parent()->GetGhostItems().size();i++) {
|
||||
TimelineViewGhostItem* ghost = parent()->GetGhostItems().at(i);
|
||||
|
||||
Stream* footage_stream = Node::ValueToPtr<Stream>(ghost->GetData(TimelineViewGhostItem::kAttachedFootage));
|
||||
TimelineViewGhostItem::AttachedFootage footage_stream = ghost->GetData(TimelineViewGhostItem::kAttachedFootage).value<TimelineViewGhostItem::AttachedFootage>();
|
||||
|
||||
NodeOutput corresponding_output(footage_stream.footage, footage_stream.output);
|
||||
|
||||
ClipBlock* clip = new ClipBlock();
|
||||
clip->set_media_in(ghost->GetMediaIn());
|
||||
clip->set_length_and_media_out(ghost->GetLength());
|
||||
clip->SetLabel(footage_stream->footage()->name());
|
||||
clip->SetLabel(footage_stream.footage->GetLabel());
|
||||
command->add_child(new NodeAddCommand(dst_graph, clip));
|
||||
|
||||
switch (footage_stream->type()) {
|
||||
switch (footage_stream.footage->GetTypeFromOutput(footage_stream.output)) {
|
||||
case Stream::kVideo:
|
||||
{
|
||||
MediaInput* video_input = new MediaInput();
|
||||
video_input->SetStream(footage_stream);
|
||||
command->add_child(new NodeAddCommand(dst_graph, video_input));
|
||||
|
||||
TransformDistortNode* transform = new TransformDistortNode();
|
||||
command->add_child(new NodeAddCommand(dst_graph, transform));
|
||||
|
||||
command->add_child(new NodeEdgeAddCommand(video_input, NodeInput(transform, TransformDistortNode::kTextureInput)));
|
||||
command->add_child(new NodeEdgeAddCommand(corresponding_output, NodeInput(transform, TransformDistortNode::kTextureInput)));
|
||||
command->add_child(new NodeEdgeAddCommand(transform, NodeInput(clip, ClipBlock::kBufferIn)));
|
||||
break;
|
||||
}
|
||||
case Stream::kAudio:
|
||||
{
|
||||
MediaInput* audio_input = new MediaInput();
|
||||
audio_input->SetStream(footage_stream);
|
||||
command->add_child(new NodeAddCommand(dst_graph, audio_input));
|
||||
|
||||
VolumeNode* volume_node = new VolumeNode();
|
||||
command->add_child(new NodeAddCommand(dst_graph, volume_node));
|
||||
|
||||
command->add_child(new NodeEdgeAddCommand(audio_input, NodeInput(volume_node, VolumeNode::kSamplesInput)));
|
||||
command->add_child(new NodeEdgeAddCommand(corresponding_output, NodeInput(volume_node, VolumeNode::kSamplesInput)));
|
||||
command->add_child(new NodeEdgeAddCommand(volume_node, NodeInput(clip, ClipBlock::kBufferIn)));
|
||||
break;
|
||||
}
|
||||
@@ -455,7 +451,7 @@ void ImportTool::DropGhosts(bool insert)
|
||||
break;
|
||||
}
|
||||
|
||||
command->add_child(new TrackPlaceBlockCommand(viewer_node->track_list(ghost->GetAdjustedTrack().type()),
|
||||
command->add_child(new TrackPlaceBlockCommand(sequence->track_list(ghost->GetAdjustedTrack().type()),
|
||||
ghost->GetAdjustedTrack().index(),
|
||||
clip,
|
||||
ghost->GetAdjustedIn()));
|
||||
@@ -464,9 +460,9 @@ void ImportTool::DropGhosts(bool insert)
|
||||
|
||||
// Link any clips so far that share the same Footage with this one
|
||||
for (int j=0;j<i;j++) {
|
||||
Stream* footage_compare = Node::ValueToPtr<Stream>(parent()->GetGhostItems().at(j)->GetData(TimelineViewGhostItem::kAttachedFootage));
|
||||
TimelineViewGhostItem::AttachedFootage footage_compare = parent()->GetGhostItems().at(j)->GetData(TimelineViewGhostItem::kAttachedFootage).value<TimelineViewGhostItem::AttachedFootage>();
|
||||
|
||||
if (footage_compare->footage() == footage_stream->footage()) {
|
||||
if (footage_compare.footage == footage_stream.footage) {
|
||||
Block::Link(block_items.at(j), clip);
|
||||
}
|
||||
}
|
||||
@@ -474,7 +470,7 @@ void ImportTool::DropGhosts(bool insert)
|
||||
}
|
||||
|
||||
if (open_sequence) {
|
||||
command->add_child(new OpenSequenceCommand(open_sequence));
|
||||
command->add_child(new OpenSequenceCommand(sequence));
|
||||
}
|
||||
|
||||
Core::instance()->undo_stack()->pushIfHasChildren(command);
|
||||
|
||||
@@ -644,7 +644,7 @@ void PointerTool::FinishDrag(TimelineViewMouseEvent *event)
|
||||
}
|
||||
|
||||
const Track::Reference& track_ref = p.ghost->GetAdjustedTrack();
|
||||
command->add_child(new TrackPlaceBlockCommand(parent()->GetConnectedNode()->track_list(track_ref.type()),
|
||||
command->add_child(new TrackPlaceBlockCommand(sequence()->track_list(track_ref.type()),
|
||||
track_ref.index(),
|
||||
block,
|
||||
p.ghost->GetAdjustedIn()));
|
||||
|
||||
@@ -58,7 +58,7 @@ void RippleTool::InitiateDrag(Block *clicked_item,
|
||||
}
|
||||
|
||||
// For each track that does NOT have a ghost, we need to make one for Gaps
|
||||
foreach (Track* track, parent()->GetConnectedNode()->GetTracks()) {
|
||||
foreach (Track* track, sequence()->GetTracks()) {
|
||||
if (track->IsLocked()) {
|
||||
continue;
|
||||
}
|
||||
@@ -144,7 +144,7 @@ void RippleTool::FinishDrag(TimelineViewMouseEvent *event)
|
||||
|
||||
for (int i=0;i<info_list.size();i++) {
|
||||
if (!info_list.at(i).isEmpty()) {
|
||||
command->add_child(new TrackListRippleToolCommand(parent()->GetConnectedNode()->track_list(static_cast<Track::Type>(i)),
|
||||
command->add_child(new TrackListRippleToolCommand(sequence()->track_list(static_cast<Track::Type>(i)),
|
||||
info_list.at(i),
|
||||
movement,
|
||||
drag_movement_mode()));
|
||||
|
||||
@@ -39,6 +39,11 @@ TimelineWidget *TimelineTool::parent()
|
||||
return parent_;
|
||||
}
|
||||
|
||||
Sequence *TimelineTool::sequence()
|
||||
{
|
||||
return parent_->sequence();
|
||||
}
|
||||
|
||||
Timeline::MovementMode TimelineTool::FlipTrimMode(const Timeline::MovementMode &trim_mode)
|
||||
{
|
||||
if (trim_mode == Timeline::kTrimIn) {
|
||||
|
||||
@@ -53,6 +53,8 @@ public:
|
||||
|
||||
TimelineWidget* parent();
|
||||
|
||||
Sequence* sequence();
|
||||
|
||||
static Timeline::MovementMode FlipTrimMode(const Timeline::MovementMode& trim_mode);
|
||||
|
||||
static rational SnapMovementToTimebase(const rational& start, rational movement, const rational& timebase);
|
||||
|
||||
@@ -126,7 +126,7 @@ void TransitionTool::MouseRelease(TimelineViewMouseEvent *event)
|
||||
command->add_child(new NodeAddCommand(static_cast<NodeGraph*>(parent()->GetConnectedNode()->parent()),
|
||||
transition));
|
||||
|
||||
command->add_child(new TrackPlaceBlockCommand(parent()->GetConnectedNode()->track_list(track.type()),
|
||||
command->add_child(new TrackPlaceBlockCommand(sequence()->track_list(track.type()),
|
||||
track.index(),
|
||||
transition,
|
||||
ghost_->GetAdjustedIn()));
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#include "common/flipmodifiers.h"
|
||||
#include "common/qtutils.h"
|
||||
#include "common/timecodefunctions.h"
|
||||
#include "node/input/media/media.h"
|
||||
#include "project/item/footage/footage.h"
|
||||
#include "ui/colorcoding.h"
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
#include "node/output/track/track.h"
|
||||
#include "project/item/footage/footage.h"
|
||||
#include "timeline/timelinecommon.h"
|
||||
|
||||
@@ -42,6 +43,11 @@ public:
|
||||
kTrimShouldBeIgnored
|
||||
};
|
||||
|
||||
struct AttachedFootage {
|
||||
Footage* footage;
|
||||
QString output;
|
||||
};
|
||||
|
||||
TimelineViewGhostItem() :
|
||||
track_adj_(0),
|
||||
mode_(Timeline::kNone),
|
||||
@@ -267,4 +273,6 @@ private:
|
||||
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(olive::TimelineViewGhostItem::AttachedFootage)
|
||||
|
||||
#endif // TIMELINEVIEWGHOSTITEM_H
|
||||
|
||||
Reference in New Issue
Block a user