Merge branch 'master' into new_timecode
This commit is contained in:
+12
-12
@@ -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++) {
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user