merged timeline and viewer nodes together

This commit is contained in:
itsmattkc
2020-01-03 03:26:00 +11:00
parent f13f5b5fdb
commit df837efbc6
22 changed files with 198 additions and 381 deletions
-3
View File
@@ -8,7 +8,6 @@
#include "distort/transform/transform.h"
#include "input/media/video/video.h"
#include "input/media/audio/audio.h"
#include "output/timeline/timeline.h"
#include "output/track/track.h"
#include "output/viewer/viewer.h"
#include "external.h"
@@ -127,8 +126,6 @@ Node *NodeFactory::CreateInternal(const NodeFactory::InternalID &id)
return new VideoInput();
case kAudioInput:
return new AudioInput();
case kTimelineOutput:
return new TimelineOutput();
case kTrackOutput:
return new TrackOutput();
case kViewerOutput:
-1
View File
@@ -16,7 +16,6 @@ public:
kAudioInput,
kTransformDistort,
kVideoInput,
kTimelineOutput,
kTrackOutput,
kAudioVolume,
kAudioPanning,
-1
View File
@@ -14,7 +14,6 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
add_subdirectory(timeline)
add_subdirectory(track)
add_subdirectory(viewer)
-24
View File
@@ -1,24 +0,0 @@
# Olive - Non-Linear Video Editor
# Copyright (C) 2019 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/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
node/output/timeline/timeline.h
node/output/timeline/timeline.cpp
node/output/timeline/tracklist.h
node/output/timeline/tracklist.cpp
PARENT_SCOPE
)
-204
View File
@@ -1,204 +0,0 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2019 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 "timeline.h"
#include <QDebug>
#include "node/block/gap/gap.h"
#include "node/graph.h"
#include "panel/timeline/timeline.h"
TimelineOutput::TimelineOutput()
{
// Create TrackList instances
track_inputs_.resize(kTrackTypeCount);
track_lists_.resize(kTrackTypeCount);
for (int i=0;i<kTrackTypeCount;i++) {
// Create track input
NodeInputArray* track_input = new NodeInputArray(QStringLiteral("track_in_%1").arg(i), NodeParam::kAny);
AddInput(track_input);
track_inputs_.replace(i, track_input);
TrackList* list = new TrackList(this, static_cast<TrackType>(i), track_input);
track_lists_.replace(i, list);
connect(list, SIGNAL(TrackListChanged()), this, SLOT(UpdateTrackCache()));
connect(list, SIGNAL(LengthChanged(const rational &)), this, SLOT(UpdateLength(const rational &)));
connect(list, SIGNAL(BlockAdded(Block*, int)), this, SLOT(TrackListAddedBlock(Block*, int)));
connect(list, SIGNAL(BlockRemoved(Block*)), this, SIGNAL(BlockRemoved(Block*)));
connect(list, SIGNAL(TrackAdded(TrackOutput*)), this, SLOT(TrackListAddedTrack(TrackOutput*)));
connect(list, SIGNAL(TrackRemoved(TrackOutput*)), this, SIGNAL(TrackRemoved(TrackOutput*)));
connect(list, SIGNAL(TrackHeightChanged(int, int)), this, SLOT(TrackHeightChangedSlot(int, int)));
}
}
Node *TimelineOutput::copy() const
{
return new TimelineOutput();
}
QString TimelineOutput::Name() const
{
return tr("Timeline");
}
QString TimelineOutput::id() const
{
return "org.olivevideoeditor.Olive.timeline";
}
QString TimelineOutput::Category() const
{
return tr("Output");
}
QString TimelineOutput::Description() const
{
return tr("Node for communicating between a Timeline panel and the node graph.");
}
const rational &TimelineOutput::length() const
{
return length_;
}
const QVector<TrackOutput *>& TimelineOutput::Tracks() const
{
return track_cache_;
}
const rational &TimelineOutput::timeline_length() const
{
return length_;
}
const rational &TimelineOutput::timebase() const
{
return timebase_;
}
NodeValueTable TimelineOutput::Value(const NodeValueDatabase &value) const
{
NodeValueTable table = value.Merge();
table.Push(NodeParam::kRational, QVariant::fromValue(length()), "length");
return table;
}
void TimelineOutput::UpdateTrackCache()
{
track_cache_.clear();
foreach (TrackList* list, track_lists_) {
QVector<TrackOutput*> track_list = list->Tracks();
foreach (TrackOutput* track, track_list) {
if (track) {
track_cache_.append(list->Tracks());
}
}
}
}
void TimelineOutput::UpdateLength(const rational &length)
{
// If this length is equal, no-op
if (length == length_) {
return;
}
// If this length is greater, this must be the new total length
if (length > length_) {
length_ = length;
emit LengthChanged(length_);
return;
}
// Otherwise, the new length is shorter and we'll have to manually determine what the new max length is
rational new_length = 0;
foreach (TrackList* list, track_lists_) {
new_length = qMax(new_length, list->TrackLength());
}
if (new_length != length_) {
length_ = new_length;
emit LengthChanged(length_);
}
}
void TimelineOutput::SetTimebase(const rational &timebase)
{
timebase_ = timebase;
emit TimebaseChanged(timebase_);
}
void TimelineOutput::Retranslate()
{
for (int i=0;i<track_inputs_.size();i++) {
QString input_name;
switch (static_cast<TrackType>(i)) {
case kTrackTypeVideo:
input_name = tr("Video Tracks");
break;
case kTrackTypeAudio:
input_name = tr("Audio Tracks");
break;
case kTrackTypeSubtitle:
input_name = tr("Subtitle Tracks");
break;
case kTrackTypeNone:
case kTrackTypeCount:
break;
}
if (!input_name.isEmpty())
track_inputs_.at(i)->set_name(input_name);
}
}
NodeInput *TimelineOutput::track_input(TrackType type) const
{
return track_inputs_.at(type);
}
TrackList *TimelineOutput::track_list(TrackType type) const
{
return track_lists_.at(type);
}
void TimelineOutput::TrackListAddedBlock(Block *block, int index)
{
TrackType type = static_cast<TrackList*>(sender())->TrackType();
emit BlockAdded(block, TrackReference(type, index));
}
void TimelineOutput::TrackListAddedTrack(TrackOutput *track)
{
TrackType type = static_cast<TrackList*>(sender())->TrackType();
emit TrackAdded(track, type);
}
void TimelineOutput::TrackHeightChangedSlot(int index, int height)
{
emit TrackHeightChanged(static_cast<TrackList*>(sender())->type(), index, height);
}
-102
View File
@@ -1,102 +0,0 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2019 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/>.
***/
#ifndef TIMELINEOUTPUT_H
#define TIMELINEOUTPUT_H
#include "common/timelinecommon.h"
#include "node/block/block.h"
#include "node/output/track/track.h"
#include "timeline/trackreference.h"
#include "timeline/tracktypes.h"
#include "tracklist.h"
/**
* @brief Node that represents the end of the Timeline as well as a time traversal Node
*/
class TimelineOutput : public Node
{
Q_OBJECT
public:
TimelineOutput();
virtual Node* copy() const override;
virtual QString Name() const override;
virtual QString id() const override;
virtual QString Category() const override;
virtual QString Description() const override;
const rational& length() const;
const QVector<TrackOutput *> &Tracks() const;
NodeInput* track_input(TrackType type) const;
TrackList* track_list(TrackType type) const;
const rational& timeline_length() const;
const rational& timebase() const;
void SetTimebase(const rational &timebase);
virtual void Retranslate() override;
signals:
void LengthChanged(const rational& length);
void TimebaseChanged(const rational &timebase);
void BlockAdded(Block* block, TrackReference track);
void BlockRemoved(Block* block);
void TrackAdded(TrackOutput* track, TrackType type);
void TrackRemoved(TrackOutput* track);
void TrackHeightChanged(TrackType type, int index, int height);
protected:
virtual NodeValueTable Value(const NodeValueDatabase& value) const override;
private:
QVector<NodeInput*> track_inputs_;
QVector<TrackList*> track_lists_;
QVector<TrackOutput*> track_cache_;
rational length_;
rational timebase_;
private slots:
void UpdateTrackCache();
void UpdateLength(const rational &length);
void TrackListAddedBlock(Block* block, int index);
void TrackListAddedTrack(TrackOutput* track);
void TrackHeightChangedSlot(int index, int height);
};
#endif // TIMELINEOUTPUT_H
+2
View File
@@ -18,5 +18,7 @@ set(OLIVE_SOURCES
${OLIVE_SOURCES}
node/output/track/track.h
node/output/track/track.cpp
node/output/track/tracklist.h
node/output/track/tracklist.cpp
PARENT_SCOPE
)
@@ -21,9 +21,9 @@
#include "tracklist.h"
#include "node/factory.h"
#include "timeline.h"
#include "node/output/viewer/viewer.h"
TrackList::TrackList(TimelineOutput* parent, const enum TrackType &type, NodeInputArray *track_input) :
TrackList::TrackList(ViewerOutput *parent, const enum TrackType &type, NodeInputArray *track_input) :
QObject(parent),
track_input_(track_input),
type_(type)
@@ -27,12 +27,12 @@
#include "node/output/track/track.h"
#include "timeline/tracktypes.h"
class TimelineOutput;
class ViewerOutput;
class TrackList : public QObject {
Q_OBJECT
public:
TrackList(TimelineOutput *parent, const enum TrackType& type, NodeInputArray* track_input);
TrackList(ViewerOutput *parent, const enum TrackType& type, NodeInputArray* track_input);
const enum TrackType& type() const;
+125 -1
View File
@@ -31,6 +31,27 @@ ViewerOutput::ViewerOutput()
length_input_ = new NodeInput("length_in", NodeInput::kRational);
AddInput(length_input_);
// Create TrackList instances
track_inputs_.resize(kTrackTypeCount);
track_lists_.resize(kTrackTypeCount);
for (int i=0;i<kTrackTypeCount;i++) {
// Create track input
NodeInputArray* track_input = new NodeInputArray(QStringLiteral("track_in_%1").arg(i), NodeParam::kAny);
AddInput(track_input);
track_inputs_.replace(i, track_input);
TrackList* list = new TrackList(this, static_cast<TrackType>(i), track_input);
track_lists_.replace(i, list);
connect(list, SIGNAL(TrackListChanged()), this, SLOT(UpdateTrackCache()));
connect(list, SIGNAL(LengthChanged(const rational &)), this, SLOT(UpdateLength(const rational &)));
connect(list, SIGNAL(BlockAdded(Block*, int)), this, SLOT(TrackListAddedBlock(Block*, int)));
connect(list, SIGNAL(BlockRemoved(Block*)), this, SIGNAL(BlockRemoved(Block*)));
connect(list, SIGNAL(TrackAdded(TrackOutput*)), this, SLOT(TrackListAddedTrack(TrackOutput*)));
connect(list, SIGNAL(TrackRemoved(TrackOutput*)), this, SIGNAL(TrackRemoved(TrackOutput*)));
connect(list, SIGNAL(TrackHeightChanged(int, int)), this, SLOT(TrackHeightChangedSlot(int, int)));
}
// Create UUID for this node
uuid_ = QUuid::createUuid();
}
@@ -115,10 +136,14 @@ void ViewerOutput::set_audio_params(const AudioParams &audio)
rational ViewerOutput::Length()
{
// FIXME: This is pretty messy, there's probably a better way...
if (!length_input_->IsConnected()) {
return timeline_length_;
}
Node* connected_node = length_input_->get_connected_node();
if (connected_node) {
// This is kind of messy?
return connected_node->Value(NodeValueDatabase()).Get(NodeParam::kNumber, "length").value<rational>();
}
@@ -140,3 +165,102 @@ void ViewerOutput::DependentEdgeChanged(NodeInput *from)
Node::DependentEdgeChanged(from);
}
void ViewerOutput::UpdateTrackCache()
{
track_cache_.clear();
foreach (TrackList* list, track_lists_) {
QVector<TrackOutput*> track_list = list->Tracks();
foreach (TrackOutput* track, track_list) {
if (track) {
track_cache_.append(list->Tracks());
}
}
}
}
void ViewerOutput::UpdateLength(const rational &length)
{
// If this length is equal, no-op
if (length == timeline_length_) {
return;
}
// If this length is greater, this must be the new total length
if (length > timeline_length_) {
timeline_length_ = length;
emit LengthChanged(timeline_length_);
return;
}
// Otherwise, the new length is shorter and we'll have to manually determine what the new max length is
rational new_length = 0;
foreach (TrackList* list, track_lists_) {
new_length = qMax(new_length, list->TrackLength());
}
if (new_length != timeline_length_) {
timeline_length_ = new_length;
emit LengthChanged(timeline_length_);
}
}
void ViewerOutput::Retranslate()
{
for (int i=0;i<track_inputs_.size();i++) {
QString input_name;
switch (static_cast<TrackType>(i)) {
case kTrackTypeVideo:
input_name = tr("Video Tracks");
break;
case kTrackTypeAudio:
input_name = tr("Audio Tracks");
break;
case kTrackTypeSubtitle:
input_name = tr("Subtitle Tracks");
break;
case kTrackTypeNone:
case kTrackTypeCount:
break;
}
if (!input_name.isEmpty())
track_inputs_.at(i)->set_name(input_name);
}
}
const QVector<TrackOutput *>& ViewerOutput::Tracks() const
{
return track_cache_;
}
NodeInput *ViewerOutput::track_input(TrackType type) const
{
return track_inputs_.at(type);
}
TrackList *ViewerOutput::track_list(TrackType type) const
{
return track_lists_.at(type);
}
void ViewerOutput::TrackListAddedBlock(Block *block, int index)
{
TrackType type = static_cast<TrackList*>(sender())->TrackType();
emit BlockAdded(block, TrackReference(type, index));
}
void ViewerOutput::TrackListAddedTrack(TrackOutput *track)
{
TrackType type = static_cast<TrackList*>(sender())->TrackType();
emit TrackAdded(track, type);
}
void ViewerOutput::TrackHeightChangedSlot(int index, int height)
{
emit TrackHeightChanged(static_cast<TrackList*>(sender())->type(), index, height);
}
+41
View File
@@ -23,9 +23,15 @@
#include <QUuid>
#include "common/timelinecommon.h"
#include "node/block/block.h"
#include "node/output/track/track.h"
#include "node/output/track/tracklist.h"
#include "node/node.h"
#include "render/videoparams.h"
#include "render/audioparams.h"
#include "timeline/trackreference.h"
#include "timeline/tracktypes.h"
/**
* @brief A bridge between a node system and a ViewerPanel
@@ -61,6 +67,14 @@ public:
const QUuid& uuid() const;
const QVector<TrackOutput *> &Tracks() const;
NodeInput* track_input(TrackType type) const;
TrackList* track_list(TrackType type) const;
virtual void Retranslate() override;
protected:
virtual void DependentEdgeChanged(NodeInput* from) override;
@@ -79,6 +93,14 @@ signals:
void SizeChanged(int width, int height);
void BlockAdded(Block* block, TrackReference track);
void BlockRemoved(Block* block);
void TrackAdded(TrackOutput* track, TrackType type);
void TrackRemoved(TrackOutput* track);
void TrackHeightChanged(TrackType type, int index, int height);
private:
QUuid uuid_;
@@ -92,6 +114,25 @@ private:
AudioParams audio_params_;
QVector<NodeInput*> track_inputs_;
QVector<TrackList*> track_lists_;
QVector<TrackOutput*> track_cache_;
rational timeline_length_;
private slots:
void UpdateTrackCache();
void UpdateLength(const rational &length);
void TrackListAddedBlock(Block* block, int index);
void TrackListAddedTrack(TrackOutput* track);
void TrackHeightChangedSlot(int index, int height);
};
#endif // VIEWER_H