half way through keyframes data
This commit is contained in:
@@ -24,12 +24,12 @@ void PanEffect::refresh() {}
|
||||
|
||||
Effect* PanEffect::copy(Clip* c) {
|
||||
PanEffect* p = new PanEffect(c);
|
||||
p->pan_val->set_double_value(pan_val->get_double_value());
|
||||
copy_field_keyframes(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
void PanEffect::process_audio(quint8 *samples, int nb_bytes) {
|
||||
double pval = pan_val->get_double_value();
|
||||
double pval = pan_val->get_double_value(-1);
|
||||
if (pval != 0) {
|
||||
for (int i=0;i<nb_bytes;i+=4) {
|
||||
qint16 left_sample = (qint16) (((samples[i+1] & 0xFF) << 8) | (samples[i] & 0xFF));
|
||||
|
||||
@@ -25,12 +25,12 @@ void VolumeEffect::refresh() {}
|
||||
|
||||
Effect* VolumeEffect::copy(Clip* c) {
|
||||
VolumeEffect* v = new VolumeEffect(c);
|
||||
v->volume_val->set_double_value(volume_val->get_double_value());
|
||||
copy_field_keyframes(v);
|
||||
return v;
|
||||
}
|
||||
|
||||
void VolumeEffect::process_audio(quint8* samples, int nb_bytes) {
|
||||
double vol_val = volume_val->get_double_value();
|
||||
double vol_val = volume_val->get_double_value(-1);
|
||||
if (vol_val != 100) {
|
||||
for (int i=0;i<nb_bytes;i+=2) {
|
||||
qint32 samp = (qint16) (((samples[i+1] & 0xFF) << 8) | (samples[i] & 0xFF));
|
||||
|
||||
+101
-31
@@ -12,6 +12,7 @@
|
||||
#include "ui/fontcombobox.h"
|
||||
#include "ui/checkboxex.h"
|
||||
#include "project/clip.h"
|
||||
#include "panels/timeline.h"
|
||||
|
||||
#include "effects/video/transformeffect.h"
|
||||
#include "effects/video/inverteffect.h"
|
||||
@@ -92,6 +93,16 @@ Effect::~Effect() {
|
||||
}
|
||||
}
|
||||
|
||||
void Effect::copy_field_keyframes(Effect* e) {
|
||||
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);
|
||||
e->rows.at(i)->field(j)->keyframes = field->keyframes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EffectRow* Effect::add_row(const QString& name) {
|
||||
EffectRow* row = new EffectRow(this, ui_layout, name, rows.size());
|
||||
rows.append(row);
|
||||
@@ -165,34 +176,31 @@ void Effect::save(QXmlStreamWriter* stream) {
|
||||
stream->writeStartElement("row");
|
||||
for (int j=0;j<row->fieldCount();j++) {
|
||||
EffectField* field = row->field(j);
|
||||
switch (field->type) {
|
||||
case EFFECT_FIELD_DOUBLE:
|
||||
stream->writeTextElement("field", QString::number(field->get_double_value()));
|
||||
break;
|
||||
case EFFECT_FIELD_COLOR:
|
||||
stream->writeTextElement("field", field->get_color_value().name());
|
||||
break;
|
||||
case EFFECT_FIELD_STRING:
|
||||
stream->writeTextElement("field", field->get_string_value());
|
||||
break;
|
||||
case EFFECT_FIELD_BOOL:
|
||||
stream->writeTextElement("field", QString::number(field->get_bool_value()));
|
||||
break;
|
||||
case EFFECT_FIELD_COMBO:
|
||||
stream->writeTextElement("field", field->get_combo_string());
|
||||
break;
|
||||
case EFFECT_FIELD_FONT:
|
||||
stream->writeTextElement("field", field->get_font_name());
|
||||
break;
|
||||
stream->writeStartElement("field");
|
||||
for (int k=0;k<field->keyframes.size();k++) {
|
||||
const EffectKeyframe& key = field->keyframes.at(i);
|
||||
stream->writeStartElement("key");
|
||||
stream->writeAttribute("frame", QString::number(key.frame));
|
||||
stream->writeAttribute("type", QString::number(key.type));
|
||||
switch (field->type) {
|
||||
case EFFECT_FIELD_DOUBLE: stream->writeAttribute("value", QString::number(key.data.toDouble())); break;
|
||||
case EFFECT_FIELD_COLOR: stream->writeAttribute("value", key.data.value<QColor>().name()); break;
|
||||
case EFFECT_FIELD_STRING: stream->writeAttribute("value", key.data.toString()); break;
|
||||
case EFFECT_FIELD_BOOL: stream->writeAttribute("value", QString::number(key.data.toBool())); break;
|
||||
case EFFECT_FIELD_COMBO: stream->writeAttribute("value", key.data.toString()); break;
|
||||
case EFFECT_FIELD_FONT: stream->writeAttribute("value", key.data.toString()); break;
|
||||
}
|
||||
stream->writeEndElement();
|
||||
}
|
||||
stream->writeEndElement(); // field
|
||||
}
|
||||
stream->writeEndElement(); // row
|
||||
}
|
||||
}
|
||||
|
||||
Effect* Effect::copy(Clip*) {return NULL;}
|
||||
void Effect::process_image(QImage&) {}
|
||||
void Effect::process_gl(QOpenGLShaderProgram&, int*, int*) {}
|
||||
void Effect::process_image(long, QImage&) {}
|
||||
void Effect::process_gl(long, QOpenGLShaderProgram&, int*, int*) {}
|
||||
void Effect::process_audio(uint8_t*, int) {}
|
||||
|
||||
/* Effect Row Definitions */
|
||||
@@ -231,6 +239,11 @@ int EffectRow::fieldCount() {
|
||||
/* Effect Field Definitions */
|
||||
|
||||
EffectField::EffectField(int t) : type(t) {
|
||||
// DEFAULT KEYFRAME
|
||||
EffectKeyframe key;
|
||||
key.frame = -1;
|
||||
keyframes.append(key);
|
||||
|
||||
switch (t) {
|
||||
case EFFECT_FIELD_DOUBLE:
|
||||
{
|
||||
@@ -279,6 +292,62 @@ EffectField::EffectField(int t) : type(t) {
|
||||
}
|
||||
}
|
||||
|
||||
bool EffectField::is_keyframed(long p) {
|
||||
return keyframes.size() == 0 || p < 0;
|
||||
}
|
||||
|
||||
QVariant EffectField::get_keyframe_data(long p) {
|
||||
if (keyframes.size() == 1) {
|
||||
return keyframes.at(0).data;
|
||||
}
|
||||
|
||||
EffectKeyframe* before = NULL;
|
||||
EffectKeyframe* after = NULL;
|
||||
for (int i=1;i<keyframes.size();i++) {
|
||||
if (keyframes.at(i).frame == p) {
|
||||
return keyframes.at(i).data;
|
||||
} else if (keyframes.at(i).frame < p && !(before != NULL && keyframes.at(i).frame <= before->frame)) {
|
||||
before = &keyframes[i];
|
||||
} else if (keyframes.at(i).frame > p && !(after != NULL && keyframes.at(i).frame >= after->frame)) {
|
||||
after = &keyframes[i];
|
||||
}
|
||||
}
|
||||
|
||||
// interpolate data
|
||||
if (before != NULL && after != NULL) {
|
||||
double progress = (p - before->frame)/(after->frame - before->frame);
|
||||
switch (type) {
|
||||
case EFFECT_FIELD_DOUBLE:
|
||||
{
|
||||
return lerp(before->data.toDouble(), after->data.toDouble(), progress);
|
||||
}
|
||||
break;
|
||||
case EFFECT_FIELD_COLOR:
|
||||
{
|
||||
QColor before_color = before->data.value<QColor>();
|
||||
QColor after_color = after->data.value<QColor>();
|
||||
QColor interval_color = QColor(
|
||||
lerp(before_color.red(), after_color.red(), progress),
|
||||
lerp(before_color.green(), after_color.green(), progress),
|
||||
lerp(before_color.blue(), after_color.blue(), progress)
|
||||
);
|
||||
return QVariant(interval_color);
|
||||
}
|
||||
break;
|
||||
case EFFECT_FIELD_STRING:
|
||||
case EFFECT_FIELD_BOOL:
|
||||
case EFFECT_FIELD_COMBO:
|
||||
case EFFECT_FIELD_FONT:
|
||||
return before->data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// return pre or post data
|
||||
if (before != NULL) return before->data;
|
||||
if (after != NULL) return after->data;
|
||||
}
|
||||
|
||||
QWidget* EffectField::get_ui_element() {
|
||||
return ui_element;
|
||||
}
|
||||
@@ -287,11 +356,12 @@ void EffectField::set_enabled(bool e) {
|
||||
ui_element->setEnabled(e);
|
||||
}
|
||||
|
||||
double EffectField::get_double_value() {
|
||||
return static_cast<LabelSlider*>(ui_element)->value();
|
||||
double EffectField::get_double_value(long p) {
|
||||
return get_keyframe_data(p).toDouble();
|
||||
}
|
||||
|
||||
void EffectField::set_double_value(double v) {
|
||||
|
||||
static_cast<LabelSlider*>(ui_element)->set_value(v, false);
|
||||
}
|
||||
|
||||
@@ -311,16 +381,16 @@ void EffectField::add_combo_item(const QString& name, const QVariant& data) {
|
||||
static_cast<ComboBoxEx*>(ui_element)->addItem(name, data);
|
||||
}
|
||||
|
||||
int EffectField::get_combo_index() {
|
||||
int EffectField::get_combo_index(long p) {
|
||||
return static_cast<ComboBoxEx*>(ui_element)->currentIndex();
|
||||
}
|
||||
|
||||
const QVariant EffectField::get_combo_data() {
|
||||
const QVariant EffectField::get_combo_data(long p) {
|
||||
return static_cast<ComboBoxEx*>(ui_element)->currentData();
|
||||
}
|
||||
|
||||
const QString EffectField::get_combo_string() {
|
||||
return static_cast<ComboBoxEx*>(ui_element)->currentText();
|
||||
const QString EffectField::get_combo_string(long p) {
|
||||
return static_cast<ComboBoxEx*>(ui_element)->itemText(get_keyframe_data(p).toInt());
|
||||
}
|
||||
|
||||
void EffectField::set_combo_index(int index) {
|
||||
@@ -331,7 +401,7 @@ void EffectField::set_combo_string(const QString& s) {
|
||||
static_cast<ComboBoxEx*>(ui_element)->setCurrentTextEx(s);
|
||||
}
|
||||
|
||||
bool EffectField::get_bool_value() {
|
||||
bool EffectField::get_bool_value(long p) {
|
||||
return static_cast<QCheckBox*>(ui_element)->isChecked();
|
||||
}
|
||||
|
||||
@@ -339,7 +409,7 @@ void EffectField::set_bool_value(bool b) {
|
||||
return static_cast<QCheckBox*>(ui_element)->setChecked(b);
|
||||
}
|
||||
|
||||
const QString EffectField::get_string_value() {
|
||||
const QString EffectField::get_string_value(long p) {
|
||||
return static_cast<QTextEdit*>(ui_element)->toPlainText();
|
||||
}
|
||||
|
||||
@@ -347,7 +417,7 @@ void EffectField::set_string_value(const QString& s) {
|
||||
static_cast<QTextEdit*>(ui_element)->setText(s);
|
||||
}
|
||||
|
||||
const QString EffectField::get_font_name() {
|
||||
const QString EffectField::get_font_name(long p) {
|
||||
return static_cast<FontCombobox*>(ui_element)->currentText();
|
||||
}
|
||||
|
||||
@@ -355,7 +425,7 @@ void EffectField::set_font_name(const QString& s) {
|
||||
static_cast<FontCombobox*>(ui_element)->setCurrentText(s);
|
||||
}
|
||||
|
||||
QColor EffectField::get_color_value() {
|
||||
QColor EffectField::get_color_value(long p) {
|
||||
return static_cast<ColorButton*>(ui_element)->get_color();
|
||||
}
|
||||
|
||||
|
||||
+21
-23
@@ -52,17 +52,10 @@ Effect* create_effect(int effect_id, Clip* c);
|
||||
#define EFFECT_KEYFRAME_HOLD 1
|
||||
#define EFFECT_KEYFRAME_BEZIER 2
|
||||
|
||||
union KeyframeValue {
|
||||
double d;
|
||||
QColor c;
|
||||
bool b;
|
||||
};
|
||||
|
||||
class EffectKeyframe {
|
||||
public:
|
||||
struct EffectKeyframe {
|
||||
long frame;
|
||||
int type;
|
||||
KeyframeValue value;
|
||||
QVariant data;
|
||||
};
|
||||
|
||||
class EffectField : public QObject {
|
||||
@@ -71,33 +64,37 @@ public:
|
||||
EffectField(int t);
|
||||
int type;
|
||||
|
||||
double get_double_value();
|
||||
QVariant get_keyframe_data(long p);
|
||||
bool is_keyframed(long p);
|
||||
|
||||
double get_double_value(long p);
|
||||
void set_double_value(double v);
|
||||
void set_double_default_value(double v);
|
||||
void set_double_minimum_value(double v);
|
||||
void set_double_maximum_value(double v);
|
||||
|
||||
const QString get_string_value();
|
||||
const QString get_string_value(long p);
|
||||
void set_string_value(const QString &s);
|
||||
|
||||
void add_combo_item(const QString& name, const QVariant &data);
|
||||
int get_combo_index();
|
||||
const QVariant get_combo_data();
|
||||
const QString get_combo_string();
|
||||
int get_combo_index(long p);
|
||||
const QVariant get_combo_data(long p);
|
||||
const QString get_combo_string(long p);
|
||||
void set_combo_index(int index);
|
||||
void set_combo_string(const QString& s);
|
||||
|
||||
bool get_bool_value();
|
||||
bool get_bool_value(long p);
|
||||
void set_bool_value(bool b);
|
||||
|
||||
const QString get_font_name();
|
||||
const QString get_font_name(long p);
|
||||
void set_font_name(const QString& s);
|
||||
|
||||
QColor get_color_value();
|
||||
QColor get_color_value(long p);
|
||||
void set_color_value(QColor color);
|
||||
|
||||
QWidget* get_ui_element();
|
||||
void set_enabled(bool e);
|
||||
QVector<EffectKeyframe> keyframes;
|
||||
signals:
|
||||
void changed();
|
||||
void toggled(bool);
|
||||
@@ -112,12 +109,12 @@ public:
|
||||
EffectField* add_field(int type, int colspan = 1);
|
||||
EffectField* field(int i);
|
||||
int fieldCount();
|
||||
void set_keyframe(int field, long time);
|
||||
void move_keyframe(int field, long from, long to);
|
||||
void delete_keyframe(int field, long time);
|
||||
void set_keyframe(long time);
|
||||
void move_keyframe(long from, long to);
|
||||
void delete_keyframe(long time);
|
||||
QLabel* label;
|
||||
private:
|
||||
Effect* parent_effect;
|
||||
private:
|
||||
QGridLayout* ui;
|
||||
QString name;
|
||||
int ui_row;
|
||||
@@ -146,6 +143,7 @@ public:
|
||||
virtual void refresh();
|
||||
|
||||
virtual Effect* copy(Clip* c);
|
||||
void copy_field_keyframes(Effect *e);
|
||||
|
||||
void load(QXmlStreamReader* stream);
|
||||
void save(QXmlStreamWriter* stream);
|
||||
@@ -155,8 +153,8 @@ public:
|
||||
|
||||
const char* ffmpeg_filter;
|
||||
|
||||
virtual void process_image(QImage& img);
|
||||
virtual void process_gl(QOpenGLShaderProgram& shader_prog, int* anchor_x, int* anchor_y);
|
||||
virtual void process_image(long frame, QImage& img);
|
||||
virtual void process_gl(long frame, QOpenGLShaderProgram& shader_prog, int* anchor_x, int* anchor_y);
|
||||
virtual void process_audio(quint8* samples, int nb_bytes);
|
||||
public slots:
|
||||
void field_changed();
|
||||
|
||||
@@ -19,25 +19,20 @@ InvertEffect::InvertEffect(Clip* c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_INVERT_
|
||||
// set defaults
|
||||
amount_val->set_double_default_value(100);
|
||||
|
||||
connect(amount_val, SIGNAL(changed()), this, SLOT(compile()));
|
||||
|
||||
compile();
|
||||
}
|
||||
|
||||
void InvertEffect::compile() {
|
||||
double value = amount_val->get_double_value()*0.01;
|
||||
vert_shader.compileSourceCode("varying vec2 vTexCoord; void main() { vTexCoord = gl_MultiTexCoord0; gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; }");
|
||||
frag_shader.compileSourceCode("uniform sampler2D myTexture; varying vec2 vTexCoord; void main(void) { vec4 textureColor = texture2D(myTexture, vTexCoord); gl_FragColor = vec4(textureColor.r+((1.0-textureColor.r-textureColor.r)*" + QString::number(value) + "), textureColor.g+((1.0-textureColor.g-textureColor.g)*" + QString::number(value) + "), textureColor.b+((1.0-textureColor.b-textureColor.b)*" + QString::number(value) + "), 1); }");
|
||||
field_changed();
|
||||
connect(amount_val, SIGNAL(changed()), this, SLOT(field_changed()));
|
||||
}
|
||||
|
||||
Effect* InvertEffect::copy(Clip* c) {
|
||||
InvertEffect* i = new InvertEffect(c);
|
||||
i->amount_val->set_double_value(amount_val->get_double_value());
|
||||
copy_field_keyframes(i);
|
||||
return i;
|
||||
}
|
||||
|
||||
void InvertEffect::process_gl(QOpenGLShaderProgram& shader_prog, int* anchor_x, int* anchor_y) {
|
||||
void InvertEffect::process_gl(long p, QOpenGLShaderProgram& shader_prog, int* anchor_x, int* anchor_y) {
|
||||
double value = amount_val->get_double_value(p)*0.01;
|
||||
vert_shader.compileSourceCode("varying vec2 vTexCoord; void main() { vTexCoord = gl_MultiTexCoord0; gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; }");
|
||||
frag_shader.compileSourceCode("uniform sampler2D myTexture; varying vec2 vTexCoord; void main(void) { vec4 textureColor = texture2D(myTexture, vTexCoord); gl_FragColor = vec4(textureColor.r+((1.0-textureColor.r-textureColor.r)*" + QString::number(value) + "), textureColor.g+((1.0-textureColor.g-textureColor.g)*" + QString::number(value) + "), textureColor.b+((1.0-textureColor.b-textureColor.b)*" + QString::number(value) + "), 1); }");
|
||||
|
||||
shader_prog.addShader(&vert_shader);
|
||||
shader_prog.addShader(&frag_shader);
|
||||
}
|
||||
|
||||
@@ -9,12 +9,10 @@ class InvertEffect : public Effect {
|
||||
Q_OBJECT
|
||||
public:
|
||||
InvertEffect(Clip* c);
|
||||
void process_gl(QOpenGLShaderProgram& shader_prog, int *anchor_x, int *anchor_y);
|
||||
void process_gl(long p, QOpenGLShaderProgram& shader_prog, int *anchor_x, int *anchor_y);
|
||||
Effect* copy(Clip *c);
|
||||
|
||||
EffectField* amount_val;
|
||||
private slots:
|
||||
void compile();
|
||||
private:
|
||||
QOpenGLShader vert_shader;
|
||||
QOpenGLShader frag_shader;
|
||||
|
||||
@@ -41,7 +41,7 @@ ShakeEffect::ShakeEffect(Clip *c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_SHAKE_EFF
|
||||
|
||||
void ShakeEffect::refresh() {
|
||||
if (parent_clip->sequence != NULL) {
|
||||
shake_limit = qRound(parent_clip->sequence->frame_rate / frequency_val->get_double_value());
|
||||
shake_limit = qRound(parent_clip->sequence->frame_rate / frequency_val->get_double_value(-1));
|
||||
shake_progress = shake_limit;
|
||||
next_x = 0;
|
||||
next_y = 0;
|
||||
@@ -51,15 +51,13 @@ void ShakeEffect::refresh() {
|
||||
|
||||
Effect* ShakeEffect::copy(Clip* c) {
|
||||
ShakeEffect* e = new ShakeEffect(c);
|
||||
e->intensity_val->set_double_value(intensity_val->get_double_value());
|
||||
e->rotation_val->set_double_value(rotation_val->get_double_value());
|
||||
e->frequency_val->set_double_value(frequency_val->get_double_value());
|
||||
copy_field_keyframes(e);
|
||||
return e;
|
||||
}
|
||||
|
||||
void ShakeEffect::process_gl(QOpenGLShaderProgram&, int*, int*) {
|
||||
void ShakeEffect::process_gl(long p, QOpenGLShaderProgram&, int*, int*) {
|
||||
if (shake_progress > shake_limit) {
|
||||
double ival = intensity_val->get_double_value();
|
||||
double ival = intensity_val->get_double_value(p);
|
||||
if ((int)ival > 0) {
|
||||
prev_x = next_x;
|
||||
prev_y = next_y;
|
||||
@@ -89,7 +87,7 @@ void ShakeEffect::process_gl(QOpenGLShaderProgram&, int*, int*) {
|
||||
offset_x = 0;
|
||||
offset_y = 0;
|
||||
}
|
||||
double rot_val = rotation_val->get_double_value();
|
||||
double rot_val = rotation_val->get_double_value(p);
|
||||
if ((int)rot_val > 0) {
|
||||
prev_rot = next_rot;
|
||||
next_rot = (qrand() % (int) (rot_val * 2)) - rot_val;
|
||||
|
||||
@@ -7,7 +7,7 @@ class ShakeEffect : public Effect {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ShakeEffect(Clip* c);
|
||||
void process_gl(QOpenGLShaderProgram& shader_prog, int* anchor_x, int* anchor_y);
|
||||
void process_gl(long p, QOpenGLShaderProgram& shader_prog, int* anchor_x, int* anchor_y);
|
||||
Effect* copy(Clip *c);
|
||||
|
||||
EffectField* intensity_val;
|
||||
|
||||
@@ -37,19 +37,19 @@ SolidEffect::SolidEffect(Clip* c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_SOLID_EFF
|
||||
}
|
||||
|
||||
void SolidEffect::enable_color() {
|
||||
solid_color_field->set_enabled(solid_type->get_combo_data() == SOLID_TYPE_COLOR);
|
||||
solid_color_field->set_enabled(solid_type->get_combo_data(-1) == SOLID_TYPE_COLOR);
|
||||
}
|
||||
|
||||
void SolidEffect::process_image(QImage& img) {
|
||||
void SolidEffect::process_image(long frame, QImage& img) {
|
||||
QPainter p(&img);
|
||||
int width = img.width();
|
||||
int height = img.height();
|
||||
|
||||
switch (solid_type->get_combo_data().toInt()) {
|
||||
switch (solid_type->get_combo_data(frame).toInt()) {
|
||||
case SOLID_TYPE_COLOR:
|
||||
{
|
||||
QColor brush = solid_color_field->get_color_value();
|
||||
p.fillRect(0, 0, width, height, QColor(brush.red(), brush.green(), brush.blue(), opacity_field->get_double_value()*2.55));
|
||||
QColor brush = solid_color_field->get_color_value(frame);
|
||||
p.fillRect(0, 0, width, height, QColor(brush.red(), brush.green(), brush.blue(), opacity_field->get_double_value(frame)*2.55));
|
||||
}
|
||||
break;
|
||||
case SOLID_TYPE_BARS:
|
||||
|
||||
@@ -10,7 +10,7 @@ public:
|
||||
EffectField* solid_type;
|
||||
EffectField* solid_color_field;
|
||||
EffectField* opacity_field;
|
||||
void process_image(QImage &img);
|
||||
void process_image(long p, QImage &img);
|
||||
private slots:
|
||||
void enable_color();
|
||||
};
|
||||
|
||||
@@ -242,7 +242,7 @@ void blurred2(QImage& result, const QRect& rect, int radius, bool alphaOnly = fa
|
||||
}
|
||||
}
|
||||
|
||||
void TextEffect::process_image(QImage& img) {
|
||||
void TextEffect::process_image(long frame, QImage& img) {
|
||||
QPainter p(&img);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
int width = img.width();
|
||||
@@ -250,15 +250,15 @@ void TextEffect::process_image(QImage& img) {
|
||||
|
||||
// set font
|
||||
font.setStyleHint(QFont::Helvetica, QFont::PreferAntialias);
|
||||
font.setFamily(set_font_combobox->get_font_name());
|
||||
font.setPointSize(size_val->get_double_value());
|
||||
font.setFamily(set_font_combobox->get_font_name(frame));
|
||||
font.setPointSize(size_val->get_double_value(frame));
|
||||
p.setFont(font);
|
||||
QFontMetrics fm(font);
|
||||
|
||||
QStringList lines = text_val->get_string_value().split('\n');
|
||||
QStringList lines = text_val->get_string_value(frame).split('\n');
|
||||
|
||||
// word wrap function
|
||||
if (word_wrap_field->get_bool_value()) {
|
||||
if (word_wrap_field->get_bool_value(frame)) {
|
||||
for (int i=0;i<lines.size();i++) {
|
||||
const QString& s = lines.at(i);
|
||||
if (fm.width(s) > width) {
|
||||
@@ -287,7 +287,7 @@ void TextEffect::process_image(QImage& img) {
|
||||
for (int i=0;i<lines.size();i++) {
|
||||
int text_x, text_y;
|
||||
|
||||
switch (halign_field->get_combo_data().toInt()) {
|
||||
switch (halign_field->get_combo_data(frame).toInt()) {
|
||||
case Qt::AlignLeft: text_x = 0; break;
|
||||
case Qt::AlignHCenter: text_x = (width/2) - (fm.width(lines.at(i))/2); break;
|
||||
case Qt::AlignRight: text_x = width - fm.width(lines.at(i)); break;
|
||||
@@ -316,7 +316,7 @@ void TextEffect::process_image(QImage& img) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (valign_field->get_combo_data().toInt()) {
|
||||
switch (valign_field->get_combo_data(frame).toInt()) {
|
||||
case Qt::AlignTop: text_y = (fm.height()*i)+fm.ascent(); break;
|
||||
case Qt::AlignVCenter: text_y = ((height/2) - (text_height/2) - fm.descent()) + (fm.height()*(i+1)); break;
|
||||
case Qt::AlignBottom: text_y = (height - text_height - fm.descent()) + (fm.height()*(i+1)); break;
|
||||
@@ -328,43 +328,38 @@ void TextEffect::process_image(QImage& img) {
|
||||
p.setPen(Qt::NoPen);
|
||||
|
||||
// draw shadow
|
||||
if (shadow_bool->get_bool_value()) {
|
||||
if (shadow_bool->get_bool_value(frame)) {
|
||||
QImage shadow(width, height, QImage::Format_ARGB32_Premultiplied);
|
||||
shadow.fill(Qt::transparent);
|
||||
QPainter spaint(&shadow);
|
||||
|
||||
int shadow_offset = shadow_distance->get_double_value();
|
||||
QColor col = shadow_color->get_color_value();
|
||||
col.setAlphaF(shadow_opacity->get_double_value()*0.01);
|
||||
int shadow_offset = shadow_distance->get_double_value(frame);
|
||||
QColor col = shadow_color->get_color_value(frame);
|
||||
col.setAlphaF(shadow_opacity->get_double_value(frame)*0.01);
|
||||
spaint.setBrush(col);
|
||||
spaint.drawPath(path);
|
||||
|
||||
blurred2(shadow, shadow.rect(), shadow_softness->get_double_value(), false);
|
||||
blurred2(shadow, shadow.rect(), shadow_softness->get_double_value(frame), false);
|
||||
p.drawImage(shadow_offset, shadow_offset, shadow);
|
||||
|
||||
spaint.end();
|
||||
}
|
||||
|
||||
// draw outline
|
||||
int outline_width_val = outline_width->get_double_value();
|
||||
if (outline_bool->get_bool_value() && outline_width_val > 0) {
|
||||
QPen outline(outline_color->get_color_value());
|
||||
int outline_width_val = outline_width->get_double_value(frame);
|
||||
if (outline_bool->get_bool_value(frame) && outline_width_val > 0) {
|
||||
QPen outline(outline_color->get_color_value(frame));
|
||||
outline.setWidth(outline_width_val);
|
||||
p.setPen(outline);
|
||||
}
|
||||
|
||||
// draw "master" text
|
||||
p.setBrush(set_color_button->get_color_value());
|
||||
p.setBrush(set_color_button->get_color_value(frame));
|
||||
p.drawPath(path);
|
||||
}
|
||||
|
||||
Effect* TextEffect::copy(Clip* c) {
|
||||
TextEffect* e = new TextEffect(c);
|
||||
e->text_val->set_string_value(text_val->get_string_value());
|
||||
e->size_val->set_double_value(size_val->get_double_value());
|
||||
e->set_color_button->set_color_value(set_color_button->get_color_value());
|
||||
e->set_font_combobox->set_font_name(set_font_combobox->get_font_name());
|
||||
e->halign_field->set_combo_index(halign_field->get_combo_index());
|
||||
e->valign_field->set_combo_index(valign_field->get_combo_index());
|
||||
copy_field_keyframes(e);
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ class TextEffect : public Effect {
|
||||
Q_OBJECT
|
||||
public:
|
||||
TextEffect(Clip* c);
|
||||
void process_image(QImage& img);
|
||||
void process_image(long frame, QImage& img);
|
||||
Effect* copy(Clip* c);
|
||||
|
||||
EffectField* text_val;
|
||||
|
||||
@@ -80,16 +80,7 @@ TransformEffect::TransformEffect(Clip* c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_T
|
||||
|
||||
Effect* TransformEffect::copy(Clip* c) {
|
||||
TransformEffect* t = new TransformEffect(c);
|
||||
t->position_x->set_double_value(position_x->get_double_value());
|
||||
t->position_y->set_double_value(position_y->get_double_value());
|
||||
t->scale_x->set_double_value(scale_x->get_double_value());
|
||||
t->scale_y->set_double_value(scale_y->get_double_value());
|
||||
t->uniform_scale_field->set_bool_value(uniform_scale_field->get_bool_value());
|
||||
t->rotation->set_double_value(rotation->get_double_value());
|
||||
t->anchor_x_box->set_double_value(anchor_x_box->get_double_value());
|
||||
t->anchor_y_box->set_double_value(anchor_y_box->get_double_value());
|
||||
t->opacity->set_double_value(opacity->get_double_value());
|
||||
t->blend_mode_box->set_combo_index(blend_mode_box->get_combo_index());
|
||||
copy_field_keyframes(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
@@ -136,24 +127,24 @@ void TransformEffect::toggle_uniform_scale(bool enabled) {
|
||||
scale_y->set_enabled(!enabled);
|
||||
}
|
||||
|
||||
void TransformEffect::process_gl(QOpenGLShaderProgram&, int* anchor_x, int* anchor_y) {
|
||||
void TransformEffect::process_gl(long frame, QOpenGLShaderProgram&, int* anchor_x, int* anchor_y) {
|
||||
// position
|
||||
glTranslatef(position_x->get_double_value()-(parent_clip->sequence->width/2), position_y->get_double_value()-(parent_clip->sequence->height/2), 0);
|
||||
glTranslatef(position_x->get_double_value(frame)-(parent_clip->sequence->width/2), position_y->get_double_value(frame)-(parent_clip->sequence->height/2), 0);
|
||||
|
||||
// anchor point
|
||||
*anchor_x += (anchor_x_box->get_double_value()-default_anchor_x);
|
||||
*anchor_y += (anchor_y_box->get_double_value()-default_anchor_y);
|
||||
*anchor_x += (anchor_x_box->get_double_value(frame)-default_anchor_x);
|
||||
*anchor_y += (anchor_y_box->get_double_value(frame)-default_anchor_y);
|
||||
|
||||
// rotation
|
||||
glRotatef(rotation->get_double_value(), 0, 0, 1);
|
||||
glRotatef(rotation->get_double_value(frame), 0, 0, 1);
|
||||
|
||||
// scale
|
||||
float sx = scale_x->get_double_value()*0.01;
|
||||
float sy = (uniform_scale_field->get_bool_value()) ? sx : scale_y->get_double_value()*0.01;
|
||||
float sx = scale_x->get_double_value(frame)*0.01;
|
||||
float sy = (uniform_scale_field->get_bool_value(frame)) ? sx : scale_y->get_double_value(frame)*0.01;
|
||||
glScalef(sx, sy, 1);
|
||||
|
||||
// blend mode
|
||||
switch (blend_mode_box->get_combo_data().toInt()) {
|
||||
switch (blend_mode_box->get_combo_data(frame).toInt()) {
|
||||
case BLEND_MODE_NORMAL:
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
break;
|
||||
@@ -173,5 +164,5 @@ void TransformEffect::process_gl(QOpenGLShaderProgram&, int* anchor_x, int* anch
|
||||
// opacity
|
||||
float color[4];
|
||||
glGetFloatv(GL_CURRENT_COLOR, color);
|
||||
glColor4f(1.0, 1.0, 1.0, color[3]*(opacity->get_double_value()*0.01));
|
||||
glColor4f(1.0, 1.0, 1.0, color[3]*(opacity->get_double_value(frame)*0.01));
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ class TransformEffect : public Effect {
|
||||
public:
|
||||
TransformEffect(Clip* c);
|
||||
void refresh();
|
||||
void process_gl(QOpenGLShaderProgram& shader_prog, int* anchor_x, int* anchor_y);
|
||||
void process_gl(long p, QOpenGLShaderProgram& shader_prog, int* anchor_x, int* anchor_y);
|
||||
Effect* copy(Clip *c);
|
||||
|
||||
EffectField* position_x;
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <QMenu>
|
||||
#include <QDebug>
|
||||
#include <QVBoxLayout>
|
||||
#include <QResizeEvent>
|
||||
#include <QScrollBar>
|
||||
|
||||
#include "panels/panels.h"
|
||||
#include "effects/effect.h"
|
||||
@@ -28,6 +30,12 @@ EffectControls::EffectControls(QWidget *parent) :
|
||||
init_transitions();
|
||||
clear_effects(false);
|
||||
ui->headers->snapping = false;
|
||||
|
||||
ui->effects_area->parent_widget = ui->scrollArea;
|
||||
ui->effects_area->keyframe_area = ui->keyframeView;
|
||||
ui->effects_area->header = ui->headers;
|
||||
|
||||
connect(ui->keyframeScroller->verticalScrollBar(), SIGNAL(valueChanged(int)), ui->scrollArea->verticalScrollBar(), SLOT(setValue(int)));
|
||||
}
|
||||
|
||||
EffectControls::~EffectControls() {
|
||||
@@ -182,9 +190,18 @@ void EffectControls::load_effects() {
|
||||
}
|
||||
connect(container, SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*)));
|
||||
connect(container, SIGNAL(visibleChanged()), ui->keyframeView, SLOT(reload()));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (selected_clips.size() > 0) {
|
||||
// ui->scrollArea->setMinimumWidth(ui->effects_area->width());
|
||||
|
||||
/*ui->effects_area->layout()->update();
|
||||
ui->effects_area->layout()->activate();
|
||||
qDebug() << ui->effects_area->height();
|
||||
|
||||
ui->keyframeView->resize(ui->keyframeView->width(), ui->effects_area->height());*/
|
||||
|
||||
ui->keyframeView->setMinimumHeight(ui->effects_area->height());
|
||||
ui->keyframeView->setEnabled(true);
|
||||
ui->keyframeView->visible_in = effects_in;
|
||||
ui->keyframeView->visible_out = effects_out;
|
||||
@@ -266,3 +283,10 @@ bool EffectControls::is_focused() {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
EffectsArea::EffectsArea(QWidget* parent) : QWidget(parent) {}
|
||||
|
||||
void EffectsArea::resizeEvent(QResizeEvent *event) {
|
||||
parent_widget->setMinimumWidth(sizeHint().width());
|
||||
keyframe_area->setMinimumHeight(height() - header->height());
|
||||
}
|
||||
|
||||
@@ -8,6 +8,17 @@ struct Clip;
|
||||
class QMenu;
|
||||
class Effect;
|
||||
class TimelineHeader;
|
||||
class QScrollArea;
|
||||
class KeyframeView;
|
||||
|
||||
class EffectsArea : public QWidget {
|
||||
public:
|
||||
EffectsArea(QWidget* parent = 0);
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
QScrollArea* parent_widget;
|
||||
KeyframeView* keyframe_area;
|
||||
TimelineHeader* header;
|
||||
};
|
||||
|
||||
namespace Ui {
|
||||
class EffectControls;
|
||||
|
||||
+122
-92
@@ -40,44 +40,62 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
<widget class="QSplitter" name="splitter_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>619</width>
|
||||
<height>489</height>
|
||||
</rect>
|
||||
<property name="childrenCollapsible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>225</width>
|
||||
<height>477</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="childrenCollapsible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="effects_area" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="EffectsArea" name="effects_area" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
@@ -399,69 +417,75 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QScrollArea" name="scrollArea_2">
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QScrollArea" name="keyframeScroller">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>376</width>
|
||||
<height>475</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="TimelineHeader" name="headers" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>1</horstretch>
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>15</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::ClickFocus</enum>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>388</width>
|
||||
<height>487</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="TimelineHeader" name="headers" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>15</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::ClickFocus</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="KeyframeView" name="keyframeView" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="KeyframeView" name="keyframeView" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -481,6 +505,12 @@
|
||||
<header>ui/timelineheader.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>EffectsArea</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>panels/effectcontrols.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
||||
+1
-1
@@ -394,7 +394,7 @@ void Timeline::delete_selection(bool ripple_delete) {
|
||||
}
|
||||
|
||||
int lerp(int a, int b, double t) {
|
||||
return ((1.0 - t) * a) + (t * b);
|
||||
return ((1.0 - t) * a) + (t * b);
|
||||
}
|
||||
|
||||
void Timeline::set_zoom(bool in) {
|
||||
|
||||
@@ -76,7 +76,8 @@ void cache_clip(Clip* clip, long playhead, bool write_A, bool write_B, bool rese
|
||||
|
||||
void get_clip_frame(Clip* c, long playhead) {
|
||||
if (c->open) {
|
||||
long clip_time = refactor_frame_number(playhead - c->timeline_in + c->clip_in, c->sequence->frame_rate, av_q2d(av_guess_frame_rate(c->formatCtx, c->stream, c->frame)));
|
||||
long sequence_clip_time = playhead - c->timeline_in + c->clip_in;
|
||||
long clip_time = refactor_frame_number(sequence_clip_time, c->sequence->frame_rate, av_q2d(av_guess_frame_rate(c->formatCtx, c->stream, c->frame)));
|
||||
|
||||
// do we need to update the texture?
|
||||
MediaStream* ms = static_cast<Media*>(c->media)->get_stream_from_file_index(c->media_stream);
|
||||
@@ -169,7 +170,7 @@ void get_clip_frame(Clip* c, long playhead) {
|
||||
QImage img(c->comp_frame, current_frame->width, current_frame->height, QImage::Format_RGBA8888);
|
||||
for (int i=0;i<c->effects.size();i++) {
|
||||
if (c->effects.at(i)->enable_image) {
|
||||
c->effects.at(i)->process_image(img);
|
||||
c->effects.at(i)->process_image(sequence_clip_time, img);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
-7
@@ -16,12 +16,6 @@
|
||||
KeyframeView::KeyframeView(QWidget *parent) : QWidget(parent), mouseover(false), visible_in(0), visible_out(0) {
|
||||
setFocusPolicy(Qt::ClickFocus);
|
||||
setMouseTracking(true);
|
||||
reload();
|
||||
}
|
||||
|
||||
void KeyframeView::reload() {
|
||||
enable_reload = true;
|
||||
update();
|
||||
}
|
||||
|
||||
void KeyframeView::paintEvent(QPaintEvent*) {
|
||||
@@ -30,6 +24,7 @@ void KeyframeView::paintEvent(QPaintEvent*) {
|
||||
setMinimumWidth(getScreenPointFromFrame(panel_effect_controls->zoom, visible_out - visible_in));
|
||||
|
||||
rowY.clear();
|
||||
rows.clear();
|
||||
for (int i=0;i<effects.size();i++) {
|
||||
Effect* e = effects.at(i);
|
||||
if (e->container->is_expanded()) {
|
||||
@@ -39,6 +34,8 @@ void KeyframeView::paintEvent(QPaintEvent*) {
|
||||
long frame = 20;
|
||||
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();
|
||||
draw_keyframe(p, getScreenPointFromFrame(panel_effect_controls->zoom, frame), keyframe_y, false);
|
||||
|
||||
rows.append(e->row(j));
|
||||
rowY.append(keyframe_y);
|
||||
}
|
||||
}
|
||||
@@ -51,7 +48,7 @@ void KeyframeView::paintEvent(QPaintEvent*) {
|
||||
}
|
||||
|
||||
if (mouseover && mouseover_row < rowY.size()) {
|
||||
draw_keyframe(p, getScreenPointFromFrame(panel_effect_controls->zoom, mouseover_frame) - visible_in, rowY.at(mouseover_row), true);
|
||||
draw_keyframe(p, getScreenPointFromFrame(panel_effect_controls->zoom, mouseover_frame - visible_in), rowY.at(mouseover_row), true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +60,10 @@ void KeyframeView::draw_keyframe(QPainter &p, int x, int y, bool semiTransparent
|
||||
p.drawPolygon(points, KEYFRAME_POINT_COUNT);
|
||||
}
|
||||
|
||||
void KeyframeView::mousePressEvent(QMouseEvent *event) {
|
||||
qDebug() << "create keyframe @ clip frame" << mouseover_frame - visible_in + (rows.at(mouseover_row)->parent_effect->parent_clip->clip_in) << "effect row" << mouseover_row;
|
||||
}
|
||||
|
||||
void KeyframeView::mouseMoveEvent(QMouseEvent* event) {
|
||||
unsetCursor();
|
||||
bool new_mo = false;
|
||||
@@ -80,3 +81,7 @@ void KeyframeView::mouseMoveEvent(QMouseEvent* event) {
|
||||
}
|
||||
mouseover = new_mo;
|
||||
}
|
||||
|
||||
void KeyframeView::mouseReleaseEvent(QMouseEvent* event) {
|
||||
|
||||
}
|
||||
|
||||
+2
-4
@@ -16,14 +16,12 @@ public:
|
||||
|
||||
long visible_in;
|
||||
long visible_out;
|
||||
public slots:
|
||||
void reload();
|
||||
private:
|
||||
QVector<int> rowY;
|
||||
QVector<EffectRow*> rows;
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
void mouseMoveEvent(QMouseEvent* event);
|
||||
/*void mousePressEvent(QMouseEvent* event);
|
||||
void mouseReleaseEvent(QMouseEvent *event);*/
|
||||
void mouseReleaseEvent(QMouseEvent *event);
|
||||
void paintEvent(QPaintEvent *event);
|
||||
void draw_keyframe(QPainter& p, int x, int y, bool semiTransparent);
|
||||
bool enable_reload;
|
||||
|
||||
+1
-1
@@ -177,7 +177,7 @@ void ViewerWidget::compose_sequence(QVector<Clip*>& nests, bool render_audio) {
|
||||
QOpenGLShaderProgram shader;
|
||||
|
||||
for (int j=0;j<c->effects.size();j++) {
|
||||
if (c->effects.at(j)->enable_opengl && c->effects.at(j)->is_enabled()) c->effects.at(j)->process_gl(shader, &anchor_x, &anchor_y);
|
||||
if (c->effects.at(j)->enable_opengl && c->effects.at(j)->is_enabled()) c->effects.at(j)->process_gl(panel_timeline->playhead-c->timeline_in+c->clip_in, shader, &anchor_x, &anchor_y);
|
||||
}
|
||||
|
||||
if (c->opening_transition != NULL) {
|
||||
|
||||
Reference in New Issue
Block a user