use strings to connect nodes

This makes the node system somewhat more high-level with the intent of making
working with them far more flexible and stable. By making the architecture more
abstracted, it becomes far less rigid which should allow us to do even more
with it and make it much less crash prone.
This commit is contained in:
itsmattkc
2021-02-09 15:48:37 +11:00
parent d1a3e22eaa
commit 81c1922911
138 changed files with 4487 additions and 3913 deletions
+18 -25
View File
@@ -63,59 +63,51 @@ void CurveView::Clear()
lines_.clear();
}
void CurveView::ConnectInput(NodeInput *input, int element, int track)
void CurveView::ConnectInput(const NodeKeyframeTrackReference& ref)
{
NodeInput::KeyframeTrackReference ref = {input, element, track};
if (connected_inputs_.contains(ref)) {
// Input wasn't connected, do nothing
return;
}
// Add keyframes from track
AddKeyframesOfTrack(input, element, track);
AddKeyframesOfTrack(ref);
// Append to the list
connected_inputs_.append(ref);
}
void CurveView::DisconnectInput(NodeInput *input, int element, int track)
void CurveView::DisconnectInput(const NodeKeyframeTrackReference& ref)
{
NodeInput::KeyframeTrackReference ref = {input, element, track};
if (!connected_inputs_.contains(ref)) {
// Input wasn't connected, do nothing
return;
}
// Remove keyframes belonging to this element and track
RemoveKeyframesOfTrack(input, element, track);
RemoveKeyframesOfTrack(ref);
// Remove from the list
connected_inputs_.removeOne(ref);
}
void CurveView::SelectKeyframesOfInput(NodeInput *input, int element, int track)
void CurveView::SelectKeyframesOfInput(const NodeKeyframeTrackReference& ref)
{
DeselectAll();
for (auto it=item_map().cbegin(); it!=item_map().cend(); it++) {
if (it.key()->parent() == input
&& it.key()->element() == element
&& it.key()->track() == track) {
if (it.key()->key_track_ref() == ref) {
it.value()->setSelected(true);
}
}
}
void CurveView::ZoomToFitInput(NodeInput *input, int element, int track)
void CurveView::ZoomToFitInput(const NodeKeyframeTrackReference& ref)
{
QList<NodeKeyframe*> keys;
for (auto it=item_map().cbegin(); it!=item_map().cend(); it++) {
if (it.key()->parent() == input
&& it.key()->element() == element
&& it.key()->track() == track) {
if (it.key()->key_track_ref() == ref) {
keys.append(it.key());
}
}
@@ -123,14 +115,14 @@ void CurveView::ZoomToFitInput(NodeInput *input, int element, int track)
ZoomToFitInternal(keys);
}
void CurveView::SetKeyframeTrackColor(const NodeInput::KeyframeTrackReference &ref, const QColor &color)
void CurveView::SetKeyframeTrackColor(const NodeKeyframeTrackReference &ref, const QColor &color)
{
// Insert color into hashmap
keyframe_colors_.insert(ref, color);
// Update all keyframes
for (auto it=item_map().cbegin(); it!=item_map().cend(); it++) {
if (it.key()->parent() == ref.input && it.key()->element() == ref.element && it.key()->track() == ref.track) {
if (it.key()->key_track_ref() == ref) {
it.value()->SetOverrideBrush(color);
}
}
@@ -187,13 +179,14 @@ void CurveView::drawBackground(QPainter *painter, const QRectF &rect)
painter->drawLines(lines);
// Draw keyframe lines
foreach (const NodeInput::KeyframeTrackReference& ref, connected_inputs_) {
NodeInput* input = ref.input;
foreach (const NodeKeyframeTrackReference& ref, connected_inputs_) {
Node* node = ref.input().node();
const QString& input = ref.input().input();
if (input->IsKeyframing(ref.element)) {
const QVector<NodeKeyframeTrack>& tracks = input->GetKeyframeTracks(ref.element);
if (node->IsInputKeyframing(input, ref.input().element())) {
const QVector<NodeKeyframeTrack>& tracks = node->GetKeyframeTracks(ref.input());
const NodeKeyframeTrack& track = tracks.at(ref.track);
const NodeKeyframeTrack& track = tracks.at(ref.track());
if (!track.isEmpty()) {
painter->setPen(QPen(keyframe_colors_.value(ref),
@@ -348,7 +341,7 @@ void CurveView::ZoomToFitInternal(const QList<NodeKeyframe *> &keys)
double max_val = DBL_MIN;
foreach (NodeKeyframe* key, keys) {
rational transformed_time = GetAdjustedTime(key->parent()->parent(),
rational transformed_time = GetAdjustedTime(key->parent(),
GetTimeTarget(),
key->time(),
false);
@@ -480,7 +473,7 @@ KeyframeViewItem* CurveView::AddKeyframe(NodeKeyframe* key)
{
KeyframeViewItem* item = super::AddKeyframe(key);
SetItemYFromKeyframeValue(key, item);
item->SetOverrideBrush(keyframe_colors_.value({key->parent(), key->element(), key->track()}));
item->SetOverrideBrush(keyframe_colors_.value(key->key_track_ref()));
connect(key, &NodeKeyframe::ValueChanged, this, &CurveView::KeyframeValueChanged);
connect(key, &NodeKeyframe::TypeChanged, this, &CurveView::KeyframeTypeChanged);
+7 -7
View File
@@ -38,15 +38,15 @@ public:
virtual void Clear() override;
void ConnectInput(NodeInput* input, int element, int track);
void ConnectInput(const NodeKeyframeTrackReference &ref);
void DisconnectInput(NodeInput* input, int element, int track);
void DisconnectInput(const NodeKeyframeTrackReference &ref);
void SelectKeyframesOfInput(NodeInput* input, int element, int track);
void SelectKeyframesOfInput(const NodeKeyframeTrackReference &ref);
void ZoomToFitInput(NodeInput* input, int element, int track);
void ZoomToFitInput(const NodeKeyframeTrackReference &ref);
void SetKeyframeTrackColor(const NodeInput::KeyframeTrackReference& ref, const QColor& color);
void SetKeyframeTrackColor(const NodeKeyframeTrackReference& ref, const QColor& color);
public slots:
virtual KeyframeViewItem* AddKeyframe(NodeKeyframe* key) override;
@@ -84,7 +84,7 @@ private:
void CreateBezierControlPoints(KeyframeViewItem *item);
QHash<NodeInput::KeyframeTrackReference, QColor> keyframe_colors_;
QHash<NodeKeyframeTrackReference, QColor> keyframe_colors_;
int text_padding_;
@@ -94,7 +94,7 @@ private:
QVector<BezierControlPointItem*> bezier_control_points_;
QVector<NodeInput::KeyframeTrackReference> connected_inputs_;
QVector<NodeKeyframeTrackReference> connected_inputs_;
private slots:
void KeyframeValueChanged();
+41 -35
View File
@@ -219,24 +219,37 @@ void CurveWidget::UpdateBridgeTime(const int64_t &timestamp)
void CurveWidget::ConnectNode(Node *node, bool connect)
{
foreach (NodeInput* input, node->parameters()) {
ConnectInput(input, connect);
foreach (const QString& input, node->inputs()) {
ConnectInput(node, input, connect);
}
// Connect add/remove signals
if (connect) {
QObject::connect(node, &Node::KeyframeAdded, this, &CurveWidget::AddKeyframe);
QObject::connect(node, &Node::KeyframeRemoved, this, &CurveWidget::RemoveKeyframe);
} else {
QObject::disconnect(node, &Node::KeyframeAdded, this, &CurveWidget::AddKeyframe);
QObject::disconnect(node, &Node::KeyframeRemoved, this, &CurveWidget::RemoveKeyframe);
}
}
void CurveWidget::ConnectInput(NodeInput *input, bool connect)
void CurveWidget::ConnectInput(Node *node, const QString &input, bool connect)
{
int track_count = NodeValue::get_number_of_keyframe_tracks(input->GetDataType());
if (!node->IsInputKeyframable(input)) {
qWarning() << "Tried to connect input that isn't keyframable";
return;
}
int track_count = NodeValue::get_number_of_keyframe_tracks(node->GetInputDataType(input));
bool multiple_tracks = track_count > 1;
for (int i=-1; i<input->ArraySize(); i++) {
if (!input->IsKeyframable()) {
continue;
}
int arr_sz = node->InputArraySize(input);
for (int i=-1; i<arr_sz; i++) {
// Generate a random color for this input
for (int j=0; j<input->GetKeyframeTracks(i).size(); j++) {
NodeInput::KeyframeTrackReference ref = {input, i, j};
const QVector<NodeKeyframeTrack>& tracks = node->GetKeyframeTracks(input, i);
for (int j=0; j<tracks.size(); j++) {
NodeKeyframeTrackReference ref(NodeInput(node, input, i), j);
if (!keyframe_colors_.contains(ref)) {
QColor c = QColor::fromHsv(std::rand()%360, std::rand()%255, 255);
@@ -247,35 +260,28 @@ void CurveWidget::ConnectInput(NodeInput *input, bool connect)
}
}
if (tree_view_->IsInputEnabled(input, i, multiple_tracks ? -1 : 0)) {
if (tree_view_->IsInputEnabled(NodeKeyframeTrackReference(NodeInput(node, input, i), multiple_tracks ? -1 : 0))) {
if (multiple_tracks) {
for (int j=0; j<track_count; j++) {
if (tree_view_->IsInputEnabled(input, i, j)) {
NodeKeyframeTrackReference ref(NodeInput(node, input, i), j);
if (tree_view_->IsInputEnabled(ref)) {
if (connect) {
view_->ConnectInput(input, i, j);
view_->ConnectInput(ref);
} else {
view_->DisconnectInput(input, i, j);
view_->DisconnectInput(ref);
}
}
}
} else {
NodeKeyframeTrackReference ref(NodeInput(node, input, i), 0);
if (connect) {
view_->ConnectInput(input, i, 0);
view_->ConnectInput(ref);
} else {
view_->DisconnectInput(input, i, 0);
view_->DisconnectInput(ref);
}
}
}
}
// Connect add/remove signals
if (connect) {
QObject::connect(input, &NodeInput::KeyframeAdded, this, &CurveWidget::AddKeyframe);
QObject::connect(input, &NodeInput::KeyframeRemoved, this, &CurveWidget::RemoveKeyframe);
} else {
QObject::disconnect(input, &NodeInput::KeyframeAdded, this, &CurveWidget::AddKeyframe);
QObject::disconnect(input, &NodeInput::KeyframeRemoved, this, &CurveWidget::RemoveKeyframe);
}
}
void CurveWidget::SelectionChanged()
@@ -357,12 +363,12 @@ void CurveWidget::NodeEnabledChanged(Node* n, bool e)
ConnectNode(n, e);
}
void CurveWidget::InputEnabledChanged(NodeInput *i, int element, int track, bool e)
void CurveWidget::InputEnabledChanged(const NodeKeyframeTrackReference& ref, bool e)
{
if (e) {
view_->ConnectInput(i, element, track);
view_->ConnectInput(ref);
} else {
view_->DisconnectInput(i, element, track);
view_->DisconnectInput(ref);
}
}
@@ -376,18 +382,18 @@ void CurveWidget::RemoveKeyframe(NodeKeyframe *key)
view_->RemoveKeyframe(key);
}
void CurveWidget::InputSelectionChanged(NodeInput *input, int element, int track)
void CurveWidget::InputSelectionChanged(const NodeKeyframeTrackReference& ref)
{
key_control_->SetInput(input, element);
key_control_->SetInput(ref.input());
if (input) {
view_->SelectKeyframesOfInput(input, element, track);
if (ref.IsValid()) {
view_->SelectKeyframesOfInput(ref);
}
}
void CurveWidget::InputDoubleClicked(NodeInput *input, int element, int track)
void CurveWidget::InputDoubleClicked(const NodeKeyframeTrackReference& ref)
{
view_->ZoomToFitInput(input, element, track);
view_->ZoomToFitInput(ref);
}
void CurveWidget::KeyframeViewDragged(int x, int y)
+5 -6
View File
@@ -27,7 +27,6 @@
#include <QWidget>
#include "curveview.h"
#include "node/input.h"
#include "widget/nodeparamview/nodeparamviewkeyframecontrol.h"
#include "widget/nodeparamview/nodeparamviewwidgetbridge.h"
#include "widget/nodetreeview/nodetreeview.h"
@@ -81,9 +80,9 @@ private:
void ConnectNode(Node* node, bool connect);
void ConnectInput(NodeInput* input, bool connect);
void ConnectInput(Node* node, const QString& input, bool connect);
QHash<NodeInput::KeyframeTrackReference, QColor> keyframe_colors_;
QHash<NodeKeyframeTrackReference, QColor> keyframe_colors_;
NodeTreeView* tree_view_;
@@ -108,15 +107,15 @@ private slots:
void NodeEnabledChanged(Node* n, bool e);
void InputEnabledChanged(NodeInput* i, int element, int track, bool e);
void InputEnabledChanged(const NodeKeyframeTrackReference &ref, bool e);
void AddKeyframe(NodeKeyframe* key);
void RemoveKeyframe(NodeKeyframe* key);
void InputSelectionChanged(NodeInput* input, int element, int track);
void InputSelectionChanged(const NodeKeyframeTrackReference& ref);
void InputDoubleClicked(NodeInput* input, int element, int track);
void InputDoubleClicked(const NodeKeyframeTrackReference& ref);
void KeyframeViewDragged(int x, int y);
+3 -3
View File
@@ -31,14 +31,14 @@ KeyframeView::KeyframeView(QWidget *parent) :
setAlignment(Qt::AlignLeft | Qt::AlignTop);
}
void KeyframeView::SetElementY(const NodeConnectable::InputConnection &c, int y)
void KeyframeView::SetElementY(const NodeInput &c, int y)
{
qreal scene_y = mapToScene(mapFromGlobal(QPoint(0, y))).y();
element_y_.insert(c, scene_y);
for (auto it=item_map().cbegin(); it!=item_map().cend(); it++) {
if (it.key()->parent() == c.input && it.key()->element() == c.element) {
if (it.key()->key_track_ref().input() == c) {
it.value()->SetOverrideY(scene_y);
}
}
@@ -60,7 +60,7 @@ void KeyframeView::SceneRectUpdateEvent(QRectF &rect)
KeyframeViewItem* KeyframeView::AddKeyframe(NodeKeyframe* key)
{
KeyframeViewItem* item = super::AddKeyframe(key);
item->SetOverrideY(element_y_.value({key->parent(), key->element()}));
item->SetOverrideY(element_y_.value(key->key_track_ref().input()));
return item;
}
+2 -2
View File
@@ -36,7 +36,7 @@ public:
max_scroll_ = i;
}
void SetElementY(const Node::InputConnection& c, int y);
void SetElementY(const NodeInput& c, int y);
protected:
virtual void wheelEvent(QWheelEvent* event) override;
@@ -47,7 +47,7 @@ public slots:
virtual KeyframeViewItem* AddKeyframe(NodeKeyframe* key) override;
private:
QHash<Node::InputConnection, qreal> element_y_;
QHash<NodeInput, qreal> element_y_;
int max_scroll_;
+39 -37
View File
@@ -74,35 +74,36 @@ void KeyframeViewBase::DeleteSelected()
void KeyframeViewBase::AddKeyframesOfNode(Node *n)
{
foreach (NodeInput* i, n->inputs()) {
AddKeyframesOfInput(i);
foreach (const QString& i, n->inputs()) {
AddKeyframesOfInput(n, i);
}
}
void KeyframeViewBase::AddKeyframesOfInput(NodeInput *input)
void KeyframeViewBase::AddKeyframesOfInput(Node* n, const QString& input)
{
if (!input->IsKeyframable()) {
if (!n->IsInputKeyframable(input)) {
return;
}
for (int i=-1; i<input->ArraySize(); i++) {
AddKeyframesOfElement(input, i);
int arr_sz = n->InputArraySize(input);
for (int i=-1; i<arr_sz; i++) {
AddKeyframesOfElement(NodeInput(n, input, i));
}
}
void KeyframeViewBase::AddKeyframesOfElement(NodeInput *input, int element)
void KeyframeViewBase::AddKeyframesOfElement(const NodeInput& input)
{
const QVector<NodeKeyframeTrack>& tracks = input->GetKeyframeTracks(element);
const QVector<NodeKeyframeTrack>& tracks = input.node()->GetKeyframeTracks(input);
for (int i=0; i<tracks.size(); i++) {
AddKeyframesOfTrack(input, element, i);
AddKeyframesOfTrack(NodeKeyframeTrackReference(input, i));
}
}
void KeyframeViewBase::AddKeyframesOfTrack(NodeInput *input, int element, int track)
void KeyframeViewBase::AddKeyframesOfTrack(const NodeKeyframeTrackReference& ref)
{
const QVector<NodeKeyframeTrack>& tracks = input->GetKeyframeTracks(element);
const NodeKeyframeTrack& t = tracks.at(track);
const QVector<NodeKeyframeTrack>& tracks = ref.input().node()->GetKeyframeTracks(ref.input());
const NodeKeyframeTrack& t = tracks.at(ref.track());
foreach (NodeKeyframe* key, t) {
AddKeyframe(key);
@@ -111,35 +112,36 @@ void KeyframeViewBase::AddKeyframesOfTrack(NodeInput *input, int element, int tr
void KeyframeViewBase::RemoveKeyframesOfNode(Node *n)
{
foreach (NodeInput* i, n->inputs()) {
RemoveKeyframesOfInput(i);
foreach (const QString& i, n->inputs()) {
RemoveKeyframesOfInput(n, i);
}
}
void KeyframeViewBase::RemoveKeyframesOfInput(NodeInput *input)
void KeyframeViewBase::RemoveKeyframesOfInput(Node* n, const QString& input)
{
if (!input->IsKeyframable()) {
if (!n->IsInputKeyframable(input)) {
return;
}
for (int i=-1; i<input->ArraySize(); i++) {
RemoveKeyframesOfElement(input, i);
int arr_sz = n->InputArraySize(input);
for (int i=-1; i<arr_sz; i++) {
RemoveKeyframesOfElement(NodeInput(n, input, i));
}
}
void KeyframeViewBase::RemoveKeyframesOfElement(NodeInput *input, int element)
void KeyframeViewBase::RemoveKeyframesOfElement(const NodeInput& input)
{
const QVector<NodeKeyframeTrack>& tracks = input->GetKeyframeTracks(element);
const QVector<NodeKeyframeTrack>& tracks = input.node()->GetKeyframeTracks(input);
for (int i=0; i<tracks.size(); i++) {
RemoveKeyframesOfTrack(input, element, i);
RemoveKeyframesOfTrack(NodeKeyframeTrackReference(input, i));
}
}
void KeyframeViewBase::RemoveKeyframesOfTrack(NodeInput *input, int element, int track)
void KeyframeViewBase::RemoveKeyframesOfTrack(const NodeKeyframeTrackReference& ref)
{
const QVector<NodeKeyframeTrack>& tracks = input->GetKeyframeTracks(element);
const NodeKeyframeTrack& t = tracks.at(track);
const QVector<NodeKeyframeTrack>& tracks = ref.input().node()->GetKeyframeTracks(ref.input());
const NodeKeyframeTrack& t = tracks.at(ref.track());
foreach (NodeKeyframe* key, t) {
RemoveKeyframe(key);
@@ -222,7 +224,7 @@ void KeyframeViewBase::mousePressEvent(QMouseEvent *event)
selected_keys_.replace(i, {key,
key->x(),
GetAdjustedTime(key->key()->parent()->parent(), GetTimeTarget(), key->key()->time(), false),
GetAdjustedTime(key->key()->parent(), GetTimeTarget(), key->key()->time(), false),
key->key()->value().toDouble()});
}
}
@@ -286,18 +288,17 @@ void KeyframeViewBase::mouseMoveEvent(QMouseEvent *event)
if (IsYAxisEnabled()) {
foreach (const KeyframeItemAndTime& keypair, selected_keys_) {
NodeInput* input = keypair.key->key()->parent();
QList<QByteArray> properties = input->dynamicPropertyNames();
Node* node = keypair.key->key()->parent();
const QString& input = keypair.key->key()->input();
double new_val = keypair.value - mouse_diff_scaled.y();
double limited = new_val;
if (properties.contains("min")) {
limited = qMax(limited, input->property("min").toDouble());
if (node->HasInputProperty(input, QStringLiteral("min"))) {
limited = qMax(limited, node->GetInputProperty(input, QStringLiteral("min")).toDouble());
}
if (properties.contains("max")) {
limited = qMin(limited, input->property("max").toDouble());
if (node->HasInputProperty(input, QStringLiteral("max"))) {
limited = qMin(limited, node->GetInputProperty(input, QStringLiteral("max")).toDouble());
}
if (limited != new_val) {
@@ -305,15 +306,16 @@ void KeyframeViewBase::mouseMoveEvent(QMouseEvent *event)
}
}
NodeInput* initial_drag_input = initial_drag_item_->key()->parent();
if (initial_drag_input->dynamicPropertyNames().contains("view")) {
display_type = static_cast<FloatSlider::DisplayType>(initial_drag_input->property("view").toInt());
Node* initial_drag_input = initial_drag_item_->key()->parent();
const QString& initial_drag_input_id = initial_drag_item_->key()->input();
if (initial_drag_input->HasInputProperty(initial_drag_input_id, QStringLiteral("view"))) {
display_type = static_cast<FloatSlider::DisplayType>(initial_drag_input->GetInputProperty(initial_drag_input_id, QStringLiteral("view")).toInt());
}
}
foreach (const KeyframeItemAndTime& keypair, selected_keys_) {
rational node_time = GetAdjustedTime(GetTimeTarget(),
keypair.key->key()->parent()->parent(),
keypair.key->key()->parent(),
CalculateNewTimeFromScreen(keypair.time, mouse_diff_scaled.x()),
true);
@@ -590,7 +592,7 @@ void KeyframeViewBase::AutoSelectKeyTimeNeighbors()
rational key_time = key_item->key()->time();
QVector<NodeKeyframe*> keys = key_item->key()->parent()->GetKeyframesAtTime(key_time, key_item->key()->element());
QVector<NodeKeyframe*> keys = key_item->key()->parent()->GetKeyframesAtTime(key_item->key()->input(), key_time, key_item->key()->element());
foreach (NodeKeyframe* k, keys) {
if (k == key_item->key()) {
+6 -6
View File
@@ -42,19 +42,19 @@ public:
void AddKeyframesOfNode(Node* n);
void AddKeyframesOfInput(NodeInput* input);
void AddKeyframesOfInput(Node *n, const QString &input);
void AddKeyframesOfElement(NodeInput* input, int element);
void AddKeyframesOfElement(const NodeInput &input);
void AddKeyframesOfTrack(NodeInput* input, int element, int track);
void AddKeyframesOfTrack(const NodeKeyframeTrackReference &ref);
void RemoveKeyframesOfNode(Node* n);
void RemoveKeyframesOfInput(NodeInput* input);
void RemoveKeyframesOfInput(Node *n, const QString &input);
void RemoveKeyframesOfElement(NodeInput* input, int element);
void RemoveKeyframesOfElement(const NodeInput &input);
void RemoveKeyframesOfTrack(NodeInput* input, int element, int track);
void RemoveKeyframesOfTrack(const NodeKeyframeTrackReference &ref);
void SelectAll();
+1 -2
View File
@@ -26,7 +26,6 @@
#include <QWidget>
#include "common/qtutils.h"
#include "node/input.h"
namespace olive {
@@ -117,7 +116,7 @@ void KeyframeViewItem::TimeTargetChangedEvent(Node *)
void KeyframeViewItem::UpdatePos()
{
rational adjusted = GetAdjustedTime(key_->parent()->parent(), GetTimeTarget(), key_->time(), false);
rational adjusted = GetAdjustedTime(key_->parent(), GetTimeTarget(), key_->time(), false);
setPos(adjusted.toDouble() * scale_, vert_center_);
}
+2 -3
View File
@@ -20,7 +20,6 @@
#include "keyframeviewundo.h"
#include "node/input.h"
#include "node/node.h"
#include "project/item/sequence/sequence.h"
@@ -35,7 +34,7 @@ KeyframeSetTypeCommand::KeyframeSetTypeCommand(NodeKeyframe* key, NodeKeyframe::
Project *KeyframeSetTypeCommand::GetRelevantProject() const
{
return key_->parent()->parent()->parent()->project();
return key_->parent()->parent()->project();
}
void KeyframeSetTypeCommand::redo()
@@ -66,7 +65,7 @@ KeyframeSetBezierControlPoint::KeyframeSetBezierControlPoint(NodeKeyframe* key,
Project *KeyframeSetBezierControlPoint::GetRelevantProject() const
{
return key_->parent()->parent()->parent()->project();
return key_->parent()->parent()->project();
}
void KeyframeSetBezierControlPoint::redo()
+10 -15
View File
@@ -291,12 +291,8 @@ void NodeParamView::AddNode(Node *n)
item->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable);
item->SetExpanded(node_expanded_state_.value(n, true));
foreach (NodeInput* input, n->inputs()) {
if (input->IsKeyframable()) {
connect(input, &NodeInput::KeyframeAdded, keyframe_view_, &KeyframeView::AddKeyframe);
connect(input, &NodeInput::KeyframeRemoved, keyframe_view_, &KeyframeView::RemoveKeyframe);
}
}
connect(n, &Node::KeyframeAdded, keyframe_view_, &KeyframeView::AddKeyframe);
connect(n, &Node::KeyframeRemoved, keyframe_view_, &KeyframeView::RemoveKeyframe);
connect(item, &NodeParamViewItem::RequestSetTime, this, &NodeParamView::ItemRequestedTimeChanged);
connect(item, &NodeParamViewItem::RequestSelectNode, this, &NodeParamView::RequestSelectNode);
@@ -326,12 +322,8 @@ void NodeParamView::RemoveNode(Node *n)
{
keyframe_view_->RemoveKeyframesOfNode(n);
foreach (NodeInput* input, n->inputs()) {
if (input->IsKeyframable()) {
disconnect(input, &NodeInput::KeyframeAdded, keyframe_view_, &KeyframeView::AddKeyframe);
disconnect(input, &NodeInput::KeyframeRemoved, keyframe_view_, &KeyframeView::RemoveKeyframe);
}
}
disconnect(n, &Node::KeyframeAdded, keyframe_view_, &KeyframeView::AddKeyframe);
disconnect(n, &Node::KeyframeRemoved, keyframe_view_, &KeyframeView::RemoveKeyframe);
delete items_.take(n);
@@ -414,9 +406,12 @@ void NodeParamView::KeyframeViewDragged(int x, int y)
void NodeParamView::UpdateElementY()
{
for (auto it=items_.cbegin(); it!=items_.cend(); it++) {
foreach (NodeInput* input, it.key()->inputs()) {
for (int i=-1; i<input->ArraySize(); i++) {
Node::InputConnection ic = {input, i};
foreach (const QString& input, it.key()->inputs()) {
int arr_sz = it.key()->InputArraySize(input);
for (int i=-1; i<arr_sz; i++) {
NodeInput ic = {it.key(), input, i};
int y = it.value()->GetElementY(ic);
keyframe_view_->SetElementY(ic, y);
}
@@ -20,22 +20,26 @@
#include "nodeparamviewarraywidget.h"
#include <QEvent>
#include <QHBoxLayout>
#include "node/node.h"
namespace olive {
NodeParamViewArrayWidget::NodeParamViewArrayWidget(NodeInput *array, QWidget* parent) :
NodeParamViewArrayWidget::NodeParamViewArrayWidget(Node *node, const QString &input, QWidget* parent) :
QWidget(parent),
array_(array)
node_(node),
input_(input)
{
QHBoxLayout* layout = new QHBoxLayout(this);
count_lbl_ = new QLabel();
layout->addWidget(count_lbl_);
connect(array_, &NodeInput::ArraySizeChanged, this, &NodeParamViewArrayWidget::UpdateCounter);
connect(node_, &Node::InputArraySizeChanged, this, &NodeParamViewArrayWidget::UpdateCounter);
UpdateCounter();
UpdateCounter(input_, node_->InputArraySize(input_));
}
void NodeParamViewArrayWidget::mouseDoubleClickEvent(QMouseEvent *event)
@@ -45,9 +49,11 @@ void NodeParamViewArrayWidget::mouseDoubleClickEvent(QMouseEvent *event)
emit DoubleClicked();
}
void NodeParamViewArrayWidget::UpdateCounter()
void NodeParamViewArrayWidget::UpdateCounter(const QString& input, int new_size)
{
count_lbl_->setText(tr("%1 element(s)").arg(array_->ArraySize()));
if (input == input_) {
count_lbl_->setText(tr("%1 element(s)").arg(new_size));
}
}
NodeParamViewArrayButton::NodeParamViewArrayButton(NodeParamViewArrayButton::Type type, QWidget *parent) :
@@ -25,7 +25,7 @@
#include <QPushButton>
#include <QWidget>
#include "node/input.h"
#include "node/param.h"
namespace olive {
@@ -54,7 +54,7 @@ class NodeParamViewArrayWidget : public QWidget
{
Q_OBJECT
public:
NodeParamViewArrayWidget(NodeInput* array, QWidget* parent = nullptr);
NodeParamViewArrayWidget(Node* node, const QString& input, QWidget* parent = nullptr);
signals:
void DoubleClicked();
@@ -63,12 +63,14 @@ protected:
virtual void mouseDoubleClickEvent(QMouseEvent* event) override;
private:
NodeInput* array_;
Node* node_;
QString input_;
QLabel* count_lbl_;
private slots:
void UpdateCounter();
void UpdateCounter(const QString &input, int new_size);
};
@@ -30,10 +30,10 @@
namespace olive {
NodeParamViewConnectedLabel::NodeParamViewConnectedLabel(NodeInput *input, int element, QWidget *parent) :
NodeParamViewConnectedLabel::NodeParamViewConnectedLabel(const NodeInput &input, QWidget *parent) :
QWidget(parent),
input_(input),
element_(element)
connected_node_(nullptr)
{
QHBoxLayout* layout = new QHBoxLayout(this);
layout->setSpacing(QtUtils::QFontMetricsWidth(fontMetrics(), QStringLiteral(" ")));
@@ -56,30 +56,38 @@ NodeParamViewConnectedLabel::NodeParamViewConnectedLabel(NodeInput *input, int e
connected_to_lbl_->setForegroundRole(QPalette::Link);
connected_to_lbl_->setFont(link_font);
UpdateConnected(nullptr, element_);
if (input_.IsConnected()) {
InputConnected(input_.GetConnectedOutput(), input_);
} else {
InputDisconnected(NodeOutput(), input_);
}
connect(input_, &NodeInput::InputConnected, this, &NodeParamViewConnectedLabel::UpdateConnected);
connect(input_, &NodeInput::InputDisconnected, this, &NodeParamViewConnectedLabel::UpdateConnected);
connect(input_.node(), &Node::InputConnected, this, &NodeParamViewConnectedLabel::InputConnected);
connect(input_.node(), &Node::InputDisconnected, this, &NodeParamViewConnectedLabel::InputDisconnected);
}
void NodeParamViewConnectedLabel::UpdateConnected(Node *src, int element)
void NodeParamViewConnectedLabel::InputConnected(const NodeOutput& output, const NodeInput& input)
{
Q_UNUSED(src)
if (element_ != element) {
// Do nothing
if (input_ != input) {
return;
}
QString connection_str;
connected_node_ = output;
if (input_->IsConnected(element_)) {
connection_str = input_->GetConnectedNode(element_)->Name();
} else {
connection_str = tr("Nothing");
UpdateLabel();
}
void NodeParamViewConnectedLabel::InputDisconnected(const NodeOutput &output, const NodeInput &input)
{
if (input_ != input) {
return;
}
connected_to_lbl_->setText(connection_str);
Q_UNUSED(output)
connected_node_ = NodeOutput();
UpdateLabel();
}
void NodeParamViewConnectedLabel::ShowLabelContextMenu()
@@ -88,7 +96,7 @@ void NodeParamViewConnectedLabel::ShowLabelContextMenu()
QAction* disconnect_action = m.addAction(tr("Disconnect"));
connect(disconnect_action, &QAction::triggered, this, [this](){
Core::instance()->undo_stack()->push(new NodeEdgeRemoveCommand(input_->GetConnectedNode(element_), input_, element_));
Core::instance()->undo_stack()->push(new NodeEdgeRemoveCommand(connected_node_, input_));
});
m.exec(QCursor::pos());
@@ -96,7 +104,22 @@ void NodeParamViewConnectedLabel::ShowLabelContextMenu()
void NodeParamViewConnectedLabel::ConnectionClicked()
{
emit RequestSelectNode({input_->GetConnectedNode(element_)});
if (connected_node_.IsValid()) {
emit RequestSelectNode({connected_node_.node()});
}
}
void NodeParamViewConnectedLabel::UpdateLabel()
{
QString s;
if (connected_node_.IsValid()) {
s = connected_node_.node()->Name();
} else {
s = tr("Nothing");
}
connected_to_lbl_->setText(s);
}
}
@@ -21,7 +21,7 @@
#ifndef NODEPARAMVIEWCONNECTEDLABEL_H
#define NODEPARAMVIEWCONNECTEDLABEL_H
#include "node/input.h"
#include "node/param.h"
#include "widget/clickablelabel/clickablelabel.h"
namespace olive {
@@ -29,24 +29,28 @@ namespace olive {
class NodeParamViewConnectedLabel : public QWidget {
Q_OBJECT
public:
NodeParamViewConnectedLabel(NodeInput* input, int element, QWidget* parent = nullptr);
NodeParamViewConnectedLabel(const NodeInput& input, QWidget* parent = nullptr);
signals:
void RequestSelectNode(const QVector<Node*>& node);
private slots:
void UpdateConnected(Node* src, int element);
void InputConnected(const NodeOutput &output, const NodeInput &input);
void InputDisconnected(const NodeOutput &output, const NodeInput &input);
void ShowLabelContextMenu();
void ConnectionClicked();
private:
void UpdateLabel();
ClickableLabel* connected_to_lbl_;
NodeInput* input_;
NodeInput input_;
int element_;
NodeOutput connected_node_;
};
+52 -52
View File
@@ -134,7 +134,7 @@ bool NodeParamViewItem::IsExpanded() const
return body_->isVisible();
}
int NodeParamViewItem::GetElementY(const NodeConnectable::InputConnection &c) const
int NodeParamViewItem::GetElementY(const NodeInput &c) const
{
if (IsExpanded()) {
return body_->GetElementY(c);
@@ -209,14 +209,12 @@ NodeParamViewItemBody::NodeParamViewItemBody(Node* node, QWidget *parent) :
int insert_row = 0;
// Create widgets all root level components
for (int i=0; i<node->inputs().size(); i++) {
NodeInput* input = node->inputs().at(i);
CreateWidgets(root_layout, input, -1, insert_row);
foreach (const QString& input, node->inputs()) {
CreateWidgets(root_layout, node, input, -1, insert_row);
insert_row++;
if (input->IsArray()) {
if (node->InputIsArray(input)) {
// Insert here
QWidget* array_widget = new QWidget();
@@ -225,28 +223,33 @@ NodeParamViewItemBody::NodeParamViewItemBody(Node* node, QWidget *parent) :
root_layout->addWidget(array_widget, insert_row, 1, 1, 10);
for (int j=0; j<input->ArraySize(); j++) {
CreateWidgets(array_layout, input, j, j);
int arr_sz = node->InputArraySize(input);
for (int j=0; j<arr_sz; j++) {
CreateWidgets(array_layout, node, input, j, j);
}
// Add one last add button for appending to the array
NodeParamViewArrayButton* append_btn = new NodeParamViewArrayButton(NodeParamViewArrayButton::kAdd);
connect(append_btn, &NodeParamViewArrayButton::clicked, this, &NodeParamViewItemBody::ArrayAppendClicked);
array_layout->addWidget(append_btn, input->ArraySize(), kArrayInsertColumn);
array_layout->addWidget(append_btn, arr_sz, kArrayInsertColumn);
array_widget->setVisible(false);
array_ui_.insert(input, {array_widget, input->ArraySize(), append_btn});
array_ui_.insert({node, input}, {array_widget, arr_sz, append_btn});
insert_row++;
connect(input, &NodeInput::ArraySizeChanged, this, &NodeParamViewItemBody::InputArraySizeChanged);
}
}
connect(node, &Node::InputArraySizeChanged, this, &NodeParamViewItemBody::InputArraySizeChanged);
connect(node, &Node::InputConnected, this, &NodeParamViewItemBody::EdgeChanged);
connect(node, &Node::InputDisconnected, this, &NodeParamViewItemBody::EdgeChanged);
}
void NodeParamViewItemBody::CreateWidgets(QGridLayout* layout, NodeInput *input, int element, int row)
void NodeParamViewItemBody::CreateWidgets(QGridLayout* layout, Node *node, const QString &input, int element, int row)
{
NodeInput input_ref(node, input, element);
InputUI ui_objects;
// Add descriptor label
@@ -255,7 +258,7 @@ void NodeParamViewItemBody::CreateWidgets(QGridLayout* layout, NodeInput *input,
// Label always goes into column 1 (array collapse button goes into 0 if applicable)
layout->addWidget(ui_objects.main_label, row, 1);
if (input->IsArray()) {
if (node->InputIsArray(input)) {
if (element == -1) {
// Create a collapse toggle for expanding/collapsing the array
@@ -270,7 +273,7 @@ void NodeParamViewItemBody::CreateWidgets(QGridLayout* layout, NodeInput *input,
// Connect signal to show/hide array params when toggled
connect(array_collapse_btn, &CollapseButton::toggled, this, &NodeParamViewItemBody::ArrayCollapseBtnPressed);
array_collapse_buttons_.insert(input, array_collapse_btn);
array_collapse_buttons_.insert({node, input}, array_collapse_btn);
} else {
@@ -290,7 +293,7 @@ void NodeParamViewItemBody::CreateWidgets(QGridLayout* layout, NodeInput *input,
}
// Create a widget/input bridge for this input
ui_objects.widget_bridge = new NodeParamViewWidgetBridge(input, element, this);
ui_objects.widget_bridge = new NodeParamViewWidgetBridge(NodeInput(node, input, element), this);
connect(ui_objects.widget_bridge, &NodeParamViewWidgetBridge::ArrayWidgetDoubleClicked, this, &NodeParamViewItemBody::ToggleArrayExpanded);
// 0 is for the array collapse button, 1 is for the main label, widgets start at 2
@@ -303,28 +306,25 @@ void NodeParamViewItemBody::CreateWidgets(QGridLayout* layout, NodeInput *input,
layout->addWidget(w, row, i+widget_start);
}
if (input->IsConnectable()) {
if (node->IsInputConnectable(input)) {
// Create clickable label used when an input is connected
ui_objects.connected_label = new NodeParamViewConnectedLabel(input, element);
ui_objects.connected_label = new NodeParamViewConnectedLabel(input_ref);
connect(ui_objects.connected_label, &NodeParamViewConnectedLabel::RequestSelectNode, this, &NodeParamViewItemBody::RequestSelectNode);
layout->addWidget(ui_objects.connected_label, row, widget_start);
connect(input, &NodeInput::InputConnected, this, &NodeParamViewItemBody::EdgeChanged);
connect(input, &NodeInput::InputDisconnected, this, &NodeParamViewItemBody::EdgeChanged);
}
// Add keyframe control to this layout if parameter is keyframable
if (input->IsKeyframable()) {
if (node->IsInputKeyframable(input)) {
ui_objects.key_control = new NodeParamViewKeyframeControl();
ui_objects.key_control->SetInput(input, element);
ui_objects.key_control->SetInput(input_ref);
layout->addWidget(ui_objects.key_control, row, kKeyControlColumn);
connect(ui_objects.key_control, &NodeParamViewKeyframeControl::RequestSetTime, this, &NodeParamViewItemBody::RequestSetTime);
}
input_ui_map_.insert(Node::InputConnection(input, element), ui_objects);
input_ui_map_.insert(input_ref, ui_objects);
if (input->IsConnectable()) {
UpdateUIForEdgeConnection(input, element);
if (node->IsInputConnectable(input)) {
UpdateUIForEdgeConnection(input_ref);
}
}
@@ -355,23 +355,23 @@ void NodeParamViewItemBody::SetTime(const rational &time)
void NodeParamViewItemBody::Retranslate()
{
for (auto i=input_ui_map_.begin(); i!=input_ui_map_.end(); i++) {
const Node::InputConnection& ic = i.key();
const NodeInput& ic = i.key();
if (ic.input->IsArray() && ic.element >= 0) {
if (ic.IsArray() && ic.element() >= 0) {
// Make the label the array index
i.value().main_label->setText(tr("%n:", nullptr, ic.element));
i.value().main_label->setText(tr("%n:", nullptr, ic.element()));
} else {
// Set to the input's name
i.value().main_label->setText(tr("%1:").arg(i.key().input->name()));
i.value().main_label->setText(tr("%1:").arg(ic.name()));
}
}
}
int NodeParamViewItemBody::GetElementY(NodeConnectable::InputConnection c) const
int NodeParamViewItemBody::GetElementY(NodeInput c) const
{
if (c.input->IsArray() && !array_ui_.value(c.input).widget->isVisible()) {
if (c.IsArray() && !array_ui_.value(c.input_pair()).widget->isVisible()) {
// Array is collapsed, so we'll return the Y of its root
c.element = -1;
c.set_element(-1);
}
// Find its row in the parameters
@@ -387,40 +387,40 @@ int NodeParamViewItemBody::GetElementY(NodeConnectable::InputConnection c) const
return lbl_center.y();
}
void NodeParamViewItemBody::EdgeChanged(Node* src, int element)
void NodeParamViewItemBody::EdgeChanged(const NodeOutput& output, const NodeInput& input)
{
Q_UNUSED(src)
Q_UNUSED(output)
UpdateUIForEdgeConnection(static_cast<NodeInput*>(sender()), element);
UpdateUIForEdgeConnection(input);
}
void NodeParamViewItemBody::UpdateUIForEdgeConnection(NodeInput *input, int element)
void NodeParamViewItemBody::UpdateUIForEdgeConnection(const NodeInput& input)
{
// Show/hide bridge widgets
const InputUI& ui_objects = input_ui_map_[{input, element}];
const InputUI& ui_objects = input_ui_map_[input];
foreach (QWidget* w, ui_objects.widget_bridge->widgets()) {
w->setVisible(!input->IsConnected(element));
w->setVisible(!input.IsConnected());
}
// Show/hide connection label
ui_objects.connected_label->setVisible(input->IsConnected(element));
ui_objects.connected_label->setVisible(input.IsConnected());
}
void NodeParamViewItemBody::ArrayCollapseBtnPressed(bool checked)
{
NodeInput* input = array_collapse_buttons_.key(static_cast<CollapseButton*>(sender()));
const NodeInputPair& input = array_collapse_buttons_.key(static_cast<CollapseButton*>(sender()));
array_ui_.value(input).widget->setVisible(checked);
emit ArrayExpandedChanged(checked);
}
void NodeParamViewItemBody::InputArraySizeChanged(int size)
void NodeParamViewItemBody::InputArraySizeChanged(const QString& input, int size)
{
NodeInput* input = static_cast<NodeInput*>(sender());
Node* node = static_cast<Node*>(sender());
ArrayUI& array_ui = array_ui_[input];
ArrayUI& array_ui = array_ui_[{node, input}];
if (size != array_ui.count) {
QGridLayout* grid = static_cast<QGridLayout*>(array_ui.widget->layout());
@@ -430,12 +430,12 @@ void NodeParamViewItemBody::InputArraySizeChanged(int size)
grid->addWidget(array_ui.append_btn, size, kArrayInsertColumn);
for (int i=array_ui.count; i<size; i++) {
CreateWidgets(grid, input, i, i);
CreateWidgets(grid, node, input, i, i);
}
} else {
for (int i=array_ui.count-1; i>=size; i--) {
// Our UI count is larger than the size, delete
InputUI input_ui = input_ui_map_.take({input, i});
InputUI input_ui = input_ui_map_.take({node, input, i});
delete input_ui.main_label;
qDeleteAll(input_ui.widget_bridge->widgets());
delete input_ui.widget_bridge;
@@ -458,7 +458,7 @@ void NodeParamViewItemBody::ArrayAppendClicked()
{
for (auto it=array_ui_.cbegin(); it!=array_ui_.cend(); it++) {
if (it.value().append_btn == sender()) {
it.key()->ArrayAppend(true);
it.key().node->InputArrayAppend(it.key().input, true);
break;
}
}
@@ -469,8 +469,8 @@ void NodeParamViewItemBody::ArrayInsertClicked()
for (auto it=input_ui_map_.cbegin(); it!=input_ui_map_.cend(); it++) {
if (it.value().array_insert_btn == sender()) {
// Found our input and element
const Node::InputConnection& ic = it.key();
ic.input->ArrayInsert(ic.element, true);
const NodeInput& ic = it.key();
ic.node()->InputArrayInsert(ic.input(), ic.element(), true);
break;
}
}
@@ -481,8 +481,8 @@ void NodeParamViewItemBody::ArrayRemoveClicked()
for (auto it=input_ui_map_.cbegin(); it!=input_ui_map_.cend(); it++) {
if (it.value().array_remove_btn == sender()) {
// Found our input and element
const Node::InputConnection& ic = it.key();
ic.input->ArrayRemove(ic.element, true);
const NodeInput& ic = it.key();
ic.node()->InputArrayRemove(ic.input(), ic.element(), true);
break;
}
}
@@ -494,7 +494,7 @@ void NodeParamViewItemBody::ToggleArrayExpanded()
for (auto it=input_ui_map_.cbegin(); it!=input_ui_map_.cend(); it++) {
if (it.value().widget_bridge == bridge) {
CollapseButton* b = array_collapse_buttons_.value(it.key().input);
CollapseButton* b = array_collapse_buttons_.value(it.key().input_pair());
b->setChecked(!b->isChecked());
return;
}
+9 -9
View File
@@ -81,7 +81,7 @@ public:
void Retranslate();
int GetElementY(NodeConnectable::InputConnection c) const;
int GetElementY(NodeInput c) const;
signals:
void RequestSetTime(const rational& time);
@@ -91,9 +91,9 @@ signals:
void ArrayExpandedChanged(bool e);
private:
void CreateWidgets(QGridLayout *layout, NodeInput* input, int element, int row_index);
void CreateWidgets(QGridLayout *layout, Node* node, const QString& input, int element, int row_index);
void UpdateUIForEdgeConnection(NodeInput* input, int element);
void UpdateUIForEdgeConnection(const NodeInput &input);
struct InputUI {
InputUI();
@@ -107,7 +107,7 @@ private:
NodeParamViewArrayButton* array_remove_btn;
};
QHash<Node::InputConnection, InputUI> input_ui_map_;
QHash<NodeInput, InputUI> input_ui_map_;
struct ArrayUI {
QWidget* widget;
@@ -115,9 +115,9 @@ private:
NodeParamViewArrayButton* append_btn;
};
QHash<NodeInput*, ArrayUI> array_ui_;
QHash<NodeInputPair, ArrayUI> array_ui_;
QHash<NodeInput*, CollapseButton*> array_collapse_buttons_;
QHash<NodeInputPair, CollapseButton*> array_collapse_buttons_;
/**
* @brief The column to place the keyframe controls in
@@ -131,11 +131,11 @@ private:
static const int kArrayRemoveColumn;
private slots:
void EdgeChanged(Node *src, int element);
void EdgeChanged(const NodeOutput &output, const NodeInput &input);
void ArrayCollapseBtnPressed(bool checked);
void InputArraySizeChanged(int size);
void InputArraySizeChanged(const QString &input, int size);
void ArrayAppendClicked();
@@ -168,7 +168,7 @@ public:
update();
}
int GetElementY(const Node::InputConnection& c) const;
int GetElementY(const NodeInput& c) const;
public slots:
void SetExpanded(bool e);
@@ -30,8 +30,7 @@
namespace olive {
NodeParamViewKeyframeControl::NodeParamViewKeyframeControl(bool right_align, QWidget *parent) :
QWidget(parent),
input_(nullptr)
QWidget(parent)
{
QHBoxLayout* layout = new QHBoxLayout(this);
layout->setMargin(0);
@@ -64,37 +63,36 @@ NodeParamViewKeyframeControl::NodeParamViewKeyframeControl(bool right_align, QWi
connect(next_key_btn_, &QPushButton::clicked, this, &NodeParamViewKeyframeControl::GoToNextKey);
connect(toggle_key_btn_, &QPushButton::clicked, this, &NodeParamViewKeyframeControl::ToggleKeyframe);
connect(enable_key_btn_, &QPushButton::toggled, this, &NodeParamViewKeyframeControl::ShowButtonsFromKeyframeEnable);
connect(enable_key_btn_, &QPushButton::clicked, this, &NodeParamViewKeyframeControl::KeyframeEnableChanged);
connect(enable_key_btn_, &QPushButton::clicked, this, &NodeParamViewKeyframeControl::KeyframeEnableBtnClicked);
// Set defaults
SetInput(nullptr, -1);
SetInput(NodeInput());
ShowButtonsFromKeyframeEnable(false);
}
void NodeParamViewKeyframeControl::SetInput(NodeInput *input, int element)
void NodeParamViewKeyframeControl::SetInput(const NodeInput& input)
{
if (input_ != nullptr) {
disconnect(input_, &NodeInput::KeyframeEnableChanged, enable_key_btn_, &QPushButton::setChecked);
disconnect(input_, &NodeInput::KeyframeAdded, this, &NodeParamViewKeyframeControl::UpdateState);
disconnect(input_, &NodeInput::KeyframeRemoved, this, &NodeParamViewKeyframeControl::UpdateState);
disconnect(input_, &NodeInput::KeyframeTimeChanged, this, &NodeParamViewKeyframeControl::UpdateState);
if (input_.IsValid()) {
disconnect(input_.node(), &Node::KeyframeEnableChanged, this, &NodeParamViewKeyframeControl::KeyframeEnableChanged);
disconnect(input_.node(), &Node::KeyframeAdded, this, &NodeParamViewKeyframeControl::UpdateState);
disconnect(input_.node(), &Node::KeyframeRemoved, this, &NodeParamViewKeyframeControl::UpdateState);
disconnect(input_.node(), &Node::KeyframeTimeChanged, this, &NodeParamViewKeyframeControl::UpdateState);
}
input_ = input;
element_ = element;
SetButtonsEnabled(input_);
SetButtonsEnabled(input_.IsValid());
// Pick up keyframing value
enable_key_btn_->setChecked(input_ && input_->IsKeyframing(element_));
enable_key_btn_->setChecked(input_.IsValid() && input_.IsKeyframing());
// Update buttons
UpdateState();
if (input_ != nullptr) {
connect(input_, &NodeInput::KeyframeEnableChanged, enable_key_btn_, &QPushButton::setChecked);
connect(input_, &NodeInput::KeyframeAdded, this, &NodeParamViewKeyframeControl::UpdateState);
connect(input_, &NodeInput::KeyframeRemoved, this, &NodeParamViewKeyframeControl::UpdateState);
connect(input_, &NodeInput::KeyframeTimeChanged, this, &NodeParamViewKeyframeControl::UpdateState);
if (input_.IsValid()) {
connect(input_.node(), &Node::KeyframeEnableChanged, this, &NodeParamViewKeyframeControl::KeyframeEnableChanged);
connect(input_.node(), &Node::KeyframeAdded, this, &NodeParamViewKeyframeControl::UpdateState);
connect(input_.node(), &Node::KeyframeRemoved, this, &NodeParamViewKeyframeControl::UpdateState);
connect(input_.node(), &Node::KeyframeTimeChanged, this, &NodeParamViewKeyframeControl::UpdateState);
}
}
@@ -124,12 +122,12 @@ void NodeParamViewKeyframeControl::SetButtonsEnabled(bool e)
rational NodeParamViewKeyframeControl::GetCurrentTimeAsNodeTime() const
{
return GetAdjustedTime(GetTimeTarget(), input_->parent(), time_, true);
return GetAdjustedTime(GetTimeTarget(), input_.node(), time_, true);
}
rational NodeParamViewKeyframeControl::ConvertToViewerTime(const rational &r) const
{
return GetAdjustedTime(input_->parent(), GetTimeTarget(), r, false);
return GetAdjustedTime(input_.node(), GetTimeTarget(), r, false);
}
void NodeParamViewKeyframeControl::ShowButtonsFromKeyframeEnable(bool e)
@@ -143,34 +141,33 @@ void NodeParamViewKeyframeControl::ToggleKeyframe(bool e)
{
rational node_time = GetCurrentTimeAsNodeTime();
QVector<NodeKeyframe*> keys = input_->GetKeyframesAtTime(node_time, element_);
QVector<NodeKeyframe*> keys = input_.node()->GetKeyframesAtTime(input_, node_time);
MultiUndoCommand* command = new MultiUndoCommand();
int nb_tracks = input_->GetNumberOfKeyframeTracks();
int nb_tracks = input_.node()->GetNumberOfKeyframeTracks(input_);
if (e && keys.isEmpty()) {
// Add a keyframe here (one for each track)
for (int i=0;i<nb_tracks;i++) {
NodeKeyframe* key = new NodeKeyframe(node_time,
input_->GetValueAtTimeForTrack(node_time, i, element_),
input_->GetBestKeyframeTypeForTime(node_time, i, element_),
input_.node()->GetSplitValueAtTimeOnTrack(input_, node_time, i),
input_.node()->GetBestKeyframeTypeForTimeOnTrack(input_, node_time, i),
i,
element_);
input_.element(),
input_.input());
command->add_child(new NodeParamInsertKeyframeCommand(input_, key));
command->add_child(new NodeParamInsertKeyframeCommand(input_.node(), key));
}
} else if (!e && !keys.isEmpty()) {
// Remove all keyframes at this time
foreach (NodeKeyframe* key, keys) {
command->add_child(new NodeParamRemoveKeyframeCommand(key));
if (input_->GetKeyframeTracks(key->track()).size() == 1) {
if (input_.node()->GetKeyframeTracks(input_).size() == 1) {
// If this was the last keyframe on this track, set the standard value to the value at this time too
command->add_child(new NodeParamSetStandardValueCommand(input_,
key->track(),
element_,
input_->GetValueAtTimeForTrack(node_time, key->track(), element_)));
command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(input_, key->track()),
input_.node()->GetSplitValueAtTimeOnTrack(input_, node_time, key->track())));
}
}
}
@@ -180,25 +177,25 @@ void NodeParamViewKeyframeControl::ToggleKeyframe(bool e)
void NodeParamViewKeyframeControl::UpdateState()
{
if (!input_) {
if (!input_.IsValid()) {
return;
}
NodeKeyframe* earliest_key = input_->GetEarliestKeyframe(element_);
NodeKeyframe* latest_key = input_->GetLatestKeyframe(element_);
NodeKeyframe* earliest_key = input_.node()->GetEarliestKeyframe(input_);
NodeKeyframe* latest_key = input_.node()->GetLatestKeyframe(input_);
rational node_time = GetCurrentTimeAsNodeTime();
prev_key_btn_->setEnabled(earliest_key && node_time > earliest_key->time());
next_key_btn_->setEnabled(latest_key && node_time < latest_key->time());
toggle_key_btn_->setChecked(input_->HasKeyframeAtTime(node_time, element_));
toggle_key_btn_->setChecked(input_.node()->HasKeyframeAtTime(input_, node_time));
}
void NodeParamViewKeyframeControl::GoToPreviousKey()
{
rational node_time = GetCurrentTimeAsNodeTime();
NodeKeyframe* previous_key = input_->GetClosestKeyframeBeforeTime(node_time, element_);
NodeKeyframe* previous_key = input_.node()->GetClosestKeyframeBeforeTime(input_, node_time);
if (previous_key) {
rational key_time = ConvertToViewerTime(previous_key->time());
@@ -211,7 +208,7 @@ void NodeParamViewKeyframeControl::GoToNextKey()
{
rational node_time = GetCurrentTimeAsNodeTime();
NodeKeyframe* next_key = input_->GetClosestKeyframeAfterTime(node_time, element_);
NodeKeyframe* next_key = input_.node()->GetClosestKeyframeAfterTime(input_, node_time);
if (next_key) {
rational key_time = ConvertToViewerTime(next_key->time());
@@ -220,9 +217,9 @@ void NodeParamViewKeyframeControl::GoToNextKey()
}
}
void NodeParamViewKeyframeControl::KeyframeEnableChanged(bool e)
void NodeParamViewKeyframeControl::KeyframeEnableBtnClicked(bool e)
{
if (e == input_->IsKeyframing(element_)) {
if (e == input_.IsKeyframing()) {
// No-op
return;
}
@@ -231,19 +228,20 @@ void NodeParamViewKeyframeControl::KeyframeEnableChanged(bool e)
if (e) {
// Enable keyframing
command->add_child(new NodeParamSetKeyframingCommand(input_, element_, true));
command->add_child(new NodeParamSetKeyframingCommand(input_, true));
// Create one keyframe across all tracks here
const QVector<QVariant>& key_vals = input_->GetSplitStandardValue(element_);
const QVector<QVariant>& key_vals = input_.node()->GetSplitStandardValue(input_);
for (int i=0;i<key_vals.size();i++) {
NodeKeyframe* key = new NodeKeyframe(GetCurrentTimeAsNodeTime(),
key_vals.at(i),
NodeKeyframe::kDefaultType,
i,
element_);
input_.element(),
input_.input());
command->add_child(new NodeParamInsertKeyframeCommand(input_, key));
command->add_child(new NodeParamInsertKeyframeCommand(input_.node(), key));
}
} else {
// Confirm the user wants to clear all keyframes
@@ -253,10 +251,10 @@ void NodeParamViewKeyframeControl::KeyframeEnableChanged(bool e)
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
// Store value at this time, we'll set this as the persistent value later
const QVector<QVariant>& stored_vals = input_->GetSplitValuesAtTime(GetCurrentTimeAsNodeTime(), element_);
const QVector<QVariant>& stored_vals = input_.node()->GetSplitValueAtTime(input_, GetCurrentTimeAsNodeTime());
// Delete all keyframes
foreach (const NodeKeyframeTrack& track, input_->GetKeyframeTracks(element_)) {
foreach (const NodeKeyframeTrack& track, input_.node()->GetKeyframeTracks(input_)) {
for (int i=track.size()-1;i>=0;i--) {
command->add_child(new NodeParamRemoveKeyframeCommand(track.at(i)));
}
@@ -264,11 +262,11 @@ void NodeParamViewKeyframeControl::KeyframeEnableChanged(bool e)
// Update standard value
for (int i=0;i<stored_vals.size();i++) {
command->add_child(new NodeParamSetStandardValueCommand(input_, i, element_, stored_vals.at(i)));
command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(input_, i), stored_vals.at(i)));
}
// Disable keyframing
command->add_child(new NodeParamSetKeyframingCommand(input_, element_, false));
command->add_child(new NodeParamSetKeyframingCommand(input_, false));
} else {
// Disable action has effectively been ignored
@@ -279,4 +277,11 @@ void NodeParamViewKeyframeControl::KeyframeEnableChanged(bool e)
Core::instance()->undo_stack()->pushIfHasChildren(command);
}
void NodeParamViewKeyframeControl::KeyframeEnableChanged(const NodeInput &input, bool e)
{
if (input_ == input) {
enable_key_btn_->setChecked(e);
}
}
}
@@ -24,7 +24,7 @@
#include <QPushButton>
#include <QWidget>
#include "node/input.h"
#include "node/param.h"
#include "widget/timetarget/timetarget.h"
namespace olive {
@@ -35,17 +35,12 @@ class NodeParamViewKeyframeControl : public QWidget, public TimeTargetObject
public:
NodeParamViewKeyframeControl(bool right_align = true, QWidget* parent = nullptr);
NodeInput* GetConnectedInput() const
const NodeInput& GetConnectedInput() const
{
return input_;
}
int GetConnectedElement() const
{
return element_;
}
void SetInput(NodeInput* input, int element);
void SetInput(const NodeInput& input);
void SetTime(const rational& time);
@@ -66,8 +61,7 @@ private:
QPushButton* next_key_btn_;
QPushButton* enable_key_btn_;
NodeInput* input_;
int element_;
NodeInput input_;
rational time_;
@@ -82,7 +76,9 @@ private slots:
void GoToNextKey();
void KeyframeEnableChanged(bool e);
void KeyframeEnableBtnClicked(bool e);
void KeyframeEnableChanged(const NodeInput& input, bool e);
};
+23 -27
View File
@@ -25,27 +25,26 @@
namespace olive {
NodeParamSetKeyframingCommand::NodeParamSetKeyframingCommand(NodeInput *input, int element, bool setting) :
NodeParamSetKeyframingCommand::NodeParamSetKeyframingCommand(const NodeInput &input, bool setting) :
input_(input),
setting_(setting),
element_(element)
setting_(setting)
{
Q_ASSERT(setting != input_->IsKeyframing());
Q_ASSERT(setting != input_.IsKeyframing());
}
Project *NodeParamSetKeyframingCommand::GetRelevantProject() const
{
return input_->parent()->parent()->project();
return input_.node()->parent()->project();
}
void NodeParamSetKeyframingCommand::redo()
{
input_->SetIsKeyframing(setting_, element_);
input_.node()->SetInputIsKeyframing(input_, setting_);
}
void NodeParamSetKeyframingCommand::undo()
{
input_->SetIsKeyframing(!setting_, element_);
input_.node()->SetInputIsKeyframing(input_, !setting_);
}
NodeParamSetKeyframeValueCommand::NodeParamSetKeyframeValueCommand(NodeKeyframe* key, const QVariant& value) :
@@ -65,7 +64,7 @@ NodeParamSetKeyframeValueCommand::NodeParamSetKeyframeValueCommand(NodeKeyframe*
Project *NodeParamSetKeyframeValueCommand::GetRelevantProject() const
{
return key_->parent()->parent()->parent()->project();
return key_->parent()->parent()->project();
}
void NodeParamSetKeyframeValueCommand::redo()
@@ -78,16 +77,17 @@ void NodeParamSetKeyframeValueCommand::undo()
key_->set_value(old_value_);
}
NodeParamInsertKeyframeCommand::NodeParamInsertKeyframeCommand(NodeInput *input, NodeKeyframe* keyframe) :
input_(input),
NodeParamInsertKeyframeCommand::NodeParamInsertKeyframeCommand(Node* node, NodeKeyframe* keyframe) :
input_(node),
keyframe_(keyframe)
{
keyframe_->setParent(&memory_manager_);
// Take ownership of the keyframe
undo();
}
Project *NodeParamInsertKeyframeCommand::GetRelevantProject() const
{
return input_->parent()->parent()->project();
return input_->parent()->project();
}
void NodeParamInsertKeyframeCommand::redo()
@@ -108,7 +108,7 @@ NodeParamRemoveKeyframeCommand::NodeParamRemoveKeyframeCommand(NodeKeyframe* key
Project *NodeParamRemoveKeyframeCommand::GetRelevantProject() const
{
return input_->parent()->parent()->project();
return input_->parent()->project();
}
void NodeParamRemoveKeyframeCommand::redo()
@@ -138,7 +138,7 @@ NodeParamSetKeyframeTimeCommand::NodeParamSetKeyframeTimeCommand(NodeKeyframe* k
Project *NodeParamSetKeyframeTimeCommand::GetRelevantProject() const
{
return key_->parent()->parent()->parent()->project();
return key_->parent()->parent()->project();
}
void NodeParamSetKeyframeTimeCommand::redo()
@@ -151,19 +151,15 @@ void NodeParamSetKeyframeTimeCommand::undo()
key_->set_time(old_time_);
}
NodeParamSetStandardValueCommand::NodeParamSetStandardValueCommand(NodeInput *input, int track, int element, const QVariant &value) :
input_(input),
element_(element),
track_(track),
old_value_(input_->GetStandardValue(element_)),
NodeParamSetStandardValueCommand::NodeParamSetStandardValueCommand(const NodeKeyframeTrackReference& input, const QVariant &value) :
ref_(input),
old_value_(ref_.input().node()->GetStandardValue(ref_.input())),
new_value_(value)
{
}
NodeParamSetStandardValueCommand::NodeParamSetStandardValueCommand(NodeInput *input, int track, int element, const QVariant &new_value, const QVariant &old_value) :
input_(input),
element_(element),
track_(track),
NodeParamSetStandardValueCommand::NodeParamSetStandardValueCommand(const NodeKeyframeTrackReference& input, const QVariant &new_value, const QVariant &old_value) :
ref_(input),
old_value_(old_value),
new_value_(new_value)
{
@@ -171,22 +167,22 @@ NodeParamSetStandardValueCommand::NodeParamSetStandardValueCommand(NodeInput *in
Project *NodeParamSetStandardValueCommand::GetRelevantProject() const
{
return input_->parent()->parent()->project();
return ref_.input().node()->parent()->project();
}
void NodeParamSetStandardValueCommand::redo()
{
input_->SetStandardValueOnTrack(new_value_, track_, element_);
ref_.input().node()->SetSplitStandardValueOnTrack(ref_, new_value_);
}
void NodeParamSetStandardValueCommand::undo()
{
input_->SetStandardValueOnTrack(old_value_, track_, element_);
ref_.input().node()->SetSplitStandardValueOnTrack(ref_, old_value_);
}
Project *NodeParamArrayInsertCommand::GetRelevantProject() const
{
return input_->parent()->parent()->project();
return input_.node()->parent()->project();
}
}
+15 -16
View File
@@ -21,7 +21,9 @@
#ifndef NODEPARAMVIEWUNDO_H
#define NODEPARAMVIEWUNDO_H
#include "node/input.h"
#include "node/keyframe.h"
#include "node/node.h"
#include "node/param.h"
#include "undo/undocommand.h"
namespace olive {
@@ -29,7 +31,7 @@ namespace olive {
class NodeParamSetKeyframingCommand : public UndoCommand
{
public:
NodeParamSetKeyframingCommand(NodeInput* input, int element, bool setting);
NodeParamSetKeyframingCommand(const NodeInput& input, bool setting);
virtual Project* GetRelevantProject() const override;
@@ -37,16 +39,15 @@ public:
virtual void undo() override;
private:
NodeInput* input_;
NodeInput input_;
bool setting_;
int element_;
};
class NodeParamInsertKeyframeCommand : public UndoCommand
{
public:
NodeParamInsertKeyframeCommand(NodeInput* input, NodeKeyframe* keyframe);
NodeParamInsertKeyframeCommand(Node *node, NodeKeyframe* keyframe);
virtual Project* GetRelevantProject() const override;
@@ -54,7 +55,7 @@ public:
virtual void undo() override;
private:
NodeInput* input_;
Node* input_;
NodeKeyframe* keyframe_;
@@ -73,7 +74,7 @@ public:
virtual void undo() override;
private:
NodeInput* input_;
Node* input_;
NodeKeyframe* keyframe_;
@@ -122,8 +123,8 @@ private:
class NodeParamSetStandardValueCommand : public UndoCommand
{
public:
NodeParamSetStandardValueCommand(NodeInput* input, int track, int element, const QVariant& value);
NodeParamSetStandardValueCommand(NodeInput* input, int track, int element, const QVariant& new_value, const QVariant& old_value);
NodeParamSetStandardValueCommand(const NodeKeyframeTrackReference& input, const QVariant& value);
NodeParamSetStandardValueCommand(const NodeKeyframeTrackReference& input, const QVariant& new_value, const QVariant& old_value);
virtual Project* GetRelevantProject() const override;
@@ -131,9 +132,7 @@ public:
virtual void undo() override;
private:
NodeInput* input_;
int element_;
int track_;
NodeKeyframeTrackReference ref_;
QVariant old_value_;
QVariant new_value_;
@@ -143,7 +142,7 @@ private:
class NodeParamArrayInsertCommand : public UndoCommand
{
public:
NodeParamArrayInsertCommand(NodeInput* input, int index) :
NodeParamArrayInsertCommand(const NodeInput& input, int index) :
input_(input),
index_(index)
{
@@ -153,16 +152,16 @@ public:
virtual void redo() override
{
input_->ArrayInsert(index_);
input_.node()->InputArrayInsert(input_.input(), index_);
}
virtual void undo() override
{
input_->ArrayRemove(index_);
input_.node()->InputArrayRemove(input_.input(), index_);
}
private:
NodeInput* input_;
NodeInput input_;
int index_;
};
@@ -40,43 +40,37 @@
namespace olive {
NodeParamViewWidgetBridge::NodeParamViewWidgetBridge(NodeInput *input, int element, QObject *parent) :
NodeParamViewWidgetBridge::NodeParamViewWidgetBridge(const NodeInput &input, QObject *parent) :
QObject(parent),
input_(input),
element_(element)
input_(input)
{
CreateWidgets();
connect(input_, &NodeInput::ValueChanged, this, &NodeParamViewWidgetBridge::InputValueChanged);
connect(input_, &NodeInput::PropertyChanged, this, &NodeParamViewWidgetBridge::PropertyChanged);
connect(input_.node(), &Node::ValueChanged, this, &NodeParamViewWidgetBridge::InputValueChanged);
connect(input_.node(), &Node::InputPropertyChanged, this, &NodeParamViewWidgetBridge::PropertyChanged);
}
void NodeParamViewWidgetBridge::SetTime(const rational &time)
{
time_ = time;
if (input_) {
if (input_.IsValid()) {
UpdateWidgetValues();
}
}
const QList<QWidget *> &NodeParamViewWidgetBridge::widgets() const
{
return widgets_;
}
void NodeParamViewWidgetBridge::CreateWidgets()
{
if (input_->IsArray() && element_ == -1) {
if (input_.IsArray() && input_.element() == -1) {
NodeParamViewArrayWidget* w = new NodeParamViewArrayWidget(input_);
NodeParamViewArrayWidget* w = new NodeParamViewArrayWidget(input_.node(), input_.input());
connect(w, &NodeParamViewArrayWidget::DoubleClicked, this, &NodeParamViewWidgetBridge::ArrayWidgetDoubleClicked);
widgets_.append(w);
} else {
// We assume the first data type is the "primary" type
switch (input_->GetDataType()) {
switch (input_.GetDataType()) {
// None of these inputs have applicable UI widgets
case NodeValue::kNone:
case NodeValue::kTexture:
@@ -89,38 +83,34 @@ void NodeParamViewWidgetBridge::CreateWidgets()
break;
case NodeValue::kInt:
{
IntegerSlider* slider = new IntegerSlider();
slider->SetDefaultValue(input_->GetDefaultValue());
slider->SetLadderElementCount(2);
widgets_.append(slider);
connect(slider, &IntegerSlider::ValueChanged, this, &NodeParamViewWidgetBridge::WidgetCallback);
CreateSliders<IntegerSlider>(1);
break;
}
case NodeValue::kFloat:
{
CreateSliders(1);
CreateSliders<FloatSlider>(1);
break;
}
case NodeValue::kVec2:
{
CreateSliders(2);
CreateSliders<FloatSlider>(2);
break;
}
case NodeValue::kVec3:
{
CreateSliders(3);
CreateSliders<FloatSlider>(3);
break;
}
case NodeValue::kVec4:
{
CreateSliders(4);
CreateSliders<FloatSlider>(4);
break;
}
case NodeValue::kCombo:
{
QComboBox* combobox = new QComboBox();
QStringList items = input_->get_combobox_strings();
QStringList items = input_.GetComboBoxStrings();
foreach (const QString& s, items) {
combobox->addItem(s);
}
@@ -135,7 +125,7 @@ void NodeParamViewWidgetBridge::CreateWidgets()
case NodeValue::kColor:
{
// NOTE: Very convoluted way to get back to the project's color manager
ColorButton* color_button = new ColorButton(input_->parent()->parent()->project()->color_manager());
ColorButton* color_button = new ColorButton(input_.node()->parent()->project()->color_manager());
widgets_.append(color_button);
connect(color_button, &ColorButton::ColorChanged, this, &NodeParamViewWidgetBridge::WidgetCallback);
break;
@@ -164,7 +154,7 @@ void NodeParamViewWidgetBridge::CreateWidgets()
case NodeValue::kFootage:
{
FootageComboBox* footage_combobox = new FootageComboBox();
footage_combobox->SetRoot(input_->parent()->parent()->project()->root());
footage_combobox->SetRoot(input_.node()->parent()->project()->root());
connect(footage_combobox, &FootageComboBox::FootageChanged, this, &NodeParamViewWidgetBridge::WidgetCallback);
@@ -175,8 +165,9 @@ void NodeParamViewWidgetBridge::CreateWidgets()
}
// Check all properties
foreach (const QByteArray& key, input_->dynamicPropertyNames()) {
PropertyChanged(key, input_->property(key));
auto input_properties = input_.node()->GetInputProperties(input_.input());
for (auto it=input_properties.cbegin(); it!=input_properties.cend(); it++) {
PropertyChanged(input_.input(), it.key(), it.value());
}
UpdateWidgetValues();
@@ -202,8 +193,8 @@ void NodeParamViewWidgetBridge::SetInputValueInternal(const QVariant &value, int
{
rational node_time = GetCurrentTimeAsNodeTime();
if (input_->IsKeyframing(element_)) {
NodeKeyframe* existing_key = input_->GetKeyframeAtTimeOnTrack(node_time, track, element_);
if (input_.IsKeyframing()) {
NodeKeyframe* existing_key = input_.GetKeyframeAtTimeOnTrack(node_time, track);
if (existing_key) {
command->add_child(new NodeParamSetKeyframeValueCommand(existing_key, value));
@@ -211,14 +202,15 @@ void NodeParamViewWidgetBridge::SetInputValueInternal(const QVariant &value, int
// No existing key, create a new one
NodeKeyframe* new_key = new NodeKeyframe(node_time,
value,
input_->GetBestKeyframeTypeForTime(node_time, track, element_),
input_.node()->GetBestKeyframeTypeForTimeOnTrack(NodeKeyframeTrackReference(input_, track), node_time),
track,
element_);
input_.element(),
input_.input());
command->add_child(new NodeParamInsertKeyframeCommand(input_, new_key));
command->add_child(new NodeParamInsertKeyframeCommand(input_.node(), new_key));
}
} else {
command->add_child(new NodeParamSetStandardValueCommand(input_, track, element_, value));
command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(input_, track), value));
}
}
@@ -232,7 +224,7 @@ void NodeParamViewWidgetBridge::ProcessSlider(SliderBase *slider, const QVariant
// While we're dragging, we block the input's normal signalling and create our own
if (!dragger_.IsStarted()) {
dragger_.Start(input_, node_time, slider_track, element_);
dragger_.Start(NodeKeyframeTrackReference(input_, slider_track), node_time);
}
dragger_.Drag(value);
@@ -253,7 +245,7 @@ void NodeParamViewWidgetBridge::ProcessSlider(SliderBase *slider, const QVariant
void NodeParamViewWidgetBridge::WidgetCallback()
{
switch (input_->GetDataType()) {
switch (input_.GetDataType()) {
// None of these inputs have applicable UI widgets
case NodeValue::kNone:
case NodeValue::kTexture:
@@ -269,7 +261,7 @@ void NodeParamViewWidgetBridge::WidgetCallback()
// Widget is a IntegerSlider
IntegerSlider* slider = static_cast<IntegerSlider*>(sender());
int64_t offset = input_->property("offset").toLongLong();
int64_t offset = input_.GetProperty("offset").toLongLong();
ProcessSlider(slider, QVariant::fromValue(slider->GetValue() - offset));
break;
@@ -279,7 +271,7 @@ void NodeParamViewWidgetBridge::WidgetCallback()
// Widget is a FloatSlider
FloatSlider* slider = static_cast<FloatSlider*>(sender());
double offset = input_->property("offset").toDouble();
double offset = input_.GetProperty("offset").toDouble();
ProcessSlider(slider, slider->GetValue() - offset);
break;
@@ -289,7 +281,7 @@ void NodeParamViewWidgetBridge::WidgetCallback()
// Widget is a FloatSlider
FloatSlider* slider = static_cast<FloatSlider*>(sender());
QVector2D offset = input_->property("offset").value<QVector2D>();
QVector2D offset = input_.GetProperty("offset").value<QVector2D>();
ProcessSlider(slider, slider->GetValue() - offset[widgets_.indexOf(slider)]);
break;
@@ -299,7 +291,7 @@ void NodeParamViewWidgetBridge::WidgetCallback()
// Widget is a FloatSlider
FloatSlider* slider = static_cast<FloatSlider*>(sender());
QVector3D offset = input_->property("offset").value<QVector3D>();
QVector3D offset = input_.GetProperty("offset").value<QVector3D>();
ProcessSlider(slider, slider->GetValue() - offset[widgets_.indexOf(slider)]);
break;
@@ -309,7 +301,7 @@ void NodeParamViewWidgetBridge::WidgetCallback()
// Widget is a FloatSlider
FloatSlider* slider = static_cast<FloatSlider*>(sender());
QVector4D offset = input_->property("offset").value<QVector4D>();
QVector4D offset = input_.GetProperty("offset").value<QVector4D>();
ProcessSlider(slider, slider->GetValue() - offset[widgets_.indexOf(slider)]);
break;
@@ -329,12 +321,13 @@ void NodeParamViewWidgetBridge::WidgetCallback()
SetInputValueInternal(c.blue(), 2, command);
SetInputValueInternal(c.alpha(), 3, command);
input_->blockSignals(true);
input_->setProperty("col_input", c.color_input());
input_->setProperty("col_display", c.color_output().display());
input_->setProperty("col_view", c.color_output().view());
input_->setProperty("col_look", c.color_output().look());
input_->blockSignals(false);
Node* n = input_.node();
n->blockSignals(true);
n->SetInputProperty(input_.input(), QStringLiteral("col_input"), c.color_input());
n->SetInputProperty(input_.input(), QStringLiteral("col_display"), c.color_output().display());
n->SetInputProperty(input_.input(), QStringLiteral("col_view"), c.color_output().view());
n->SetInputProperty(input_.input(), QStringLiteral("col_look"), c.color_output().look());
n->blockSignals(false);
Core::instance()->undo_stack()->pushIfHasChildren(command);
break;
@@ -382,27 +375,28 @@ void NodeParamViewWidgetBridge::WidgetCallback()
}
}
template <typename T>
void NodeParamViewWidgetBridge::CreateSliders(int count)
{
for (int i=0;i<count;i++) {
FloatSlider* fs = new FloatSlider();
fs->SetDefaultValue(input_->GetDefaultValueForTrack(i));
T* fs = new T();
fs->SetDefaultValue(input_.GetSplitDefaultValueForTrack(i));
fs->SetLadderElementCount(2);
widgets_.append(fs);
connect(fs, &FloatSlider::ValueChanged, this, &NodeParamViewWidgetBridge::WidgetCallback);
connect(fs, &T::ValueChanged, this, &NodeParamViewWidgetBridge::WidgetCallback);
}
}
void NodeParamViewWidgetBridge::UpdateWidgetValues()
{
if (input_->IsArray() && element_ == -1) {
if (input_.IsArray() && input_.element() == -1) {
return;
}
rational node_time = GetCurrentTimeAsNodeTime();
// We assume the first data type is the "primary" type
switch (input_->GetDataType()) {
switch (input_.GetDataType()) {
// None of these inputs have applicable UI widgets
case NodeValue::kNone:
case NodeValue::kTexture:
@@ -415,22 +409,22 @@ void NodeParamViewWidgetBridge::UpdateWidgetValues()
break;
case NodeValue::kInt:
{
int64_t offset = input_->property("offset").toLongLong();
int64_t offset = input_.GetProperty("offset").toLongLong();
static_cast<IntegerSlider*>(widgets_.first())->SetValue(input_->GetValueAtTime(node_time, element_).toLongLong() + offset);
static_cast<IntegerSlider*>(widgets_.first())->SetValue(input_.GetValueAtTime(node_time).toLongLong() + offset);
break;
}
case NodeValue::kFloat:
{
double offset = input_->property("offset").toDouble();
double offset = input_.GetProperty("offset").toDouble();
static_cast<FloatSlider*>(widgets_.first())->SetValue(input_->GetValueAtTime(node_time, element_).toDouble() + offset);
static_cast<FloatSlider*>(widgets_.first())->SetValue(input_.GetValueAtTime(node_time).toDouble() + offset);
break;
}
case NodeValue::kVec2:
{
QVector2D vec2 = input_->GetValueAtTime(node_time, element_).value<QVector2D>();
QVector2D offset = input_->property("offset").value<QVector2D>();
QVector2D vec2 = input_.GetValueAtTime(node_time).value<QVector2D>();
QVector2D offset = input_.GetProperty("offset").value<QVector2D>();
static_cast<FloatSlider*>(widgets_.at(0))->SetValue(static_cast<double>(vec2.x() + offset.x()));
static_cast<FloatSlider*>(widgets_.at(1))->SetValue(static_cast<double>(vec2.y() + offset.y()));
@@ -438,8 +432,8 @@ void NodeParamViewWidgetBridge::UpdateWidgetValues()
}
case NodeValue::kVec3:
{
QVector3D vec3 = input_->GetValueAtTime(node_time, element_).value<QVector3D>();
QVector3D offset = input_->property("offset").value<QVector3D>();
QVector3D vec3 = input_.GetValueAtTime(node_time).value<QVector3D>();
QVector3D offset = input_.GetProperty("offset").value<QVector3D>();
static_cast<FloatSlider*>(widgets_.at(0))->SetValue(static_cast<double>(vec3.x() + offset.x()));
static_cast<FloatSlider*>(widgets_.at(1))->SetValue(static_cast<double>(vec3.y() + offset.y()));
@@ -448,8 +442,8 @@ void NodeParamViewWidgetBridge::UpdateWidgetValues()
}
case NodeValue::kVec4:
{
QVector4D vec4 = input_->GetValueAtTime(node_time, element_).value<QVector4D>();
QVector4D offset = input_->property("offset").value<QVector4D>();
QVector4D vec4 = input_.GetValueAtTime(node_time).value<QVector4D>();
QVector4D offset = input_.GetProperty("offset").value<QVector4D>();
static_cast<FloatSlider*>(widgets_.at(0))->SetValue(static_cast<double>(vec4.x() + offset.x()));
static_cast<FloatSlider*>(widgets_.at(1))->SetValue(static_cast<double>(vec4.y() + offset.y()));
@@ -462,13 +456,13 @@ void NodeParamViewWidgetBridge::UpdateWidgetValues()
break;
case NodeValue::kColor:
{
ManagedColor mc = input_->GetValueAtTime(node_time, element_).value<Color>();
ManagedColor mc = input_.GetValueAtTime(node_time).value<Color>();
mc.set_color_input(input_->property("col_input").toString());
mc.set_color_input(input_.GetProperty("col_input").toString());
QString d = input_->property("col_display").toString();
QString v = input_->property("col_view").toString();
QString l = input_->property("col_look").toString();
QString d = input_.GetProperty("col_display").toString();
QString v = input_.GetProperty("col_view").toString();
QString l = input_.GetProperty("col_look").toString();
mc.set_color_output(ColorTransform(d, v, l));
@@ -478,17 +472,17 @@ void NodeParamViewWidgetBridge::UpdateWidgetValues()
case NodeValue::kText:
{
NodeParamViewRichText* e = static_cast<NodeParamViewRichText*>(widgets_.first());
e->setTextPreservingCursor(input_->GetValueAtTime(node_time, element_).toString());
e->setTextPreservingCursor(input_.GetValueAtTime(node_time).toString());
break;
}
case NodeValue::kBoolean:
static_cast<QCheckBox*>(widgets_.first())->setChecked(input_->GetValueAtTime(node_time, element_).toBool());
static_cast<QCheckBox*>(widgets_.first())->setChecked(input_.GetValueAtTime(node_time).toBool());
break;
case NodeValue::kFont:
{
QFontComboBox* fc = static_cast<QFontComboBox*>(widgets_.first());
fc->blockSignals(true);
fc->setCurrentFont(input_->GetValueAtTime(node_time, element_).toString());
fc->setCurrentFont(input_.GetValueAtTime(node_time).toString());
fc->blockSignals(false);
break;
}
@@ -496,24 +490,24 @@ void NodeParamViewWidgetBridge::UpdateWidgetValues()
{
QComboBox* cb = static_cast<QComboBox*>(widgets_.first());
cb->blockSignals(true);
cb->setCurrentIndex(input_->GetValueAtTime(node_time, element_).toInt());
cb->setCurrentIndex(input_.GetValueAtTime(node_time).toInt());
cb->blockSignals(false);
break;
}
case NodeValue::kFootage:
static_cast<FootageComboBox*>(widgets_.first())->SetFootage(Node::ValueToPtr<Stream>(input_->GetValueAtTime(node_time, element_)));
static_cast<FootageComboBox*>(widgets_.first())->SetFootage(Node::ValueToPtr<Stream>(input_.GetValueAtTime(node_time)));
break;
}
}
rational NodeParamViewWidgetBridge::GetCurrentTimeAsNodeTime() const
{
return GetAdjustedTime(GetTimeTarget(), input_->parent(), time_, true);
return GetAdjustedTime(GetTimeTarget(), input_.node(), time_, true);
}
void NodeParamViewWidgetBridge::InputValueChanged(const TimeRange &range, int element)
void NodeParamViewWidgetBridge::InputValueChanged(const NodeInput &input, const TimeRange &range)
{
if (element == element_
if (input_ == input
&& !dragger_.IsStarted()
&& range.in() <= time_ && range.out() >= time_) {
// We'll need to update the widgets because the values have changed on our current time
@@ -521,10 +515,16 @@ void NodeParamViewWidgetBridge::InputValueChanged(const TimeRange &range, int el
}
}
void NodeParamViewWidgetBridge::PropertyChanged(const QString &key, const QVariant &value)
void NodeParamViewWidgetBridge::PropertyChanged(const QString& input, const QString &key, const QVariant &value)
{
if (input != input_.input()) {
return;
}
NodeValue::Type data_type = input_.GetDataType();
// Parameters for vectors only
if (NodeValue::type_is_vector(input_->GetDataType())) {
if (NodeValue::type_is_vector(data_type)) {
if (key == QStringLiteral("disablex")) {
static_cast<FloatSlider*>(widgets_.at(0))->setEnabled(!value.toBool());
} else if (key == QStringLiteral("disabley")) {
@@ -537,9 +537,9 @@ void NodeParamViewWidgetBridge::PropertyChanged(const QString &key, const QVaria
}
// Parameters for integers, floats, and vectors
if (NodeValue::type_is_numeric(input_->GetDataType()) || NodeValue::type_is_vector(input_->GetDataType())) {
if (NodeValue::type_is_numeric(data_type) || NodeValue::type_is_vector(data_type)) {
if (key == QStringLiteral("min")) {
switch (input_->GetDataType()) {
switch (data_type) {
case NodeValue::kInt:
static_cast<IntegerSlider*>(widgets_.first())->SetMinimum(value.value<int64_t>());
break;
@@ -577,7 +577,7 @@ void NodeParamViewWidgetBridge::PropertyChanged(const QString &key, const QVaria
break;
}
} else if (key == QStringLiteral("max")) {
switch (input_->GetDataType()) {
switch (data_type) {
case NodeValue::kInt:
static_cast<IntegerSlider*>(widgets_.first())->SetMaximum(value.value<int64_t>());
break;
@@ -620,7 +620,7 @@ void NodeParamViewWidgetBridge::PropertyChanged(const QString &key, const QVaria
}
// ComboBox strings changing
if (input_->GetDataType() & NodeValue::kCombo) {
if (data_type & NodeValue::kCombo) {
QComboBox* cb = static_cast<QComboBox*>(widgets_.first());
int old_index = cb->currentIndex();
@@ -630,7 +630,7 @@ void NodeParamViewWidgetBridge::PropertyChanged(const QString &key, const QVaria
cb->clear();
QStringList items = input_->get_combobox_strings();
QStringList items = input_.GetComboBoxStrings();
foreach (const QString& s, items) {
if (s.isEmpty()) {
cb->insertSeparator(cb->count());
@@ -651,7 +651,7 @@ void NodeParamViewWidgetBridge::PropertyChanged(const QString &key, const QVaria
}
// Parameters for floats and vectors only
if (input_->GetDataType() == NodeValue::kFloat || NodeValue::type_is_vector(input_->GetDataType())) {
if (data_type == NodeValue::kFloat || NodeValue::type_is_vector(data_type)) {
if (key == QStringLiteral("view")) {
FloatSlider::DisplayType display_type = static_cast<FloatSlider::DisplayType>(value.toInt());
@@ -23,7 +23,6 @@
#include <QObject>
#include "node/input.h"
#include "node/inputdragger.h"
#include "widget/slider/sliderbase.h"
#include "widget/timetarget/timetarget.h"
@@ -41,11 +40,14 @@ class NodeParamViewWidgetBridge : public QObject, public TimeTargetObject
{
Q_OBJECT
public:
NodeParamViewWidgetBridge(NodeInput* input, int element, QObject* parent);
NodeParamViewWidgetBridge(const NodeInput& input, QObject* parent);
void SetTime(const rational& time);
const QList<QWidget*>& widgets() const;
const QVector<QWidget*>& widgets() const
{
return widgets_;
}
signals:
void ArrayWidgetDoubleClicked();
@@ -59,17 +61,16 @@ private:
void ProcessSlider(SliderBase* slider, const QVariant& value);
template <typename T>
void CreateSliders(int count);
void UpdateWidgetValues();
rational GetCurrentTimeAsNodeTime() const;
NodeInput* input_;
NodeInput input_;
int element_;
QList<QWidget*> widgets_;
QVector<QWidget*> widgets_;
rational time_;
@@ -80,9 +81,9 @@ private:
private slots:
void WidgetCallback();
void InputValueChanged(const TimeRange& range, int element);
void InputValueChanged(const NodeInput& input, const TimeRange& range);
void PropertyChanged(const QString& key, const QVariant& value);
void PropertyChanged(const QString &input, const QString& key, const QVariant& value);
};
+5 -6
View File
@@ -87,8 +87,7 @@ void NodeTableView::SetTime(const rational &time)
for (l=db.begin(); l!=db.end(); l++) {
const NodeValueTable& table = l.value();
NodeInput* input = node->GetInputWithID(l.key());
if (!input) {
if (!node->HasInputWithID(l.key())) {
// Filters out table entries that aren't inputs (like "global")
continue;
}
@@ -98,7 +97,7 @@ void NodeTableView::SetTime(const rational &time)
for (int j=0; j<item->childCount(); j++) {
QTreeWidgetItem* compare = item->child(j);
if (compare->data(0, Qt::UserRole).toString() == input->id()) {
if (compare->data(0, Qt::UserRole).toString() == l.key()) {
input_item = compare;
break;
}
@@ -106,8 +105,8 @@ void NodeTableView::SetTime(const rational &time)
if (!input_item) {
input_item = new QTreeWidgetItem();
input_item->setText(0, input->name());
input_item->setData(0, Qt::UserRole, input->id());
input_item->setText(0, node->GetInputName(l.key()));
input_item->setData(0, Qt::UserRole, l.key());
input_item->setFirstColumnSpanned(true);
item->addChild(input_item);
}
@@ -151,7 +150,7 @@ void NodeTableView::SetTime(const rational &time)
}
default:
{
QVector<QVariant> split_values = NodeValue::split_normal_value_into_track_values(input->GetDataType(), value.data());
QVector<QVariant> split_values = NodeValue::split_normal_value_into_track_values(node->GetInputDataType(l.key()), value.data());
for (int k=0;k<split_values.size();k++) {
sub_item->setText(2 + k, NodeValue::ValueToString(value.type(), split_values.at(k), true));
}
+1 -1
View File
@@ -42,7 +42,7 @@ public:
}
protected:
virtual void TimeChangedEvent(const int64_t& ts) override
virtual void TimeChangedEvent(const int64_t&) override
{
UpdateView();
}
+37 -47
View File
@@ -18,12 +18,12 @@ bool NodeTreeView::IsNodeEnabled(Node *n) const
return !disabled_nodes_.contains(n);
}
bool NodeTreeView::IsInputEnabled(NodeInput *i, int element, int track) const
bool NodeTreeView::IsInputEnabled(const NodeKeyframeTrackReference &ref) const
{
return !disabled_inputs_.contains({i, element, track});
return !disabled_inputs_.contains(ref);
}
void NodeTreeView::SetKeyframeTrackColor(const NodeInput::KeyframeTrackReference &ref, const QColor &color)
void NodeTreeView::SetKeyframeTrackColor(const NodeKeyframeTrackReference &ref, const QColor &color)
{
// Insert into hashmap
keyframe_colors_.insert(ref, color);
@@ -47,21 +47,24 @@ void NodeTreeView::SetNodes(const QVector<Node *> &nodes)
node_item->setText(0, n->Name());
node_item->setCheckState(0, disabled_nodes_.contains(n) ? Qt::Unchecked : Qt::Checked);
node_item->setData(0, kItemType, kItemTypeNode);
node_item->setData(0, kItemPointer, reinterpret_cast<quintptr>(n));
node_item->setData(0, kItemNodePointer, Node::PtrToValue(n));
foreach (NodeInput* input, n->inputs()) {
if (only_show_keyframable_ && !input->IsKeyframable()) {
foreach (const QString& input, n->inputs()) {
if (only_show_keyframable_ && !n->IsInputKeyframable(input)) {
continue;
}
QTreeWidgetItem* input_item = nullptr;
for (int i=-1; i<input->ArraySize(); i++) {
const QVector<NodeKeyframeTrack>& key_tracks = input->GetKeyframeTracks(i);
int arr_sz = n->InputArraySize(input);
for (int i=-1; i<arr_sz; i++) {
NodeInput input_ref(n, input, i);
const QVector<NodeKeyframeTrack>& key_tracks = n->GetKeyframeTracks(input_ref);
int this_element_track;
if (show_keyframe_tracks_as_rows_ && (key_tracks.size() == 1 || (i == -1 && input->IsArray()))) {
if (show_keyframe_tracks_as_rows_
&& (key_tracks.size() == 1 || (i == -1 && n->InputIsArray(input)))) {
this_element_track = 0;
} else {
this_element_track = -1;
@@ -70,14 +73,14 @@ void NodeTreeView::SetNodes(const QVector<Node *> &nodes)
QTreeWidgetItem* element_item;
if (input_item) {
element_item = CreateItem(input_item, input, i, this_element_track);
element_item = CreateItem(input_item, NodeKeyframeTrackReference(input_ref, this_element_track));
} else {
input_item = CreateItem(node_item, input, i, this_element_track);
input_item = CreateItem(node_item, NodeKeyframeTrackReference(input_ref, this_element_track));
element_item = input_item;
}
if (show_keyframe_tracks_as_rows_ && key_tracks.size() > 1 && (!input->IsArray() || i >= 0)) {
CreateItemsForTracks(element_item, input, i, key_tracks.size());
if (show_keyframe_tracks_as_rows_ && key_tracks.size() > 1 && (!n->InputIsArray(input) || i >= 0)) {
CreateItemsForTracks(element_item, input_ref, key_tracks.size());
}
}
@@ -105,10 +108,10 @@ void NodeTreeView::mouseDoubleClickEvent(QMouseEvent *e)
{
QTreeWidget::mouseDoubleClickEvent(e);
NodeInput::KeyframeTrackReference ref = GetSelectedInput();
NodeKeyframeTrackReference ref = GetSelectedInput();
if (ref.input) {
emit InputDoubleClicked(ref.input, ref.element, ref.track);
if (ref.input().IsValid()) {
emit InputDoubleClicked(ref);
}
}
@@ -117,36 +120,32 @@ void NodeTreeView::Retranslate()
setHeaderLabel(tr("Nodes"));
}
NodeInput::KeyframeTrackReference NodeTreeView::GetSelectedInput()
NodeKeyframeTrackReference NodeTreeView::GetSelectedInput()
{
QList<QTreeWidgetItem*> sel = selectedItems();
NodeInput* selected_input = nullptr;
int selected_element = -1;
int selected_track = -1;
NodeKeyframeTrackReference selected_ref;
if (!sel.isEmpty()) {
QTreeWidgetItem* item = sel.first();
if (item->data(0, kItemType).toInt() == kItemTypeInput) {
selected_input = reinterpret_cast<NodeInput*>(item->data(0, kItemPointer).value<quintptr>());
selected_element = item->data(0, kItemElement).toInt();
selected_track = item->data(0, kItemTrack).toInt();
selected_ref = item->data(0, kItemInputReference).value<NodeKeyframeTrackReference>();
}
}
return {selected_input, selected_element, selected_track};
return selected_ref;
}
QTreeWidgetItem* NodeTreeView::CreateItem(QTreeWidgetItem *parent, NodeInput *input, int element, int track)
QTreeWidgetItem* NodeTreeView::CreateItem(QTreeWidgetItem *parent, const NodeKeyframeTrackReference& ref)
{
QTreeWidgetItem* input_item = new QTreeWidgetItem(parent);
QString item_name;
if (track == -1 || NodeValue::get_number_of_keyframe_tracks(input->GetDataType()) == 1) {
item_name = input->name();
if (ref.track() == -1 || NodeValue::get_number_of_keyframe_tracks(ref.input().GetDataType()) == 1) {
item_name = ref.input().name();
} else {
switch (track) {
switch (ref.track()) {
case 0:
item_name = tr("X");
break;
@@ -160,18 +159,14 @@ QTreeWidgetItem* NodeTreeView::CreateItem(QTreeWidgetItem *parent, NodeInput *in
item_name = tr("W");
break;
default:
item_name = QString::number(track);
item_name = QString::number(ref.track());
}
}
input_item->setText(0, item_name);
input_item->setCheckState(0, disabled_inputs_.contains({input, element, track}) ? Qt::Unchecked : Qt::Checked);
input_item->setCheckState(0, disabled_inputs_.contains(ref) ? Qt::Unchecked : Qt::Checked);
input_item->setData(0, kItemType, kItemTypeInput);
input_item->setData(0, kItemPointer, reinterpret_cast<quintptr>(input));
input_item->setData(0, kItemElement, element);
input_item->setData(0, kItemTrack, track);
NodeInput::KeyframeTrackReference ref = {input, element, track};
input_item->setData(0, kItemInputReference, QVariant::fromValue(ref));
if (keyframe_colors_.contains(ref)) {
input_item->setForeground(0, keyframe_colors_.value(ref));
@@ -182,10 +177,10 @@ QTreeWidgetItem* NodeTreeView::CreateItem(QTreeWidgetItem *parent, NodeInput *in
return input_item;
}
void NodeTreeView::CreateItemsForTracks(QTreeWidgetItem *parent, NodeInput *input, int element, int track_count)
void NodeTreeView::CreateItemsForTracks(QTreeWidgetItem *parent, const NodeInput& input, int track_count)
{
for (int j=0; j<track_count; j++) {
CreateItem(parent, input, element, j);
CreateItem(parent, NodeKeyframeTrackReference(input, j));
}
}
@@ -196,7 +191,7 @@ void NodeTreeView::ItemCheckStateChanged(QTreeWidgetItem *item, int column)
switch (item->data(0, kItemType).toInt()) {
case kItemTypeNode:
{
Node* n = reinterpret_cast<Node*>(item->data(0, kItemPointer).value<quintptr>());
Node* n = Node::ValueToPtr<Node>(item->data(0, kItemNodePointer));
if (item->checkState(0) == Qt::Checked) {
if (disabled_nodes_.contains(n)) {
@@ -211,19 +206,16 @@ void NodeTreeView::ItemCheckStateChanged(QTreeWidgetItem *item, int column)
}
case kItemTypeInput:
{
NodeInput* input = reinterpret_cast<NodeInput*>(item->data(0, kItemPointer).value<quintptr>());
int element = item->data(0, kItemElement).toInt();
int track = item->data(0, kItemTrack).toInt();
NodeInput::KeyframeTrackReference i = {input, element, track};
NodeKeyframeTrackReference i = item->data(0, kItemInputReference).value<NodeKeyframeTrackReference>();
if (item->checkState(0) == Qt::Checked) {
if (disabled_inputs_.contains(i)) {
disabled_inputs_.removeOne(i);
emit InputEnableChanged(input, element, track, true);
emit InputEnableChanged(i, true);
}
} else if (!disabled_inputs_.contains(i)) {
disabled_inputs_.append(i);
emit InputEnableChanged(input, element, track, false);
emit InputEnableChanged(i, false);
}
break;
}
@@ -232,9 +224,7 @@ void NodeTreeView::ItemCheckStateChanged(QTreeWidgetItem *item, int column)
void NodeTreeView::SelectionChanged()
{
NodeInput::KeyframeTrackReference ref = GetSelectedInput();
emit InputSelectionChanged(ref.input, ref.element, ref.track);
emit InputSelectionChanged(GetSelectedInput());
}
}
+13 -14
View File
@@ -15,9 +15,9 @@ public:
bool IsNodeEnabled(Node* n) const;
bool IsInputEnabled(NodeInput* i, int element, int track) const;
bool IsInputEnabled(const NodeKeyframeTrackReference& ref) const;
void SetKeyframeTrackColor(const NodeInput::KeyframeTrackReference& ref, const QColor& color);
void SetKeyframeTrackColor(const NodeKeyframeTrackReference& ref, const QColor& color);
void SetOnlyShowKeyframable(bool e)
{
@@ -35,11 +35,11 @@ public slots:
signals:
void NodeEnableChanged(Node* n, bool e);
void InputEnableChanged(NodeInput* i, int element, int track, bool e);
void InputEnableChanged(const NodeKeyframeTrackReference& ref, bool e);
void InputSelectionChanged(NodeInput* input, int element, int track);
void InputSelectionChanged(const NodeKeyframeTrackReference& ref);
void InputDoubleClicked(NodeInput* input, int element, int track);
void InputDoubleClicked(const NodeKeyframeTrackReference& ref);
protected:
virtual void changeEvent(QEvent* e) override;
@@ -49,11 +49,11 @@ protected:
private:
void Retranslate();
NodeInput::KeyframeTrackReference GetSelectedInput();
NodeKeyframeTrackReference GetSelectedInput();
QTreeWidgetItem *CreateItem(QTreeWidgetItem* parent, NodeInput* input, int element, int track);
QTreeWidgetItem *CreateItem(QTreeWidgetItem* parent, const NodeKeyframeTrackReference& ref);
void CreateItemsForTracks(QTreeWidgetItem* parent, NodeInput* input, int element, int track_count);
void CreateItemsForTracks(QTreeWidgetItem* parent, const NodeInput& input, int track_count);
enum ItemType {
kItemTypeNode,
@@ -61,23 +61,22 @@ private:
};
static const int kItemType = Qt::UserRole;
static const int kItemPointer = Qt::UserRole + 1;
static const int kItemElement = Qt::UserRole + 2;
static const int kItemTrack = Qt::UserRole + 3;
static const int kItemInputReference = Qt::UserRole + 1;
static const int kItemNodePointer = Qt::UserRole + 1;
QVector<Node*> nodes_;
QVector<Node*> disabled_nodes_;
QVector<NodeInput::KeyframeTrackReference> disabled_inputs_;
QVector<NodeKeyframeTrackReference> disabled_inputs_;
QHash<NodeInput::KeyframeTrackReference, QTreeWidgetItem*> item_map_;
QHash<NodeKeyframeTrackReference, QTreeWidgetItem*> item_map_;
bool only_show_keyframable_;
bool show_keyframe_tracks_as_rows_;
QHash<NodeInput::KeyframeTrackReference, QColor> keyframe_colors_;
QHash<NodeKeyframeTrackReference, QColor> keyframe_colors_;
private slots:
void ItemCheckStateChanged(QTreeWidgetItem* item, int column);
+24 -25
View File
@@ -40,7 +40,6 @@ NodeView::NodeView(QWidget *parent) :
drop_edge_(nullptr),
create_edge_(nullptr),
create_edge_dst_(nullptr),
create_edge_dst_input_(nullptr),
create_edge_dst_temp_expanded_(false),
filter_mode_(kFilterShowSelectedBlocks),
scale_(1.0)
@@ -103,10 +102,8 @@ void NodeView::SetGraph(NodeGraph *graph)
}
foreach (Node* n, graph_->nodes()) {
foreach (NodeInput* input, n->parameters()) {
for (auto it=input->edges().cbegin(); it!=input->edges().cend(); it++) {
scene_.AddEdge(it->second, input, it->first);
}
for (auto it=n->input_connections().cbegin(); it!=n->input_connections().cend(); it++) {
scene_.AddEdge(it->second, it->first);
}
}
}
@@ -124,7 +121,7 @@ void NodeView::DeleteSelected()
QVector<NodeViewEdge *> selected_edges = scene_.GetSelectedEdges();
foreach (NodeViewEdge* edge, selected_edges) {
command->add_child(new NodeEdgeRemoveCommand(edge->output(), edge->input(), edge->element()));
command->add_child(new NodeEdgeRemoveCommand(edge->output(), edge->input()));
}
}
@@ -426,18 +423,18 @@ void NodeView::mouseMoveEvent(QMouseEvent *event)
if (highlight_index >= 0) {
create_edge_dst_input_ = create_edge_dst_->GetInputAtIndex(highlight_index);
create_edge_->SetPoints(create_edge_src_->GetOutputPoint(),
create_edge_dst_->GetInputPoint(highlight_index, create_edge_src_->pos()),
create_edge_->SetPoints(create_edge_src_->GetOutputPoint(Node::kDefaultOutput),
create_edge_dst_->GetInputPoint(create_edge_dst_input_.input(), create_edge_dst_input_.element(), create_edge_src_->pos()),
true);
} else {
create_edge_dst_input_ = nullptr;
create_edge_->SetPoints(create_edge_src_->GetOutputPoint(),
create_edge_dst_input_.Reset();
create_edge_->SetPoints(create_edge_src_->GetOutputPoint(Node::kDefaultOutput),
scene_pt,
false);
}
// Set connected to whether we have a valid input destination
create_edge_->SetConnected(create_edge_dst_input_);
create_edge_->SetConnected(create_edge_dst_input_.IsValid());
return;
}
@@ -466,20 +463,22 @@ void NodeView::mouseMoveEvent(QMouseEvent *event)
new_drop_edge = dynamic_cast<NodeViewEdge*>(item);
if (new_drop_edge) {
drop_input_ = nullptr;
drop_input_.Reset();
foreach (NodeInput* input, attached_node->parameters()) {
if (input->IsConnectable()) {
if (input->GetDataType() == new_drop_edge->input()->GetDataType()) {
drop_input_ = input;
foreach (const QString& input, attached_node->inputs()) {
NodeInput i(attached_node, input);
if (attached_node->IsInputConnectable(input)) {
if (attached_node->GetInputDataType(input) == new_drop_edge->input().GetDataType()) {
drop_input_ = i;
break;
} else if (!drop_input_) {
drop_input_ = input;
} else if (!drop_input_.IsValid()) {
drop_input_ = i;
}
}
}
if (drop_input_) {
if (drop_input_.IsValid()) {
break;
} else {
new_drop_edge = nullptr;
@@ -519,10 +518,10 @@ void NodeView::mouseReleaseEvent(QMouseEvent *event)
create_edge_dst_->SetExpanded(false);
}
if (create_edge_dst_input_) {
if (create_edge_dst_input_.IsValid()) {
// Make connection
Core::instance()->undo_stack()->push(new NodeEdgeAddCommand(create_edge_src_->GetNode(), create_edge_dst_input_, -1));
create_edge_dst_input_ = nullptr;
Core::instance()->undo_stack()->push(new NodeEdgeAddCommand(create_edge_src_->GetNode(), create_edge_dst_input_));
create_edge_dst_input_.Reset();
}
create_edge_dst_ = nullptr;
@@ -539,11 +538,11 @@ void NodeView::mouseReleaseEvent(QMouseEvent *event)
MultiUndoCommand* command = new MultiUndoCommand();
// Remove old edge
command->add_child(new NodeEdgeRemoveCommand(drop_edge_->output(), drop_edge_->input(), drop_edge_->element()));
command->add_child(new NodeEdgeRemoveCommand(drop_edge_->output(), drop_edge_->input()));
// Place new edges
command->add_child(new NodeEdgeAddCommand(drop_edge_->output(), drop_input_, -1));
command->add_child(new NodeEdgeAddCommand(dropping_node, drop_edge_->input(), drop_edge_->element()));
command->add_child(new NodeEdgeAddCommand(drop_edge_->output(), drop_input_));
command->add_child(new NodeEdgeAddCommand(dropping_node, drop_edge_->input()));
Core::instance()->undo_stack()->push(command);
}
+2 -2
View File
@@ -107,12 +107,12 @@ private:
QList<AttachedItem> attached_items_;
NodeViewEdge* drop_edge_;
NodeInput* drop_input_;
NodeInput drop_input_;
NodeViewEdge* create_edge_;
NodeViewItem* create_edge_src_;
NodeViewItem* create_edge_dst_;
NodeInput* create_edge_dst_input_;
NodeInput create_edge_dst_input_;
bool create_edge_dst_temp_expanded_;
NodeViewScene scene_;
+3 -4
View File
@@ -33,13 +33,12 @@
namespace olive {
NodeViewEdge::NodeViewEdge(Node* output, NodeInput *input, int element,
NodeViewEdge::NodeViewEdge(const NodeOutput &output, const NodeInput &input,
NodeViewItem* from_item, NodeViewItem* to_item,
QGraphicsItem* parent) :
QGraphicsPathItem(parent),
output_(output),
input_(input),
element_(element),
from_item_(from_item),
to_item_(to_item)
{
@@ -56,8 +55,8 @@ NodeViewEdge::NodeViewEdge(QGraphicsItem *parent) :
void NodeViewEdge::Adjust()
{
// Draw a line between the two
SetPoints(from_item()->GetOutputPoint(),
to_item()->GetInputPoint(input_, from_item()->pos()),
SetPoints(from_item()->GetOutputPoint(output_.output()),
to_item()->GetInputPoint(input_.input(), input_.element(), from_item()->pos()),
to_item()->IsExpanded());
}
+5 -5
View File
@@ -39,18 +39,18 @@ class NodeViewItem;
class NodeViewEdge : public QGraphicsPathItem
{
public:
NodeViewEdge(Node* output, NodeInput *input, int element,
NodeViewEdge(const NodeOutput& output, const NodeInput& input,
NodeViewItem* from_item, NodeViewItem* to_item,
QGraphicsItem* parent = nullptr);
NodeViewEdge(QGraphicsItem* parent = nullptr);
Node* output() const
const NodeOutput& output() const
{
return output_;
}
NodeInput* input() const
const NodeInput& input() const
{
return input_;
}
@@ -112,9 +112,9 @@ protected:
private:
void Init();
Node* output_;
NodeOutput output_;
NodeInput* input_;
NodeInput input_;
int element_;
+6 -11
View File
@@ -187,8 +187,8 @@ void NodeViewItem::SetNode(Node *n)
if (node_) {
node_->Retranslate();
foreach (NodeInput* input, node_->parameters()) {
if (input->IsConnectable()) {
foreach (const QString& input, node_->inputs()) {
if (node_->IsInputConnectable(input)) {
node_inputs_.append(input);
}
}
@@ -258,7 +258,7 @@ void NodeViewItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
painter->fillRect(input_rect, highlight_col);
}
painter->drawText(input_rect, Qt::AlignCenter, node_inputs_.at(i)->name());
painter->drawText(input_rect, Qt::AlignCenter, node_->GetInputName(node_inputs_.at(i)));
}
}
@@ -430,17 +430,12 @@ QRectF NodeViewItem::GetInputRect(int index) const
return r;
}
QPointF NodeViewItem::GetInputPoint(NodeInput *input, const QPointF& source_pos) const
QPointF NodeViewItem::GetInputPoint(const QString &input, int element, const QPointF& source_pos) const
{
return GetInputPoint(node_inputs_.indexOf(input), source_pos);
return pos() + GetInputPointInternal(node_inputs_.indexOf(input), source_pos);
}
QPointF NodeViewItem::GetInputPoint(int input, const QPointF &source_pos) const
{
return pos() + GetInputPointInternal(input, source_pos);
}
QPointF NodeViewItem::GetOutputPoint() const
QPointF NodeViewItem::GetOutputPoint(const QString& output) const
{
switch (flow_dir_) {
case NodeViewCommon::kLeftToRight:
+5 -6
View File
@@ -78,10 +78,9 @@ public:
/**
* @brief Returns GLOBAL point that edges should connect to for any NodeParam member of this object
*/
QPointF GetInputPoint(NodeInput* input, const QPointF &source_pos) const;
QPointF GetInputPoint(int input, const QPointF &source_pos) const;
QPointF GetInputPoint(const QString& input, int element, const QPointF &source_pos) const;
QPointF GetOutputPoint() const;
QPointF GetOutputPoint(const QString &output) const;
/**
* @brief Sets the direction nodes are flowing
@@ -105,9 +104,9 @@ public:
int GetIndexAt(QPointF pt) const;
NodeInput* GetInputAtIndex(int index) const
NodeInput GetInputAtIndex(int index) const
{
return node_inputs_.at(index);
return NodeInput(node_, node_inputs_.at(index));
}
void SetHighlightedIndex(int index);
@@ -143,7 +142,7 @@ private:
/**
* @brief Cached list of node inputs
*/
QList<NodeInput*> node_inputs_;
QVector<QString> node_inputs_;
/**
* @brief Rectangle of the Node's title bar (equal to rect() when collapsed)
+8 -8
View File
@@ -98,10 +98,10 @@ NodeViewItem *NodeViewScene::NodeToUIObject(Node *n)
return item_map_.value(n);
}
NodeViewEdge *NodeViewScene::EdgeToUIObject(Node* output, NodeInput* input, int element)
NodeViewEdge *NodeViewScene::EdgeToUIObject(const NodeOutput& output, const NodeInput& input)
{
foreach (NodeViewEdge* edge, edges_) {
if (edge->output() == output && edge->input() == input && edge->element() == element) {
if (edge->output() == output && edge->input() == input) {
return edge;
}
}
@@ -174,14 +174,14 @@ void NodeViewScene::RemoveNode(Node *node)
delete item_map_.take(node);
}
void NodeViewScene::AddEdge(Node* output, NodeInput* input, int element)
void NodeViewScene::AddEdge(const NodeOutput &output, const NodeInput &input)
{
AddEdgeInternal(output, input, element, NodeToUIObject(output), NodeToUIObject(input->parent()));
AddEdgeInternal(output, input, NodeToUIObject(output.node()), NodeToUIObject(input.node()));
}
void NodeViewScene::RemoveEdge(Node* output, NodeInput* input, int element)
void NodeViewScene::RemoveEdge(const NodeOutput &output, const NodeInput &input)
{
NodeViewEdge* edge = EdgeToUIObject(output, input, element);
NodeViewEdge* edge = EdgeToUIObject(output, input);
edge->from_item()->RemoveEdge(edge);
edge->to_item()->RemoveEdge(edge);
edges_.removeOne(edge);
@@ -203,9 +203,9 @@ int NodeViewScene::DetermineWeight(Node *n)
return qMax(1, weight);
}
void NodeViewScene::AddEdgeInternal(Node *output, NodeInput *input, int element, NodeViewItem *from, NodeViewItem *to)
void NodeViewScene::AddEdgeInternal(const NodeOutput& output, const NodeInput& input, NodeViewItem *from, NodeViewItem *to)
{
NodeViewEdge* edge_ui = new NodeViewEdge(output, input, element, from, to);
NodeViewEdge* edge_ui = new NodeViewEdge(output, input, from, to);
edge_ui->SetFlowDirection(direction_);
edge_ui->SetCurved(curved_edges_);
+4 -4
View File
@@ -53,7 +53,7 @@ public:
* in this view/scene), this function returns nullptr.
*/
NodeViewItem* NodeToUIObject(Node* n);
NodeViewEdge *EdgeToUIObject(Node* output, NodeInput *input, int element);
NodeViewEdge *EdgeToUIObject(const NodeOutput &output, const NodeInput &input);
QVector<Node *> GetSelectedNodes() const;
QVector<NodeViewItem*> GetSelectedItems() const;
@@ -98,8 +98,8 @@ public slots:
*/
void RemoveNode(Node* node);
void AddEdge(Node* output, NodeInput* input, int element);
void RemoveEdge(Node* output, NodeInput* input, int element);
void AddEdge(const NodeOutput& output, const NodeInput& input);
void RemoveEdge(const NodeOutput& output, const NodeInput& input);
/**
* @brief Set whether edges in this scene should be curved or not
@@ -109,7 +109,7 @@ public slots:
private:
static int DetermineWeight(Node* n);
void AddEdgeInternal(Node* output, NodeInput* input, int element, NodeViewItem* from, NodeViewItem* to);
void AddEdgeInternal(const NodeOutput &output, const NodeInput &input, NodeViewItem* from, NodeViewItem* to);
QHash<Node*, NodeViewItem*> item_map_;
+15 -21
View File
@@ -25,10 +25,9 @@
namespace olive {
NodeEdgeAddCommand::NodeEdgeAddCommand(Node *output, NodeInput *input, int element) :
NodeEdgeAddCommand::NodeEdgeAddCommand(const NodeOutput &output, const NodeInput &input) :
output_(output),
input_(input),
element_(element),
remove_command_(nullptr)
{
}
@@ -40,22 +39,20 @@ NodeEdgeAddCommand::~NodeEdgeAddCommand()
void NodeEdgeAddCommand::redo()
{
if (input_->IsConnected(element_)) {
if (input_.IsConnected()) {
if (!remove_command_) {
remove_command_ = new NodeEdgeRemoveCommand(input_->GetConnectedNode(element_),
input_,
element_);
remove_command_ = new NodeEdgeRemoveCommand(input_.GetConnectedOutput(), input_);
}
remove_command_->redo();
}
Node::ConnectEdge(output_, input_, element_);
Node::ConnectEdge(output_, input_);
}
void NodeEdgeAddCommand::undo()
{
Node::DisconnectEdge(output_, input_, element_);
Node::DisconnectEdge(output_, input_);
if (remove_command_) {
remove_command_->undo();
@@ -64,29 +61,28 @@ void NodeEdgeAddCommand::undo()
Project *NodeEdgeAddCommand::GetRelevantProject() const
{
return output_->parent()->project();
return output_.node()->parent()->project();
}
NodeEdgeRemoveCommand::NodeEdgeRemoveCommand(Node *output, NodeInput *input, int element) :
NodeEdgeRemoveCommand::NodeEdgeRemoveCommand(const NodeOutput &output, const NodeInput &input) :
output_(output),
input_(input),
element_(element)
input_(input)
{
}
void NodeEdgeRemoveCommand::redo()
{
Node::DisconnectEdge(output_, input_, element_);
Node::DisconnectEdge(output_, input_);
}
void NodeEdgeRemoveCommand::undo()
{
Node::ConnectEdge(output_, input_, element_);
Node::ConnectEdge(output_, input_);
}
Project *NodeEdgeRemoveCommand::GetRelevantProject() const
{
return output_->parent()->project();
return output_.node()->parent()->project();
}
NodeAddCommand::NodeAddCommand(NodeGraph *graph, Node *node) :
@@ -134,14 +130,12 @@ void NodeRemoveAndDisconnectCommand::prep()
}
// Disconnect everything
foreach (const Node::InputConnection& conn, node_->edges()) {
command_->add_child(new NodeEdgeRemoveCommand(node_, conn.input, conn.element));
for (auto it=node_->input_connections().cbegin(); it!=node_->input_connections().cend(); it++) {
command_->add_child(new NodeEdgeRemoveCommand(it->second, it->first));
}
foreach (NodeInput* input, node_->inputs()) {
for (auto it=input->edges().cbegin(); it!=input->edges().cend(); it++) {
command_->add_child(new NodeEdgeRemoveCommand(it->second, input, it->first));
}
for (const Node::OutputConnection& conn : node_->output_connections()) {
command_->add_child(new NodeEdgeRemoveCommand(conn.first, conn.second));
}
}
+6 -8
View File
@@ -34,7 +34,7 @@ namespace olive {
*/
class NodeEdgeRemoveCommand : public UndoCommand {
public:
NodeEdgeRemoveCommand(Node* output, NodeInput* input, int element);
NodeEdgeRemoveCommand(const NodeOutput& output, const NodeInput& input);
virtual Project* GetRelevantProject() const override;
@@ -42,9 +42,8 @@ public:
virtual void undo() override;
private:
Node* output_;
NodeInput* input_;
int element_;
NodeOutput output_;
NodeInput input_;
};
@@ -55,7 +54,7 @@ private:
*/
class NodeEdgeAddCommand : public UndoCommand {
public:
NodeEdgeAddCommand(Node* output, NodeInput* input, int element);
NodeEdgeAddCommand(const NodeOutput& output, const NodeInput& input);
virtual ~NodeEdgeAddCommand() override;
@@ -65,9 +64,8 @@ public:
virtual void undo() override;
private:
Node* output_;
NodeInput* input_;
int element_;
NodeOutput output_;
NodeInput input_;
NodeEdgeRemoveCommand* remove_command_;
+60 -56
View File
@@ -41,7 +41,7 @@ namespace olive {
inline bool NodeCanBeRemoved(Node* n)
{
//return n->edges().isEmpty() && n->GetExclusiveDependencies().isEmpty();
return n->edges().empty();
return n->output_connections().empty();
}
inline UndoCommand* CreateRemoveCommand(Node* n)
@@ -234,7 +234,7 @@ public:
invalidate_range = block_->range();
}
track_->InvalidateCache(invalidate_range, track_->block_input());
track_->InvalidateCache(invalidate_range, Track::kBlockInput);
}
virtual void undo() override
@@ -294,7 +294,7 @@ public:
track_->EndOperation();
track_->InvalidateCache(invalidate_range, track_->block_input());
track_->InvalidateCache(invalidate_range, Track::kBlockInput);
}
private:
@@ -578,13 +578,13 @@ public:
track->InsertBlockAfter(new_block(), block_);
// If the block had an out transition, we move it to the new block
moved_transition_ = nullptr;
moved_transition_ = NodeInput();
TransitionBlock* potential_transition = dynamic_cast<TransitionBlock*>(new_block()->next());
if (potential_transition) {
foreach (const Node::InputConnection& conn, block_->edges()) {
if (conn.input->parent() == potential_transition) {
moved_transition_ = potential_transition->out_block_input();
for (const Node::OutputConnection& output : block_->output_connections()) {
if (output.second.node() == potential_transition) {
moved_transition_ = NodeInput(potential_transition, TransitionBlock::kOutBlockInput);
Node::DisconnectEdge(block_, moved_transition_);
Node::ConnectEdge(new_block(), moved_transition_);
break;
@@ -601,9 +601,9 @@ public:
track->BeginOperation();
if (moved_transition_) {
if (moved_transition_.IsValid()) {
Node::DisconnectEdge(new_block(), moved_transition_);
Node::DisconnectEdge(block_, moved_transition_);
Node::ConnectEdge(block_, moved_transition_);
}
block_->set_length_and_media_out(old_length_);
@@ -630,7 +630,7 @@ private:
UndoCommand* reconnect_tree_command_;
NodeInput* moved_transition_;
NodeInput moved_transition_;
QVector<Node*> src_nodes_;
QVector<Node*> added_nodes_;
@@ -1144,8 +1144,7 @@ public:
TrackListRippleToolCommand(TrackList* track_list,
const QHash<Track*, RippleInfo>& info,
const rational& ripple_movement,
const Timeline::MovementMode& movement_mode,
UndoCommand* parent = nullptr) :
const Timeline::MovementMode& movement_mode) :
track_list_(track_list),
info_(info),
ripple_movement_(ripple_movement),
@@ -1356,23 +1355,20 @@ private:
class TimelineAddTrackCommand : public UndoCommand {
public:
TimelineAddTrackCommand(TrackList *timeline) :
timeline_(timeline),
direct_(nullptr)
timeline_(timeline)
{
track_ = new Track();
track_->setParent(&memory_manager_);
if (timeline->GetTrackCount() > 0 && Config::Current()[QStringLiteral("AutoMergeTracks")].toBool()) {
if (timeline_->type() == Track::kVideo) {
MergeNode* merge = new MergeNode();
base_ = merge->base_in();
blend_ = merge->blend_in();
merge_ = merge;
merge_ = new MergeNode();
base_ = NodeInput(merge_, MergeNode::kBaseIn);
blend_ = NodeInput(merge_, MergeNode::kBlendIn);
} else {
MathNode* math = new MathNode();
base_ = math->param_a_in();
blend_ = math->param_b_in();
merge_ = math;
merge_ = new MathNode();
base_ = NodeInput(merge_, MathNode::kParamAIn);
blend_ = NodeInput(merge_, MathNode::kParamBIn);
}
merge_->setParent(&memory_manager_);
} else {
@@ -1394,8 +1390,8 @@ public:
{
// Add track
track_->setParent(timeline_->GetParentGraph());
timeline_->track_input()->ArrayAppend();
Node::ConnectEdge(track_, timeline_->track_input(), timeline_->track_input()->ArraySize() - 1);
timeline_->ArrayAppend();
Node::ConnectEdge(track_, timeline_->track_input(timeline_->ArraySize() - 1));
// Add merge if applicable
if (merge_) {
@@ -1404,11 +1400,14 @@ public:
Track* last_track = timeline_->GetTrackAt(timeline_->GetTrackCount()-2);
// Whatever this track used to be connected to, connect the merge instead
std::vector<Node::InputConnection> edges = last_track->edges();
foreach (const Node::InputConnection& ic, edges) {
if (ic.input != timeline_->track_input()) {
Node::DisconnectEdge(last_track, ic.input, ic.element);
Node::ConnectEdge(merge_, ic.input, ic.element);
const Node::OutputConnections edges = last_track->output_connections();
for (const Node::OutputConnection& ic : edges) {
const NodeInput& i = ic.second;
// Ignore the track input, but funnel everything else through our merge
if (i.node() != timeline_->parent() && i.input() != timeline_->track_input()) {
Node::DisconnectEdge(last_track, i);
Node::ConnectEdge(merge_, i);
}
}
@@ -1417,18 +1416,20 @@ public:
Node::ConnectEdge(last_track, base_);
} else if (timeline_->GetTrackCount() == 1) {
// If this was the first track we added,
NodeInput* relevant_input;
QString relevant_input;
if (timeline_->type() == Track::kVideo) {
relevant_input = timeline_->parent()->texture_input();
relevant_input = ViewerOutput::kTextureInput;
} else {
relevant_input = timeline_->parent()->samples_input();
relevant_input = ViewerOutput::kSamplesInput;
}
if (!relevant_input->IsConnected()) {
Node::ConnectEdge(track_, relevant_input);
if (!timeline_->parent()->IsInputConnected(relevant_input)) {
direct_ = NodeInput(timeline_->parent(), relevant_input);
direct_ = relevant_input;
Node::ConnectEdge(track_, direct_);
} else {
direct_ = NodeInput();
}
}
}
@@ -1443,20 +1444,23 @@ public:
Node::DisconnectEdge(track_, blend_);
Node::DisconnectEdge(last_track, base_);
std::vector<Node::InputConnection> edges = merge_->edges();
foreach (const Node::InputConnection& ic, edges) {
Node::DisconnectEdge(merge_, ic.input, ic.element);
Node::ConnectEdge(last_track, ic.input, ic.element);
// Make copy of edges since the node's internal array will change as we disconnect things
const Node::OutputConnections edges = merge_->output_connections();
for (const Node::OutputConnection& ic : edges) {
const NodeInput& i = ic.second;
Node::DisconnectEdge(merge_, i);
Node::ConnectEdge(last_track, i);
}
merge_->setParent(&memory_manager_);
} else if (direct_) {
} else if (direct_.IsValid()) {
Node::DisconnectEdge(track_, direct_);
}
// Remove track
Node::DisconnectEdge(track_, timeline_->track_input(), timeline_->track_input()->ArraySize() - 1);
timeline_->track_input()->ArrayRemoveLast();
Node::DisconnectEdge(track_, timeline_->track_input(timeline_->ArraySize() - 1));
timeline_->ArrayRemoveLast();
track_->setParent(&memory_manager_);
}
@@ -1465,10 +1469,10 @@ private:
Track* track_;
Node* merge_;
NodeInput* base_;
NodeInput* blend_;
NodeInput base_;
NodeInput blend_;
NodeInput* direct_;
NodeInput direct_;
QObject memory_manager_;
@@ -1705,7 +1709,7 @@ public:
track_->EndOperation();
track_->InvalidateCache(invalidate_range, track_->block_input());
track_->InvalidateCache(invalidate_range, Track::kBlockInput);
}
virtual void undo() override
@@ -1762,7 +1766,7 @@ public:
track_->EndOperation();
track_->InvalidateCache(TimeRange(block_->in(), block_->out()), track_->block_input());
track_->InvalidateCache(TimeRange(block_->in(), block_->out()), Track::kBlockInput);
}
private:
@@ -2047,7 +2051,7 @@ public:
invalidate_range.set_range(qMin(invalidate_range.in(), blocks_.first()->in()),
qMax(invalidate_range.out(), blocks_.last()->out()));
track_->InvalidateCache(invalidate_range, track_->block_input());
track_->InvalidateCache(invalidate_range, Track::kBlockInput);
}
virtual void undo() override
@@ -2087,7 +2091,7 @@ public:
invalidate_range.set_range(qMin(invalidate_range.in(), blocks_.first()->in()),
qMax(invalidate_range.out(), blocks_.last()->out()));
track_->InvalidateCache(invalidate_range, track_->block_input());
track_->InvalidateCache(invalidate_range, Track::kBlockInput);
}
private:
@@ -2315,7 +2319,7 @@ private:
class TransitionRemoveCommand : public UndoCommand {
public:
TransitionRemoveCommand(TransitionBlock* block, UndoCommand *parent = nullptr) :
TransitionRemoveCommand(TransitionBlock* block) :
block_(block)
{
}
@@ -2346,18 +2350,18 @@ public:
}
if (in_block_) {
Node::DisconnectEdge(in_block_, block_->in_block_input());
Node::DisconnectEdge(in_block_, NodeInput(block_, TransitionBlock::kInBlockInput));
}
if (out_block_) {
Node::DisconnectEdge(out_block_, block_->out_block_input());
Node::DisconnectEdge(out_block_, NodeInput(block_, TransitionBlock::kOutBlockInput));
}
track_->RippleRemoveBlock(block_);
track_->EndOperation();
track_->InvalidateCache(invalidate_range, track_->block_input());
track_->InvalidateCache(invalidate_range, Track::kBlockInput);
}
virtual void undo() override
@@ -2371,11 +2375,11 @@ public:
}
if (in_block_) {
Node::ConnectEdge(in_block_, block_->in_block_input());
Node::ConnectEdge(in_block_, NodeInput(block_, TransitionBlock::kInBlockInput));
}
if (out_block_) {
Node::ConnectEdge(out_block_, block_->out_block_input());
Node::ConnectEdge(out_block_, NodeInput(block_, TransitionBlock::kOutBlockInput));
}
// These if statements must be separated because in_offset and out_offset report different things
@@ -2391,7 +2395,7 @@ public:
track_->EndOperation();
track_->InvalidateCache(TimeRange(block_->in(), block_->out()), track_->block_input());
track_->InvalidateCache(TimeRange(block_->in(), block_->out()), Track::kBlockInput);
}
private:
+2 -2
View File
@@ -118,7 +118,7 @@ void AddTool::MouseRelease(TimelineViewMouseEvent *event)
command->add_child(new NodeAddCommand(graph,
solid));
command->add_child(new NodeEdgeAddCommand(solid, clip->texture_input(), -1));
command->add_child(new NodeEdgeAddCommand(solid, NodeInput(clip, ClipBlock::kBufferIn)));
break;
}
case olive::Tool::kAddableTitle:
@@ -128,7 +128,7 @@ void AddTool::MouseRelease(TimelineViewMouseEvent *event)
command->add_child(new NodeAddCommand(graph,
text));
command->add_child(new NodeEdgeAddCommand(text, clip->texture_input(), -1));
command->add_child(new NodeEdgeAddCommand(text, NodeInput(clip, ClipBlock::kBufferIn)));
break;
}
case olive::Tool::kAddableBars:
+4 -4
View File
@@ -434,8 +434,8 @@ void ImportTool::DropGhosts(bool insert)
TransformDistortNode* transform = new TransformDistortNode();
command->add_child(new NodeAddCommand(dst_graph, transform));
command->add_child(new NodeEdgeAddCommand(video_input, transform->texture_input(), -1));
command->add_child(new NodeEdgeAddCommand(transform, clip->texture_input(), -1));
command->add_child(new NodeEdgeAddCommand(video_input, NodeInput(transform, TransformDistortNode::kTextureInput)));
command->add_child(new NodeEdgeAddCommand(transform, NodeInput(clip, ClipBlock::kBufferIn)));
break;
}
case Stream::kAudio:
@@ -447,8 +447,8 @@ void ImportTool::DropGhosts(bool insert)
VolumeNode* volume_node = new VolumeNode();
command->add_child(new NodeAddCommand(dst_graph, volume_node));
command->add_child(new NodeEdgeAddCommand(audio_input, volume_node->samples_input(), -1));
command->add_child(new NodeEdgeAddCommand(volume_node, clip->texture_input(), -1));
command->add_child(new NodeEdgeAddCommand(audio_input, NodeInput(volume_node, VolumeNode::kSamplesInput)));
command->add_child(new NodeEdgeAddCommand(volume_node, NodeInput(clip, ClipBlock::kBufferIn)));
break;
}
default:
+6
View File
@@ -37,6 +37,12 @@ public:
class DraggedFootage {
public:
DraggedFootage() :
footage_(nullptr),
streams_(0)
{
}
DraggedFootage(Footage* f, quint64 streams) :
footage_(f),
streams_(streams)
@@ -147,28 +147,25 @@ void TransitionTool::MouseRelease(TimelineViewMouseEvent *event)
// Connect block to transition
command->add_child(new NodeEdgeAddCommand(out_block,
transition->out_block_input(),
-1));
NodeInput(transition, TransitionBlock::kOutBlockInput)));
command->add_child(new NodeEdgeAddCommand(in_block,
transition->in_block_input(),
-1));
NodeInput(transition, TransitionBlock::kInBlockInput)));
} else {
Block* block_to_transition = Node::ValueToPtr<Block>(ghost_->GetData(TimelineViewGhostItem::kAttachedBlock));
NodeInput* transition_input_to_connect;
QString transition_input_to_connect;
if (ghost_->GetMode() == Timeline::kTrimIn) {
transition->set_length_and_media_out(ghost_->GetAdjustedLength());
transition_input_to_connect = transition->in_block_input();
transition_input_to_connect = TransitionBlock::kInBlockInput;
} else {
transition->set_length_and_media_out(ghost_->GetAdjustedLength());
transition_input_to_connect = transition->out_block_input();
transition_input_to_connect = TransitionBlock::kOutBlockInput;
}
// Connect block to transition
command->add_child(new NodeEdgeAddCommand(block_to_transition,
transition_input_to_connect,
-1));
NodeInput(transition, transition_input_to_connect)));
}
Core::instance()->undo_stack()->push(command);
+4 -4
View File
@@ -60,8 +60,8 @@ void FootageViewerWidget::SetFootage(Footage *footage)
video_node_->SetStream(nullptr);
audio_node_->SetStream(nullptr);
Node::DisconnectEdge(video_node_, sequence_.viewer_output()->texture_input());
Node::DisconnectEdge(audio_node_, sequence_.viewer_output()->samples_input());
Node::DisconnectEdge(video_node_, NodeInput(sequence_.viewer_output(), ViewerOutput::kTextureInput));
Node::DisconnectEdge(audio_node_, NodeInput(sequence_.viewer_output(), ViewerOutput::kSamplesInput));
}
footage_ = footage;
@@ -98,12 +98,12 @@ void FootageViewerWidget::SetFootage(Footage *footage)
if (video_stream) {
video_node_->SetStream(video_stream);
Node::ConnectEdge(video_node_, sequence_.viewer_output()->texture_input());
Node::ConnectEdge(video_node_, NodeInput(sequence_.viewer_output(), ViewerOutput::kTextureInput));
}
if (audio_stream) {
audio_node_->SetStream(audio_stream);
Node::ConnectEdge(audio_node_, sequence_.viewer_output()->samples_input());
Node::ConnectEdge(audio_node_, NodeInput(sequence_.viewer_output(), ViewerOutput::kSamplesInput));
}
ConnectViewerNode(sequence_.viewer_output(), footage_->project()->color_manager());
+4 -6
View File
@@ -178,8 +178,7 @@ void ViewerWidget::ConnectNodeInternal(ViewerOutput *n)
connect(n, &ViewerOutput::AudioParamsChanged, this, &ViewerWidget::UpdateRendererAudioParameters);
connect(n->video_frame_cache(), &FrameHashCache::Invalidated, this, &ViewerWidget::ViewerInvalidatedVideoRange);
connect(n->video_frame_cache(), &FrameHashCache::Shifted, this, &ViewerWidget::ViewerShiftedRange);
connect(n->texture_input(), &NodeInput::InputConnected, this, &ViewerWidget::UpdateStack);
connect(n->texture_input(), &NodeInput::InputDisconnected, this, &ViewerWidget::UpdateStack);
connect(n, &ViewerOutput::TextureInputChanged, this, &ViewerWidget::UpdateStack);
InterlacingChangedSlot(n->video_params().interlacing());
@@ -233,8 +232,7 @@ void ViewerWidget::DisconnectNodeInternal(ViewerOutput *n)
disconnect(n, &ViewerOutput::AudioParamsChanged, this, &ViewerWidget::UpdateRendererAudioParameters);
disconnect(n->video_frame_cache(), &FrameHashCache::Invalidated, this, &ViewerWidget::ViewerInvalidatedVideoRange);
disconnect(n->video_frame_cache(), &FrameHashCache::Shifted, this, &ViewerWidget::ViewerShiftedRange);
disconnect(n->texture_input(), &NodeInput::InputConnected, this, &ViewerWidget::UpdateStack);
disconnect(n->texture_input(), &NodeInput::InputDisconnected, this, &ViewerWidget::UpdateStack);
disconnect(n, &ViewerOutput::TextureInputChanged, this, &ViewerWidget::UpdateStack);
ruler()->SetPlaybackCache(nullptr);
@@ -398,8 +396,8 @@ void ViewerWidget::DecodeCachedImage(RenderTicketPtr ticket, const QString &fn,
bool ViewerWidget::ShouldForceWaveform() const
{
return GetConnectedNode()
&& !GetConnectedNode()->texture_input()->IsConnected()
&& GetConnectedNode()->samples_input()->IsConnected();
&& !GetConnectedNode()->IsInputConnected(ViewerOutput::kTextureInput)
&& GetConnectedNode()->IsInputConnected(ViewerOutput::kSamplesInput);
}
void ViewerWidget::UpdateTextureFromNode(const rational& time)