basic titling function added #84

This commit is contained in:
itsmattkc
2018-07-20 00:47:05 +01:00
parent a14c24ad27
commit 590644ec1b
7 changed files with 195 additions and 3 deletions
+2
View File
@@ -14,6 +14,7 @@ void init_effects() {
video_effect_names[VIDEO_TRANSFORM_EFFECT] = "Transform";
video_effect_names[VIDEO_SHAKE_EFFECT] = "Shake";
video_effect_names[VIDEO_TEXT_EFFECT] = "Text";
audio_effect_names[AUDIO_VOLUME_EFFECT] = "Volume";
audio_effect_names[AUDIO_PAN_EFFECT] = "Pan";
@@ -24,6 +25,7 @@ Effect* create_effect(int effect_id, Clip* c) {
switch (effect_id) {
case VIDEO_TRANSFORM_EFFECT: return new TransformEffect(c);
case VIDEO_SHAKE_EFFECT: return new ShakeEffect(c);
case VIDEO_TEXT_EFFECT: return new TextEffect(c);
}
} else {
switch (effect_id) {
+29 -1
View File
@@ -3,16 +3,22 @@
#include "project/effect.h"
#include <QPixmap>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
class QSpinBox;
class QCheckBox;
class QComboBox;
class LabelSlider;
class QOpenGLTexture;
class QTextEdit;
class QPushButton;
enum VideoEffects {
VIDEO_TRANSFORM_EFFECT,
VIDEO_SHAKE_EFFECT,
VIDEO_EFFECT_COUNT
VIDEO_TEXT_EFFECT,
VIDEO_EFFECT_COUNT
};
enum AudioEffects {
@@ -82,6 +88,28 @@ private:
double t;
};
class TextEffect : public Effect {
Q_OBJECT
public:
TextEffect(Clip* c);
~TextEffect();
void post_gl();
Effect* copy(Clip* c);
void load(QXmlStreamReader* stream);
void save(QXmlStreamWriter* stream);
QTextEdit* text_val;
LabelSlider* size_val;
QPushButton* set_color_button;
QColor color;
private slots:
void set_color();
void update_texture();
private:
void set_button_color();
QPixmap pixmap;
QOpenGLTexture* texture;
};
// audio effects
class VolumeEffect : public Effect {
public:
+151
View File
@@ -0,0 +1,151 @@
#include "effects.h"
#include <QGridLayout>
#include <QLabel>
#include <QOpenGLTexture>
#include <QTextEdit>
#include <QPainter>
#include <QPushButton>
#include <QColorDialog>
#include <QDebug>
#include "ui/labelslider.h"
#include "ui/collapsiblewidget.h"
#include "project/clip.h"
#include "project/sequence.h"
TextEffect::TextEffect(Clip *c) : Effect(c), texture(NULL) {
setup_effect(EFFECT_TYPE_VIDEO, VIDEO_TEXT_EFFECT);
QGridLayout* ui_layout = new QGridLayout();
ui_layout->addWidget(new QLabel("Text:"), 0, 0);
text_val = new QTextEdit();
ui_layout->addWidget(text_val, 0, 1);
ui_layout->addWidget(new QLabel("Size:"), 1, 0);
size_val = new LabelSlider();
size_val->set_minimum_value(0);
ui_layout->addWidget(size_val, 1, 1);
ui_layout->addWidget(new QLabel("Color:"), 2, 0);
set_color_button = new QPushButton();
ui_layout->addWidget(set_color_button, 2, 1);
ui->setLayout(ui_layout);
container->setContents(ui);
color = Qt::white;
set_button_color();
connect(text_val, SIGNAL(textChanged()), this, SLOT(update_texture()));
connect(size_val, SIGNAL(valueChanged()), this, SLOT(update_texture()));
connect(set_color_button, SIGNAL(clicked(bool)), this, SLOT(set_color()));
size_val->set_value(24);
text_val->setText("Sample Text");
}
TextEffect::~TextEffect() {
texture->destroy();
delete texture;
}
void TextEffect::set_button_color() {
QPalette pal = set_color_button->palette();
pal.setColor(QPalette::Button, color);
set_color_button->setPalette(pal);
}
void TextEffect::set_color() {
color = QColorDialog::getColor(color, NULL);
set_button_color();
update_texture();
}
void TextEffect::update_texture() {
pixmap = QPixmap(parent_clip->sequence->width, parent_clip->sequence->height);
pixmap.fill(Qt::transparent);
QPainter p(&pixmap);
p.setRenderHint(QPainter::TextAntialiasing, true);
// set font
QFont font = p.font();
font.setPointSize(size_val->value());
p.setFont(font);
p.setPen(color);
p.drawText(QRect(0, 0, pixmap.width(), pixmap.height()), Qt::AlignCenter | Qt::TextWordWrap, text_val->toPlainText());
if (texture == NULL) {
texture = new QOpenGLTexture(pixmap.toImage());
} else {
texture->destroy();
texture->setData(pixmap.toImage());
}
// queue a repaint of the canvas
field_changed();
}
void TextEffect::post_gl() {
if (texture != NULL) {
texture->bind();
int half_width = pixmap.width()/2;
int half_height = pixmap.height()/2;
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex2f(-half_width, -half_height);
glTexCoord2f(1.0, 0.0);
glVertex2f(half_width, -half_height);
glTexCoord2f(1.0, 1.0);
glVertex2f(half_width, half_height);
glTexCoord2f(0.0, 1.0);
glVertex2f(-half_width, half_height);
glEnd();
texture->release();
}
}
Effect* TextEffect::copy(Clip* c) {
TextEffect* e = new TextEffect(c);
e->text_val->setPlainText(text_val->toPlainText());
e->size_val->set_value(size_val->value());
e->color = color;
return e;
}
void TextEffect::load(QXmlStreamReader* stream) {
const QXmlStreamAttributes& attr = stream->attributes();
for (int i=0;i<attr.size();i++) {
const QXmlStreamAttribute& a = attr.at(i);
if (a.name() == "size") {
size_val->set_value(a.value().toDouble());
} else if (a.name() == "r") {
color.setRed(a.value().toInt());
} else if (a.name() == "g") {
color.setGreen(a.value().toInt());
} else if (a.name() == "b") {
color.setBlue(a.value().toInt());
}
}
while (!(stream->name() == "effect" && stream->isEndElement())) {
stream->readNext();
if (stream->name() == "text" && stream->isStartElement()) {
text_val->setPlainText(stream->text().toString());
}
}
}
void TextEffect::save(QXmlStreamWriter* stream) {
stream->writeAttribute("size", QString::number(size_val->value()));
stream->writeAttribute("r", QString::number(color.red()));
stream->writeAttribute("g", QString::number(color.green()));
stream->writeAttribute("b", QString::number(color.blue()));
stream->writeTextElement("text", text_val->toPlainText());
}
+2 -1
View File
@@ -61,7 +61,8 @@ SOURCES += \
ui/audiomonitor.cpp \
project/undo.cpp \
ui/scrollarea.cpp \
effects/shakeeffect.cpp
effects/shakeeffect.cpp \
effects/texteffect.cpp
HEADERS += \
mainwindow.h \
+1
View File
@@ -36,4 +36,5 @@ Effect* Effect::copy(Clip*) {return NULL;}
void Effect::load(QXmlStreamReader*) {}
void Effect::save(QXmlStreamWriter*) {}
void Effect::process_gl(int*, int*) {}
void Effect::post_gl() {}
void Effect::process_audio(uint8_t*, int) {}
+1
View File
@@ -32,6 +32,7 @@ public:
virtual void save(QXmlStreamWriter* stream);
virtual void process_gl(int* anchor_x, int* anchor_y);
virtual void post_gl();
virtual void process_audio(quint8* samples, int nb_bytes);
public slots:
+9 -1
View File
@@ -116,8 +116,8 @@ void ViewerWidget::paintGL() {
} else if (panel_timeline->playhead >= c->timeline_in) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(1.0, 1.0, 1.0, 1.0);
glLoadIdentity();
int half_width = c->sequence->width/2;
int half_height = c->sequence->height/2;
if (flip) {
@@ -151,6 +151,9 @@ void ViewerWidget::paintGL() {
c->texture->bind();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex2f(-anchor_x, -anchor_y);
@@ -163,6 +166,11 @@ void ViewerWidget::paintGL() {
glEnd();
c->texture->release();
// perform all transform effects
for (int j=0;j<c->effects.size();j++) {
c->effects.at(j)->post_gl();
}
}
} else if (render_audio &&
c->stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&