finished moving field data retrieving to row
This commit is contained in:
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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().
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public:
|
||||
int channel_count,
|
||||
int type) override;
|
||||
private:
|
||||
ComboField* fill_type;
|
||||
ComboInput* fill_type;
|
||||
};
|
||||
|
||||
#endif // FILLLEFTRIGHTEFFECT_H
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -34,7 +34,7 @@ public:
|
||||
int channel_count,
|
||||
int type) override;
|
||||
|
||||
DoubleField* pan_val;
|
||||
DoubleInput* pan_val;
|
||||
};
|
||||
|
||||
#endif // PANEFFECT_H
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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];
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -34,7 +34,7 @@ public:
|
||||
int channel_count,
|
||||
int type) override;
|
||||
|
||||
DoubleField* volume_val;
|
||||
DoubleInput* volume_val;
|
||||
};
|
||||
|
||||
#endif // VOLUMEEFFECT_H
|
||||
|
||||
@@ -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)));
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -1,6 +0,0 @@
|
||||
#include "doubleinput.h"
|
||||
|
||||
DoubleInput::DoubleInput()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
#ifndef DOUBLEINPUT_H
|
||||
#define DOUBLEINPUT_H
|
||||
|
||||
#include "effects/effectrow.h"
|
||||
|
||||
class DoubleInput : public EffectRow
|
||||
{
|
||||
public:
|
||||
DoubleInput();
|
||||
};
|
||||
|
||||
#endif // DOUBLEINPUT_H
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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());
|
||||
}
|
||||
@@ -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
|
||||
@@ -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. */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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
|
||||
@@ -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 +=
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user