made all keyframes editable and undoable

This commit is contained in:
itsmattkc
2018-08-20 23:35:56 +10:00
parent 33d3cc34c8
commit 263bf090b4
22 changed files with 470 additions and 156 deletions
+1 -1
View File
@@ -3,7 +3,7 @@
#include "project/undo.h"
CheckboxEx::CheckboxEx(QWidget* parent) : QCheckBox(parent) {
connect(this, SIGNAL(clicked(bool)), this, SLOT(checkbox_command()));
// connect(this, SIGNAL(clicked(bool)), this, SLOT(checkbox_command()));
}
void CheckboxEx::checkbox_command() {
+4 -2
View File
@@ -29,8 +29,10 @@ void ColorButton::open_dialog() {
QColor old_color = color;
QColor new_color = QColorDialog::getColor(color, NULL);
if (new_color.isValid() && old_color != new_color) {
ColorCommand* command = new ColorCommand(this, old_color, new_color);
undo_stack.push(command);
ColorCommand* command = new ColorCommand(this, old_color, new_color);
// undo_stack.push(command);
command->redo();
delete command;
set_button_color();
+1 -1
View File
@@ -45,7 +45,7 @@ void ComboBoxEx::setCurrentTextEx(const QString &text) {
void ComboBoxEx::index_changed(int i) {
if (index != i) {
undo_stack.push(new ComboBoxExCommand(this, index, i));
// undo_stack.push(new ComboBoxExCommand(this, index, i));
index = i;
}
}
+117 -22
View File
@@ -7,6 +7,9 @@
#include "project/clip.h"
#include "panels/timeline.h"
#include "ui/timelineheader.h"
#include "project/undo.h"
#include "panels/viewer.h"
#include "ui/viewerwidget.h"
#include <QLabel>
#include <QMouseEvent>
@@ -14,7 +17,11 @@
#define KEYFRAME_SIZE 6
#define KEYFRAME_POINT_COUNT 4
KeyframeView::KeyframeView(QWidget *parent) : QWidget(parent), mousedown(false), visible_in(0), visible_out(0) {
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);
}
KeyframeView::KeyframeView(QWidget *parent) : QWidget(parent), mousedown(false), dragging(false), keys_selected(false), select_rect(false), visible_in(0), visible_out(0) {
setFocusPolicy(Qt::ClickFocus);
setMouseTracking(true);
}
@@ -39,15 +46,10 @@ void KeyframeView::paintEvent(QPaintEvent*) {
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();
for (int k=0;k<row->keyframe_times.size();k++) {
bool keyframe_selected = false;
for (int l=0;l<selected_rows.size();l++) {
if (selected_rows.at(l) == rows.size() && selected_keyframes.at(l) == k) {
keyframe_selected = true;
break;
}
}
draw_keyframe(p, getScreenPointFromFrame(panel_effect_controls->zoom, row->keyframe_times.at(k)-row->parent_effect->parent_clip->clip_in+(row->parent_effect->parent_clip->timeline_in-visible_in)), keyframe_y, keyframe_selected);
bool keyframe_selected = keyframeIsSelected(row, k);
long keyframe_frame = adjust_row_keyframe(row, row->keyframe_times.at(k));
if (dragging && keyframe_selected) keyframe_frame += frame_diff;
draw_keyframe(p, getScreenPointFromFrame(panel_effect_controls->zoom, keyframe_frame), keyframe_y, keyframe_selected);
}
rows.append(row);
@@ -62,11 +64,43 @@ void KeyframeView::paintEvent(QPaintEvent*) {
p.drawLine(playhead_x, 0, playhead_x, height());
}
if (select_rect) {
draw_selection_rectangle(p, QRect(rect_select_x, rect_select_y, rect_select_w, rect_select_h));
}
/*if (mouseover && mouseover_row < rowY.size()) {
draw_keyframe(p, getScreenPointFromFrame(panel_effect_controls->zoom, mouseover_frame - visible_in), rowY.at(mouseover_row), true);
}*/
}
bool KeyframeView::keyframeIsSelected(EffectRow *row, int keyframe) {
for (int i=0;i<selected_rows.size();i++) {
if (selected_rows.at(i) == row && selected_keyframes.at(i) == keyframe) {
return true;
}
}
return false;
}
void KeyframeView::delete_selected_keyframes() {
KeyframeDelete* kd = new KeyframeDelete();
bool del = false;
for (int i=0;i<selected_keyframes.size();i++) {
selected_rows.at(i)->delete_keyframe(kd, selected_keyframes.at(i));
del = true;
}
if (del) {
undo_stack.push(kd);
selected_keyframes.clear();
selected_rows.clear();
update();
panel_viewer->viewer_widget->update();
} else {
delete kd;
}
}
void KeyframeView::draw_keyframe(QPainter &p, int x, int y, bool darker) {
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)};
int color = (darker) ? 100 : 160;
@@ -80,7 +114,7 @@ void KeyframeView::mousePressEvent(QMouseEvent *event) {
int keyframe_index = -1;
long frame_diff = 0;
long frame_min = getFrameFromScreenPoint(panel_effect_controls->zoom, event->x()-KEYFRAME_SIZE);
long frame_mid = getFrameFromScreenPoint(panel_effect_controls->zoom, event->x());
drag_frame_start = getFrameFromScreenPoint(panel_effect_controls->zoom, event->x());
long frame_max = getFrameFromScreenPoint(panel_effect_controls->zoom, event->x()+KEYFRAME_SIZE);
for (int i=0;i<rowY.size();i++) {
if (event->y() > rowY.at(i)-KEYFRAME_SIZE-KEYFRAME_SIZE && event->y() < rowY.at(i)+KEYFRAME_SIZE+KEYFRAME_SIZE) {
@@ -88,7 +122,7 @@ void KeyframeView::mousePressEvent(QMouseEvent *event) {
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) {
long eval_frame_diff = qAbs(eval_keyframe_time - frame_mid);
long eval_frame_diff = qAbs(eval_keyframe_time - drag_frame_start);
if (keyframe_index == -1 || eval_frame_diff < frame_diff) {
row_index = i;
keyframe_index = j;
@@ -100,24 +134,26 @@ void KeyframeView::mousePressEvent(QMouseEvent *event) {
}
}
bool already_selected = false;
if (keyframe_index > -1) {
for (int i=0;i<selected_rows.size();i++) {
if (selected_rows.at(i) == row_index && selected_keyframes.at(i) == keyframe_index) {
already_selected = true;
}
}
}
keys_selected = false;
if (keyframe_index > -1) already_selected = keyframeIsSelected(rows.at(row_index), keyframe_index);
if (!already_selected) {
if (!(event->modifiers() & Qt::ShiftModifier)) {
selected_rows.clear();
selected_keyframes.clear();
}
if (keyframe_index > -1) {
selected_rows.append(row_index);
selected_rows.append(rows.at(row_index));
selected_keyframes.append(keyframe_index);
}
}
if (selected_rows.size() > 0) {
keys_selected = true;
} else {
rect_select_x = event->x();
rect_select_y = event->y();
}
update();
mousedown = true;
}
@@ -138,11 +174,70 @@ void KeyframeView::mouseMoveEvent(QMouseEvent* event) {
update();
}
mouseover = new_mo;*/
if (mousedown) {
if (mousedown) {
if (keys_selected) {
frame_diff = getFrameFromScreenPoint(panel_effect_controls->zoom, event->x()) - drag_frame_start;
// validate frame_diff
for (int i=0;i<selected_keyframes.size();i++) {
EffectRow* row = selected_rows.at(i);
long eval_key = row->keyframe_times.at(selected_keyframes.at(i));
for (int j=0;j<row->keyframe_times.size();j++) {
while (!keyframeIsSelected(row, j) && row->keyframe_times.at(j) == eval_key + frame_diff) {
if (last_frame_diff > frame_diff) {
frame_diff++;
} else {
frame_diff--;
}
}
}
}
last_frame_diff = frame_diff;
dragging = true;
} else {
rect_select_w = event->x() - rect_select_x;
rect_select_h = event->y() - rect_select_y;
int min_row = qMin(rect_select_y, event->y())-KEYFRAME_SIZE;
int max_row = qMax(rect_select_y, event->y())+KEYFRAME_SIZE;
long frame_start = getFrameFromScreenPoint(panel_effect_controls->zoom, rect_select_x);
long frame_end = getFrameFromScreenPoint(panel_effect_controls->zoom, event->x());
long min_frame = qMin(frame_start, frame_end)-KEYFRAME_SIZE;
long max_frame = qMax(frame_start, frame_end)+KEYFRAME_SIZE;
for (int i=0;i<rowY.size();i++) {
if (rowY.at(i) >= min_row && rowY.at(i) <= max_row) {
EffectRow* row = rows.at(i);
for (int j=0;j<row->keyframe_times.size();j++) {
long keyframe_frame = adjust_row_keyframe(row, row->keyframe_times.at(j));
if (!keyframeIsSelected(row, j) && keyframe_frame >= min_frame && keyframe_frame <= max_frame) {
selected_rows.append(rows.at(i));
selected_keyframes.append(j);
}
}
}
}
select_rect = true;
}
update();
}
}
void KeyframeView::mouseReleaseEvent(QMouseEvent* event) {
void KeyframeView::mouseReleaseEvent(QMouseEvent*) {
if (dragging && frame_diff != 0) {
KeyframeMove* ka = new KeyframeMove();
ka->movement = frame_diff;
ka->keyframes = selected_keyframes;
ka->rows = selected_rows;
undo_stack.push(ka);
}
select_rect = false;
dragging = false;
mousedown = false;
update();
}
+16 -3
View File
@@ -15,14 +15,18 @@ public:
KeyframeView(QWidget* parent = 0);
QVector<Effect*> effects;
void delete_selected_keyframes();
TimelineHeader* header;
long visible_in;
long visible_out;
private:
QVector<int> selected_rows;
long adjust_row_keyframe(EffectRow* row, long time);
QVector<EffectRow*> selected_rows;
QVector<int> selected_keyframes;
QVector<int> rowY;
long frame_diff;
QVector<EffectRow*> rows;
void mousePressEvent(QMouseEvent* event);
void mouseMoveEvent(QMouseEvent* event);
@@ -30,9 +34,18 @@ private:
void paintEvent(QPaintEvent *event);
void draw_keyframe(QPainter& p, int x, int y, bool darker);
bool mousedown;
bool dragging;
bool keys_selected;
bool select_rect;
int drag_row_index;
int drag_keyframe_index;
bool keyframeIsSelected(EffectRow* row, int keyframe);
long drag_frame_start;
long last_frame_diff;
int rect_select_x;
int rect_select_y;
int rect_select_w;
int rect_select_h;
};
#endif // KEYFRAMEVIEW_H
+14 -24
View File
@@ -8,6 +8,7 @@
LabelSlider::LabelSlider(QWidget* parent) : QLabel(parent) {
drag_start = false;
drag_proc = false;
min_enabled = false;
max_enabled = false;
setStyleSheet("QLabel{color:#ffc000;text-decoration:underline;}QLabel:disabled{color:#808080;}");
@@ -38,6 +39,10 @@ bool LabelSlider::is_set() {
return set;
}
bool LabelSlider::is_dragging() {
return drag_proc;
}
double LabelSlider::value() {
return internal_value;
}
@@ -60,18 +65,16 @@ void LabelSlider::set_maximum_value(double v) {
max_enabled = true;
}
void LabelSlider::mousePressEvent(QMouseEvent *ev) {
if (ev->modifiers() & Qt::AltModifier) {
ValueChangeCommand* vcc = new ValueChangeCommand();
vcc->source = this;
vcc->old_val = internal_value;
vcc->new_val = default_value;
undo_stack.push(vcc);
double LabelSlider::get_drag_start_value() {
return drag_start_value;
}
void LabelSlider::mousePressEvent(QMouseEvent *ev) {
drag_start_value = internal_value;
if (ev->modifiers() & Qt::AltModifier) {
set_value(default_value, true);
} else {
qApp->setOverrideCursor(Qt::BlankCursor);
drag_start_value = internal_value;
drag_start = true;
drag_start_x = cursor().pos().x();
drag_start_y = cursor().pos().y();
@@ -80,9 +83,9 @@ void LabelSlider::mousePressEvent(QMouseEvent *ev) {
void LabelSlider::mouseMoveEvent(QMouseEvent*) {
if (drag_start) {
drag_proc = true;
set_value(internal_value + (cursor().pos().x()-drag_start_x) + (drag_start_y-cursor().pos().y()), true);
cursor().setPos(drag_start_x, drag_start_y);
drag_proc = true;
}
}
@@ -91,25 +94,12 @@ void LabelSlider::mouseReleaseEvent(QMouseEvent*) {
qApp->restoreOverrideCursor();
drag_start = false;
if (drag_proc) {
// send undo event
ValueChangeCommand* vcc = new ValueChangeCommand();
vcc->source = this;
vcc->old_val = drag_start_value;
vcc->new_val = internal_value;
undo_stack.push(vcc);
drag_proc = false;
drag_proc = false;
emit valueChanged();
} else {
double d = QInputDialog::getDouble(this, "Set Value", "New value:", internal_value);
if (d != internal_value) {
ValueChangeCommand* vcc = new ValueChangeCommand();
vcc->source = this;
vcc->old_val = internal_value;
set_value(d, true);
vcc->new_val = internal_value;
undo_stack.push(vcc);
}
}
}
+3 -1
View File
@@ -15,6 +15,8 @@ public:
void set_maximum_value(double v);
double value();
bool is_set();
double get_drag_start_value();
bool is_dragging();
protected:
void mousePressEvent(QMouseEvent *ev);
void mouseMoveEvent(QMouseEvent *ev);
@@ -36,7 +38,7 @@ private:
bool set;
signals:
void valueChanged();
void valueChanged();
};
#endif // LABELSLIDER_H
+2 -4
View File
@@ -1793,10 +1793,8 @@ void TimelineWidget::paintEvent(QPaintEvent*) {
if (bottom_align) {
rsy += height();
}
QRect rect_select(panel_timeline->rect_select_x, rsy, panel_timeline->rect_select_w, rsh);
p.setPen(QColor(204, 204, 204));
p.drawRect(rect_select);
p.fillRect(rect_select, QColor(0, 0, 0, 32));
QRect rect_select(panel_timeline->rect_select_x, rsy, panel_timeline->rect_select_w, rsh);
draw_selection_rectangle(p, rect_select);
}
// Draw ghosts