finished moving field data retrieving to row

This commit is contained in:
itsmattkc
2019-04-11 00:02:50 +10:00
parent 14ae903000
commit d3bc1d4f06
78 changed files with 1189 additions and 676 deletions
-2
View File
@@ -270,8 +270,6 @@ void NewSequenceDialog::setup_ui() {
videoLayout->addWidget(new QLabel(tr("Interlacing:"), this), 6, 0, 1, 1);
interlacing_combobox = new QComboBox(videoGroupBox);
interlacing_combobox->addItem(tr("None (Progressive)"));
// interlacing_combobox->addItem("Upper Field First");
// interlacing_combobox->addItem("Lower Field First");
videoLayout->addWidget(interlacing_combobox, 6, 2, 1, 2);
verticalLayout->addWidget(videoGroupBox);
+155 -152
View File
@@ -53,6 +53,7 @@
#include "transition.h"
#include "undo/undostack.h"
#include "rendering/shadergenerators.h"
#include "global/timing.h"
#include "effects/internal/transformeffect.h"
#include "effects/internal/texteffect.h"
@@ -136,153 +137,138 @@ Effect::Effect(Clip* c, const EffectMeta *em) :
QXmlStreamReader reader(&effect_file);
while (!reader.atEnd()) {
if (reader.name() == "row" && reader.isStartElement()) {
QString row_name;
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() == "name") {
row_name = attr.value().toString();
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 (!row_name.isEmpty()) {
EffectRow* row = new EffectRow(this, row_name);
while (!reader.atEnd() && !(reader.name() == "row" && reader.isEndElement())) {
reader.readNext();
if (reader.name() == "field" && reader.isStartElement()) {
int type = -1;
QString id;
// 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();
}
}
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()) {
qCritical() << "Couldn't load field from" << em->filename << "- ID cannot be empty.";
} else if (type == olive::nodes::kInvalid) {
qWarning() << "Invalid field type found";
} else {
EffectField* field = nullptr;
switch (type) {
case olive::nodes::kFloat:
{
switch (type) {
case olive::nodes::kFloat:
{
DoubleInput* double_field = new DoubleInput(this, id, name);
DoubleField* double_field = new DoubleField(row, id);
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 ColorField(row, id);
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 StringField(row, id);
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 BoolField(row, id);
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:
{
ComboField* combo_field = new ComboField(row, id);
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())) {
reader.readNext();
if (reader.name() == "option" && reader.isStartElement()) {
reader.readNext();
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 FontField(row, id);
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 FileField(row, id);
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;
}
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);
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());
}
}
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;
}
}
int combo_item_count = 0;
while (!reader.atEnd() && !(reader.name() == "field" && reader.isEndElement())) {
reader.readNext();
if (reader.name() == "option" && reader.isStartElement()) {
reader.readNext();
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;
}
}
} else if (reader.name() == "shader" && reader.isStartElement()) {
@@ -515,6 +501,7 @@ void Effect::SetEnabled(bool b) {
}
void Effect::load(QXmlStreamReader& stream) {
/*
int row_count = 0;
QString tag = stream.name().toString();
@@ -602,11 +589,13 @@ void Effect::load(QXmlStreamReader& stream) {
custom_load(stream);
}
}
*/
}
void Effect::custom_load(QXmlStreamReader &) {}
void Effect::save(QXmlStreamWriter& stream) {
/*
stream.writeAttribute("name", meta->category + "/" + meta->name);
stream.writeAttribute("enabled", QString::number(IsEnabled()));
@@ -639,6 +628,7 @@ void Effect::save(QXmlStreamWriter& stream) {
stream.writeEndElement(); // row
}
}
*/
}
void Effect::load_from_string(const QByteArray &s) {
@@ -840,6 +830,7 @@ EffectPtr Effect::copy(Clip *c) {
}
void Effect::process_shader(double timecode, GLTextureCoords&, int iteration) {
/*
shader_program_->bind();
shader_program_->setUniformValue("resolution", parent_clip->media_width(), parent_clip->media_height());
@@ -848,20 +839,21 @@ void Effect::process_shader(double timecode, GLTextureCoords&, int iteration) {
for (int i=0;i<rows.size();i++) {
EffectRow* row = rows.at(i);
for (int j=0;j<row->FieldCount();j++) {
EffectField* field = row->Field(j);
if (!field->id().isEmpty()) {
switch (field->type()) {
case EFFECT_FIELD_DOUBLE:
case EffectField::EFFECT_FIELD_DOUBLE:
{
DoubleField* double_field = static_cast<DoubleField*>(field);
shader_program_->setUniformValue(double_field->id().toUtf8().constData(),
GLfloat(double_field->GetDoubleAt(timecode)));
}
break;
case EFFECT_FIELD_COLOR:
case EffectField::EFFECT_FIELD_COLOR:
{
ColorField* color_field = static_cast<ColorField*>(field);
ColorField* color_field = static_cast<ColorField *>(field);
shader_program_->setUniformValue(
color_field->id().toUtf8().constData(),
GLfloat(color_field->GetColorAt(timecode).redF()),
@@ -870,18 +862,18 @@ void Effect::process_shader(double timecode, GLTextureCoords&, int iteration) {
);
}
break;
case EFFECT_FIELD_BOOL:
case EffectField::EFFECT_FIELD_BOOL:
shader_program_->setUniformValue(field->id().toUtf8().constData(), field->GetValueAt(timecode).toBool());
break;
case EFFECT_FIELD_COMBO:
case EffectField::EFFECT_FIELD_COMBO:
shader_program_->setUniformValue(field->id().toUtf8().constData(), field->GetValueAt(timecode).toInt());
break;
// can you even send a string to a uniform value?
case EFFECT_FIELD_STRING:
case EFFECT_FIELD_FONT:
case EFFECT_FIELD_FILE:
case EFFECT_FIELD_UI:
case EffectField::EFFECT_FIELD_STRING:
case EffectField::EFFECT_FIELD_FONT:
case EffectField::EFFECT_FIELD_FILE:
case EffectField::EFFECT_FIELD_UI:
break;
}
}
@@ -889,6 +881,7 @@ void Effect::process_shader(double timecode, GLTextureCoords&, int iteration) {
}
shader_program_->release();
*/
}
void Effect::process_coords(double, GLTextureCoords&, int) {}
@@ -929,7 +922,7 @@ GLuint Effect::process_superimpose(QOpenGLContext* ctx, double timecode) {
f->glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA8, tex_width_, tex_height_, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.constBits()
);
);
f->glBindTexture(GL_TEXTURE_2D, 0);
@@ -1045,6 +1038,16 @@ bool Effect::are_gizmos_enabled() {
return (gizmos.size() > 0);
}
double Effect::Now()
{
return playhead_to_clip_seconds(parent_clip, parent_clip->track()->sequence()->playhead);
}
long Effect::NowInFrames()
{
return playhead_to_clip_frame(parent_clip, parent_clip->track()->sequence()->playhead);
}
void Effect::redraw(double) {
/*
// run javascript
@@ -1062,22 +1065,22 @@ void Effect::redraw(double) {
EffectField* field = row->field(j);
if (!field->id.isEmpty()) {
switch (field->type) {
case EFFECT_FIELD_DOUBLE:
case EffectField::EFFECT_FIELD_DOUBLE:
jsEngine.globalObject().setProperty(field->id, field->get_double_value(timecode));
break;
case EFFECT_FIELD_COLOR:
case EffectField::EFFECT_FIELD_COLOR:
jsEngine.globalObject().setProperty(field->id, field->get_color_value(timecode).name());
break;
case EFFECT_FIELD_STRING:
case EffectField::EFFECT_FIELD_STRING:
jsEngine.globalObject().setProperty(field->id, field->get_string_value(timecode));
break;
case EFFECT_FIELD_BOOL:
case EffectField::EFFECT_FIELD_BOOL:
jsEngine.globalObject().setProperty(field->id, field->get_bool_value(timecode));
break;
case EFFECT_FIELD_COMBO:
case EffectField::EFFECT_FIELD_COMBO:
jsEngine.globalObject().setProperty(field->id, field->get_combo_index(timecode));
break;
case EFFECT_FIELD_FONT:
case EffectField::EFFECT_FIELD_FONT:
jsEngine.globalObject().setProperty(field->id, field->get_font_name(timecode));
break;
}
+25
View File
@@ -44,6 +44,7 @@
#include "effectrow.h"
#include "effectgizmo.h"
#include "rendering/qopenglshaderprogramptr.h"
#include "nodes/inputs.h"
class Clip;
@@ -192,6 +193,30 @@ public:
void gizmo_world_to_screen(const QMatrix4x4 &matrix, const QMatrix4x4 &projection);
bool are_gizmos_enabled();
/**
* @brief Get the current clip/media time
*
* A convenience function that can be plugged into GetValueAt() to get the value wherever the appropriate Sequence's
* playhead it.
*
* @return
*
* Current clip/media time in seconds.
*/
double Now();
/**
* @brief Retrieve the current clip as a frame number
*
* Same as Now() but retrieves the value as a frame number (in the appropriate Sequence's frame rate) instead of
* seconds.
*
* @return
*
* The current clip time in frames
*/
long NowInFrames();
template <typename T>
T randomNumber()
{
+3 -37
View File
@@ -37,16 +37,10 @@
EffectField::EffectField(EffectRow* parent, EffectFieldType t) :
QObject(parent),
type_(t),
id_(i),
enabled_(true),
colspan_(1)
enabled_(true)
{
// EffectField MUST be created with a parent.
Q_ASSERT(parent != nullptr);
Q_ASSERT(!i.isEmpty() || t == EFFECT_FIELD_UI);
// Add this field to the parent row specified
parent->AddField(this);
// Set a very base default value
SetValueAt(0, 0);
@@ -60,17 +54,6 @@ EffectRow *EffectField::GetParentRow()
return static_cast<EffectRow*>(parent());
}
int EffectField::GetColumnSpan()
{
return colspan_;
}
void EffectField::SetColumnSpan(int i)
{
Q_ASSERT(i >= 1);
colspan_ = i;
}
QVariant EffectField::ConvertStringToValue(const QString &s)
{
return s;
@@ -232,18 +215,6 @@ void EffectField::SetValueAt(double time, const QVariant &value)
emit Changed();
}
double EffectField::Now()
{
Clip* c = GetParentRow()->GetParentEffect()->parent_clip;
return playhead_to_clip_seconds(c, c->track()->sequence()->playhead);
}
long EffectField::NowInFrames()
{
Clip* c = GetParentRow()->GetParentEffect()->parent_clip;
return playhead_to_clip_frame(c, c->track()->sequence()->playhead);
}
void EffectField::PrepareDataForKeyframing(bool enabled, ComboAction *ca)
{
if (enabled) {
@@ -251,7 +222,7 @@ void EffectField::PrepareDataForKeyframing(bool enabled, ComboAction *ca)
// Create keyframe from perpetual data
EffectKeyframe key;
key.time = NowInFrames();
key.time = GetParentRow()->GetParentEffect()->NowInFrames();
key.data = persistent_data_;
key.type = EFFECT_KEYFRAME_LINEAR;
@@ -264,7 +235,7 @@ void EffectField::PrepareDataForKeyframing(bool enabled, ComboAction *ca)
// Convert keyframes to one "perpetual" keyframe
// Set first keyframe to whatever the data is now
ca->append(new SetQVariant(&persistent_data_, persistent_data_, GetValueAt(Now())));
ca->append(new SetQVariant(&persistent_data_, persistent_data_, GetValueAt(GetParentRow()->GetParentEffect()->Now())));
// Delete all keyframes
for (int i=0;i<keyframes.size();i++) {
@@ -279,11 +250,6 @@ const EffectField::EffectFieldType &EffectField::type()
return type_;
}
const QString &EffectField::id()
{
return id_;
}
double EffectField::GetValidKeyframeHandlePosition(int key, bool post) {
int comp_key = -1;
-62
View File
@@ -129,15 +129,6 @@ public:
*/
const EffectFieldType& type();
/**
* @brief Get the unique identifier of this field set in the constructor
*
* Mostly used for saving/loading or interacting with GLSL-based shader effects (see EffectField() for more details).
*
* @return
*/
const QString& id();
/**
* @brief Get the value of this field at a given timecode
*
@@ -188,18 +179,6 @@ public:
*/
void SetValueAt(double time, const QVariant& value);
/**
* @brief Get the current clip/media time
*
* A convenience function that can be plugged into GetValueAt() to get the value wherever the appropriate Sequence's
* playhead it.
*
* @return
*
* Current clip/media time in seconds.
*/
double Now();
/**
* @brief Set up keyframing on this field
*
@@ -223,30 +202,6 @@ public:
*/
void PrepareDataForKeyframing(bool enabled, ComboAction* ca);
/**
* @brief Get field's column span
*
* Used whenever constructing the effect's UI. EffectFields are visually laid out in a table, and some widgets can
* be set to take up multiple columns for a better visual flow.
*
* @return
*
* The current column span.
*/
int GetColumnSpan();
/**
* @brief Set field's column span
*
* Used whenever constructing the effect's UI. EffectFields are visually laid out in a table, and some widgets can
* be set to take up multiple columns for a better visual flow.
*
* @param i
*
* The column span to set on this field.
*/
void SetColumnSpan(int i);
/**
* @brief Convert a value from this field to a string
*
@@ -482,28 +437,11 @@ private:
*/
void GetKeyframeData(double timecode, int& before, int& after, double& d);
/**
* @brief Retrieve the current clip as a frame number
*
* Same as Now() but retrieves the value as a frame number (in the appropriate Sequence's frame rate) instead of
* seconds.
*
* @return
*
* The current clip time in frames
*/
long NowInFrames();
/**
* @brief Internal enabled value
*/
bool enabled_;
/**
* @brief Internal column span value
*/
int colspan_;
};
#endif // EFFECTFIELD_H
+26 -1
View File
@@ -53,6 +53,10 @@ EffectRow::EffectRow(Effect *parent, const QString &id, const QString &name, boo
void EffectRow::AddField(EffectField *field)
{
field->setParent(this);
connect(field, SIGNAL(Clicked()), this, SIGNAL(Clicked()));
connect(field, SIGNAL(Changed()), this, SIGNAL(Changed()));
fields_.append(field);
}
@@ -77,6 +81,27 @@ bool EffectRow::IsKeyframable()
return keyframable_;
}
QVariant EffectRow::GetValueAt(double timecode)
{
Q_ASSERT(FieldCount() == 1);
return Field(0)->GetValueAt(timecode);
}
void EffectRow::SetValueAt(double timecode, const QVariant &value)
{
Q_ASSERT(FieldCount() == 1);
Field(0)->SetValueAt(timecode, value);
}
void EffectRow::SetEnabled(bool enabled)
{
for (int i=0;i<FieldCount();i++) {
Field(i)->SetEnabled(enabled);
}
}
void EffectRow::SetKeyframingEnabled(bool enabled) {
if (enabled == keyframing_) {
return;
@@ -252,7 +277,7 @@ void EffectRow::SetKeyframeOnAllFields(ComboAction* ca) {
KeyframeDataChange* kdc = new KeyframeDataChange(field);
field->SetValueAt(field->Now(), field->GetValueAt(field->Now()));
field->SetValueAt(GetParentEffect()->Now(), field->GetValueAt(GetParentEffect()->Now()));
kdc->SetNewKeyframes();
ca->append(kdc);
+82 -11
View File
@@ -130,6 +130,15 @@ public:
*/
const QString& name();
/**
* @brief Get the unique identifier of this field set in the constructor
*
* Mostly used for saving/loading or interacting with GLSL-based shader effects (see EffectField() for more details).
*
* @return
*/
const QString& id();
/**
* @brief Get whether this row is keyframing or not
*
@@ -158,6 +167,63 @@ public:
* @return True if this row can be keyframed. This value is set in the constructor.
*/
bool IsKeyframable();
/**
* @brief Get value at a given timecode
*
* Functions as a wrapper for EffectField::GetValueAt().
*
* The default function is to return the result of the first EffectField on this EffectRow which should be sufficient
* for most input types. If this EffectRow has more or less than one EffectField, you must override this function in a
* derived class to provide the correct field <-> row coordination or else it will trigger an abort.
*
* @param timecode
*
* Timecode to get the value at
*
* @return
*
* The value of the first EffectField at the given timecode
*/
virtual QVariant GetValueAt(double timecode);
/**
* @brief SetValueAt
*
* Functions as a wrapper for EffectField::SetValueAt().
*
* The default function is to call the function of the first EffectField on this EffectRow which should be sufficient
* for most input types. If this EffectRow has more or less than one EffectField, you must override this function in a
* derived class to provide the correct field <-> row coordination or else it will trigger an abort.
*
* @param timecode
*
* Timecode to set the value at
*
* @param value
*
* Value to set at this timecode
*/
virtual void SetValueAt(double timecode, const QVariant& value);
/**
* @brief Sets the enabled state on all EffectField objects on this row to enabled
*/
void SetEnabled(bool enabled);
protected:
/**
* @brief Add a field to this row
*
* Ownership of the EffectField is transferred to this row and the row will free its memory. In the Effect's UI, this
* will add the field to an additional column.
*
* @param Field
*
* The field to add to this row.
*/
void AddField(EffectField* Field);
public slots:
/**
* @brief Go to previous keyframe
@@ -194,6 +260,7 @@ public slots:
*/
void FocusRow();
signals:
/**
* @brief Keyframing setting changed signal
*
@@ -204,6 +271,21 @@ signals:
* True if keyframing was enabled, false if keyframing was disabled.
*/
void KeyframingSetChanged(bool);
/**
* @brief Changed signal
*
* Wrapper for EffectField::Changed().
*/
void Changed();
/**
* @brief Clicked signal
*
* Wrapper for EffectField::Clicked().
*/
void Clicked();
private slots:
/**
* @brief Set keyframing enabled state
@@ -217,17 +299,6 @@ private slots:
*/
void SetKeyframingEnabled(bool);
private:
/**
* @brief Add a field to this row
*
* Ownership of the EffectField is transferred to this row and the row will free its memory. In the Effect's UI, this
* will add the field to an additional column.
*
* @param Field
*
* The field to add to this row.
*/
void AddField(EffectField* Field);
/**
* @brief Internal unique identifier for this field set in the constructor. Access with id().
+3 -1
View File
@@ -22,6 +22,8 @@
#include <QCheckBox>
#include "effects/effect.h"
BoolField::BoolField(EffectRow *parent) :
EffectField(parent, EffectField::EFFECT_FIELD_BOOL)
{}
@@ -89,7 +91,7 @@ void BoolField::UpdateFromWidget(bool b)
{
KeyframeDataChange* kdc = new KeyframeDataChange(this);
SetValueAt(Now(), b);
SetValueAt(GetParentRow()->GetParentEffect()->Now(), b);
kdc->SetNewKeyframes();
olive::undo_stack.push(kdc);
+1 -1
View File
@@ -22,7 +22,7 @@
#include <QPushButton>
ButtonField::ButtonField(EffectRow *parent) :
ButtonField::ButtonField(EffectRow *parent, const QString &string) :
EffectField(parent, EffectField::EFFECT_FIELD_UI),
button_text_(string)
{}
+1 -1
View File
@@ -42,7 +42,7 @@ public:
/**
* @brief Reimplementation of EffectField::EffectField().
*/
ButtonField(EffectRow* parent);
ButtonField(EffectRow* parent, const QString& string);
/**
* @brief Set whether this pushbutton is checkable
+2 -1
View File
@@ -23,6 +23,7 @@
#include <QColor>
#include "ui/colorbutton.h"
#include "effects/effect.h"
ColorField::ColorField(EffectRow* parent) :
EffectField(parent, EffectField::EFFECT_FIELD_COLOR)
@@ -64,7 +65,7 @@ void ColorField::UpdateFromWidget(const QColor& c)
{
KeyframeDataChange* kdc = new KeyframeDataChange(this);
SetValueAt(Now(), c);
SetValueAt(GetParentRow()->GetParentEffect()->Now(), c);
kdc->SetNewKeyframes();
olive::undo_stack.push(kdc);
+2 -1
View File
@@ -22,6 +22,7 @@
#include <QDebug>
#include "effects/effect.h"
#include "ui/comboboxex.h"
ComboField::ComboField(EffectRow* parent) :
@@ -84,7 +85,7 @@ void ComboField::UpdateFromWidget(int index)
{
KeyframeDataChange* kdc = new KeyframeDataChange(this);
SetValueAt(Now(), items_.at(index).data);
SetValueAt(GetParentRow()->GetParentEffect()->Now(), items_.at(index).data);
kdc->SetNewKeyframes();
olive::undo_stack.push(kdc);
+2 -2
View File
@@ -20,7 +20,7 @@
#include "doublefield.h"
#include "effects/effectrow.h"
#include "effects/effect.h"
DoubleField::DoubleField(EffectRow* parent) :
EffectField(parent, EffectField::EFFECT_FIELD_DOUBLE),
@@ -138,7 +138,7 @@ void DoubleField::UpdateFromWidget(double d)
kdc_ = new KeyframeDataChange(this);
}
SetValueAt(Now(), d);
SetValueAt(GetParentRow()->GetParentEffect()->Now(), d);
if (!ls->IsDragging() && kdc_ != nullptr) {
kdc_->SetNewKeyframes();
+4 -3
View File
@@ -23,9 +23,10 @@
#include <QDebug>
#include "ui/embeddedfilechooser.h"
#include "effects/effect.h"
FileField::FileField(EffectRow* parent, const QString &id) :
EffectField(parent, id, EffectField::EFFECT_FIELD_FILE)
FileField::FileField(EffectRow* parent) :
EffectField(parent, EffectField::EFFECT_FIELD_FILE)
{
// Set default value to an empty string
SetValueAt(0, "");
@@ -59,7 +60,7 @@ void FileField::UpdateFromWidget(const QString &s)
{
KeyframeDataChange* kdc = new KeyframeDataChange(this);
SetValueAt(Now(), s);
SetValueAt(GetParentRow()->GetParentEffect()->Now(), s);
kdc->SetNewKeyframes();
olive::undo_stack.push(kdc);
+2 -2
View File
@@ -24,7 +24,7 @@
#include "../effectfield.h"
/**
* @brief The FileField class
* @brief The FileInput class
*
* An EffectField derivative that produces filenames in string and uses an EmbeddedFileChooser
* as its visual representation.
@@ -36,7 +36,7 @@ public:
/**
* @brief Reimplementation of EffectField::EffectField().
*/
FileField(EffectRow* parent, const QString& id);
FileField(EffectRow* parent);
/**
* @brief Get the filename at the given timecode
+5 -4
View File
@@ -24,11 +24,12 @@
#include <QDebug>
#include "ui/comboboxex.h"
#include "effects/effect.h"
// NOTE/TODO: This shares a lot of similarity with ComboField, and could probably be a derived class of it
// NOTE/TODO: This shares a lot of similarity with ComboInput, and could probably be a derived class of it
FontField::FontField(EffectRow* parent, const QString &id) :
EffectField(parent, id, EffectField::EFFECT_FIELD_FONT)
FontField::FontField(EffectRow* parent) :
EffectField(parent, EffectField::EFFECT_FIELD_FONT)
{
font_list = QFontDatabase().families();
@@ -86,7 +87,7 @@ void FontField::UpdateFromWidget(const QString& s)
{
KeyframeDataChange* kdc = new KeyframeDataChange(this);
SetValueAt(Now(), s);
SetValueAt(GetParentRow()->GetParentEffect()->Now(), s);
kdc->SetNewKeyframes();
olive::undo_stack.push(kdc);
+1 -1
View File
@@ -37,7 +37,7 @@ public:
/**
* @brief Reimplementation of EffectField::EffectField().
*/
FontField(EffectRow* parent, const QString& id);
FontField(EffectRow* parent);
/**
* @brief Get the font family name at the given timecode
+1 -1
View File
@@ -23,7 +23,7 @@
#include <QLabel>
LabelField::LabelField(EffectRow *parent, const QString &string) :
EffectField(parent, nullptr, EffectField::EFFECT_FIELD_UI),
EffectField(parent, EffectField::EFFECT_FIELD_UI),
label_text_(string)
{}
+2 -1
View File
@@ -23,6 +23,7 @@
#include <QtMath>
#include <QDebug>
#include "effects/effect.h"
#include "ui/texteditex.h"
#include "global/config.h"
@@ -92,7 +93,7 @@ void StringField::UpdateFromWidget(const QString &s)
{
KeyframeDataChange* kdc = new KeyframeDataChange(this);
SetValueAt(Now(), s);
SetValueAt(GetParentRow()->GetParentEffect()->Now(), s);
kdc->SetNewKeyframes();
olive::undo_stack.push(kdc);
+1 -1
View File
@@ -39,7 +39,7 @@ public:
* Provides a setting for whether this StringField - and its attached TextEditEx objects - should operate in rich
* text or plain text mode, defaulting to rich text mode.
*/
StringField(EffectRow* parent, const QString& id, bool rich_text = true);
StringField(EffectRow* parent, bool rich_text = true);
/**
* @brief Get the string at the given timecode
+2 -4
View File
@@ -24,14 +24,12 @@
#include <QtMath>
AudioNoiseEffect::AudioNoiseEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
EffectRow* amount_row = new EffectRow(this, tr("Amount"));
amount_val = new DoubleField(amount_row, "amount");
amount_val = new DoubleInput(this, "amount", tr("Amount"));
amount_val->SetMinimum(0);
amount_val->SetDefault(20);
amount_val->SetMaximum(100);
EffectRow* mix_row = new EffectRow(this, tr("Mix"));
mix_val = new BoolField(mix_row, "mix");
mix_val = new BoolInput(this, "mix", tr("Mix"));
mix_val->SetValueAt(0, true);
}
+2 -2
View File
@@ -34,8 +34,8 @@ public:
int channel_count,
int type) override;
DoubleField* amount_val;
BoolField* mix_val;
DoubleInput* amount_val;
BoolInput* mix_val;
};
#endif // AUDIONOISEEFFECT_H
+17 -29
View File
@@ -27,54 +27,42 @@
CornerPinEffect::CornerPinEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
SetFlags(Effect::CoordsFlag | Effect::ShaderFlag);
EffectRow* top_left = new EffectRow(this, tr("Top Left"));
top_left_x = new DoubleField(top_left, "topleftx");
top_left_y = new DoubleField(top_left, "toplefty");
top_left = new Vec2Input(this, "topleft", tr("Top Left"));
EffectRow* top_right = new EffectRow(this, tr("Top Right"));
top_right_x = new DoubleField(top_right, "toprightx");
top_right_y = new DoubleField(top_right, "toprighty");
top_right = new Vec2Input(this, "topright", tr("Top Right"));
EffectRow* bottom_left = new EffectRow(this, tr("Bottom Left"));
bottom_left_x = new DoubleField(bottom_left, "bottomleftx");
bottom_left_y = new DoubleField(bottom_left, "bottomlefty");
bottom_left = new Vec2Input(this, "bottomleft", tr("Bottom Left"));
EffectRow* bottom_right = new EffectRow(this, tr("Bottom Right"));
bottom_right_x = new DoubleField(bottom_right, "bottomrightx");
bottom_right_y = new DoubleField(bottom_right, "bottomrighty");
bottom_right = new Vec2Input(this, "bottomright", tr("Bottom Right"));
EffectRow* perspective_row = new EffectRow(this, tr("Perspective"));
perspective = new BoolField(perspective_row, "perspective");
perspective = new BoolInput(this, "perspective", tr("Perspective"));
perspective->SetValueAt(0, true);
top_left_gizmo = add_gizmo(GIZMO_TYPE_DOT);
top_left_gizmo->x_field1 = top_left_x;
top_left_gizmo->y_field1 = top_left_y;
top_left_gizmo->x_field1 = static_cast<DoubleField*>(top_left->Field(0));
top_left_gizmo->y_field1 = static_cast<DoubleField*>(top_left->Field(1));
top_right_gizmo = add_gizmo(GIZMO_TYPE_DOT);
top_right_gizmo->x_field1 = top_right_x;
top_right_gizmo->y_field1 = top_right_y;
top_right_gizmo->x_field1 = static_cast<DoubleField*>(top_right->Field(0));
top_right_gizmo->y_field1 = static_cast<DoubleField*>(top_right->Field(1));
bottom_left_gizmo = add_gizmo(GIZMO_TYPE_DOT);
bottom_left_gizmo->x_field1 = bottom_left_x;
bottom_left_gizmo->y_field1 = bottom_left_y;
bottom_left_gizmo->x_field1 = static_cast<DoubleField*>(bottom_left->Field(0));
bottom_left_gizmo->y_field1 = static_cast<DoubleField*>(bottom_left->Field(1));
bottom_right_gizmo = add_gizmo(GIZMO_TYPE_DOT);
bottom_right_gizmo->x_field1 = bottom_right_x;
bottom_right_gizmo->y_field1 = bottom_right_y;
bottom_right_gizmo->x_field1 = static_cast<DoubleField*>(bottom_right->Field(0));
bottom_right_gizmo->y_field1 = static_cast<DoubleField*>(bottom_right->Field(1));
shader_vert_path_ = "cornerpin.vert";
shader_frag_path_ = "cornerpin.frag";
}
void CornerPinEffect::process_coords(double timecode, GLTextureCoords &coords, int) {
coords.vertex_top_left += QVector3D(top_left_x->GetDoubleAt(timecode), top_left_y->GetDoubleAt(timecode), 0.0f);
coords.vertex_top_right += QVector3D(top_right_x->GetDoubleAt(timecode), top_right_y->GetDoubleAt(timecode), 0.0f);
coords.vertex_bottom_left += QVector3D(bottom_left_x->GetDoubleAt(timecode), bottom_left_y->GetDoubleAt(timecode), 0.0f);
coords.vertex_bottom_right += QVector3D(bottom_right_x->GetDoubleAt(timecode), bottom_right_y->GetDoubleAt(timecode), 0.0f);
coords.vertex_top_left += top_left->GetVector2DAt(timecode);
coords.vertex_top_right += top_right->GetVector2DAt(timecode);
coords.vertex_bottom_left += bottom_left->GetVector2DAt(timecode);
coords.vertex_bottom_right += bottom_right->GetVector2DAt(timecode);
}
void CornerPinEffect::process_shader(double timecode, GLTextureCoords &coords, int) {
+6 -9
View File
@@ -31,15 +31,12 @@ public:
void process_shader(double timecode, GLTextureCoords& coords, int iterations);
void gizmo_draw(double timecode, GLTextureCoords& coords);
private:
DoubleField* top_left_x;
DoubleField* top_left_y;
DoubleField* top_right_x;
DoubleField* top_right_y;
DoubleField* bottom_left_x;
DoubleField* bottom_left_y;
DoubleField* bottom_right_x;
DoubleField* bottom_right_y;
BoolField* perspective;
Vec2Input* top_left;
Vec2Input* top_right;
Vec2Input* bottom_left;
Vec2Input* bottom_right;
BoolInput* perspective;
EffectGizmo* top_left_gizmo;
EffectGizmo* top_right_gizmo;
+1 -2
View File
@@ -26,8 +26,7 @@ enum FillType {
};
FillLeftRightEffect::FillLeftRightEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
EffectRow* type_row = new EffectRow(this, tr("Type"));
fill_type = new ComboField(type_row, "type");
fill_type = new ComboInput(this, "type", tr("Type"));
fill_type->AddItem(tr("Fill Left with Right"), FILL_TYPE_LEFT);
fill_type->AddItem(tr("Fill Right with Left"), FILL_TYPE_RIGHT);
}
+1 -1
View File
@@ -34,7 +34,7 @@ public:
int channel_count,
int type) override;
private:
ComboField* fill_type;
ComboInput* fill_type;
};
#endif // FILLLEFTRIGHTEFFECT_H
+1 -2
View File
@@ -29,8 +29,7 @@
#include "ui/collapsiblewidget.h"
PanEffect::PanEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
EffectRow* pan_row = new EffectRow(this, tr("Pan"));
pan_val = new DoubleField(pan_row, "pan");
pan_val = new DoubleInput(this, "pan", tr("Pan"));
pan_val->SetMinimum(-100);
pan_val->SetDefault(0);
pan_val->SetMaximum(100);
+1 -1
View File
@@ -34,7 +34,7 @@ public:
int channel_count,
int type) override;
DoubleField* pan_val;
DoubleInput* pan_val;
};
#endif // PANEFFECT_H
+20 -42
View File
@@ -39,60 +39,38 @@ RichTextEffect::RichTextEffect(Clip *c, const EffectMeta *em) :
{
SetFlags(Effect::SuperimposeFlag);
EffectRow* text_row = new EffectRow(this, tr("Text"));
text_val = new StringField(text_row, "text");
text_val->SetColumnSpan(2);
text_val = new StringInput(this, "text", tr("Text"));
EffectRow* padding_row = new EffectRow(this, tr("Padding"));
padding_field = new DoubleField(padding_row, "padding");
padding_field->SetColumnSpan(2);
padding_field = new DoubleInput(this, "padding", tr("Padding"));
EffectRow* position_row = new EffectRow(this, tr("Position"));
position_x = new DoubleField(position_row, "posx");
position_y = new DoubleField(position_row, "posy");
position = new Vec2Input(this, "pos", tr("Position"));
EffectRow* vertical_align_row = new EffectRow(this, tr("Vertical Align:"));
vertical_align = new ComboField(vertical_align_row, "valign");
vertical_align = new ComboInput(this, "valign", tr("Vertical Align:"));
vertical_align->AddItem(tr("Top"), Qt::AlignTop);
vertical_align->AddItem(tr("Center"), Qt::AlignCenter);
vertical_align->AddItem(tr("Bottom"), Qt::AlignBottom);
vertical_align->SetValueAt(0, Qt::AlignCenter);
vertical_align->SetColumnSpan(2);
EffectRow* autoscroll_row = new EffectRow(this, tr("Auto-Scroll"));
autoscroll = new ComboField(autoscroll_row, "autoscroll");
autoscroll = new ComboInput(this, "autoscroll", tr("Auto-Scroll"));
autoscroll->AddItem(tr("Off"), SCROLL_OFF);
autoscroll->AddItem(tr("Up"), SCROLL_UP);
autoscroll->AddItem(tr("Down"), SCROLL_DOWN);
autoscroll->AddItem(tr("Left"), SCROLL_LEFT);
autoscroll->AddItem(tr("Right"), SCROLL_RIGHT);
autoscroll->SetColumnSpan(2);
EffectRow* shadow_row = new EffectRow(this, tr("Shadow"));
shadow_bool = new BoolField(shadow_row, "shadow");
shadow_bool->SetColumnSpan(2);
shadow_bool = new BoolInput(this, "shadow", tr("Shadow"));
EffectRow* shadow_color_row = new EffectRow(this, tr("Shadow Color"));
shadow_color = new ColorField(shadow_color_row, "shadowcolor");
shadow_color->SetColumnSpan(2);
shadow_color = new ColorInput(this, "shadowcolor", tr("Shadow Color"));
EffectRow* shadow_angle_row = new EffectRow(this, tr("Shadow Angle"));
shadow_angle = new DoubleField(shadow_angle_row, "shadowangle");
shadow_angle->SetColumnSpan(2);
shadow_angle = new DoubleInput(this, "shadowangle", tr("Shadow Angle"));
EffectRow* shadow_distance_row = new EffectRow(this, tr("Shadow Distance"));
shadow_distance = new DoubleField(shadow_distance_row, "shadowdistance");
shadow_distance->SetColumnSpan(2);
shadow_distance = new DoubleInput(this, "shadowdistance", tr("Shadow Distance"));
shadow_distance->SetMinimum(0);
EffectRow* shadow_softness_row = new EffectRow(this, tr("Shadow Softness"));
shadow_softness = new DoubleField(shadow_softness_row, "shadowsoftness");
shadow_softness->SetColumnSpan(2);
shadow_softness = new DoubleInput(this, "shadowsoftness", tr("Shadow Softness"));
shadow_softness->SetMinimum(0);
EffectRow* shadow_opacity_row = new EffectRow(this, tr("Shadow Opacity"));
shadow_opacity = new DoubleField(shadow_opacity_row, "shadowopacity");
shadow_opacity->SetColumnSpan(2);
shadow_opacity = new DoubleInput(this, "shadowopacity", tr("Shadow Opacity"));
shadow_opacity->SetMinimum(0);
shadow_opacity->SetMaximum(100);
@@ -120,8 +98,8 @@ void RichTextEffect::redraw(double timecode)
td.setHtml(text_val->GetStringAt(timecode));
td.setTextWidth(width);
int translate_x = qRound(position_x->GetDoubleAt(timecode) + padding);
int translate_y = qRound(position_y->GetDoubleAt(timecode) + padding);
QPoint translation = position->GetVector2DAt(timecode).toPoint();
translation += {padding, padding};
int doc_height = qRound(td.size().height());
@@ -138,9 +116,9 @@ void RichTextEffect::redraw(double timecode)
// If we're not auto-scrolling the vertical direction, respect the vertical alignment
if (vertical_align->GetValueAt(timecode).toInt() == Qt::AlignCenter) {
translate_y += height / 2 - doc_height / 2;
translation.setY(translation.y() + height / 2 - doc_height / 2);
} else if (vertical_align->GetValueAt(timecode).toInt() == Qt::AlignBottom) {
translate_y += height - doc_height;
translation.setY(translation.y() + height - doc_height);
}
// Check if we are autoscrolling
@@ -151,7 +129,7 @@ void RichTextEffect::redraw(double timecode)
}
int doc_width = qRound(td.size().width());
translate_x += qRound(-doc_width + (img.width() + doc_width) * scroll_progress);
translation.setX(translation.x() + qRound(-doc_width + (img.width() + doc_width) * scroll_progress));
}
} else if (auto_scroll_dir == SCROLL_UP || auto_scroll_dir == SCROLL_DOWN) {
@@ -162,13 +140,13 @@ void RichTextEffect::redraw(double timecode)
scroll_progress = 1.0 - scroll_progress;
}
translate_y += qRound(-doc_height + (img.height() + doc_height)*scroll_progress);
translation.setY(translation.y() + qRound(-doc_height + (img.height() + doc_height)*scroll_progress));
}
QRect clip_rect = img.rect();
clip_rect.translate(-translate_x, -translate_y);
p.translate(translate_x, translate_y);
clip_rect.translate(-translation);
p.translate(translation);
img.fill(Qt::transparent);
@@ -208,5 +186,5 @@ void RichTextEffect::redraw(double timecode)
bool RichTextEffect::AlwaysUpdate()
{
return autoscroll->GetValueAt(autoscroll->Now()).toInt() != SCROLL_OFF;
return autoscroll->GetValueAt(Now()).toInt() != SCROLL_OFF;
}
+11 -12
View File
@@ -31,19 +31,18 @@ public:
protected:
virtual bool AlwaysUpdate() override;
private:
StringField* text_val;
DoubleField* padding_field;
DoubleField* position_x;
DoubleField* position_y;
ComboField* vertical_align;
ComboField* autoscroll;
StringInput* text_val;
DoubleInput* padding_field;
Vec2Input* position;
ComboInput* vertical_align;
ComboInput* autoscroll;
BoolField* shadow_bool;
DoubleField* shadow_angle;
DoubleField* shadow_distance;
ColorField* shadow_color;
DoubleField* shadow_softness;
DoubleField* shadow_opacity;
BoolInput* shadow_bool;
DoubleInput* shadow_angle;
DoubleInput* shadow_distance;
ColorInput* shadow_color;
DoubleInput* shadow_softness;
DoubleInput* shadow_opacity;
};
#endif // RICHTEXTEFFECT_H
+3 -6
View File
@@ -35,18 +35,15 @@
ShakeEffect::ShakeEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
SetFlags(Effect::CoordsFlag);
EffectRow* intensity_row = new EffectRow(this, tr("Intensity"));
intensity_val = new DoubleField(intensity_row, "intensity");
intensity_val = new DoubleInput(this, "intensity", tr("Intensity"));
intensity_val->SetMinimum(0);
intensity_val->SetDefault(25);
EffectRow* rotation_row = new EffectRow(this, tr("Rotation"));
rotation_val = new DoubleField(rotation_row, "rotation");
rotation_val = new DoubleInput(this, "rotation", tr("Rotation"));
rotation_val->SetMinimum(0);
rotation_val->SetDefault(10);
EffectRow* frequency_row = new EffectRow(this, tr("Frequency"));
frequency_val = new DoubleField(frequency_row, "frequency");
frequency_val = new DoubleInput(this, "frequency", tr("Frequency"));
frequency_val->SetMinimum(0);
frequency_val->SetDefault(5);
+3 -3
View File
@@ -31,9 +31,9 @@ public:
ShakeEffect(Clip* c, const EffectMeta* em);
virtual void process_coords(double timecode, GLTextureCoords& coords, int data) override;
DoubleField* intensity_val;
DoubleField* rotation_val;
DoubleField* frequency_val;
DoubleInput* intensity_val;
DoubleInput* rotation_val;
DoubleInput* frequency_val;
private:
double random_vals[RANDOM_VAL_SIZE];
};
+4 -8
View File
@@ -40,24 +40,20 @@ SolidEffect::SolidEffect(Clip* c, const EffectMeta* em) :
SetFlags(Effect::SuperimposeFlag);
// Field for solid type
EffectRow* type_row = new EffectRow(this, tr("Type"));
solid_type = new ComboField(type_row, "type");
solid_type = new ComboInput(this, "type", tr("Type"));
solid_type->AddItem(tr("Solid Color"), SOLID_TYPE_COLOR);
solid_type->AddItem(tr("SMPTE Bars"), SOLID_TYPE_BARS);
solid_type->AddItem(tr("Checkerboard"), SOLID_TYPE_CHECKERBOARD);
EffectRow* opacity_row = new EffectRow(this, tr("Opacity"));
opacity_field = new DoubleField(opacity_row, "opacity");
opacity_field = new DoubleInput(this, "opacity", tr("Opacity"));
opacity_field->SetMinimum(0);
opacity_field->SetDefault(100);
opacity_field->SetMaximum(100);
EffectRow* solid_color_row = new EffectRow(this, tr("Color"));
solid_color_field = new ColorField(solid_color_row, "color");
solid_color_field = new ColorInput(this, "color", tr("Color"));
solid_color_field->SetValueAt(0, QColor(Qt::red));
EffectRow* checkerboard_size = new EffectRow(this, tr("Checkerboard Size"));
checkerboard_size_field = new DoubleField(checkerboard_size, "checker_size");
checkerboard_size_field = new DoubleInput(this, "checker_size", tr("Checkerboard Size"));
checkerboard_size_field->SetMinimum(1);
checkerboard_size_field->SetDefault(10);
+4 -4
View File
@@ -41,10 +41,10 @@ public:
private slots:
void ui_update(const QVariant &d);
private:
ComboField* solid_type;
ColorField* solid_color_field;
DoubleField* opacity_field;
DoubleField* checkerboard_size_field;
ComboInput* solid_type;
ColorInput* solid_color_field;
DoubleInput* opacity_field;
DoubleInput* checkerboard_size_field;
};
#endif // SOLIDEFFECT_H
+19 -52
View File
@@ -47,85 +47,52 @@ TextEffect::TextEffect(Clip* c, const EffectMeta* em) :
{
SetFlags(Effect::SuperimposeFlag);
EffectRow* text_field = new EffectRow(this, tr("Text"));
text_val = new StringField(text_field, "text", false);
text_val->SetColumnSpan(2);
text_val = new StringInput(this, "text", tr("Text"), false);
EffectRow* font_row = new EffectRow(this, tr("Font"));
set_font_combobox = new FontField(font_row, "font");
set_font_combobox->SetColumnSpan(2);
set_font_combobox = new FontInput(this, "font", tr("Font"));
EffectRow* size_row = new EffectRow(this, tr("Size"));
size_val = new DoubleField(size_row, "size");
size_val = new DoubleInput(this, "size", tr("Size"));
size_val->SetMinimum(0);
size_val->SetColumnSpan(2);
EffectRow* color_row = new EffectRow(this, tr("Color"));
set_color_button = new ColorField(color_row, "color");
set_color_button->SetColumnSpan(2);
set_color_button = new ColorInput(this, "color", tr("Color"));
EffectRow* alignment_row = new EffectRow(this, tr("Alignment"));
halign_field = new ComboField(alignment_row, "halign");
halign_field = new ComboInput(this, "halign", tr("Horizontal Alignment"));
halign_field->AddItem(tr("Left"), Qt::AlignLeft);
halign_field->AddItem(tr("Center"), Qt::AlignHCenter);
halign_field->AddItem(tr("Right"), Qt::AlignRight);
halign_field->AddItem(tr("Justify"), Qt::AlignJustify);
valign_field = new ComboField(alignment_row, "valign");
valign_field = new ComboInput(this, "valign", tr("Vertical Alignment"));
valign_field->AddItem(tr("Top"), Qt::AlignTop);
valign_field->AddItem(tr("Center"), Qt::AlignVCenter);
valign_field->AddItem(tr("Bottom"), Qt::AlignBottom);
EffectRow* word_wrap_row = new EffectRow(this, tr("Word Wrap"));
word_wrap_field = new BoolField(word_wrap_row, "wordwrap");
word_wrap_field->SetColumnSpan(2);
word_wrap_field = new BoolInput(this, "wordwrap", tr("Word Wrap"));
EffectRow* padding_row = new EffectRow(this, tr("Padding"));
padding_field = new DoubleField(padding_row, "padding");
padding_field->SetColumnSpan(2);
padding_field = new DoubleInput(this, "padding", tr("Padding"));
EffectRow* position_row = new EffectRow(this, tr("Position"));
position_x = new DoubleField(position_row, "posx");
position_y = new DoubleField(position_row, "posy");
position = new Vec2Input(this, "pos", tr("Position"));
EffectRow* outline_row = new EffectRow(this, tr("Outline"));
outline_bool = new BoolField(outline_row, "outline");
outline_bool->SetColumnSpan(2);
outline_bool = new BoolInput(this, "outline", tr("Outline"));
EffectRow* outline_color_row = new EffectRow(this, tr("Outline Color"));
outline_color = new ColorField(outline_color_row, "outlinecolor");
outline_color->SetColumnSpan(2);
outline_color = new ColorInput(this, "outlinecolor", tr("Outline Color"));
EffectRow* outline_width_row = new EffectRow(this, tr("Outline Width"));
outline_width = new DoubleField(outline_width_row, "outlinewidth");
outline_width->SetColumnSpan(2);
outline_width = new DoubleInput(this, "outlinewidth", tr("Outline Width"));
outline_width->SetMinimum(0);
EffectRow* shadow_row = new EffectRow(this, tr("Shadow"));
shadow_bool = new BoolField(shadow_row, "shadow");
shadow_bool->SetColumnSpan(2);
shadow_bool = new BoolInput(this, "shadow", tr("Shadow"));
EffectRow* shadow_color_row = new EffectRow(this, tr("Shadow Color"));
shadow_color = new ColorField(shadow_color_row, "shadowcolor");
shadow_color->SetColumnSpan(2);
shadow_color = new ColorInput(this, "shadowcolor", tr("Shadow Color"));
EffectRow* shadow_angle_row = new EffectRow(this, tr("Shadow Angle"));
shadow_angle = new DoubleField(shadow_angle_row, "shadowangle");
shadow_angle->SetColumnSpan(2);
shadow_angle = new DoubleInput(this, "shadowangle", tr("Shadow Angle"));
EffectRow* shadow_distance_row = new EffectRow(this, tr("Shadow Distance"));
shadow_distance = new DoubleField(shadow_distance_row, "shadowdistance");
shadow_distance->SetColumnSpan(2);
shadow_distance = new DoubleInput(this, "shadowdistance", tr("Shadow Distance"));
shadow_distance->SetMinimum(0);
EffectRow* shadow_softness_row = new EffectRow(this, tr("Shadow Softness"));
shadow_softness = new DoubleField(shadow_softness_row, "shadowsoftness");
shadow_softness->SetColumnSpan(2);
shadow_softness = new DoubleInput(this, "shadowsoftness", tr("Shadow Softness"));
shadow_softness->SetMinimum(0);
EffectRow* shadow_opacity_row = new EffectRow(this, tr("Shadow Opacity"));
shadow_opacity = new DoubleField(shadow_opacity_row, "shadowopacity");
shadow_opacity->SetColumnSpan(2);
shadow_opacity = new DoubleInput(this, "shadowopacity", tr("Shadow Opacity"));
shadow_opacity->SetMinimum(0);
shadow_opacity->SetMaximum(100);
@@ -252,7 +219,7 @@ void TextEffect::redraw(double timecode) {
path.addText(text_x, text_y, font, lines.at(i));
}
path.translate(position_x->GetDoubleAt(timecode) + padding, position_y->GetDoubleAt(timecode) + padding);
path.translate(position->GetVector2DAt(timecode).toPointF() + QPointF(padding, padding));
// draw software shadow
if (shadow_bool->GetBoolAt(timecode)) {
+18 -19
View File
@@ -37,27 +37,26 @@ private slots:
private:
QFont font;
StringField* text_val;
DoubleField* size_val;
ColorField* set_color_button;
FontField* set_font_combobox;
ComboField* halign_field;
ComboField* valign_field;
BoolField* word_wrap_field;
DoubleField* padding_field;
DoubleField* position_x;
DoubleField* position_y;
StringInput* text_val;
DoubleInput* size_val;
ColorInput* set_color_button;
FontInput* set_font_combobox;
ComboInput* halign_field;
ComboInput* valign_field;
BoolInput* word_wrap_field;
DoubleInput* padding_field;
Vec2Input* position;
BoolField* outline_bool;
DoubleField* outline_width;
ColorField* outline_color;
BoolInput* outline_bool;
DoubleInput* outline_width;
ColorInput* outline_color;
BoolField* shadow_bool;
DoubleField* shadow_angle;
DoubleField* shadow_distance;
ColorField* shadow_color;
DoubleField* shadow_softness;
DoubleField* shadow_opacity;
BoolInput* shadow_bool;
DoubleInput* shadow_angle;
DoubleInput* shadow_distance;
ColorInput* shadow_color;
DoubleInput* shadow_softness;
DoubleInput* shadow_opacity;
};
+12 -25
View File
@@ -47,43 +47,31 @@ TimecodeEffect::TimecodeEffect(Clip* c, const EffectMeta* em) :
{
SetFlags(Effect::SuperimposeFlag);
EffectRow* tc_row = new EffectRow(this, tr("Timecode"));
tc_select = new ComboField(tc_row, "tc_selector");
tc_select = new ComboInput(this, "tc_selector", tr("Timecode"));
tc_select->AddItem(tr("Sequence"), true);
tc_select->AddItem(tr("Media"), false);
tc_select->SetValueAt(0, true);
EffectRow* scale_row = new EffectRow(this, tr("Scale"));
scale_val = new DoubleField(scale_row, "scale");
scale_val->SetColumnSpan(2);
scale_val = new DoubleInput(this, "scale", tr("Scale"));
scale_val->SetMinimum(1);
scale_val->SetDefault(100);
scale_val->SetMaximum(1000);
EffectRow* color_row = new EffectRow(this, tr("Color"));
color_val = new ColorField(color_row, "color");
color_val->SetColumnSpan(2);
color_val = new ColorInput(this, "color", tr("Color"));
color_val->SetValueAt(0, QColor(Qt::white));
EffectRow* color_bg_row = new EffectRow(this, tr("Background Color"));
color_bg_val = new ColorField(color_bg_row, "bgcolor");
color_bg_val->SetColumnSpan(2);
color_bg_val = new ColorInput(this, "bgcolor", tr("Background Color"));
color_bg_val->SetValueAt(0, QColor(Qt::black));
EffectRow* bg_alpha_row = new EffectRow(this, tr("Background Opacity"));
bg_alpha = new DoubleField(bg_alpha_row, "bgalpha");
bg_alpha->SetColumnSpan(2);
bg_alpha = new DoubleInput(this, "bgalpha", tr("Background Opacity"));
bg_alpha->SetMinimum(0);
bg_alpha->SetDefault(50);
bg_alpha->SetMaximum(100);
EffectRow* offset_row = new EffectRow(this, tr("Offset"));
offset_x_val = new DoubleField(offset_row, "offsetx");
offset_y_val = new DoubleField(offset_row, "offsety");
offset_val = new Vec2Input(this, "offset", tr("Offset"));
offset_val->SetDefault(0);
EffectRow* prepent_text_row = new EffectRow(this, tr("Prepend"));
prepend_text = new StringField(prepent_text_row, "prepend", false);
prepend_text->SetColumnSpan(2);
prepend_text = new StringInput(this, "prepend", tr("Prepend"), false);
}
@@ -116,18 +104,17 @@ void TimecodeEffect::redraw(double timecode) {
QPainterPath path;
int text_x, text_y, rect_y, offset_x, offset_y;
int text_x, text_y, rect_y;
int text_height = fm.height();
int text_width = fm.width(display_timecode);
QColor background_color = color_bg_val->GetColorAt(timecode);
int alpha_val = qCeil(bg_alpha->GetDoubleAt(timecode)*2.55);
background_color.setAlpha(alpha_val);
offset_x = int(offset_x_val->GetDoubleAt(timecode));
offset_y = int(offset_y_val->GetDoubleAt(timecode));
QVector2D offset = offset_val->GetVector2DAt(timecode);
text_x = offset_x + (width/2) - (text_width/2);
text_y = offset_y + height - height/10;
text_x = offset.x() + (width/2) - (text_width/2);
text_y = offset.y() + height - height/10;
rect_y = text_y + fm.descent() - text_height;
path.addText(text_x, text_y, font, display_timecode);
+7 -8
View File
@@ -31,14 +31,13 @@ class TimecodeEffect : public Effect {
public:
TimecodeEffect(Clip* c, const EffectMeta *em);
virtual void redraw(double timecode) override;
DoubleField* scale_val;
ColorField* color_val;
ColorField* color_bg_val;
DoubleField* bg_alpha;
DoubleField* offset_x_val;
DoubleField* offset_y_val;
StringField* prepend_text;
ComboField* tc_select;
DoubleInput* scale_val;
ColorInput* color_val;
ColorInput* color_bg_val;
DoubleInput* bg_alpha;
Vec2Input* offset_val;
StringInput* prepend_text;
ComboInput* tc_select;
protected:
virtual bool AlwaysUpdate() override;
+4 -8
View File
@@ -28,24 +28,20 @@
#include "timeline/sequence.h"
ToneEffect::ToneEffect(Clip* c, const EffectMeta *em) : Effect(c, em), sinX(INT_MIN) {
EffectRow* type_row = new EffectRow(this, tr("Type"));
type_val = new ComboField(type_row, "type");
type_val = new ComboInput(this, "type", tr("Type"));
type_val->AddItem(tr("Sine"), TONE_TYPE_SINE);
EffectRow* frequency_row = new EffectRow(this, tr("Frequency"));
freq_val = new DoubleField(frequency_row, "frequency");
freq_val = new DoubleInput(this, "frequency", tr("Frequency"));
freq_val->SetMinimum(20);
freq_val->SetMaximum(20000);
freq_val->SetDefault(1000);
EffectRow* amount_row = new EffectRow(this, tr("Amount"));
amount_val = new DoubleField(amount_row, "amount");
amount_val = new DoubleInput(this, "amount", tr("Amount"));
amount_val->SetMinimum(0);
amount_val->SetMaximum(100);
amount_val->SetDefault(25);
EffectRow* mix_row = new EffectRow(this, tr("Mix"));
mix_val = new BoolField(mix_row, "mix");
mix_val = new BoolInput(this, "mix", tr("Mix"));
mix_val->SetValueAt(0, true);
}
+4 -4
View File
@@ -34,10 +34,10 @@ public:
int channel_count,
int type) override;
ComboField* type_val;
DoubleField* freq_val;
DoubleField* amount_val;
BoolField* mix_val;
ComboInput* type_val;
DoubleInput* freq_val;
DoubleInput* amount_val;
BoolInput* mix_val;
private:
int sinX;
};
+45 -78
View File
@@ -46,116 +46,86 @@
TransformEffect::TransformEffect(Clip* c, const EffectMeta* em) : Effect(c, em) {
SetFlags(Effect::CoordsFlag);
EffectRow* position_row = new EffectRow(this, tr("Position"));
position = new Vec2Input(this, "pos", tr("Position"));
position_x = new DoubleField(position_row, "posx"); // position X
position_y = new DoubleField(position_row, "posy"); // position Y
scale = new Vec2Input(this, "scale", tr("Scale"));
scale->SetMinimum(0);
scale->SetDefault(100);
EffectRow* scale_row = new EffectRow(this, tr("Scale"));
uniform_scale_field = new BoolInput(this, "uniformscale", tr("Uniform Scale"));
connect(uniform_scale_field, SIGNAL(Toggled(bool)), scale, SLOT(SetSingleValueMode(bool)));
uniform_scale_field->SetValueAt(0, true);
// scale X (and Y is uniform scale is selected)
scale_x = new DoubleField(scale_row, "scalex");
scale_x->SetMinimum(0);
rotation = new DoubleInput(this, "rotation", tr("Rotation"));
// scale Y (disabled if uniform scale is selected)
scale_y = new DoubleField(scale_row, "scaley");
scale_y->SetMinimum(0);
EffectRow* uniform_scale_row = new EffectRow(this, tr("Uniform Scale"));
uniform_scale_field = new BoolField(uniform_scale_row, "uniformscale"); // uniform scale option
EffectRow* rotation_row = new EffectRow(this, tr("Rotation"));
rotation = new DoubleField(rotation_row, "rotation");
EffectRow* anchor_point_row = new EffectRow(this, tr("Anchor Point"));
anchor_x_box = new DoubleField(anchor_point_row, "anchorx"); // anchor point X
anchor_y_box = new DoubleField(anchor_point_row, "anchory"); // anchor point Y
EffectRow* opacity_row = new EffectRow(this, tr("Opacity"));
anchor_point = new Vec2Input(this, "anchor", tr("Anchor Point"));
anchor_point->SetDefault(0);
// opacity
opacity = new DoubleField(opacity_row, "opacity");
opacity = new DoubleInput(this, "opacity", tr("Opacity"));
opacity->SetMinimum(0);
opacity->SetMaximum(100);
EffectRow* blend_mode_row = new EffectRow(this, tr("Blend Mode"));
// blend mode
blend_mode_box = new ComboField(blend_mode_row, "blendmode");
blend_mode_box->SetColumnSpan(2);
blend_mode_box->AddItem(tr("Normal"), -1);
opacity->SetDefault(100);
// set up gizmos
top_left_gizmo = add_gizmo(GIZMO_TYPE_DOT);
top_left_gizmo->set_cursor(Qt::SizeFDiagCursor);
top_left_gizmo->x_field1 = scale_x;
top_left_gizmo->x_field1 = static_cast<DoubleField*>(scale->Field(0));
top_center_gizmo = add_gizmo(GIZMO_TYPE_DOT);
top_center_gizmo->set_cursor(Qt::SizeVerCursor);
top_center_gizmo->y_field1 = scale_x;
top_center_gizmo->y_field1 = static_cast<DoubleField*>(scale->Field(0));
top_right_gizmo = add_gizmo(GIZMO_TYPE_DOT);
top_right_gizmo->set_cursor(Qt::SizeBDiagCursor);
top_right_gizmo->x_field1 = scale_x;
top_right_gizmo->x_field1 = static_cast<DoubleField*>(scale->Field(0));
bottom_left_gizmo = add_gizmo(GIZMO_TYPE_DOT);
bottom_left_gizmo->set_cursor(Qt::SizeBDiagCursor);
bottom_left_gizmo->x_field1 = scale_x;
bottom_left_gizmo->x_field1 = static_cast<DoubleField*>(scale->Field(0));
bottom_center_gizmo = add_gizmo(GIZMO_TYPE_DOT);
bottom_center_gizmo->set_cursor(Qt::SizeVerCursor);
bottom_center_gizmo->y_field1 = scale_x;
bottom_center_gizmo->y_field1 = static_cast<DoubleField*>(scale->Field(0));
bottom_right_gizmo = add_gizmo(GIZMO_TYPE_DOT);
bottom_right_gizmo->set_cursor(Qt::SizeFDiagCursor);
bottom_right_gizmo->x_field1 = scale_x;
bottom_right_gizmo->x_field1 = static_cast<DoubleField*>(scale->Field(0));
left_center_gizmo = add_gizmo(GIZMO_TYPE_DOT);
left_center_gizmo->set_cursor(Qt::SizeHorCursor);
left_center_gizmo->x_field1 = scale_x;
left_center_gizmo->x_field1 = static_cast<DoubleField*>(scale->Field(0));
right_center_gizmo = add_gizmo(GIZMO_TYPE_DOT);
right_center_gizmo->set_cursor(Qt::SizeHorCursor);
right_center_gizmo->x_field1 = scale_x;
right_center_gizmo->x_field1 = static_cast<DoubleField*>(scale->Field(0));
anchor_gizmo = add_gizmo(GIZMO_TYPE_TARGET);
anchor_gizmo->set_cursor(Qt::SizeAllCursor);
anchor_gizmo->x_field1 = anchor_x_box;
anchor_gizmo->y_field1 = anchor_y_box;
anchor_gizmo->x_field2 = position_x;
anchor_gizmo->y_field2 = position_y;
anchor_gizmo->x_field1 = static_cast<DoubleField*>(anchor_point->Field(0));
anchor_gizmo->y_field1 = static_cast<DoubleField*>(anchor_point->Field(1));
anchor_gizmo->x_field2 = static_cast<DoubleField*>(position->Field(0));
anchor_gizmo->y_field2 = static_cast<DoubleField*>(position->Field(1));
rotate_gizmo = add_gizmo(GIZMO_TYPE_DOT);
rotate_gizmo->color = Qt::green;
rotate_gizmo->set_cursor(Qt::SizeAllCursor);
rotate_gizmo->x_field1 = rotation;
rotate_gizmo->x_field1 = static_cast<DoubleField*>(rotation->Field(0));
rect_gizmo = add_gizmo(GIZMO_TYPE_POLY);
rect_gizmo->x_field1 = position_x;
rect_gizmo->y_field1 = position_y;
rect_gizmo->x_field1 = static_cast<DoubleField*>(position->Field(0));
rect_gizmo->y_field1 = static_cast<DoubleField*>(position->Field(1));
connect(uniform_scale_field, SIGNAL(Toggled(bool)), this, SLOT(toggle_uniform_scale(bool)));
// set defaults
uniform_scale_field->SetValueAt(0, true);
blend_mode_box->SetValueAt(0, -1);
anchor_x_box->SetDefault(0);
anchor_y_box->SetDefault(0);
opacity->SetDefault(100);
scale_x->SetDefault(100);
scale_y->SetDefault(100);
refresh();
}
void TransformEffect::refresh() {
if (parent_clip != nullptr && parent_clip->track()->sequence() != nullptr) {
position_x->SetDefault(parent_clip->track()->sequence()->width/2);
position_y->SetDefault(parent_clip->track()->sequence()->height/2);
position->SetDefault({float(parent_clip->track()->sequence()->width)*0.5f,
float(parent_clip->track()->sequence()->height)*0.5f});
double x_percent_multipler = 200.0 / parent_clip->track()->sequence()->width;
double y_percent_multipler = 200.0 / parent_clip->track()->sequence()->height;
@@ -178,7 +148,10 @@ void TransformEffect::refresh() {
}
void TransformEffect::toggle_uniform_scale(bool enabled) {
scale_y->SetEnabled(!enabled);
scale->SetSingleValueMode(enabled);
DoubleField* scale_x = static_cast<DoubleField*>(scale->Field(0));
DoubleField* scale_y = static_cast<DoubleField*>(scale->Field(1));
top_center_gizmo->y_field1 = enabled ? scale_x : scale_y;
bottom_center_gizmo->y_field1 = enabled ? scale_x : scale_y;
@@ -190,29 +163,23 @@ void TransformEffect::toggle_uniform_scale(bool enabled) {
void TransformEffect::process_coords(double timecode, GLTextureCoords& coords, int) {
// position
coords.matrix.translate(position_x->GetDoubleAt(timecode)-(parent_clip->track()->sequence()->width/2),
position_y->GetDoubleAt(timecode)-(parent_clip->track()->sequence()->height/2),
0);
coords.matrix.translate(position->GetVector2DAt(timecode)
- QVector2D(parent_clip->track()->sequence()->width*0.5f,
parent_clip->track()->sequence()->height*0.5f));
// anchor point
int anchor_x_offset = qRound(anchor_x_box->GetDoubleAt(timecode));
int anchor_y_offset = qRound(anchor_y_box->GetDoubleAt(timecode));
QVector2D anchor_val = anchor_point->GetVector2DAt(timecode);
coords.vertex_top_left -= QVector3D(anchor_x_offset, anchor_y_offset, 0.0f);
coords.vertex_top_right -= QVector3D(anchor_x_offset, anchor_y_offset, 0.0f);
coords.vertex_bottom_left -= QVector3D(anchor_x_offset, anchor_y_offset, 0.0f);
coords.vertex_bottom_right -= QVector3D(anchor_x_offset, anchor_y_offset, 0.0f);
coords.vertex_top_left -= anchor_val;
coords.vertex_top_right -= anchor_val;
coords.vertex_bottom_left -= anchor_val;
coords.vertex_bottom_right -= anchor_val;
// rotation
coords.matrix.rotate(QQuaternion::fromEulerAngles(0, 0, rotation->GetDoubleAt(timecode)));
// scale
double sx = scale_x->GetDoubleAt(timecode)*0.01;
double sy = (uniform_scale_field->GetBoolAt(timecode)) ? sx : scale_y->GetDoubleAt(timecode)*0.01;
coords.matrix.scale(sx, sy);
// blend mode
coords.blendmode = blend_mode_box->GetValueAt(timecode).toInt();
coords.matrix.scale(scale->GetVector2DAt(timecode)*0.01);
// opacity
coords.opacity *= float(opacity->GetDoubleAt(timecode)*0.01);
@@ -239,9 +206,9 @@ void TransformEffect::gizmo_draw(double, GLTextureCoords& coords) {
rotate_gizmo->world_pos[0] = QVector3D(
float_lerp(top_center_gizmo->world_pos[0].x(), bottom_center_gizmo->world_pos[0].x(), 0.5f),
float_lerp(top_center_gizmo->world_pos[0].y(), bottom_center_gizmo->world_pos[0].y(), -0.1f),
0.0f
);
float_lerp(top_center_gizmo->world_pos[0].y(), bottom_center_gizmo->world_pos[0].y(), -0.1f),
0.0f
);
rect_gizmo->world_pos[0] = coords.vertex_top_left;
rect_gizmo->world_pos[1] = coords.vertex_top_right;
+8 -10
View File
@@ -31,19 +31,17 @@ public:
virtual void process_coords(double timecode, GLTextureCoords& coords, int data) override;
virtual void gizmo_draw(double timecode, GLTextureCoords& coords) override;
public slots:
void toggle_uniform_scale(bool enabled);
private:
DoubleField* position_x;
DoubleField* position_y;
DoubleField* scale_x;
DoubleField* scale_y;
BoolField* uniform_scale_field;
DoubleField* rotation;
DoubleField* anchor_x_box;
DoubleField* anchor_y_box;
DoubleField* opacity;
ComboField* blend_mode_box;
Vec2Input* position;
Vec2Input* scale;
BoolInput* uniform_scale_field;
DoubleInput* rotation;
Vec2Input* anchor_point;
DoubleInput* opacity;
EffectGizmo* top_left_gizmo;
EffectGizmo* top_center_gizmo;
+1 -2
View File
@@ -34,9 +34,8 @@ VoidEffect::VoidEffect(Clip* c, const QString& n) : Effect(c, nullptr) {
} else {
display_name = n;
}
EffectRow* row = new EffectRow(this, tr("Missing Effect"), false, false);
new LabelField(row, display_name);
new LabelWidget(this, tr("Missing Effect"), display_name);
name = display_name;
+1 -2
View File
@@ -29,8 +29,7 @@
#include "ui/collapsiblewidget.h"
VolumeEffect::VolumeEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
EffectRow* volume_row = new EffectRow(this, tr("Volume"));
volume_val = new DoubleField(volume_row, "volume");
volume_val = new DoubleInput(this, "volume", tr("Volume"));
// set defaults
volume_val->SetDefault(1);
+1 -1
View File
@@ -34,7 +34,7 @@ public:
int channel_count,
int type) override;
DoubleField* volume_val;
DoubleInput* volume_val;
};
#endif // VOLUMEEFFECT_H
+2 -5
View File
@@ -236,13 +236,10 @@ VSTHost::VSTHost(Clip* c, const EffectMeta *em) :
{
plugin = nullptr;
EffectRow* file_row = new EffectRow(this, tr("Plugin"), true, false);
file_field = new FileField(file_row, "filename");
file_field = new FileInput(this, "filename", tr("Plugin"), true, false);
connect(file_field, SIGNAL(Changed()), this, SLOT(change_plugin()), Qt::QueuedConnection);
EffectRow* interface_row = new EffectRow(this, tr("Interface"), false, false);
show_interface_btn = new ButtonField(interface_row, tr("Show"));
show_interface_btn = new ButtonWidget(this, tr("Interface"), tr("Show"));
show_interface_btn->SetCheckable(true);
show_interface_btn->SetEnabled(false);
connect(show_interface_btn, SIGNAL(Toggled(bool)), this, SLOT(show_interface(bool)));
+2 -2
View File
@@ -65,8 +65,8 @@ private slots:
void uncheck_show_button();
void change_plugin();
private:
FileField* file_field;
ButtonField* show_interface_btn;
FileInput* file_field;
ButtonWidget* show_interface_btn;
void loadPlugin();
void freePlugin();
+3 -9
View File
@@ -1,13 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<effect name="Box Blur" category="Blur">
<row name="Radius">
<field type="double" min="0" default="10" id="radius"/>
</row>
<row name="Horizontal">
<field type="bool" default="1" id="horiz_blur"/>
</row>
<row name="Vertical">
<field type="bool" default="1" id="vert_blur"/>
</row>
<field name="Radius" type="double" min="0" default="10" id="radius"/>
<field name="Horizontal" type="bool" default="1" id="horiz_blur"/>
<field name="Vertical" type="bool" default="1" id="vert_blur"/>
<shader vert="common.vert" frag="boxblur.frag" iterations="2" />
</effect>
+1 -2
View File
@@ -44,8 +44,7 @@ Transition::Transition(Clip *c, Clip *s, const EffectMeta* em) :
Effect(c, em),
secondary_clip(s)
{
EffectRow* length_row = new EffectRow(this, tr("Length"), false, false);
length_field = new DoubleField(length_row, "length");
length_field = new DoubleInput(this, "length", tr("Length"), false, false);
length_field->SetDefault(30);
length_field->SetMinimum(1);
length_field->SetDisplayType(LabelSlider::FrameNumber);
+1 -1
View File
@@ -61,7 +61,7 @@ public:
static TransitionPtr CreateFromMeta(Clip *c, Clip *s, const EffectMeta* em);
private:
DoubleField* length_field;
DoubleInput* length_field;
private slots:
void UpdateMaximumLength();
+15
View File
@@ -0,0 +1,15 @@
#ifndef INPUTS_H
#define INPUTS_H
#include "inputs/vecinput.h"
#include "inputs/boolinput.h"
#include "inputs/comboinput.h"
#include "inputs/colorinput.h"
#include "inputs/stringinput.h"
#include "inputs/fileinput.h"
#include "inputs/fontinput.h"
#include "widgets/labelwidget.h"
#include "widgets/buttonwidget.h"
#endif // INPUTS_H
+14
View File
@@ -0,0 +1,14 @@
#include "boolinput.h"
BoolInput::BoolInput(Effect* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
EffectRow(parent, id, name, savable, keyframable)
{
BoolField* bool_field = new BoolField(this);
connect(bool_field, SIGNAL(Toggled(bool)), this, SIGNAL(Toggled(bool)));
AddField(bool_field);
}
bool BoolInput::GetBoolAt(double timecode)
{
return static_cast<BoolField*>(Field(0))->GetBoolAt(timecode);
}
+36
View File
@@ -0,0 +1,36 @@
#ifndef BOOLINPUT_H
#define BOOLINPUT_H
#include "effects/effectrow.h"
class BoolInput : public EffectRow
{
Q_OBJECT
public:
BoolInput(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
/**
* @brief Get the boolean value at a given timecode
*
* A wrapper for BoolField::GetBoolAt().
*
* @param timecode
*
* The timecode to retrieve the value at
*
* @return
*
* The boolean value at this timecode
*/
bool GetBoolAt(double timecode);
signals:
/**
* @brief Emitted whenever the UI widget's boolean value has changed
*
* Wrapper for BoolField::Toggled().
*/
void Toggled(bool);
};
#endif // BOOLINPUT_H
+12
View File
@@ -0,0 +1,12 @@
#include "colorinput.h"
ColorInput::ColorInput(Effect* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
EffectRow(parent, id, name, savable, keyframable)
{
AddField(new ColorField(this));
}
QColor ColorInput::GetColorAt(double timecode)
{
static_cast<ColorField*>(Field(0))->GetColorAt(timecode);
}
+28
View File
@@ -0,0 +1,28 @@
#ifndef COLORINPUT_H
#define COLORINPUT_H
#include "effects/effectrow.h"
class ColorInput : public EffectRow
{
Q_OBJECT
public:
ColorInput(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
/**
* @brief Get the color value at a given timecode
*
* Wrapper for ColorField::GetColorAt().
*
* @param timecode
*
* The timecode to retrieve the color at
*
* @return
*
* The color value at this timecode
*/
QColor GetColorAt(double timecode);
};
#endif // COLORINPUT_H
+14
View File
@@ -0,0 +1,14 @@
#include "comboinput.h"
ComboInput::ComboInput(Effect* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
EffectRow(parent, id, name, savable, keyframable)
{
ComboField* combo_field = new ComboField(this);
connect(combo_field, SIGNAL(DataChanged(const QVariant&)), this, SIGNAL(DataChanged(const QVariant&)));
AddField(combo_field);
}
void ComboInput::AddItem(const QString &text, const QVariant &data)
{
static_cast<ComboField*>(Field(0))->AddItem(text, data);
}
+36
View File
@@ -0,0 +1,36 @@
#ifndef COMBOINPUT_H
#define COMBOINPUT_H
#include "effects/effectrow.h"
class ComboInput : public EffectRow
{
Q_OBJECT
public:
ComboInput(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
/**
* @brief Add an item to this ComboInput
*
* Wrapper for ComboField::AddItem.
*
* @param text
*
* The text to show at this index.
*
* @param data
*
* The data to be retrieved at this index.
*/
void AddItem(const QString& text, const QVariant& data);
signals:
/**
* @brief Signal emitted whenever a connected widget's data gets changed
*
* Wrapper for ComboField::DataChanged.
*/
void DataChanged(const QVariant&);
};
#endif // COMBOINPUT_H
-6
View File
@@ -1,6 +0,0 @@
#include "doubleinput.h"
DoubleInput::DoubleInput()
{
}
-12
View File
@@ -1,12 +0,0 @@
#ifndef DOUBLEINPUT_H
#define DOUBLEINPUT_H
#include "effects/effectrow.h"
class DoubleInput : public EffectRow
{
public:
DoubleInput();
};
#endif // DOUBLEINPUT_H
+12
View File
@@ -0,0 +1,12 @@
#include "fileinput.h"
FileInput::FileInput(Effect* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
EffectRow(parent, id, name, savable, keyframable)
{
AddField(new FileField(this));
}
QString FileInput::GetFileAt(double timecode)
{
return static_cast<FileField*>(Field(0))->GetFileAt(timecode);
}
+28
View File
@@ -0,0 +1,28 @@
#ifndef FILEINPUT_H
#define FILEINPUT_H
#include "effects/effectrow.h"
class FileInput : public EffectRow
{
Q_OBJECT
public:
FileInput(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
/**
* @brief Get the filename at the given timecode
*
* A convenience function, equivalent to GetValueAt(timecode).toString()
*
* @param timecode
*
* The timecode to retrieve the filename at
*
* @return
*
* The filename at this timecode
*/
QString GetFileAt(double timecode);
};
#endif // FILEINPUT_H
+12
View File
@@ -0,0 +1,12 @@
#include "fontinput.h"
FontInput::FontInput(Effect* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
EffectRow(parent, id, name, savable, keyframable)
{
AddField(new FontField(this));
}
QString FontInput::GetFontAt(double timecode)
{
return static_cast<FontField*>(Field(0))->GetFontAt(timecode);
}
+28
View File
@@ -0,0 +1,28 @@
#ifndef FONTINPUT_H
#define FONTINPUT_H
#include "effects/effectrow.h"
class FontInput : public EffectRow
{
Q_OBJECT
public:
FontInput(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
/**
* @brief Get the font family name at the given timecode
*
* Wrapper for FontField::GetFontAt().
*
* @param timecode
*
* The timecode to retrieve the font family name at
*
* @return
*
* The font family name at this timecode
*/
QString GetFontAt(double timecode);
};
#endif // FONTINPUT_H
+12
View File
@@ -0,0 +1,12 @@
#include "stringinput.h"
StringInput::StringInput(Effect* parent, const QString& id, const QString& name, bool rich_text, bool savable, bool keyframable) :
EffectRow(parent, id, name, savable, keyframable)
{
AddField(new StringField(this, rich_text));
}
QString StringInput::GetStringAt(double timecode)
{
return static_cast<StringField*>(Field(0))->GetStringAt(timecode);
}
+33
View File
@@ -0,0 +1,33 @@
#ifndef STRINGINPUT_H
#define STRINGINPUT_H
#include "effects/effectrow.h"
class StringInput : public EffectRow
{
Q_OBJECT
public:
StringInput(Effect* parent,
const QString& id,
const QString& name,
bool rich_text = true,
bool savable = true,
bool keyframable = true);
/**
* @brief Get the string at the given timecode
*
* Wrappre for StringField::GetStringAt().
*
* @param timecode
*
* The timecode to retrieve the string at
*
* @return
*
* The string at this timecode
*/
QString GetStringAt(double timecode);
};
#endif // STRINGINPUT_H
+186
View File
@@ -0,0 +1,186 @@
#include "vecinput.h"
#include <QVector3D>
#include <QVector4D>
#include <QDebug>
VecInput::VecInput(Effect* parent, const QString& id, const QString& name, int values, bool savable, bool keyframable) :
EffectRow(parent, id, name, savable, keyframable),
single_value_mode_(false),
values_(values)
{
Q_ASSERT(values_ >= 1 && values_ <= 4);
for (int i=0;i<values_;i++) {
AddField(new DoubleField(this));
}
}
void VecInput::SetMinimum(double minimum)
{
for (int i=0;i<values_;i++) {
static_cast<DoubleField*>(Field(i))->SetMinimum(minimum);
}
}
void VecInput::SetMaximum(double maximum)
{
for (int i=0;i<values_;i++) {
static_cast<DoubleField*>(Field(i))->SetMaximum(maximum);
}
}
void VecInput::SetDefault(double def)
{
for (int i=0;i<values_;i++) {
static_cast<DoubleField*>(Field(i))->SetDefault(def);
}
}
void VecInput::SetDefault(const QVector<double> &def)
{
for (int i=0;i<values_;i++) {
static_cast<DoubleField*>(Field(i))->SetDefault(def.at(i));
}
}
void VecInput::SetDisplayType(LabelSlider::DisplayType type)
{
for (int i=0;i<FieldCount();i++) {
static_cast<DoubleField*>(Field(i))->SetDisplayType(type);
}
}
void VecInput::SetFrameRate(const double &rate)
{
for (int i=0;i<FieldCount();i++) {
static_cast<DoubleField*>(Field(i))->SetFrameRate(rate);
}
}
void VecInput::SetSingleValueMode(bool on)
{
qDebug() << "i'm here";
single_value_mode_ = on;
// Disable all fields except the first
for (int i=1;i<FieldCount();i++) {
Field(i)->SetEnabled(!single_value_mode_);
}
}
DoubleInput::DoubleInput(Effect *parent, const QString &id, const QString &name, bool savable, bool keyframable) :
VecInput(parent, id, name, 1, savable, keyframable)
{
}
double DoubleInput::GetDoubleAt(double timecode)
{
return static_cast<DoubleField*>(Field(0))->GetDoubleAt(timecode);
}
Vec2Input::Vec2Input(Effect *parent, const QString &id, const QString &name, bool savable, bool keyframable) :
VecInput(parent, id, name, 2, savable, keyframable)
{
}
QVector2D Vec2Input::GetVector2DAt(double timecode)
{
return GetValueAt(timecode).value<QVector2D>();
}
QVariant Vec2Input::GetValueAt(double timecode)
{
QVector2D vec2;
vec2.setX(static_cast<DoubleField*>(Field(0))->GetDoubleAt(timecode));
if (single_value_mode_) {
vec2.setY(static_cast<DoubleField*>(Field(0))->GetDoubleAt(timecode));
} else {
vec2.setY(static_cast<DoubleField*>(Field(1))->GetDoubleAt(timecode));
}
return vec2;
}
void Vec2Input::SetValueAt(double timecode, const QVariant &value)
{
QVector2D vec2 = value.value<QVector2D>();
static_cast<DoubleField*>(Field(0))->SetValueAt(timecode, vec2.x());
static_cast<DoubleField*>(Field(1))->SetValueAt(timecode, vec2.y());
}
Vec3Input::Vec3Input(Effect *parent, const QString &id, const QString &name, bool savable, bool keyframable) :
VecInput(parent, id, name, 3, savable, keyframable)
{
}
QVector3D Vec3Input::GetVector3DAt(double timecode)
{
return GetValueAt(timecode).value<QVector3D>();
}
QVariant Vec3Input::GetValueAt(double timecode)
{
QVector3D vec3;
vec3.setX(static_cast<DoubleField*>(Field(0))->GetDoubleAt(timecode));
if (single_value_mode_) {
vec3.setY(static_cast<DoubleField*>(Field(0))->GetDoubleAt(timecode));
vec3.setZ(static_cast<DoubleField*>(Field(0))->GetDoubleAt(timecode));
} else {
vec3.setY(static_cast<DoubleField*>(Field(1))->GetDoubleAt(timecode));
vec3.setZ(static_cast<DoubleField*>(Field(2))->GetDoubleAt(timecode));
}
return vec3;
}
void Vec3Input::SetValueAt(double timecode, const QVariant &value)
{
QVector3D vec3 = value.value<QVector3D>();
static_cast<DoubleField*>(Field(0))->SetValueAt(timecode, vec3.x());
static_cast<DoubleField*>(Field(1))->SetValueAt(timecode, vec3.y());
static_cast<DoubleField*>(Field(2))->SetValueAt(timecode, vec3.z());
}
Vec4Input::Vec4Input(Effect *parent, const QString &id, const QString &name, bool savable, bool keyframable) :
VecInput(parent, id, name, 4, savable, keyframable)
{
}
QVector4D Vec4Input::GetVector4DAt(double timecode)
{
return GetValueAt(timecode).value<QVector4D>();
}
QVariant Vec4Input::GetValueAt(double timecode)
{
QVector4D vec4;
vec4.setX(static_cast<DoubleField*>(Field(0))->GetDoubleAt(timecode));
if (single_value_mode_) {
vec4.setY(static_cast<DoubleField*>(Field(0))->GetDoubleAt(timecode));
vec4.setZ(static_cast<DoubleField*>(Field(0))->GetDoubleAt(timecode));
vec4.setZ(static_cast<DoubleField*>(Field(0))->GetDoubleAt(timecode));
} else {
vec4.setY(static_cast<DoubleField*>(Field(1))->GetDoubleAt(timecode));
vec4.setZ(static_cast<DoubleField*>(Field(2))->GetDoubleAt(timecode));
vec4.setW(static_cast<DoubleField*>(Field(3))->GetDoubleAt(timecode));
}
return vec4;
}
void Vec4Input::SetValueAt(double timecode, const QVariant &value)
{
QVector4D vec4 = value.value<QVector4D>();
static_cast<DoubleField*>(Field(0))->SetValueAt(timecode, vec4.x());
static_cast<DoubleField*>(Field(1))->SetValueAt(timecode, vec4.y());
static_cast<DoubleField*>(Field(2))->SetValueAt(timecode, vec4.z());
static_cast<DoubleField*>(Field(3))->SetValueAt(timecode, vec4.w());
}
+78
View File
@@ -0,0 +1,78 @@
#ifndef VEC2INPUT_H
#define VEC2INPUT_H
#include <QVector2D>
#include "effects/effectrow.h"
class VecInput : public EffectRow
{
Q_OBJECT
public:
VecInput(Effect* parent, const QString& id, const QString& name, int values, bool savable = true, bool keyframable = true);
void SetMinimum(double minimum);
void SetMaximum(double maximum);
void SetDefault(double def);
void SetDefault(const QVector<double> &def);
/**
* @brief Sets the UI display type to a member of LabelSlider::DisplayType.
*/
void SetDisplayType(LabelSlider::DisplayType type);
/**
* @brief For a timecode-based display type, sets the frame rate to be used for the displayed timecode
*
* \see SetDisplayType() and LabelSlider::SetFrameRate().
*/
void SetFrameRate(const double& rate);
protected:
bool single_value_mode_;
public slots:
void SetSingleValueMode(bool on);
private:
int values_;
};
class DoubleInput : public VecInput
{
public:
DoubleInput(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
double GetDoubleAt(double timecode);
};
class Vec2Input : public VecInput {
public:
Vec2Input(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
QVector2D GetVector2DAt(double timecode);
virtual QVariant GetValueAt(double timecode) override;
virtual void SetValueAt(double timecode, const QVariant &value) override;
};
class Vec3Input : public VecInput {
public:
Vec3Input(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
QVector3D GetVector3DAt(double timecode);
virtual QVariant GetValueAt(double timecode) override;
virtual void SetValueAt(double timecode, const QVariant &value) override;
};
class Vec4Input : public VecInput {
public:
Vec4Input(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
QVector4D GetVector4DAt(double timecode);
virtual QVariant GetValueAt(double timecode) override;
virtual void SetValueAt(double timecode, const QVariant &value) override;
};
#endif // VEC2INPUT_H
+8 -8
View File
@@ -12,13 +12,13 @@ namespace nodes {
* Predetermined types of fields. Used throughout Olive to identify what kind of data to expect from GetValueAt().
*
* This enum is also currently used to match an external XML effect's fields with the correct derived class (e.g.
* EFFECT_FIELD_DOUBLE matches to DoubleField).
* EFFECT_FIELD_DOUBLE matches to DoubleInput).
*/
enum DataType {
/** Invalid data type. Used only for error handling. */
kInvalid,
/** Values are doubles. Also corresponds to DoubleField. */
/** Values are doubles. Also corresponds to DoubleInput. */
kFloat,
/** Value is an 2-component vector of floats. */
@@ -33,22 +33,22 @@ enum DataType {
/** Value is an array of floats. This cannot be an input field, and can only be passed between nodes. */
kArray,
/** Values are colors. Equivalent to kVec4 but represents as a color. Corresponds to ColorField. */
/** Values are colors. Equivalent to kVec4 but represents as a color. Corresponds to ColorInput. */
kColor,
/** Values are strings. Also corresponds to StringField. */
/** Values are strings. Also corresponds to StringInput. */
kString,
/** Values are booleans. Also corresponds to BoolField. */
/** Values are booleans. Also corresponds to BoolInput. */
kBoolean,
/** Values are arbitrary data. Also corresponds to ComboField. */
/** Values are arbitrary data. Also corresponds to ComboInput. */
kCombo,
/** Values are font family names (in string). Also corresponds to FontField. */
/** Values are font family names (in string). Also corresponds to FontInput. */
kFont,
/** Values are filenames (in string). Also corresponds to FileField. */
/** Values are filenames (in string). Also corresponds to FileInput. */
kFile,
/** Values are integers. */
+23
View File
@@ -0,0 +1,23 @@
#include "buttonwidget.h"
ButtonWidget::ButtonWidget(Effect* parent, const QString& name, const QString& text) :
EffectRow(parent, nullptr, name, false, false)
{
ButtonField* button_field = new ButtonField(this, text);
connect(button_field, SIGNAL(CheckedChanged(bool)), this, SIGNAL(CheckedChanged(bool)));
connect(button_field, SIGNAL(Toggled(bool)), this, SIGNAL(Toggled(bool)));
connect(this, SLOT(SetChecked(bool)), button_field, SLOT(SetChecked(bool)));
AddField(button_field);
}
void ButtonWidget::SetCheckable(bool c)
{
static_cast<ButtonField*>(Field(0))->SetCheckable(c);
}
void ButtonWidget::SetChecked(bool c)
{
static_cast<ButtonField*>(Field(0))->SetChecked(c);
}
+35
View File
@@ -0,0 +1,35 @@
#ifndef BUTTONWIDGET_H
#define BUTTONWIDGET_H
#include "effects/effectrow.h"
class ButtonWidget : public EffectRow
{
public:
ButtonWidget(Effect* parent, const QString& name, const QString& text);
/**
* @brief Wrapper for ButtonField::SetCheckable.
*/
void SetCheckable(bool c);
public slots:
/**
* @brief Wrapper for ButtonField::SetChecked()
*/
void SetChecked(bool c);
signals:
/**
* @brief Wrapper for ButtonField::CheckedChanged()
*/
void CheckedChanged(bool);
/**
* @brief Wrapper for ButtonField::Toggled()
*/
void Toggled(bool);
};
#endif // BUTTONWIDGET_H
+7
View File
@@ -0,0 +1,7 @@
#include "labelwidget.h"
LabelWidget::LabelWidget(Effect *parent, const QString &name, const QString &text) :
EffectRow(parent, nullptr, name, false, false)
{
AddField(new LabelField(this, text));
}
+12
View File
@@ -0,0 +1,12 @@
#ifndef LABELWIDGET_H
#define LABELWIDGET_H
#include "effects/effectrow.h"
class LabelWidget : public EffectRow
{
public:
LabelWidget(Effect* parent, const QString& name, const QString& text);
};
#endif // LABELWIDGET_H
+19 -2
View File
@@ -194,7 +194,15 @@ SOURCES += \
panels/effectspanel.cpp \
nodes/nodedatatypes.cpp \
nodes/nodeplug.cpp \
nodes/inputs/doubleinput.cpp
nodes/inputs/boolinput.cpp \
nodes/inputs/comboinput.cpp \
nodes/inputs/colorinput.cpp \
nodes/inputs/stringinput.cpp \
nodes/inputs/fontinput.cpp \
nodes/inputs/vecinput.cpp \
nodes/widgets/labelwidget.cpp \
nodes/inputs/fileinput.cpp \
nodes/widgets/buttonwidget.cpp
HEADERS += \
ui/mainwindow.h \
@@ -343,7 +351,16 @@ HEADERS += \
panels/effectspanel.h \
nodes/nodedatatypes.h \
nodes/nodeplug.h \
nodes/inputs/doubleinput.h
nodes/inputs.h \
nodes/inputs/boolinput.h \
nodes/inputs/comboinput.h \
nodes/inputs/colorinput.h \
nodes/inputs/stringinput.h \
nodes/inputs/fontinput.h \
nodes/inputs/vecinput.h \
nodes/widgets/labelwidget.h \
nodes/inputs/fileinput.h \
nodes/widgets/buttonwidget.h
FORMS +=
+3 -3
View File
@@ -149,8 +149,8 @@ void GraphEditor::update_panel() {
int slider_index = 0;
for (int i=0;i<row->FieldCount();i++) {
EffectField* field = row->Field(i);
if (field->type() == olive::nodes::kFloat) {
field->UpdateWidgetValue(field_sliders_.at(slider_index), field->Now());
if (field->type() == EffectField::EFFECT_FIELD_DOUBLE) {
field->UpdateWidgetValue(field_sliders_.at(slider_index), row->GetParentEffect()->Now());
slider_index++;
}
}
@@ -186,7 +186,7 @@ void GraphEditor::set_row(EffectRow *r) {
if (r != nullptr && r->IsKeyframing()) {
for (int i=0;i<r->FieldCount();i++) {
EffectField* field = r->Field(i);
if (field->type() == olive::nodes::kFloat) {
if (field->type() == EffectField::EFFECT_FIELD_DOUBLE) {
QPushButton* slider_button = new QPushButton();
slider_button->setCheckable(true);
slider_button->setChecked(field->IsEnabled());
+7
View File
@@ -260,6 +260,13 @@ void Timeline::toggle_show_all() {
}
}
void Timeline::toggle_links()
{
if (sequence_ != nullptr) {
sequence_->ToggleLinksOnSelected();
}
}
void Timeline::add_transition() {
ComboAction* ca = new ComboAction();
bool adding = false;
+1
View File
@@ -150,6 +150,7 @@ protected:
public slots:
void repaint_timeline();
void toggle_show_all();
void toggle_links();
void deselect();
void split_at_playhead();
void ripple_delete();
+2 -2
View File
@@ -159,8 +159,8 @@ FootageStream* Footage::get_stream_from_file_index(bool video, int index) {
QString Footage::get_interlacing_name(int interlacing) {
switch (interlacing) {
case VIDEO_PROGRESSIVE: return QCoreApplication::translate("InterlacingName", "None (Progressive)");
case VIDEO_TOP_FIELD_FIRST: return QCoreApplication::translate("InterlacingName", "Top Field First");
case VIDEO_BOTTOM_FIELD_FIRST: return QCoreApplication::translate("InterlacingName", "Bottom Field First");
case VIDEO_TOP_FIELD_FIRST: return QCoreApplication::translate("InterlacingName", "Upper Field First");
case VIDEO_BOTTOM_FIELD_FIRST: return QCoreApplication::translate("InterlacingName", "Lower Field First");
default: return QCoreApplication::translate("InterlacingName", "Invalid");
}
}
+5 -5
View File
@@ -127,9 +127,9 @@ EffectUI::EffectUI(Effect* e) :
widgets_[i][j] = widget;
layout_->addWidget(widget, i, column, 1, field->GetColumnSpan());
layout_->addWidget(widget, i, column, 1, 1);
column += field->GetColumnSpan();
column++;
}
// Find maximum column to place keyframe controls
@@ -237,7 +237,7 @@ void EffectUI::UpdateFromEffect()
// Check if this UI object is attached to one effect or many
if (additional_effects_.isEmpty()) {
field->UpdateWidgetValue(Widget(j, k), field->Now());
field->UpdateWidgetValue(Widget(j, k), effect->Now());
} else {
@@ -247,14 +247,14 @@ void EffectUI::UpdateFromEffect()
EffectField* previous_field = i > 0 ? additional_effects_.at(i-1)->row(j)->Field(k) : field;
EffectField* additional_field = additional_effects_.at(i)->row(j)->Field(k);
if (additional_field->GetValueAt(additional_field->Now()) != previous_field->GetValueAt(previous_field->Now())) {
if (additional_field->GetValueAt(additional_effects_.at(i)->Now()) != previous_field->GetValueAt(additional_effects_.at(i-1)->Now())) {
same_value = false;
break;
}
}
if (same_value) {
field->UpdateWidgetValue(Widget(j, k), field->Now());
field->UpdateWidgetValue(Widget(j, k), effect->Now());
} else {
field->UpdateWidgetValue(Widget(j, k), qSNaN());
}