decoupled ui from effect row

This commit is contained in:
itsmattkc
2019-03-12 20:12:12 +11:00
parent 170fe9bd01
commit 0b090ddc21
45 changed files with 416 additions and 432 deletions
+2 -2
View File
@@ -21,13 +21,13 @@
#include <QtMath>
AudioNoiseEffect::AudioNoiseEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
EffectRow* amount_row = add_row(tr("Amount"));
EffectRow* amount_row = new EffectRow(this, tr("Amount"));
amount_val = new DoubleField(amount_row, "amount");
amount_val->SetMinimum(0);
amount_val->SetDefault(20);
amount_val->SetMaximum(100);
EffectRow* mix_row = add_row(tr("Mix"));
EffectRow* mix_row = new EffectRow(this, tr("Mix"));
mix_val = new BoolField(mix_row, "mix");
mix_val->SetValueAt(0, true);
}
+5 -5
View File
@@ -27,23 +27,23 @@
CornerPinEffect::CornerPinEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
SetFlags(Effect::CoordsFlag & Effect::ShaderFlag);
EffectRow* top_left = add_row(tr("Top Left"));
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");
EffectRow* top_right = add_row(tr("Top Right"));
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");
EffectRow* bottom_left = add_row(tr("Bottom Left"));
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");
EffectRow* bottom_right = add_row(tr("Bottom Right"));
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");
EffectRow* perspective_row = add_row(tr("Perspective"));
EffectRow* perspective_row = new EffectRow(this, tr("Perspective"));
perspective = new BoolField(perspective_row, "perspective");
perspective->SetValueAt(0, true);
+1 -1
View File
@@ -24,7 +24,7 @@
#define FILL_TYPE_RIGHT 1
FillLeftRightEffect::FillLeftRightEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
EffectRow* type_row = add_row(tr("Type"));
EffectRow* type_row = new EffectRow(this, tr("Type"));
fill_type = new ComboField(type_row, "type");
fill_type->AddItem(tr("Fill Left with Right"), FILL_TYPE_LEFT);
fill_type->AddItem(tr("Fill Right with Left"), FILL_TYPE_RIGHT);
+7 -7
View File
@@ -92,7 +92,7 @@ Frei0rEffect::Frei0rEffect(Clip* c, const EffectMeta *em) :
get_param_info(&param_info, i);
if (param_info.type >= 0 && param_info.type <= F0R_PARAM_STRING) {
EffectRow* row = add_row(param_info.name);
EffectRow* row = new EffectRow(this, param_info.name);
switch (param_info.type) {
case F0R_PARAM_BOOL:
new BoolField(row, QString::number(i));
@@ -147,19 +147,19 @@ void Frei0rEffect::process_image(double timecode, uint8_t *input, uint8_t *outpu
switch (param_info.type) {
case F0R_PARAM_BOOL:
{
double b = param_row->field(0)->GetValueAt(timecode).toBool();
double b = param_row->Field(0)->GetValueAt(timecode).toBool();
set_param(instance, &b, i);
}
break;
case F0R_PARAM_DOUBLE:
{
double d = param_row->field(0)->GetValueAt(timecode).toDouble()*0.01;
double d = param_row->Field(0)->GetValueAt(timecode).toDouble()*0.01;
set_param(instance, &d, i);
}
break;
case F0R_PARAM_COLOR:
{
QColor qcolor = param_row->field(0)->GetValueAt(timecode).value<QColor>();
QColor qcolor = param_row->Field(0)->GetValueAt(timecode).value<QColor>();
f0r_param_color fcolor;
fcolor.r = float(qcolor.redF());
@@ -172,14 +172,14 @@ void Frei0rEffect::process_image(double timecode, uint8_t *input, uint8_t *outpu
case F0R_PARAM_POSITION:
{
f0r_param_position pos;
pos.x = param_row->field(0)->GetValueAt(timecode).toDouble();
pos.y = param_row->field(1)->GetValueAt(timecode).toDouble();
pos.x = param_row->Field(0)->GetValueAt(timecode).toDouble();
pos.y = param_row->Field(1)->GetValueAt(timecode).toDouble();
set_param(instance, &pos, i);
}
break;
case F0R_PARAM_STRING:
{
QByteArray bytes = param_row->field(0)->GetValueAt(timecode).toString().toUtf8();
QByteArray bytes = param_row->Field(0)->GetValueAt(timecode).toString().toUtf8();
char* byte_data = bytes.data();
set_param(instance, &byte_data, i);
}
+1 -1
View File
@@ -29,7 +29,7 @@
#include "ui/collapsiblewidget.h"
PanEffect::PanEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
EffectRow* pan_row = add_row(tr("Pan"));
EffectRow* pan_row = new EffectRow(this, tr("Pan"));
pan_val = new DoubleField(pan_row, "pan");
pan_val->SetMinimum(-100);
pan_val->SetDefault(0);
+3 -3
View File
@@ -36,17 +36,17 @@
ShakeEffect::ShakeEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
SetFlags(Effect::CoordsFlag);
EffectRow* intensity_row = add_row(tr("Intensity"));
EffectRow* intensity_row = new EffectRow(this, tr("Intensity"));
intensity_val = new DoubleField(intensity_row, "intensity");
intensity_val->SetMinimum(0);
intensity_val->SetDefault(25);
EffectRow* rotation_row = add_row(tr("Rotation"));
EffectRow* rotation_row = new EffectRow(this, tr("Rotation"));
rotation_val = new DoubleField(rotation_row, "rotation");
rotation_val->SetMinimum(0);
rotation_val->SetDefault(10);
EffectRow* frequency_row = add_row(tr("Frequency"));
EffectRow* frequency_row = new EffectRow(this, tr("Frequency"));
frequency_val = new DoubleField(frequency_row, "frequency");
frequency_val->SetMinimum(0);
frequency_val->SetDefault(5);
+4 -4
View File
@@ -40,23 +40,23 @@ SolidEffect::SolidEffect(Clip* c, const EffectMeta* em) :
SetFlags(Effect::SuperimposeFlag);
// Field for solid type
EffectRow* type_row = add_row(tr("Type"));
EffectRow* type_row = new EffectRow(this, tr("Type"));
solid_type = new ComboField(type_row, "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 = add_row(tr("Opacity"));
EffectRow* opacity_row = new EffectRow(this, tr("Opacity"));
opacity_field = new DoubleField(opacity_row, "opacity");
opacity_field->SetMinimum(0);
opacity_field->SetDefault(0);
opacity_field->SetMaximum(100);
EffectRow* solid_color_row = add_row(tr("Color"));
EffectRow* solid_color_row = new EffectRow(this, tr("Color"));
solid_color_field = new ColorField(solid_color_row, "color");
solid_color_field->SetValueAt(0, QColor(Qt::red));
EffectRow* checkerboard_size = add_row(tr("Checkerboard Size"));
EffectRow* checkerboard_size = new EffectRow(this, tr("Checkerboard Size"));
checkerboard_size_field = new DoubleField(checkerboard_size, "checker_size");
checkerboard_size_field->SetMinimum(1);
checkerboard_size_field->SetDefault(10);
+16 -16
View File
@@ -47,24 +47,24 @@ TextEffect::TextEffect(Clip* c, const EffectMeta* em) :
{
SetFlags(Effect::SuperimposeFlag);
EffectRow* text_field = add_row(tr("Text"));
EffectRow* text_field = new EffectRow(this, tr("Text"));
text_val = new StringField(text_field, "text");
text_val->SetColumnSpan(2);
EffectRow* font_row = add_row(tr("Font"));
EffectRow* font_row = new EffectRow(this, tr("Font"));
set_font_combobox = new FontField(font_row, "font");
set_font_combobox->SetColumnSpan(2);
EffectRow* size_row = add_row(tr("Size"));
EffectRow* size_row = new EffectRow(this, tr("Size"));
size_val = new DoubleField(size_row, "size");
size_val->SetMinimum(0);
size_val->SetColumnSpan(2);
EffectRow* color_row = add_row(tr("Color"));
EffectRow* color_row = new EffectRow(this, tr("Color"));
set_color_button = new ColorField(color_row, "color");
set_color_button->SetColumnSpan(2);
EffectRow* alignment_row = add_row(tr("Alignment"));
EffectRow* alignment_row = new EffectRow(this, tr("Alignment"));
halign_field = new ComboField(alignment_row, "halign");
halign_field->AddItem(tr("Left"), Qt::AlignLeft);
halign_field->AddItem(tr("Center"), Qt::AlignHCenter);
@@ -76,46 +76,46 @@ TextEffect::TextEffect(Clip* c, const EffectMeta* em) :
valign_field->AddItem(tr("Center"), Qt::AlignVCenter);
valign_field->AddItem(tr("Bottom"), Qt::AlignBottom);
EffectRow* word_wrap_row = add_row(tr("Word Wrap"));
EffectRow* word_wrap_row = new EffectRow(this, tr("Word Wrap"));
word_wrap_field = new BoolField(word_wrap_row, "wordwrap");
word_wrap_field->SetColumnSpan(2);
EffectRow* outline_row = add_row(tr("Outline"));
EffectRow* outline_row = new EffectRow(this, tr("Outline"));
outline_bool = new BoolField(outline_row, "outline");
outline_bool->SetColumnSpan(2);
EffectRow* outline_color_row = add_row(tr("Outline Color"));
EffectRow* outline_color_row = new EffectRow(this, tr("Outline Color"));
outline_color = new ColorField(outline_color_row, "outlinecolor");
outline_color->SetColumnSpan(2);
EffectRow* outline_width_row = add_row(tr("Outline Width"));
EffectRow* outline_width_row = new EffectRow(this, tr("Outline Width"));
outline_width = new DoubleField(outline_width_row, "outlinewidth");
outline_width->SetColumnSpan(2);
outline_width->SetMinimum(0);
EffectRow* shadow_row = add_row(tr("Shadow"));
EffectRow* shadow_row = new EffectRow(this, tr("Shadow"));
shadow_bool = new BoolField(shadow_row, "shadow");
shadow_bool->SetColumnSpan(2);
EffectRow* shadow_color_row = add_row(tr("Shadow Color"));
EffectRow* shadow_color_row = new EffectRow(this, tr("Shadow Color"));
shadow_color = new ColorField(shadow_color_row, "shadowcolor");
shadow_color->SetColumnSpan(2);
EffectRow* shadow_angle_row = add_row(tr("Shadow Angle"));
EffectRow* shadow_angle_row = new EffectRow(this, tr("Shadow Angle"));
shadow_angle = new DoubleField(shadow_angle_row, "shadowangle");
shadow_angle->SetColumnSpan(2);
EffectRow* shadow_distance_row = add_row(tr("Shadow Distance"));
EffectRow* shadow_distance_row = new EffectRow(this, tr("Shadow Distance"));
shadow_distance = new DoubleField(shadow_distance_row, "shadowdistance");
shadow_distance->SetColumnSpan(2);
shadow_distance->SetMinimum(0);
EffectRow* shadow_softness_row = add_row(tr("Shadow Softness"));
EffectRow* shadow_softness_row = new EffectRow(this, tr("Shadow Softness"));
shadow_softness = new DoubleField(shadow_softness_row, "shadowsoftness");
shadow_softness->SetColumnSpan(2);
shadow_softness->SetMinimum(0);
EffectRow* shadow_opacity_row = add_row(tr("Shadow Opacity"));
EffectRow* shadow_opacity_row = new EffectRow(this, tr("Shadow Opacity"));
shadow_opacity = new DoubleField(shadow_opacity_row, "shadowopacity");
shadow_opacity->SetColumnSpan(2);
shadow_opacity->SetMinimum(0);
@@ -145,7 +145,7 @@ TextEffect::TextEffect(Clip* c, const EffectMeta* em) :
fragPath = "dropshadow.frag";
}
void blurred2(QImage& result, const QRect& rect, int radius, bool alphaOnly = false) {
void blurred2(QImage& result, const QRect& rect, int radius, bool alphaOnly) {
int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
int alpha = (radius < 1) ? 16 : (radius > 17) ? 1 : tab[radius-1];
+7 -7
View File
@@ -49,41 +49,41 @@ TimecodeEffect::TimecodeEffect(Clip* c, const EffectMeta* em) :
SetAlwaysUpdate(true);
SetFlags(Effect::SuperimposeFlag);
EffectRow* tc_row = add_row(tr("Timecode"));
EffectRow* tc_row = new EffectRow(this, tr("Timecode"));
tc_select = new ComboField(tc_row, "tc_selector");
tc_select->AddItem(tr("Sequence"), true);
tc_select->AddItem(tr("Media"), false);
tc_select->SetValueAt(0, true);
EffectRow* scale_row = add_row(tr("Scale"));
EffectRow* scale_row = new EffectRow(this, tr("Scale"));
scale_val = new DoubleField(scale_row, "scale");
scale_val->SetColumnSpan(2);
scale_val->SetMinimum(1);
scale_val->SetDefault(100);
scale_val->SetMaximum(1000);
EffectRow* color_row = add_row(tr("Color"));
EffectRow* color_row = new EffectRow(this, tr("Color"));
color_val = new ColorField(color_row, "color");
color_val->SetColumnSpan(2);
color_val->SetValueAt(0, QColor(Qt::white));
EffectRow* color_bg_row = add_row(tr("Background Color"));
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->SetValueAt(0, QColor(Qt::black));
EffectRow* bg_alpha_row = add_row(tr("Background Opacity"));
EffectRow* bg_alpha_row = new EffectRow(this, tr("Background Opacity"));
bg_alpha = new DoubleField(bg_alpha_row, "bgalpha");
bg_alpha->SetColumnSpan(2);
bg_alpha->SetMinimum(0);
bg_alpha->SetDefault(50);
bg_alpha->SetMaximum(100);
EffectRow* offset_row = add_row(tr("Offset"));
EffectRow* offset_row = new EffectRow(this, tr("Offset"));
offset_x_val = new DoubleField(offset_row, "offsetx");
offset_y_val = new DoubleField(offset_row, "offsety");
EffectRow* prepent_text_row = add_row(tr("Prepend"));
EffectRow* prepent_text_row = new EffectRow(this, tr("Prepend"));
prepend_text = new StringField(prepent_text_row, "prepend");
prepend_text->SetColumnSpan(2);
}
+4 -4
View File
@@ -29,23 +29,23 @@
#include "debug.h"
ToneEffect::ToneEffect(Clip* c, const EffectMeta *em) : Effect(c, em), sinX(INT_MIN) {
EffectRow* type_row = add_row(tr("Type"));
EffectRow* type_row = new EffectRow(this, tr("Type"));
type_val = new ComboField(type_row, "type");
type_val->AddItem(tr("Sine"), TONE_TYPE_SINE);
EffectRow* frequency_row = add_row(tr("Frequency"));
EffectRow* frequency_row = new EffectRow(this, tr("Frequency"));
freq_val = new DoubleField(frequency_row, "frequency");
freq_val->SetMinimum(20);
freq_val->SetMaximum(20000);
freq_val->SetDefault(1000);
EffectRow* amount_row = add_row(tr("Amount"));
EffectRow* amount_row = new EffectRow(this, tr("Amount"));
amount_val = new DoubleField(amount_row, "amount");
amount_val->SetMinimum(0);
amount_val->SetMaximum(100);
amount_val->SetDefault(25);
EffectRow* mix_row = add_row(tr("Mix"));
EffectRow* mix_row = new EffectRow(this, tr("Mix"));
mix_val = new BoolField(mix_row, "mix");
mix_val->SetValueAt(0, true);
}
+7 -7
View File
@@ -46,12 +46,12 @@
TransformEffect::TransformEffect(Clip* c, const EffectMeta* em) : Effect(c, em) {
SetFlags(Effect::CoordsFlag);
EffectRow* position_row = add_row(tr("Position"));
EffectRow* position_row = new EffectRow(this, tr("Position"));
position_x = new DoubleField(position_row, "posx"); // position X
position_y = new DoubleField(position_row, "posy"); // position Y
EffectRow* scale_row = add_row(tr("Scale"));
EffectRow* scale_row = new EffectRow(this, tr("Scale"));
// scale X (and Y is uniform scale is selected)
scale_x = new DoubleField(scale_row, "scalex");
@@ -61,27 +61,27 @@ TransformEffect::TransformEffect(Clip* c, const EffectMeta* em) : Effect(c, em)
scale_y = new DoubleField(scale_row, "scaley");
scale_y->SetMinimum(0);
EffectRow* uniform_scale_row = add_row(tr("Uniform Scale"));
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 = add_row(tr("Rotation"));
EffectRow* rotation_row = new EffectRow(this, tr("Rotation"));
rotation = new DoubleField(rotation_row, "rotation");
EffectRow* anchor_point_row = add_row(tr("Anchor Point"));
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 = add_row(tr("Opacity"));
EffectRow* opacity_row = new EffectRow(this, tr("Opacity"));
// opacity
opacity = new DoubleField(opacity_row, "opacity");
opacity->SetMinimum(0);
opacity->SetMaximum(100);
EffectRow* blend_mode_row = add_row(tr("Blend Mode"));
EffectRow* blend_mode_row = new EffectRow(this, tr("Blend Mode"));
// blend mode
blend_mode_box = new ComboField(blend_mode_row, "blendmode");
+31 -29
View File
@@ -28,36 +28,38 @@
#include "debug.h"
VoidEffect::VoidEffect(Clip* c, const QString& n) : Effect(c, nullptr) {
name = n;
QString display_name;
if (n.isEmpty()) {
display_name = tr("(unknown)");
} else {
display_name = n;
}
EffectRow* row = add_row(tr("Missing Effect"), false, false);
row->add_widget(new QLabel(display_name));
container->setText(display_name);
name = n;
QString display_name;
if (n.isEmpty()) {
display_name = tr("(unknown)");
} else {
display_name = n;
}
EffectRow* row = new EffectRow(this, tr("Missing Effect"), false, false);
void_meta.type = EFFECT_TYPE_EFFECT;
meta = &void_meta;
new LabelField(row, display_name);
container->setText(display_name);
void_meta.type = EFFECT_TYPE_EFFECT;
meta = &void_meta;
}
EffectPtr VoidEffect::copy(Clip* c) {
EffectPtr copy(new VoidEffect(c, name));
copy->set_enabled(is_enabled());
copy_field_keyframes(copy);
return copy;
copy->set_enabled(is_enabled());
copy_field_keyframes(copy);
return copy;
}
void VoidEffect::load(QXmlStreamReader &stream) {
QString tag = stream.name().toString();
QString tag = stream.name().toString();
QXmlStreamWriter writer(&bytes);
// copy XML from reader to writer
while (!stream.atEnd() && !(stream.name() == tag && stream.isEndElement())) {
stream.readNext();
stream.readNext();
if (stream.isStartElement()) {
writer.writeStartElement(stream.name().toString());
@@ -75,18 +77,18 @@ void VoidEffect::load(QXmlStreamReader &stream) {
}
void VoidEffect::save(QXmlStreamWriter &stream) {
if (!name.isEmpty()) {
stream.writeAttribute("name", name);
stream.writeAttribute("enabled", QString::number(is_enabled()));
if (!name.isEmpty()) {
stream.writeAttribute("name", name);
stream.writeAttribute("enabled", QString::number(is_enabled()));
// force xml writer to expand <effect> tag, ignored when loading
stream.writeStartElement("void");
stream.writeEndElement();
// force xml writer to expand <effect> tag, ignored when loading
stream.writeStartElement("void");
stream.writeEndElement();
if (!bytes.isEmpty()) {
// write stored data
QIODevice* device = stream.device();
device->write(bytes);
}
}
if (!bytes.isEmpty()) {
// write stored data
QIODevice* device = stream.device();
device->write(bytes);
}
}
}
+1 -1
View File
@@ -29,7 +29,7 @@
#include "ui/collapsiblewidget.h"
VolumeEffect::VolumeEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
EffectRow* volume_row = add_row(tr("Volume"));
EffectRow* volume_row = new EffectRow(this, tr("Volume"));
volume_val = new DoubleField(volume_row, "volume");
// set defaults
+9 -8
View File
@@ -266,16 +266,17 @@ VSTHost::VSTHost(Clip* c, const EffectMeta *em) : Effect(c, em) {
outputs[channel] = new float[BLOCK_SIZE];
}
EffectRow* file_row = add_row(tr("Plugin"), true, false);
EffectRow* file_row = new EffectRow(this, tr("Plugin"), true, false);
file_field = new FileField(file_row, "filename");
connect(file_field, SIGNAL(changed()), this, SLOT(change_plugin()));
EffectRow* interface_row = add_row(tr("Interface"), false, false);
show_interface_btn = new QPushButton(tr("Show"));
show_interface_btn->setCheckable(true);
show_interface_btn->setEnabled(false);
EffectRow* interface_row = new EffectRow(this, tr("Interface"), false, false);
show_interface_btn = new ButtonField(interface_row, tr("Show"));
show_interface_btn->SetCheckable(true);
show_interface_btn->SetEnabled(false);
connect(show_interface_btn, SIGNAL(toggled(bool)), this, SLOT(show_interface(bool)));
interface_row->add_widget(show_interface_btn);
dialog = new QDialog(olive::MainWindow);
dialog->setWindowTitle(tr("VST Plugin"));
@@ -373,7 +374,7 @@ void VSTHost::show_interface(bool show) {
}
void VSTHost::uncheck_show_button() {
show_interface_btn->setChecked(false);
show_interface_btn->SetChecked(false);
}
void VSTHost::change_plugin() {
@@ -395,7 +396,7 @@ void VSTHost::change_plugin() {
plugin = nullptr;
}
}
show_interface_btn->setEnabled(plugin != nullptr);
show_interface_btn->SetEnabled(plugin != nullptr);
}
#endif
+2 -2
View File
@@ -37,7 +37,7 @@ typedef intptr_t (*dispatcherFuncPtr)(AEffect *effect, int32_t opCode, int32_t i
class VSTHost : public Effect {
Q_OBJECT
public:
VSTHost(Clip* c, const EffectMeta* em);
VSTHost(Clip* c, const EffectMeta* em);
~VSTHost();
void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count);
@@ -49,6 +49,7 @@ private slots:
void change_plugin();
private:
FileField* file_field;
ButtonField* show_interface_btn;
void loadPlugin();
void freePlugin();
@@ -64,7 +65,6 @@ private:
float** inputs;
float** outputs;
QDialog* dialog;
QPushButton* show_interface_btn;
QByteArray data_cache;
#if defined(__APPLE__)
+6 -2
View File
@@ -168,7 +168,9 @@ SOURCES += \
project/effectfields/stringfield.cpp \
project/effectfields/boolfield.cpp \
project/effectfields/combofield.cpp \
project/effectfields/filefield.cpp
project/effectfields/filefield.cpp \
project/effectfields/labelfield.cpp \
project/effectfields/buttonfield.cpp
HEADERS += \
mainwindow.h \
@@ -290,7 +292,9 @@ HEADERS += \
project/effectfields/stringfield.h \
project/effectfields/boolfield.h \
project/effectfields/combofield.h \
project/effectfields/filefield.h
project/effectfields/filefield.h \
project/effectfields/labelfield.h \
project/effectfields/buttonfield.h
FORMS +=
+10 -10
View File
@@ -141,11 +141,11 @@ void GraphEditor::update_panel() {
if (isVisible()) {
if (row != nullptr) {
int slider_index = 0;
for (int i=0;i<row->fieldCount();i++) {
EffectField* field = row->field(i);
for (int i=0;i<row->FieldCount();i++) {
EffectField* field = row->Field(i);
if (field->type() == EffectField::EFFECT_FIELD_DOUBLE) {
slider_proxies.at(slider_index)->set_value(
row->field(i)->GetValueAt(playhead_to_clip_seconds(field->GetParentRow()->parent_effect->parent_clip,
row->Field(i)->GetValueAt(playhead_to_clip_seconds(field->GetParentRow()->GetParentEffect()->parent_clip,
olive::ActiveSequence->playhead)).toDouble(),
false
);
@@ -177,9 +177,9 @@ void GraphEditor::set_row(EffectRow *r) {
bool found_vals = false;
if (r != nullptr && r->isKeyframing()) {
for (int i=0;i<r->fieldCount();i++) {
EffectField* field = r->field(i);
if (r != nullptr && r->IsKeyframing()) {
for (int i=0;i<r->FieldCount();i++) {
EffectField* field = r->Field(i);
if (field->type() == EffectField::EFFECT_FIELD_DOUBLE) {
QPushButton* slider_button = new QPushButton();
slider_button->setCheckable(true);
@@ -192,7 +192,7 @@ void GraphEditor::set_row(EffectRow *r) {
value_layout->addWidget(slider_button);
LabelSlider* slider = new LabelSlider();
slider->set_color(get_curve_color(i, r->fieldCount()).name());
slider->set_color(get_curve_color(i, r->FieldCount()).name());
connect(slider, SIGNAL(valueChanged()), this, SLOT(passthrough_slider_value()));
slider_proxies.append(slider);
value_layout->addWidget(slider);
@@ -206,10 +206,10 @@ void GraphEditor::set_row(EffectRow *r) {
if (found_vals) {
row = r;
current_row_desc->setText(row->parent_effect->parent_clip->name()
+ " :: " + row->parent_effect->meta->name
current_row_desc->setText(row->GetParentEffect()->parent_clip->name()
+ " :: " + row->GetParentEffect()->meta->name
+ " :: " + row->name());
header->set_visible_in(r->parent_effect->parent_clip->timeline_in());
header->set_visible_in(r->GetParentEffect()->parent_clip->timeline_in());
connect(keyframe_nav, SIGNAL(goto_previous_key()), row, SLOT(goto_previous_key()));
connect(keyframe_nav, SIGNAL(toggle_key()), row, SLOT(toggle_key()));
+2 -2
View File
@@ -442,8 +442,8 @@ void Clip::refactor_frame_rate(ComboAction* ca, double multiplier, bool change_t
EffectPtr e = effects.at(i);
for (int j=0;j<e->row_count();j++) {
EffectRow* r = e->row(j);
for (int l=0;l<r->fieldCount();l++) {
EffectField* f = r->field(l);
for (int l=0;l<r->FieldCount();l++) {
EffectField* f = r->Field(l);
for (int k=0;k<f->keyframes.size();k++) {
ca->append(new SetLong(&f->keyframes[k].time, f->keyframes[k].time, qRound(f->keyframes[k].time * multiplier)));
}
+52 -61
View File
@@ -153,7 +153,7 @@ Effect::Effect(Clip* c, const EffectMeta *em) :
}
}
if (!row_name.isEmpty()) {
EffectRow* row = add_row(row_name);
EffectRow* row = new EffectRow(this, row_name);
while (!reader.atEnd() && !(reader.name() == "row" && reader.isEndElement())) {
reader.readNext();
if (reader.name() == "field" && reader.isStartElement()) {
@@ -356,9 +356,6 @@ Effect::~Effect() {
delete container;
for (int i=0;i<rows.size();i++) {
delete rows.at(i);
}
for (int i=0;i<gizmos.size();i++) {
delete gizmos.at(i);
}
@@ -368,13 +365,13 @@ void Effect::copy_field_keyframes(EffectPtr e) {
for (int i=0;i<rows.size();i++) {
EffectRow* row = rows.at(i);
EffectRow* copy_row = e->rows.at(i);
copy_row->setKeyframing(row->isKeyframing());
for (int j=0;j<row->fieldCount();j++) {
copy_row->SetKeyframing(row->IsKeyframing());
for (int j=0;j<row->FieldCount();j++) {
// Get field from this (the source) effect
EffectField* field = row->field(j);
EffectField* field = row->Field(j);
// Get field from the destination effect
EffectField* copy_field = copy_row->field(j);
EffectField* copy_field = copy_row->Field(j);
// Copy keyframes between effects
copy_field->keyframes = field->keyframes;
@@ -382,12 +379,6 @@ void Effect::copy_field_keyframes(EffectPtr e) {
}
}
EffectRow* Effect::add_row(const QString& name, bool savable, bool keyframable) {
EffectRow* row = new EffectRow(this, savable, ui_layout, name, rows.size(), keyframable);
rows.append(row);
return row;
}
EffectRow* Effect::row(int i) {
return rows.at(i);
}
@@ -575,30 +566,30 @@ void Effect::load(QXmlStreamReader& stream) {
if (stream.name() == "row" && stream.isStartElement()) {
if (row_count < rows.size()) {
EffectRow* row = rows.at(row_count);
int field_count = 0;
while (!stream.atEnd() && !(stream.name() == "row" && stream.isEndElement())) {
stream.readNext();
// read field
if (stream.name() == "field" && stream.isStartElement()) {
if (field_count < row->fieldCount()) {
// match field using ID
int field_number = field_count;
for (int k=0;k<stream.attributes().size();k++) {
const QXmlStreamAttribute& attr = stream.attributes().at(k);
if (attr.name() == "id") {
for (int l=0;l<row->fieldCount();l++) {
if (row->field(l)->id() == attr.value()) {
field_number = l;
break;
}
}
break;
}
}
int field_number = -1;
EffectField* field = row->field(field_number);
// match field using ID
for (int k=0;k<stream.attributes().size();k++) {
const QXmlStreamAttribute& attr = stream.attributes().at(k);
if (attr.name() == "id") {
for (int l=0;l<row->FieldCount();l++) {
if (row->Field(l)->id() == attr.value()) {
field_number = l;
break;
}
}
break;
}
}
if (field_number > -1) {
EffectField* field = row->Field(field_number);
// get current field value
/*
@@ -616,7 +607,7 @@ void Effect::load(QXmlStreamReader& stream) {
// read keyframes
if (stream.name() == "key" && stream.isStartElement()) {
row->setKeyframing(true);
row->SetKeyframing(true);
EffectKeyframe key;
for (int k=0;k<stream.attributes().size();k++) {
@@ -640,10 +631,7 @@ void Effect::load(QXmlStreamReader& stream) {
field->keyframes.append(key);
}
}
} else {
qCritical() << "Too many fields for effect" << id << "row" << row_count << ". Project might be corrupt. (Got" << field_count << ", expected <" << row->fieldCount()-1 << ")";
}
field_count++;
}
}
@@ -665,25 +653,28 @@ void Effect::save(QXmlStreamWriter& stream) {
for (int i=0;i<rows.size();i++) {
EffectRow* row = rows.at(i);
if (row->savable) {
if (row->IsSavable()) {
stream.writeStartElement("row"); // row
for (int j=0;j<row->fieldCount();j++) {
EffectField* field = row->field(j);
stream.writeStartElement("field"); // field
stream.writeAttribute("id", field->id());
for (int k=0;k<field->keyframes.size();k++) {
const EffectKeyframe& key = field->keyframes.at(k);
stream.writeStartElement("key");
stream.writeAttribute("value", field->ConvertValueToString(key.data));
stream.writeAttribute("frame", QString::number(key.time));
stream.writeAttribute("type", QString::number(key.type));
stream.writeAttribute("prehx", QString::number(key.pre_handle_x));
stream.writeAttribute("prehy", QString::number(key.pre_handle_y));
stream.writeAttribute("posthx", QString::number(key.post_handle_x));
stream.writeAttribute("posthy", QString::number(key.post_handle_y));
stream.writeEndElement(); // key
for (int j=0;j<row->FieldCount();j++) {
EffectField* field = row->Field(j);
if (field->id().isEmpty()) {
stream.writeStartElement("field"); // field
stream.writeAttribute("id", field->id());
for (int k=0;k<field->keyframes.size();k++) {
const EffectKeyframe& key = field->keyframes.at(k);
stream.writeStartElement("key");
stream.writeAttribute("value", field->ConvertValueToString(key.data));
stream.writeAttribute("frame", QString::number(key.time));
stream.writeAttribute("type", QString::number(key.type));
stream.writeAttribute("prehx", QString::number(key.pre_handle_x));
stream.writeAttribute("prehy", QString::number(key.pre_handle_y));
stream.writeAttribute("posthx", QString::number(key.post_handle_x));
stream.writeAttribute("posthy", QString::number(key.post_handle_y));
stream.writeEndElement(); // key
}
stream.writeEndElement(); // field
}
stream.writeEndElement(); // field
}
stream.writeEndElement(); // row
}
@@ -694,9 +685,9 @@ void Effect::load_from_string(const QByteArray &s) {
// clear existing keyframe data
for (int i=0;i<rows.size();i++) {
EffectRow* row = rows.at(i);
row->setKeyframing(false);
for (int j=0;j<row->fieldCount();j++) {
EffectField* field = row->field(j);
row->SetKeyframing(false);
for (int j=0;j<row->FieldCount();j++) {
EffectField* field = row->Field(j);
field->keyframes.clear();
}
}
@@ -884,8 +875,8 @@ 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);
for (int j=0;j<row->FieldCount();j++) {
EffectField* field = row->Field(j);
if (!field->id().isEmpty()) {
switch (field->type()) {
case EffectField::EFFECT_FIELD_DOUBLE:
@@ -1070,8 +1061,8 @@ bool Effect::valueHasChanged(double timecode) {
for (int i=0;i<row_count();i++) {
EffectRow* crow = row(i);
for (int j=0;j<crow->fieldCount();j++) {
cachedValues.append(crow->field(j)->GetValueAt(timecode));
for (int j=0;j<crow->FieldCount();j++) {
cachedValues.append(crow->Field(j)->GetValueAt(timecode));
}
}
return true;
@@ -1082,8 +1073,8 @@ bool Effect::valueHasChanged(double timecode) {
int index = 0;
for (int i=0;i<row_count();i++) {
EffectRow* crow = row(i);
for (int j=0;j<crow->fieldCount();j++) {
EffectField* field = crow->field(j);
for (int j=0;j<crow->FieldCount();j++) {
EffectField* field = crow->Field(j);
if (cachedValues.at(index) != field->GetValueAt(timecode)) {
changed = true;
}
-1
View File
@@ -145,7 +145,6 @@ public:
QString name;
CollapsibleWidget* container;
EffectRow* add_row(const QString &name, bool savable = true, bool keyframable = true);
EffectRow* row(int i);
int row_count();
+2
View File
@@ -2,11 +2,13 @@
#define EFFECTFIELDS_H
#include "effectfields/boolfield.h"
#include "effectfields/buttonfield.h"
#include "effectfields/colorfield.h"
#include "effectfields/combofield.h"
#include "effectfields/doublefield.h"
#include "effectfields/filefield.h"
#include "effectfields/fontfield.h"
#include "effectfields/labelfield.h"
#include "effectfields/stringfield.h"
#endif // EFFECTFIELDS_H
+2 -2
View File
@@ -11,8 +11,8 @@ public:
bool GetBoolAt(double timecode);
virtual QVariant ConvertStringToValue(const QString& s);
virtual QString ConvertValueToString(const QVariant& v);
virtual QVariant ConvertStringToValue(const QString& s) override;
virtual QString ConvertValueToString(const QVariant& v) override;
};
#endif // BOOLFIELD_H
+18
View File
@@ -0,0 +1,18 @@
#include "buttonfield.h"
ButtonField::ButtonField(EffectRow *parent, const QString &string) :
EffectField(parent, nullptr, EFFECT_FIELD_UI)
{
SetValueAt(0, string);
}
void ButtonField::SetCheckable(bool c)
{
checkable_ = c;
}
void ButtonField::SetChecked(bool c)
{
checked_ = c;
emit CheckedChanged(c);
}
+21
View File
@@ -0,0 +1,21 @@
#ifndef BUTTONFIELD_H
#define BUTTONFIELD_H
#include "effectfield.h"
class ButtonField : public EffectField
{
Q_OBJECT
public:
ButtonField(EffectRow* parent, const QString& string);
void SetCheckable(bool c);
void SetChecked(bool c);
signals:
void CheckedChanged(bool);
private:
bool checkable_;
bool checked_;
};
#endif // BUTTONFIELD_H
+2 -2
View File
@@ -11,8 +11,8 @@ public:
QColor GetColorAt(double timecode);
virtual QVariant ConvertStringToValue(const QString& s);
virtual QString ConvertValueToString(const QVariant& v);
virtual QVariant ConvertStringToValue(const QString& s) override;
virtual QString ConvertValueToString(const QVariant& v) override;
};
#endif // COLORFIELD_H
-10
View File
@@ -13,13 +13,3 @@ void ComboField::AddItem(const QString &text, const QVariant &data)
items_.append(item);
}
QVariant ComboField::ConvertStringToValue(const QString &s)
{
return s;
}
QString ComboField::ConvertValueToString(const QVariant &v)
{
return v.toString();
}
-3
View File
@@ -16,9 +16,6 @@ public:
void AddItem(const QString& text, const QVariant& data);
virtual QVariant ConvertStringToValue(const QString& s);
virtual QString ConvertValueToString(const QVariant& v);
signals:
void IndexChanged(int i);
+18 -8
View File
@@ -52,7 +52,7 @@ EffectField::EffectField(EffectRow* parent, const QString &i, EffectFieldType t)
{
// EffectField MUST be created with a parent.
Q_ASSERT(parent != nullptr);
Q_ASSERT(!i.isEmpty());
Q_ASSERT(!i.isEmpty() || t == EFFECT_FIELD_UI);
parent->AddField(this);
/*
@@ -141,6 +141,16 @@ void EffectField::SetColumnSpan(int i)
colspan_ = i;
}
QVariant EffectField::ConvertStringToValue(const QString &s)
{
return s;
}
QString EffectField::ConvertValueToString(const QVariant &v)
{
return v.toString();
}
QVariant EffectField::GetValueAt(double timecode)
{
Q_ASSERT(!keyframes.isEmpty());
@@ -172,15 +182,15 @@ QVariant EffectField::GetValueAt(double timecode)
// bezier interpolation
if (before_key.type == EFFECT_KEYFRAME_BEZIER && after_key.type == EFFECT_KEYFRAME_BEZIER) {
// cubic bezier
double t = cubic_t_from_x(timecode*GetParentRow()->parent_effect->parent_clip->sequence->frame_rate, before_key.time, before_key.time+GetValidKeyframeHandlePosition(before_keyframe, true), after_key.time+GetValidKeyframeHandlePosition(after_keyframe, false), after_key.time);
double t = cubic_t_from_x(timecode*GetParentRow()->GetParentEffect()->parent_clip->sequence->frame_rate, before_key.time, before_key.time+GetValidKeyframeHandlePosition(before_keyframe, true), after_key.time+GetValidKeyframeHandlePosition(after_keyframe, false), after_key.time);
value = cubic_from_t(before_dbl, before_dbl+before_key.post_handle_y, after_dbl+after_key.pre_handle_y, after_dbl, t);
} else if (after_key.type == EFFECT_KEYFRAME_LINEAR) { // quadratic bezier
// last keyframe is the bezier one
double t = quad_t_from_x(timecode*GetParentRow()->parent_effect->parent_clip->sequence->frame_rate, before_key.time, before_key.time+GetValidKeyframeHandlePosition(before_keyframe, true), after_key.time);
double t = quad_t_from_x(timecode*GetParentRow()->GetParentEffect()->parent_clip->sequence->frame_rate, before_key.time, before_key.time+GetValidKeyframeHandlePosition(before_keyframe, true), after_key.time);
value = quad_from_t(before_dbl, before_dbl+before_key.post_handle_y, after_dbl, t);
} else {
// this keyframe is the bezier one
double t = quad_t_from_x(timecode*GetParentRow()->parent_effect->parent_clip->sequence->frame_rate, before_key.time, after_key.time+GetValidKeyframeHandlePosition(after_keyframe, false), after_key.time);
double t = quad_t_from_x(timecode*GetParentRow()->GetParentEffect()->parent_clip->sequence->frame_rate, before_key.time, after_key.time+GetValidKeyframeHandlePosition(after_keyframe, false), after_key.time);
value = quad_from_t(before_dbl, after_dbl+after_key.pre_handle_y, after_dbl, t);
}
} else {
@@ -223,7 +233,7 @@ void EffectField::SetValueAt(double timecode, const QVariant &value)
return;
}
if (GetParentRow()->isKeyframing()) {
if (GetParentRow()->IsKeyframing()) {
// create keyframe here
} else {
keyframes.first().data = value;
@@ -289,11 +299,11 @@ double EffectField::GetValidKeyframeHandlePosition(int key, bool post) {
}
double EffectField::frameToTimecode(long frame) {
return (double(frame) / GetParentRow()->parent_effect->parent_clip->sequence->frame_rate);
return (double(frame) / GetParentRow()->GetParentEffect()->parent_clip->sequence->frame_rate);
}
long EffectField::timecodeToFrame(double timecode) {
return qRound(timecode * GetParentRow()->parent_effect->parent_clip->sequence->frame_rate);
return qRound(timecode * GetParentRow()->GetParentEffect()->parent_clip->sequence->frame_rate);
}
void EffectField::get_keyframe_data(double timecode, int &before, int &after, double &progress) {
@@ -333,7 +343,7 @@ void EffectField::get_keyframe_data(double timecode, int &before, int &after, do
}
bool EffectField::HasKeyframes() {
return (GetParentRow()->isKeyframing() && keyframes.size() > 1);
return (GetParentRow()->IsKeyframing() && keyframes.size() > 1);
}
void EffectField::ui_element_change() {
+4 -3
View File
@@ -40,7 +40,8 @@ public:
EFFECT_FIELD_BOOL,
EFFECT_FIELD_COMBO,
EFFECT_FIELD_FONT,
EFFECT_FIELD_FILE
EFFECT_FIELD_FILE,
EFFECT_FIELD_UI
};
EffectField(EffectRow* parent, const QString& i, EffectFieldType t);
@@ -57,8 +58,8 @@ public:
int GetColumnSpan();
void SetColumnSpan(int i);
virtual QVariant ConvertStringToValue(const QString& s) = 0;
virtual QString ConvertValueToString(const QVariant& v) = 0;
virtual QVariant ConvertStringToValue(const QString& s);
virtual QString ConvertValueToString(const QVariant& v);
double GetValidKeyframeHandlePosition(int key, bool post);
-10
View File
@@ -10,13 +10,3 @@ QString FileField::GetFileAt(double timecode)
{
return GetValueAt(timecode).toString();
}
QVariant FileField::ConvertStringToValue(const QString &s)
{
return s;
}
QString FileField::ConvertValueToString(const QVariant &v)
{
return v.toString();
}
-3
View File
@@ -10,9 +10,6 @@ public:
FileField(EffectRow* parent, const QString& id);
QString GetFileAt(double timecode);
virtual QVariant ConvertStringToValue(const QString& s);
virtual QString ConvertValueToString(const QVariant& v);
};
#endif // FILEFIELD_H
-10
View File
@@ -10,13 +10,3 @@ QString FontField::GetFontAt(double timecode)
{
return GetValueAt(timecode).toString();
}
QVariant FontField::ConvertStringToValue(const QString &s)
{
return s;
}
QString FontField::ConvertValueToString(const QVariant &v)
{
return v.toString();
}
-3
View File
@@ -9,9 +9,6 @@ public:
FontField(EffectRow* parent, const QString& id);
QString GetFontAt(double timecode);
virtual QVariant ConvertStringToValue(const QString& s);
virtual QString ConvertValueToString(const QVariant& v);
};
#endif // FONTFIELD_H
+7
View File
@@ -0,0 +1,7 @@
#include "labelfield.h"
LabelField::LabelField(EffectRow *parent, const QString &string) :
EffectField(parent, nullptr, EFFECT_FIELD_UI)
{
SetValueAt(0, string);
}
+13
View File
@@ -0,0 +1,13 @@
#ifndef LABELFIELD_H
#define LABELFIELD_H
#include "effectfield.h"
class LabelField : public EffectField
{
Q_OBJECT
public:
LabelField(EffectRow* parent, const QString& string);
};
#endif // LABELFIELD_H
-10
View File
@@ -10,13 +10,3 @@ QString StringField::GetStringAt(double timecode)
{
return GetValueAt(timecode).toString();
}
QVariant StringField::ConvertStringToValue(const QString &s)
{
return s;
}
QString StringField::ConvertValueToString(const QVariant &v)
{
return v.toString();
}
-3
View File
@@ -10,9 +10,6 @@ public:
StringField(EffectRow* parent, const QString& id);
QString GetStringAt(double timecode);
virtual QVariant ConvertStringToValue(const QString& s);
virtual QString ConvertValueToString(const QVariant& v);
};
#endif // STRINGFIELD_H
+43 -81
View File
@@ -36,41 +36,14 @@
#include "ui/keyframenavigator.h"
#include "ui/clickablelabel.h"
EffectRow::EffectRow(Effect *parent, bool save, QGridLayout *uilayout, const QString &n, int row, bool keyframable) :
parent_effect(parent),
savable(save),
keyframing(false),
ui(uilayout),
EffectRow::EffectRow(Effect *parent, const QString &n, bool savable, bool keyframable) :
QObject(parent),
name_(n),
ui_row(row),
just_made_unsafe_keyframe(false)
keyframable_(keyframable),
keyframing_(false),
savable_(savable)
{
label = new ClickableLabel(name_ + ":");
ui->addWidget(label, row, 0);
column_count = 1;
keyframe_nav = nullptr;
if (parent_effect->meta != nullptr
&& parent_effect->meta->type != EFFECT_TYPE_TRANSITION
&& keyframable) {
connect(label, SIGNAL(clicked()), this, SLOT(FocusRow()));
keyframe_nav = new KeyframeNavigator();
connect(keyframe_nav, SIGNAL(GoToPreviousKeyframe()), this, SLOT(GoToPreviousKeyframe()));
connect(keyframe_nav, SIGNAL(ToggleKeyframe()), this, SLOT(ToggleKeyframe()));
connect(keyframe_nav, SIGNAL(GoToNextKeyframe()), this, SLOT(GoToNextKeyframe()));
connect(keyframe_nav, SIGNAL(keyframe_enabled_changed(bool)), this, SLOT(SetKeyframingEnabled(bool)));
connect(keyframe_nav, SIGNAL(clicked()), this, SLOT(FocusRow()));
ui->addWidget(keyframe_nav, row, 6);
}
}
EffectRow::~EffectRow() {
for (int i=0;i<fields_.size();i++) {
delete fields_.at(i);
}
Q_ASSERT(parent != nullptr);
}
void EffectRow::AddField(EffectField *field)
@@ -79,52 +52,55 @@ void EffectRow::AddField(EffectField *field)
fields_.append(field);
}
bool EffectRow::isKeyframing() {
return keyframing;
bool EffectRow::IsKeyframing() {
return keyframing_;
}
void EffectRow::setKeyframing(bool b) {
if (parent_effect->meta->type != EFFECT_TYPE_TRANSITION) {
keyframing = b;
if (keyframe_nav != nullptr) {
keyframe_nav->enable_keyframes(b);
}
void EffectRow::SetKeyframing(bool b) {
if (GetParentEffect()->meta->type != EFFECT_TYPE_TRANSITION) {
keyframing_ = b;
emit KeyframingSetChanged(keyframing_);
}
}
bool EffectRow::IsSavable()
{
return savable_;
}
void EffectRow::SetKeyframingEnabled(bool enabled) {
if (enabled) {
ComboAction* ca = new ComboAction();
ca->append(new SetKeyframing(this, true));
ca->append(new SetIsKeyframing(this, true));
set_keyframe_now(ca);
olive::UndoStack.push(ca);
} else {
if (QMessageBox::question(panel_effect_controls,
tr("Disable Keyframes"),
tr("Disabling keyframes will delete all current keyframes. Are you sure you want to do this?"),
QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
tr("Disable Keyframes"),
tr("Disabling keyframes will delete all current keyframes. Are you sure you want to do this?"),
QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
// clear
ComboAction* ca = new ComboAction();
for (int i=0;i<fieldCount();i++) {
EffectField* f = field(i);
for (int i=0;i<FieldCount();i++) {
EffectField* f = Field(i);
for (int j=0;j<f->keyframes.size();j++) {
ca->append(new KeyframeDelete(f, 0));
}
}
ca->append(new SetKeyframing(this, false));
ca->append(new SetIsKeyframing(this, false));
olive::UndoStack.push(ca);
panel_effect_controls->update_keyframes();
} else {
setKeyframing(true);
SetKeyframing(true);
}
}
}
void EffectRow::GoToPreviousKeyframe() {
long key = LONG_MIN;
Clip* c = parent_effect->parent_clip;
for (int i=0;i<fieldCount();i++) {
EffectField* f = field(i);
Clip* c = GetParentEffect()->parent_clip;
for (int i=0;i<FieldCount();i++) {
EffectField* f = Field(i);
for (int j=0;j<f->keyframes.size();j++) {
long comp = f->keyframes.at(j).time - c->clip_in() + c->timeline_in();
if (comp < olive::ActiveSequence->playhead) {
@@ -138,9 +114,9 @@ void EffectRow::GoToPreviousKeyframe() {
void EffectRow::ToggleKeyframe() {
QVector<EffectField*> key_fields;
QVector<int> key_field_index;
Clip* c = parent_effect->parent_clip;
for (int j=0;j<fieldCount();j++) {
EffectField* f = field(j);
Clip* c = GetParentEffect()->parent_clip;
for (int j=0;j<FieldCount();j++) {
EffectField* f = Field(j);
for (int i=0;i<f->keyframes.size();i++) {
long comp = c->timeline_in() - c->clip_in() + f->keyframes.at(i).time;
if (comp == olive::ActiveSequence->playhead) {
@@ -165,9 +141,9 @@ void EffectRow::ToggleKeyframe() {
void EffectRow::GoToNextKeyframe() {
long key = LONG_MAX;
Clip* c = parent_effect->parent_clip;
for (int i=0;i<fieldCount();i++) {
EffectField* f = field(i);
Clip* c = GetParentEffect()->parent_clip;
for (int i=0;i<FieldCount();i++) {
EffectField* f = Field(i);
for (int j=0;j<f->keyframes.size();j++) {
long comp = f->keyframes.at(j).time - c->clip_in() + c->timeline_in();
if (comp > olive::ActiveSequence->playhead) {
@@ -182,25 +158,6 @@ void EffectRow::FocusRow() {
panel_graph_editor->set_row(this);
}
/*
EffectField* EffectRow::add_field(int type, const QString& id, int colspan) {
EffectField* field = new EffectField(this, type, id);
if (parent_effect->meta->type != EFFECT_TYPE_TRANSITION) connect(field, SIGNAL(clicked()), this, SLOT(focus_row()));
fields_.append(field);
QWidget* element = field->get_ui_element();
ui->addWidget(element, ui_row, column_count, 1, colspan);
column_count++;
connect(field, SIGNAL(changed()), parent_effect, SLOT(field_changed()));
return field;
}
*/
void EffectRow::add_widget(QWidget* w) {
widgets.append(w);
ui->addWidget(w, ui_row, column_count);
column_count++;
}
void EffectRow::set_keyframe_now(ComboAction* ca) {
// TODO address this...
/*
@@ -263,8 +220,8 @@ void EffectRow::set_keyframe_now(ComboAction* ca) {
}
void EffectRow::delete_keyframe_at_time(ComboAction* ca, long time) {
for (int j=0;j<fieldCount();j++) {
EffectField* f = field(j);
for (int j=0;j<FieldCount();j++) {
EffectField* f = Field(j);
for (int i=0;i<f->keyframes.size();i++) {
if (f->keyframes.at(i).time == time) {
ca->append(new KeyframeDelete(f, i));
@@ -274,14 +231,19 @@ void EffectRow::delete_keyframe_at_time(ComboAction* ca, long time) {
}
}
Effect *EffectRow::GetParentEffect()
{
return static_cast<Effect*>(parent());
}
const QString &EffectRow::name() {
return name_;
}
EffectField* EffectRow::field(int i) {
EffectField* EffectRow::Field(int i) {
return fields_.at(i);
}
int EffectRow::fieldCount() {
int EffectRow::FieldCount() {
return fields_.size();
}
+18 -24
View File
@@ -39,46 +39,40 @@ class ClickableLabel;
class EffectRow : public QObject {
Q_OBJECT
public:
EffectRow(Effect* parent, bool save, QGridLayout* uilayout, const QString& n, int row, bool keyframable = true);
~EffectRow();
EffectRow(Effect* parent, const QString& n, bool savable = true, bool keyframable = true);
void AddField(EffectField* field);
void AddField(EffectField* Field);
void add_widget(QWidget *w);
EffectField* field(int i);
int fieldCount();
EffectField* Field(int i);
int FieldCount();
void set_keyframe_now(ComboAction *ca);
void delete_keyframe_at_time(ComboAction *ca, long time);
ClickableLabel* label;
Effect* parent_effect;
bool savable;
Effect* GetParentEffect();
const QString& name();
bool isKeyframing();
void setKeyframing(bool);
bool IsKeyframing();
void SetKeyframing(bool);
bool IsSavable();
public slots:
void GoToPreviousKeyframe();
void ToggleKeyframe();
void GoToNextKeyframe();
void FocusRow();
signals:
void KeyframingSetChanged(bool);
private slots:
void SetKeyframingEnabled(bool);
private:
bool keyframing;
QGridLayout* ui;
QString name_;
int ui_row;
bool keyframable_;
bool keyframing_;
bool savable_;
QVector<EffectField*> fields_;
QVector<QWidget*> widgets;
KeyframeNavigator* keyframe_nav;
bool just_made_unsafe_keyframe;
QVector<int> unsafe_keys;
QVector<QVariant> unsafe_old_data;
QVector<bool> key_is_new;
int column_count;
};
#endif // EFFECTROW_H
+1 -1
View File
@@ -45,7 +45,7 @@ Transition::Transition(Clip *c, Clip *s, const EffectMeta* em) :
Effect(c, em),
secondary_clip(s)
{
EffectRow* length_row = add_row(tr("Length"), false, false);
EffectRow* length_row = new EffectRow(this, tr("Length"), false, false);
length_field = new DoubleField(length_row, "length");
length_field->SetDefault(30);
length_field->SetMinimum(0);
+5 -5
View File
@@ -1136,17 +1136,17 @@ void KeyframeFieldSet::doRedo() {
done = true;
}
SetKeyframing::SetKeyframing(EffectRow *irow, bool ib) {
SetIsKeyframing::SetIsKeyframing(EffectRow *irow, bool ib) {
row = irow;
b = ib;
}
void SetKeyframing::doUndo() {
row->setKeyframing(!b);
void SetIsKeyframing::doUndo() {
row->SetKeyframing(!b);
}
void SetKeyframing::doRedo() {
row->setKeyframing(b);
void SetIsKeyframing::doRedo() {
row->SetKeyframing(b);
}
RefreshClips::RefreshClips(Media *m) {
+2 -2
View File
@@ -600,9 +600,9 @@ private:
QVariant new_val;
};
class SetKeyframing : public OliveAction {
class SetIsKeyframing : public OliveAction {
public:
SetKeyframing(EffectRow* irow, bool ib);
SetIsKeyframing(EffectRow* irow, bool ib);
virtual void doUndo() override;
virtual void doRedo() override;
private:
+37 -37
View File
@@ -120,15 +120,15 @@ void GraphView::set_view_to_selection() {
double min_dbl = DBL_MAX;
double max_dbl = DBL_MIN;
for (int i=0;i<selected_keys.size();i++) {
const EffectKeyframe& key = row->field(selected_keys_fields.at(i))->keyframes.at(selected_keys.at(i));
const EffectKeyframe& key = row->Field(selected_keys_fields.at(i))->keyframes.at(selected_keys.at(i));
min_time = qMin(key.time, min_time);
max_time = qMax(key.time, max_time);
min_dbl = qMin(key.data.toDouble(), min_dbl);
max_dbl = qMax(key.data.toDouble(), max_dbl);
}
min_time -= row->parent_effect->parent_clip->clip_in();
max_time -= row->parent_effect->parent_clip->clip_in();
min_time -= row->GetParentEffect()->parent_clip->clip_in();
max_time -= row->GetParentEffect()->parent_clip->clip_in();
set_view_to_rect(min_time, min_dbl, max_time, max_dbl);
}
@@ -142,9 +142,9 @@ void GraphView::set_view_to_all() {
long max_time = LONG_MIN;
double min_dbl = DBL_MAX;
double max_dbl = DBL_MIN;
for (int i=0;i<row->fieldCount();i++) {
for (int j=0;j<row->field(i)->keyframes.size();j++) {
const EffectKeyframe& key = row->field(i)->keyframes.at(j);
for (int i=0;i<row->FieldCount();i++) {
for (int j=0;j<row->Field(i)->keyframes.size();j++) {
const EffectKeyframe& key = row->Field(i)->keyframes.at(j);
min_time = qMin(key.time, min_time);
max_time = qMax(key.time, max_time);
min_dbl = qMin(key.data.toDouble(), min_dbl);
@@ -153,8 +153,8 @@ void GraphView::set_view_to_all() {
}
}
if (can_set) {
min_time -= row->parent_effect->parent_clip->clip_in();
max_time -= row->parent_effect->parent_clip->clip_in();
min_time -= row->GetParentEffect()->parent_clip->clip_in();
max_time -= row->GetParentEffect()->parent_clip->clip_in();
set_view_to_rect(min_time, min_dbl, max_time, max_dbl);
}
@@ -242,8 +242,8 @@ void GraphView::paintEvent(QPaintEvent *) {
QPen line_pen;
line_pen.setWidth(kBezierLineSize);
for (int i=row->fieldCount()-1;i>=0;i--) {
EffectField* field = row->field(i);
for (int i=row->FieldCount()-1;i>=0;i--) {
EffectField* field = row->Field(i);
if (field->type() == EffectField::EFFECT_FIELD_DOUBLE && field_visibility.at(i)) {
// sort keyframes by time
@@ -259,7 +259,7 @@ void GraphView::paintEvent(QPaintEvent *) {
int key_x = get_screen_x(key.time);
int key_y = get_screen_y(key.data.toDouble());
line_pen.setColor(get_curve_color(i, row->fieldCount()));
line_pen.setColor(get_curve_color(i, row->FieldCount()));
p.setPen(line_pen);
if (j == 0) {
p.drawLine(0, key_y, key_x, key_y);
@@ -385,8 +385,8 @@ void GraphView::mousePressEvent(QMouseEvent *event) {
update_ui(false);
click_add_proc = true;
} else {
for (int i=0;i<row->fieldCount();i++) {
EffectField* field = row->field(i);
for (int i=0;i<row->FieldCount();i++) {
EffectField* field = row->Field(i);
if (field->type() == EffectField::EFFECT_FIELD_DOUBLE && field_visibility.at(i)) {
for (int j=0;j<field->keyframes.size();j++) {
const EffectKeyframe& key = field->keyframes.at(j);
@@ -488,8 +488,8 @@ void GraphView::mouseMoveEvent(QMouseEvent *event) {
selected_keys.resize(rect_select_offset);
selected_keys_fields.resize(rect_select_offset);
for (int i=0;i<row->fieldCount();i++) {
EffectField* f = row->field(i);
for (int i=0;i<row->FieldCount();i++) {
EffectField* f = row->Field(i);
for (int j=0;j<f->keyframes.size();j++) {
bool already_selected = false;
for (int k=0;k<selected_keys.size();k++) {
@@ -514,11 +514,11 @@ void GraphView::mouseMoveEvent(QMouseEvent *event) {
switch (current_handle) {
case kBezierHandleNone:
for (int i=0;i<selected_keys.size();i++) {
row->field(selected_keys_fields.at(i))->keyframes[selected_keys.at(i)].time = qRound(selected_keys_old_vals.at(i) + (double(event->pos().x() - start_x)/x_zoom));
row->Field(selected_keys_fields.at(i))->keyframes[selected_keys.at(i)].time = qRound(selected_keys_old_vals.at(i) + (double(event->pos().x() - start_x)/x_zoom));
if (event->modifiers() & Qt::ShiftModifier) {
row->field(selected_keys_fields.at(i))->keyframes[selected_keys.at(i)].data = selected_keys_old_doubles.at(i);
row->Field(selected_keys_fields.at(i))->keyframes[selected_keys.at(i)].data = selected_keys_old_doubles.at(i);
} else {
row->field(selected_keys_fields.at(i))->keyframes[selected_keys.at(i)].data = qRound(selected_keys_old_doubles.at(i) + (double(start_y - event->pos().y())/y_zoom));
row->Field(selected_keys_fields.at(i))->keyframes[selected_keys.at(i)].data = qRound(selected_keys_old_doubles.at(i) + (double(start_y - event->pos().y())/y_zoom));
}
}
moved_keys = true;
@@ -551,7 +551,7 @@ void GraphView::mouseMoveEvent(QMouseEvent *event) {
}
}
EffectKeyframe& key = row->field(handle_field)->keyframes[handle_index];
EffectKeyframe& key = row->Field(handle_field)->keyframes[handle_index];
key.pre_handle_x = qMin(0.0, new_pre_handle_x);
key.pre_handle_y = new_pre_handle_y;
key.post_handle_x = qMax(0.0, new_post_handle_x);
@@ -569,9 +569,9 @@ void GraphView::mouseMoveEvent(QMouseEvent *event) {
bool hovering_key = false;
for (int i=0;i<row->fieldCount();i++) {
for (int j=0;j<row->field(i)->keyframes.size();j++) {
const EffectKeyframe& key = row->field(i)->keyframes.at(j);
for (int i=0;i<row->FieldCount();i++) {
for (int j=0;j<row->Field(i)->keyframes.size();j++) {
const EffectKeyframe& key = row->Field(i)->keyframes.at(j);
int key_x = get_screen_x(key.time);
int key_y = get_screen_y(key.data.toDouble());
QRect test_rect(
@@ -603,8 +603,8 @@ void GraphView::mouseMoveEvent(QMouseEvent *event) {
}
if (!hovering_key) {
for (int i=0;i<row->fieldCount();i++) {
EffectField* f = row->field(i);
for (int i=0;i<row->FieldCount();i++) {
EffectField* f = row->Field(i);
if (field_visibility.at(i)) {
QVector<int> sorted_keys = sort_keys_from_field(f);
@@ -708,7 +708,7 @@ void GraphView::mouseReleaseEvent(QMouseEvent *) {
switch (current_handle) {
case kBezierHandleNone:
for (int i=0;i<selected_keys.size();i++) {
EffectKeyframe& key = row->field(selected_keys_fields.at(i))->keyframes[selected_keys.at(i)];
EffectKeyframe& key = row->Field(selected_keys_fields.at(i))->keyframes[selected_keys.at(i)];
ca->append(new SetLong(&key.time, selected_keys_old_vals.at(i), key.time));
ca->append(new SetQVariant(&key.data, selected_keys_old_doubles.at(i), key.data));
}
@@ -716,7 +716,7 @@ void GraphView::mouseReleaseEvent(QMouseEvent *) {
case kBezierHandlePre:
case kBezierHandlePost:
{
EffectKeyframe& key = row->field(handle_field)->keyframes[handle_index];
EffectKeyframe& key = row->Field(handle_field)->keyframes[handle_index];
ca->append(new SetDouble(&key.pre_handle_x, old_pre_handle_x, key.pre_handle_x));
ca->append(new SetDouble(&key.pre_handle_y, old_pre_handle_y, key.pre_handle_y));
ca->append(new SetDouble(&key.post_handle_x, old_post_handle_x, key.post_handle_x));
@@ -831,11 +831,11 @@ void GraphView::set_row(EffectRow *r) {
emit selection_changed(false, -1);
row = r;
if (row != nullptr) {
field_visibility.resize(row->fieldCount());
for (int i=0;i<row->fieldCount();i++) {
field_visibility[i] = row->field(i)->IsEnabled();
field_visibility.resize(row->FieldCount());
for (int i=0;i<row->FieldCount();i++) {
field_visibility[i] = row->Field(i)->IsEnabled();
}
visible_in = row->parent_effect->parent_clip->timeline_in();
visible_in = row->GetParentEffect()->parent_clip->timeline_in();
set_view_to_all();
} else {
update();
@@ -847,7 +847,7 @@ void GraphView::set_selected_keyframe_type(int type) {
if (selected_keys.size() > 0) {
ComboAction* ca = new ComboAction();
for (int i=0;i<selected_keys.size();i++) {
EffectKeyframe& key = row->field(selected_keys_fields.at(i))->keyframes[selected_keys.at(i)];
EffectKeyframe& key = row->Field(selected_keys_fields.at(i))->keyframes[selected_keys.at(i)];
ca->append(new SetInt(&key.type, type));
}
olive::UndoStack.push(ca);
@@ -864,7 +864,7 @@ void GraphView::delete_selected_keys() {
if (row != nullptr) {
QVector<EffectField*> fields;
for (int i=0;i<selected_keys_fields.size();i++) {
fields.append(row->field(selected_keys_fields.at(i)));
fields.append(row->Field(selected_keys_fields.at(i)));
}
delete_keyframes(fields, selected_keys);
}
@@ -874,8 +874,8 @@ void GraphView::select_all() {
if (row != nullptr) {
selected_keys.clear();
selected_keys_fields.clear();
for (int i=0;i<row->fieldCount();i++) {
EffectField* field = row->field(i);
for (int i=0;i<row->FieldCount();i++) {
EffectField* field = row->Field(i);
for (int j=0;j<field->keyframes.size();j++) {
selected_keys.append(j);
selected_keys_fields.append(i);
@@ -903,7 +903,7 @@ void GraphView::set_zoom(double xz, double yz) {
int GraphView::get_screen_x(double d) {
if (row != nullptr) {
d -= row->parent_effect->parent_clip->clip_in();
d -= row->GetParentEffect()->parent_clip->clip_in();
}
return qRound((d*x_zoom) - x_scroll);
}
@@ -915,7 +915,7 @@ int GraphView::get_screen_y(double d) {
long GraphView::get_value_x(int i) {
long frame = qRound((i + x_scroll)/x_zoom);
if (row != nullptr) {
frame += row->parent_effect->parent_clip->clip_in();
frame += row->GetParentEffect()->parent_clip->clip_in();
}
return frame;
}
@@ -931,7 +931,7 @@ void GraphView::selection_update() {
int selected_key_type = -1;
for (int i=0;i<selected_keys.size();i++) {
const EffectKeyframe& key = row->field(selected_keys_fields.at(i))->keyframes.at(selected_keys.at(i));
const EffectKeyframe& key = row->Field(selected_keys_fields.at(i))->keyframes.at(selected_keys.at(i));
selected_keys_old_vals.append(key.time);
selected_keys_old_doubles.append(key.data.toDouble());
+24 -24
View File
@@ -27,35 +27,35 @@
// routine for drawing a keyframe onscreen
void draw_keyframe(QPainter &p, int type, int x, int y, bool darker, int r, int g, int b) {
if (darker) {
r *= 0.625;
g *= 0.625;
b *= 0.625;
}
p.setPen(QColor(0, 0, 0));
p.setBrush(QColor(r, g, b));
if (darker) {
r *= 0.625;
g *= 0.625;
b *= 0.625;
}
p.setPen(QColor(0, 0, 0));
p.setBrush(QColor(r, g, b));
switch (type) {
case EFFECT_KEYFRAME_LINEAR:
{
QPoint points[KEYFRAME_POINT_COUNT] = {QPoint(x-KEYFRAME_SIZE, y), QPoint(x, y-KEYFRAME_SIZE), QPoint(x+KEYFRAME_SIZE, y), QPoint(x, y+KEYFRAME_SIZE)};
p.drawPolygon(points, KEYFRAME_POINT_COUNT);
}
break;
case EFFECT_KEYFRAME_BEZIER:
p.drawEllipse(QPoint(x, y), KEYFRAME_SIZE, KEYFRAME_SIZE);
break;
case EFFECT_KEYFRAME_HOLD:
p.drawRect(QRect(x - KEYFRAME_SIZE, y - KEYFRAME_SIZE, KEYFRAME_SIZE*2, KEYFRAME_SIZE*2));
break;
}
switch (type) {
case EFFECT_KEYFRAME_LINEAR:
{
QPoint points[KEYFRAME_POINT_COUNT] = {QPoint(x-KEYFRAME_SIZE, y), QPoint(x, y-KEYFRAME_SIZE), QPoint(x+KEYFRAME_SIZE, y), QPoint(x, y+KEYFRAME_SIZE)};
p.drawPolygon(points, KEYFRAME_POINT_COUNT);
}
break;
case EFFECT_KEYFRAME_BEZIER:
p.drawEllipse(QPoint(x, y), KEYFRAME_SIZE, KEYFRAME_SIZE);
break;
case EFFECT_KEYFRAME_HOLD:
p.drawRect(QRect(x - KEYFRAME_SIZE, y - KEYFRAME_SIZE, KEYFRAME_SIZE*2, KEYFRAME_SIZE*2));
break;
}
p.setBrush(Qt::NoBrush);
p.setBrush(Qt::NoBrush);
}
// adjusts keyframe's internal time (in clip time) to timeline time
long adjust_row_keyframe(EffectRow* row, long time, long visible_in) {
return time
- row->parent_effect->parent_clip->clip_in()
+ (row->parent_effect->parent_clip->timeline_in() - visible_in);
- row->GetParentEffect()->parent_clip->clip_in()
+ (row->GetParentEffect()->parent_clip->timeline_in() - visible_in);
}
+29 -18
View File
@@ -119,13 +119,22 @@ void KeyframeView::paintEvent(QPaintEvent*) {
for (int j=0;j<e->row_count();j++) {
EffectRow* row = e->row(j);
// TODO address this
/*
ClickableLabel* label = row->label;
QWidget* contents = e->container->contents;
QVector<long> key_times;
int keyframe_y = label->y() + (label->height()>>1) + mapFrom(panel_effect_controls, contents->mapTo(panel_effect_controls, contents->pos())).y() - e->container->title_bar->height()/* - y_scroll*/;
for (int l=0;l<row->fieldCount();l++) {
EffectField* f = row->field(l);
int keyframe_y = label->y()
+ (label->height()>>1)
+ mapFrom(panel_effect_controls, contents->mapTo(panel_effect_controls, contents->pos())).y()
- e->container->title_bar->height();
for (int l=0;l<row->FieldCount();l++) {
EffectField* f = row->Field(l);
for (int k=0;k<f->keyframes.size();k++) {
if (!key_times.contains(f->keyframes.at(k).time)) {
bool keyframe_selected = keyframeIsSelected(f, k);
@@ -133,8 +142,8 @@ void KeyframeView::paintEvent(QPaintEvent*) {
// see if any other keyframes have this time
int appearances = 0;
for (int m=0;m<row->fieldCount();m++) {
EffectField* compf = row->field(m);
for (int m=0;m<row->FieldCount();m++) {
EffectField* compf = row->Field(m);
for (int n=0;n<compf->keyframes.size();n++) {
if (f->keyframes.at(k).time == compf->keyframes.at(n).time) {
appearances++;
@@ -142,8 +151,8 @@ void KeyframeView::paintEvent(QPaintEvent*) {
}
}
if (appearances != row->fieldCount()) {
QColor cc = get_curve_color(l, row->fieldCount());
if (appearances != row->FieldCount()) {
QColor cc = get_curve_color(l, row->FieldCount());
draw_keyframe(p, f->keyframes.at(k).type, getScreenPointFromFrame(panel_effect_controls->zoom, keyframe_frame) - x_scroll, keyframe_y, keyframe_selected, cc.red(), cc.green(), cc.blue());
} else {
draw_keyframe(p, f->keyframes.at(k).type, getScreenPointFromFrame(panel_effect_controls->zoom, keyframe_frame) - x_scroll, keyframe_y, keyframe_selected);
@@ -156,6 +165,8 @@ void KeyframeView::paintEvent(QPaintEvent*) {
rows.append(row);
rowY.append(keyframe_y);
*/
}
}
}
@@ -252,10 +263,10 @@ void KeyframeView::mousePressEvent(QMouseEvent *event) {
row->FocusRow();
for (int k=0;k<row->fieldCount();k++) {
EffectField* f = row->field(k);
for (int k=0;k<row->FieldCount();k++) {
EffectField* f = row->Field(k);
for (int j=0;j<f->keyframes.size();j++) {
long eval_keyframe_time = f->keyframes.at(j).time-row->parent_effect->parent_clip->clip_in()+(row->parent_effect->parent_clip->timeline_in()-visible_in);
long eval_keyframe_time = f->keyframes.at(j).time-row->GetParentEffect()->parent_clip->clip_in()+(row->GetParentEffect()->parent_clip->timeline_in()-visible_in);
if (eval_keyframe_time >= frame_min && eval_keyframe_time <= frame_max) {
long eval_frame_diff = qAbs(eval_keyframe_time - drag_frame_start);
if (keyframe_index == -1 || eval_frame_diff < frame_diff) {
@@ -273,7 +284,7 @@ void KeyframeView::mousePressEvent(QMouseEvent *event) {
bool already_selected = false;
keys_selected = false;
if (keyframe_index > -1) {
already_selected = keyframeIsSelected(rows.at(row_index)->field(field_index), keyframe_index);
already_selected = keyframeIsSelected(rows.at(row_index)->Field(field_index), keyframe_index);
} else {
select_rect = true;
}
@@ -283,14 +294,14 @@ void KeyframeView::mousePressEvent(QMouseEvent *event) {
selected_keyframes.clear();
}
if (keyframe_index > -1) {
selected_fields.append(rows.at(row_index)->field(field_index));
selected_fields.append(rows.at(row_index)->Field(field_index));
selected_keyframes.append(keyframe_index);
// find other field with keyframes at the same time
long comp_time = rows.at(row_index)->field(field_index)->keyframes.at(keyframe_index).time;
for (int i=0;i<rows.at(row_index)->fieldCount();i++) {
long comp_time = rows.at(row_index)->Field(field_index)->keyframes.at(keyframe_index).time;
for (int i=0;i<rows.at(row_index)->FieldCount();i++) {
if (i != field_index) {
EffectField* f = rows.at(row_index)->field(i);
EffectField* f = rows.at(row_index)->Field(i);
for (int j=0;j<f->keyframes.size();j++) {
if (f->keyframes.at(j).time == comp_time) {
selected_fields.append(f);
@@ -353,8 +364,8 @@ void KeyframeView::mouseMoveEvent(QMouseEvent* event) {
for (int i=0;i<rowY.size();i++) {
if (rowY.at(i) >= min_row && rowY.at(i) <= max_row) {
EffectRow* row = rows.at(i);
for (int k=0;k<row->fieldCount();k++) {
EffectField* field = row->field(k);
for (int k=0;k<row->FieldCount();k++) {
EffectField* field = row->Field(k);
for (int j=0;j<field->keyframes.size();j++) {
long keyframe_frame = adjust_row_keyframe(row, field->keyframes.at(j).time, visible_in);
if (!keyframeIsSelected(field, j) && keyframe_frame >= min_frame && keyframe_frame <= max_frame) {
@@ -376,7 +387,7 @@ void KeyframeView::mouseMoveEvent(QMouseEvent* event) {
if (panel_timeline->snapping) {
for (int i=0;i<selected_keyframes.size();i++) {
EffectField* field = selected_fields.at(i);
Clip* c = field->GetParentRow()->parent_effect->parent_clip;
Clip* c = field->GetParentRow()->GetParentEffect()->parent_clip;
long key_time = old_key_vals.at(i) + frame_diff - c->clip_in() + c->timeline_in();
long key_eval = key_time;
if (panel_timeline->snap_to_point(olive::ActiveSequence->playhead, &key_eval)) {