Merge branch 'bezierkeys' of https://github.com/olive-editor/olive into bezierkeys
This commit is contained in:
+1
-1
@@ -237,7 +237,7 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) {
|
||||
} else if (m->url.contains('%')) {
|
||||
// hack for image sequences (qt won't be able to find the URL with %, but ffmpeg may)
|
||||
m->url = internal_proj_dir_test;
|
||||
dout << "[INFO] Guess image sequence" << attr.value().toString() << "path to project's current directory";
|
||||
dout << "[INFO] Guess image sequence" << attr.value().toString() << "path to project's internal directory";
|
||||
} else {
|
||||
dout << "[INFO] Failed to match" << attr.value().toString() << "to file";
|
||||
}
|
||||
|
||||
+25
-36
@@ -18,6 +18,7 @@
|
||||
#include "panels/effectcontrols.h"
|
||||
#include "panels/viewer.h"
|
||||
#include "panels/timeline.h"
|
||||
#include "panels/grapheditor.h"
|
||||
|
||||
#include "dialogs/aboutdialog.h"
|
||||
#include "dialogs/newsequencedialog.h"
|
||||
@@ -57,31 +58,28 @@ void MainWindow::setup_layout(bool reset) {
|
||||
panel_footage_viewer->show();
|
||||
panel_sequence_viewer->show();
|
||||
panel_timeline->show();
|
||||
panel_graph_editor->hide();
|
||||
|
||||
bool load_default = true;
|
||||
|
||||
/*if (!reset) {
|
||||
QFile panel_config(get_data_path() + "/layout");
|
||||
if (panel_config.exists() && panel_config.open(QFile::ReadOnly)) {
|
||||
if (restoreState(panel_config.readAll(), 0)) {
|
||||
load_default = false;
|
||||
}
|
||||
panel_config.close();
|
||||
}
|
||||
}*/
|
||||
|
||||
if (load_default) {
|
||||
addDockWidget(Qt::TopDockWidgetArea, panel_project);
|
||||
addDockWidget(Qt::TopDockWidgetArea, panel_footage_viewer);
|
||||
tabifyDockWidget(panel_footage_viewer, panel_effect_controls);
|
||||
panel_footage_viewer->raise();
|
||||
addDockWidget(Qt::TopDockWidgetArea, panel_sequence_viewer);
|
||||
addDockWidget(Qt::BottomDockWidgetArea, panel_timeline);
|
||||
addDockWidget(Qt::TopDockWidgetArea, panel_project);
|
||||
addDockWidget(Qt::TopDockWidgetArea, panel_footage_viewer);
|
||||
tabifyDockWidget(panel_footage_viewer, panel_effect_controls);
|
||||
panel_footage_viewer->raise();
|
||||
addDockWidget(Qt::TopDockWidgetArea, panel_sequence_viewer);
|
||||
addDockWidget(Qt::BottomDockWidgetArea, panel_timeline);
|
||||
panel_graph_editor->setFloating(true);
|
||||
|
||||
// workaround for strange Qt dock bug (see https://bugreports.qt.io/browse/QTBUG-65592)
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
|
||||
resizeDocks({panel_project}, {40}, Qt::Horizontal);
|
||||
resizeDocks({panel_project}, {40}, Qt::Horizontal);
|
||||
#endif
|
||||
|
||||
// load panels from file
|
||||
if (!reset) {
|
||||
QFile panel_config(get_data_path() + "/layout");
|
||||
if (panel_config.exists() && panel_config.open(QFile::ReadOnly)) {
|
||||
restoreState(panel_config.readAll(), 0);
|
||||
panel_config.close();
|
||||
}
|
||||
}
|
||||
|
||||
layout()->update();
|
||||
@@ -194,12 +192,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
}
|
||||
}
|
||||
|
||||
// TODO maybe replace these with non-pointers later on?
|
||||
panel_sequence_viewer = new Viewer(this);
|
||||
panel_footage_viewer = new Viewer(this);
|
||||
panel_project = new Project(this);
|
||||
panel_effect_controls = new EffectControls(this);
|
||||
panel_timeline = new Timeline(this);
|
||||
alloc_panels(this);
|
||||
|
||||
if (!data_dir.isEmpty()) {
|
||||
// detect auto-recovery file
|
||||
@@ -259,16 +252,7 @@ MainWindow::~MainWindow() {
|
||||
|
||||
delete ui;
|
||||
|
||||
delete panel_sequence_viewer;
|
||||
panel_sequence_viewer = NULL;
|
||||
delete panel_footage_viewer;
|
||||
panel_footage_viewer = NULL;
|
||||
delete panel_project;
|
||||
panel_project = NULL;
|
||||
delete panel_effect_controls;
|
||||
panel_effect_controls = NULL;
|
||||
delete panel_timeline;
|
||||
panel_timeline = NULL;
|
||||
free_panels();
|
||||
|
||||
close_debug();
|
||||
}
|
||||
@@ -673,6 +657,7 @@ void MainWindow::windowMenu_About_To_Be_Shown() {
|
||||
ui->actionTimeline->setChecked(panel_timeline->isVisible());
|
||||
ui->actionViewer->setChecked(panel_sequence_viewer->isVisible());
|
||||
ui->actionFootage_Viewer->setChecked(panel_footage_viewer->isVisible());
|
||||
ui->actionGraph_Editor->setChecked(panel_graph_editor->isVisible());
|
||||
}
|
||||
|
||||
void MainWindow::viewMenu_About_To_Be_Shown() {
|
||||
@@ -1075,3 +1060,7 @@ void MainWindow::on_actionHand_Tool_triggered() {
|
||||
|| panel_sequence_viewer->is_focused())
|
||||
panel_timeline->ui->toolHandButton->click();
|
||||
}
|
||||
|
||||
void MainWindow::on_actionGraph_Editor_triggered() {
|
||||
panel_graph_editor->setVisible(!panel_graph_editor->isVisible());
|
||||
}
|
||||
|
||||
@@ -215,6 +215,8 @@ private slots:
|
||||
|
||||
void on_actionHand_Tool_triggered();
|
||||
|
||||
void on_actionGraph_Editor_triggered();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
void setup_layout(bool reset);
|
||||
|
||||
@@ -111,6 +111,7 @@
|
||||
<addaction name="actionFootage_Viewer"/>
|
||||
<addaction name="actionViewer"/>
|
||||
<addaction name="actionTimeline"/>
|
||||
<addaction name="actionGraph_Editor"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionReset_to_default_layout"/>
|
||||
</widget>
|
||||
@@ -957,6 +958,14 @@
|
||||
<string>H</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionGraph_Editor">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Graph Editor</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
|
||||
@@ -105,7 +105,9 @@ SOURCES += \
|
||||
ui/resizablescrollbar.cpp \
|
||||
ui/sourceiconview.cpp \
|
||||
project/sourcescommon.cpp \
|
||||
ui/keyframenavigator.cpp
|
||||
ui/keyframenavigator.cpp \
|
||||
panels/grapheditor.cpp \
|
||||
ui/graphview.cpp
|
||||
|
||||
HEADERS += \
|
||||
mainwindow.h \
|
||||
@@ -185,7 +187,9 @@ HEADERS += \
|
||||
ui/resizablescrollbar.h \
|
||||
ui/sourceiconview.h \
|
||||
project/sourcescommon.h \
|
||||
ui/keyframenavigator.h
|
||||
ui/keyframenavigator.h \
|
||||
panels/grapheditor.h \
|
||||
ui/graphview.h
|
||||
|
||||
FORMS += \
|
||||
mainwindow.ui \
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
#include "grapheditor.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
|
||||
#include "ui/graphview.h"
|
||||
#include "ui/keyframenavigator.h"
|
||||
|
||||
GraphEditor::GraphEditor(QWidget* parent) : QDockWidget(parent) {
|
||||
setWindowTitle("Graph Editor");
|
||||
resize(720, 480);
|
||||
|
||||
QWidget* central_widget = new QWidget();
|
||||
setWidget(central_widget);
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout();
|
||||
central_widget->setLayout(layout);
|
||||
|
||||
QWidget* tool_widget = new QWidget();
|
||||
tool_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
|
||||
QHBoxLayout* tools = new QHBoxLayout();
|
||||
tool_widget->setLayout(tools);
|
||||
|
||||
KeyframeNavigator* keyframe_nav = new KeyframeNavigator();
|
||||
tools->addWidget(keyframe_nav);
|
||||
tools->addStretch();
|
||||
|
||||
tools->addWidget(new QPushButton("HECK!"));
|
||||
tools->addStretch();
|
||||
|
||||
tools->addWidget(new QPushButton("Hand"));
|
||||
|
||||
layout->addWidget(tool_widget);
|
||||
|
||||
view = new GraphView();
|
||||
layout->addWidget(view);
|
||||
|
||||
QWidget* value_widget = new QWidget();
|
||||
value_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
|
||||
QHBoxLayout* values = new QHBoxLayout();
|
||||
value_widget->setLayout(values);
|
||||
values->addStretch();
|
||||
values->addWidget(new QLabel("1920.0"));
|
||||
values->addWidget(new QLabel("1080.0"));
|
||||
values->addStretch();
|
||||
layout->addWidget(value_widget);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef GRAPHEDITOR_H
|
||||
#define GRAPHEDITOR_H
|
||||
|
||||
#include <QDockWidget>
|
||||
|
||||
class GraphView;
|
||||
|
||||
class GraphEditor : public QDockWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
GraphEditor(QWidget* parent = 0);
|
||||
private:
|
||||
GraphView* view;
|
||||
};
|
||||
|
||||
#endif // GRAPHEDITOR_H
|
||||
+36
-5
@@ -8,6 +8,7 @@
|
||||
#include "project/clip.h"
|
||||
#include "project/transition.h"
|
||||
#include "io/config.h"
|
||||
#include "grapheditor.h"
|
||||
#include "debug.h"
|
||||
|
||||
Project* panel_project = 0;
|
||||
@@ -15,6 +16,7 @@ EffectControls* panel_effect_controls = 0;
|
||||
Viewer* panel_sequence_viewer = 0;
|
||||
Viewer* panel_footage_viewer = 0;
|
||||
Timeline* panel_timeline = 0;
|
||||
GraphEditor* panel_graph_editor = 0;
|
||||
|
||||
void update_effect_controls() {
|
||||
// SEND CLIPS TO EFFECT CONTROLS
|
||||
@@ -110,15 +112,15 @@ void update_ui(bool modified) {
|
||||
QDockWidget *get_focused_panel() {
|
||||
QDockWidget* w = NULL;
|
||||
if (config.hover_focus) {
|
||||
if (panel_project->rect().contains(panel_project->mapFromGlobal(QCursor::pos()))) {
|
||||
if (panel_project->underMouse()) {
|
||||
w = panel_project;
|
||||
} else if (panel_effect_controls->rect().contains(panel_effect_controls->mapFromGlobal(QCursor::pos()))) {
|
||||
} else if (panel_effect_controls->underMouse()) {
|
||||
w = panel_effect_controls;
|
||||
} else if (panel_sequence_viewer->rect().contains(panel_sequence_viewer->mapFromGlobal(QCursor::pos()))) {
|
||||
} else if (panel_sequence_viewer->underMouse()) {
|
||||
w = panel_sequence_viewer;
|
||||
} else if (panel_footage_viewer->rect().contains(panel_footage_viewer->mapFromGlobal(QCursor::pos()))) {
|
||||
} else if (panel_footage_viewer->underMouse()) {
|
||||
w = panel_footage_viewer;
|
||||
} else if (panel_timeline->rect().contains(panel_timeline->mapFromGlobal(QCursor::pos()))) {
|
||||
} else if (panel_timeline->underMouse()) {
|
||||
w = panel_timeline;
|
||||
}
|
||||
}
|
||||
@@ -137,3 +139,32 @@ QDockWidget *get_focused_panel() {
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
void alloc_panels(QWidget* parent) {
|
||||
// TODO maybe replace these with non-pointers later on?
|
||||
panel_sequence_viewer = new Viewer(parent);
|
||||
panel_sequence_viewer->setObjectName("seq_viewer");
|
||||
panel_footage_viewer = new Viewer(parent);
|
||||
panel_footage_viewer->setObjectName("footage_viewer");
|
||||
panel_project = new Project(parent);
|
||||
panel_project->setObjectName("proj_root");
|
||||
panel_effect_controls = new EffectControls(parent);
|
||||
panel_effect_controls->setObjectName("fx_controls");
|
||||
panel_timeline = new Timeline(parent);
|
||||
panel_timeline->setObjectName("timeline");
|
||||
panel_graph_editor = new GraphEditor(parent);
|
||||
panel_graph_editor->setObjectName("graph_editor");
|
||||
}
|
||||
|
||||
void free_panels() {
|
||||
delete panel_sequence_viewer;
|
||||
panel_sequence_viewer = NULL;
|
||||
delete panel_footage_viewer;
|
||||
panel_footage_viewer = NULL;
|
||||
delete panel_project;
|
||||
panel_project = NULL;
|
||||
delete panel_effect_controls;
|
||||
panel_effect_controls = NULL;
|
||||
delete panel_timeline;
|
||||
panel_timeline = NULL;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,9 @@ class Project;
|
||||
class EffectControls;
|
||||
class Viewer;
|
||||
class Timeline;
|
||||
class GraphEditor;
|
||||
|
||||
class QWidget;
|
||||
class QDockWidget;
|
||||
|
||||
extern Project* panel_project;
|
||||
@@ -12,8 +15,11 @@ extern EffectControls* panel_effect_controls;
|
||||
extern Viewer* panel_sequence_viewer;
|
||||
extern Viewer* panel_footage_viewer;
|
||||
extern Timeline* panel_timeline;
|
||||
extern GraphEditor* panel_graph_editor;
|
||||
|
||||
void update_ui(bool modified);
|
||||
QDockWidget* get_focused_panel();
|
||||
void alloc_panels(QWidget *parent);
|
||||
void free_panels();
|
||||
|
||||
#endif // PANELS_H
|
||||
|
||||
+4
-2
@@ -99,8 +99,10 @@ void stop_audio() {
|
||||
}
|
||||
|
||||
void clear_audio_ibuffer() {
|
||||
if (audio_thread != NULL) audio_thread->lock.lock();
|
||||
memset(audio_ibuffer, 0, audio_ibuffer_size);
|
||||
audio_ibuffer_read = 0;
|
||||
if (audio_thread != NULL) audio_thread->lock.unlock();
|
||||
}
|
||||
|
||||
int get_buffer_offset_from_frame(double framerate, long frame) {
|
||||
@@ -130,7 +132,7 @@ void AudioSenderThread::run() {
|
||||
// start data loop
|
||||
send_audio_to_output(0, audio_ibuffer_size);
|
||||
|
||||
lock.lock();
|
||||
lock.lock();
|
||||
while (true) {
|
||||
cond.wait(&lock);
|
||||
if (close) {
|
||||
@@ -149,7 +151,7 @@ void AudioSenderThread::run() {
|
||||
|
||||
audio_scrub = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -69,8 +69,8 @@ extern QMutex effects_loaded;
|
||||
#define EFFECT_INTERNAL_COUNT 13
|
||||
|
||||
#define KEYFRAME_TYPE_LINEAR 0
|
||||
#define KEYFRAME_TYPE_SMOOTH 1
|
||||
#define KEYFRAME_TYPE_BEZIER 2
|
||||
#define KEYFRAME_TYPE_BEZIER 1
|
||||
#define KEYFRAME_TYPE_HOLD 2
|
||||
|
||||
struct GLTextureCoords {
|
||||
int grid_size;
|
||||
|
||||
@@ -140,7 +140,12 @@ void EffectField::get_keyframe_data(double timecode, int &before, int &after, do
|
||||
before = before_keyframe_index;
|
||||
after = after_keyframe_index;
|
||||
|
||||
progress = (timecode-frameToTimecode(before_keyframe_time))/(frameToTimecode(after_keyframe_time)-frameToTimecode(before_keyframe_time));
|
||||
if (parent_row->keyframe_types.at(before) == KEYFRAME_TYPE_HOLD) {
|
||||
progress = 0;
|
||||
} else {
|
||||
// TODO replace with bezier function
|
||||
progress = (timecode-frameToTimecode(before_keyframe_time))/(frameToTimecode(after_keyframe_time)-frameToTimecode(before_keyframe_time));
|
||||
}
|
||||
} else if (before_keyframe_index > -1) {
|
||||
before = before_keyframe_index;
|
||||
after = before_keyframe_index;
|
||||
@@ -161,13 +166,13 @@ QVariant EffectField::validate_keyframe_data(double timecode, bool async) {
|
||||
double progress;
|
||||
get_keyframe_data(timecode, before_keyframe, after_keyframe, progress);
|
||||
|
||||
int kf_type = (progress < 0.5) ? parent_row->keyframe_types.at(before_keyframe) : parent_row->keyframe_types.at(after_keyframe);
|
||||
if (kf_type == KEYFRAME_TYPE_SMOOTH) {
|
||||
/*int kf_type = (progress < 0.5) ? parent_row->keyframe_types.at(before_keyframe) : parent_row->keyframe_types.at(after_keyframe);
|
||||
if (kf_type == KEYFRAME_TYPE_BEZIER) {
|
||||
double x = (8.0 * progress) - 4.0;
|
||||
progress = 1.0 / (1.0 + qPow(M_E, -x));
|
||||
progress *= 1.0373;
|
||||
progress -= 0.01865;
|
||||
}
|
||||
}*/
|
||||
|
||||
const QVariant& before_data = keyframe_data.at(before_keyframe);
|
||||
switch (type) {
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "graphview.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
GraphView::GraphView(QWidget* parent) {}
|
||||
|
||||
void GraphView::paintEvent(QPaintEvent *event) {
|
||||
QPainter p(this);
|
||||
|
||||
p.setPen(Qt::white);
|
||||
|
||||
QRect border = rect();
|
||||
border.setWidth(border.width()-1);
|
||||
border.setHeight(border.height()-1);
|
||||
p.drawRect(border);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#ifndef GRAPHVIEW_H
|
||||
#define GRAPHVIEW_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class GraphView : public QWidget {
|
||||
public:
|
||||
GraphView(QWidget* parent = 0);
|
||||
|
||||
void paintEvent(QPaintEvent *event);
|
||||
};
|
||||
|
||||
#endif // GRAPHVIEW_H
|
||||
+22
-9
@@ -11,6 +11,7 @@
|
||||
#include "panels/viewer.h"
|
||||
#include "ui/viewerwidget.h"
|
||||
#include "project/sequence.h"
|
||||
#include "panels/grapheditor.h"
|
||||
#include "ui_effectcontrols.h"
|
||||
|
||||
#include <QLabel>
|
||||
@@ -47,24 +48,33 @@ KeyframeView::KeyframeView(QWidget *parent) :
|
||||
void KeyframeView::show_context_menu(const QPoint& pos) {
|
||||
if (selected_rows.size() > 0) {
|
||||
QMenu menu(this);
|
||||
|
||||
QAction* linear = menu.addAction("Linear");
|
||||
linear->setData(KEYFRAME_TYPE_LINEAR);
|
||||
QAction* smooth = menu.addAction("Smooth");
|
||||
smooth->setData(KEYFRAME_TYPE_SMOOTH);
|
||||
/*QAction* bezier = menu.addAction("Bezier");
|
||||
bezier->setData(KEYFRAME_TYPE_BEZIER);*/
|
||||
smooth->setData(KEYFRAME_TYPE_BEZIER);
|
||||
QAction* hold = menu.addAction("Hold");
|
||||
hold->setData(KEYFRAME_TYPE_HOLD);
|
||||
menu.addSeparator();
|
||||
menu.addAction("Graph Editor");
|
||||
|
||||
connect(&menu, SIGNAL(triggered(QAction*)), this, SLOT(menu_set_key_type(QAction*)));
|
||||
menu.exec(mapToGlobal(pos));
|
||||
}
|
||||
}
|
||||
|
||||
void KeyframeView::menu_set_key_type(QAction* a) {
|
||||
ComboAction* ca = new ComboAction();
|
||||
for (int i=0;i<selected_rows.size();i++) {
|
||||
ca->append(new SetInt(&selected_rows.at(i)->keyframe_types[selected_keyframes.at(i)], a->data().toInt()));
|
||||
if (a->data().isNull()) {
|
||||
// load graph editor
|
||||
panel_graph_editor->show();
|
||||
} else {
|
||||
ComboAction* ca = new ComboAction();
|
||||
for (int i=0;i<selected_rows.size();i++) {
|
||||
ca->append(new SetInt(&selected_rows.at(i)->keyframe_types[selected_keyframes.at(i)], a->data().toInt()));
|
||||
}
|
||||
undo_stack.push(ca);
|
||||
update();
|
||||
}
|
||||
undo_stack.push(ca);
|
||||
update();
|
||||
}
|
||||
|
||||
void KeyframeView::paintEvent(QPaintEvent*) {
|
||||
@@ -184,9 +194,12 @@ void KeyframeView::draw_keyframe(QPainter &p, int type, int x, int y, bool darke
|
||||
p.drawPolygon(points, KEYFRAME_POINT_COUNT);
|
||||
}
|
||||
break;
|
||||
case KEYFRAME_TYPE_SMOOTH:
|
||||
case KEYFRAME_TYPE_BEZIER:
|
||||
p.drawEllipse(QPoint(x, y), KEYFRAME_SIZE, KEYFRAME_SIZE);
|
||||
break;
|
||||
case KEYFRAME_TYPE_HOLD:
|
||||
p.drawRect(QRect(x - KEYFRAME_SIZE, y - KEYFRAME_SIZE, KEYFRAME_SIZE*2, KEYFRAME_SIZE*2));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user