ui for output rows on nodes
This commit is contained in:
@@ -128,6 +128,10 @@ Effect::Effect(Clip* c, const EffectMeta *em) :
|
||||
expanded_(true),
|
||||
texture_ctx(nullptr)
|
||||
{
|
||||
if (em != nullptr) {
|
||||
// set up UI from effect metadata
|
||||
name = em->name;
|
||||
}
|
||||
}
|
||||
|
||||
Effect::~Effect() {
|
||||
|
||||
+24
-5
@@ -37,13 +37,18 @@
|
||||
#include "ui/keyframenavigator.h"
|
||||
#include "ui/clickablelabel.h"
|
||||
|
||||
EffectRow::EffectRow(Effect *parent, const QString &id, const QString &name, bool savable, bool keyframable) :
|
||||
EffectRow::EffectRow(Effect *parent,
|
||||
const QString &id,
|
||||
const QString &name,
|
||||
bool savable,
|
||||
bool keyframable) :
|
||||
QObject(parent),
|
||||
id_(id),
|
||||
name_(name),
|
||||
keyframable_(keyframable),
|
||||
keyframing_(false),
|
||||
savable_(savable)
|
||||
savable_(savable),
|
||||
output_type_(olive::nodes::kInvalid)
|
||||
{
|
||||
Q_ASSERT(parent != nullptr);
|
||||
|
||||
@@ -62,7 +67,9 @@ void EffectRow::AddField(EffectField *field)
|
||||
|
||||
void EffectRow::AddNodeInput(olive::nodes::DataType type)
|
||||
{
|
||||
accepted_datatypes_.append(type);
|
||||
Q_ASSERT(output_type_ == olive::nodes::kInvalid);
|
||||
|
||||
accepted_inputs_.append(type);
|
||||
}
|
||||
|
||||
bool EffectRow::IsKeyframing() {
|
||||
@@ -107,9 +114,21 @@ void EffectRow::SetEnabled(bool enabled)
|
||||
}
|
||||
}
|
||||
|
||||
bool EffectRow::CanConnectNodes()
|
||||
void EffectRow::SetOutputDataType(olive::nodes::DataType type)
|
||||
{
|
||||
return !accepted_datatypes_.isEmpty();
|
||||
Q_ASSERT(accepted_inputs_.isEmpty());
|
||||
|
||||
output_type_ = type;
|
||||
}
|
||||
|
||||
bool EffectRow::IsNodeInput()
|
||||
{
|
||||
return !accepted_inputs_.isEmpty();
|
||||
}
|
||||
|
||||
bool EffectRow::IsNodeOutput()
|
||||
{
|
||||
return output_type_ != olive::nodes::kInvalid;
|
||||
}
|
||||
|
||||
void EffectRow::SetKeyframingEnabled(bool enabled) {
|
||||
|
||||
+40
-6
@@ -51,6 +51,7 @@ class ClickableLabel;
|
||||
class EffectRow : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief EffectRow Constructor
|
||||
*
|
||||
@@ -82,7 +83,11 @@ public:
|
||||
* Whether keyframing can be enabled on this row or not. This is true by default. Some values you may want to prevent
|
||||
* the user from keyframing (e.g. the filename of a VST plugin), which can be done by setting this to false.
|
||||
*/
|
||||
EffectRow(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
|
||||
EffectRow(Effect* parent,
|
||||
const QString& id,
|
||||
const QString& name,
|
||||
bool savable = true,
|
||||
bool keyframable = true);
|
||||
|
||||
/**
|
||||
* @brief Retrieve the EffectField at this index. Must be less than FieldCount().
|
||||
@@ -212,15 +217,33 @@ public:
|
||||
void SetEnabled(bool enabled);
|
||||
|
||||
/**
|
||||
* @brief Check if nodes can be connected to this input.
|
||||
* @brief Check if nodes can be connected to this as an input.
|
||||
*
|
||||
* Connecting is enabled by adding an accepted node input using AddNodeInput().
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* TRUE if nodes can be connected.
|
||||
* TRUE if nodes can be connected as an input.
|
||||
*/
|
||||
bool CanConnectNodes();
|
||||
bool IsNodeInput();
|
||||
|
||||
/**
|
||||
* @brief Check if nodes can be connected to this as an output
|
||||
*
|
||||
* Connecting is enabled by setting an output data type in SetOutputDataType().
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* TRUE if nodes can be connected as an output
|
||||
*/
|
||||
bool IsNodeOutput();
|
||||
|
||||
/**
|
||||
* @brief Set output data type
|
||||
*
|
||||
* Set the type of data this row outputs to type
|
||||
*/
|
||||
void SetOutputDataType(olive::nodes::DataType type);
|
||||
|
||||
protected:
|
||||
/**
|
||||
@@ -365,9 +388,20 @@ private:
|
||||
QVector<EffectField*> fields_;
|
||||
|
||||
/**
|
||||
* @brief Internal array of accepted node data types
|
||||
* @brief Internal array of accepted node data types.
|
||||
*
|
||||
* Is mutally-exclusive with accepted_outputs_, i.e. you cannot have values added to this and also a value set in
|
||||
* accepted_outputs_.
|
||||
*/
|
||||
QVector<olive::nodes::DataType> accepted_datatypes_;
|
||||
QVector<olive::nodes::DataType> accepted_inputs_;
|
||||
|
||||
/**
|
||||
* @brief Internal value for what kind of data this row outputs
|
||||
*
|
||||
* Is mutally-exclusive with accepted_inputs_, i.e. you cannot have values added to it and also a value set in
|
||||
* this.
|
||||
*/
|
||||
olive::nodes::DataType output_type_;
|
||||
};
|
||||
|
||||
#endif // EFFECTROW_H
|
||||
|
||||
@@ -67,6 +67,10 @@ TransformEffect::TransformEffect(Clip* c, const EffectMeta* em) : Effect(c, em)
|
||||
opacity->SetMaximum(100);
|
||||
opacity->SetDefault(100);
|
||||
|
||||
// TEMP - Create matrix output
|
||||
EffectRow* matrix_output = new EffectRow(this, "matrix", "Matrix", false, false);
|
||||
matrix_output->SetOutputDataType(olive::nodes::kMatrix);
|
||||
|
||||
// set up gizmos
|
||||
top_left_gizmo = add_gizmo(GIZMO_TYPE_DOT);
|
||||
top_left_gizmo->set_cursor(Qt::SizeFDiagCursor);
|
||||
|
||||
+154
-159
@@ -3,189 +3,184 @@
|
||||
NodeShader::NodeShader(Clip* c, const EffectMeta *em) :
|
||||
Effect(c, em)
|
||||
{
|
||||
if (em != nullptr) {
|
||||
// set up UI from effect file
|
||||
name = em->name;
|
||||
if (em != nullptr && !em->filename.isEmpty() && em->internal == -1) {
|
||||
QFile effect_file(em->filename);
|
||||
if (effect_file.open(QFile::ReadOnly)) {
|
||||
QXmlStreamReader reader(&effect_file);
|
||||
|
||||
if (!em->filename.isEmpty() && em->internal == -1) {
|
||||
QFile effect_file(em->filename);
|
||||
if (effect_file.open(QFile::ReadOnly)) {
|
||||
QXmlStreamReader reader(&effect_file);
|
||||
while (!reader.atEnd()) {
|
||||
if (reader.name() == "field" && reader.isStartElement()) {
|
||||
int type = olive::nodes::kInvalid;
|
||||
QString id;
|
||||
QString name;
|
||||
|
||||
while (!reader.atEnd()) {
|
||||
if (reader.name() == "field" && reader.isStartElement()) {
|
||||
int type = olive::nodes::kInvalid;
|
||||
QString id;
|
||||
QString name;
|
||||
|
||||
// get field type
|
||||
const QXmlStreamAttributes& attributes = reader.attributes();
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "type") {
|
||||
QString comp = attr.value().toString().toUpper();
|
||||
type = olive::nodes::StringToDataType(comp);
|
||||
} else if (attr.name() == "id") {
|
||||
id = attr.value().toString();
|
||||
} else if (attr.name() == "name") {
|
||||
name = attr.value().toString();
|
||||
}
|
||||
// get field type
|
||||
const QXmlStreamAttributes& attributes = reader.attributes();
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "type") {
|
||||
QString comp = attr.value().toString().toUpper();
|
||||
type = olive::nodes::StringToDataType(comp);
|
||||
} else if (attr.name() == "id") {
|
||||
id = attr.value().toString();
|
||||
} else if (attr.name() == "name") {
|
||||
name = attr.value().toString();
|
||||
}
|
||||
}
|
||||
|
||||
if (id.isEmpty() || name.isEmpty() || type == olive::nodes::kInvalid) {
|
||||
qCritical() << "Couldn't load field from" << em->filename << "- ID, type, and name cannot be empty.";
|
||||
} else {
|
||||
EffectRow* field = nullptr;
|
||||
if (id.isEmpty() || name.isEmpty() || type == olive::nodes::kInvalid) {
|
||||
qCritical() << "Couldn't load field from" << em->filename << "- ID, type, and name cannot be empty.";
|
||||
} else {
|
||||
EffectRow* field = nullptr;
|
||||
|
||||
switch (type) {
|
||||
case olive::nodes::kFloat:
|
||||
{
|
||||
switch (type) {
|
||||
case olive::nodes::kFloat:
|
||||
{
|
||||
|
||||
DoubleInput* double_field = new DoubleInput(this, id, name);
|
||||
DoubleInput* double_field = new DoubleInput(this, id, name);
|
||||
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "default") {
|
||||
double_field->SetDefault(attr.value().toDouble());
|
||||
} else if (attr.name() == "min") {
|
||||
double_field->SetMinimum(attr.value().toDouble());
|
||||
} else if (attr.name() == "max") {
|
||||
double_field->SetMaximum(attr.value().toDouble());
|
||||
}
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "default") {
|
||||
double_field->SetDefault(attr.value().toDouble());
|
||||
} else if (attr.name() == "min") {
|
||||
double_field->SetMinimum(attr.value().toDouble());
|
||||
} else if (attr.name() == "max") {
|
||||
double_field->SetMaximum(attr.value().toDouble());
|
||||
}
|
||||
|
||||
field = double_field;
|
||||
}
|
||||
break;
|
||||
case olive::nodes::kColor:
|
||||
{
|
||||
QColor color;
|
||||
|
||||
field = new ColorInput(this, id, name);
|
||||
field = double_field;
|
||||
}
|
||||
break;
|
||||
case olive::nodes::kColor:
|
||||
{
|
||||
QColor color;
|
||||
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "r") {
|
||||
color.setRed(attr.value().toInt());
|
||||
} else if (attr.name() == "g") {
|
||||
color.setGreen(attr.value().toInt());
|
||||
} else if (attr.name() == "b") {
|
||||
color.setBlue(attr.value().toInt());
|
||||
} else if (attr.name() == "rf") {
|
||||
color.setRedF(attr.value().toDouble());
|
||||
} else if (attr.name() == "gf") {
|
||||
color.setGreenF(attr.value().toDouble());
|
||||
} else if (attr.name() == "bf") {
|
||||
color.setBlueF(attr.value().toDouble());
|
||||
} else if (attr.name() == "hex") {
|
||||
color.setNamedColor(attr.value().toString());
|
||||
}
|
||||
field = new ColorInput(this, id, name);
|
||||
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "r") {
|
||||
color.setRed(attr.value().toInt());
|
||||
} else if (attr.name() == "g") {
|
||||
color.setGreen(attr.value().toInt());
|
||||
} else if (attr.name() == "b") {
|
||||
color.setBlue(attr.value().toInt());
|
||||
} else if (attr.name() == "rf") {
|
||||
color.setRedF(attr.value().toDouble());
|
||||
} else if (attr.name() == "gf") {
|
||||
color.setGreenF(attr.value().toDouble());
|
||||
} else if (attr.name() == "bf") {
|
||||
color.setBlueF(attr.value().toDouble());
|
||||
} else if (attr.name() == "hex") {
|
||||
color.setNamedColor(attr.value().toString());
|
||||
}
|
||||
|
||||
field->SetValueAt(0, color);
|
||||
}
|
||||
break;
|
||||
case olive::nodes::kString:
|
||||
field = new StringInput(this, id, name);
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "default") {
|
||||
field->SetValueAt(0, attr.value().toString());
|
||||
}
|
||||
|
||||
field->SetValueAt(0, color);
|
||||
}
|
||||
break;
|
||||
case olive::nodes::kString:
|
||||
field = new StringInput(this, id, name);
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "default") {
|
||||
field->SetValueAt(0, attr.value().toString());
|
||||
}
|
||||
break;
|
||||
case olive::nodes::kBoolean:
|
||||
field = new BoolInput(this, id, name);
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "default") {
|
||||
field->SetValueAt(0, attr.value() == "1");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case olive::nodes::kBoolean:
|
||||
field = new BoolInput(this, id, name);
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "default") {
|
||||
field->SetValueAt(0, attr.value() == "1");
|
||||
}
|
||||
break;
|
||||
case olive::nodes::kCombo:
|
||||
{
|
||||
ComboInput* combo_field = new ComboInput(this, id, name);
|
||||
int combo_default_index = 0;
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "default") {
|
||||
combo_default_index = attr.value().toInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case olive::nodes::kCombo:
|
||||
{
|
||||
ComboInput* combo_field = new ComboInput(this, id, name);
|
||||
int combo_default_index = 0;
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "default") {
|
||||
combo_default_index = attr.value().toInt();
|
||||
break;
|
||||
}
|
||||
int combo_item_count = 0;
|
||||
while (!reader.atEnd() && !(reader.name() == "field" && reader.isEndElement())) {
|
||||
}
|
||||
int combo_item_count = 0;
|
||||
while (!reader.atEnd() && !(reader.name() == "field" && reader.isEndElement())) {
|
||||
reader.readNext();
|
||||
if (reader.name() == "option" && reader.isStartElement()) {
|
||||
reader.readNext();
|
||||
if (reader.name() == "option" && reader.isStartElement()) {
|
||||
reader.readNext();
|
||||
combo_field->AddItem(reader.text().toString(), combo_item_count);
|
||||
combo_item_count++;
|
||||
}
|
||||
combo_field->AddItem(reader.text().toString(), combo_item_count);
|
||||
combo_item_count++;
|
||||
}
|
||||
combo_field->SetValueAt(0, combo_default_index);
|
||||
field = combo_field;
|
||||
}
|
||||
break;
|
||||
case olive::nodes::kFont:
|
||||
field = new FontInput(this, id, name);
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "default") {
|
||||
field->SetValueAt(0, attr.value().toString());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case olive::nodes::kFile:
|
||||
field = new FileInput(this, id, name);
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "filename") {
|
||||
field->SetValueAt(0, attr.value().toString());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
combo_field->SetValueAt(0, combo_default_index);
|
||||
field = combo_field;
|
||||
}
|
||||
} else if (reader.name() == "shader" && reader.isStartElement()) {
|
||||
SetFlags(Flags() | ShaderFlag);
|
||||
const QXmlStreamAttributes& attributes = reader.attributes();
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "vert") {
|
||||
shader_vert_path_ = attr.value().toString();
|
||||
} else if (attr.name() == "frag") {
|
||||
shader_frag_path_ = attr.value().toString();
|
||||
} else if (attr.name() == "iterations") {
|
||||
setIterations(attr.value().toInt());
|
||||
} else if (attr.name() == "function") {
|
||||
shader_function_name_ = attr.value().toString();
|
||||
}
|
||||
}
|
||||
}/* else if (reader.name() == "superimpose" && reader.isStartElement()) {
|
||||
enable_superimpose = true;
|
||||
const QXmlStreamAttributes& attributes = reader.attributes();
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "script") {
|
||||
QFile script_file(get_effects_dir() + "/" + attr.value().toString());
|
||||
if (script_file.open(QFile::ReadOnly)) {
|
||||
script = script_file.readAll();
|
||||
} else {
|
||||
qCritical() << "Failed to open superimpose script file for" << em->filename;
|
||||
enable_superimpose = false;
|
||||
break;
|
||||
case olive::nodes::kFont:
|
||||
field = new FontInput(this, id, name);
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "default") {
|
||||
field->SetValueAt(0, attr.value().toString());
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case olive::nodes::kFile:
|
||||
field = new FileInput(this, id, name);
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "filename") {
|
||||
field->SetValueAt(0, attr.value().toString());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
reader.readNext();
|
||||
}
|
||||
|
||||
effect_file.close();
|
||||
} else {
|
||||
qCritical() << "Failed to open effect file" << em->filename;
|
||||
}
|
||||
} else if (reader.name() == "shader" && reader.isStartElement()) {
|
||||
SetFlags(Flags() | ShaderFlag);
|
||||
const QXmlStreamAttributes& attributes = reader.attributes();
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "vert") {
|
||||
shader_vert_path_ = attr.value().toString();
|
||||
} else if (attr.name() == "frag") {
|
||||
shader_frag_path_ = attr.value().toString();
|
||||
} else if (attr.name() == "iterations") {
|
||||
setIterations(attr.value().toInt());
|
||||
} else if (attr.name() == "function") {
|
||||
shader_function_name_ = attr.value().toString();
|
||||
}
|
||||
}
|
||||
}/* else if (reader.name() == "superimpose" && reader.isStartElement()) {
|
||||
enable_superimpose = true;
|
||||
const QXmlStreamAttributes& attributes = reader.attributes();
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "script") {
|
||||
QFile script_file(get_effects_dir() + "/" + attr.value().toString());
|
||||
if (script_file.open(QFile::ReadOnly)) {
|
||||
script = script_file.readAll();
|
||||
} else {
|
||||
qCritical() << "Failed to open superimpose script file for" << em->filename;
|
||||
enable_superimpose = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
reader.readNext();
|
||||
}
|
||||
|
||||
effect_file.close();
|
||||
} else {
|
||||
qCritical() << "Failed to open effect file" << em->filename;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+38
-29
@@ -115,41 +115,50 @@ EffectUI::EffectUI(Effect* e) :
|
||||
|
||||
labels_.append(row_label);
|
||||
|
||||
layout_->addWidget(row_label, i, 0);
|
||||
if (row->IsNodeOutput()) {
|
||||
|
||||
widgets_[i].resize(row->FieldCount());
|
||||
|
||||
QGridLayout* field_layout = new QGridLayout();
|
||||
for (int j=0;j<row->FieldCount();j++) {
|
||||
EffectField* field = row->Field(j);
|
||||
|
||||
QWidget* widget = field->CreateWidget();
|
||||
|
||||
widgets_[i][j] = widget;
|
||||
|
||||
field_layout->addWidget(widget, 0, j);
|
||||
}
|
||||
layout_->addLayout(field_layout, i, 1);
|
||||
|
||||
KeyframeNavigator* nav;
|
||||
|
||||
if (row->IsKeyframable()) {
|
||||
|
||||
nav = new KeyframeNavigator();
|
||||
|
||||
nav->enable_keyframes(row->IsKeyframing());
|
||||
|
||||
AttachKeyframeNavigationToRow(row, nav);
|
||||
|
||||
layout_->addWidget(nav, i, 2);
|
||||
row_label->setAlignment(Qt::AlignRight);
|
||||
layout_->addWidget(row_label, i, 2);
|
||||
|
||||
} else {
|
||||
|
||||
nav = nullptr;
|
||||
layout_->addWidget(row_label, i, 0);
|
||||
|
||||
widgets_[i].resize(row->FieldCount());
|
||||
|
||||
QGridLayout* field_layout = new QGridLayout();
|
||||
for (int j=0;j<row->FieldCount();j++) {
|
||||
EffectField* field = row->Field(j);
|
||||
|
||||
QWidget* widget = field->CreateWidget();
|
||||
|
||||
widgets_[i][j] = widget;
|
||||
|
||||
field_layout->addWidget(widget, 0, j);
|
||||
}
|
||||
layout_->addLayout(field_layout, i, 1);
|
||||
|
||||
KeyframeNavigator* nav;
|
||||
|
||||
if (row->IsKeyframable()) {
|
||||
|
||||
nav = new KeyframeNavigator();
|
||||
|
||||
nav->enable_keyframes(row->IsKeyframing());
|
||||
|
||||
AttachKeyframeNavigationToRow(row, nav);
|
||||
|
||||
layout_->addWidget(nav, i, 2);
|
||||
|
||||
} else {
|
||||
|
||||
nav = nullptr;
|
||||
|
||||
}
|
||||
|
||||
keyframe_navigators_[i] = nav;
|
||||
|
||||
}
|
||||
|
||||
keyframe_navigators_[i] = nav;
|
||||
}
|
||||
|
||||
enabled_check->setChecked(e->IsEnabled());
|
||||
|
||||
+7
-6
@@ -14,7 +14,7 @@
|
||||
#include "ui/effectui.h"
|
||||
|
||||
const int kRoundedRectRadius = 5;
|
||||
const int kNodePlugSize = 6;
|
||||
const int kNodePlugSize = 10;
|
||||
|
||||
NodeUI::NodeUI() :
|
||||
central_widget_(nullptr)
|
||||
@@ -117,15 +117,16 @@ QVector<QRectF> NodeUI::GetNodeSocketRects()
|
||||
Effect* e = central_widget_->GetEffect();
|
||||
|
||||
for (int i=0;i<e->row_count();i++) {
|
||||
if (e->row(i)->CanConnectNodes()) {
|
||||
int y = central_widget_->GetRowY(i);
|
||||
|
||||
rects.append(QRectF(rect().x(),
|
||||
EffectRow* row = e->row(i);
|
||||
qreal x = (row->IsNodeOutput()) ? rect().right() - kNodePlugSize : rect().x();
|
||||
int y = central_widget_->GetRowY(i);
|
||||
|
||||
if (row->IsNodeInput() || row->IsNodeOutput()) {
|
||||
rects.append(QRectF(x,
|
||||
proxy_->pos().y() + y - kNodePlugSize/2,
|
||||
kNodePlugSize,
|
||||
kNodePlugSize));
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user