made all keyframes editable and undoable
This commit is contained in:
@@ -6,18 +6,18 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>220</height>
|
||||
<width>358</width>
|
||||
<height>422</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
<string>About Olive</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Olive is a non-linear video editor. This software is free and protected by the GNU GPL.</string>
|
||||
<string><html><head/><body><p><img src=":/icons/olive-splash.png"/></p><p><a href="https://www.olivevideoeditor.org/"><span style=" text-decoration: underline; color:#007af4;">https://www.olivevideoeditor.org/</span></a></p><p>Olive is a non-linear video editor. This software is free and protected by the GNU GPL.</p><p>Olive Team is obliged to inform users that Olive source code is available for download from its website.</p><p>Olive uses (at least) the following libraries in accordance with the GNU GPL/LGPL:</p><p>Qt, FFmpeg, libass, libfreetype, libmp3lame, libopenjpeg, libopus, libtheora, libtwolame, libvpx, libwavpack, libwebp, libx264, libx265, lzma, bzlib, zlib, libvidstab, libvorbis.</p></body></html></string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
|
||||
+91
-61
@@ -29,6 +29,7 @@
|
||||
#include <QTextEdit>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QMessageBox>
|
||||
|
||||
QVector<QString> video_effect_names;
|
||||
QVector<QString> audio_effect_names;
|
||||
@@ -101,7 +102,7 @@ Effect::~Effect() {
|
||||
void Effect::copy_field_keyframes(Effect* e) {
|
||||
for (int i=0;i<rows.size();i++) {
|
||||
EffectRow* row = rows.at(i);
|
||||
e->rows.at(i)->keyframing = rows.at(i)->keyframing;
|
||||
e->rows.at(i)->setKeyframing(rows.at(i)->isKeyframing());
|
||||
e->rows.at(i)->keyframe_times = rows.at(i)->keyframe_times;
|
||||
e->rows.at(i)->keyframe_types = rows.at(i)->keyframe_types;
|
||||
for (int j=0;j<row->fieldCount();j++) {
|
||||
@@ -178,11 +179,11 @@ void Effect::load(QXmlStreamReader& stream) {
|
||||
for (int k=0;k<stream.attributes().size();k++) {
|
||||
const QXmlStreamAttribute& attr = stream.attributes().at(k);
|
||||
if (attr.name() == "enabled") {
|
||||
row->keyframing = (attr.value() == "1");
|
||||
row->setKeyframing(attr.value() == "1");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (row->keyframing) {
|
||||
if (row->isKeyframing()) {
|
||||
stream.readNext();
|
||||
while (!stream.atEnd() && !(stream.name() == "keyframes" && stream.isEndElement())) {
|
||||
if (stream.name() == "key" && stream.isStartElement()) {
|
||||
@@ -248,7 +249,7 @@ void Effect::save(QXmlStreamWriter& stream) {
|
||||
EffectRow* row = rows.at(i);
|
||||
stream.writeStartElement("row"); // row
|
||||
stream.writeStartElement("keyframes"); // keyframes
|
||||
stream.writeAttribute("enabled", QString::number(row->keyframing));
|
||||
stream.writeAttribute("enabled", QString::number(row->isKeyframing()));
|
||||
for (int j=0;j<row->keyframe_times.size();j++) {
|
||||
stream.writeStartElement("key"); // key
|
||||
stream.writeAttribute("frame", QString::number(row->keyframe_times.at(j)));
|
||||
@@ -286,20 +287,44 @@ EffectRow::EffectRow(Effect *parent, QGridLayout *uilayout, const QString &n, in
|
||||
keyframing(false),
|
||||
ui(uilayout),
|
||||
name(n),
|
||||
ui_row(row)
|
||||
ui_row(row),
|
||||
just_made_unsafe_keyframe(false)
|
||||
{
|
||||
label = new QLabel(name);
|
||||
ui->addWidget(label, row, 0);
|
||||
|
||||
// DEBUG STARTS
|
||||
QPushButton* nkf = new QPushButton();
|
||||
nkf->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);
|
||||
connect(nkf, SIGNAL(clicked(bool)), this, SLOT(set_keyframe_now()));
|
||||
ui->addWidget(nkf, row, 5);
|
||||
// DEBUG ENDS
|
||||
/*keyframe_enable = new CheckboxEx();
|
||||
keyframe_enable = new CheckboxEx();
|
||||
keyframe_enable->setToolTip("Enable Keyframes");
|
||||
ui->addWidget(keyframe_enable, row, 5);*/
|
||||
connect(keyframe_enable, SIGNAL(clicked(bool)), this, SLOT(set_keyframe_enabled(bool)));
|
||||
ui->addWidget(keyframe_enable, row, 6);
|
||||
}
|
||||
|
||||
bool EffectRow::isKeyframing() {
|
||||
return keyframing;
|
||||
}
|
||||
|
||||
void EffectRow::setKeyframing(bool b) {
|
||||
keyframing = b;
|
||||
keyframe_enable->setChecked(b);
|
||||
}
|
||||
|
||||
void EffectRow::set_keyframe_enabled(bool enabled) {
|
||||
if (enabled) {
|
||||
set_keyframe_now(true);
|
||||
} else {
|
||||
if (QMessageBox::question(panel_effect_controls, "Disable Keyframes", "Disabling keyframes will delete all current keyframes. Are you sure you want to do this?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
|
||||
// clear
|
||||
KeyframeDelete* kd = new KeyframeDelete();
|
||||
for (int i=keyframe_times.size()-1;i>=0;i--) {
|
||||
delete_keyframe(kd, i);
|
||||
}
|
||||
kd->disable_keyframes_on_row = this;
|
||||
undo_stack.push(kd);
|
||||
panel_effect_controls->update_keyframes();
|
||||
} else {
|
||||
setKeyframing(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EffectField* EffectRow::add_field(int type, int colspan) {
|
||||
@@ -316,27 +341,42 @@ EffectRow::~EffectRow() {
|
||||
}
|
||||
}
|
||||
|
||||
void EffectRow::set_keyframe_now() {
|
||||
set_keyframe(panel_timeline->playhead-parent_effect->parent_clip->timeline_in+parent_effect->parent_clip->clip_in);
|
||||
void EffectRow::set_keyframe_now(bool undoable) {
|
||||
int index = -1;
|
||||
long time = panel_timeline->playhead-parent_effect->parent_clip->timeline_in+parent_effect->parent_clip->clip_in;
|
||||
for (int i=0;i<keyframe_times.size();i++) {
|
||||
if (keyframe_times.at(i) == time) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
KeyframeSet* ks = new KeyframeSet(this, index, time, just_made_unsafe_keyframe);
|
||||
|
||||
if (undoable) {
|
||||
just_made_unsafe_keyframe = false;
|
||||
undo_stack.push(ks);
|
||||
} else {
|
||||
if (index == -1) just_made_unsafe_keyframe = true;
|
||||
ks->redo();
|
||||
delete ks;
|
||||
}
|
||||
|
||||
panel_effect_controls->update_keyframes();
|
||||
}
|
||||
|
||||
void EffectRow::set_keyframe(long time) {
|
||||
keyframing = true;
|
||||
int index = -1;
|
||||
for (int i=0;i<keyframe_times.size();i++) {
|
||||
if (keyframe_times.at(i) == time) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index == -1) {
|
||||
keyframe_times.append(time);
|
||||
keyframe_types.append((keyframe_types.size() > 0) ? keyframe_types.last() : EFFECT_KEYFRAME_LINEAR);
|
||||
}
|
||||
for (int i=0;i<fields.size();i++) {
|
||||
fields.at(i)->set_keyframe_data(index);
|
||||
}
|
||||
panel_effect_controls->update_keyframes();
|
||||
void EffectRow::delete_keyframe_at_time(KeyframeDelete* kd, long time) {
|
||||
for (int i=0;i<keyframe_times.size();i++) {
|
||||
if (keyframe_times.at(i) == time) {
|
||||
delete_keyframe(kd, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EffectRow::delete_keyframe(KeyframeDelete* kd, int index) {
|
||||
kd->rows.append(this);
|
||||
kd->keyframes.append(index);
|
||||
}
|
||||
|
||||
EffectField* EffectRow::field(int i) {
|
||||
@@ -421,15 +461,7 @@ void EffectField::set_current_data(const QVariant& data) {
|
||||
}
|
||||
}
|
||||
|
||||
void EffectField::set_keyframe_data(int i) {
|
||||
if (i == -1) {
|
||||
keyframe_data.append(get_current_data());
|
||||
} else {
|
||||
keyframe_data[i] = get_current_data();
|
||||
}
|
||||
}
|
||||
|
||||
void EffectField::get_keyframe_data(long frame, int* before, int* after, double* progress) {
|
||||
void EffectField::get_keyframe_data(long frame, int &before, int &after, double &progress) {
|
||||
int before_keyframe_index = -1;
|
||||
int after_keyframe_index = -1;
|
||||
long before_keyframe_time = LONG_MIN;
|
||||
@@ -438,8 +470,8 @@ void EffectField::get_keyframe_data(long frame, int* before, int* after, double*
|
||||
for (int i=0;i<parent_row->keyframe_times.size();i++) {
|
||||
long eval_keyframe_time = parent_row->keyframe_times.at(i);
|
||||
if (eval_keyframe_time == frame) {
|
||||
*before = i;
|
||||
*after = i;
|
||||
before = i;
|
||||
after = i;
|
||||
return;
|
||||
} else if (eval_keyframe_time < frame && eval_keyframe_time > before_keyframe_time) {
|
||||
before_keyframe_index = i;
|
||||
@@ -448,40 +480,40 @@ void EffectField::get_keyframe_data(long frame, int* before, int* after, double*
|
||||
after_keyframe_index = i;
|
||||
after_keyframe_time = eval_keyframe_time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type == EFFECT_FIELD_DOUBLE || type == EFFECT_FIELD_COLOR) {
|
||||
if (before_keyframe_index > -1 && after_keyframe_index > -1) {
|
||||
// interpolate
|
||||
*before = before_keyframe_index;
|
||||
*after = after_keyframe_index;
|
||||
*progress = (double)(frame-before_keyframe_time)/(double)(after_keyframe_time-before_keyframe_time);
|
||||
before = before_keyframe_index;
|
||||
after = after_keyframe_index;
|
||||
progress = (double)(frame-before_keyframe_time)/(double)(after_keyframe_time-before_keyframe_time);
|
||||
|
||||
// TODO routines for bezier - currently this is purely linear
|
||||
} else if (before_keyframe_index > -1) {
|
||||
*before = before_keyframe_index;
|
||||
*after = before_keyframe_index;
|
||||
before = before_keyframe_index;
|
||||
after = before_keyframe_index;
|
||||
} else if (after_keyframe_index > -1) {
|
||||
*before = after_keyframe_index;
|
||||
*after = after_keyframe_index;
|
||||
before = after_keyframe_index;
|
||||
after = after_keyframe_index;
|
||||
}
|
||||
} else {
|
||||
if (before_keyframe_index > -1) {
|
||||
*before = before_keyframe_index;
|
||||
*after = before_keyframe_index;
|
||||
before = before_keyframe_index;
|
||||
after = before_keyframe_index;
|
||||
} else {
|
||||
*before = after_keyframe_time;
|
||||
*after = after_keyframe_time;
|
||||
before = after_keyframe_index;
|
||||
after = after_keyframe_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EffectField::validate_keyframe_data(long frame) {
|
||||
if (parent_row->keyframing) {
|
||||
if (parent_row->isKeyframing()) {
|
||||
int before_keyframe;
|
||||
int after_keyframe;
|
||||
double progress;
|
||||
get_keyframe_data(frame, &before_keyframe, &after_keyframe, &progress);
|
||||
get_keyframe_data(frame, before_keyframe, after_keyframe, progress);
|
||||
|
||||
const QVariant& before_data = keyframe_data.at(before_keyframe);
|
||||
switch (type) {
|
||||
@@ -524,14 +556,12 @@ void EffectField::validate_keyframe_data(long frame) {
|
||||
static_cast<FontCombobox*>(ui_element)->setCurrentTextEx(before_data.toString());
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void EffectField::uiElementChange() {
|
||||
if (parent_row->keyframing) {
|
||||
parent_row->set_keyframe_now();
|
||||
if (parent_row->isKeyframing()) {
|
||||
parent_row->set_keyframe_now(!(type == EFFECT_FIELD_DOUBLE && static_cast<LabelSlider*>(ui_element)->is_dragging()));
|
||||
}
|
||||
emit changed();
|
||||
}
|
||||
|
||||
+15
-10
@@ -17,6 +17,7 @@ class QXmlStreamWriter;
|
||||
class Effect;
|
||||
class EffectRow;
|
||||
class CheckboxEx;
|
||||
class KeyframeDelete;
|
||||
|
||||
enum VideoEffects {
|
||||
VIDEO_TRANSFORM_EFFECT,
|
||||
@@ -81,9 +82,8 @@ public:
|
||||
int type;
|
||||
|
||||
QVariant get_current_data();
|
||||
void set_current_data(const QVariant&);
|
||||
void set_keyframe_data(int i);
|
||||
void get_keyframe_data(long frame, int* before, int *after, double* d);
|
||||
void set_current_data(const QVariant&);
|
||||
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);
|
||||
@@ -116,8 +116,8 @@ public:
|
||||
QWidget* get_ui_element();
|
||||
void set_enabled(bool e);
|
||||
QVector<QVariant> keyframe_data;
|
||||
QWidget* ui_element;
|
||||
private:
|
||||
QWidget* ui_element;
|
||||
private slots:
|
||||
void uiElementChange();
|
||||
signals:
|
||||
@@ -133,24 +133,29 @@ public:
|
||||
EffectField* add_field(int type, int colspan = 1);
|
||||
EffectField* field(int i);
|
||||
int fieldCount();
|
||||
void set_keyframe(long time);
|
||||
void move_keyframe(long from, long to);
|
||||
void delete_keyframe(long time);
|
||||
void set_keyframe_now(bool undoable);
|
||||
void delete_keyframe(KeyframeDelete *kd, int index);
|
||||
void delete_keyframe_at_time(KeyframeDelete* kd, long time);
|
||||
QLabel* label;
|
||||
Effect* parent_effect;
|
||||
|
||||
bool keyframing;
|
||||
bool isKeyframing();
|
||||
void setKeyframing(bool);
|
||||
|
||||
QVector<long> keyframe_times;
|
||||
QVector<int> keyframe_types;
|
||||
public slots:
|
||||
void set_keyframe_now();
|
||||
private slots:
|
||||
void set_keyframe_enabled(bool);
|
||||
private:
|
||||
bool keyframing;
|
||||
QGridLayout* ui;
|
||||
QString name;
|
||||
int ui_row;
|
||||
QVector<EffectField*> fields;
|
||||
|
||||
CheckboxEx* keyframe_enable;
|
||||
|
||||
bool just_made_unsafe_keyframe;
|
||||
};
|
||||
|
||||
class Effect : public QObject {
|
||||
|
||||
@@ -49,7 +49,7 @@ void ShakeEffect::refresh() {
|
||||
}
|
||||
}
|
||||
|
||||
void ShakeEffect::process_gl(long frame, QOpenGLShaderProgram& shaders, GLTextureCoords& coords) {
|
||||
void ShakeEffect::process_gl(long frame, QOpenGLShaderProgram&, GLTextureCoords&) {
|
||||
if (shake_progress > shake_limit) {
|
||||
double ival = intensity_val->get_double_value(frame);
|
||||
if ((int)ival > 0) {
|
||||
|
||||
@@ -128,14 +128,14 @@ void TransformEffect::process_gl(long frame, QOpenGLShaderProgram&, GLTextureCoo
|
||||
// anchor point
|
||||
int anchor_x_offset = (anchor_x_box->get_double_value(frame)-default_anchor_x);
|
||||
int anchor_y_offset = (anchor_y_box->get_double_value(frame)-default_anchor_y);
|
||||
coords.vertexTopLeftX += anchor_x_offset;
|
||||
coords.vertexTopRightX += anchor_x_offset;
|
||||
coords.vertexBottomLeftX += anchor_x_offset;
|
||||
coords.vertexBottomRightX += anchor_x_offset;
|
||||
coords.vertexTopLeftY += anchor_y_offset;
|
||||
coords.vertexTopRightY += anchor_y_offset;
|
||||
coords.vertexBottomLeftY += anchor_y_offset;
|
||||
coords.vertexBottomRightY += anchor_y_offset;
|
||||
coords.vertexTopLeftX -= anchor_x_offset;
|
||||
coords.vertexTopRightX -= anchor_x_offset;
|
||||
coords.vertexBottomLeftX -= anchor_x_offset;
|
||||
coords.vertexBottomRightX -= anchor_x_offset;
|
||||
coords.vertexTopLeftY -= anchor_y_offset;
|
||||
coords.vertexTopRightY -= anchor_y_offset;
|
||||
coords.vertexBottomLeftY -= anchor_y_offset;
|
||||
coords.vertexBottomRightY -= anchor_y_offset;
|
||||
|
||||
// rotation
|
||||
glRotatef(rotation->get_double_value(frame), 0, 0, 1);
|
||||
|
||||
@@ -38,5 +38,6 @@
|
||||
<file>zoomout-disabled.png</file>
|
||||
<file>add-transition.png</file>
|
||||
<file>add-effect.png</file>
|
||||
<file>olive-splash.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 8.7 KiB |
+3
-1
@@ -186,7 +186,9 @@ void MainWindow::on_actionDelete_triggered()
|
||||
panel_effect_controls->delete_effects();
|
||||
} else if (panel_project->is_focused()) {
|
||||
panel_project->delete_selected_media();
|
||||
}
|
||||
} else if (panel_effect_controls->keyframe_focus()) {
|
||||
panel_effect_controls->delete_selected_keyframes();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_actionSelect_All_triggered()
|
||||
|
||||
@@ -89,6 +89,10 @@ void EffectControls::update_keyframes() {
|
||||
ui->keyframeView->update();
|
||||
}
|
||||
|
||||
void EffectControls::delete_selected_keyframes() {
|
||||
ui->keyframeView->delete_selected_keyframes();
|
||||
}
|
||||
|
||||
void EffectControls::show_effect_menu(bool video, bool transitions) {
|
||||
video_menu = video;
|
||||
transition_menu = transitions;
|
||||
|
||||
@@ -38,6 +38,7 @@ public:
|
||||
void reload_clips();
|
||||
void set_zoom(bool in);
|
||||
bool keyframe_focus();
|
||||
void delete_selected_keyframes();
|
||||
|
||||
double zoom;
|
||||
public slots:
|
||||
|
||||
@@ -22,12 +22,19 @@
|
||||
#include <QtMath>
|
||||
#include <QGuiApplication>
|
||||
#include <QScreen>
|
||||
#include <QPainter>
|
||||
|
||||
long refactor_frame_number(long framenumber, double source_frame_rate, double target_frame_rate) {
|
||||
if (source_frame_rate == target_frame_rate) return framenumber;
|
||||
return qRound(((double)framenumber/source_frame_rate)*target_frame_rate);
|
||||
}
|
||||
|
||||
void draw_selection_rectangle(QPainter& painter, const QRect& rect) {
|
||||
painter.setPen(QColor(204, 204, 204));
|
||||
painter.setBrush(QColor(0, 0, 0, 32));
|
||||
painter.drawRect(rect);
|
||||
}
|
||||
|
||||
Timeline::Timeline(QWidget *parent) :
|
||||
QDockWidget(parent),
|
||||
playhead(0),
|
||||
|
||||
@@ -24,6 +24,7 @@ int lerp(int a, int b, double t);
|
||||
long refactor_frame_number(long framenumber, double source_frame_rate, double target_frame_rate);
|
||||
int getScreenPointFromFrame(double zoom, long frame);
|
||||
long getFrameFromScreenPoint(double zoom, int x);
|
||||
void draw_selection_rectangle(QPainter& painter, const QRect& rect);
|
||||
|
||||
struct Ghost {
|
||||
int clip;
|
||||
|
||||
+136
-7
@@ -787,17 +787,146 @@ void MediaRename::redo() {
|
||||
project_changed = true;
|
||||
}
|
||||
|
||||
ValueChangeCommand::ValueChangeCommand() : done(true), old_project_changed(project_changed) {}
|
||||
KeyframeMove::KeyframeMove() : old_project_changed(project_changed) {}
|
||||
|
||||
void ValueChangeCommand::undo() {
|
||||
source->set_value(old_val, false);
|
||||
done = false;
|
||||
void KeyframeMove::undo() {
|
||||
for (int i=0;i<rows.size();i++) {
|
||||
rows.at(i)->keyframe_times[keyframes.at(i)] -= movement;
|
||||
}
|
||||
project_changed = old_project_changed;
|
||||
}
|
||||
|
||||
void ValueChangeCommand::redo() {
|
||||
if (!done) {
|
||||
source->set_value(new_val, false);
|
||||
void KeyframeMove::redo() {
|
||||
for (int i=0;i<rows.size();i++) {
|
||||
rows.at(i)->keyframe_times[keyframes.at(i)] += movement;
|
||||
}
|
||||
project_changed = true;
|
||||
}
|
||||
|
||||
KeyframeDelete::KeyframeDelete() : old_project_changed(project_changed), disable_keyframes_on_row(NULL), sorted(false) {}
|
||||
|
||||
void KeyframeDelete::undo() {
|
||||
if (disable_keyframes_on_row != NULL) disable_keyframes_on_row->setKeyframing(true);
|
||||
|
||||
int data_index = 0;
|
||||
for (int i=0;i<rows.size();i++) {
|
||||
EffectRow* row = rows.at(i);
|
||||
int keyframe_index = keyframes.at(i);
|
||||
|
||||
row->keyframe_times.insert(keyframe_index, deleted_keyframe_times.at(i));
|
||||
row->keyframe_types.insert(keyframe_index, deleted_keyframe_types.at(i));
|
||||
|
||||
for (int j=0;j<row->fieldCount();j++) {
|
||||
row->field(j)->keyframe_data.insert(keyframe_index, deleted_keyframe_data.at(data_index));
|
||||
data_index++;
|
||||
}
|
||||
}
|
||||
|
||||
project_changed = old_project_changed;
|
||||
}
|
||||
|
||||
void KeyframeDelete::redo() {
|
||||
if (!sorted) {
|
||||
for (int i=0;i<keyframes.size();i++) {
|
||||
for (int j=i+1;j<keyframes.size();j++) {
|
||||
if (keyframes.at(i) > keyframes.at(j)) {
|
||||
int temp = keyframes.at(i);
|
||||
EffectRow* temp_row = rows.at(i);
|
||||
|
||||
keyframes[i] = keyframes.at(j);
|
||||
rows[i] = rows.at(j);
|
||||
|
||||
keyframes[j] = temp;
|
||||
rows[j] = temp_row;
|
||||
}
|
||||
}
|
||||
}
|
||||
sorted = true;
|
||||
}
|
||||
|
||||
deleted_keyframe_times.resize(rows.size());
|
||||
deleted_keyframe_types.resize(rows.size());
|
||||
deleted_keyframe_data.clear();
|
||||
|
||||
for (int i=0;i<rows.size();i++) {
|
||||
EffectRow* row = rows.at(i);
|
||||
int keyframe_index = keyframes.at(i) - i;
|
||||
|
||||
deleted_keyframe_times[i] = (row->keyframe_times.at(keyframe_index));
|
||||
deleted_keyframe_types[i] = (row->keyframe_types.at(keyframe_index));
|
||||
|
||||
row->keyframe_times.removeAt(keyframe_index);
|
||||
row->keyframe_types.removeAt(keyframe_index);
|
||||
|
||||
for (int j=0;j<row->fieldCount();j++) {
|
||||
deleted_keyframe_data.append(row->field(j)->keyframe_data.at(keyframe_index));
|
||||
row->field(j)->keyframe_data.removeAt(keyframe_index);
|
||||
}
|
||||
}
|
||||
|
||||
if (disable_keyframes_on_row != NULL) disable_keyframes_on_row->setKeyframing(false);
|
||||
project_changed = true;
|
||||
}
|
||||
|
||||
KeyframeSet::KeyframeSet(EffectRow* r, int i, long t, bool justMadeKeyframe) :
|
||||
old_project_changed(project_changed),
|
||||
row(r),
|
||||
index(i),
|
||||
time(t),
|
||||
just_made_keyframe(justMadeKeyframe),
|
||||
done(true)
|
||||
{
|
||||
enable_keyframes = !row->isKeyframing();
|
||||
if (index != -1) old_values.resize(row->fieldCount());
|
||||
new_values.resize(row->fieldCount());
|
||||
for (int i=0;i<row->fieldCount();i++) {
|
||||
EffectField* field = row->field(i);
|
||||
if (index != -1) {
|
||||
if (field->type == EFFECT_FIELD_DOUBLE) {
|
||||
old_values[i] = static_cast<LabelSlider*>(field->ui_element)->get_drag_start_value();
|
||||
} else {
|
||||
old_values[i] = field->keyframe_data.at(index);
|
||||
}
|
||||
}
|
||||
new_values[i] = field->get_current_data();
|
||||
}
|
||||
}
|
||||
|
||||
void KeyframeSet::undo() {
|
||||
if (enable_keyframes) row->setKeyframing(false);
|
||||
|
||||
bool append = (index == -1 || just_made_keyframe);
|
||||
if (append) {
|
||||
row->keyframe_times.removeLast();
|
||||
row->keyframe_types.removeLast();
|
||||
}
|
||||
for (int i=0;i<row->fieldCount();i++) {
|
||||
if (append) {
|
||||
row->field(i)->keyframe_data.removeLast();
|
||||
} else {
|
||||
row->field(i)->keyframe_data[index] = old_values.at(i);
|
||||
}
|
||||
}
|
||||
|
||||
project_changed = old_project_changed;
|
||||
done = false;
|
||||
}
|
||||
|
||||
void KeyframeSet::redo() {
|
||||
bool append = (index == -1 || (just_made_keyframe && !done));
|
||||
if (append) {
|
||||
row->keyframe_times.append(time);
|
||||
row->keyframe_types.append((row->keyframe_types.size() > 0) ? row->keyframe_types.last() : EFFECT_KEYFRAME_LINEAR);
|
||||
}
|
||||
for (int i=0;i<row->fieldCount();i++) {
|
||||
if (append) {
|
||||
row->field(i)->keyframe_data.append(new_values.at(i));
|
||||
} else {
|
||||
row->field(i)->keyframe_data[index] = new_values.at(i);
|
||||
}
|
||||
}
|
||||
row->setKeyframing(true);
|
||||
|
||||
project_changed = true;
|
||||
done = true;
|
||||
}
|
||||
|
||||
+40
-6
@@ -6,6 +6,7 @@ class QCheckBox;
|
||||
class LabelSlider;
|
||||
class Effect;
|
||||
class SourceTable;
|
||||
class EffectRow;
|
||||
struct Clip;
|
||||
struct Sequence;
|
||||
struct Media;
|
||||
@@ -200,17 +201,50 @@ private:
|
||||
bool old_project_changed;
|
||||
};
|
||||
|
||||
class ValueChangeCommand : public QUndoCommand {
|
||||
class KeyframeMove : public QUndoCommand {
|
||||
public:
|
||||
ValueChangeCommand();
|
||||
LabelSlider* source;
|
||||
float old_val;
|
||||
float new_val;
|
||||
KeyframeMove();
|
||||
QVector<EffectRow*> rows;
|
||||
QVector<int> keyframes;
|
||||
long movement;
|
||||
void undo();
|
||||
void redo();
|
||||
private:
|
||||
bool done;
|
||||
bool old_project_changed;
|
||||
};
|
||||
|
||||
class KeyframeDelete : public QUndoCommand {
|
||||
public:
|
||||
KeyframeDelete();
|
||||
QVector<EffectRow*> rows;
|
||||
EffectRow* disable_keyframes_on_row;
|
||||
QVector<int> keyframes;
|
||||
void undo();
|
||||
void redo();
|
||||
private:
|
||||
bool old_project_changed;
|
||||
QVector<long> deleted_keyframe_times;
|
||||
QVector<int> deleted_keyframe_types;
|
||||
QVector<QVariant> deleted_keyframe_data;
|
||||
bool sorted;
|
||||
};
|
||||
|
||||
|
||||
class KeyframeSet : public QUndoCommand {
|
||||
public:
|
||||
KeyframeSet(EffectRow* r, int i, long t, bool justMadeKeyframe);
|
||||
void undo();
|
||||
void redo();
|
||||
QVector<QVariant> old_values;
|
||||
QVector<QVariant> new_values;
|
||||
private:
|
||||
bool old_project_changed;
|
||||
EffectRow* row;
|
||||
int index;
|
||||
long time;
|
||||
bool enable_keyframes;
|
||||
bool just_made_keyframe;
|
||||
bool done;
|
||||
};
|
||||
|
||||
#endif // UNDO_H
|
||||
|
||||
+1
-1
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user