diff --git a/dialogs/exportdialog.cpp b/dialogs/exportdialog.cpp
index 59bab8c06..80f444a21 100644
--- a/dialogs/exportdialog.cpp
+++ b/dialogs/exportdialog.cpp
@@ -49,6 +49,9 @@ ExportDialog::ExportDialog(QWidget *parent) :
{
ui->setupUi(this);
+ ui->rangeCombobox->setCurrentIndex(0);
+ ui->rangeCombobox->setEnabled(sequence->using_workarea);
+
format_strings.resize(FORMAT_SIZE);
format_strings[FORMAT_3GPP] = "3GPP";
format_strings[FORMAT_AIFF] = "AIFF";
@@ -454,7 +457,6 @@ void ExportDialog::on_pushButton_clicked()
}
}
-
et = new ExportThread();
et->surface.create();
@@ -487,6 +489,13 @@ void ExportDialog::on_pushButton_clicked()
et->audio_bitrate = ui->audiobitrateSpinbox->value();
}
+ et->start_frame = 0;
+ et->end_frame = sequence->getEndFrame(); // entire sequence
+ if (ui->rangeCombobox->currentIndex() == 1) {
+ et->start_frame = qMax(sequence->workarea_in, et->start_frame);
+ et->end_frame = qMin(sequence->workarea_out, et->end_frame);
+ }
+
et->ed = this;
cancelled = false;
diff --git a/dialogs/exportdialog.ui b/dialogs/exportdialog.ui
index 3434cb213..df0d18d2f 100644
--- a/dialogs/exportdialog.ui
+++ b/dialogs/exportdialog.ui
@@ -6,8 +6,8 @@
0
0
- 299
- 372
+ 557
+ 659
@@ -28,6 +28,31 @@
+ -
+
+
-
+
+
+ Range:
+
+
+
+ -
+
+
-
+
+ Entire Sequence
+
+
+ -
+
+ In to Out
+
+
+
+
+
+
-
diff --git a/io/exportthread.cpp b/io/exportthread.cpp
index 0ba0ac752..05b069942 100644
--- a/io/exportthread.cpp
+++ b/io/exportthread.cpp
@@ -53,10 +53,6 @@ void ExportThread::run() {
panel_timeline->pause();
// av_log_set_level(AV_LOG_DEBUG);
- // TODO make customizable
- long start = 0;
- long end = sequence->getEndFrame();
-
if (!panel_viewer->viewer_widget->context()->makeCurrent(&surface)) {
qDebug() << "[ERROR] Make current failed";
ed->export_error = "could not make OpenGL context current";
@@ -283,7 +279,7 @@ void ExportThread::run() {
qDebug() << "[ERROR] Could not write output file header." << ret;
ed->export_error = "could not write output file header (" + QString::number(ret) + ")";
} else {
- panel_timeline->seek(start);
+ panel_timeline->seek(start_frame);
QOpenGLFramebufferObject fbo(video_width, video_height, QOpenGLFramebufferObject::CombinedDepthStencil, GL_TEXTURE_RECTANGLE);
fbo.bind();
@@ -296,10 +292,10 @@ void ExportThread::run() {
long file_audio_samples = 0;
- while (panel_timeline->playhead < end && !fail) {
+ while (panel_timeline->playhead < end_frame && !fail) {
panel_viewer->viewer_widget->paintGL();
- double timecode_secs = (double) panel_timeline->playhead / sequence->frame_rate;
+ double timecode_secs = (double) (panel_timeline->playhead-start_frame) / sequence->frame_rate;
if (video_enabled) {
// get image from opengl
glReadPixels(0, 0, video_width, video_height, GL_RGBA, GL_UNSIGNED_BYTE, video_frame->data[0]);
@@ -338,7 +334,7 @@ void ExportThread::run() {
file_audio_samples += swr_frame->nb_samples;
}
}
- emit progress_changed(((float) panel_timeline->playhead / (float) end) * 100);
+ emit progress_changed(((double) (panel_timeline->playhead-start_frame) / (double) (end_frame-start_frame)) * 100);
panel_timeline->playhead++;
}
diff --git a/io/exportthread.h b/io/exportthread.h
index bcd516030..31f768af2 100644
--- a/io/exportthread.h
+++ b/io/exportthread.h
@@ -28,6 +28,8 @@ public:
int audio_codec;
int audio_sampling_rate;
int audio_bitrate;
+ long start_frame;
+ long end_frame;
QOffscreenSurface surface;
diff --git a/mainwindow.cpp b/mainwindow.cpp
index ed91a4058..556edaf7c 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -357,11 +357,9 @@ void MainWindow::on_actionProject_triggered()
{
if (can_close_project()) {
panel_effect_controls->clear_effects(true);
- panel_project->new_project();
undo_stack.clear();
- panel_timeline->redraw_all_clips(false);
project_url.clear();
- project_changed = false;
+ panel_project->new_project();
}
}
@@ -617,15 +615,49 @@ void MainWindow::on_actionScroll_Wheel_Zooms_triggered()
void MainWindow::on_actionLink_Unlink_triggered()
{
- panel_timeline->toggle_links();
+ if (panel_timeline->focused()) panel_timeline->toggle_links();
}
void MainWindow::on_actionRipple_To_In_Point_triggered()
{
- panel_timeline->ripple_to_in_point(true);
+ if (panel_timeline->focused()) panel_timeline->ripple_to_in_point(true);
}
void MainWindow::on_actionRipple_to_Out_Point_triggered()
{
- panel_timeline->ripple_to_in_point(false);
+ if (panel_timeline->focused()) panel_timeline->ripple_to_in_point(false);
+}
+
+void MainWindow::on_actionSet_In_Point_triggered()
+{
+ if (panel_timeline->focused()) panel_timeline->set_in_point();
+}
+
+void MainWindow::on_actionSet_Out_Point_triggered()
+{
+ if (panel_timeline->focused()) panel_timeline->set_out_point();
+}
+
+void MainWindow::on_actionClear_In_Out_triggered()
+{
+ if (panel_timeline->focused() && sequence->using_workarea) {
+ TimelineAction* ta = new TimelineAction();
+ ta->set_in_out(sequence, false, 0, 0);
+ undo_stack.push(ta);
+ panel_timeline->repaint_timeline();
+ }
+}
+
+void MainWindow::on_actionDelete_In_Out_triggered()
+{
+ if (panel_timeline->focused()) {
+ panel_timeline->delete_in_out(false);
+ }
+}
+
+void MainWindow::on_actionRipple_Delete_In_Out_triggered()
+{
+ if (panel_timeline->focused()) {
+ panel_timeline->delete_in_out(true);
+ }
}
diff --git a/mainwindow.h b/mainwindow.h
index 62f6d0f1d..7b97d60a3 100644
--- a/mainwindow.h
+++ b/mainwindow.h
@@ -158,6 +158,16 @@ private slots:
void on_actionRipple_to_Out_Point_triggered();
+ void on_actionSet_In_Point_triggered();
+
+ void on_actionSet_Out_Point_triggered();
+
+ void on_actionClear_In_Out_triggered();
+
+ void on_actionDelete_In_Out_triggered();
+
+ void on_actionRipple_Delete_In_Out_triggered();
+
private:
Ui::MainWindow *ui;
void setup_layout();
diff --git a/mainwindow.ui b/mainwindow.ui
index 1a7cbd7c6..7e0f78bf4 100644
--- a/mainwindow.ui
+++ b/mainwindow.ui
@@ -79,6 +79,12 @@
+
+
+
+
+
+
diff --git a/panels/project.cpp b/panels/project.cpp
index 37774aec3..88c9879dc 100644
--- a/panels/project.cpp
+++ b/panels/project.cpp
@@ -406,9 +406,9 @@ void Project::clear() {
void Project::new_project() {
// clear existing project
- set_sequence(NULL);
clear();
project_changed = false;
+ set_sequence(NULL);
}
QTreeWidgetItem* Project::find_loaded_folder_by_id(int id) {
@@ -579,6 +579,11 @@ bool Project::load_worker(QFile& f, QXmlStreamReader& stream, int type) {
s->audio_layout = attr.value().toInt();
} else if (attr.name() == "open") {
open_sequence = true;
+ } else if (attr.name() == "workareaIn") {
+ s->using_workarea = true;
+ s->workarea_in = attr.value().toLong();
+ } else if (attr.name() == "workareaOut") {
+ s->workarea_out = attr.value().toLong();
}
}
@@ -596,11 +601,11 @@ bool Project::load_worker(QFile& f, QXmlStreamReader& stream, int type) {
} else if (attr.name() == "id") {
c->load_id = attr.value().toInt();
} else if (attr.name() == "clipin") {
- c->clip_in = attr.value().toInt();
+ c->clip_in = attr.value().toLong();
} else if (attr.name() == "in") {
- c->timeline_in = attr.value().toInt();
+ c->timeline_in = attr.value().toLong();
} else if (attr.name() == "out") {
- c->timeline_out = attr.value().toInt();
+ c->timeline_out = attr.value().toLong();
} else if (attr.name() == "track") {
c->track = attr.value().toInt();
} else if (attr.name() == "r") {
@@ -842,6 +847,10 @@ void Project::save_folder(QXmlStreamWriter& stream, QTreeWidgetItem* parent, int
if (s == sequence) {
stream.writeAttribute("open", "1");
}
+ if (s->using_workarea) {
+ stream.writeAttribute("workareaIn", QString::number(s->workarea_in));
+ stream.writeAttribute("workareaOut", QString::number(s->workarea_out));
+ }
for (int j=0;jclip_count();j++) {
Clip* c = s->get_clip(j);
if (c != NULL) {
diff --git a/panels/project.h b/panels/project.h
index 95a881c8b..13d49f7f0 100644
--- a/panels/project.h
+++ b/panels/project.h
@@ -15,7 +15,7 @@ class QXmlStreamWriter;
class QXmlStreamReader;
class QFile;
-#define SAVE_VERSION "180719"
+#define SAVE_VERSION "180722"
#define MEDIA_TYPE_FOOTAGE 0
#define MEDIA_TYPE_SEQUENCE 1
diff --git a/panels/timeline.cpp b/panels/timeline.cpp
index 0a86edf1e..bfb763a72 100644
--- a/panels/timeline.cpp
+++ b/panels/timeline.cpp
@@ -35,7 +35,6 @@ Timeline::Timeline(QWidget *parent) :
edit_tool_selects_links(false),
edit_tool_also_seeks(false),
select_also_seeks(false),
- using_workarea(false),
paste_seeks(true),
snapping(true),
last_frame(0),
@@ -206,6 +205,14 @@ int Timeline::calculate_track_height(int track, int value) {
return vector.at(index);
}
+void Timeline::set_in_point() {
+ ui->headers->set_in_point(playhead);
+}
+
+void Timeline::set_out_point() {
+ ui->headers->set_out_point(playhead);
+}
+
void Timeline::update_sequence() {
bool null_sequence = (sequence == NULL);
@@ -216,16 +223,14 @@ void Timeline::update_sequence() {
ui->pushButton_4->setEnabled(!null_sequence);
ui->pushButton_5->setEnabled(!null_sequence);
ui->headers->setEnabled(!null_sequence);
-// ui->video_area->setEnabled(!null_sequence);
-// ui->audio_area->setEnabled(!null_sequence);
if (null_sequence) {
setWindowTitle("Timeline: ");
} else {
setWindowTitle("Timeline: " + sequence->name);
+ reset_all_audio();
redraw_all_clips(false);
playback_updater.setInterval(qFloor(1000 / sequence->frame_rate));
- reset_all_audio();
}
}
@@ -279,6 +284,27 @@ void Timeline::select_all() {
repaint_timeline();
}
+void Timeline::delete_in_out(bool ripple) {
+ if (sequence != NULL && sequence->using_workarea) {
+ QVector areas;
+ int video_tracks = 0, audio_tracks = 0;
+ sequence->get_track_limits(&video_tracks, &audio_tracks);
+ for (int i=video_tracks;i<=audio_tracks;i++) {
+ Selection s;
+ s.in = sequence->workarea_in;
+ s.out = sequence->workarea_out;
+ s.track = i;
+ areas.append(s);
+ }
+ TimelineAction* ta = new TimelineAction();
+ panel_timeline->delete_areas_and_relink(ta, areas);
+ if (ripple) ta->ripple(sequence, sequence->workarea_in, sequence->workarea_in - sequence->workarea_out);
+ ta->set_in_out(sequence, false, 0, 0);
+ undo_stack.push(ta);
+ redraw_all_clips(true);
+ }
+}
+
void Timeline::delete_selection(bool ripple_delete) {
if (selections.size() > 0) {
panel_effect_controls->clear_effects(true);
@@ -301,7 +327,6 @@ void Timeline::delete_selection(bool ripple_delete) {
// it feels a little more intuitive with this here
ripple_point++;
- QVector ignore;
bool can_ripple = true;
for (int i=0;iclip_count();i++) {
Clip* c = sequence->get_clip(i);
@@ -329,7 +354,7 @@ void Timeline::delete_selection(bool ripple_delete) {
}
}
}
- if (can_ripple) ta->ripple(sequence, ripple_point, -ripple_length, ignore);
+ if (can_ripple) ta->ripple(sequence, ripple_point, -ripple_length);
}
selections.clear();
@@ -743,10 +768,9 @@ void Timeline::ripple_to_in_point(bool in) {
}
// trim and move clips around the in point
- QVector ignore;
TimelineAction* ta = new TimelineAction();
delete_areas_and_relink(ta, areas);
- ta->ripple(sequence, in_point, (in) ? (in_point - playhead) : (playhead - in_point), ignore);
+ ta->ripple(sequence, in_point, (in) ? (in_point - playhead) : (playhead - in_point));
undo_stack.push(ta);
redraw_all_clips(true);
diff --git a/panels/timeline.h b/panels/timeline.h
index 7310dc753..abf143fb1 100644
--- a/panels/timeline.h
+++ b/panels/timeline.h
@@ -85,6 +85,9 @@ public:
bool has_clip_been_split(int c);
void toggle_links();
void ripple_to_in_point(bool in);
+ void set_in_point();
+ void set_out_point();
+ void delete_in_out(bool ripple);
int get_snap_range();
int getScreenPointFromFrame(long frame);
@@ -93,11 +96,7 @@ public:
bool snap_to_point(long point, long* l);
void snap_to_clip(long* l, bool playhead_inclusive);
- long playhead;
-
- bool using_workarea;
- long workarea_in;
- long workarea_out;
+ long playhead;
// playback functions
void go_to_start();
diff --git a/project/sequence.cpp b/project/sequence.cpp
index 788a35a1b..eefeb643d 100644
--- a/project/sequence.cpp
+++ b/project/sequence.cpp
@@ -5,7 +5,11 @@
#include
-Sequence::Sequence() {}
+Sequence::Sequence() :
+ using_workarea(false),
+ workarea_in(0),
+ workarea_out(0)
+{}
Sequence::~Sequence() {
// dealloc all clips
diff --git a/project/sequence.h b/project/sequence.h
index 408b68e10..0381901d4 100644
--- a/project/sequence.h
+++ b/project/sequence.h
@@ -23,6 +23,10 @@ public:
double frame_rate;
int audio_frequency;
int audio_layout;
+
+ bool using_workarea;
+ long workarea_in;
+ long workarea_out;
private:
QVector clips;
};
diff --git a/project/undo.cpp b/project/undo.cpp
index 14656b451..d0bb1c8b9 100644
--- a/project/undo.cpp
+++ b/project/undo.cpp
@@ -24,7 +24,12 @@ QUndoStack undo_stack;
#define TA_ADD_CLIP_IN 7
#define TA_ADD_TRACK 8
-TimelineAction::TimelineAction() : done(false), change_seq(false), ripple_enabled(false) {}
+TimelineAction::TimelineAction() :
+ done(false),
+ change_seq(false),
+ ripple_enabled(false),
+ change_in_out(false)
+{}
TimelineAction::~TimelineAction() {
for (int i=0;i i;
+ ripple(s, point, length, i);
+}
+
+void TimelineAction::set_in_out(Sequence* s, bool enabled, long in, long out) {
+ change_in_out = true;
+ change_in_out_sequence = s;
+
+ old_in_out_enabled = s->using_workarea;
+ old_sequence_in = s->workarea_in;
+ old_sequence_out = s->workarea_out;
+
+ new_in_out_enabled = enabled;
+ new_sequence_in = in;
+ new_sequence_out = out;
+
+}
+
void TimelineAction::ripple(Sequence* s, long point, long length, QVector& ignore) {
ripple_enabled = true;
ripple_point = point;
@@ -220,6 +244,14 @@ void TimelineAction::undo() {
}
}
+ // un-change workarea
+ if (change_in_out) {
+ change_in_out_sequence->using_workarea = old_in_out_enabled;
+ change_in_out_sequence->workarea_in = old_sequence_in;
+ change_in_out_sequence->workarea_out = old_sequence_out;
+ }
+
+ // un-change current active sequence
if (change_seq) {
set_sequence(old_seq);
}
@@ -388,6 +420,13 @@ void TimelineAction::redo() {
}
}
+ // change sequence workarea
+ if (change_in_out) {
+ change_in_out_sequence->using_workarea = new_in_out_enabled;
+ change_in_out_sequence->workarea_in = new_sequence_in;
+ change_in_out_sequence->workarea_out = new_sequence_out;
+ }
+
// change current sequence
if (change_seq) {
old_seq = sequence;
diff --git a/project/undo.h b/project/undo.h
index 7ca08ea76..67195a8be 100644
--- a/project/undo.h
+++ b/project/undo.h
@@ -30,7 +30,9 @@ public:
void delete_clip(Sequence* s, int clip);
void add_media(QTreeWidgetItem* item);
void delete_media(QTreeWidgetItem* item);
+ void ripple(Sequence* s, long point, long length);
void ripple(Sequence* s, long point, long length, QVector &ignore);
+ void set_in_out(Sequence* s, bool enabled, long in, long out);
void undo();
void redo();
private:
@@ -73,6 +75,15 @@ private:
QVector rippled_clips;
QVector ripple_ignores;
+ bool change_in_out;
+ Sequence* change_in_out_sequence;
+ bool old_in_out_enabled;
+ bool new_in_out_enabled;
+ long old_sequence_in;
+ long new_sequence_in;
+ long old_sequence_out;
+ long new_sequence_out;
+
void new_action(Sequence* s, int action, int clip, long old_val, long new_val);
void offset_links(QVector& clips, int offset);
};
diff --git a/ui/timelineheader.cpp b/ui/timelineheader.cpp
index ed16c65c8..1ed76bb7a 100644
--- a/ui/timelineheader.cpp
+++ b/ui/timelineheader.cpp
@@ -3,42 +3,110 @@
#include "panels/panels.h"
#include "panels/timeline.h"
#include "project/sequence.h"
+#include "project/undo.h"
#include
#include
+#include
#define CLICK_RANGE 5
#define PLAYHEAD_SIZE 6
-TimelineHeader::TimelineHeader(QWidget *parent) : QWidget(parent)
-{
- dragging = false;
+TimelineHeader::TimelineHeader(QWidget *parent) : QWidget(parent), dragging(false), resizing_workarea(false) {
setCursor(Qt::ArrowCursor);
+ setMouseTracking(true);
}
-void set_playhead(QMouseEvent* event) {
- long frame = panel_timeline->getFrameFromScreenPoint(event->pos().x());
+void set_playhead(int mouse_x) {
+ long frame = panel_timeline->getFrameFromScreenPoint(mouse_x);
panel_timeline->snap_to_clip(&frame, false);
panel_timeline->seek(frame);
panel_timeline->repaint_timeline();
}
-void TimelineHeader::mousePressEvent(QMouseEvent* event) {
- /*if (panel_timeline->using_workarea) {
- event->pos().x()
- if (panel_timeline->workarea_in)
- } else {
+void TimelineHeader::set_in_point(long new_in) {
+ long new_out = sequence->workarea_out;
+ if (new_out == new_in) {
+ new_in--;
+ } else if (new_out < new_in) {
+ new_out = sequence->getEndFrame();
+ }
- }*/
- set_playhead(event);
+ TimelineAction* ta = new TimelineAction();
+ ta->set_in_out(sequence, true, new_in, new_out);
+ undo_stack.push(ta);
+
+ update();
+}
+
+void TimelineHeader::set_out_point(long new_out) {
+ long new_in = sequence->workarea_in;
+ if (new_out == new_in) {
+ new_out++;
+ } else if (new_in > new_out) {
+ new_in = 0;
+ }
+
+ TimelineAction* ta = new TimelineAction();
+ ta->set_in_out(sequence, true, new_in, new_out);
+ undo_stack.push(ta);
+
+ update();
+}
+
+void TimelineHeader::mousePressEvent(QMouseEvent* event) {
+ if (resizing_workarea) {
+ sequence_end = sequence->getEndFrame();
+ } else {
+ set_playhead(event->pos().x());
+ }
dragging = true;
}
void TimelineHeader::mouseMoveEvent(QMouseEvent* event) {
- if (dragging) set_playhead(event);
+ if (dragging) {
+ if (resizing_workarea) {
+ long frame = panel_timeline->getFrameFromScreenPoint(event->pos().x());
+ panel_timeline->snap_to_clip(&frame, true);
+ if (resizing_workarea_in) {
+ temp_workarea_in = qMax(qMin(temp_workarea_out-1, frame), 0L);
+ } else {
+ temp_workarea_out = qMin(qMax(temp_workarea_in+1, frame), sequence_end);
+ }
+ panel_timeline->repaint_timeline();
+ } else {
+ set_playhead(event->pos().x());
+ }
+ } else {
+ resizing_workarea = false;
+ unsetCursor();
+ if (sequence->using_workarea) {
+ long min_frame = panel_timeline->getFrameFromScreenPoint(event->pos().x() - CLICK_RANGE) - 1;
+ long max_frame = panel_timeline->getFrameFromScreenPoint(event->pos().x() + CLICK_RANGE) + 1;
+ if (sequence->workarea_in > min_frame && sequence->workarea_in < max_frame) {
+ resizing_workarea = true;
+ resizing_workarea_in = true;
+ } else if (sequence->workarea_out > min_frame && sequence->workarea_out < max_frame) {
+ resizing_workarea = true;
+ resizing_workarea_in = false;
+ }
+ if (resizing_workarea) {
+ temp_workarea_in = sequence->workarea_in;
+ temp_workarea_out = sequence->workarea_out;
+ setCursor(Qt::SizeHorCursor);
+ }
+ }
+ }
}
-void TimelineHeader::mouseReleaseEvent(QMouseEvent *) {
+void TimelineHeader::mouseReleaseEvent(QMouseEvent*) {
+ if (resizing_workarea) {
+ TimelineAction* ta = new TimelineAction();
+ ta->set_in_out(sequence, true, temp_workarea_in, temp_workarea_out);
+ undo_stack.push(ta);
+ }
+
+ resizing_workarea = false;
dragging = false;
panel_timeline->snapped = false;
panel_timeline->repaint_timeline();
@@ -60,9 +128,9 @@ void TimelineHeader::paintEvent(QPaintEvent*) {
// draw in/out selection
int in_x;
- if (panel_timeline->using_workarea) {
- in_x = panel_timeline->getScreenPointFromFrame(panel_timeline->workarea_in);
- int out_x = panel_timeline->getScreenPointFromFrame(panel_timeline->workarea_out);
+ if (sequence->using_workarea) {
+ in_x = panel_timeline->getScreenPointFromFrame(resizing_workarea ? temp_workarea_in : sequence->workarea_in);
+ int out_x = panel_timeline->getScreenPointFromFrame(resizing_workarea ? temp_workarea_out :sequence->workarea_out);
p.fillRect(QRect(in_x, 0, out_x-in_x, height()), QColor(0, 192, 255, 128));
p.setPen(Qt::white);
p.drawLine(in_x, 0, in_x, height());
diff --git a/ui/timelineheader.h b/ui/timelineheader.h
index 9dbead229..2c5dd27d5 100644
--- a/ui/timelineheader.h
+++ b/ui/timelineheader.h
@@ -8,6 +8,8 @@ class TimelineHeader : public QWidget
Q_OBJECT
public:
explicit TimelineHeader(QWidget *parent = 0);
+ void set_in_point(long p);
+ void set_out_point(long p);
protected:
void paintEvent(QPaintEvent*);
@@ -18,6 +20,12 @@ protected:
private:
bool dragging;
+ bool resizing_workarea;
+ bool resizing_workarea_in;
+ long temp_workarea_in;
+ long temp_workarea_out;
+ long sequence_end;
+
signals:
public slots:
diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp
index 9be2b8871..9f7d01443 100644
--- a/ui/timelinewidget.cpp
+++ b/ui/timelinewidget.cpp
@@ -755,7 +755,7 @@ void TimelineWidget::update_ghosts(QPoint& mouse_pos) {
}
}
}
- panel_timeline->snapped = (temp_frame_diff == frame_diff);
+ if (temp_frame_diff != frame_diff) panel_timeline->snapped = false;
// apply changes to ghosts
for (int i=0;ighosts.size();i++) {