/***
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 .
***/
#include "inputarray.h"
#include
#include "common/xmlutils.h"
#include "node.h"
OLIVE_NAMESPACE_ENTER
NodeInputArray::NodeInputArray(const QString &id, const DataType &type, const QVariant &default_value) :
NodeInput(id, type, default_value),
default_value_(default_value)
{
}
bool NodeInputArray::IsArray() const
{
return true;
}
int NodeInputArray::GetSize() const
{
return sub_params_.size();
}
void NodeInputArray::Prepend()
{
InsertAt(0);
}
void NodeInputArray::SetSize(int size)
{
int old_size = GetSize();
if (size == old_size) {
return;
}
if (size < old_size) {
// If the new size is less, delete all extraneous parameters
for (int i=size;i old_size) {
// If the new size is greater, create valid parameters for each slot
for (int i=old_size;iHasParamWithID(sub_id));
NodeInput* new_param = new NodeInput(sub_id, data_type(), default_value_);
new_param->setParent(this);
sub_params_.replace(i, new_param);
connect(new_param, &NodeInput::ValueChanged, this, &NodeInput::ValueChanged);
connect(new_param, &NodeInput::EdgeAdded, this, &NodeInputArray::SubParamEdgeAdded);
connect(new_param, &NodeInput::EdgeRemoved, this, &NodeInputArray::SubParamEdgeRemoved);
}
}
emit SizeChanged(size);
}
bool NodeInputArray::ContainsSubParameter(NodeInput *input) const
{
return sub_params_.contains(input);
}
int NodeInputArray::IndexOfSubParameter(NodeInput *input) const
{
return sub_params_.indexOf(input);
}
NodeInput *NodeInputArray::At(int index) const
{
return sub_params_.at(index);
}
NodeInput *NodeInputArray::First() const
{
return sub_params_.first();
}
NodeInput *NodeInputArray::Last() const
{
return sub_params_.last();
}
const QVector &NodeInputArray::sub_params()
{
return sub_params_;
}
void NodeInputArray::InsertAt(int index)
{
// Add another input at the end
Append();
// Shift all connections from index down
for (int i=sub_params_.size()-1;i>index;i--) {
NodeInput* this_param = sub_params_.at(i);
NodeInput* prev_param = sub_params_.at(i-1);
if (this_param->is_connected()) {
// Disconnect whatever is at this parameter (presumably its connection has already been copied so we can just remove it)
NodeParam::DisconnectEdge(this_param->edges().first());
}
if (prev_param->is_connected()) {
// Get edge here (only one since it's an input)
NodeEdgePtr edge = prev_param->edges().first();
// Disconnect it
NodeParam::DisconnectEdge(edge);
// Create a new edge between it and the next one down
NodeParam::ConnectEdge(edge->output(),
this_param);
}
}
}
void NodeInputArray::Append()
{
SetSize(GetSize() + 1);
}
void NodeInputArray::RemoveLast()
{
SetSize(GetSize() - 1);
}
void NodeInputArray::RemoveAt(int index)
{
// Shift all connections from index down
for (int i=index;iis_connected()) {
// Disconnect current edge
NodeParam::DisconnectEdge(this_param->edges().first());
}
if (i < sub_params_.size() - 1) {
NodeInput* next_param = sub_params_.at(i + 1);
if (next_param->is_connected()) {
// Get edge from next param
NodeEdgePtr edge = next_param->edges().first();
// Disconnect it
NodeParam::DisconnectEdge(edge);
// Reconnect it to this param
NodeParam::ConnectEdge(edge->output(),
this_param);
}
}
}
RemoveLast();
}
void NodeInputArray::LoadInternal(QXmlStreamReader *reader, XMLNodeData &xml_node_data, const QAtomicInt* cancelled)
{
if (reader->name() == QStringLiteral("subparameters")) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("input")) {
Append();
At(GetSize() - 1)->Load(reader, xml_node_data, cancelled);
} else {
reader->skipCurrentElement();
}
}
} else {
NodeInput::Load(reader, xml_node_data, cancelled);
}
}
void NodeInputArray::SaveInternal(QXmlStreamWriter *writer) const
{
writer->writeStartElement("subparameters");
foreach (NodeInput* sub, sub_params_) {
sub->Save(writer);
}
writer->writeEndElement(); // subparameters
}
OLIVE_NAMESPACE_EXIT