basic save support added
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "project/effect.h"
|
||||
|
||||
#include <QXmlStreamWriter>
|
||||
class QSpinBox;
|
||||
class QCheckBox;
|
||||
|
||||
@@ -52,6 +53,7 @@ public:
|
||||
VolumeEffect(Clip* c);
|
||||
void process_audio(uint8_t* samples, int nb_bytes);
|
||||
Effect* copy();
|
||||
void save(QXmlStreamWriter* stream);
|
||||
|
||||
QSpinBox* volume_val;
|
||||
};
|
||||
@@ -61,6 +63,7 @@ public:
|
||||
PanEffect(Clip* c);
|
||||
void process_audio(uint8_t* samples, int nb_bytes);
|
||||
Effect* copy();
|
||||
void save(QXmlStreamWriter* stream);
|
||||
|
||||
QSpinBox* pan_val;
|
||||
};
|
||||
|
||||
@@ -7,12 +7,9 @@
|
||||
#include "ui/collapsiblewidget.h"
|
||||
|
||||
PanEffect::PanEffect(Clip* c) : Effect(c) {
|
||||
container = new CollapsibleWidget();
|
||||
container->setText(audio_effect_names[AUDIO_PAN_EFFECT]);
|
||||
setup_effect(EFFECT_TYPE_AUDIO, AUDIO_PAN_EFFECT);
|
||||
|
||||
ui = new QWidget();
|
||||
|
||||
QGridLayout* ui_layout = new QGridLayout();
|
||||
QGridLayout* ui_layout = new QGridLayout();
|
||||
|
||||
ui_layout->addWidget(new QLabel("Pan:"), 0, 0);
|
||||
pan_val = new QSpinBox();
|
||||
@@ -34,6 +31,10 @@ Effect* PanEffect::copy() {
|
||||
return p;
|
||||
}
|
||||
|
||||
void PanEffect::save(QXmlStreamWriter *stream) {
|
||||
stream->writeTextElement("pan", QString::number(pan_val->value()));
|
||||
}
|
||||
|
||||
void PanEffect::process_audio(uint8_t *samples, int nb_bytes) {
|
||||
for (int i=0;i<nb_bytes;i+=4) {
|
||||
int16_t left_sample = (int16_t) ((samples[i+1] << 8) | samples[i]);
|
||||
|
||||
@@ -14,10 +14,7 @@
|
||||
#include "io/media.h"
|
||||
|
||||
TransformEffect::TransformEffect(Clip* c) : Effect(c) {
|
||||
container = new CollapsibleWidget();
|
||||
container->setText(video_effect_names[VIDEO_TRANSFORM_EFFECT]);
|
||||
|
||||
ui = new QWidget();
|
||||
setup_effect(EFFECT_TYPE_VIDEO, VIDEO_TRANSFORM_EFFECT);
|
||||
|
||||
QGridLayout* ui_layout = new QGridLayout();
|
||||
|
||||
|
||||
@@ -7,10 +7,7 @@
|
||||
#include "ui/collapsiblewidget.h"
|
||||
|
||||
VolumeEffect::VolumeEffect(Clip* c) : Effect(c) {
|
||||
container = new CollapsibleWidget();
|
||||
container->setText(audio_effect_names[AUDIO_VOLUME_EFFECT]);
|
||||
|
||||
ui = new QWidget();
|
||||
setup_effect(EFFECT_TYPE_AUDIO, AUDIO_VOLUME_EFFECT);
|
||||
|
||||
QGridLayout* ui_layout = new QGridLayout();
|
||||
|
||||
@@ -34,6 +31,10 @@ Effect* VolumeEffect::copy() {
|
||||
return v;
|
||||
}
|
||||
|
||||
void VolumeEffect::save(QXmlStreamWriter *stream) {
|
||||
stream->writeTextElement("volume", QString::number(volume_val->value()));
|
||||
}
|
||||
|
||||
void VolumeEffect::process_audio(uint8_t *samples, int nb_bytes) {
|
||||
for (int i=0;i<nb_bytes;i+=2) {
|
||||
int16_t full_sample = (int16_t) ((samples[i+1] << 8) | samples[i]);
|
||||
|
||||
@@ -24,6 +24,7 @@ struct Media
|
||||
QVector<MediaStream> video_tracks;
|
||||
QVector<MediaStream> audio_tracks;
|
||||
Sequence* sequence;
|
||||
int save_id;
|
||||
long get_length_in_frames(float frame_rate);
|
||||
};
|
||||
|
||||
|
||||
@@ -203,3 +203,8 @@ void MainWindow::on_action_Paste_triggered()
|
||||
panel_timeline->paste();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_action_Save_Project_triggered()
|
||||
{
|
||||
panel_project->save_project();
|
||||
}
|
||||
|
||||
@@ -63,6 +63,8 @@ private slots:
|
||||
|
||||
void on_action_Paste_triggered();
|
||||
|
||||
void on_action_Save_Project_triggered();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
void setup_layout();
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 4.6.1, 2018-06-08T22:09:27. -->
|
||||
<!-- Written by QtCreator 4.6.1, 2018-06-10T00:00:44. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
|
||||
+136
-2
@@ -2,15 +2,22 @@
|
||||
#include "ui_project.h"
|
||||
#include "io/media.h"
|
||||
|
||||
#include "panels/panels.h"
|
||||
#include "panels/timeline.h"
|
||||
#include "panels/viewer.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
#include <QDebug>
|
||||
#include <QCharRef>
|
||||
#include <QMessageBox>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QXmlStreamWriter>
|
||||
|
||||
#include "panels/timeline.h"
|
||||
#include "project/sequence.h"
|
||||
#include "project/effect.h"
|
||||
|
||||
extern "C" {
|
||||
#include <libavformat/avformat.h>
|
||||
@@ -58,7 +65,7 @@ void Project::new_sequence(Sequence *s) {
|
||||
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem();
|
||||
item->setText(0, s->name);
|
||||
item->setData(0, Qt::UserRole + 1, QVariant::fromValue(reinterpret_cast<quintptr>(m)));
|
||||
set_media_of_tree(item, m);
|
||||
|
||||
ui->treeWidget->addTopLevelItem(item);
|
||||
source_table = ui->treeWidget;
|
||||
@@ -153,7 +160,7 @@ void Project::import_dialog() {
|
||||
}
|
||||
item->setText(0, m->name);
|
||||
item->setText(1, QString::number(m->length));
|
||||
item->setData(0, Qt::UserRole + 1, QVariant::fromValue(reinterpret_cast<quintptr>(m)));
|
||||
set_media_of_tree(item, m);
|
||||
|
||||
ui->treeWidget->addTopLevelItem(item);
|
||||
}
|
||||
@@ -162,3 +169,130 @@ void Project::import_dialog() {
|
||||
delete [] filename;
|
||||
}
|
||||
}
|
||||
|
||||
Media* Project::get_media_from_tree(QTreeWidgetItem* item) {
|
||||
return reinterpret_cast<Media*>(item->data(0, Qt::UserRole + 1).value<quintptr>());
|
||||
}
|
||||
|
||||
void Project::set_media_of_tree(QTreeWidgetItem* item, Media* media) {
|
||||
item->setData(0, Qt::UserRole + 1, QVariant::fromValue(reinterpret_cast<quintptr>(media)));
|
||||
}
|
||||
|
||||
void Project::remove_item(int i) {
|
||||
Media* m = get_media_from_tree(ui->treeWidget->topLevelItem(i));
|
||||
if (m->is_sequence) {
|
||||
delete m->sequence;
|
||||
}
|
||||
delete m;
|
||||
ui->treeWidget->takeTopLevelItem(i);
|
||||
}
|
||||
|
||||
void Project::clear() {
|
||||
int len = ui->treeWidget->topLevelItemCount();
|
||||
for (int i=0;i<len;i++) {
|
||||
remove_item(i);
|
||||
}
|
||||
}
|
||||
|
||||
void Project::set_sequence(Sequence* s) {
|
||||
panel_timeline->set_sequence(s);
|
||||
panel_viewer->set_sequence(s);
|
||||
}
|
||||
|
||||
void Project::load_project() {
|
||||
// clear existing project
|
||||
set_sequence(NULL);
|
||||
clear();
|
||||
|
||||
QFile file("C:/Users/Matt/Desktop/test.xml");
|
||||
if (!file.open(QIODevice::ReadOnly/* | QIODevice::Text*/)) {
|
||||
qDebug() << "[ERROR] Could not open file";
|
||||
return;
|
||||
}
|
||||
|
||||
QXmlStreamReader stream(&file);
|
||||
|
||||
while (!stream.atEnd()) {
|
||||
stream.readNext();
|
||||
|
||||
}
|
||||
if (stream.hasError()) {
|
||||
qDebug() << "[ERROR] Error parsing XML." << stream.error();
|
||||
}
|
||||
}
|
||||
|
||||
void Project::save_project() {
|
||||
QFile file("C:/Users/Matt/Desktop/test.xml");
|
||||
if (!file.open(QIODevice::WriteOnly/* | QIODevice::Text*/)) {
|
||||
qDebug() << "[ERROR] Could not open file";
|
||||
return;
|
||||
}
|
||||
|
||||
QXmlStreamWriter stream(&file);
|
||||
stream.setAutoFormatting(true);
|
||||
stream.writeStartDocument();
|
||||
|
||||
int len = ui->treeWidget->topLevelItemCount();
|
||||
stream.writeStartElement("media");
|
||||
for (int i=0;i<len;i++) {
|
||||
Media* m = get_media_from_tree(ui->treeWidget->topLevelItem(i));
|
||||
if (!m->is_sequence) {
|
||||
m->save_id = i;
|
||||
stream.writeStartElement("footage");
|
||||
stream.writeAttribute("id", QString::number(m->save_id));
|
||||
stream.writeTextElement("name", m->name);
|
||||
stream.writeTextElement("url", m->url);
|
||||
stream.writeEndElement();
|
||||
}
|
||||
}
|
||||
stream.writeEndElement();
|
||||
|
||||
stream.writeStartElement("timeline");
|
||||
for (int i=0;i<len;i++) {
|
||||
Media* m = get_media_from_tree(ui->treeWidget->topLevelItem(i));
|
||||
if (m->is_sequence) {
|
||||
Sequence* s = m->sequence;
|
||||
stream.writeStartElement("sequence");
|
||||
stream.writeTextElement("name", s->name);
|
||||
stream.writeTextElement("width", QString::number(s->width));
|
||||
stream.writeTextElement("height", QString::number(s->height));
|
||||
stream.writeTextElement("framerate", QString::number(s->frame_rate));
|
||||
stream.writeTextElement("afreq", QString::number(s->audio_frequency));
|
||||
stream.writeTextElement("alayout", QString::number(s->audio_layout));
|
||||
stream.writeStartElement("clips");
|
||||
for (int i=0;i<s->clip_count();i++) {
|
||||
Clip* c = s->get_clip(i);
|
||||
|
||||
stream.writeStartElement("clip");
|
||||
stream.writeTextElement("name", c->name);
|
||||
stream.writeTextElement("clipin", QString::number(c->clip_in));
|
||||
stream.writeTextElement("in", QString::number(c->timeline_in));
|
||||
stream.writeTextElement("out", QString::number(c->timeline_out));
|
||||
stream.writeTextElement("track", QString::number(c->track));
|
||||
stream.writeStartElement("color");
|
||||
stream.writeAttribute("r", QString::number(c->color_r));
|
||||
stream.writeAttribute("g", QString::number(c->color_g));
|
||||
stream.writeAttribute("b", QString::number(c->color_b));
|
||||
stream.writeEndElement();
|
||||
stream.writeTextElement("media", QString::number(c->media->save_id));
|
||||
stream.writeTextElement("stream", QString::number(c->media_stream->file_index));
|
||||
stream.writeStartElement("effects");
|
||||
for (int j=0;j<c->effects.size();j++) {
|
||||
stream.writeStartElement("effect");
|
||||
Effect* e = c->effects.at(j);
|
||||
stream.writeAttribute("id", QString::number(e->id));
|
||||
e->save(&stream);
|
||||
stream.writeEndElement();
|
||||
}
|
||||
stream.writeEndElement();
|
||||
stream.writeEndElement();
|
||||
}
|
||||
stream.writeEndElement();
|
||||
}
|
||||
}
|
||||
stream.writeEndElement();
|
||||
|
||||
stream.writeEndDocument();
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ struct Sequence;
|
||||
class Timeline;
|
||||
class Viewer;
|
||||
class SourceTable;
|
||||
class QTreeWidgetItem;
|
||||
|
||||
namespace Ui {
|
||||
class Project;
|
||||
@@ -21,9 +22,18 @@ class Project : public QDockWidget
|
||||
public:
|
||||
explicit Project(QWidget *parent = 0);
|
||||
~Project();
|
||||
void clear();
|
||||
void import_dialog();
|
||||
void set_sequence(Sequence* s);
|
||||
void new_sequence(Sequence* s);
|
||||
QString get_next_sequence_name();
|
||||
void remove_item(int i);
|
||||
|
||||
void load_project();
|
||||
void save_project();
|
||||
|
||||
Media* get_media_from_tree(QTreeWidgetItem* item);
|
||||
void set_media_of_tree(QTreeWidgetItem* item, Media* media);
|
||||
|
||||
SourceTable* source_table;
|
||||
|
||||
|
||||
+16
-6
@@ -3,6 +3,8 @@
|
||||
#include "panels/panels.h"
|
||||
#include "panels/viewer.h"
|
||||
#include "ui/viewerwidget.h"
|
||||
#include "ui/collapsiblewidget.h"
|
||||
#include "effects/effects.h"
|
||||
|
||||
Effect::Effect(Clip* c) : parent_clip(c)
|
||||
{
|
||||
@@ -10,16 +12,24 @@ Effect::Effect(Clip* c) : parent_clip(c)
|
||||
type = EFFECT_TYPE_INVALID;
|
||||
}
|
||||
|
||||
void Effect::setup_effect(int t, int i) {
|
||||
type = t;
|
||||
id = i;
|
||||
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]);
|
||||
}
|
||||
ui = new QWidget();
|
||||
}
|
||||
|
||||
void Effect::field_changed() {
|
||||
panel_viewer->viewer_widget->update();
|
||||
}
|
||||
|
||||
Effect* Effect::copy() {
|
||||
Effect* e = new Effect(parent_clip);
|
||||
name = e->name;
|
||||
type = e->type;
|
||||
return e;
|
||||
}
|
||||
Effect* Effect::copy() {return NULL;}
|
||||
void Effect::save(QXmlStreamWriter *stream) {}
|
||||
|
||||
void Effect::process_gl(int*, int*) {}
|
||||
void Effect::process_audio(uint8_t*, int) {}
|
||||
|
||||
@@ -7,6 +7,7 @@ class QWidget;
|
||||
class CollapsibleWidget;
|
||||
|
||||
struct Clip;
|
||||
class QXmlStreamWriter;
|
||||
|
||||
enum EffectTypes { EFFECT_TYPE_INVALID, EFFECT_TYPE_VIDEO, EFFECT_TYPE_AUDIO };
|
||||
|
||||
@@ -16,18 +17,23 @@ class Effect : public QObject
|
||||
public:
|
||||
Effect(Clip* c); // default constructor
|
||||
int type;
|
||||
int id;
|
||||
QString name;
|
||||
CollapsibleWidget* container;
|
||||
QWidget* ui;
|
||||
Clip* parent_clip;
|
||||
|
||||
virtual Effect* copy();
|
||||
virtual void save(QXmlStreamWriter* stream);
|
||||
|
||||
virtual void process_gl(int* anchor_x, int* anchor_y);
|
||||
virtual void process_audio(uint8_t* samples, int nb_bytes);
|
||||
|
||||
public slots:
|
||||
void field_changed();
|
||||
|
||||
protected:
|
||||
void setup_effect(int t, int i);
|
||||
};
|
||||
|
||||
#endif // EFFECT_H
|
||||
|
||||
+1
-2
@@ -19,8 +19,7 @@ void SourceTable::mouseDoubleClickEvent(QMouseEvent* )
|
||||
} else if (selectedItems().count() == 1) {
|
||||
Media* m = reinterpret_cast<Media*>(selectedItems().at(0)->data(0, Qt::UserRole + 1).value<quintptr>());
|
||||
if (m->is_sequence) {
|
||||
panel_timeline->set_sequence(m->sequence);
|
||||
panel_viewer->set_sequence(m->sequence);
|
||||
panel_project->set_sequence(m->sequence);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) {
|
||||
panel_timeline->drag_track_start = (bottom_align) ? -1 : 0;
|
||||
for (int i=0;i<items.size();i++) {
|
||||
bool ignore_infinite_length = false;
|
||||
Media* m = reinterpret_cast<Media*>(items.at(i)->data(0, Qt::UserRole + 1).value<quintptr>());
|
||||
Media* m = panel_project->get_media_from_tree(items.at(i));
|
||||
long duration = m->get_length_in_frames(panel_timeline->sequence->frame_rate);
|
||||
Ghost g = {NULL, entry_point, entry_point + duration};
|
||||
g.media = m;
|
||||
@@ -544,6 +544,8 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) {
|
||||
panel_timeline->cursor_frame > panel_timeline->playhead-limit-1 &&
|
||||
panel_timeline->cursor_frame < panel_timeline->playhead+limit+1) {
|
||||
panel_timeline->cursor_frame = panel_timeline->playhead;
|
||||
panel_timeline->snapped = true;
|
||||
panel_timeline->snap_point = panel_timeline->playhead;
|
||||
} else {
|
||||
panel_timeline->snap_to_clip(&panel_timeline->cursor_frame);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user