From 3f043496f3499e6cd7c09e937932a3ea3a108ce1 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sat, 7 Mar 2020 02:16:48 +1100 Subject: [PATCH] nodeparam: allowed for dynamic nodeparam property change to affect UI widgets immediately --- app/node/distort/transform/transform.cpp | 7 + app/node/distort/transform/transform.h | 3 + app/node/input.cpp | 5 + app/node/input.h | 9 + app/node/param.cpp | 1 - app/node/param.h | 11 +- app/render/backend/opengl/openglproxy.cpp | 1 - .../nodeparamviewwidgetbridge.cpp | 184 +++++++++++++----- .../nodeparamview/nodeparamviewwidgetbridge.h | 4 +- 9 files changed, 159 insertions(+), 66 deletions(-) diff --git a/app/node/distort/transform/transform.cpp b/app/node/distort/transform/transform.cpp index 8660a38b8..b9e9c4c91 100644 --- a/app/node/distort/transform/transform.cpp +++ b/app/node/distort/transform/transform.cpp @@ -34,11 +34,13 @@ TransformDistort::TransformDistort() scale_input_ = new NodeInput("scale_in", NodeParam::kVec2, QVector2D(1.0f, 1.0f)); scale_input_->set_property("min", QVector2D(0, 0)); scale_input_->set_property("view", "percent"); + scale_input_->set_property("disabley", true); AddInput(scale_input_); uniform_scale_input_ = new NodeInput("uniform_scale_in", NodeParam::kBoolean, true); uniform_scale_input_->set_is_keyframable(false); uniform_scale_input_->SetConnectable(false); + connect(uniform_scale_input_, &NodeInput::ValueChanged, this, &TransformDistort::UniformScaleChanged); AddInput(uniform_scale_input_); anchor_input_ = new NodeInput("anchor_in", NodeParam::kVec2); @@ -105,3 +107,8 @@ NodeValueTable TransformDistort::Value(const NodeValueDatabase &value) const output.Push(NodeParam::kMatrix, mat); return output; } + +void TransformDistort::UniformScaleChanged() +{ + scale_input_->set_property("disabley", uniform_scale_input_->get_standard_value().toBool()); +} diff --git a/app/node/distort/transform/transform.h b/app/node/distort/transform/transform.h index 4a94a03ca..305fb48fa 100644 --- a/app/node/distort/transform/transform.h +++ b/app/node/distort/transform/transform.h @@ -51,6 +51,9 @@ private: NodeInput* anchor_input_; +private slots: + void UniformScaleChanged(); + }; #endif // TRANSFORMDISTORT_H diff --git a/app/node/input.cpp b/app/node/input.cpp index db7f39150..c4a5281f6 100644 --- a/app/node/input.cpp +++ b/app/node/input.cpp @@ -917,6 +917,11 @@ bool NodeInput::has_property(const QString &key) const return properties_.contains(key); } +const QHash &NodeInput::properties() const +{ + return properties_; +} + QVector NodeInput::split_normal_value_into_track_values(const QVariant &value) const { QVector vals(get_number_of_keyframe_tracks()); diff --git a/app/node/input.h b/app/node/input.h index 8b5fd3fbc..7f75f7190 100644 --- a/app/node/input.h +++ b/app/node/input.h @@ -232,6 +232,10 @@ public: * - `min` - For any numeral type represented with a slider, prevents values going BELOW this number * - `max` - For any numeral type represented with a slider, prevents values going ABOVE this number * - `view` - For any numeral type represented with a slider, shows number either as `db`, `percent`, or `normal` + * - `disablex` - For kVec2, kVec3, kVec4 and kColor types, disables the first/X/R UI widget + * - `disabley` - For kVec2, kVec3, kVec4 and kColor types, disables the second/Y/G UI widget + * - `disablez` - For kVec3, kVec4 and kColor types, disables the third/Z/B UI widget + * - `disablew` - For kVec4 and kColor types, disables the fourth/W/A UI widget */ void set_property(const QString& key, const QVariant& value); @@ -245,6 +249,11 @@ public: */ bool has_property(const QString& key) const; + /** + * @brief Get properties hashmap (useful for iterating) + */ + const QHash& properties() const; + QVector split_normal_value_into_track_values(const QVariant &value) const; QVariant combine_track_values_into_normal_value(const QVector& split) const; diff --git a/app/node/param.cpp b/app/node/param.cpp index bd63b35be..d39603ec2 100644 --- a/app/node/param.cpp +++ b/app/node/param.cpp @@ -206,7 +206,6 @@ QByteArray NodeParam::ValueToBytes(const NodeParam::DataType &type, const QVaria case kTexture: case kSamples: case kDecimal: - case kWholeNumber: case kNumber: case kString: case kBuffer: diff --git a/app/node/param.h b/app/node/param.h index dc6ac7557..719253880 100644 --- a/app/node/param.h +++ b/app/node/param.h @@ -179,19 +179,12 @@ public: */ kDecimal = 0x6, - /** - * Identifier for type that contains a whole number - * - * Includes kInt and kBoolean. - */ - kWholeNumber = 0x9, - /** * Identifier for type that contains a number of any kind (whole or decimal) * - * Includes kInt, kFloat, kRational, and kBoolean. + * Includes kInt, kFloat, and kRational. */ - kNumber = 0xF, + kNumber = 0x7, /** * Identifier for type that contains a text string of any kind. diff --git a/app/render/backend/opengl/openglproxy.cpp b/app/render/backend/opengl/openglproxy.cpp index 05c978745..2d2170da3 100644 --- a/app/render/backend/opengl/openglproxy.cpp +++ b/app/render/backend/opengl/openglproxy.cpp @@ -316,7 +316,6 @@ void OpenGLProxy::RunNodeAccelerated(const Node *node, const TimeRange &range, c case NodeInput::kFont: case NodeInput::kFile: case NodeInput::kDecimal: - case NodeInput::kWholeNumber: case NodeInput::kNumber: case NodeInput::kString: case NodeInput::kVector: diff --git a/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp b/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp index 16956262d..5e4e0559b 100644 --- a/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp +++ b/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp @@ -25,6 +25,7 @@ NodeParamViewWidgetBridge::NodeParamViewWidgetBridge(NodeInput *input, QObject * CreateWidgets(); connect(input_, &NodeInput::ValueChanged, this, &NodeParamViewWidgetBridge::InputValueChanged); + connect(input_, &NodeInput::PropertyChanged, this, &NodeParamViewWidgetBridge::PropertyChanged); } void NodeParamViewWidgetBridge::SetTime(const rational &time) @@ -45,7 +46,6 @@ void NodeParamViewWidgetBridge::SetTime(const rational &time) case NodeParam::kRational: case NodeParam::kSamples: case NodeParam::kDecimal: - case NodeParam::kWholeNumber: case NodeParam::kNumber: case NodeParam::kString: case NodeParam::kBuffer: @@ -126,7 +126,6 @@ void NodeParamViewWidgetBridge::CreateWidgets() case NodeParam::kRational: case NodeParam::kSamples: case NodeParam::kDecimal: - case NodeParam::kWholeNumber: case NodeParam::kNumber: case NodeParam::kString: case NodeParam::kBuffer: @@ -137,58 +136,26 @@ void NodeParamViewWidgetBridge::CreateWidgets() IntegerSlider* slider = new IntegerSlider(); widgets_.append(slider); connect(slider, &IntegerSlider::ValueChanged, this, &NodeParamViewWidgetBridge::WidgetCallback); - - if (input_->has_property(QStringLiteral("min"))) { - slider->SetMinimum(input_->get_property(QStringLiteral("min")).value()); - } - - if (input_->has_property(QStringLiteral("max"))) { - slider->SetMinimum(input_->get_property(QStringLiteral("max")).value()); - } break; } case NodeParam::kFloat: { - float min_flt = input_->get_property(QStringLiteral("min")).value(); - float max_flt = input_->get_property(QStringLiteral("max")).value(); - - CreateSliders(1, - input_->has_property(QStringLiteral("min")) ? &min_flt : nullptr, - input_->has_property(QStringLiteral("max")) ? &max_flt : nullptr, - input_->get_property(QStringLiteral("view")).toString()); + CreateSliders(1); break; } case NodeParam::kVec2: { - QVector2D min_vec = input_->get_property(QStringLiteral("min")).value(); - QVector2D max_vec = input_->get_property(QStringLiteral("max")).value(); - - CreateSliders(2, - input_->has_property(QStringLiteral("min")) ? reinterpret_cast(&min_vec) : nullptr, - input_->has_property(QStringLiteral("max")) ? reinterpret_cast(&max_vec) : nullptr, - input_->get_property(QStringLiteral("view")).toString()); + CreateSliders(2); break; } case NodeParam::kVec3: { - QVector3D min_vec = input_->get_property(QStringLiteral("min")).value(); - QVector3D max_vec = input_->get_property(QStringLiteral("max")).value(); - - CreateSliders(3, - input_->has_property(QStringLiteral("min")) ? reinterpret_cast(&min_vec) : nullptr, - input_->has_property(QStringLiteral("max")) ? reinterpret_cast(&max_vec) : nullptr, - input_->get_property(QStringLiteral("view")).toString()); + CreateSliders(3); break; } case NodeParam::kVec4: { - QVector4D min_vec = input_->get_property(QStringLiteral("min")).value(); - QVector4D max_vec = input_->get_property(QStringLiteral("max")).value(); - - CreateSliders(4, - input_->has_property(QStringLiteral("min")) ? reinterpret_cast(&min_vec) : nullptr, - input_->has_property(QStringLiteral("max")) ? reinterpret_cast(&max_vec) : nullptr, - input_->get_property(QStringLiteral("view")).toString()); + CreateSliders(4); break; } case NodeParam::kFile: @@ -229,6 +196,13 @@ void NodeParamViewWidgetBridge::CreateWidgets() break; } } + + // Check all properties + QHash::const_iterator iterator; + + for (iterator=input_->properties().begin();iterator!=input_->properties().end();iterator++) { + PropertyChanged(iterator.key(), iterator.value()); + } } void NodeParamViewWidgetBridge::SetInputValue(const QVariant &value, int track) @@ -345,7 +319,6 @@ void NodeParamViewWidgetBridge::WidgetCallback() case NodeParam::kSamples: case NodeParam::kRational: case NodeParam::kDecimal: - case NodeParam::kWholeNumber: case NodeParam::kNumber: case NodeParam::kString: case NodeParam::kVector: @@ -424,26 +397,12 @@ void NodeParamViewWidgetBridge::WidgetCallback() } } -void NodeParamViewWidgetBridge::CreateSliders(int count, float *min, float *max, const QString &type) +void NodeParamViewWidgetBridge::CreateSliders(int count) { for (int i=0;iSetMinimum(min[i]); - } - - if (max) { - fs->SetMaximum(max[i]); - } - - if (type == QStringLiteral("percent")) { - fs->SetDisplayType(FloatSlider::kPercentage); - } else if (type == QStringLiteral("db")) { - fs->SetDisplayType(FloatSlider::kDecibel); - } } } @@ -454,3 +413,120 @@ void NodeParamViewWidgetBridge::InputValueChanged(const rational &start, const r SetTime(time_); } } + +void NodeParamViewWidgetBridge::PropertyChanged(const QString &key, const QVariant &value) +{ + // Parameters for vectors only + if (input_->data_type() & NodeParam::kVector) { + if (key == QStringLiteral("disablex")) { + static_cast(widgets_.at(0))->setEnabled(!value.toBool()); + } else if (key == QStringLiteral("disabley")) { + static_cast(widgets_.at(1))->setEnabled(!value.toBool()); + } else if (widgets_.size() > 2 && key == QStringLiteral("disablez")) { + static_cast(widgets_.at(2))->setEnabled(!value.toBool()); + } else if (widgets_.size() > 3 && key == QStringLiteral("disablew")) { + static_cast(widgets_.at(3))->setEnabled(!value.toBool()); + } + } + + // Parameters for integers, floats, and vectors + if (input_->data_type() & NodeParam::kNumber || input_->data_type() & NodeParam::kVector) { + if (key == QStringLiteral("min")) { + switch (input_->data_type()) { + case NodeParam::kInt: + static_cast(widgets_.first())->SetMinimum(value.value()); + break; + case NodeParam::kFloat: + static_cast(widgets_.first())->SetMinimum(value.toDouble()); + break; + case NodeParam::kRational: + // FIXME: Rational doesn't have a UI implementation yet + break; + case NodeParam::kVec2: + { + QVector2D min = value.value(); + static_cast(widgets_.at(0))->SetMinimum(min.x()); + static_cast(widgets_.at(1))->SetMinimum(min.y()); + break; + } + case NodeParam::kVec3: + { + QVector3D min = value.value(); + static_cast(widgets_.at(0))->SetMinimum(min.x()); + static_cast(widgets_.at(1))->SetMinimum(min.y()); + static_cast(widgets_.at(2))->SetMinimum(min.z()); + break; + } + case NodeParam::kVec4: + { + QVector4D min = value.value(); + static_cast(widgets_.at(0))->SetMinimum(min.x()); + static_cast(widgets_.at(1))->SetMinimum(min.y()); + static_cast(widgets_.at(2))->SetMinimum(min.z()); + static_cast(widgets_.at(3))->SetMinimum(min.w()); + break; + } + default: + break; + } + } else if (key == QStringLiteral("max")) { + switch (input_->data_type()) { + case NodeParam::kInt: + static_cast(widgets_.first())->SetMaximum(value.value()); + break; + case NodeParam::kFloat: + static_cast(widgets_.first())->SetMaximum(value.toDouble()); + break; + case NodeParam::kRational: + // FIXME: Rational doesn't have a UI implementation yet + break; + case NodeParam::kVec2: + { + QVector2D max = value.value(); + static_cast(widgets_.at(0))->SetMaximum(max.x()); + static_cast(widgets_.at(1))->SetMaximum(max.y()); + break; + } + case NodeParam::kVec3: + { + QVector3D max = value.value(); + static_cast(widgets_.at(0))->SetMaximum(max.x()); + static_cast(widgets_.at(1))->SetMaximum(max.y()); + static_cast(widgets_.at(2))->SetMaximum(max.z()); + break; + } + case NodeParam::kVec4: + { + QVector4D max = value.value(); + static_cast(widgets_.at(0))->SetMaximum(max.x()); + static_cast(widgets_.at(1))->SetMaximum(max.y()); + static_cast(widgets_.at(2))->SetMaximum(max.z()); + static_cast(widgets_.at(3))->SetMaximum(max.w()); + break; + } + default: + break; + } + } + } + + // Parameters for floats and vectors only + if (input_->data_type() & NodeParam::kFloat || input_->data_type() & NodeParam::kVector) { + if (key == QStringLiteral("view")) { + FloatSlider::DisplayType display_type; + + if (value == QStringLiteral("percent")) { + display_type = FloatSlider::kPercentage; + } else if (value == QStringLiteral("db")) { + display_type = FloatSlider::kDecibel; + } else { + // Avoid undefined behavior + return; + } + + foreach (QWidget* w, widgets_) { + static_cast(w)->SetDisplayType(display_type); + } + } + } +} diff --git a/app/widget/nodeparamview/nodeparamviewwidgetbridge.h b/app/widget/nodeparamview/nodeparamviewwidgetbridge.h index d40c487ab..658910f22 100644 --- a/app/widget/nodeparamview/nodeparamviewwidgetbridge.h +++ b/app/widget/nodeparamview/nodeparamviewwidgetbridge.h @@ -23,7 +23,7 @@ private: void ProcessSlider(SliderBase* slider, const QVariant& value); - void CreateSliders(int count, float *min, float *max, const QString& type); + void CreateSliders(int count); NodeInput* input_; @@ -41,6 +41,8 @@ private slots: void InputValueChanged(const rational& start, const rational& end); + void PropertyChanged(const QString& key, const QVariant& value); + }; #endif // NODEPARAMVIEWWIDGETBRIDGE_H