reworked param view passthroughs for groups

This commit is contained in:
itsmattkc
2022-01-22 18:17:51 -08:00
parent aae0c4963b
commit 6aa493bd67
8 changed files with 196 additions and 131 deletions
+19
View File
@@ -139,6 +139,25 @@ QString NodeGroup::GetInputName(const QString &id) const
return pass.node()->GetInputName(pass.input());
}
NodeInput NodeGroup::ResolveInput(NodeInput input)
{
while (GetInner(&input)) {}
return input;
}
bool NodeGroup::GetInner(NodeInput *input)
{
if (NodeGroup *g = dynamic_cast<NodeGroup*>(input->node())) {
const NodeInput &passthrough = g->GetInputPassthroughs().value(input->input());
input->set_node(passthrough.node());
input->set_input(passthrough.input());
return true;
} else {
return false;
}
}
void NodeGroupAddInputPassthrough::redo()
{
if (!group_->ContainsInputPassthrough(input_)) {
+3
View File
@@ -63,6 +63,9 @@ public:
virtual QString GetInputName(const QString& id) const override;
static NodeInput ResolveInput(NodeInput input);
static bool GetInner(NodeInput *input);
signals:
void InputPassthroughAdded(NodeGroup *group, const NodeInput &input);
+5 -1
View File
@@ -72,10 +72,14 @@ KeyframeView::NodeConnections KeyframeView::AddKeyframesOfNode(Node *n)
return map;
}
KeyframeView::InputConnections KeyframeView::AddKeyframesOfInput(Node* n, const QString& input)
KeyframeView::InputConnections KeyframeView::AddKeyframesOfInput(Node* on, const QString& oinput)
{
InputConnections vec;
NodeInput resolved = NodeGroup::ResolveInput(NodeInput(on, oinput));
Node *n = resolved.node();
const QString &input = resolved.input();
if (n->IsInputKeyframable(input)) {
int arr_sz = n->InputArraySize(input);
vec.resize(arr_sz + 1);
+1 -1
View File
@@ -580,7 +580,7 @@ void NodeParamView::UpdateElementY()
if (!connections.isEmpty()) {
foreach (const QString& input, it.key()->inputs()) {
if (!(it.key()->GetInputFlags(input) & kInputFlagHidden)) {
int arr_sz = it.key()->InputArraySize(input);
int arr_sz = NodeGroup::ResolveInput(NodeInput(it.key(), input)).GetArraySize();
for (int i=-1; i<arr_sz; i++) {
NodeInput ic = {it.key(), input, i};
+33 -37
View File
@@ -102,19 +102,17 @@ NodeParamViewItemBody::NodeParamViewItemBody(Node* node, NodeParamViewCheckBoxBe
// Create widgets all root level components
foreach (QString input, node->inputs()) {
Node *n = node;
while (NodeGroup *g = dynamic_cast<NodeGroup*>(n)) {
const NodeInput &ni = g->GetInputPassthroughs().value(input);
n = ni.node();
input = ni.input();
NodeInput resolved = NodeGroup::ResolveInput(NodeInput(n, input));
if (!connected_signals.contains(resolved.node())) {
connect(resolved.node(), &Node::InputArraySizeChanged, this, &NodeParamViewItemBody::InputArraySizeChanged);
connect(resolved.node(), &Node::InputConnected, this, &NodeParamViewItemBody::EdgeChanged);
connect(resolved.node(), &Node::InputDisconnected, this, &NodeParamViewItemBody::EdgeChanged);
connected_signals.append(resolved.node());
}
if (!connected_signals.contains(n)) {
connect(n, &Node::InputArraySizeChanged, this, &NodeParamViewItemBody::InputArraySizeChanged);
connect(n, &Node::InputConnected, this, &NodeParamViewItemBody::EdgeChanged);
connect(n, &Node::InputDisconnected, this, &NodeParamViewItemBody::EdgeChanged);
connected_signals.append(n);
}
input_group_lookup_.insert({resolved.node(), resolved.input()}, {n, input});
if (!(n->GetInputFlags(input) & kInputFlagHidden)) {
CreateWidgets(root_layout, n, input, -1, insert_row);
@@ -208,14 +206,6 @@ void NodeParamViewItemBody::CreateWidgets(QGridLayout* layout, Node *node, const
connect(remove_element_btn, &NodeParamViewArrayButton::clicked, this, &NodeParamViewItemBody::ArrayRemoveClicked);
}
} else if (dynamic_cast<ClipBlock*>(node) && input == ClipBlock::kSpeedInput) {
// Special behavior - this was the most preferable way to do this so we could support multiple
// nodes per item one day
QPushButton *btn = new QPushButton(tr("..."));
btn->setFixedWidth(btn->sizeHint().height());
connect(btn, &QPushButton::clicked, this, &NodeParamViewItemBody::ShowSpeedDurationDialogForNode);
layout->addWidget(btn, row, kExtraButtonColumn);
ui_objects.extra_btn = btn;
}
// Create a widget/input bridge for this input
@@ -233,9 +223,12 @@ void NodeParamViewItemBody::CreateWidgets(QGridLayout* layout, Node *node, const
layout->addWidget(w, row, i+kWidgetStartColumn);
}
// In case this input is a group, resolve that actual input to use for connected labels
NodeInput resolved = NodeGroup::ResolveInput(input_ref);
if (node->IsInputConnectable(input)) {
// Create clickable label used when an input is connected
ui_objects.connected_label = new NodeParamViewConnectedLabel(input_ref);
ui_objects.connected_label = new NodeParamViewConnectedLabel(resolved);
connect(ui_objects.connected_label, &NodeParamViewConnectedLabel::RequestSelectNode, this, &NodeParamViewItemBody::RequestSelectNode);
layout->addWidget(ui_objects.connected_label, row, kWidgetStartColumn, 1, kKeyControlColumn - kWidgetStartColumn);
}
@@ -243,7 +236,7 @@ void NodeParamViewItemBody::CreateWidgets(QGridLayout* layout, Node *node, const
// Add keyframe control to this layout if parameter is keyframable
if (node->IsInputKeyframable(input)) {
ui_objects.key_control = new NodeParamViewKeyframeControl();
ui_objects.key_control->SetInput(input_ref);
ui_objects.key_control->SetInput(resolved);
layout->addWidget(ui_objects.key_control, row, kKeyControlColumn);
connect(ui_objects.key_control, &NodeParamViewKeyframeControl::RequestSetTime, this, &NodeParamViewItemBody::RequestSetTime);
}
@@ -305,11 +298,7 @@ int NodeParamViewItemBody::GetElementY(NodeInput c) const
c.set_element(-1);
}
while (NodeGroup *g = dynamic_cast<NodeGroup*>(c.node())) {
const NodeInput &passthrough = g->GetInputPassthroughs().value(c.input());
c.set_node(passthrough.node());
c.set_input(passthrough.input());
}
//c = NodeGroup::ResolveInput(c);
// Find its row in the parameters
QLabel* lbl = input_ui_map_.value(c).main_label;
@@ -328,7 +317,10 @@ void NodeParamViewItemBody::EdgeChanged(Node *output, const NodeInput& input)
{
Q_UNUSED(output)
UpdateUIForEdgeConnection(input);
const NodeInputPair &pair = input_group_lookup_.value({input.node(), input.input()});
NodeInput resolved(pair.node, pair.input, input.element());
UpdateUIForEdgeConnection(resolved);
}
void NodeParamViewItemBody::UpdateUIForEdgeConnection(const NodeInput& input)
@@ -337,20 +329,22 @@ void NodeParamViewItemBody::UpdateUIForEdgeConnection(const NodeInput& input)
if (input_ui_map_.contains(input)) {
const InputUI& ui_objects = input_ui_map_[input];
bool is_connected = NodeGroup::ResolveInput(input).IsConnected();
foreach (QWidget* w, ui_objects.widget_bridge->widgets()) {
w->setVisible(!input.IsConnected());
w->setVisible(!is_connected);
}
// Show/hide connection label
ui_objects.connected_label->setVisible(input.IsConnected());
ui_objects.connected_label->setVisible(is_connected);
if (ui_objects.key_control) {
ui_objects.key_control->setVisible(!input.IsConnected());
ui_objects.key_control->setVisible(!is_connected);
}
// Show/hide optional checkbox if requested
if (create_checkboxes_ == kCheckBoxesOnNonConnected) {
ui_objects.optional_checkbox->setVisible(!input.IsConnected());
ui_objects.optional_checkbox->setVisible(!is_connected);
}
}
}
@@ -414,7 +408,8 @@ void NodeParamViewItemBody::ArrayCollapseBtnPressed(bool checked)
array_ui_.value(input).widget->setVisible(checked);
if (checked) {
// Ensure widgets are created (the signal will be ignored if they are)
InputArraySizeChangedInternal(input.node, input.input, input.node->InputArraySize(input.input));
NodeInput resolved = NodeGroup::ResolveInput(NodeInput(input.node, input.input));
InputArraySizeChangedInternal(input.node, input.input, resolved.GetArraySize());
}
emit ArrayExpandedChanged(checked);
@@ -424,16 +419,17 @@ void NodeParamViewItemBody::InputArraySizeChanged(const QString& input, int old_
{
Q_UNUSED(old_sz)
Node* node = static_cast<Node*>(sender());
NodeInputPair nip = input_group_lookup_.value({static_cast<Node*>(sender()), input});
InputArraySizeChangedInternal(node, input, size);
InputArraySizeChangedInternal(nip.node, nip.input, size);
}
void NodeParamViewItemBody::ArrayAppendClicked()
{
for (auto it=array_ui_.cbegin(); it!=array_ui_.cend(); it++) {
if (it.value().append_btn == sender()) {
it.key().node->InputArrayAppend(it.key().input, true);
NodeInput real_input = NodeGroup::ResolveInput(NodeInput(it.key().node, it.key().input));
real_input.node()->InputArrayAppend(real_input.input(), true);
break;
}
}
@@ -444,7 +440,7 @@ 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 NodeInput& ic = it.key();
NodeInput ic = NodeGroup::ResolveInput(it.key());
ic.node()->InputArrayInsert(ic.input(), ic.element(), true);
break;
}
@@ -456,7 +452,7 @@ 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 NodeInput& ic = it.key();
NodeInput ic = NodeGroup::ResolveInput(it.key());
ic.node()->InputArrayRemove(ic.input(), ic.element(), true);
break;
}
@@ -116,6 +116,8 @@ private:
NodeParamViewCheckBoxBehavior create_checkboxes_;
QHash<NodeInputPair, NodeInputPair> input_group_lookup_;
/**
* @brief The column to place the keyframe controls in
*
@@ -41,24 +41,25 @@
namespace olive {
NodeParamViewWidgetBridge::NodeParamViewWidgetBridge(const NodeInput &input, QObject *parent) :
QObject(parent),
input_(input)
NodeParamViewWidgetBridge::NodeParamViewWidgetBridge(NodeInput input, QObject *parent) :
QObject(parent)
{
CreateWidgets();
do {
input_hierarchy_.append(input);
connect(input_.node(), &Node::ValueChanged, this, &NodeParamViewWidgetBridge::InputValueChanged);
connect(input_.node(), &Node::InputPropertyChanged, this, &NodeParamViewWidgetBridge::PropertyChanged);
connect(input_.node(), &Node::InputDataTypeChanged, this, &NodeParamViewWidgetBridge::InputDataTypeChanged);
connect(input.node(), &Node::ValueChanged, this, &NodeParamViewWidgetBridge::InputValueChanged);
connect(input.node(), &Node::InputPropertyChanged, this, &NodeParamViewWidgetBridge::PropertyChanged);
connect(input.node(), &Node::InputDataTypeChanged, this, &NodeParamViewWidgetBridge::InputDataTypeChanged);
} while (NodeGroup::GetInner(&input));
CreateWidgets();
}
void NodeParamViewWidgetBridge::SetTime(const rational &time)
{
time_ = time;
if (input_.IsValid()) {
UpdateWidgetValues();
}
UpdateWidgetValues();
}
int GetSliderCount(NodeValue::Type type)
@@ -68,16 +69,16 @@ int GetSliderCount(NodeValue::Type type)
void NodeParamViewWidgetBridge::CreateWidgets()
{
if (input_.IsArray() && input_.element() == -1) {
if (GetInnerInput().IsArray() && GetInnerInput().element() == -1) {
NodeParamViewArrayWidget* w = new NodeParamViewArrayWidget(input_.node(), input_.input());
NodeParamViewArrayWidget* w = new NodeParamViewArrayWidget(GetInnerInput().node(), GetInnerInput().input());
connect(w, &NodeParamViewArrayWidget::DoubleClicked, this, &NodeParamViewWidgetBridge::ArrayWidgetDoubleClicked);
widgets_.append(w);
} else {
// We assume the first data type is the "primary" type
NodeValue::Type t = input_.GetDataType();
NodeValue::Type t = GetDataType();
switch (t) {
// None of these inputs have applicable UI widgets
case NodeValue::kNone:
@@ -113,7 +114,7 @@ void NodeParamViewWidgetBridge::CreateWidgets()
{
QComboBox* combobox = new QComboBox();
QStringList items = input_.GetComboBoxStrings();
QStringList items = GetInnerInput().GetComboBoxStrings();
foreach (const QString& s, items) {
combobox->addItem(s);
}
@@ -131,7 +132,7 @@ void NodeParamViewWidgetBridge::CreateWidgets()
}
case NodeValue::kColor:
{
ColorButton* color_button = new ColorButton(input_.node()->project()->color_manager());
ColorButton* color_button = new ColorButton(GetInnerInput().node()->project()->color_manager());
widgets_.append(color_button);
connect(color_button, &ColorButton::ColorChanged, this, &NodeParamViewWidgetBridge::WidgetCallback);
break;
@@ -160,10 +161,7 @@ void NodeParamViewWidgetBridge::CreateWidgets()
}
// Check all properties
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());
}
UpdateProperties();
UpdateWidgetValues();
@@ -186,16 +184,16 @@ void NodeParamViewWidgetBridge::SetInputValue(const QVariant &value, int track)
void NodeParamViewWidgetBridge::SetInputValueInternal(const QVariant &value, int track, MultiUndoCommand *command, bool insert_on_all_tracks_if_no_key)
{
if (input_.IsKeyframing()) {
if (GetInnerInput().IsKeyframing()) {
rational node_time = GetCurrentTimeAsNodeTime();
NodeKeyframe* existing_key = input_.GetKeyframeAtTimeOnTrack(node_time, track);
NodeKeyframe* existing_key = GetInnerInput().GetKeyframeAtTimeOnTrack(node_time, track);
if (existing_key) {
command->add_child(new NodeParamSetKeyframeValueCommand(existing_key, value));
} else {
// No existing key, create a new one
int nb_tracks = NodeValue::get_number_of_keyframe_tracks(input_.node()->GetInputDataType(input_.input()));
int nb_tracks = NodeValue::get_number_of_keyframe_tracks(GetInnerInput().node()->GetInputDataType(GetInnerInput().input()));
for (int i=0; i<nb_tracks; i++) {
QVariant track_value;
@@ -204,21 +202,21 @@ void NodeParamViewWidgetBridge::SetInputValueInternal(const QVariant &value, int
} else if (!insert_on_all_tracks_if_no_key) {
continue;
} else {
track_value = input_.node()->GetSplitValueAtTimeOnTrack(input_.input(), node_time, i, input_.element());
track_value = GetInnerInput().node()->GetSplitValueAtTimeOnTrack(GetInnerInput().input(), node_time, i, GetInnerInput().element());
}
NodeKeyframe* new_key = new NodeKeyframe(node_time,
track_value,
input_.node()->GetBestKeyframeTypeForTimeOnTrack(NodeKeyframeTrackReference(input_, i), node_time),
GetInnerInput().node()->GetBestKeyframeTypeForTimeOnTrack(NodeKeyframeTrackReference(GetInnerInput(), i), node_time),
i,
input_.element(),
input_.input());
GetInnerInput().element(),
GetInnerInput().input());
command->add_child(new NodeParamInsertKeyframeCommand(input_.node(), new_key));
command->add_child(new NodeParamInsertKeyframeCommand(GetInnerInput().node(), new_key));
}
}
} else {
command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(input_, track), value));
command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(GetInnerInput(), track), value));
}
}
@@ -232,7 +230,7 @@ void NodeParamViewWidgetBridge::ProcessSlider(NumericSliderBase *slider, const Q
if (!dragger_.IsStarted()) {
rational node_time = GetCurrentTimeAsNodeTime();
dragger_.Start(NodeKeyframeTrackReference(input_, slider_track), node_time);
dragger_.Start(NodeKeyframeTrackReference(GetInnerInput(), slider_track), node_time);
}
dragger_.Drag(value);
@@ -256,7 +254,7 @@ void NodeParamViewWidgetBridge::ProcessSlider(NumericSliderBase *slider, const Q
void NodeParamViewWidgetBridge::WidgetCallback()
{
switch (input_.GetDataType()) {
switch (GetDataType()) {
// None of these inputs have applicable UI widgets
case NodeValue::kNone:
case NodeValue::kTexture:
@@ -333,12 +331,12 @@ void NodeParamViewWidgetBridge::WidgetCallback()
SetInputValueInternal(c.blue(), 2, command, false);
SetInputValueInternal(c.alpha(), 3, command, false);
Node* n = input_.node();
Node* n = GetInnerInput().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->SetInputProperty(GetInnerInput().input(), QStringLiteral("col_input"), c.color_input());
n->SetInputProperty(GetInnerInput().input(), QStringLiteral("col_display"), c.color_output().display());
n->SetInputProperty(GetInnerInput().input(), QStringLiteral("col_view"), c.color_output().view());
n->SetInputProperty(GetInnerInput().input(), QStringLiteral("col_look"), c.color_output().look());
n->blockSignals(false);
Core::instance()->undo_stack()->pushIfHasChildren(command);
@@ -386,7 +384,7 @@ void NodeParamViewWidgetBridge::CreateSliders(int count)
{
for (int i=0;i<count;i++) {
T* fs = new T();
fs->SliderBase::SetDefaultValue(input_.GetSplitDefaultValueForTrack(i));
fs->SliderBase::SetDefaultValue(GetInnerInput().GetSplitDefaultValueForTrack(i));
fs->SetLadderElementCount(2);
widgets_.append(fs);
connect(fs, &T::ValueChanged, this, &NodeParamViewWidgetBridge::WidgetCallback);
@@ -395,17 +393,17 @@ void NodeParamViewWidgetBridge::CreateSliders(int count)
void NodeParamViewWidgetBridge::UpdateWidgetValues()
{
if (input_.IsArray() && input_.element() == -1) {
if (GetInnerInput().IsArray() && GetInnerInput().element() == -1) {
return;
}
rational node_time;
if (input_.IsKeyframing()) {
if (GetInnerInput().IsKeyframing()) {
node_time = GetCurrentTimeAsNodeTime();
}
// We assume the first data type is the "primary" type
switch (input_.GetDataType()) {
switch (GetDataType()) {
// None of these inputs have applicable UI widgets
case NodeValue::kNone:
case NodeValue::kTexture:
@@ -420,22 +418,22 @@ void NodeParamViewWidgetBridge::UpdateWidgetValues()
break;
case NodeValue::kInt:
{
static_cast<IntegerSlider*>(widgets_.first())->SetValue(input_.GetValueAtTime(node_time).toLongLong());
static_cast<IntegerSlider*>(widgets_.first())->SetValue(GetInnerInput().GetValueAtTime(node_time).toLongLong());
break;
}
case NodeValue::kFloat:
{
static_cast<FloatSlider*>(widgets_.first())->SetValue(input_.GetValueAtTime(node_time).toDouble());
static_cast<FloatSlider*>(widgets_.first())->SetValue(GetInnerInput().GetValueAtTime(node_time).toDouble());
break;
}
case NodeValue::kRational:
{
static_cast<RationalSlider*>(widgets_.first())->SetValue(input_.GetValueAtTime(node_time).value<rational>());
static_cast<RationalSlider*>(widgets_.first())->SetValue(GetInnerInput().GetValueAtTime(node_time).value<rational>());
break;
}
case NodeValue::kVec2:
{
QVector2D vec2 = input_.GetValueAtTime(node_time).value<QVector2D>();
QVector2D vec2 = GetInnerInput().GetValueAtTime(node_time).value<QVector2D>();
static_cast<FloatSlider*>(widgets_.at(0))->SetValue(static_cast<double>(vec2.x()));
static_cast<FloatSlider*>(widgets_.at(1))->SetValue(static_cast<double>(vec2.y()));
@@ -443,7 +441,7 @@ void NodeParamViewWidgetBridge::UpdateWidgetValues()
}
case NodeValue::kVec3:
{
QVector3D vec3 = input_.GetValueAtTime(node_time).value<QVector3D>();
QVector3D vec3 = GetInnerInput().GetValueAtTime(node_time).value<QVector3D>();
static_cast<FloatSlider*>(widgets_.at(0))->SetValue(static_cast<double>(vec3.x()));
static_cast<FloatSlider*>(widgets_.at(1))->SetValue(static_cast<double>(vec3.y()));
@@ -452,7 +450,7 @@ void NodeParamViewWidgetBridge::UpdateWidgetValues()
}
case NodeValue::kVec4:
{
QVector4D vec4 = input_.GetValueAtTime(node_time).value<QVector4D>();
QVector4D vec4 = GetInnerInput().GetValueAtTime(node_time).value<QVector4D>();
static_cast<FloatSlider*>(widgets_.at(0))->SetValue(static_cast<double>(vec4.x()));
static_cast<FloatSlider*>(widgets_.at(1))->SetValue(static_cast<double>(vec4.y()));
@@ -463,18 +461,18 @@ void NodeParamViewWidgetBridge::UpdateWidgetValues()
case NodeValue::kFile:
{
FileField* ff = static_cast<FileField*>(widgets_.first());
ff->SetFilename(input_.GetValueAtTime(node_time).toString());
ff->SetFilename(GetInnerInput().GetValueAtTime(node_time).toString());
break;
}
case NodeValue::kColor:
{
ManagedColor mc = input_.GetValueAtTime(node_time).value<Color>();
ManagedColor mc = GetInnerInput().GetValueAtTime(node_time).value<Color>();
mc.set_color_input(input_.GetProperty("col_input").toString());
mc.set_color_input(GetInnerInput().GetProperty("col_input").toString());
QString d = input_.GetProperty("col_display").toString();
QString v = input_.GetProperty("col_view").toString();
QString l = input_.GetProperty("col_look").toString();
QString d = GetInnerInput().GetProperty("col_display").toString();
QString v = GetInnerInput().GetProperty("col_view").toString();
QString l = GetInnerInput().GetProperty("col_look").toString();
mc.set_color_output(ColorTransform(d, v, l));
@@ -484,17 +482,17 @@ void NodeParamViewWidgetBridge::UpdateWidgetValues()
case NodeValue::kText:
{
NodeParamViewTextEdit* e = static_cast<NodeParamViewTextEdit*>(widgets_.first());
e->setTextPreservingCursor(input_.GetValueAtTime(node_time).toString());
e->setTextPreservingCursor(GetInnerInput().GetValueAtTime(node_time).toString());
break;
}
case NodeValue::kBoolean:
static_cast<QCheckBox*>(widgets_.first())->setChecked(input_.GetValueAtTime(node_time).toBool());
static_cast<QCheckBox*>(widgets_.first())->setChecked(GetInnerInput().GetValueAtTime(node_time).toBool());
break;
case NodeValue::kFont:
{
QFontComboBox* fc = static_cast<QFontComboBox*>(widgets_.first());
fc->blockSignals(true);
fc->setCurrentFont(input_.GetValueAtTime(node_time).toString());
fc->setCurrentFont(GetInnerInput().GetValueAtTime(node_time).toString());
fc->blockSignals(false);
break;
}
@@ -502,7 +500,7 @@ void NodeParamViewWidgetBridge::UpdateWidgetValues()
{
QComboBox* cb = static_cast<QComboBox*>(widgets_.first());
cb->blockSignals(true);
int index = input_.GetValueAtTime(node_time).toInt();
int index = GetInnerInput().GetValueAtTime(node_time).toInt();
for (int i=0; i<cb->count(); i++) {
if (cb->itemData(i).toInt() == index) {
cb->setCurrentIndex(i);
@@ -516,19 +514,19 @@ void NodeParamViewWidgetBridge::UpdateWidgetValues()
rational NodeParamViewWidgetBridge::GetCurrentTimeAsNodeTime() const
{
return GetAdjustedTime(GetTimeTarget(), input_.node(), time_, true);
return GetAdjustedTime(GetTimeTarget(), GetInnerInput().node(), time_, true);
}
void NodeParamViewWidgetBridge::SetTimebase(const rational& timebase)
{
if (input_.GetDataType() == NodeValue::kRational) {
if (GetDataType() == NodeValue::kRational) {
static_cast<RationalSlider*>(widgets_.first())->SetTimebase(timebase);
}
}
void NodeParamViewWidgetBridge::InputValueChanged(const NodeInput &input, const TimeRange &range)
{
if (input_ == input
if (GetInnerInput() == 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
@@ -536,13 +534,9 @@ void NodeParamViewWidgetBridge::InputValueChanged(const NodeInput &input, const
}
}
void NodeParamViewWidgetBridge::PropertyChanged(const QString& input, const QString &key, const QVariant &value)
void NodeParamViewWidgetBridge::SetProperty(const QString &key, const QVariant &value)
{
if (input != input_.input() || (input_.IsArray() && input_.element() == -1)) {
return;
}
NodeValue::Type data_type = input_.GetDataType();
NodeValue::Type data_type = GetDataType();
// Parameters for all types
if (key == QStringLiteral("enabled")) {
@@ -657,35 +651,37 @@ void NodeParamViewWidgetBridge::PropertyChanged(const QString& input, const QStr
// ComboBox strings changing
if (data_type == NodeValue::kCombo) {
QComboBox* cb = static_cast<QComboBox*>(widgets_.first());
if (key == QStringLiteral("combo_str")) {
QComboBox* cb = static_cast<QComboBox*>(widgets_.first());
int old_index = cb->currentIndex();
int old_index = cb->currentIndex();
// Block the combobox changed signals since we anticipate the index will be the same and not require a re-render
cb->blockSignals(true);
// Block the combobox changed signals since we anticipate the index will be the same and not require a re-render
cb->blockSignals(true);
cb->clear();
cb->clear();
QStringList items = input_.GetComboBoxStrings();
int index = 0;
foreach (const QString& s, items) {
if (s.isEmpty()) {
cb->insertSeparator(cb->count());
cb->setItemData(cb->count()-1, -1);
} else {
cb->addItem(s, index);
index++;
QStringList items = value.toStringList();
int index = 0;
foreach (const QString& s, items) {
if (s.isEmpty()) {
cb->insertSeparator(cb->count());
cb->setItemData(cb->count()-1, -1);
} else {
cb->addItem(s, index);
index++;
}
}
}
cb->setCurrentIndex(old_index);
cb->setCurrentIndex(old_index);
cb->blockSignals(false);
cb->blockSignals(false);
// In case the amount of items is LESS and the previous index cannot be set, NOW we trigger a re-cache since the
// value has changed
if (cb->currentIndex() != old_index) {
WidgetCallback();
// In case the amount of items is LESS and the previous index cannot be set, NOW we trigger a re-cache since the
// value has changed
if (cb->currentIndex() != old_index) {
WidgetCallback();
}
}
}
@@ -742,8 +738,7 @@ void NodeParamViewWidgetBridge::PropertyChanged(const QString& input, const QStr
void NodeParamViewWidgetBridge::InputDataTypeChanged(const QString &input, NodeValue::Type type)
{
Q_UNUSED(type)
if (input == this->input_.input()) {
if (sender() == GetOuterInput().node() && input == GetOuterInput().input()) {
// Delete all widgets
qDeleteAll(widgets_);
widgets_.clear();
@@ -752,7 +747,34 @@ void NodeParamViewWidgetBridge::InputDataTypeChanged(const QString &input, NodeV
CreateWidgets();
// Signal that widgets are new
emit WidgetsRecreated(input_);
emit WidgetsRecreated(GetOuterInput());
}
}
void NodeParamViewWidgetBridge::PropertyChanged(const QString &input, const QString &key, const QVariant &value)
{
bool found = false;
for (auto it=input_hierarchy_.cbegin(); it!=input_hierarchy_.cend(); it++) {
if (it->input() == input) {
found = true;
break;
}
}
if (found) {
UpdateProperties();
}
}
void NodeParamViewWidgetBridge::UpdateProperties()
{
// Set properties from the last entry (the innermost input) to the first (the outermost)
for (auto it=input_hierarchy_.crbegin(); it!=input_hierarchy_.crend(); it++) {
auto input_properties = it->node()->GetInputProperties(it->input());
for (auto jt=input_properties.cbegin(); jt!=input_properties.cend(); jt++) {
SetProperty(jt.key(), jt.value());
}
}
}
@@ -40,7 +40,7 @@ class NodeParamViewWidgetBridge : public QObject, public TimeTargetObject
{
Q_OBJECT
public:
NodeParamViewWidgetBridge(const NodeInput& input, QObject* parent);
NodeParamViewWidgetBridge(NodeInput input, QObject* parent);
void SetTime(const rational& time);
@@ -66,6 +66,8 @@ private:
void ProcessSlider(NumericSliderBase* slider, const QVariant& value);
void SetProperty(const QString &key, const QVariant &value);
template <typename T>
void CreateSliders(int count);
@@ -73,7 +75,24 @@ private:
rational GetCurrentTimeAsNodeTime() const;
NodeInput input_;
const NodeInput &GetOuterInput() const
{
return input_hierarchy_.first();
}
const NodeInput &GetInnerInput() const
{
return input_hierarchy_.last();
}
NodeValue::Type GetDataType() const
{
return GetOuterInput().GetDataType();
}
void UpdateProperties();
QVector<NodeInput> input_hierarchy_;
QVector<QWidget*> widgets_;
@@ -88,10 +107,10 @@ private slots:
void InputValueChanged(const NodeInput& input, const TimeRange& range);
void PropertyChanged(const QString &input, const QString& key, const QVariant& value);
void InputDataTypeChanged(const QString& input, NodeValue::Type type);
void PropertyChanged(const QString &input, const QString &key, const QVariant &value);
};
}