sequence is now a node graph

This commit is contained in:
itsmattkc
2019-05-11 11:38:18 +10:00
parent 3fe0d1cda5
commit f796c2b379
9 changed files with 179 additions and 94 deletions
+25 -2
View File
@@ -1,6 +1,29 @@
#include "node.h"
Node::Node(NodeGraph *graph)
{
#include "nodegraph.h"
Node::Node(NodeGraph *graph) :
QObject(graph)
{
}
void Node::AddParameter(NodeIO *param)
{
param->setParent(this);
parameters_.append(param);
}
int Node::IndexOfParameter(NodeIO *param)
{
return parameters_.indexOf(param);
}
NodeIO *Node::Parameter(int i)
{
return parameters_.at(i);
}
int Node::ParameterCount()
{
return parameters_.size();
}
+10 -5
View File
@@ -3,18 +3,23 @@
#include <memory>
#include "nodes/nodeio.h"
class NodeGraph;
class Node;
using NodePtr = std::shared_ptr<Node>;
class Node
class Node : public QObject
{
Q_OBJECT
public:
Node(NodeGraph* parent);
void AddParameter(NodeIO* row);
int IndexOfParameter(NodeIO* row);
NodeIO* Parameter(int i);
int ParameterCount();
private:
NodeGraph* parent_;
QVector<NodeIO*> parameters_;
};
#endif // NODE_H
+12 -6
View File
@@ -1,20 +1,26 @@
#include "nodegraph.h"
#include <QChildEvent>
#include <QDebug>
NodeGraph::NodeGraph() :
output_node_(nullptr)
NodeGraph::NodeGraph()
{
}
void NodeGraph::AddNode(NodePtr node)
void NodeGraph::childEvent(QChildEvent *event)
{
nodes_.append(node);
emit NodeGraphChanged();
if (event->type() == QEvent::ChildAdded || event->type() == QEvent::ChildRemoved) {
emit NodeGraphChanged();
}
}
void NodeGraph::SetOutputNode(Node *node)
{
output_node_ = node;
}
Node *NodeGraph::OutputNode()
{
return output_node_.get();
return output_node_;
}
+5 -13
View File
@@ -12,15 +12,6 @@ class NodeGraph : public QObject
public:
NodeGraph();
/**
* @brief Add a node to this graph
*
* The graph takes ownership of the node.
*
* @param node
*/
void AddNode(NodePtr node);
/**
* @brief Process the graph
*
@@ -43,7 +34,7 @@ public:
*
* The node to set as the output node. The graph takes ownership of the node and the user cannot delete it.
*/
void SetOutputNode(NodePtr node);
void SetOutputNode(Node* node);
/**
* @brief Returns the currently set output node
@@ -53,10 +44,11 @@ public:
signals:
void NodeGraphChanged();
private:
NodePtr output_node_;
protected:
virtual void childEvent(QChildEvent *event) override;
QVector<NodePtr> nodes_;
private:
Node* output_node_;
};
#endif // NODEGRAPH_H
+113 -54
View File
@@ -169,8 +169,11 @@ void Sequence::set_audio_layout(const int& l)
long Sequence::GetEndFrame() {
long end_frame = 0;
for (int i=0;i<tracks_.size();i++) {
end_frame = qMax(tracks_.at(i)->GetEndFrame(), end_frame);
const QObjectList& all_tracks = children();
for (int i=0;i<all_tracks.size();i++) {
Track* t = static_cast<Track*>(all_tracks.at(i));
end_frame = qMax(t->GetEndFrame(), end_frame);
}
return end_frame;
@@ -180,9 +183,11 @@ QVector<Clip *> Sequence::GetAllClips()
{
QVector<Clip*> all_clips;
for (int j=0;j<tracks_.size();j++) {
const QObjectList& tracks = children();
all_clips.append(tracks_.at(j)->GetAllClips());
for (int j=0;j<tracks.size();j++) {
all_clips.append(static_cast<Track*>(tracks.at(j))->GetAllClips());
}
@@ -193,9 +198,12 @@ QVector<Track *> Sequence::GetTrackList(olive::TrackType type)
{
QVector<Track*> tracks;
for (int i=0;i<tracks_.size();i++) {
if (tracks_.at(i)->type() == type) {
tracks.append(tracks_.at(i));
const QObjectList& all_tracks = children();
for (int i=0;i<all_tracks.size();i++) {
Track* t = static_cast<Track*>(all_tracks.at(i));
if (t->type() == type) {
tracks.append(t);
}
}
@@ -230,8 +238,10 @@ QVector<Clip *> Sequence::SelectedClips(bool containing)
{
QVector<Clip*> selected_clips;
for (int j=0;j<tracks_.size();j++) {
Track* t = tracks_.at(j);
const QObjectList& all_tracks = children();
for (int j=0;j<all_tracks.size();j++) {
Track* t = static_cast<Track*>(all_tracks.at(j));
selected_clips.append(t->GetSelectedClips(containing));
}
@@ -388,6 +398,8 @@ void Sequence::EditToPoint(bool in, bool ripple)
bool push_undo = true;
long seek = playhead;
const QObjectList& all_tracks = children();
if ((in && (playhead_falls_on_out || (playhead_falls_on_in && playhead == 0)))
|| (!in && (playhead_falls_on_in || (playhead_falls_on_out && playhead == sequence_end)))) { // one frame mode
if (ripple) {
@@ -400,8 +412,9 @@ void Sequence::EditToPoint(bool in, bool ripple)
if (in_point >= 0) {
for (int j=0;j<tracks_.size();j++) {
areas.append(Selection(in_point, in_point+1, tracks_.at(j)));
for (int j=0;j<all_tracks.size();j++) {
Track* t = static_cast<Track*>(all_tracks.at(j));
areas.append(Selection(in_point, in_point+1, t));
}
// trim and move clips around the in point
@@ -436,8 +449,9 @@ void Sequence::EditToPoint(bool in, bool ripple)
} else {
for (int j=0;j<tracks_.size();j++) {
areas.append(Selection(area_in, area_out, tracks_.at(j)));
for (int j=0;j<all_tracks.size();j++) {
Track* t = static_cast<Track*>(all_tracks.at(j));
areas.append(Selection(area_in, area_out, t));
}
// trim and move clips around the in point
@@ -522,8 +536,11 @@ void Sequence::DeleteInToOut(bool ripple)
QVector<Selection> areas_to_delete;
for (int j=0;j<tracks_.size();j++) {
areas_to_delete.append(Selection(workarea_in, workarea_out, tracks_.at(j)));
const QObjectList& all_tracks = children();
for (int j=0;j<all_tracks.size();j++) {
Track* t = static_cast<Track*>(all_tracks.at(j));
areas_to_delete.append(Selection(workarea_in, workarea_out, t));
}
ComboAction* ca = new ComboAction();
@@ -576,8 +593,10 @@ void Sequence::Ripple(ComboAction *ca, long point, long length, const QVector<Cl
void Sequence::ChangeTrackHeightsRelatively(int diff)
{
for (int j=0;j<tracks_.size();j++) {
Track* t = tracks_.at(j);
const QObjectList& all_tracks = children();
for (int j=0;j<all_tracks.size();j++) {
Track* t = static_cast<Track*>(all_tracks.at(j));
t->set_height(t->height() + diff);
}
@@ -649,9 +668,12 @@ void Sequence::Split()
// If we weren't able to split any selected clips above, see if there are arbitrary selections to split
if (!split_occurred) {
Track* track;
const QObjectList& all_tracks = children();
QObject* obj;
foreach (track, tracks_) {
foreach (obj, all_tracks) {
Track* track = static_cast<Track*>(obj);
QVector<Selection> track_selections = track->Selections();
QVector<long> split_positions;
@@ -894,8 +916,10 @@ void Sequence::RippleDeleteEmptySpace(ComboAction* ca, Track* track, long point)
void Sequence::RippleDeleteArea(ComboAction* ca, long ripple_point, long ripple_length) {
for (int j=0;j<tracks_.size();j++) {
Track* t = tracks_.at(j);
const QObjectList& all_tracks = children();
for (int j=0;j<all_tracks.size();j++) {
Track* t = static_cast<Track*>(all_tracks.at(j));
// We've already tested `track`, so we don't need to test it again
long first_in_point_after_point = LONG_MAX;
@@ -982,22 +1006,25 @@ OldEffectNode *Sequence::GetSelectedGizmo()
void Sequence::SelectAll()
{
for (int i=0;i<tracks_.size();i++) {
tracks_.at(i)->SelectAll();
const QObjectList& all_tracks = children();
for (int i=0;i<all_tracks.size();i++) {
static_cast<Track*>(all_tracks.at(i))->SelectAll();
}
}
void Sequence::SelectAtPlayhead()
{
for (int i=0;i<tracks_.size();i++) {
tracks_.at(i)->SelectAtPoint(playhead);
const QObjectList& all_tracks = children();
for (int i=0;i<all_tracks.size();i++) {
static_cast<Track*>(all_tracks.at(i))->SelectAtPoint(playhead);
}
}
void Sequence::ClearSelections()
{
for (int i=0;i<tracks_.size();i++) {
tracks_.at(i)->ClearSelections();
const QObjectList& all_tracks = children();
for (int i=0;i<all_tracks.size();i++) {
static_cast<Track*>(all_tracks.at(i))->ClearSelections();
}
}
@@ -1078,8 +1105,10 @@ QVector<Selection> Sequence::Selections()
{
QVector<Selection> selections;
for (int i=0;i<tracks_.size();i++) {
selections.append(tracks_.at(i)->Selections());
const QObjectList& all_tracks = children();
for (int i=0;i<all_tracks.size();i++) {
selections.append(static_cast<Track*>(all_tracks.at(i))->Selections());
}
return selections;
@@ -1108,12 +1137,15 @@ Track *Sequence::PreviousTrack(Track *t)
Track* previous_track = nullptr;
// Loop through tracks
for (int i=0;i<tracks_.size();i++) {
const QObjectList& all_tracks = children();
for (int i=0;i<all_tracks.size();i++) {
if (tracks_.at(i) == t) {
Track* comp_track = static_cast<Track*>(all_tracks.at(i));
if (comp_track == t) {
// If this is the track, we'll know the previous track by now
break;
} else if (tracks_.at(i)->type() == t->type()) {
} else if (comp_track->type() == t->type()) {
// Otherwise, we'll keep "track" of it
previous_track = t;
}
@@ -1132,14 +1164,18 @@ Track *Sequence::NextTrack(Track *t)
Track* next_track = nullptr;
for (int i=tracks_.size()-1;i>=0;i--) {
const QObjectList& all_tracks = children();
if (tracks_.at(i) == t) {
for (int i=all_tracks.size()-1;i>=0;i--) {
Track* track = static_cast<Track*>(all_tracks.at(i));
if (track == t) {
break;
}
if (tracks_.at(i)->type() == t->type()) {
next_track = tracks_.at(i);
if (track->type() == t->type()) {
next_track = track;
}
}
@@ -1161,13 +1197,17 @@ int Sequence::IndexOfTrack(Track *t)
{
int counter = -1;
for (int i=0;i<tracks_.size();i++) {
const QObjectList& all_tracks = children();
if (tracks_.at(i)->type() == t->type()) {
for (int i=0;i<all_tracks.size();i++) {
Track* track = static_cast<Track*>(all_tracks.at(i));
if (track->type() == t->type()) {
counter++;
}
if (tracks_.at(i) == t) {
if (track == t) {
return counter;
}
}
@@ -1177,9 +1217,14 @@ int Sequence::IndexOfTrack(Track *t)
Track *Sequence::FirstTrack(olive::TrackType type)
{
for (int i=0;i<tracks_.size();i++) {
if (tracks_.at(i)->type() == type) {
return tracks_.at(i);
const QObjectList& all_tracks = children();
for (int i=0;i<all_tracks.size();i++) {
Track* track = static_cast<Track*>(all_tracks.at(i));
if (track->type() == type) {
return track;
}
}
return nullptr;
@@ -1187,9 +1232,14 @@ Track *Sequence::FirstTrack(olive::TrackType type)
Track *Sequence::LastTrack(olive::TrackType type)
{
for (int i=tracks_.size()-1;i>=0;i--) {
if (tracks_.at(i)->type() == type) {
return tracks_.at(i);
const QObjectList& all_tracks = children();
for (int i=all_tracks.size()-1;i>=0;i--) {
Track* track = static_cast<Track*>(all_tracks.at(i));
if (track->type() == type) {
return track;
}
}
return nullptr;
@@ -1199,13 +1249,18 @@ Track *Sequence::TrackAt(olive::TrackType type, int index)
{
int counter = -1;
for (int i=0;i<tracks_.size();i++) {
if (tracks_.at(i)->type() == type) {
const QObjectList& all_tracks = children();
for (int i=0;i<all_tracks.size();i++) {
Track* track = static_cast<Track*>(all_tracks.at(i));
if (track->type() == type) {
counter++;
}
if (counter == index) {
return tracks_.at(i);
return track;
}
}
@@ -1223,8 +1278,13 @@ int Sequence::TrackCount(olive::TrackType type)
{
int counter = 0;
for (int i=0;i<tracks_.size();i++) {
if (tracks_.at(i)->type() == type) {
const QObjectList& all_tracks = children();
for (int i=0;i<all_tracks.size();i++) {
Track* track = static_cast<Track*>(all_tracks.at(i));
if (track->type() == type) {
counter++;
}
}
@@ -1234,10 +1294,9 @@ int Sequence::TrackCount(olive::TrackType type)
Track* Sequence::AddTrack(olive::TrackType type)
{
Track* track = new Track(this, type);
tracks_.append(track);
emit TrackCountChanged();
return track;
Track* t = new Track(nullptr, type);
t->setParent(this);
return t;
}
ClipPtr Sequence::SplitClip(ComboAction *ca, bool transitions, Clip* pre, long frame)
+3 -3
View File
@@ -28,8 +28,9 @@
#include "marker.h"
#include "selection.h"
#include "ghost.h"
#include "nodes/nodegraph.h"
class Sequence : public QObject {
class Sequence : public NodeGraph {
Q_OBJECT
public:
Sequence();
@@ -142,11 +143,10 @@ public:
QVector<Marker> markers;
signals:
void SequenceParametersChanged();
void TrackCountChanged();
private:
Track *AddTrack(olive::TrackType type);
QVector<Track*> tracks_;
//QVector<Track*> tracks_;
ClipPtr SplitClip(ComboAction* ca, bool transitions, Clip *clip, long frame);
ClipPtr SplitClip(ComboAction* ca, bool transitions, Clip *clip, long frame, long post_in);
+7 -7
View File
@@ -9,7 +9,7 @@ int olive::timeline::kTrackMinHeight = 30;
int olive::timeline::kTrackHeightIncrement = 10;
Track::Track(Sequence* parent, olive::TrackType type) :
parent_(parent),
Node(parent),
type_(type),
muted_(false),
soloed_(false),
@@ -35,7 +35,7 @@ Track *Track::copy(Sequence *parent)
Sequence *Track::sequence()
{
return parent_;
return static_cast<Sequence*>(parent());
}
void Track::Save(QXmlStreamWriter &stream)
@@ -204,22 +204,22 @@ bool Track::ContainsClip(Clip *c)
Track *Track::Previous()
{
return parent_->PreviousTrack(this);
return sequence()->PreviousTrack(this);
}
Track *Track::Next()
{
return parent_->NextTrack(this);
return sequence()->NextTrack(this);
}
Track *Track::Sibling(int diff)
{
return parent_->SiblingTrack(this, diff);
return sequence()->SiblingTrack(this, diff);
}
int Track::Index()
{
return parent_->IndexOfTrack(this);
return sequence()->IndexOfTrack(this);
}
bool Track::IsClipSelected(int clip_index, bool containing)
@@ -378,7 +378,7 @@ bool Track::IsEffectivelyMuted()
// Check if any tracks are soloed
bool a_track_is_soloed = false;
QVector<Track*> siblings = parent_->GetTrackList(type_);
QVector<Track*> siblings = sequence()->GetTrackList(type_);
for (int i=0;i<siblings.size();i++) {
if (siblings.at(i)->IsSoloed()) {
a_track_is_soloed = true;
+2 -2
View File
@@ -8,6 +8,7 @@
#include "tracktypes.h"
#include "undo/comboaction.h"
#include "timeline/selection.h"
#include "nodes/node.h"
class Sequence;
class Transition;
@@ -37,7 +38,7 @@ namespace olive {
class Sequence;
class Track : public QObject
class Track : public Node
{
Q_OBJECT
public:
@@ -107,7 +108,6 @@ signals:
private:
void ResizeClipArray(int new_size);
Sequence* parent_;
olive::TrackType type_;
int height_;
QVector<ClipPtr> clips_;
+2 -2
View File
@@ -52,7 +52,7 @@ TimelineArea::TimelineArea(Timeline* timeline, olive::timeline::Alignment alignm
void TimelineArea::SetTrackType(Sequence *sequence, olive::TrackType track_type)
{
if (sequence_ != nullptr) {
disconnect(sequence_, SIGNAL(TrackCountChanged()), this, SLOT(RefreshLabels()));
disconnect(sequence_, SIGNAL(NodeGraphChanged()), this, SLOT(RefreshLabels()));
}
sequence_ = sequence;
@@ -60,7 +60,7 @@ void TimelineArea::SetTrackType(Sequence *sequence, olive::TrackType track_type)
if (sequence_ != nullptr) {
connect(sequence_, SIGNAL(TrackCountChanged()), this, SLOT(RefreshLabels()));
connect(sequence_, SIGNAL(NodeGraphChanged()), this, SLOT(RefreshLabels()));
}