Merge branch 'master' into otio
This commit is contained in:
@@ -25,6 +25,7 @@ OLIVE_NAMESPACE_ENTER
|
||||
VolumeNode::VolumeNode()
|
||||
{
|
||||
samples_input_ = new NodeInput("samples_in", NodeParam::kSamples);
|
||||
samples_input_->set_is_keyframable(false);
|
||||
AddInput(samples_input_);
|
||||
|
||||
volume_input_ = new NodeInput("volume_in", NodeParam::kFloat, 1.0);
|
||||
|
||||
@@ -122,6 +122,11 @@ void Block::set_length_and_media_in(const rational &length)
|
||||
LengthChangedEvent(old_length, length, Timeline::kTrimIn);
|
||||
}
|
||||
|
||||
TimeRange Block::range() const
|
||||
{
|
||||
return TimeRange(in(), out());
|
||||
}
|
||||
|
||||
Block *Block::previous()
|
||||
{
|
||||
return previous_;
|
||||
|
||||
@@ -54,6 +54,8 @@ public:
|
||||
void set_length_and_media_out(const rational &length);
|
||||
void set_length_and_media_in(const rational &length);
|
||||
|
||||
TimeRange range() const;
|
||||
|
||||
Block* previous();
|
||||
Block* next();
|
||||
void set_previous(Block* previous);
|
||||
|
||||
+16
-7
@@ -20,22 +20,31 @@
|
||||
|
||||
#include "edge.h"
|
||||
|
||||
#include "input.h"
|
||||
#include "node.h"
|
||||
#include "output.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
NodeEdge::NodeEdge(NodeOutput *output, NodeInput *input) :
|
||||
output_(output),
|
||||
input_(input)
|
||||
NodeEdge::NodeEdge(NodeOutput *output, NodeInput *input)
|
||||
{
|
||||
output_ = ParamToConnection(output);
|
||||
input_ = ParamToConnection(input);
|
||||
}
|
||||
|
||||
NodeOutput *NodeEdge::output()
|
||||
NodeOutput *NodeEdge::output() const
|
||||
{
|
||||
return output_;
|
||||
return output_.node->GetOutputWithID(output_.id);
|
||||
}
|
||||
|
||||
NodeInput *NodeEdge::input()
|
||||
NodeInput *NodeEdge::input() const
|
||||
{
|
||||
return input_;
|
||||
return input_.node->GetInputWithID(input_.id);
|
||||
}
|
||||
|
||||
NodeEdge::Connection NodeEdge::ParamToConnection(NodeParam *param)
|
||||
{
|
||||
return {param->parentNode(), param->id()};
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
+26
-5
@@ -22,13 +22,16 @@
|
||||
#define EDGE_H
|
||||
|
||||
#include <memory>
|
||||
#include <QString>
|
||||
|
||||
#include "common/define.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
class NodeOutput;
|
||||
class Node;
|
||||
class NodeInput;
|
||||
class NodeOutput;
|
||||
class NodeParam;
|
||||
|
||||
/**
|
||||
* @brief A connection between two node parameters (a NodeOutput and a NodeInput)
|
||||
@@ -44,19 +47,37 @@ public:
|
||||
*/
|
||||
NodeEdge(NodeOutput* output, NodeInput* input);
|
||||
|
||||
Node* output_node() const
|
||||
{
|
||||
return output_.node;
|
||||
}
|
||||
|
||||
Node* input_node() const
|
||||
{
|
||||
return input_.node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the output parameter this edge is connected to
|
||||
*/
|
||||
NodeOutput* output();
|
||||
NodeOutput* output() const;
|
||||
|
||||
/**
|
||||
* @brief Return the input parameter this edge is connected to
|
||||
*/
|
||||
NodeInput* input();
|
||||
NodeInput* input() const;
|
||||
|
||||
private:
|
||||
NodeOutput* output_;
|
||||
NodeInput* input_;
|
||||
struct Connection {
|
||||
Node* node;
|
||||
QString id;
|
||||
};
|
||||
|
||||
static Connection ParamToConnection(NodeParam* param);
|
||||
|
||||
Connection output_;
|
||||
Connection input_;
|
||||
|
||||
};
|
||||
|
||||
using NodeEdgePtr = std::shared_ptr<NodeEdge>;
|
||||
|
||||
+87
-2
@@ -22,6 +22,11 @@
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
NodeGraph::NodeGraph() :
|
||||
operation_stack_(0)
|
||||
{
|
||||
}
|
||||
|
||||
void NodeGraph::Clear()
|
||||
{
|
||||
foreach (Node* node, node_children_) {
|
||||
@@ -38,14 +43,94 @@ void NodeGraph::AddNode(Node *node)
|
||||
|
||||
node->setParent(this);
|
||||
|
||||
connect(node, &Node::EdgeAdded, this, &NodeGraph::EdgeAdded);
|
||||
connect(node, &Node::EdgeRemoved, this, &NodeGraph::EdgeRemoved);
|
||||
connect(node, &Node::EdgeAdded, this, &NodeGraph::SignalEdgeAdded);
|
||||
connect(node, &Node::EdgeRemoved, this, &NodeGraph::SignalEdgeRemoved);
|
||||
|
||||
node_children_.append(node);
|
||||
|
||||
emit NodeAdded(node);
|
||||
}
|
||||
|
||||
void NodeGraph::BeginOperation()
|
||||
{
|
||||
operation_stack_++;
|
||||
}
|
||||
|
||||
void NodeGraph::EndOperation()
|
||||
{
|
||||
operation_stack_--;
|
||||
|
||||
if (!operation_stack_) {
|
||||
// Signal everything that we cached during the operation
|
||||
|
||||
// First, signal the removed edges
|
||||
foreach (NodeEdgePtr e, cached_removed_edges_) {
|
||||
emit EdgeRemoved(e);
|
||||
}
|
||||
cached_removed_edges_.clear();
|
||||
|
||||
// Next, signal the removed nodes
|
||||
foreach (Node* n, cached_removed_nodes_) {
|
||||
emit NodeRemoved(n);
|
||||
}
|
||||
cached_removed_nodes_.clear();
|
||||
|
||||
// Next, signal the added nodes
|
||||
foreach (Node* n, cached_added_nodes_) {
|
||||
emit NodeAdded(n);
|
||||
}
|
||||
cached_added_nodes_.clear();
|
||||
|
||||
// Finally, signal the added edges
|
||||
foreach (NodeEdgePtr e, cached_added_edges_) {
|
||||
emit EdgeAdded(e);
|
||||
}
|
||||
cached_added_edges_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void NodeGraph::SignalNodeAdded(Node* node)
|
||||
{
|
||||
if (!operation_stack_) {
|
||||
emit NodeAdded(node);
|
||||
} else if (!cached_removed_nodes_.removeOne(node)) {
|
||||
// If we already removed this node during the operation (appending a signal to
|
||||
// cached_removed_nodes_), we just remove that instead of appending a new signal. However if we
|
||||
// didn't (removeOne returning false), only then do we append an add signal
|
||||
cached_added_nodes_.append(node);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeGraph::SignalNodeRemoved(Node *node)
|
||||
{
|
||||
if (!operation_stack_) {
|
||||
emit NodeRemoved(node);
|
||||
} else if (!cached_added_nodes_.removeOne(node)) {
|
||||
// See SignalNodeAdded() for explanation of this
|
||||
cached_removed_nodes_.append(node);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeGraph::SignalEdgeAdded(NodeEdgePtr edge)
|
||||
{
|
||||
if (!operation_stack_) {
|
||||
emit EdgeAdded(edge);
|
||||
} else if (!cached_removed_edges_.removeOne(edge)) {
|
||||
// See SignalNodeAdded() for explanation of this
|
||||
cached_added_edges_.append(edge);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeGraph::SignalEdgeRemoved(NodeEdgePtr edge)
|
||||
{
|
||||
if (!operation_stack_) {
|
||||
emit EdgeRemoved(edge);
|
||||
} else if (!cached_added_edges_.removeOne(edge)) {
|
||||
// See SignalNodeAdded() for explanation of this
|
||||
cached_removed_edges_.append(edge);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeGraph::TakeNode(Node *node, QObject* new_parent)
|
||||
{
|
||||
if (!ContainsNode(node)) {
|
||||
|
||||
+19
-1
@@ -37,7 +37,7 @@ public:
|
||||
/**
|
||||
* @brief NodeGraph Constructor
|
||||
*/
|
||||
NodeGraph() = default;
|
||||
NodeGraph();
|
||||
|
||||
/**
|
||||
* @brief Destructively destroys all nodes in the graph
|
||||
@@ -67,6 +67,10 @@ public:
|
||||
*/
|
||||
bool ContainsNode(Node* n) const;
|
||||
|
||||
void BeginOperation();
|
||||
|
||||
void EndOperation();
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief Signal emitted when a Node is added to the graph
|
||||
@@ -90,6 +94,20 @@ signals:
|
||||
|
||||
private:
|
||||
QList<Node*> node_children_;
|
||||
|
||||
int operation_stack_;
|
||||
|
||||
QList<Node*> cached_added_nodes_;
|
||||
QList<Node*> cached_removed_nodes_;
|
||||
QList<NodeEdgePtr> cached_added_edges_;
|
||||
QList<NodeEdgePtr> cached_removed_edges_;
|
||||
|
||||
private slots:
|
||||
void SignalNodeAdded(Node *node);
|
||||
void SignalNodeRemoved(Node* node);
|
||||
void SignalEdgeAdded(NodeEdgePtr edge);
|
||||
void SignalEdgeRemoved(NodeEdgePtr edge);
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -27,6 +27,11 @@ Node *AudioInput::copy() const
|
||||
return new AudioInput();
|
||||
}
|
||||
|
||||
Stream::Type AudioInput::type() const
|
||||
{
|
||||
return Stream::kAudio;
|
||||
}
|
||||
|
||||
QString AudioInput::Name() const
|
||||
{
|
||||
return tr("Audio Input");
|
||||
|
||||
@@ -32,6 +32,8 @@ public:
|
||||
|
||||
virtual Node* copy() const override;
|
||||
|
||||
virtual Stream::Type type() const override;
|
||||
|
||||
virtual QString Name() const override;
|
||||
virtual QString ShortName() const override;
|
||||
virtual QString id() const override;
|
||||
|
||||
@@ -50,6 +50,11 @@ void MediaInput::SetFootage(StreamPtr f)
|
||||
footage_input_->set_standard_value(QVariant::fromValue(f));
|
||||
}
|
||||
|
||||
bool MediaInput::IsMedia() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void MediaInput::Retranslate()
|
||||
{
|
||||
footage_input_->set_name(tr("Footage"));
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "codec/decoder.h"
|
||||
#include "node/node.h"
|
||||
#include "project/item/footage/stream.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
@@ -35,11 +36,16 @@ class MediaInput : public Node
|
||||
public:
|
||||
MediaInput();
|
||||
|
||||
virtual Stream::Type type() const = 0;
|
||||
|
||||
virtual QList<CategoryID> Category() const override;
|
||||
|
||||
StreamPtr footage();
|
||||
void SetFootage(StreamPtr f);
|
||||
|
||||
virtual bool IsMedia() const override;
|
||||
|
||||
|
||||
virtual void Retranslate() override;
|
||||
|
||||
virtual NodeValueTable Value(NodeValueDatabase& value) const override;
|
||||
|
||||
@@ -36,6 +36,11 @@ Node *VideoInput::copy() const
|
||||
return new VideoInput();
|
||||
}
|
||||
|
||||
Stream::Type VideoInput::type() const
|
||||
{
|
||||
return Stream::kVideo;
|
||||
}
|
||||
|
||||
QString VideoInput::Name() const
|
||||
{
|
||||
return tr("Video Input");
|
||||
|
||||
@@ -35,6 +35,8 @@ public:
|
||||
|
||||
virtual Node* copy() const override;
|
||||
|
||||
virtual Stream::Type type() const override;
|
||||
|
||||
virtual QString Name() const override;
|
||||
virtual QString ShortName() const override;
|
||||
virtual QString id() const override;
|
||||
|
||||
@@ -33,6 +33,12 @@ NodeInputArray::NodeInputArray(const QString &id, const DataType &type, const QV
|
||||
{
|
||||
}
|
||||
|
||||
NodeInputArray::~NodeInputArray()
|
||||
{
|
||||
// Clear all connected edges (make sure our override is called)
|
||||
DisconnectAll();
|
||||
}
|
||||
|
||||
bool NodeInputArray::IsArray() const
|
||||
{
|
||||
return true;
|
||||
@@ -58,6 +64,10 @@ void NodeInputArray::SetSize(int size)
|
||||
|
||||
if (size < old_size) {
|
||||
// If the new size is less, delete all extraneous parameters
|
||||
for (int i=size;i<old_size;i++) {
|
||||
sub_params_.at(i)->DisconnectAll();
|
||||
}
|
||||
|
||||
for (int i=size;i<old_size;i++) {
|
||||
delete sub_params_.at(i);
|
||||
}
|
||||
@@ -116,6 +126,15 @@ const QVector<NodeInput *> &NodeInputArray::sub_params()
|
||||
return sub_params_;
|
||||
}
|
||||
|
||||
void NodeInputArray::DisconnectAll()
|
||||
{
|
||||
NodeParam::DisconnectAll();
|
||||
|
||||
foreach (NodeInput* input, sub_params_) {
|
||||
input->DisconnectAll();
|
||||
}
|
||||
}
|
||||
|
||||
void NodeInputArray::InsertAt(int index)
|
||||
{
|
||||
// Add another input at the end
|
||||
|
||||
@@ -31,6 +31,8 @@ class NodeInputArray : public NodeInput
|
||||
public:
|
||||
NodeInputArray(const QString &id, const DataType& type, const QVariant& default_value = 0);
|
||||
|
||||
virtual ~NodeInputArray() override;
|
||||
|
||||
virtual bool IsArray() const override;
|
||||
|
||||
int GetSize() const;
|
||||
@@ -51,6 +53,8 @@ public:
|
||||
|
||||
const QVector<NodeInput*>& sub_params();
|
||||
|
||||
virtual void DisconnectAll() override;
|
||||
|
||||
signals:
|
||||
void SizeChanged(int size);
|
||||
|
||||
|
||||
@@ -467,6 +467,11 @@ bool Node::IsTrack() const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Node::IsMedia() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const QList<NodeParam *>& Node::parameters() const
|
||||
{
|
||||
return params_;
|
||||
|
||||
@@ -369,6 +369,15 @@ public:
|
||||
*/
|
||||
virtual bool IsTrack() const;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Returns whether this Node is a "Media" type or not
|
||||
*
|
||||
* You shouldn't ever need to override this since all derivatives of Media will automatically have this set to true.
|
||||
* It's just a more convenient way of checking than dynamic_casting.
|
||||
*/
|
||||
virtual bool IsMedia() const;
|
||||
|
||||
/**
|
||||
* @brief The main processing function
|
||||
*
|
||||
@@ -568,6 +577,8 @@ QList<T *> Node::FindOutputNode()
|
||||
return list;
|
||||
}
|
||||
|
||||
using NodePtr = std::shared_ptr<Node>;
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
#endif // NODE_H
|
||||
|
||||
@@ -55,6 +55,11 @@ TrackOutput::TrackOutput() :
|
||||
track_height_ = kTrackHeightDefault;
|
||||
}
|
||||
|
||||
TrackOutput::~TrackOutput()
|
||||
{
|
||||
DisconnectAll();
|
||||
}
|
||||
|
||||
void TrackOutput::set_track_type(const Timeline::TrackType &track_type)
|
||||
{
|
||||
track_type_ = track_type;
|
||||
@@ -91,15 +96,6 @@ QString TrackOutput::Description() const
|
||||
"a Sequence.");
|
||||
}
|
||||
|
||||
QString TrackOutput::GetTrackName()
|
||||
{
|
||||
if (track_name_.isEmpty()) {
|
||||
return GetDefaultTrackName(track_type_, index_);
|
||||
}
|
||||
|
||||
return track_name_;
|
||||
}
|
||||
|
||||
const double &TrackOutput::GetTrackHeight() const
|
||||
{
|
||||
return track_height_;
|
||||
@@ -435,11 +431,6 @@ void TrackOutput::Hash(QCryptographicHash &hash, const rational &time) const
|
||||
}
|
||||
}
|
||||
|
||||
void TrackOutput::SetTrackName(const QString &name)
|
||||
{
|
||||
track_name_ = name;
|
||||
}
|
||||
|
||||
void TrackOutput::SetMuted(bool e)
|
||||
{
|
||||
muted_input_->set_standard_value(e);
|
||||
@@ -555,7 +546,7 @@ void TrackOutput::BlockConnected(NodeEdgePtr edge)
|
||||
|
||||
void TrackOutput::BlockDisconnected(NodeEdgePtr edge)
|
||||
{
|
||||
Block* b = static_cast<Block*>(edge->output()->parentNode());
|
||||
Block* b = static_cast<Block*>(edge->output_node());
|
||||
|
||||
if (block_cache_.contains(b)) {
|
||||
block_cache_.removeOne(b);
|
||||
|
||||
@@ -36,6 +36,8 @@ class TrackOutput : public Node
|
||||
public:
|
||||
TrackOutput();
|
||||
|
||||
virtual ~TrackOutput() override;
|
||||
|
||||
const Timeline::TrackType& track_type() const;
|
||||
void set_track_type(const Timeline::TrackType& track_type);
|
||||
|
||||
@@ -46,8 +48,6 @@ public:
|
||||
virtual QList<CategoryID> Category() const override;
|
||||
virtual QString Description() const override;
|
||||
|
||||
QString GetTrackName();
|
||||
|
||||
const double& GetTrackHeight() const;
|
||||
void SetTrackHeight(const double& height);
|
||||
|
||||
@@ -227,8 +227,6 @@ public:
|
||||
static const double kTrackHeightInterval;
|
||||
|
||||
public slots:
|
||||
void SetTrackName(const QString& name);
|
||||
|
||||
void SetMuted(bool e);
|
||||
|
||||
void SetLocked(bool e);
|
||||
@@ -294,8 +292,6 @@ private:
|
||||
|
||||
double track_height_;
|
||||
|
||||
QString track_name_;
|
||||
|
||||
int index_;
|
||||
|
||||
bool locked_;
|
||||
|
||||
@@ -134,7 +134,7 @@ TrackOutput* TrackList::AddTrack()
|
||||
return track;
|
||||
}
|
||||
|
||||
void TrackList::RemoveTrack()
|
||||
void TrackList::RemoveTrack(QObject* new_parent)
|
||||
{
|
||||
if (track_cache_.isEmpty()) {
|
||||
return;
|
||||
@@ -144,7 +144,11 @@ void TrackList::RemoveTrack()
|
||||
|
||||
GetParentGraph()->TakeNode(track);
|
||||
|
||||
delete track;
|
||||
if (!new_parent) {
|
||||
delete track;
|
||||
} else {
|
||||
track->setParent(new_parent);
|
||||
}
|
||||
|
||||
track_input_->RemoveLast();
|
||||
}
|
||||
@@ -184,7 +188,8 @@ void TrackList::TrackConnected(NodeEdgePtr edge)
|
||||
track_cache_.append(connected_track);
|
||||
}
|
||||
|
||||
connected_track->SetIndex(track_index);
|
||||
// Update track indexes in the list (including this track)
|
||||
UpdateTrackIndexesFrom(track_index);
|
||||
}
|
||||
|
||||
connect(connected_track, &TrackOutput::BlockAdded, this, &TrackList::TrackAddedBlock);
|
||||
@@ -220,9 +225,7 @@ void TrackList::TrackDisconnected(NodeEdgePtr edge)
|
||||
track_cache_.removeAt(index_of_track);
|
||||
|
||||
// Update indices for all subsequent tracks
|
||||
for (int i=index_of_track; i<track_cache_.size(); i++) {
|
||||
track_cache_.at(i)->SetIndex(i);
|
||||
}
|
||||
UpdateTrackIndexesFrom(index_of_track);
|
||||
|
||||
// Traverse through Tracks uncaching and disconnecting them
|
||||
emit TrackRemoved(track);
|
||||
@@ -241,6 +244,13 @@ void TrackList::TrackDisconnected(NodeEdgePtr edge)
|
||||
}
|
||||
}
|
||||
|
||||
void TrackList::UpdateTrackIndexesFrom(int index)
|
||||
{
|
||||
for (int i=index; i<track_cache_.size(); i++) {
|
||||
track_cache_.at(i)->SetIndex(i);
|
||||
}
|
||||
}
|
||||
|
||||
NodeGraph *TrackList::GetParentGraph() const
|
||||
{
|
||||
return static_cast<NodeGraph*>(parent()->parent());
|
||||
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
|
||||
TrackOutput *AddTrack();
|
||||
|
||||
void RemoveTrack();
|
||||
void RemoveTrack(QObject *new_parent);
|
||||
|
||||
const rational& GetTotalLength() const;
|
||||
|
||||
@@ -68,6 +68,8 @@ signals:
|
||||
void TrackHeightChanged(int index, int height);
|
||||
|
||||
private:
|
||||
void UpdateTrackIndexesFrom(int index);
|
||||
|
||||
/**
|
||||
* @brief A cache of connected Tracks
|
||||
*/
|
||||
|
||||
@@ -52,7 +52,7 @@ ViewerOutput::ViewerOutput() :
|
||||
connect(list, &TrackList::TrackListChanged, this, &ViewerOutput::UpdateTrackCache);
|
||||
connect(list, &TrackList::LengthChanged, this, &ViewerOutput::VerifyLength);
|
||||
connect(list, &TrackList::BlockAdded, this, &ViewerOutput::TrackListAddedBlock);
|
||||
connect(list, &TrackList::BlockRemoved, this, &ViewerOutput::BlockRemoved);
|
||||
connect(list, &TrackList::BlockRemoved, this, &ViewerOutput::SignalBlockRemoved);
|
||||
connect(list, &TrackList::TrackAdded, this, &ViewerOutput::TrackListAddedTrack);
|
||||
connect(list, &TrackList::TrackRemoved, this, &ViewerOutput::TrackRemoved);
|
||||
connect(list, &TrackList::TrackHeightChanged, this, &ViewerOutput::TrackHeightChangedSlot);
|
||||
@@ -62,6 +62,11 @@ ViewerOutput::ViewerOutput() :
|
||||
uuid_ = QUuid::createUuid();
|
||||
}
|
||||
|
||||
ViewerOutput::~ViewerOutput()
|
||||
{
|
||||
DisconnectAll();
|
||||
}
|
||||
|
||||
Node *ViewerOutput::copy() const
|
||||
{
|
||||
return new ViewerOutput();
|
||||
@@ -274,6 +279,27 @@ void ViewerOutput::set_media_name(const QString &name)
|
||||
emit MediaNameChanged(media_name_);
|
||||
}
|
||||
|
||||
void ViewerOutput::SignalBlockAdded(Block *block, const TrackReference& track)
|
||||
{
|
||||
if (!operation_stack_) {
|
||||
emit BlockAdded(block, track);
|
||||
} else {
|
||||
cached_block_removed_.removeOne(block);
|
||||
cached_block_added_.insert(block, track);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerOutput::SignalBlockRemoved(Block *block)
|
||||
{
|
||||
if (!operation_stack_) {
|
||||
emit BlockRemoved({block});
|
||||
} else {
|
||||
// We keep track of all blocks that are removed, even if we don't end up signalling them
|
||||
cached_block_added_.remove(block);
|
||||
cached_block_removed_.append(block);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerOutput::BeginOperation()
|
||||
{
|
||||
operation_stack_++;
|
||||
@@ -285,13 +311,23 @@ void ViewerOutput::EndOperation()
|
||||
{
|
||||
operation_stack_--;
|
||||
|
||||
if (!operation_stack_) {
|
||||
for (auto it=cached_block_added_.cbegin(); it!=cached_block_added_.cend(); it++) {
|
||||
emit BlockAdded(it.key(), it.value());
|
||||
}
|
||||
cached_block_added_.clear();
|
||||
|
||||
emit BlockRemoved(cached_block_removed_);
|
||||
cached_block_removed_.clear();
|
||||
}
|
||||
|
||||
Node::EndOperation();
|
||||
}
|
||||
|
||||
void ViewerOutput::TrackListAddedBlock(Block *block, int index)
|
||||
{
|
||||
Timeline::TrackType type = static_cast<TrackList*>(sender())->type();
|
||||
emit BlockAdded(block, TrackReference(type, index));
|
||||
SignalBlockAdded(block, TrackReference(type, index));
|
||||
}
|
||||
|
||||
void ViewerOutput::TrackListAddedTrack(TrackOutput *track)
|
||||
|
||||
@@ -47,6 +47,8 @@ class ViewerOutput : public Node
|
||||
public:
|
||||
ViewerOutput();
|
||||
|
||||
virtual ~ViewerOutput() override;
|
||||
|
||||
virtual Node* copy() const override;
|
||||
|
||||
virtual QString Name() const override;
|
||||
@@ -139,7 +141,7 @@ signals:
|
||||
void AudioParamsChanged();
|
||||
|
||||
void BlockAdded(Block* block, TrackReference track);
|
||||
void BlockRemoved(Block* block);
|
||||
void BlockRemoved(const QList<Block*>& blocks);
|
||||
|
||||
void TrackAdded(TrackOutput* track, Timeline::TrackType type);
|
||||
void TrackRemoved(TrackOutput* track);
|
||||
@@ -149,6 +151,9 @@ signals:
|
||||
void MediaNameChanged(const QString& name);
|
||||
|
||||
private:
|
||||
QMap<Block*, TrackReference> cached_block_added_;
|
||||
QList<Block*> cached_block_removed_;
|
||||
|
||||
QUuid uuid_;
|
||||
|
||||
NodeInput* texture_input_;
|
||||
@@ -186,6 +191,9 @@ private slots:
|
||||
|
||||
void TrackHeightChangedSlot(int index, int height);
|
||||
|
||||
void SignalBlockAdded(Block *block, const TrackReference &track);
|
||||
void SignalBlockRemoved(Block *block);
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
+2
-4
@@ -43,9 +43,7 @@ NodeParam::NodeParam(const QString &id) :
|
||||
NodeParam::~NodeParam()
|
||||
{
|
||||
// Clear all connected edges
|
||||
while (!edges_.isEmpty()) {
|
||||
DisconnectEdge(edges_.last());
|
||||
}
|
||||
DisconnectAll();
|
||||
}
|
||||
|
||||
const QString NodeParam::id() const
|
||||
@@ -111,7 +109,7 @@ const QVector<NodeEdgePtr> &NodeParam::edges()
|
||||
void NodeParam::DisconnectAll()
|
||||
{
|
||||
while (!edges_.isEmpty()) {
|
||||
DisconnectEdge(edges_.first());
|
||||
DisconnectEdge(edges_.last());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -319,7 +319,7 @@ public:
|
||||
/**
|
||||
* @brief Disconnect any edges connecting this parameter to other parameters
|
||||
*/
|
||||
void DisconnectAll();
|
||||
virtual void DisconnectAll();
|
||||
|
||||
/**
|
||||
* @brief Connect an output parameter to an input parameter
|
||||
|
||||
Reference in New Issue
Block a user