From 4378fb74232052d9da5bcb1440dad92ba7264ef9 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Thu, 27 Dec 2018 09:47:08 +1100 Subject: [PATCH 1/3] changed img seq debug message --- io/loadthread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/io/loadthread.cpp b/io/loadthread.cpp index b7688a1a6..65bdc50f4 100644 --- a/io/loadthread.cpp +++ b/io/loadthread.cpp @@ -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"; } From 1ee9451343313e38b199b2a21d14df8815f9e706 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Thu, 27 Dec 2018 10:29:02 +1100 Subject: [PATCH 2/3] implemented hold keyframe and began new panel --- mainwindow.cpp | 21 +++++---------------- olive.pro | 8 ++++++-- panels/grapheditor.cpp | 31 +++++++++++++++++++++++++++++++ panels/grapheditor.h | 16 ++++++++++++++++ panels/panels.cpp | 35 ++++++++++++++++++++++++++++++----- panels/panels.h | 6 ++++++ project/effect.h | 4 ++-- project/effectfield.cpp | 13 +++++++++---- ui/graphview.cpp | 13 +++++++++++++ ui/graphview.h | 13 +++++++++++++ ui/keyframeview.cpp | 31 ++++++++++++++++++++++--------- 11 files changed, 153 insertions(+), 38 deletions(-) create mode 100644 panels/grapheditor.cpp create mode 100644 panels/grapheditor.h create mode 100644 ui/graphview.cpp create mode 100644 ui/graphview.h diff --git a/mainwindow.cpp b/mainwindow.cpp index 738e7c9b6..8cd2f0972 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -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,6 +58,7 @@ 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; @@ -77,6 +79,7 @@ void MainWindow::setup_layout(bool reset) { 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) @@ -194,12 +197,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 +257,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(); } diff --git a/olive.pro b/olive.pro index 650aedb28..eab6b3b19 100644 --- a/olive.pro +++ b/olive.pro @@ -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 \ diff --git a/panels/grapheditor.cpp b/panels/grapheditor.cpp new file mode 100644 index 000000000..ef2f1fdd2 --- /dev/null +++ b/panels/grapheditor.cpp @@ -0,0 +1,31 @@ +#include "grapheditor.h" + +#include +#include +#include + +#include "ui/graphview.h" + +GraphEditor::GraphEditor(QWidget* parent) : QDockWidget(parent) { + setWindowTitle("Graph Editor"); + + QWidget* central_widget = new QWidget(); + setWidget(central_widget); + + QVBoxLayout* layout = new QVBoxLayout(); + central_widget->setLayout(layout); + + QHBoxLayout* tools = new QHBoxLayout(); + tools->addWidget(new QPushButton("HECK!")); + layout->addLayout(tools); + + view = new GraphView(); + layout->addWidget(view); + + QHBoxLayout* values = new QHBoxLayout(); + values->addStretch(); + values->addWidget(new QLabel("1920.0")); + values->addWidget(new QLabel("1080.0")); + values->addStretch(); + layout->addLayout(values); +} diff --git a/panels/grapheditor.h b/panels/grapheditor.h new file mode 100644 index 000000000..5e4a919cf --- /dev/null +++ b/panels/grapheditor.h @@ -0,0 +1,16 @@ +#ifndef GRAPHEDITOR_H +#define GRAPHEDITOR_H + +#include + +class GraphView; + +class GraphEditor : public QDockWidget { + Q_OBJECT +public: + GraphEditor(QWidget* parent = 0); +private: + GraphView* view; +}; + +#endif // GRAPHEDITOR_H diff --git a/panels/panels.cpp b/panels/panels.cpp index dd8206ccc..fcc9e0008 100644 --- a/panels/panels.cpp +++ b/panels/panels.cpp @@ -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,26 @@ 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_footage_viewer = new Viewer(parent); + panel_project = new Project(parent); + panel_effect_controls = new EffectControls(parent); + panel_timeline = new Timeline(parent); + panel_graph_editor = new GraphEditor(parent); +} + +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; +} diff --git a/panels/panels.h b/panels/panels.h index 042a652d8..691736b82 100644 --- a/panels/panels.h +++ b/panels/panels.h @@ -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 diff --git a/project/effect.h b/project/effect.h index 08fcc13b4..572baf7a9 100644 --- a/project/effect.h +++ b/project/effect.h @@ -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; diff --git a/project/effectfield.cpp b/project/effectfield.cpp index d2166a835..2caaf2991 100644 --- a/project/effectfield.cpp +++ b/project/effectfield.cpp @@ -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) { diff --git a/ui/graphview.cpp b/ui/graphview.cpp new file mode 100644 index 000000000..405663889 --- /dev/null +++ b/ui/graphview.cpp @@ -0,0 +1,13 @@ +#include "graphview.h" + +#include + +GraphView::GraphView(QWidget* parent) {} + +void GraphView::paintEvent(QPaintEvent *event) { + QPainter p(this); + + p.setPen(Qt::white); + + p.drawRect(rect()); +} diff --git a/ui/graphview.h b/ui/graphview.h new file mode 100644 index 000000000..b28d80bf9 --- /dev/null +++ b/ui/graphview.h @@ -0,0 +1,13 @@ +#ifndef GRAPHVIEW_H +#define GRAPHVIEW_H + +#include + +class GraphView : public QWidget { +public: + GraphView(QWidget* parent = 0); + + void paintEvent(QPaintEvent *event); +}; + +#endif // GRAPHVIEW_H diff --git a/ui/keyframeview.cpp b/ui/keyframeview.cpp index c46dcb0c2..431d9ab03 100644 --- a/ui/keyframeview.cpp +++ b/ui/keyframeview.cpp @@ -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 @@ -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;iappend(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;iappend(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; } } From 8a6242e36fde034d77b2bd5f8b4b6b836af0f760 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Thu, 27 Dec 2018 11:51:35 +1100 Subject: [PATCH 3/3] reimplemented panel state restoration --- mainwindow.cpp | 42 +++++++++++++++++++++--------------------- mainwindow.h | 2 ++ mainwindow.ui | 9 +++++++++ panels/grapheditor.cpp | 21 +++++++++++++++++++-- panels/panels.cpp | 6 ++++++ playback/audio.cpp | 6 ++++-- ui/graphview.cpp | 5 ++++- 7 files changed, 65 insertions(+), 26 deletions(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index 8cd2f0972..f8be11aff 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -60,31 +60,26 @@ void MainWindow::setup_layout(bool reset) { 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); - panel_graph_editor->setFloating(true); + 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(); @@ -662,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() { @@ -1064,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()); +} diff --git a/mainwindow.h b/mainwindow.h index a1b380542..76d70263a 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -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); diff --git a/mainwindow.ui b/mainwindow.ui index fe24d5e23..1daae80cf 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -111,6 +111,7 @@ + @@ -957,6 +958,14 @@ H + + + true + + + Graph Editor + + diff --git a/panels/grapheditor.cpp b/panels/grapheditor.cpp index ef2f1fdd2..4128b2474 100644 --- a/panels/grapheditor.cpp +++ b/panels/grapheditor.cpp @@ -5,9 +5,11 @@ #include #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); @@ -15,17 +17,32 @@ GraphEditor::GraphEditor(QWidget* parent) : QDockWidget(parent) { 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!")); - layout->addLayout(tools); + 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->addLayout(values); + layout->addWidget(value_widget); } diff --git a/panels/panels.cpp b/panels/panels.cpp index fcc9e0008..be40e402b 100644 --- a/panels/panels.cpp +++ b/panels/panels.cpp @@ -143,11 +143,17 @@ QDockWidget *get_focused_panel() { 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() { diff --git a/playback/audio.cpp b/playback/audio.cpp index 8d04cedce..9f80c7c6c 100644 --- a/playback/audio.cpp +++ b/playback/audio.cpp @@ -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(); } diff --git a/ui/graphview.cpp b/ui/graphview.cpp index 405663889..7b1bad15f 100644 --- a/ui/graphview.cpp +++ b/ui/graphview.cpp @@ -9,5 +9,8 @@ void GraphView::paintEvent(QPaintEvent *event) { p.setPen(Qt::white); - p.drawRect(rect()); + QRect border = rect(); + border.setWidth(border.width()-1); + border.setHeight(border.height()-1); + p.drawRect(border); }