effects system rewrite
This commit is contained in:
+224
-79
@@ -17,24 +17,7 @@
|
||||
#include "panels/timeline.h"
|
||||
#include "panels/effectcontrols.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include "effects/video/transformeffect.h"
|
||||
#include "effects/video/inverteffect.h"
|
||||
#include "effects/video/shakeeffect.h"
|
||||
#include "effects/video/solideffect.h"
|
||||
#include "effects/video/texteffect.h"
|
||||
#include "effects/video/chromakeyeffect.h"
|
||||
#include "effects/video/gaussianblureffect.h"
|
||||
#include "effects/video/cropeffect.h"
|
||||
#include "effects/video/flipeffect.h"
|
||||
#include "effects/video/boxblureffect.h"
|
||||
#include "effects/video/waveeffect.h"
|
||||
#include "effects/video/temperatureeffect.h"
|
||||
|
||||
#include "effects/audio/paneffect.h"
|
||||
#include "effects/audio/volumeeffect.h"
|
||||
#include "effects/audio/audionoiseeffect.h"
|
||||
#include "effects/audio/toneeffect.h"
|
||||
#include "io/path.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QGridLayout>
|
||||
@@ -42,58 +25,92 @@
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QMessageBox>
|
||||
#include <QOpenGLContext>
|
||||
#include <QDir>
|
||||
|
||||
QVector<EffectMeta> video_effects;
|
||||
QVector<EffectMeta> audio_effects;
|
||||
|
||||
QVector<QString> video_effect_names;
|
||||
QVector<QString> audio_effect_names;
|
||||
|
||||
void init_effects() {
|
||||
video_effect_names.resize(VIDEO_EFFECT_COUNT);
|
||||
audio_effect_names.resize(AUDIO_EFFECT_COUNT);
|
||||
video_effect_names.resize(VIDEO_EFFECT_COUNT);
|
||||
audio_effect_names.resize(AUDIO_EFFECT_COUNT);
|
||||
|
||||
video_effect_names[VIDEO_TRANSFORM_EFFECT] = "Transform";
|
||||
video_effect_names[VIDEO_SHAKE_EFFECT] = "Shake";
|
||||
video_effect_names[VIDEO_TEXT_EFFECT] = "Text";
|
||||
video_effect_names[VIDEO_SOLID_EFFECT] = "Solid";
|
||||
video_effect_names[VIDEO_INVERT_EFFECT] = "Invert";
|
||||
video_effect_names[VIDEO_CHROMAKEY_EFFECT] = "Chroma Key";
|
||||
video_effect_names[VIDEO_GAUSSIANBLUR_EFFECT] = "Gaussian Blur";
|
||||
video_effect_names[VIDEO_CROP_EFFECT] = "Crop";
|
||||
video_effect_names[VIDEO_FLIP_EFFECT] = "Flip";
|
||||
video_effect_names[VIDEO_TRANSFORM_EFFECT] = "Transform";
|
||||
video_effect_names[VIDEO_SHAKE_EFFECT] = "Shake";
|
||||
video_effect_names[VIDEO_TEXT_EFFECT] = "Text";
|
||||
video_effect_names[VIDEO_SOLID_EFFECT] = "Solid";
|
||||
video_effect_names[VIDEO_INVERT_EFFECT] = "Invert";
|
||||
video_effect_names[VIDEO_CHROMAKEY_EFFECT] = "Chroma Key";
|
||||
video_effect_names[VIDEO_GAUSSIANBLUR_EFFECT] = "Gaussian Blur";
|
||||
video_effect_names[VIDEO_CROP_EFFECT] = "Crop";
|
||||
video_effect_names[VIDEO_FLIP_EFFECT] = "Flip";
|
||||
video_effect_names[VIDEO_BOXBLUR_EFFECT] = "Box Blur";
|
||||
video_effect_names[VIDEO_WAVE_EFFECT] = "Wave";
|
||||
video_effect_names[VIDEO_WAVE_EFFECT] = "Wave";
|
||||
video_effect_names[VIDEO_TEMPERATURE_EFFECT] = "Temperature";
|
||||
|
||||
audio_effect_names[AUDIO_VOLUME_EFFECT] = "Volume";
|
||||
audio_effect_names[AUDIO_PAN_EFFECT] = "Pan";
|
||||
audio_effect_names[AUDIO_NOISE_EFFECT] = "Noise";
|
||||
audio_effect_names[AUDIO_TONE_EFFECT] = "Tone";
|
||||
audio_effect_names[AUDIO_VOLUME_EFFECT] = "Volume";
|
||||
audio_effect_names[AUDIO_PAN_EFFECT] = "Pan";
|
||||
audio_effect_names[AUDIO_NOISE_EFFECT] = "Noise";
|
||||
audio_effect_names[AUDIO_TONE_EFFECT] = "Tone";
|
||||
|
||||
dout << "Starting init effect (TODO: multithread this)";
|
||||
QString effects_path = get_effects_dir();
|
||||
QDir effects_dir(effects_path);
|
||||
if (effects_dir.exists()) {
|
||||
QList<QString> entries = effects_dir.entryList(QStringList("*.xml"), QDir::Files);
|
||||
for (int i=0;i<entries.size();i++) {
|
||||
QFile file(effects_path + "/" + entries.at(i));
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
dout << "[ERROR] Could not open file";
|
||||
return;
|
||||
}
|
||||
|
||||
QXmlStreamReader reader(&file);
|
||||
while (!reader.atEnd()) {
|
||||
if (reader.name() == "effect") {
|
||||
QString effect_name = "";
|
||||
QString effect_cat = "";
|
||||
int effect_type = EFFECT_TYPE_INVALID;
|
||||
const QXmlStreamAttributes attr = reader.attributes();
|
||||
for (int j=0;j<attr.size();j++) {
|
||||
if (attr.at(j).name() == "name") {
|
||||
effect_name = attr.at(j).value().toString();
|
||||
} else if (attr.at(j).name() == "category") {
|
||||
effect_cat = attr.at(j).value().toString();
|
||||
} else if (attr.at(j).name() == "type") {
|
||||
QString compare = attr.at(j).value().toString().toUpper();
|
||||
if (compare == "VIDEO") {
|
||||
effect_type = EFFECT_TYPE_VIDEO;
|
||||
} else if (compare == "AUDIO") {
|
||||
effect_type = EFFECT_TYPE_AUDIO;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (effect_type != EFFECT_TYPE_INVALID && !effect_name.isEmpty()) {
|
||||
EffectMeta em;
|
||||
em.name = effect_name;
|
||||
em.category = effect_cat;
|
||||
em.filename = entries.at(i);
|
||||
if (effect_type == EFFECT_TYPE_VIDEO) {
|
||||
video_effects.append(em);
|
||||
} else {
|
||||
audio_effects.append(em);
|
||||
}
|
||||
} else {
|
||||
dout << "[ERROR] Invalid effect found in" << entries.at(i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
reader.readNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
dout << "Completed init effect (TODO: multithread this)";
|
||||
}
|
||||
|
||||
Effect* create_effect(int effect_id, Clip* c) {
|
||||
if (c->track < 0) {
|
||||
switch (effect_id) {
|
||||
case VIDEO_TRANSFORM_EFFECT: return new TransformEffect(c); break;
|
||||
case VIDEO_SHAKE_EFFECT: return new ShakeEffect(c); break;
|
||||
case VIDEO_TEXT_EFFECT: return new TextEffect(c); break;
|
||||
case VIDEO_SOLID_EFFECT: return new SolidEffect(c); break;
|
||||
case VIDEO_INVERT_EFFECT: return new InvertEffect(c); break;
|
||||
case VIDEO_CHROMAKEY_EFFECT: return new ChromaKeyEffect(c); break;
|
||||
case VIDEO_GAUSSIANBLUR_EFFECT: return new GaussianBlurEffect(c); break;
|
||||
case VIDEO_CROP_EFFECT: return new CropEffect(c);
|
||||
case VIDEO_FLIP_EFFECT: return new FlipEffect(c);
|
||||
case VIDEO_BOXBLUR_EFFECT: return new BoxBlurEffect(c);
|
||||
case VIDEO_WAVE_EFFECT: return new WaveEffect(c);
|
||||
case VIDEO_TEMPERATURE_EFFECT: return new TemperatureEffect(c);
|
||||
}
|
||||
} else {
|
||||
switch (effect_id) {
|
||||
case AUDIO_VOLUME_EFFECT: return new VolumeEffect(c); break;
|
||||
case AUDIO_PAN_EFFECT: return new PanEffect(c); break;
|
||||
case AUDIO_NOISE_EFFECT: return new AudioNoiseEffect(c); break;
|
||||
case AUDIO_TONE_EFFECT: return new ToneEffect(c); break;
|
||||
}
|
||||
}
|
||||
dout << "[ERROR] Invalid effect ID";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -101,31 +118,167 @@ double double_lerp(double a, double b, double t) {
|
||||
return ((1.0 - t) * a) + (t * b);
|
||||
}
|
||||
|
||||
Effect::Effect(Clip* c, int t, int i) :
|
||||
Effect::Effect(Clip* c, const EffectMeta &em) :
|
||||
parent_clip(c),
|
||||
type(t),
|
||||
id(i),
|
||||
meta(em),
|
||||
enable_shader(false),
|
||||
enable_coords(false),
|
||||
enable_superimpose(false),
|
||||
iterations(1),
|
||||
enable_superimpose(false),
|
||||
isOpen(false),
|
||||
glslProgram(NULL),
|
||||
bound(false)
|
||||
{
|
||||
container = new CollapsibleWidget();
|
||||
if (type == EFFECT_TYPE_VIDEO) {
|
||||
container->setText(video_effect_names[i]);
|
||||
} else if (type == EFFECT_TYPE_AUDIO) {
|
||||
container->setText(audio_effect_names[i]);
|
||||
}
|
||||
// set up base UI
|
||||
container = new CollapsibleWidget();
|
||||
connect(container->enabled_check, SIGNAL(clicked(bool)), this, SLOT(field_changed()));
|
||||
ui = new QWidget();
|
||||
|
||||
ui_layout = new QGridLayout();
|
||||
ui_layout->setSpacing(4);
|
||||
ui->setLayout(ui_layout);
|
||||
container->setContents(ui);
|
||||
|
||||
// set up UI from effect file
|
||||
container->setText(em.name);
|
||||
QFile effect_file(get_effects_dir() + "/" + em.filename);
|
||||
|
||||
if (effect_file.open(QFile::ReadOnly)) {
|
||||
QXmlStreamReader reader(&effect_file);
|
||||
|
||||
while (!reader.atEnd()) {
|
||||
if (reader.name() == "row" && reader.isStartElement()) {
|
||||
QString row_name;
|
||||
const QXmlStreamAttributes& attributes = reader.attributes();
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "name") {
|
||||
row_name = attr.value().toString();
|
||||
}
|
||||
}
|
||||
if (!row_name.isEmpty()) {
|
||||
EffectRow* row = add_row(row_name);
|
||||
while (!reader.atEnd() && !(reader.name() == "row" && reader.isEndElement())) {
|
||||
reader.readNext();
|
||||
if (reader.name() == "field" && reader.isStartElement()) {
|
||||
int type = -1;
|
||||
|
||||
// get field type
|
||||
const QXmlStreamAttributes& attributes = reader.attributes();
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "type") {
|
||||
QString comp = attr.value().toString().toUpper();
|
||||
if (comp == "DOUBLE") {
|
||||
type = EFFECT_FIELD_DOUBLE;
|
||||
} else if (comp == "BOOL") {
|
||||
type = EFFECT_FIELD_BOOL;
|
||||
} else if (comp == "COLOR") {
|
||||
type = EFFECT_FIELD_COLOR;
|
||||
} else if (comp == "COMBO") {
|
||||
type = EFFECT_FIELD_COMBO;
|
||||
} else if (comp == "FONT") {
|
||||
type = EFFECT_FIELD_FONT;
|
||||
} else if (comp == "STRING") {
|
||||
type = EFFECT_FIELD_STRING;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << "add field" << type;
|
||||
if (type > -1) {
|
||||
EffectField* field = row->add_field(type);
|
||||
switch (type) {
|
||||
case EFFECT_FIELD_DOUBLE:
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "default") {
|
||||
field->set_double_default_value(attr.value().toDouble());
|
||||
} else if (attr.name() == "min") {
|
||||
field->set_double_minimum_value(attr.value().toDouble());
|
||||
} else if (attr.name() == "max") {
|
||||
field->set_double_maximum_value(attr.value().toDouble());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EFFECT_FIELD_COLOR:
|
||||
{
|
||||
QColor color;
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "r") {
|
||||
color.setRed(attr.value().toInt());
|
||||
} else if (attr.name() == "g") {
|
||||
color.setGreen(attr.value().toInt());
|
||||
} else if (attr.name() == "b") {
|
||||
color.setBlue(attr.value().toInt());
|
||||
} else if (attr.name() == "rf") {
|
||||
color.setRedF(attr.value().toFloat());
|
||||
} else if (attr.name() == "gf") {
|
||||
color.setGreenF(attr.value().toFloat());
|
||||
} else if (attr.name() == "bf") {
|
||||
color.setBlueF(attr.value().toFloat());
|
||||
} else if (attr.name() == "hex") {
|
||||
color.setNamedColor(attr.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EFFECT_FIELD_STRING:
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "default") {
|
||||
field->set_string_value(attr.value().toString());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EFFECT_FIELD_BOOL:
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "default") {
|
||||
field->set_bool_value(attr.value() == "1");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EFFECT_FIELD_COMBO:
|
||||
{
|
||||
int combo_index = 0;
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "default") {
|
||||
combo_index = attr.value().toInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (!reader.atEnd() && !(reader.name() == "field" && reader.isEndElement())) {
|
||||
reader.readNext();
|
||||
if (reader.name() == "option" && reader.isStartElement()) {
|
||||
reader.readNext();
|
||||
field->add_combo_item(reader.text().toString(), 0);
|
||||
}
|
||||
}
|
||||
field->set_combo_index(combo_index);
|
||||
}
|
||||
break;
|
||||
case EFFECT_FIELD_FONT:
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "default") {
|
||||
field->set_font_name(attr.value().toString());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
reader.readNext();
|
||||
}
|
||||
|
||||
effect_file.close();
|
||||
} else {
|
||||
dout << "[ERROR] Failed to open effect file" << em.filename;
|
||||
}
|
||||
}
|
||||
|
||||
Effect::~Effect() {
|
||||
@@ -351,14 +504,6 @@ void Effect::endEffect() {
|
||||
bound = false;
|
||||
}
|
||||
|
||||
int Effect::getIterations() {
|
||||
return iterations;
|
||||
}
|
||||
|
||||
void Effect::setIterations(int i) {
|
||||
iterations = qMax(i, 1);
|
||||
}
|
||||
|
||||
Effect* Effect::copy(Clip* c) {
|
||||
Effect* copy = create_effect(id, c);
|
||||
copy->set_enabled(is_enabled());
|
||||
@@ -371,7 +516,7 @@ void Effect::process_coords(double, GLTextureCoords&) {}
|
||||
GLuint Effect::process_superimpose(double) {return 0;}
|
||||
void Effect::process_audio(double, double, quint8*, int, int) {}
|
||||
|
||||
SuperimposeEffect::SuperimposeEffect(Clip* c, int t, int i) : Effect(c, t, i), texture(NULL) {
|
||||
SuperimposeEffect::SuperimposeEffect(Clip* c, const EffectMeta& e) : Effect(c, e), texture(NULL) {
|
||||
enable_superimpose = true;
|
||||
}
|
||||
|
||||
|
||||
+15
-7
@@ -46,8 +46,17 @@ enum AudioEffects {
|
||||
AUDIO_EFFECT_COUNT
|
||||
};
|
||||
|
||||
extern QVector<QString> video_effect_names;
|
||||
extern QVector<QString> audio_effect_names;
|
||||
struct EffectMeta {
|
||||
QString name;
|
||||
QString category;
|
||||
QString filename;
|
||||
};
|
||||
|
||||
extern QVector<EffectMeta> video_effects;
|
||||
extern QVector<EffectMeta> audio_effects;
|
||||
|
||||
extern QVector<QString> video_effect_names; // deprecated
|
||||
extern QVector<QString> audio_effect_names; // deprecated
|
||||
void init_effects();
|
||||
Effect* create_effect(int effect_id, Clip* c);
|
||||
|
||||
@@ -184,10 +193,10 @@ private:
|
||||
class Effect : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Effect(Clip* c, int t, int i);
|
||||
Effect(Clip* c, const EffectMeta& em);
|
||||
~Effect();
|
||||
Clip* parent_clip;
|
||||
int type;
|
||||
const EffectMeta& meta;
|
||||
int id;
|
||||
QString name;
|
||||
CollapsibleWidget* container;
|
||||
@@ -236,14 +245,13 @@ protected:
|
||||
private:
|
||||
QVector<EffectRow*> rows;
|
||||
QGridLayout* ui_layout;
|
||||
QWidget* ui;
|
||||
int iterations;
|
||||
QWidget* ui;
|
||||
bool bound;
|
||||
};
|
||||
|
||||
class SuperimposeEffect : public Effect {
|
||||
public:
|
||||
SuperimposeEffect(Clip* c, int t, int i);
|
||||
SuperimposeEffect(Clip* c, const EffectMeta& e);
|
||||
virtual void open();
|
||||
virtual void close();
|
||||
virtual GLuint process_superimpose(double timecode);
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <QString>
|
||||
|
||||
#define SAVE_VERSION "180820" // YYMMDD
|
||||
#define SAVE_VERSION "181030" // YYMMDD
|
||||
|
||||
#define TIMECODE_DROP 0
|
||||
#define TIMECODE_NONDROP 1
|
||||
|
||||
+3
-1
@@ -10,7 +10,9 @@ extern "C" {
|
||||
|
||||
#include "project/clip.h"
|
||||
|
||||
Media::Media() : ready(false), preview_gen(NULL) {}
|
||||
Media::Media() : ready(false), preview_gen(NULL) {
|
||||
ready_lock.lock();
|
||||
}
|
||||
|
||||
Media::~Media() {
|
||||
reset();
|
||||
|
||||
@@ -53,6 +53,7 @@ struct Media {
|
||||
bool ready;
|
||||
|
||||
PreviewGenerator* preview_gen;
|
||||
QMutex ready_lock;
|
||||
|
||||
bool using_inout;
|
||||
long in;
|
||||
|
||||
+15
-3
@@ -4,10 +4,22 @@
|
||||
#include <QFileInfo>
|
||||
#include <QCoreApplication>
|
||||
|
||||
QString get_data_path() {
|
||||
QString app_path = QCoreApplication::applicationFilePath();
|
||||
QString app_dir = app_path.left(app_path.lastIndexOf('/'));
|
||||
QString real_app_dir;
|
||||
|
||||
QString get_effects_dir() {
|
||||
return get_app_dir() + "/effects";
|
||||
}
|
||||
|
||||
QString get_app_dir() {
|
||||
if (real_app_dir.isEmpty()) {
|
||||
QString app_path = QCoreApplication::applicationFilePath();
|
||||
real_app_dir = app_path.left(app_path.lastIndexOf('/'));
|
||||
}
|
||||
return real_app_dir;
|
||||
}
|
||||
|
||||
QString get_data_path() {
|
||||
QString app_dir = get_app_dir();
|
||||
if (QFileInfo::exists(app_dir + "/portable")) {
|
||||
return app_dir;
|
||||
} else {
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#include <QString>
|
||||
|
||||
QString get_app_dir();
|
||||
QString get_data_path();
|
||||
QString get_effects_dir();
|
||||
|
||||
#endif // PATH_H
|
||||
|
||||
@@ -168,6 +168,7 @@ bool PreviewGenerator::retrieve_preview(const QString& hash) {
|
||||
}
|
||||
|
||||
void PreviewGenerator::finalize_media() {
|
||||
media->ready_lock.unlock();
|
||||
media->ready = true;
|
||||
|
||||
if (media->video_tracks.size() == 0) {
|
||||
|
||||
@@ -128,6 +128,8 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
qint64 a_month_ago = QDateTime::currentMSecsSinceEpoch() - 2592000000;
|
||||
qint64 a_week_ago = QDateTime::currentMSecsSinceEpoch() - 604800000;
|
||||
|
||||
// TODO put delete functions in another thread?
|
||||
|
||||
// delete auto-recoveries older than 7 days
|
||||
QStringList old_autorecoveries = dir.entryList(QStringList("autorecovery.ove.*"), QDir::Files);
|
||||
int deleted_ars = 0;
|
||||
|
||||
@@ -63,28 +63,12 @@ SOURCES += \
|
||||
ui/fontcombobox.cpp \
|
||||
ui/checkboxex.cpp \
|
||||
effects/effect.cpp \
|
||||
effects/video/transformeffect.cpp \
|
||||
effects/audio/volumeeffect.cpp \
|
||||
effects/audio/paneffect.cpp \
|
||||
effects/video/texteffect.cpp \
|
||||
effects/video/solideffect.cpp \
|
||||
effects/video/shakeeffect.cpp \
|
||||
effects/video/inverteffect.cpp \
|
||||
ui/keyframeview.cpp \
|
||||
ui/texteditex.cpp \
|
||||
effects/video/chromakeyeffect.cpp \
|
||||
effects/video/gaussianblureffect.cpp \
|
||||
effects/video/cropeffect.cpp \
|
||||
effects/video/flipeffect.cpp \
|
||||
effects/audio/audionoiseeffect.cpp \
|
||||
effects/video/boxblureffect.cpp \
|
||||
dialogs/demonotice.cpp \
|
||||
effects/audio/toneeffect.cpp \
|
||||
project/marker.cpp \
|
||||
dialogs/speeddialog.cpp \
|
||||
dialogs/mediapropertiesdialog.cpp \
|
||||
effects/video/waveeffect.cpp \
|
||||
effects/video/temperatureeffect.cpp \
|
||||
io/crc32.cpp \
|
||||
dialogs/loaddialog.cpp \
|
||||
debug.cpp \
|
||||
@@ -128,30 +112,14 @@ HEADERS += \
|
||||
ui/fontcombobox.h \
|
||||
ui/checkboxex.h \
|
||||
effects/effect.h \
|
||||
effects/video/transformeffect.h \
|
||||
effects/video/solideffect.h \
|
||||
effects/video/shakeeffect.h \
|
||||
effects/video/texteffect.h \
|
||||
effects/video/inverteffect.h \
|
||||
effects/audio/volumeeffect.h \
|
||||
effects/audio/paneffect.h \
|
||||
ui/keyframeview.h \
|
||||
ui/texteditex.h \
|
||||
effects/video/chromakeyeffect.h \
|
||||
effects/video/gaussianblureffect.h \
|
||||
effects/video/cropeffect.h \
|
||||
effects/video/flipeffect.h \
|
||||
effects/audio/audionoiseeffect.h \
|
||||
effects/video/boxblureffect.h \
|
||||
dialogs/demonotice.h \
|
||||
effects/audio/toneeffect.h \
|
||||
project/marker.h \
|
||||
project/selection.h \
|
||||
dialogs/speeddialog.h \
|
||||
dialogs/speeddialog.h \
|
||||
dialogs/mediapropertiesdialog.h \
|
||||
effects/video/waveeffect.h \
|
||||
effects/video/temperatureeffect.h \
|
||||
io/crc32.h \
|
||||
dialogs/loaddialog.h \
|
||||
debug.h \
|
||||
|
||||
@@ -74,7 +74,7 @@ void EffectControls::menu_select(QAction* q) {
|
||||
ca->append(new AddTransitionCommand(c, q->data().toInt(), TA_CLOSING_TRANSITION));
|
||||
}
|
||||
} else {
|
||||
ca->append(new AddEffectCommand(c, q->data().toInt()));
|
||||
ca->append(new AddEffectCommand(c, reinterpret_cast<EffectMeta*>(q->data().value<quintptr>())));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,7 @@ void EffectControls::menu_select(QAction* q) {
|
||||
} else {
|
||||
reload_clips();
|
||||
panel_sequence_viewer->viewer_widget->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EffectControls::update_keyframes() {
|
||||
@@ -97,7 +97,7 @@ void EffectControls::delete_selected_keyframes() {
|
||||
}
|
||||
|
||||
void EffectControls::show_effect_menu(bool video, bool transitions) {
|
||||
video_menu = video;
|
||||
/*video_menu = video;
|
||||
transition_menu = transitions;
|
||||
|
||||
int lim;
|
||||
@@ -142,6 +142,48 @@ void EffectControls::show_effect_menu(bool video, bool transitions) {
|
||||
|
||||
connect(&effects_menu, SIGNAL(triggered(QAction*)), this, SLOT(menu_select(QAction*)));
|
||||
|
||||
effects_menu.exec(QCursor::pos());*/
|
||||
video_menu = video;
|
||||
transition_menu = transitions;
|
||||
|
||||
QVector<EffectMeta>& effect_list = (video) ? video_effects : audio_effects;
|
||||
QMenu effects_menu(this);
|
||||
for (int i=0;i<effect_list.size();i++) {
|
||||
const EffectMeta& em = effect_list.at(i);
|
||||
QAction* action = new QAction(&effects_menu);
|
||||
action->setText(em.name);
|
||||
action->setData(reinterpret_cast<quintptr>(&em));
|
||||
|
||||
// TODO alphabetical ordering
|
||||
QMenu* parent = &effects_menu;
|
||||
if (!em.category.isEmpty()) {
|
||||
bool found = false;
|
||||
for (int j=0;j<effects_menu.actions().size();j++) {
|
||||
QAction* action = effects_menu.actions().at(j);
|
||||
if (action->menu() != NULL) {
|
||||
if (action->menu()->title() == em.category) {
|
||||
parent = action->menu();
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
parent = new QMenu(&effects_menu);
|
||||
parent->setTitle(em.category);
|
||||
effects_menu.addMenu(parent);
|
||||
}
|
||||
}
|
||||
|
||||
parent->addAction(action);
|
||||
}
|
||||
|
||||
QMenu test_menu(this);
|
||||
test_menu.setTitle("HEY NOW");
|
||||
test_menu.addAction("YOU'RE AN ALL STAR");
|
||||
effects_menu.addMenu(&test_menu);
|
||||
|
||||
connect(&effects_menu, SIGNAL(triggered(QAction*)), this, SLOT(menu_select(QAction*)));
|
||||
effects_menu.exec(QCursor::pos());
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -56,8 +56,7 @@ Project::Project(QWidget *parent) :
|
||||
connect(ui->treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(rename_media(QTreeWidgetItem*,int)));
|
||||
}
|
||||
|
||||
Project::~Project()
|
||||
{
|
||||
Project::~Project() {
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -193,9 +193,9 @@ void SetTimelineInOutCommand::redo() {
|
||||
mainWindow->setWindowModified(true);
|
||||
}
|
||||
|
||||
AddEffectCommand::AddEffectCommand(Clip* c, int ieffect) :
|
||||
AddEffectCommand::AddEffectCommand(Clip* c, EffectMeta *e) :
|
||||
clip(c),
|
||||
effect(ieffect),
|
||||
meta(e),
|
||||
ref(NULL),
|
||||
done(false),
|
||||
old_project_changed(mainWindow->isWindowModified())
|
||||
@@ -213,7 +213,7 @@ void AddEffectCommand::undo() {
|
||||
|
||||
void AddEffectCommand::redo() {
|
||||
if (ref == NULL) {
|
||||
ref = create_effect(effect, clip);
|
||||
ref = new Effect(clip, *meta);
|
||||
}
|
||||
clip->effects.append(ref);
|
||||
done = true;
|
||||
|
||||
+3
-2
@@ -12,6 +12,7 @@ class Transition;
|
||||
struct Clip;
|
||||
struct Sequence;
|
||||
struct Media;
|
||||
struct EffectMeta;
|
||||
|
||||
#include "project/marker.h"
|
||||
#include "project/selection.h"
|
||||
@@ -90,13 +91,13 @@ private:
|
||||
|
||||
class AddEffectCommand : public QUndoCommand {
|
||||
public:
|
||||
AddEffectCommand(Clip* c, int ieffect);
|
||||
AddEffectCommand(Clip* c, EffectMeta* e);
|
||||
~AddEffectCommand();
|
||||
void undo();
|
||||
void redo();
|
||||
private:
|
||||
Clip* clip;
|
||||
int effect;
|
||||
EffectMeta* meta;
|
||||
Effect* ref;
|
||||
bool done;
|
||||
bool old_project_changed;
|
||||
|
||||
@@ -623,14 +623,14 @@ void TimelineWidget::dropEvent(QDropEvent* event) {
|
||||
}
|
||||
}
|
||||
|
||||
if (c->track < 0) {
|
||||
/*if (c->track < 0) {
|
||||
// add default video effects
|
||||
c->effects.append(create_effect(VIDEO_TRANSFORM_EFFECT, c));
|
||||
} else {
|
||||
// add default audio effects
|
||||
c->effects.append(create_effect(AUDIO_VOLUME_EFFECT, c));
|
||||
c->effects.append(create_effect(AUDIO_PAN_EFFECT, c));
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
panel_timeline->ghosts.clear();
|
||||
|
||||
+9
-9
@@ -365,15 +365,15 @@ GLuint ViewerWidget::compose_sequence(Clip* nest, bool render_audio) {
|
||||
}
|
||||
if (e->enable_shader || e->enable_superimpose) {
|
||||
e->startEffect();
|
||||
for (int k=0;k<e->getIterations();k++) {
|
||||
e->process_shader(timecode);
|
||||
composite_texture = draw_clip(c->fbo[fbo_switcher], composite_texture);
|
||||
if (e->enable_superimpose) {
|
||||
GLuint superimpose_texture = e->process_superimpose(timecode);
|
||||
if (superimpose_texture != 0) draw_clip(c->fbo[fbo_switcher], superimpose_texture);
|
||||
}
|
||||
fbo_switcher = !fbo_switcher;
|
||||
}
|
||||
//for (int k=0;k<e->getIterations();k++) {
|
||||
e->process_shader(timecode);
|
||||
composite_texture = draw_clip(c->fbo[fbo_switcher], composite_texture);
|
||||
if (e->enable_superimpose) {
|
||||
GLuint superimpose_texture = e->process_superimpose(timecode);
|
||||
if (superimpose_texture != 0) draw_clip(c->fbo[fbo_switcher], superimpose_texture);
|
||||
}
|
||||
fbo_switcher = !fbo_switcher;
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user