more keyframe improvements
This commit is contained in:
+63
-33
@@ -339,14 +339,14 @@ EffectField::EffectField(EffectRow *parent, int t) : parent_row(parent), type(t)
|
||||
{
|
||||
ComboBoxEx* cb = new ComboBoxEx();
|
||||
ui_element = cb;
|
||||
connect(cb, SIGNAL(currentIndexChanged(int)), this, SLOT(uiElementChange()));
|
||||
connect(cb, SIGNAL(activated(int)), this, SLOT(uiElementChange()));
|
||||
}
|
||||
break;
|
||||
case EFFECT_FIELD_FONT:
|
||||
{
|
||||
FontCombobox* fcb = new FontCombobox();
|
||||
ui_element = fcb;
|
||||
connect(fcb, SIGNAL(currentIndexChanged(int)), this, SLOT(uiElementChange()));
|
||||
connect(fcb, SIGNAL(activated(int)), this, SLOT(uiElementChange()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -414,6 +414,59 @@ void EffectField::get_keyframe_data(long frame, int* before, int* after, double*
|
||||
}
|
||||
}
|
||||
|
||||
void EffectField::validate_keyframe_data(long frame) {
|
||||
if (parent_row->keyframing) {
|
||||
int before_keyframe;
|
||||
int after_keyframe;
|
||||
double progress;
|
||||
get_keyframe_data(frame, &before_keyframe, &after_keyframe, &progress);
|
||||
|
||||
const QVariant& before_data = keyframe_data.at(before_keyframe);
|
||||
switch (type) {
|
||||
case EFFECT_FIELD_DOUBLE:
|
||||
{
|
||||
double value;
|
||||
if (before_keyframe == after_keyframe) {
|
||||
value = keyframe_data.at(before_keyframe).toDouble();
|
||||
} else {
|
||||
double before_dbl = keyframe_data.at(before_keyframe).toDouble();
|
||||
double after_dbl = keyframe_data.at(after_keyframe).toDouble();
|
||||
value = double_lerp(before_dbl, after_dbl, progress);
|
||||
}
|
||||
static_cast<LabelSlider*>(ui_element)->set_value(value, false);
|
||||
}
|
||||
break;
|
||||
case EFFECT_FIELD_COLOR:
|
||||
{
|
||||
QColor value;
|
||||
if (before_keyframe == after_keyframe) {
|
||||
value = keyframe_data.at(before_keyframe).value<QColor>();
|
||||
} else {
|
||||
QColor before_data = keyframe_data.at(before_keyframe).value<QColor>();
|
||||
QColor after_data = keyframe_data.at(after_keyframe).value<QColor>();
|
||||
value = QColor(lerp(before_data.red(), after_data.red(), progress), lerp(before_data.green(), after_data.green(), progress), lerp(before_data.blue(), after_data.blue(), progress));
|
||||
}
|
||||
return static_cast<ColorButton*>(ui_element)->set_color(value);
|
||||
}
|
||||
break;
|
||||
case EFFECT_FIELD_STRING:
|
||||
static_cast<QTextEdit*>(ui_element)->setPlainText(before_data.toString());
|
||||
break;
|
||||
case EFFECT_FIELD_BOOL:
|
||||
static_cast<QCheckBox*>(ui_element)->setChecked(before_data.toBool());
|
||||
break;
|
||||
case EFFECT_FIELD_COMBO:
|
||||
static_cast<ComboBoxEx*>(ui_element)->setCurrentIndexEx(before_data.toInt());
|
||||
break;
|
||||
case EFFECT_FIELD_FONT:
|
||||
static_cast<FontCombobox*>(ui_element)->setCurrentTextEx(before_data.toString());
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void EffectField::uiElementChange() {
|
||||
if (parent_row->keyframing) {
|
||||
parent_row->set_keyframe_now();
|
||||
@@ -430,24 +483,8 @@ void EffectField::set_enabled(bool e) {
|
||||
}
|
||||
|
||||
double EffectField::get_double_value(long p) {
|
||||
if (parent_row->keyframing) {
|
||||
int before_keyframe;
|
||||
int after_keyframe;
|
||||
double progress;
|
||||
get_keyframe_data(p, &before_keyframe, &after_keyframe, &progress);
|
||||
double value;
|
||||
if (before_keyframe == after_keyframe) {
|
||||
value = keyframe_data.at(before_keyframe).toDouble();
|
||||
} else {
|
||||
double before_data = keyframe_data.at(before_keyframe).toDouble();
|
||||
double after_data = keyframe_data.at(after_keyframe).toDouble();
|
||||
value = double_lerp(before_data, after_data, progress);
|
||||
}
|
||||
static_cast<LabelSlider*>(ui_element)->set_value(value, false);
|
||||
return value;
|
||||
} else {
|
||||
validate_keyframe_data(p);
|
||||
return static_cast<LabelSlider*>(ui_element)->value();
|
||||
}
|
||||
}
|
||||
|
||||
void EffectField::set_double_value(double v) {
|
||||
@@ -471,14 +508,17 @@ void EffectField::add_combo_item(const QString& name, const QVariant& data) {
|
||||
}
|
||||
|
||||
int EffectField::get_combo_index(long p) {
|
||||
validate_keyframe_data(p);
|
||||
return static_cast<ComboBoxEx*>(ui_element)->currentIndex();
|
||||
}
|
||||
|
||||
const QVariant EffectField::get_combo_data(long p) {
|
||||
validate_keyframe_data(p);
|
||||
return static_cast<ComboBoxEx*>(ui_element)->currentData();
|
||||
}
|
||||
|
||||
const QString EffectField::get_combo_string(long p) {
|
||||
validate_keyframe_data(p);
|
||||
return static_cast<ComboBoxEx*>(ui_element)->currentText();
|
||||
}
|
||||
|
||||
@@ -491,6 +531,7 @@ void EffectField::set_combo_string(const QString& s) {
|
||||
}
|
||||
|
||||
bool EffectField::get_bool_value(long p) {
|
||||
validate_keyframe_data(p);
|
||||
return static_cast<QCheckBox*>(ui_element)->isChecked();
|
||||
}
|
||||
|
||||
@@ -499,6 +540,7 @@ void EffectField::set_bool_value(bool b) {
|
||||
}
|
||||
|
||||
const QString EffectField::get_string_value(long p) {
|
||||
validate_keyframe_data(p);
|
||||
return static_cast<QTextEdit*>(ui_element)->toPlainText();
|
||||
}
|
||||
|
||||
@@ -507,6 +549,7 @@ void EffectField::set_string_value(const QString& s) {
|
||||
}
|
||||
|
||||
const QString EffectField::get_font_name(long p) {
|
||||
validate_keyframe_data(p);
|
||||
return static_cast<FontCombobox*>(ui_element)->currentText();
|
||||
}
|
||||
|
||||
@@ -515,20 +558,7 @@ void EffectField::set_font_name(const QString& s) {
|
||||
}
|
||||
|
||||
QColor EffectField::get_color_value(long p) {
|
||||
if (parent_row->keyframing) {
|
||||
int before_keyframe;
|
||||
int after_keyframe;
|
||||
double progress;
|
||||
get_keyframe_data(p, &before_keyframe, &after_keyframe, &progress);
|
||||
if (before_keyframe == after_keyframe) {
|
||||
return keyframe_data.at(before_keyframe).value<QColor>();
|
||||
} else {
|
||||
QColor before_data = keyframe_data.at(before_keyframe).value<QColor>();
|
||||
QColor after_data = keyframe_data.at(after_keyframe).value<QColor>();
|
||||
return QColor(lerp(before_data.red(), after_data.red(), progress), lerp(before_data.green(), after_data.green(), progress), lerp(before_data.blue(), after_data.blue(), progress));
|
||||
}
|
||||
}
|
||||
|
||||
validate_keyframe_data(p);
|
||||
return static_cast<ColorButton*>(ui_element)->get_color();
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ public:
|
||||
QVariant get_current_data();
|
||||
void set_keyframe_data(int i);
|
||||
void get_keyframe_data(long frame, int* before, int *after, double* d);
|
||||
void validate_keyframe_data(long frame);
|
||||
// QVariant get_keyframe_data(long p);
|
||||
// bool is_keyframed(long p);
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ void cache_clip(Clip* clip, long playhead, bool write_A, bool write_B, bool rese
|
||||
}
|
||||
}
|
||||
|
||||
void get_clip_frame(Clip* c, long playhead) {
|
||||
bool get_clip_frame(Clip* c, long playhead) {
|
||||
if (c->open) {
|
||||
long sequence_clip_time = playhead - c->timeline_in + c->clip_in;
|
||||
long clip_time = refactor_frame_number(sequence_clip_time, c->sequence->frame_rate, av_q2d(av_guess_frame_rate(c->formatCtx, c->stream, c->frame)));
|
||||
@@ -176,12 +176,15 @@ void get_clip_frame(Clip* c, long playhead) {
|
||||
|
||||
c->texture->setData(0, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, c->comp_frame);
|
||||
c->texture_frame = clip_time;
|
||||
|
||||
return true;
|
||||
} else if (!no_frame) {
|
||||
texture_failed = true;
|
||||
qDebug() << "[ERROR] Failed to retrieve frame from cache (R:" << clip_time << "| A:" << c->cache_A.offset << "-" << c->cache_A.offset+c->cache_size-1 << "| B:" << c->cache_B.offset << "-" << c->cache_B.offset+c->cache_size-1 << "| WA:" << c->cache_A.written << "| WB:" << c->cache_B.written << ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
double playhead_to_seconds(Clip* c, long playhead) {
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ void cache_audio_worker(Clip* c, bool write_A);
|
||||
void cache_video_worker(Clip* c, long playhead, ClipCache* cache);
|
||||
void handle_media(Sequence* sequence, long playhead, bool multithreaded);
|
||||
void reset_cache(Clip* c, long target_frame);
|
||||
void get_clip_frame(Clip* c, long playhead);
|
||||
bool get_clip_frame(Clip* c, long playhead);
|
||||
double playhead_to_seconds(Clip* c, long playhead);
|
||||
long seconds_to_clip_frame(Clip* c, double seconds);
|
||||
double clip_frame_to_seconds(Clip* c, long clip_frame);
|
||||
|
||||
+65
-10
@@ -13,7 +13,7 @@
|
||||
#define KEYFRAME_SIZE 6
|
||||
#define KEYFRAME_POINT_COUNT 4
|
||||
|
||||
KeyframeView::KeyframeView(QWidget *parent) : QWidget(parent), mouseover(false), visible_in(0), visible_out(0) {
|
||||
KeyframeView::KeyframeView(QWidget *parent) : QWidget(parent), mousedown(false), visible_in(0), visible_out(0) {
|
||||
setFocusPolicy(Qt::ClickFocus);
|
||||
setMouseTracking(true);
|
||||
}
|
||||
@@ -36,7 +36,16 @@ 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++) {
|
||||
draw_keyframe(p, getScreenPointFromFrame(panel_effect_controls->zoom, row->keyframe_times.at(k)), keyframe_y, false);
|
||||
bool keyframe_selected = false;
|
||||
for (int l=0;l<selected_rows.size();l++) {
|
||||
// qDebug() << selected_rows.at(l) << rows.size() << selected_keyframes.at(l) << k;
|
||||
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);
|
||||
}
|
||||
|
||||
rows.append(row);
|
||||
@@ -51,21 +60,64 @@ void KeyframeView::paintEvent(QPaintEvent*) {
|
||||
p.drawLine(playhead_x, 0, playhead_x, height());
|
||||
}
|
||||
|
||||
if (mouseover && mouseover_row < rowY.size()) {
|
||||
/*if (mouseover && mouseover_row < rowY.size()) {
|
||||
draw_keyframe(p, getScreenPointFromFrame(panel_effect_controls->zoom, mouseover_frame - visible_in), rowY.at(mouseover_row), true);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
void KeyframeView::draw_keyframe(QPainter &p, int x, int y, bool semiTransparent) {
|
||||
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 alpha = (semiTransparent) ? 128 : 255;
|
||||
p.setPen(QColor(0, 0, 0, alpha));
|
||||
p.setBrush(QColor(160, 160, 160, alpha));
|
||||
int color = (darker) ? 100 : 160;
|
||||
p.setPen(QColor(0, 0, 0));
|
||||
p.setBrush(QColor(color, color, color));
|
||||
p.drawPolygon(points, KEYFRAME_POINT_COUNT);
|
||||
}
|
||||
|
||||
void KeyframeView::mousePressEvent(QMouseEvent *event) {
|
||||
qDebug() << "create keyframe @ clip frame" << mouseover_frame - visible_in + (rows.at(mouseover_row)->parent_effect->parent_clip->clip_in) << "effect row" << mouseover_row;
|
||||
int row_index = -1;
|
||||
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());
|
||||
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) {
|
||||
EffectRow* row = rows.at(i);
|
||||
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);
|
||||
if (keyframe_index == -1 || eval_frame_diff < frame_diff) {
|
||||
row_index = i;
|
||||
keyframe_index = j;
|
||||
frame_diff = eval_frame_diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!already_selected) {
|
||||
if (!(event->modifiers() & Qt::ShiftModifier)) {
|
||||
selected_rows.clear();
|
||||
selected_keyframes.clear();
|
||||
}
|
||||
if (keyframe_index > -1) {
|
||||
selected_rows.append(row_index);
|
||||
selected_keyframes.append(keyframe_index);
|
||||
}
|
||||
}
|
||||
|
||||
update();
|
||||
mousedown = true;
|
||||
}
|
||||
|
||||
void KeyframeView::mouseMoveEvent(QMouseEvent* event) {
|
||||
@@ -84,8 +136,11 @@ void KeyframeView::mouseMoveEvent(QMouseEvent* event) {
|
||||
update();
|
||||
}
|
||||
mouseover = new_mo;*/
|
||||
if (mousedown) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void KeyframeView::mouseReleaseEvent(QMouseEvent* event) {
|
||||
|
||||
mousedown = false;
|
||||
}
|
||||
|
||||
+7
-5
@@ -17,17 +17,19 @@ public:
|
||||
long visible_in;
|
||||
long visible_out;
|
||||
private:
|
||||
QVector<int> selected_rows;
|
||||
QVector<int> selected_keyframes;
|
||||
QVector<int> rowY;
|
||||
QVector<EffectRow*> rows;
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
void mouseMoveEvent(QMouseEvent* event);
|
||||
void mouseReleaseEvent(QMouseEvent *event);
|
||||
void paintEvent(QPaintEvent *event);
|
||||
void draw_keyframe(QPainter& p, int x, int y, bool semiTransparent);
|
||||
bool enable_reload;
|
||||
bool mouseover;
|
||||
long mouseover_frame;
|
||||
int mouseover_row;
|
||||
void draw_keyframe(QPainter& p, int x, int y, bool darker);
|
||||
bool mousedown;
|
||||
|
||||
int drag_row_index;
|
||||
int drag_keyframe_index;
|
||||
};
|
||||
|
||||
#endif // KEYFRAMEVIEW_H
|
||||
|
||||
Reference in New Issue
Block a user