big progress on graph editor

This commit is contained in:
itsmattkc
2018-12-28 22:06:38 +11:00
parent c3ea55faf4
commit e101739214
25 changed files with 607 additions and 84 deletions
+8 -2
View File
@@ -107,7 +107,10 @@ SOURCES += \
project/sourcescommon.cpp \
ui/keyframenavigator.cpp \
panels/grapheditor.cpp \
ui/graphview.cpp
ui/graphview.cpp \
ui/keyframedrawing.cpp \
ui/clickablelabel.cpp \
project/keyframe.cpp
HEADERS += \
mainwindow.h \
@@ -189,7 +192,10 @@ HEADERS += \
project/sourcescommon.h \
ui/keyframenavigator.h \
panels/grapheditor.h \
ui/graphview.h
ui/graphview.h \
ui/keyframedrawing.h \
ui/clickablelabel.h \
project/keyframe.h
FORMS += \
mainwindow.ui \
+4
View File
@@ -16,6 +16,7 @@
#include "panels/project.h"
#include "panels/timeline.h"
#include "panels/viewer.h"
#include "panels/grapheditor.h"
#include "ui/viewerwidget.h"
#include "io/clipboard.h"
#include "debug.h"
@@ -204,6 +205,9 @@ void EffectControls::clear_effects(bool clear_cache) {
// clear existing clips
deselect_all_effects(NULL);
// clear graph editor
if (panel_graph_editor != NULL) panel_graph_editor->set_row(NULL);
QVBoxLayout* video_layout = static_cast<QVBoxLayout*>(ui->video_effect_area->layout());
QVBoxLayout* audio_layout = static_cast<QVBoxLayout*>(ui->audio_effect_area->layout());
QLayoutItem* item;
+172 -18
View File
@@ -3,46 +3,200 @@
#include <QVBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QVariant>
#include "ui/graphview.h"
#include "ui/keyframenavigator.h"
#include "ui/timelineheader.h"
#include "ui/timelinetools.h"
#include "ui/labelslider.h"
#include "ui/graphview.h"
#include "project/effect.h"
#include "project/effectfield.h"
#include "project/effectrow.h"
#include "project/clip.h"
#include "panels.h"
#include "debug.h"
GraphEditor::GraphEditor(QWidget* parent) : QDockWidget(parent) {
GraphEditor::GraphEditor(QWidget* parent) : QDockWidget(parent), row(NULL) {
setWindowTitle("Graph Editor");
resize(720, 480);
QWidget* central_widget = new QWidget();
setWidget(central_widget);
QWidget* main_widget = new QWidget();
setWidget(main_widget);
QVBoxLayout* layout = new QVBoxLayout();
central_widget->setLayout(layout);
main_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();
QWidget* left_tool_widget = new QWidget();
QHBoxLayout* left_tool_layout = new QHBoxLayout();
left_tool_layout->setSpacing(0);
left_tool_layout->setMargin(0);
left_tool_widget->setLayout(left_tool_layout);
tools->addWidget(left_tool_widget);
QWidget* center_tool_widget = new QWidget();
QHBoxLayout* center_tool_layout = new QHBoxLayout();
center_tool_layout->setSpacing(0);
center_tool_layout->setMargin(0);
center_tool_widget->setLayout(center_tool_layout);
tools->addWidget(center_tool_widget);
QWidget* right_tool_widget = new QWidget();
QHBoxLayout* right_tool_layout = new QHBoxLayout();
right_tool_layout->setSpacing(0);
right_tool_layout->setMargin(0);
right_tool_widget->setLayout(right_tool_layout);
tools->addWidget(right_tool_widget);
tools->addWidget(new QPushButton("HECK!"));
tools->addStretch();
keyframe_nav = new KeyframeNavigator();
keyframe_nav->enable_keyframes(true);
keyframe_nav->enable_keyframe_toggle(false);
left_tool_layout->addWidget(keyframe_nav);
left_tool_layout->addStretch();
tools->addWidget(new QPushButton("Hand"));
QPushButton* linear_button = new QPushButton("Linear");
linear_button->setCheckable(true);
QPushButton* bezier_button = new QPushButton("Bezier");
bezier_button->setCheckable(true);
QPushButton* hold_button = new QPushButton("Hold");
hold_button->setCheckable(true);
center_tool_layout->addStretch();
center_tool_layout->addWidget(linear_button);
center_tool_layout->addWidget(bezier_button);
center_tool_layout->addWidget(hold_button);
/*QPushButton* tool_arrow_button = new QPushButton();
tool_arrow_button->setCheckable(true);
tool_arrow_button->setIcon(QIcon(":/icons/arrow.png"));
tool_arrow_button->setProperty("tool", TIMELINE_TOOL_POINTER);
tool_buttons.append(tool_arrow_button);
QPushButton* tool_hand_button = new QPushButton();
tool_hand_button->setCheckable(true);
tool_hand_button->setIcon(QIcon(":/icons/hand.png"));
tool_hand_button->setProperty("tool", TIMELINE_TOOL_HAND);
tool_buttons.append(tool_hand_button);
QPushButton* tool_zoom_button = new QPushButton();
tool_zoom_button->setCheckable(true);
tool_zoom_button->setIcon(QIcon(":/icons/zoomin.png"));
tool_zoom_button->setProperty("tool", TIMELINE_TOOL_ZOOM);
tool_buttons.append(tool_zoom_button);
right_tool_layout->addStretch();
for (int i=0;i<tool_buttons.size();i++) {
right_tool_layout->addWidget(tool_buttons.at(i));
}*/
layout->addWidget(tool_widget);
view = new GraphView();
layout->addWidget(view);
QWidget* central_widget = new QWidget();
QVBoxLayout* central_layout = new QVBoxLayout();
central_widget->setLayout(central_layout);
central_layout->setSpacing(0);
central_layout->setMargin(0);
header = new TimelineHeader();
header->viewer = panel_sequence_viewer;
central_layout->addWidget(header);
view = new GraphView();
central_layout->addWidget(view);
layout->addWidget(central_widget);
QWidget* value_widget = new QWidget();
value_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
QHBoxLayout* values = new QHBoxLayout();
QHBoxLayout* values = new QHBoxLayout();
value_widget->setLayout(values);
values->addStretch();
values->addWidget(new QLabel("1920.0"));
values->addWidget(new QLabel("1080.0"));
current_row_desc = new QLabel();
values->addWidget(current_row_desc);
QWidget* central_value_widget = new QWidget();
value_layout = new QHBoxLayout();
value_layout->setMargin(0);
central_value_widget->setLayout(value_layout);
values->addWidget(central_value_widget);
values->addStretch();
layout->addWidget(value_widget);
layout->addWidget(value_widget);
connect(view, SIGNAL(zoom_changed(double)), header, SLOT(update_zoom(double)));
connect(view, SIGNAL(x_scroll_changed(int)), header, SLOT(set_scroll(int)));
}
void GraphEditor::update_panel() {
if (isVisible()) {
if (row != NULL) {
int slider_index = 0;
for (int i=0;i<row->fieldCount();i++) {
EffectField* field = row->field(i);
if (field->type == EFFECT_FIELD_DOUBLE) {
slider_proxies.at(slider_index)->set_value(row->field(i)->get_current_data().toDouble(), false);
slider_index++;
}
}
}
header->update();
view->update();
}
}
void GraphEditor::set_row(EffectRow *r) {
for (int i=0;i<slider_proxies.size();i++) {
delete slider_proxies.at(i);
}
slider_proxies.clear();
slider_proxy_sources.clear();
if (row != NULL) {
// clear old row connections
disconnect(keyframe_nav, SIGNAL(goto_previous_key()), row, SLOT(goto_previous_key()));
disconnect(keyframe_nav, SIGNAL(toggle_key()), row, SLOT(toggle_key()));
disconnect(keyframe_nav, SIGNAL(goto_next_key()), row, SLOT(goto_next_key()));
}
bool found_vals = false;
if (r != NULL && r->isKeyframing()) {
for (int i=0;i<r->fieldCount();i++) {
EffectField* field = r->field(i);
if (field->type == EFFECT_FIELD_DOUBLE) {
LabelSlider* slider = new LabelSlider();
slider->set_color(get_curve_color(i, r->fieldCount()).name());
connect(slider, SIGNAL(valueChanged()), this, SLOT(passthrough_slider_value()));
slider_proxies.append(slider);
value_layout->addWidget(slider);
slider_proxy_sources.append(static_cast<LabelSlider*>(field->ui_element));
found_vals = true;
}
}
}
if (found_vals) {
row = r;
current_row_desc->setText(row->parent_effect->parent_clip->name + " :: " + row->parent_effect->meta->name + " :: " + row->get_name());
connect(keyframe_nav, SIGNAL(goto_previous_key()), row, SLOT(goto_previous_key()));
connect(keyframe_nav, SIGNAL(toggle_key()), row, SLOT(toggle_key()));
connect(keyframe_nav, SIGNAL(goto_next_key()), row, SLOT(goto_next_key()));
} else {
row = NULL;
current_row_desc->setText(0);
}
view->set_row(row);
update_panel();
}
void GraphEditor::passthrough_slider_value() {
for (int i=0;i<slider_proxies.size();i++) {
if (slider_proxies.at(i) == sender()) {
slider_proxy_sources.at(i)->set_value(slider_proxies.at(i)->value(), true);
}
}
}
+19 -1
View File
@@ -4,13 +4,31 @@
#include <QDockWidget>
class GraphView;
class TimelineHeader;
class QPushButton;
class EffectRow;
class QHBoxLayout;
class LabelSlider;
class QLabel;
class KeyframeNavigator;
class GraphEditor : public QDockWidget {
Q_OBJECT
public:
GraphEditor(QWidget* parent = 0);
void update_panel();
void set_row(EffectRow* r);
private:
GraphView* view;
GraphView* view;
TimelineHeader* header;
QHBoxLayout* value_layout;
QVector<LabelSlider*> slider_proxies;
QVector<LabelSlider*> slider_proxy_sources;
QLabel* current_row_desc;
EffectRow* row;
KeyframeNavigator* keyframe_nav;
private slots:
void passthrough_slider_value();
};
#endif // GRAPHEDITOR_H
+1
View File
@@ -107,6 +107,7 @@ void update_ui(bool modified) {
panel_effect_controls->update_keyframes();
panel_timeline->repaint_timeline();
panel_sequence_viewer->update_viewer();
panel_graph_editor->update_panel();
}
QDockWidget *get_focused_panel() {
+2
View File
@@ -10,6 +10,7 @@
#include "project/clip.h"
#include "panels/timeline.h"
#include "panels/effectcontrols.h"
#include "panels/grapheditor.h"
#include "ui/checkboxex.h"
#include "debug.h"
#include "io/path.h"
@@ -489,6 +490,7 @@ void Effect::refresh() {}
void Effect::field_changed() {
panel_sequence_viewer->viewer_widget->update();
panel_graph_editor->update_panel();
}
void Effect::show_context_menu(const QPoint& pos) {
+1
View File
@@ -28,6 +28,7 @@ EffectField::EffectField(EffectRow *parent, int t, const QString &i) :
LabelSlider* ls = new LabelSlider();
ui_element = ls;
connect(ls, SIGNAL(valueChanged()), this, SLOT(ui_element_change()));
connect(ls, SIGNAL(clicked()), this, SIGNAL(clicked()));
}
break;
case EFFECT_FIELD_COLOR:
+1
View File
@@ -69,6 +69,7 @@ private slots:
signals:
void changed();
void toggled(bool);
void clicked();
};
#endif // EFFECTFIELD_H
+19 -5
View File
@@ -1,6 +1,5 @@
#include "effectrow.h"
#include <QLabel>
#include <QHBoxLayout>
#include <QPushButton>
#include <QMessageBox>
@@ -11,9 +10,11 @@
#include "panels/panels.h"
#include "panels/effectcontrols.h"
#include "panels/viewer.h"
#include "panels/grapheditor.h"
#include "effect.h"
#include "ui/viewerwidget.h"
#include "ui/keyframenavigator.h"
#include "ui/clickablelabel.h"
EffectRow::EffectRow(Effect *parent, bool save, QGridLayout *uilayout, const QString &n, int row) :
parent_effect(parent),
@@ -24,15 +25,19 @@ EffectRow::EffectRow(Effect *parent, bool save, QGridLayout *uilayout, const QSt
ui_row(row),
just_made_unsafe_keyframe(false)
{
label = new QLabel(name);
label = new ClickableLabel(name);
ui->addWidget(label, row, 0);
if (parent_effect->meta->type != EFFECT_TYPE_TRANSITION) {
connect(label, SIGNAL(clicked()), this, SLOT(focus_row()));
keyframe_nav = new KeyframeNavigator();
connect(keyframe_nav, SIGNAL(goto_previous_key()), this, SLOT(goto_previous_key()));
connect(keyframe_nav, SIGNAL(toggle_key()), this, SLOT(toggle_key()));
connect(keyframe_nav, SIGNAL(goto_next_key()), this, SLOT(goto_next_key()));
connect(keyframe_nav, SIGNAL(set_keyframe_enabled(bool)), this, SLOT(set_keyframe_enabled(bool)));
connect(keyframe_nav, SIGNAL(keyframe_enabled_changed(bool)), this, SLOT(set_keyframe_enabled(bool)));
connect(keyframe_nav, SIGNAL(clicked()), this, SLOT(focus_row()));
ui->addWidget(keyframe_nav, row, 6);
}
}
@@ -114,11 +119,16 @@ void EffectRow::goto_next_key() {
key = qMin(comp, key);
}
}
if (key != LONG_MAX) panel_sequence_viewer->seek(key);
if (key != LONG_MAX) panel_sequence_viewer->seek(key);
}
void EffectRow::focus_row() {
panel_graph_editor->set_row(this);
}
EffectField* EffectRow::add_field(int type, const QString& id, int colspan) {
EffectField* field = new EffectField(this, type, id);
if (parent_effect->meta->type != EFFECT_TYPE_TRANSITION) connect(field, SIGNAL(clicked()), this, SLOT(focus_row()));
fields.append(field);
QWidget* element = field->get_ui_element();
ui->addWidget(element, ui_row, fields.size(), 1, colspan);
@@ -162,7 +172,11 @@ void EffectRow::delete_keyframe_at_time(KeyframeDelete* kd, long time) {
delete_keyframe(kd, i);
break;
}
}
}
}
const QString &EffectRow::get_name() {
return name;
}
void EffectRow::delete_keyframe(KeyframeDelete* kd, int index) {
+9 -5
View File
@@ -13,6 +13,7 @@ class QPushButton;
class ComboAction;
class QHBoxLayout;
class KeyframeNavigator;
class ClickableLabel;
class EffectRow : public QObject {
Q_OBJECT
@@ -25,20 +26,23 @@ public:
void set_keyframe_now(ComboAction *ca);
void delete_keyframe(KeyframeDelete *kd, int index);
void delete_keyframe_at_time(KeyframeDelete* kd, long time);
QLabel* label;
ClickableLabel* label;
Effect* parent_effect;
bool savable;
const QString& get_name();
bool isKeyframing();
void setKeyframing(bool);
QVector<long> keyframe_times;
QVector<int> keyframe_types;
public slots:
void goto_previous_key();
void toggle_key();
void goto_next_key();
void focus_row();
private slots:
void set_keyframe_enabled(bool);
void goto_previous_key();
void toggle_key();
void goto_next_key();
void set_keyframe_enabled(bool);
private:
bool keyframing;
QGridLayout* ui;
+2
View File
@@ -0,0 +1,2 @@
#include "keyframe.h"
+17
View File
@@ -0,0 +1,17 @@
#ifndef KEYFRAME_H
#define KEYFRAME_H
#include <QVariant>
#include <QPoint>
class KeyframeData
{
public:
QVariant data;
QPoint handle_pre;
QPoint handle_post;
};
#endif // KEYFRAME_H
+13
View File
@@ -0,0 +1,13 @@
#include "clickablelabel.h"
ClickableLabel::ClickableLabel(QWidget *parent, Qt::WindowFlags f) :
QLabel(parent, f)
{}
ClickableLabel::ClickableLabel(const QString &text, QWidget *parent, Qt::WindowFlags f) :
QLabel(text, parent, f)
{}
void ClickableLabel::mousePressEvent(QMouseEvent *) {
emit clicked();
}
+16
View File
@@ -0,0 +1,16 @@
#ifndef CLICKABLELABEL_H
#define CLICKABLELABEL_H
#include <QLabel>
class ClickableLabel : public QLabel {
Q_OBJECT
public:
ClickableLabel(QWidget * parent = 0, Qt::WindowFlags f = 0);
ClickableLabel(const QString & text, QWidget * parent = 0, Qt::WindowFlags f = 0);
void mousePressEvent(QMouseEvent *ev);
signals:
void clicked();
};
#endif // CLICKABLELABEL_H
+200 -7
View File
@@ -1,16 +1,209 @@
#include "graphview.h"
#include <QPainter>
#include <QMouseEvent>
GraphView::GraphView(QWidget* parent) {}
#include "panels/panels.h"
#include "panels/timeline.h"
#include "panels/viewer.h"
#include "project/sequence.h"
#include "project/effectrow.h"
#include "project/effectfield.h"
#include "ui/keyframedrawing.h"
#include "debug.h"
#define GRAPH_ZOOM_SPEED 0.05
#define GRAPH_SIZE 100
QColor get_curve_color(int index, int length) {
QColor c;
int hue = (double(index)/double(length))*255;
c.setHsv(hue, 255, 255);
return c;
}
GraphView::GraphView(QWidget* parent) :
QWidget(parent),
x_scroll(0),
y_scroll(0),
mousedown(false),
zoom(1.0),
row(NULL)
{
setMouseTracking(true);
}
void GraphView::paintEvent(QPaintEvent *event) {
QPainter p(this);
QPainter p(this);
p.setPen(Qt::white);
if (panel_sequence_viewer->seq != NULL) {
// draw lines
//int graph_size = GRAPH_SIZE*zoom;
bool draw_text = true;//(fontMetrics().height() < graph_size && fontMetrics().width("0000") < graph_size);
QRect border = rect();
border.setWidth(border.width()-1);
border.setHeight(border.height()-1);
p.drawRect(border);
p.setPen(Qt::gray);
int i = 0;
while (true) {
int line_x = (i*GRAPH_SIZE*zoom) - x_scroll;
if (line_x >= width()) {
break;
}
if (line_x >= 0) {
if (line_x > 0) p.drawLine(line_x, 0, line_x, height());
if (draw_text) p.drawText(QRect(line_x, height()-50, 50, 50), Qt::AlignBottom | Qt::AlignLeft, QString::number(i*GRAPH_SIZE));
}
i++;
}
i = 0;
while (true) {
int line_y = height() - (i*GRAPH_SIZE*zoom) + y_scroll;
if (line_y <= 0) {
break;
}
if (line_y <= height()) {
if (line_y < height()) p.drawLine(0, line_y, width(), line_y);
if (draw_text) p.drawText(QRect(0, line_y-50, 50, 50), Qt::AlignBottom | Qt::AlignLeft, QString::number(i*GRAPH_SIZE));
}
i++;
}
// draw keyframes
if (row != NULL) {
QPen line_pen;
line_pen.setWidth(2);
// sort keyframes by time
QVector<int> sorted_keys;
for (int i=0;i<row->keyframe_times.size();i++) {
bool inserted = false;
for (int j=0;j<sorted_keys.size();j++) {
if (row->keyframe_times.at(sorted_keys.at(j)) > row->keyframe_times.at(i)) {
sorted_keys.insert(j, i);
inserted = true;
break;
}
}
if (!inserted) {
sorted_keys.append(i);
}
}
int last_key_x, last_key_y;
for (int i=0;i<row->fieldCount();i++) {
EffectField* field = row->field(i);
if (field->type == EFFECT_FIELD_DOUBLE) {
for (int j=0;j<sorted_keys.size();j++) {
int key_index = sorted_keys.at(j);
int key_x = get_screen_x(row->keyframe_times.at(key_index));
int key_y = get_screen_y(field->keyframe_data.at(key_index).toDouble());
line_pen.setColor(get_curve_color(i, row->fieldCount()));
p.setPen(line_pen);
if (key_index == 0) {
p.drawLine(0, key_y, key_x, key_y);
} else {
p.drawLine(last_key_x, last_key_y, key_x, key_y);
}
last_key_x = key_x;
last_key_y = key_y;
}
for (int j=0;j<sorted_keys.size();j++) {
int key_index = sorted_keys.at(j);
int key_x = get_screen_x(row->keyframe_times.at(key_index));
int key_y = get_screen_y(field->keyframe_data.at(key_index).toDouble());
draw_keyframe(p, row->keyframe_types.at(key_index), key_x, key_y, false);
}
p.setBrush(Qt::NoBrush);
}
}
}
// draw playhead
p.setPen(Qt::red);
int playhead_x = get_screen_x(panel_sequence_viewer->seq->playhead);
p.drawLine(playhead_x, 0, playhead_x, height());
}
p.setPen(Qt::white);
QRect border = rect();
border.setWidth(border.width()-1);
border.setHeight(border.height()-1);
p.drawRect(border);
}
void GraphView::mousePressEvent(QMouseEvent *event) {
mousedown = true;
start_x = event->pos().x();
start_y = event->pos().y();
}
void GraphView::mouseMoveEvent(QMouseEvent *event) {
if (mousedown) {
if (event->buttons() & Qt::MiddleButton || panel_timeline->tool == TIMELINE_TOOL_HAND) {
set_scroll_x(x_scroll + start_x - event->pos().x());
set_scroll_y(y_scroll + event->pos().y() - start_y);
start_x = event->pos().x();
start_y = event->pos().y();
update();
}
}
}
void GraphView::mouseReleaseEvent(QMouseEvent *event) {
mousedown = false;
}
void GraphView::wheelEvent(QWheelEvent *event) {
bool redraw = false;
bool shift = (event->modifiers() & Qt::ShiftModifier); // scroll instead of zoom
bool alt = (event->modifiers() & Qt::AltModifier); // horiz scroll instead of vert scroll
if (shift) {
// scroll
set_scroll_x(x_scroll + event->angleDelta().x()/10);
set_scroll_y(y_scroll + event->angleDelta().y()/10);
redraw = true;
} else {
// set zoom
if (event->angleDelta().y() != 0) {
double zoom_diff = (GRAPH_ZOOM_SPEED*zoom);
if (event->angleDelta().y() < 0) zoom_diff = -zoom_diff;
zoom += zoom_diff;
emit zoom_changed(zoom);
redraw = true;
}
}
if (redraw) {
update();
}
}
void GraphView::set_row(EffectRow *r) {
row = r;
update();
}
void GraphView::set_scroll_x(int s) {
x_scroll = s;//qMax(0, s);
dout << x_scroll;
emit x_scroll_changed(x_scroll);
}
void GraphView::set_scroll_y(int s) {
y_scroll = s;//qMax(0, s);
emit y_scroll_changed(y_scroll);
}
int GraphView::get_screen_x(double d) {
return (d*zoom) - x_scroll;
}
int GraphView::get_screen_y(double d) {
return height() + y_scroll - d*zoom;
}
+30
View File
@@ -3,11 +3,41 @@
#include <QWidget>
class EffectRow;
QColor get_curve_color(int index, int length);
class GraphView : public QWidget {
Q_OBJECT
public:
GraphView(QWidget* parent = 0);
void paintEvent(QPaintEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void wheelEvent(QWheelEvent *event);
void set_row(EffectRow* r);
signals:
void x_scroll_changed(int);
void y_scroll_changed(int);
void zoom_changed(double);
private:
int x_scroll;
int y_scroll;
bool mousedown;
int start_x;
int start_y;
double zoom;
void set_scroll_x(int s);
void set_scroll_y(int s);
int get_screen_x(double);
int get_screen_y(double);
EffectRow* row;
};
#endif // GRAPHVIEW_H
+26
View File
@@ -0,0 +1,26 @@
#include "keyframedrawing.h"
#include "project/effect.h"
#define KEYFRAME_POINT_COUNT 4
void draw_keyframe(QPainter &p, int type, int x, int y, bool darker) {
int color = (darker) ? 100 : 160;
p.setPen(QColor(0, 0, 0));
p.setBrush(QColor(color, color, color));
switch (type) {
case KEYFRAME_TYPE_LINEAR:
{
QPoint points[KEYFRAME_POINT_COUNT] = {QPoint(x-KEYFRAME_SIZE, y), QPoint(x, y-KEYFRAME_SIZE), QPoint(x+KEYFRAME_SIZE, y), QPoint(x, y+KEYFRAME_SIZE)};
p.drawPolygon(points, KEYFRAME_POINT_COUNT);
}
break;
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;
}
}
+10
View File
@@ -0,0 +1,10 @@
#ifndef KEYFRAMEDRAWING_H
#define KEYFRAMEDRAWING_H
#include <QPainter>
#define KEYFRAME_SIZE 6
void draw_keyframe(QPainter &p, int type, int x, int y, bool darker);
#endif // KEYFRAMEDRAWING_H
+21 -6
View File
@@ -2,15 +2,22 @@
#include <QHBoxLayout>
#include <QPushButton>
#include <QApplication>
#include <QDesktopWidget>
KeyframeNavigator::KeyframeNavigator(QWidget *parent) : QWidget(parent) {
QSize icon_size(12, 12);
QSize button_size(20, 20);
int icon_size_val = 8*QApplication::desktop()->devicePixelRatio();
int clock_size_val = 12*QApplication::desktop()->devicePixelRatio();
int button_size_val = 20*QApplication::desktop()->devicePixelRatio();
QSize icon_size(icon_size_val, icon_size_val);
QSize clock_size(clock_size_val, clock_size_val);
QSize button_size(button_size_val, button_size_val);
key_controls = new QHBoxLayout();
key_controls->setSpacing(0);
key_controls->setMargin(0);
key_controls->addStretch();
//key_controls->addStretch();
setLayout(key_controls);
@@ -21,6 +28,7 @@ KeyframeNavigator::KeyframeNavigator(QWidget *parent) : QWidget(parent) {
left_key_nav->setVisible(false);
key_controls->addWidget(left_key_nav);
connect(left_key_nav, SIGNAL(clicked(bool)), this, SIGNAL(goto_previous_key()));
connect(left_key_nav, SIGNAL(clicked(bool)), this, SIGNAL(clicked()));
key_addremove = new QPushButton();
key_addremove->setIcon(QIcon(":/icons/diamond.png"));
@@ -29,6 +37,7 @@ KeyframeNavigator::KeyframeNavigator(QWidget *parent) : QWidget(parent) {
key_addremove->setVisible(false);
key_controls->addWidget(key_addremove);
connect(key_addremove, SIGNAL(clicked(bool)), this, SIGNAL(toggle_key()));
connect(key_addremove, SIGNAL(clicked(bool)), this, SIGNAL(clicked()));
right_key_nav = new QPushButton();
right_key_nav->setIcon(QIcon(":/icons/tri-right.png"));
@@ -37,20 +46,26 @@ KeyframeNavigator::KeyframeNavigator(QWidget *parent) : QWidget(parent) {
right_key_nav->setVisible(false);
key_controls->addWidget(right_key_nav);
connect(right_key_nav, SIGNAL(clicked(bool)), this, SIGNAL(goto_next_key()));
connect(right_key_nav, SIGNAL(clicked(bool)), this, SIGNAL(clicked()));
keyframe_enable = new QPushButton(QIcon(":/icons/clock.png"), "");
keyframe_enable->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
keyframe_enable->setMaximumSize(button_size);
keyframe_enable->setIconSize(icon_size);
keyframe_enable->setIconSize(clock_size);
keyframe_enable->setCheckable(true);
keyframe_enable->setToolTip("Enable Keyframes");
connect(keyframe_enable, SIGNAL(clicked(bool)), this, SIGNAL(set_keyframe_enabled(bool)));
connect(keyframe_enable, SIGNAL(clicked(bool)), this, SIGNAL(keyframe_enabled_changed(bool)));
connect(keyframe_enable, SIGNAL(toggled(bool)), this, SLOT(keyframe_ui_enabled(bool)));
connect(keyframe_enable, SIGNAL(clicked(bool)), this, SIGNAL(clicked()));
key_controls->addWidget(keyframe_enable);
}
void KeyframeNavigator::enable_keyframes(bool b) {
keyframe_enable->setChecked(b);
keyframe_enable->setChecked(b);
}
void KeyframeNavigator::enable_keyframe_toggle(bool b) {
keyframe_enable->setVisible(b);
}
void KeyframeNavigator::keyframe_ui_enabled(bool enabled) {
+3 -1
View File
@@ -12,11 +12,13 @@ class KeyframeNavigator : public QWidget
public:
KeyframeNavigator(QWidget* parent = 0);
void enable_keyframes(bool);
void enable_keyframe_toggle(bool);
signals:
void goto_previous_key();
void toggle_key();
void goto_next_key();
void set_keyframe_enabled(bool);
void keyframe_enabled_changed(bool);
void clicked();
private slots:
void keyframe_ui_enabled(bool);
private:
+19 -34
View File
@@ -12,16 +12,14 @@
#include "ui/viewerwidget.h"
#include "project/sequence.h"
#include "panels/grapheditor.h"
#include "ui/keyframedrawing.h"
#include "ui_effectcontrols.h"
#include "ui/clickablelabel.h"
#include <QLabel>
#include <QMouseEvent>
#include <QtMath>
#include <QMenu>
#define KEYFRAME_SIZE 6
#define KEYFRAME_POINT_COUNT 4
long KeyframeView::adjust_row_keyframe(EffectRow* row, long time) {
return time-row->parent_effect->parent_clip->clip_in+(row->parent_effect->parent_clip->timeline_in-visible_in);
}
@@ -36,7 +34,7 @@ KeyframeView::KeyframeView(QWidget *parent) :
select_rect(false),
x_scroll(0),
y_scroll(0),
scroll_drag(false)
scroll_drag(false)
{
setFocusPolicy(Qt::ClickFocus);
setMouseTracking(true);
@@ -73,7 +71,7 @@ void KeyframeView::menu_set_key_type(QAction* a) {
ca->append(new SetInt(&selected_rows.at(i)->keyframe_types[selected_keyframes.at(i)], a->data().toInt()));
}
undo_stack.push(ca);
update();
update_keys();
}
}
@@ -101,7 +99,7 @@ void KeyframeView::paintEvent(QPaintEvent*) {
for (int j=0;j<e->row_count();j++) {
EffectRow* row = e->row(j);
QLabel* label = row->label;
ClickableLabel* label = row->label;
QWidget* contents = e->container->contents;
int keyframe_y = label->y() + (label->height()>>1) + mapFrom(panel_effect_controls, contents->mapTo(panel_effect_controls, contents->pos())).y() - e->container->title_bar->height()/* - y_scroll*/;
@@ -153,6 +151,11 @@ bool KeyframeView::keyframeIsSelected(EffectRow *row, int keyframe) {
return false;
}
void KeyframeView::update_keys() {
// panel_graph_editor->update_panel();
update();
}
void KeyframeView::delete_selected_keyframes() {
KeyframeDelete* kd = new KeyframeDelete();
bool del = false;
@@ -165,7 +168,7 @@ void KeyframeView::delete_selected_keyframes() {
selected_keyframes.clear();
selected_rows.clear();
update();
update_keys();
panel_sequence_viewer->viewer_widget->update();
} else {
delete kd;
@@ -174,33 +177,12 @@ void KeyframeView::delete_selected_keyframes() {
void KeyframeView::set_x_scroll(int s) {
x_scroll = s;
update();
update_keys();
}
void KeyframeView::set_y_scroll(int s) {
y_scroll = s;
update();
}
void KeyframeView::draw_keyframe(QPainter &p, int type, int x, int y, bool darker) {
int color = (darker) ? 100 : 160;
p.setPen(QColor(0, 0, 0));
p.setBrush(QColor(color, color, color));
switch (type) {
case KEYFRAME_TYPE_LINEAR:
{
QPoint points[KEYFRAME_POINT_COUNT] = {QPoint(x-KEYFRAME_SIZE, y), QPoint(x, y-KEYFRAME_SIZE), QPoint(x+KEYFRAME_SIZE, y), QPoint(x, y+KEYFRAME_SIZE)};
p.drawPolygon(points, KEYFRAME_POINT_COUNT);
}
break;
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;
}
update_keys();
}
void KeyframeView::resize_move(double d) {
@@ -227,6 +209,9 @@ void KeyframeView::mousePressEvent(QMouseEvent *event) {
for (int i=0;i<rowY.size();i++) {
if (mouse_y > rowY.at(i)-KEYFRAME_SIZE-KEYFRAME_SIZE && mouse_y < rowY.at(i)+KEYFRAME_SIZE+KEYFRAME_SIZE) {
EffectRow* row = rows.at(i);
row->focus_row();
for (int j=0;j<row->keyframe_times.size();j++) {
long eval_keyframe_time = row->keyframe_times.at(j)-row->parent_effect->parent_clip->clip_in+(row->parent_effect->parent_clip->timeline_in-visible_in);
if (eval_keyframe_time >= frame_min && eval_keyframe_time <= frame_max) {
@@ -259,7 +244,7 @@ void KeyframeView::mousePressEvent(QMouseEvent *event) {
keys_selected = true;
}
update();
update_keys();
if (event->button() == Qt::LeftButton) {
mousedown = true;
@@ -345,7 +330,7 @@ void KeyframeView::mouseMoveEvent(QMouseEvent* event) {
select_rect = true;
}
update();
update_keys();
}
}
@@ -363,5 +348,5 @@ void KeyframeView::mouseReleaseEvent(QMouseEvent*) {
mousedown = false;
scroll_drag = false;
panel_timeline->snapped = false;
update();
update_ui(false);
}
+3 -2
View File
@@ -23,7 +23,7 @@ public:
public slots:
void set_x_scroll(int);
void set_y_scroll(int);
void resize_move(double d);
void resize_move(double d);
private:
long adjust_row_keyframe(EffectRow* row, long time);
QVector<EffectRow*> selected_rows;
@@ -35,7 +35,6 @@ private:
void mouseMoveEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent *event);
void paintEvent(QPaintEvent *event);
void draw_keyframe(QPainter& p, int type, int x, int y, bool darker);
bool mousedown;
bool dragging;
bool keys_selected;
@@ -53,6 +52,8 @@ private:
int x_scroll;
int y_scroll;
void update_keys();
private slots:
void show_context_menu(const QPoint& pos);
void menu_set_key_type(QAction*);
+8 -2
View File
@@ -16,7 +16,7 @@ LabelSlider::LabelSlider(QWidget* parent) : QLabel(parent) {
drag_proc = false;
min_enabled = false;
max_enabled = false;
setStyleSheet("QLabel{color:#ffc000;text-decoration:underline;}QLabel:disabled{color:#808080;}");
set_color();
setCursor(Qt::SizeHorCursor);
internal_value = -1;
set = false;
@@ -75,7 +75,12 @@ double LabelSlider::getPreviousValue() {
}
void LabelSlider::set_previous_value() {
previous_value = internal_value;
previous_value = internal_value;
}
void LabelSlider::set_color(QString c) {
if (c.isEmpty()) c = "#ffc000";
setStyleSheet("QLabel{color:" + c + ";text-decoration:underline;}QLabel:disabled{color:#808080;}");
}
double LabelSlider::value() {
@@ -115,6 +120,7 @@ void LabelSlider::mousePressEvent(QMouseEvent *ev) {
drag_start_x = cursor().pos().x();
drag_start_y = cursor().pos().y();
}
emit clicked();
}
void LabelSlider::mouseMoveEvent(QMouseEvent* event) {
+2
View File
@@ -25,6 +25,7 @@ public:
QString valueToString(double v);
double getPreviousValue();
void set_previous_value();
void set_color(QString c = 0);
int decimal_places;
protected:
void mousePressEvent(QMouseEvent *ev);
@@ -53,6 +54,7 @@ private:
double frame_rate;
signals:
void valueChanged();
void clicked();
};
#endif // LABELSLIDER_H
+1 -1
View File
@@ -21,12 +21,12 @@ public:
bool snapping;
void show_text(bool enable);
void update_zoom(double z);
double get_zoom();
void delete_markers();
void set_scrollbar_max(QScrollBar* bar, long sequence_end_frame, int offset);
public slots:
void update_zoom(double z);
void set_scroll(int);
void set_visible_in(long i);
void show_context_menu(const QPoint &pos);