Merge branch 'master' into new_timecode

This commit is contained in:
itsmattkc
2018-12-01 12:24:32 +11:00
committed by GitHub
53 changed files with 1874 additions and 954 deletions
+12 -12
View File
@@ -66,8 +66,8 @@ Clip* Clip::copy(Sequence* s) {
}
// TODO make a replacemennt for this somehow
//if (opening_transition != -1) copy->opening_transition = this->sequence->transitions.at(opening_transition)->copy(copy);
//if (closing_transition != -1) copy->closing_transition = this->sequence->transitions.at(closing_transition)->copy(copy);
if (get_opening_transition() != NULL && get_opening_transition()->secondary_clip == NULL) copy->opening_transition = get_opening_transition()->copy(copy, NULL);
if (get_closing_transition() != NULL && get_closing_transition()->secondary_clip == NULL) copy->closing_transition = get_closing_transition()->copy(copy, NULL);
copy->recalculateMaxLength();
@@ -169,8 +169,8 @@ Clip::~Clip() {
}
}
//if (opening_transition != -1) this->sequence->hard_delete_transition(this, TA_OPENING_TRANSITION);
//if (closing_transition != -1) this->sequence->hard_delete_transition(this, TA_CLOSING_TRANSITION);
if (opening_transition != -1) this->sequence->hard_delete_transition(this, TA_OPENING_TRANSITION);
if (closing_transition != -1) this->sequence->hard_delete_transition(this, TA_CLOSING_TRANSITION);
for (int i=0;i<effects.size();i++) {
delete effects.at(i);
@@ -181,7 +181,7 @@ Clip::~Clip() {
long Clip::get_clip_in_with_transition() {
if (get_opening_transition() != NULL && get_opening_transition()->secondary_clip != NULL) {
// we must be the secondary clip, so return (timeline in - length)
return clip_in - get_opening_transition()->length;
return clip_in - get_opening_transition()->get_true_length();
}
return clip_in;
}
@@ -189,7 +189,7 @@ long Clip::get_clip_in_with_transition() {
long Clip::get_timeline_in_with_transition() {
if (get_opening_transition() != NULL && get_opening_transition()->secondary_clip != NULL) {
// we must be the secondary clip, so return (timeline in - length)
return timeline_in - get_opening_transition()->length;
return timeline_in - get_opening_transition()->get_true_length();
}
return timeline_in;
}
@@ -197,7 +197,7 @@ long Clip::get_timeline_in_with_transition() {
long Clip::get_timeline_out_with_transition() {
if (get_closing_transition() != NULL && get_closing_transition()->secondary_clip != NULL) {
// we must be the primary clip, so return (timeline out + length2)
return timeline_out + get_closing_transition()->length;
return timeline_out + get_closing_transition()->get_true_length();
} else {
return timeline_out;
}
@@ -293,11 +293,11 @@ int Clip::getHeight() {
void Clip::refactor_frame_rate(ComboAction* ca, double multiplier, bool change_timeline_points) {
if (change_timeline_points) {
ca->append(new MoveClipAction(this,
qRound((double) timeline_in * multiplier),
qRound((double) timeline_out * multiplier),
qRound((double) clip_in * multiplier),
track));
move_clip(ca, this,
qRound((double) timeline_in * multiplier),
qRound((double) timeline_out * multiplier),
qRound((double) clip_in * multiplier),
track);
}
for (int i=0;i<effects.size();i++) {
+1
View File
@@ -67,6 +67,7 @@ struct Clip
int media_type;
int media_stream;
double speed;
double cached_fr;
bool reverse;
bool maintain_audio_pitch;
bool autoscale;
+100 -61
View File
@@ -39,8 +39,7 @@
#include <QtMath>
#include <QMenu>
QVector<EffectMeta> video_effects;
QVector<EffectMeta> audio_effects;
QVector<EffectMeta> effects;
QMutex effects_loaded;
Effect* create_effect(Clip* c, const EffectMeta* em) {
@@ -68,17 +67,12 @@ Effect* create_effect(Clip* c, const EffectMeta* em) {
return NULL;
}
const EffectMeta* get_internal_meta(int internal_id) {
for (int i=0;i<audio_effects.size();i++) {
if (audio_effects.at(i).internal == internal_id) {
return &audio_effects.at(i);
const EffectMeta* get_internal_meta(int internal_id, int type) {
for (int i=0;i<effects.size();i++) {
if (effects.at(i).internal == internal_id && effects.at(i).type == type) {
return &effects.at(i);
}
}
for (int i=0;i<video_effects.size();i++) {
if (video_effects.at(i).internal == internal_id) {
return &video_effects.at(i);
}
}
}
return NULL;
}
@@ -87,37 +81,40 @@ void load_internal_effects() {
// internal effects
em.type = EFFECT_TYPE_EFFECT;
em.subtype = EFFECT_TYPE_AUDIO;
em.name = "Volume";
em.internal = EFFECT_INTERNAL_VOLUME;
audio_effects.append(em);
effects.append(em);
em.name = "Pan";
em.internal = EFFECT_INTERNAL_PAN;
audio_effects.append(em);
effects.append(em);
em.name = "Tone";
em.internal = EFFECT_INTERNAL_TONE;
audio_effects.append(em);
effects.append(em);
em.name = "Noise";
em.internal = EFFECT_INTERNAL_NOISE;
audio_effects.append(em);
effects.append(em);
em.subtype = EFFECT_TYPE_VIDEO;
em.name = "Transform";
em.category = "Distort";
em.internal = EFFECT_INTERNAL_TRANSFORM;
video_effects.append(em);
effects.append(em);
em.name = "Corner Pin";
em.category = "Distort";
em.internal = EFFECT_INTERNAL_CORNERPIN;
video_effects.append(em);
em.name = "Corner Pin";
em.category = "Distort";
em.internal = EFFECT_INTERNAL_CORNERPIN;
effects.append(em);
em.name = "Text";
em.category = "Render";
em.internal = EFFECT_INTERNAL_TEXT;
video_effects.append(em);
effects.append(em);
em.name = "Timecode";
em.category = "Render";
@@ -127,12 +124,12 @@ void load_internal_effects() {
em.name = "Solid";
em.category = "Render";
em.internal = EFFECT_INTERNAL_SOLID;
video_effects.append(em);
effects.append(em);
em.name = "Shake";
em.category = "Distort";
em.internal = EFFECT_INTERNAL_SHAKE;
video_effects.append(em);
effects.append(em);
// internal transitions
em.type = EFFECT_TYPE_TRANSITION;
@@ -140,23 +137,21 @@ void load_internal_effects() {
em.name = "Cross Dissolve";
em.internal = TRANSITION_INTERNAL_CROSSDISSOLVE;
video_effects.append(em);
effects.append(em);
em.name = "Cube";
em.internal = TRANSITION_INTERNAL_CUBE;
video_effects.append(em);
em.subtype = EFFECT_TYPE_AUDIO;
em.name = "Linear Fade";
em.internal = TRANSITION_INTERNAL_LINEARFADE;
audio_effects.append(em);
effects.append(em);
em.name = "Exponential Fade";
em.internal = TRANSITION_INTERNAL_EXPONENTIALFADE;
audio_effects.append(em);
effects.append(em);
em.name = "Logarithmic Fade";
em.internal = TRANSITION_INTERNAL_LOGARITHMICFADE;
audio_effects.append(em);
effects.append(em);
}
void load_shader_effects() {
@@ -187,11 +182,12 @@ void load_shader_effects() {
if (!effect_name.isEmpty()) {
EffectMeta em;
em.type = EFFECT_TYPE_EFFECT;
em.subtype = EFFECT_TYPE_VIDEO;
em.name = effect_name;
em.category = effect_cat;
em.filename = entries.at(i);
em.internal = -1;
video_effects.append(em);
effects.append(em);
} else {
dout << "[ERROR] Invalid effect found in" << entries.at(i);
}
@@ -231,10 +227,9 @@ void EffectInit::run() {
Effect::Effect(Clip* c, const EffectMeta *em) :
parent_clip(c),
meta(em),
length(30),
enable_shader(false),
enable_coords(false),
enable_superimpose(false),
enable_superimpose(false),
glslProgram(NULL),
texture(NULL),
isOpen(false),
@@ -305,8 +300,7 @@ Effect::Effect(Clip* c, const EffectMeta *em) :
if (id.isEmpty()) {
dout << "[ERROR] Couldn't load field from" << em->filename << "- ID cannot be empty.";
} else if (type > -1) {
EffectField* field = row->add_field(type);
field->id = id;
EffectField* field = row->add_field(type, id);
connect(field, SIGNAL(changed()), this, SLOT(field_changed()));
switch (type) {
case EFFECT_FIELD_DOUBLE:
@@ -457,9 +451,9 @@ void Effect::copy_field_keyframes(Effect* e) {
}
}
EffectRow* Effect::add_row(const QString& name) {
EffectRow* row = new EffectRow(this, ui_layout, name, rows.size());
rows.append(row);
EffectRow* Effect::add_row(const QString& name, bool savable) {
EffectRow* row = new EffectRow(this, savable, ui_layout, name, rows.size());
rows.append(row);
return row;
}
@@ -468,7 +462,21 @@ EffectRow* Effect::row(int i) {
}
int Effect::row_count() {
return rows.size();
return rows.size();
}
EffectGizmo *Effect::add_gizmo(int type) {
EffectGizmo* gizmo = new EffectGizmo(type);
gizmos.append(gizmo);
return gizmo;
}
EffectGizmo *Effect::gizmo(int i) {
return gizmos.at(i);
}
int Effect::gizmo_count(){
return gizmos.size();
}
void Effect::refresh() {}
@@ -679,31 +687,32 @@ void Effect::load(QXmlStreamReader& stream) {
void Effect::save(QXmlStreamWriter& stream) {
stream.writeAttribute("name", meta->name);
stream.writeAttribute("enabled", QString::number(is_enabled()));
stream.writeAttribute("length", QString::number(length));
for (int i=0;i<rows.size();i++) {
EffectRow* row = rows.at(i);
stream.writeStartElement("row"); // row
stream.writeStartElement("keyframes"); // keyframes
stream.writeAttribute("enabled", QString::number(row->isKeyframing()));
for (int j=0;j<row->keyframe_times.size();j++) {
stream.writeStartElement("key"); // key
stream.writeAttribute("frame", QString::number(row->keyframe_times.at(j)));
stream.writeAttribute("type", QString::number(row->keyframe_types.at(j)));
stream.writeEndElement(); // key
if (row->savable) {
stream.writeStartElement("row"); // row
stream.writeStartElement("keyframes"); // keyframes
stream.writeAttribute("enabled", QString::number(row->isKeyframing()));
for (int j=0;j<row->keyframe_times.size();j++) {
stream.writeStartElement("key"); // key
stream.writeAttribute("frame", QString::number(row->keyframe_times.at(j)));
stream.writeAttribute("type", QString::number(row->keyframe_types.at(j)));
stream.writeEndElement(); // key
}
stream.writeEndElement(); // keyframes
for (int j=0;j<row->fieldCount();j++) {
EffectField* field = row->field(j);
stream.writeStartElement("field"); // field
stream.writeAttribute("id", field->id);
stream.writeAttribute("value", save_data_to_string(field->type, field->get_current_data()));
for (int k=0;k<field->keyframe_data.size();k++) {
stream.writeTextElement("key", save_data_to_string(field->type, field->keyframe_data.at(k)));
}
stream.writeEndElement(); // field
}
stream.writeEndElement(); // row
}
stream.writeEndElement(); // keyframes
for (int j=0;j<row->fieldCount();j++) {
EffectField* field = row->field(j);
stream.writeStartElement("field"); // field
stream.writeAttribute("id", field->id);
stream.writeAttribute("value", save_data_to_string(field->type, field->get_current_data()));
for (int k=0;k<field->keyframe_data.size();k++) {
stream.writeTextElement("key", save_data_to_string(field->type, field->keyframe_data.at(k)));
}
stream.writeEndElement(); // field
}
stream.writeEndElement(); // row
}
}
@@ -844,6 +853,36 @@ void Effect::process_audio(double, double, quint8*, int, int) {
}*/
}
void Effect::gizmo_draw(double, GLTextureCoords &) {}
void Effect::gizmo_move(EffectGizmo* , int , int , double ) {}
void Effect::gizmo_world_to_screen() {
GLfloat view_val[16];
GLfloat projection_val[16];
glGetFloatv(GL_MODELVIEW_MATRIX, view_val);
glGetFloatv(GL_PROJECTION_MATRIX, projection_val);
QMatrix4x4 view_matrix(view_val);
QMatrix4x4 projection_matrix(projection_val);
for (int i=0;i<gizmos.size();i++) {
EffectGizmo* g = gizmos.at(i);
for (int j=0;j<g->get_point_count();j++) {
QVector4D screen_pos = QVector4D(g->world_pos[j].x(), g->world_pos[j].y(), 0, 1.0) * (view_matrix * projection_matrix);
int adjusted_sx1 = qRound(((screen_pos.x()*0.5f)+0.5f)*parent_clip->sequence->width);
int adjusted_sy1 = qRound((1.0f-((screen_pos.y()*0.5f)+0.5f))*parent_clip->sequence->height);
g->screen_pos[j] = QPoint(adjusted_sx1, adjusted_sy1);
}
}
}
bool Effect::are_gizmos_enabled() {
return (gizmos.size() > 0);
}
void Effect::redraw(double) {
/*
// run javascript
+34 -16
View File
@@ -1,4 +1,4 @@
#ifndef EFFECT_H
#ifndef EFFECT_H
#define EFFECT_H
#include <QObject>
@@ -15,6 +15,7 @@ class QWidget;
class CollapsibleWidget;
class QGridLayout;
class QPushButton;
class QMouseEvent;
struct Clip;
class QXmlStreamReader;
@@ -30,15 +31,15 @@ struct EffectMeta {
QString filename;
int internal;
int type;
int subtype;
};
extern QVector<EffectMeta> video_effects;
extern QVector<EffectMeta> audio_effects;
extern QVector<EffectMeta> effects;
double log_volume(double linear);
void init_effects();
Effect* create_effect(Clip* c, const EffectMeta *em);
const EffectMeta* get_internal_meta(int internal_id);
const EffectMeta* get_internal_meta(int internal_id, int type);
extern QMutex effects_loaded;
@@ -64,7 +65,6 @@ extern QMutex effects_loaded;
#define EFFECT_INTERNAL_CORNERPIN 12
#define EFFECT_INTERNAL_COUNT 13
@@ -77,27 +77,36 @@ struct GLTextureCoords {
int vertexTopLeftX;
int vertexTopLeftY;
int vertexTopLeftZ;
int vertexTopRightX;
int vertexTopRightY;
int vertexTopRightZ;
int vertexBottomLeftX;
int vertexBottomLeftY;
int vertexBottomLeftZ;
int vertexBottomRightX;
int vertexBottomRightY;
int vertexBottomRightZ;
double textureTopLeftX;
double textureTopLeftY;
double textureTopRightX;
double textureTopRightY;
double textureBottomRightX;
double textureBottomRightY;
double textureBottomLeftX;
double textureBottomLeftY;
float textureTopLeftX;
float textureTopLeftY;
float textureTopLeftQ;
float textureTopRightX;
float textureTopRightY;
float textureTopRightQ;
float textureBottomRightX;
float textureBottomRightY;
float textureBottomRightQ;
float textureBottomLeftX;
float textureBottomLeftY;
float textureBottomLeftQ;
};
qint16 mix_audio_sample(qint16 a, qint16 b);
#include "effectfield.h"
#include "effectrow.h"
#include "effectgizmo.h"
class Effect : public QObject {
Q_OBJECT
@@ -106,15 +115,18 @@ public:
~Effect();
Clip* parent_clip;
const EffectMeta* meta;
long length; // used only for transitions
int id;
QString name;
CollapsibleWidget* container;
EffectRow* add_row(const QString &name);
EffectRow* add_row(const QString &name, bool savable = true);
EffectRow* row(int i);
int row_count();
EffectGizmo* add_gizmo(int type);
EffectGizmo* gizmo(int i);
int gizmo_count();
bool is_enabled();
void set_enabled(bool b);
@@ -134,7 +146,7 @@ public:
bool enable_shader;
bool enable_coords;
bool enable_superimpose;
bool enable_superimpose;
int getIterations();
void setIterations(int i);
@@ -145,6 +157,11 @@ public:
virtual void process_coords(double timecode, GLTextureCoords& coords, int data);
virtual GLuint process_superimpose(double timecode);
virtual void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count);
virtual void gizmo_draw(double timecode, GLTextureCoords& coords);
virtual void gizmo_move(EffectGizmo* sender, int x_movement, int y_movement, double timecode);
void gizmo_world_to_screen();
bool are_gizmos_enabled();
public slots:
void field_changed();
private slots:
@@ -170,6 +187,7 @@ private:
bool isOpen;
QVector<EffectRow*> rows;
QVector<EffectGizmo*> gizmos;
QGridLayout* ui_layout;
QWidget* ui;
bool bound;
+1 -1
View File
@@ -17,7 +17,7 @@
#include "io/math.h"
#include <QtMath>
EffectField::EffectField(EffectRow *parent, int t) : parent_row(parent), type(t) {
EffectField::EffectField(EffectRow *parent, int t, const QString &i) : parent_row(parent), type(t), id(i) {
switch (t) {
case EFFECT_FIELD_DOUBLE:
{
+1 -1
View File
@@ -17,7 +17,7 @@ class EffectRow;
class EffectField : public QObject {
Q_OBJECT
public:
EffectField(EffectRow* parent, int t);
EffectField(EffectRow* parent, int t, const QString& i);
EffectRow* parent_row;
int type;
QString id;
+28
View File
@@ -0,0 +1,28 @@
#include "effectgizmo.h"
EffectGizmo::EffectGizmo(int type) :
type(type),
cursor(-1)
{
int point_count = (type == GIZMO_TYPE_POLY) ? 4 : 1;
world_pos.resize(point_count);
screen_pos.resize(point_count);
color = Qt::white;
}
int EffectGizmo::get_point_count() {
return world_pos.size();
}
int EffectGizmo::get_type() {
return type;
}
int EffectGizmo::get_cursor() {
return cursor;
}
void EffectGizmo::set_cursor(int c) {
cursor = c;
}
+34
View File
@@ -0,0 +1,34 @@
#ifndef EFFECTGIZMO_H
#define EFFECTGIZMO_H
#define GIZMO_TYPE_DOT 0
#define GIZMO_TYPE_POLY 1
#define GIZMO_DOT_SIZE 2.5F
#include <QString>
#include <QRect>
#include <QPoint>
#include <QVector>
#include <QColor>
class EffectGizmo
{
public:
EffectGizmo(int type);
QVector<QPoint> world_pos;
QVector<QPoint> screen_pos;
QColor color;
int get_point_count();
int get_type();
int get_cursor();
void set_cursor(int c);
private:
int type;
int cursor;
};
#endif // EFFECTGIZMO_H
+42 -36
View File
@@ -14,8 +14,9 @@
#include "effect.h"
#include "ui/viewerwidget.h"
EffectRow::EffectRow(Effect *parent, QGridLayout *uilayout, const QString &n, int row) :
EffectRow::EffectRow(Effect *parent, bool save, QGridLayout *uilayout, const QString &n, int row) :
parent_effect(parent),
savable(save),
keyframing(false),
ui(uilayout),
name(n),
@@ -25,43 +26,45 @@ EffectRow::EffectRow(Effect *parent, QGridLayout *uilayout, const QString &n, in
label = new QLabel(name);
ui->addWidget(label, row, 0);
QSize button_size(20, 20);
QSize icon_size(12, 12);
if (parent_effect->meta->type != EFFECT_TYPE_TRANSITION) {
QSize button_size(20, 20);
QSize icon_size(12, 12);
QHBoxLayout* key_controls = new QHBoxLayout();
key_controls->setSpacing(0);
key_controls->setMargin(0);
key_controls->addStretch();
QHBoxLayout* key_controls = new QHBoxLayout();
key_controls->setSpacing(0);
key_controls->setMargin(0);
key_controls->addStretch();
left_key_nav = new QPushButton("<");
left_key_nav->setVisible(false);
left_key_nav->setMaximumSize(button_size);
key_controls->addWidget(left_key_nav);
connect(left_key_nav, SIGNAL(clicked(bool)), this, SLOT(goto_previous_key()));
left_key_nav = new QPushButton("<");
left_key_nav->setVisible(false);
left_key_nav->setMaximumSize(button_size);
key_controls->addWidget(left_key_nav);
connect(left_key_nav, SIGNAL(clicked(bool)), this, SLOT(goto_previous_key()));
key_addremove = new QPushButton(".");
key_addremove->setVisible(false);
key_addremove->setMaximumSize(button_size);
key_controls->addWidget(key_addremove);
connect(key_addremove, SIGNAL(clicked(bool)), this, SLOT(toggle_key()));
key_addremove = new QPushButton(".");
key_addremove->setVisible(false);
key_addremove->setMaximumSize(button_size);
key_controls->addWidget(key_addremove);
connect(key_addremove, SIGNAL(clicked(bool)), this, SLOT(toggle_key()));
right_key_nav = new QPushButton(">");
right_key_nav->setVisible(false);
right_key_nav->setMaximumSize(button_size);
key_controls->addWidget(right_key_nav);
connect(right_key_nav, SIGNAL(clicked(bool)), this, SLOT(goto_next_key()));
right_key_nav = new QPushButton(">");
right_key_nav->setVisible(false);
right_key_nav->setMaximumSize(button_size);
key_controls->addWidget(right_key_nav);
connect(right_key_nav, SIGNAL(clicked(bool)), this, SLOT(goto_next_key()));
keyframe_enable = new QPushButton(QIcon(":/icons/clock.png"), "");
keyframe_enable->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
keyframe_enable->setMaximumSize(button_size);
keyframe_enable->setIconSize(icon_size);
keyframe_enable->setCheckable(true);
keyframe_enable->setToolTip("Enable Keyframes");
connect(keyframe_enable, SIGNAL(clicked(bool)), this, SLOT(set_keyframe_enabled(bool)));
connect(keyframe_enable, SIGNAL(toggled(bool)), this, SLOT(keyframe_ui_enabled(bool)));
key_controls->addWidget(keyframe_enable);
keyframe_enable = new QPushButton(QIcon(":/icons/clock.png"), "");
keyframe_enable->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
keyframe_enable->setMaximumSize(button_size);
keyframe_enable->setIconSize(icon_size);
keyframe_enable->setCheckable(true);
keyframe_enable->setToolTip("Enable Keyframes");
connect(keyframe_enable, SIGNAL(clicked(bool)), this, SLOT(set_keyframe_enabled(bool)));
connect(keyframe_enable, SIGNAL(toggled(bool)), this, SLOT(keyframe_ui_enabled(bool)));
key_controls->addWidget(keyframe_enable);
ui->addLayout(key_controls, row, 6);
ui->addLayout(key_controls, row, 6);
}
}
bool EffectRow::isKeyframing() {
@@ -69,8 +72,10 @@ bool EffectRow::isKeyframing() {
}
void EffectRow::setKeyframing(bool b) {
keyframing = b;
keyframe_enable->setChecked(b);
if (parent_effect->meta->type != EFFECT_TYPE_TRANSITION) {
keyframing = b;
keyframe_enable->setChecked(b);
}
}
void EffectRow::set_keyframe_enabled(bool enabled) {
@@ -144,11 +149,12 @@ void EffectRow::goto_next_key() {
if (key != LONG_MAX) panel_sequence_viewer->seek(key);
}
EffectField* EffectRow::add_field(int type, int colspan) {
EffectField* field = new EffectField(this, type);
EffectField* EffectRow::add_field(int type, const QString& id, int colspan) {
EffectField* field = new EffectField(this, type, id);
fields.append(field);
QWidget* element = field->get_ui_element();
ui->addWidget(element, ui_row, fields.size(), 1, colspan);
connect(field, SIGNAL(changed()), parent_effect, SLOT(field_changed()));
return field;
}
+3 -2
View File
@@ -14,9 +14,9 @@ class QPushButton;
class EffectRow : public QObject {
Q_OBJECT
public:
EffectRow(Effect* parent, QGridLayout* uilayout, const QString& n, int row);
EffectRow(Effect* parent, bool save, QGridLayout* uilayout, const QString& n, int row);
~EffectRow();
EffectField* add_field(int type, int colspan = 1);
EffectField* add_field(int type, const QString &id, int colspan = 1);
EffectField* field(int i);
int fieldCount();
void set_keyframe_now(bool undoable);
@@ -24,6 +24,7 @@ public:
void delete_keyframe_at_time(KeyframeDelete* kd, long time);
QLabel* label;
Effect* parent_effect;
bool savable;
bool isKeyframing();
void setKeyframing(bool);
+8 -3
View File
@@ -57,6 +57,7 @@ long Sequence::getEndFrame() {
void Sequence::hard_delete_transition(Clip *c, int type) {
int transition_index = (type == TA_OPENING_TRANSITION) ? c->opening_transition : c->closing_transition;
if (transition_index > -1) {
bool del = true;
for (int i=0;i<clips.size();i++) {
Clip* cc = clips.at(i);
if (cc != NULL
@@ -64,12 +65,16 @@ void Sequence::hard_delete_transition(Clip *c, int type) {
&& (cc->opening_transition == transition_index
|| cc->closing_transition == transition_index)) {
// another clip is using this, don't delete just yet
return;
del = false;
break;
}
}
delete transitions.at(transition_index);
transitions[transition_index] = NULL;
if (del) {
delete transitions.at(transition_index);
transitions[transition_index] = NULL;
}
if (type == TA_OPENING_TRANSITION) {
c->opening_transition = -1;
} else {
+31 -2
View File
@@ -11,10 +11,25 @@
#include "effects/internal/logarithmicfadetransition.h"
#include "effects/internal/cubetransition.h"
#include "ui/labelslider.h"
#include "panels/panels.h"
#include "panels/timeline.h"
#include <QMessageBox>
Transition::Transition(Clip* c, Clip* s, const EffectMeta* em) : Effect(c, em), secondary_clip(s) {
add_row("Length:")->add_field(EFFECT_FIELD_DOUBLE);
Transition::Transition(Clip* c, Clip* s, const EffectMeta* em) :
Effect(c, em), secondary_clip(s),
length(30)
{
length_field = add_row("Length:", false)->add_field(EFFECT_FIELD_DOUBLE, "length");
connect(length_field, SIGNAL(changed()), this, SLOT(set_length_from_slider()));
length_field->set_double_default_value(30);
length_field->set_double_minimum_value(0);
LabelSlider* length_ui_ele = static_cast<LabelSlider*>(length_field->ui_element);
length_ui_ele->set_display_type(LABELSLIDER_FRAMENUMBER);
length_ui_ele->set_frame_rate(parent_clip->sequence->frame_rate);
}
int Transition::copy(Clip *c, Clip* s) {
@@ -23,6 +38,15 @@ int Transition::copy(Clip *c, Clip* s) {
return copy_index;
}
void Transition::set_length(long l) {
length = l;
length_field->set_double_value(l);
}
long Transition::get_true_length() {
return length;
}
long Transition::get_length() {
if (secondary_clip != NULL) {
return length * 2;
@@ -30,6 +54,11 @@ long Transition::get_length() {
return length;
}
void Transition::set_length_from_slider() {
set_length(length_field->get_double_value(0));
update_ui(false);
}
Transition* get_transition_from_meta(Clip* c, Clip* s, const EffectMeta* em) {
if (!em->filename.isEmpty()) {
// load effect from file
+8
View File
@@ -17,11 +17,19 @@
int create_transition(Clip* c, Clip* s, const EffectMeta* em);
class Transition : public Effect {
Q_OBJECT
public:
Transition(Clip* c, Clip* s, const EffectMeta* em);
int copy(Clip* c, Clip* s);
Clip* secondary_clip;
void set_length(long l);
long get_true_length();
long get_length();
private slots:
void set_length_from_slider();
private:
long length; // used only for transitions
EffectField* length_field;
};
#endif // TRANSITION_H
+59 -13
View File
@@ -21,6 +21,7 @@
#include "ui/viewerwidget.h"
#include "project/marker.h"
#include "mainwindow.h"
#include "io/clipboard.h"
#include "debug.h"
QUndoStack undo_stack;
@@ -224,9 +225,10 @@ void AddEffectCommand::redo() {
mainWindow->setWindowModified(true);
}
AddTransitionCommand::AddTransitionCommand(Clip* c, Clip *s, const EffectMeta *itransition, int itype, int ilength) :
AddTransitionCommand::AddTransitionCommand(Clip* c, Clip *s, Transition* copy, const EffectMeta *itransition, int itype, int ilength) :
clip(c),
secondary(s),
transition_to_copy(copy),
transition(itransition),
type(itype),
length(ilength),
@@ -236,21 +238,38 @@ AddTransitionCommand::AddTransitionCommand(Clip* c, Clip *s, const EffectMeta *i
void AddTransitionCommand::undo() {
clip->sequence->hard_delete_transition(clip, type);
if (secondary != NULL) secondary->sequence->hard_delete_transition(secondary, (type == TA_OPENING_TRANSITION) ? TA_CLOSING_TRANSITION : TA_OPENING_TRANSITION);
if (type == TA_OPENING_TRANSITION) {
clip->opening_transition = old_ptransition;
if (secondary != NULL) secondary->closing_transition = old_stransition;
} else {
clip->closing_transition = old_ptransition;
if (secondary != NULL) secondary->opening_transition = old_stransition;
}
mainWindow->setWindowModified(old_project_changed);
}
void AddTransitionCommand::redo() {
if (type == TA_OPENING_TRANSITION) {
clip->opening_transition = create_transition(clip, secondary, transition);
if (secondary != NULL) secondary->closing_transition = clip->opening_transition;
old_ptransition = clip->opening_transition;
clip->opening_transition = (transition_to_copy == NULL) ? create_transition(clip, secondary, transition) : transition_to_copy->copy(clip, NULL);
if (secondary != NULL) {
old_stransition = secondary->closing_transition;
secondary->closing_transition = clip->opening_transition;
}
if (length > 0) {
clip->get_opening_transition()->length = length;
clip->get_opening_transition()->set_length(length);
}
} else {
clip->closing_transition = create_transition(clip, secondary, transition);
if (secondary != NULL) secondary->opening_transition = clip->closing_transition;
old_ptransition = clip->closing_transition;
clip->closing_transition = (transition_to_copy == NULL) ? create_transition(clip, secondary, transition) : transition_to_copy->copy(clip, NULL);
if (secondary != NULL) {
old_stransition = secondary->opening_transition;
secondary->opening_transition = clip->closing_transition;
}
if (length > 0) {
clip->get_closing_transition()->length = length;
clip->get_closing_transition()->set_length(length);
}
}
mainWindow->setWindowModified(true);
@@ -265,14 +284,14 @@ ModifyTransitionCommand::ModifyTransitionCommand(Clip* c, int itype, long ilengt
void ModifyTransitionCommand::undo() {
Transition* t = (type == TA_OPENING_TRANSITION) ? clip->get_opening_transition() : clip->get_closing_transition();
t->length = old_length;
t->set_length(old_length);
mainWindow->setWindowModified(old_project_changed);
}
void ModifyTransitionCommand::redo() {
Transition* t = (type == TA_OPENING_TRANSITION) ? clip->get_opening_transition() : clip->get_closing_transition();
old_length = t->length;
t->length = new_length;
old_length = t->get_true_length();
t->set_length(new_length);
mainWindow->setWindowModified(true);
}
@@ -484,6 +503,7 @@ void AddClipCommand::undo() {
Clip* c = seq->clips.last();
panel_timeline->deselect_area(c->timeline_in, c->timeline_out, c->track);
undone_clips.prepend(c);
if (c->open) close_clip(c);
seq->clips.removeLast();
}
mainWindow->setWindowModified(old_project_changed);
@@ -504,6 +524,8 @@ void AddClipCommand::redo() {
for (int j=0;j<original->linked.size();j++) {
copy->linked[j] = original->linked.at(j) + linkOffset;
}
if (original->opening_transition > -1) copy->opening_transition = original->get_opening_transition()->copy(copy, NULL);
if (original->closing_transition > -1) copy->closing_transition = original->get_closing_transition()->copy(copy, NULL);
seq->clips.append(copy);
}
}
@@ -1233,13 +1255,13 @@ RemoveClipsFromClipboard::~RemoveClipsFromClipboard() {
}
void RemoveClipsFromClipboard::undo() {
panel_timeline->clip_clipboard.insert(pos, clip);
clipboard.insert(pos, clip);
done = false;
}
void RemoveClipsFromClipboard::redo() {
clip = panel_timeline->clip_clipboard.at(pos);
panel_timeline->clip_clipboard.removeAt(pos);
clip = static_cast<Clip*>(clipboard.at(pos));
clipboard.removeAt(pos);
done = true;
}
@@ -1277,3 +1299,27 @@ void SetPointer::redo() {
*p = new_data;
mainWindow->setWindowModified(true);
}
MoveGizmo::MoveGizmo(Effect *e, EffectGizmo *g, int x_movement, int y_movement, double tc) :
effect(e),
gizmo(g),
x(x_movement),
y(y_movement),
timecode(tc),
done(true),
old_changed(mainWindow->isWindowModified())
{}
void MoveGizmo::undo() {
effect->gizmo_move(gizmo, -x, -y, timecode);
mainWindow->setWindowModified(old_changed);
done = false;
}
void MoveGizmo::redo() {
if (!done) {
effect->gizmo_move(gizmo, x, y, timecode);
mainWindow->setWindowModified(true);
done = true;
}
}
+20 -1
View File
@@ -9,6 +9,7 @@ class SourceTable;
class EffectRow;
class EffectField;
class Transition;
class EffectGizmo;
struct Clip;
struct Sequence;
struct Media;
@@ -101,16 +102,19 @@ private:
class AddTransitionCommand : public QUndoCommand {
public:
AddTransitionCommand(Clip* c, Clip* s, const EffectMeta* itransition, int itype, int ilength);
AddTransitionCommand(Clip* c, Clip* s, Transition *copy, const EffectMeta* itransition, int itype, int ilength);
void undo();
void redo();
private:
Clip* clip;
Clip* secondary;
Transition* transition_to_copy;
const EffectMeta* transition;
int type;
int length;
bool old_project_changed;
int old_ptransition;
int old_stransition;
};
class ModifyTransitionCommand : public QUndoCommand {
@@ -594,4 +598,19 @@ private:
void* old_data;
};
class MoveGizmo : public QUndoCommand {
public:
MoveGizmo(Effect* e, EffectGizmo* g, int x_movement, int y_movement, double tc);
void undo();
void redo();
private:
Effect* effect;
EffectGizmo* gizmo;
int x;
int y;
double timecode;
bool done;
bool old_changed;
};
#endif // UNDO_H