workarea in/out added #108
This commit is contained in:
@@ -49,6 +49,9 @@ ExportDialog::ExportDialog(QWidget *parent) :
|
|||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
ui->rangeCombobox->setCurrentIndex(0);
|
||||||
|
ui->rangeCombobox->setEnabled(sequence->using_workarea);
|
||||||
|
|
||||||
format_strings.resize(FORMAT_SIZE);
|
format_strings.resize(FORMAT_SIZE);
|
||||||
format_strings[FORMAT_3GPP] = "3GPP";
|
format_strings[FORMAT_3GPP] = "3GPP";
|
||||||
format_strings[FORMAT_AIFF] = "AIFF";
|
format_strings[FORMAT_AIFF] = "AIFF";
|
||||||
@@ -454,7 +457,6 @@ void ExportDialog::on_pushButton_clicked()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
et = new ExportThread();
|
et = new ExportThread();
|
||||||
|
|
||||||
et->surface.create();
|
et->surface.create();
|
||||||
@@ -487,6 +489,13 @@ void ExportDialog::on_pushButton_clicked()
|
|||||||
et->audio_bitrate = ui->audiobitrateSpinbox->value();
|
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;
|
et->ed = this;
|
||||||
cancelled = false;
|
cancelled = false;
|
||||||
|
|
||||||
|
|||||||
+27
-2
@@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>299</width>
|
<width>557</width>
|
||||||
<height>372</height>
|
<height>659</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@@ -28,6 +28,31 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_10">
|
||||||
|
<property name="text">
|
||||||
|
<string>Range:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="rangeCombobox">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Entire Sequence</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>In to Out</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="videoGroupbox">
|
<widget class="QGroupBox" name="videoGroupbox">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
|
|||||||
+4
-8
@@ -53,10 +53,6 @@ void ExportThread::run() {
|
|||||||
panel_timeline->pause();
|
panel_timeline->pause();
|
||||||
// av_log_set_level(AV_LOG_DEBUG);
|
// 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)) {
|
if (!panel_viewer->viewer_widget->context()->makeCurrent(&surface)) {
|
||||||
qDebug() << "[ERROR] Make current failed";
|
qDebug() << "[ERROR] Make current failed";
|
||||||
ed->export_error = "could not make OpenGL context current";
|
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;
|
qDebug() << "[ERROR] Could not write output file header." << ret;
|
||||||
ed->export_error = "could not write output file header (" + QString::number(ret) + ")";
|
ed->export_error = "could not write output file header (" + QString::number(ret) + ")";
|
||||||
} else {
|
} else {
|
||||||
panel_timeline->seek(start);
|
panel_timeline->seek(start_frame);
|
||||||
|
|
||||||
QOpenGLFramebufferObject fbo(video_width, video_height, QOpenGLFramebufferObject::CombinedDepthStencil, GL_TEXTURE_RECTANGLE);
|
QOpenGLFramebufferObject fbo(video_width, video_height, QOpenGLFramebufferObject::CombinedDepthStencil, GL_TEXTURE_RECTANGLE);
|
||||||
fbo.bind();
|
fbo.bind();
|
||||||
@@ -296,10 +292,10 @@ void ExportThread::run() {
|
|||||||
|
|
||||||
long file_audio_samples = 0;
|
long file_audio_samples = 0;
|
||||||
|
|
||||||
while (panel_timeline->playhead < end && !fail) {
|
while (panel_timeline->playhead < end_frame && !fail) {
|
||||||
panel_viewer->viewer_widget->paintGL();
|
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) {
|
if (video_enabled) {
|
||||||
// get image from opengl
|
// get image from opengl
|
||||||
glReadPixels(0, 0, video_width, video_height, GL_RGBA, GL_UNSIGNED_BYTE, video_frame->data[0]);
|
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;
|
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++;
|
panel_timeline->playhead++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ public:
|
|||||||
int audio_codec;
|
int audio_codec;
|
||||||
int audio_sampling_rate;
|
int audio_sampling_rate;
|
||||||
int audio_bitrate;
|
int audio_bitrate;
|
||||||
|
long start_frame;
|
||||||
|
long end_frame;
|
||||||
|
|
||||||
QOffscreenSurface surface;
|
QOffscreenSurface surface;
|
||||||
|
|
||||||
|
|||||||
+38
-6
@@ -357,11 +357,9 @@ void MainWindow::on_actionProject_triggered()
|
|||||||
{
|
{
|
||||||
if (can_close_project()) {
|
if (can_close_project()) {
|
||||||
panel_effect_controls->clear_effects(true);
|
panel_effect_controls->clear_effects(true);
|
||||||
panel_project->new_project();
|
|
||||||
undo_stack.clear();
|
undo_stack.clear();
|
||||||
panel_timeline->redraw_all_clips(false);
|
|
||||||
project_url.clear();
|
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()
|
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()
|
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()
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -158,6 +158,16 @@ private slots:
|
|||||||
|
|
||||||
void on_actionRipple_to_Out_Point_triggered();
|
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:
|
private:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
void setup_layout();
|
void setup_layout();
|
||||||
|
|||||||
@@ -79,6 +79,12 @@
|
|||||||
<addaction name="actionRipple_To_In_Point"/>
|
<addaction name="actionRipple_To_In_Point"/>
|
||||||
<addaction name="actionRipple_to_Out_Point"/>
|
<addaction name="actionRipple_to_Out_Point"/>
|
||||||
<addaction name="actionSplit_at_Playhead"/>
|
<addaction name="actionSplit_at_Playhead"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionSet_In_Point"/>
|
||||||
|
<addaction name="actionSet_Out_Point"/>
|
||||||
|
<addaction name="actionClear_In_Out"/>
|
||||||
|
<addaction name="actionDelete_In_Out"/>
|
||||||
|
<addaction name="actionRipple_Delete_In_Out"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="menuWindow">
|
<widget class="QMenu" name="menuWindow">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
@@ -639,6 +645,40 @@
|
|||||||
<string>W</string>
|
<string>W</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionSet_In_Point">
|
||||||
|
<property name="text">
|
||||||
|
<string>Set In Point</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>I</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionSet_Out_Point">
|
||||||
|
<property name="text">
|
||||||
|
<string>Set Out Point</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>O</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionClear_In_Out">
|
||||||
|
<property name="text">
|
||||||
|
<string>Clear In/Out</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>G</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionDelete_In_Out">
|
||||||
|
<property name="text">
|
||||||
|
<string>Delete In/Out</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionRipple_Delete_In_Out">
|
||||||
|
<property name="text">
|
||||||
|
<string>Ripple Delete In/Out</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
<resources>
|
<resources>
|
||||||
|
|||||||
+13
-4
@@ -406,9 +406,9 @@ void Project::clear() {
|
|||||||
|
|
||||||
void Project::new_project() {
|
void Project::new_project() {
|
||||||
// clear existing project
|
// clear existing project
|
||||||
set_sequence(NULL);
|
|
||||||
clear();
|
clear();
|
||||||
project_changed = false;
|
project_changed = false;
|
||||||
|
set_sequence(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
QTreeWidgetItem* Project::find_loaded_folder_by_id(int id) {
|
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();
|
s->audio_layout = attr.value().toInt();
|
||||||
} else if (attr.name() == "open") {
|
} else if (attr.name() == "open") {
|
||||||
open_sequence = true;
|
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") {
|
} else if (attr.name() == "id") {
|
||||||
c->load_id = attr.value().toInt();
|
c->load_id = attr.value().toInt();
|
||||||
} else if (attr.name() == "clipin") {
|
} else if (attr.name() == "clipin") {
|
||||||
c->clip_in = attr.value().toInt();
|
c->clip_in = attr.value().toLong();
|
||||||
} else if (attr.name() == "in") {
|
} else if (attr.name() == "in") {
|
||||||
c->timeline_in = attr.value().toInt();
|
c->timeline_in = attr.value().toLong();
|
||||||
} else if (attr.name() == "out") {
|
} else if (attr.name() == "out") {
|
||||||
c->timeline_out = attr.value().toInt();
|
c->timeline_out = attr.value().toLong();
|
||||||
} else if (attr.name() == "track") {
|
} else if (attr.name() == "track") {
|
||||||
c->track = attr.value().toInt();
|
c->track = attr.value().toInt();
|
||||||
} else if (attr.name() == "r") {
|
} else if (attr.name() == "r") {
|
||||||
@@ -842,6 +847,10 @@ void Project::save_folder(QXmlStreamWriter& stream, QTreeWidgetItem* parent, int
|
|||||||
if (s == sequence) {
|
if (s == sequence) {
|
||||||
stream.writeAttribute("open", "1");
|
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;j<s->clip_count();j++) {
|
for (int j=0;j<s->clip_count();j++) {
|
||||||
Clip* c = s->get_clip(j);
|
Clip* c = s->get_clip(j);
|
||||||
if (c != NULL) {
|
if (c != NULL) {
|
||||||
|
|||||||
+1
-1
@@ -15,7 +15,7 @@ class QXmlStreamWriter;
|
|||||||
class QXmlStreamReader;
|
class QXmlStreamReader;
|
||||||
class QFile;
|
class QFile;
|
||||||
|
|
||||||
#define SAVE_VERSION "180719"
|
#define SAVE_VERSION "180722"
|
||||||
|
|
||||||
#define MEDIA_TYPE_FOOTAGE 0
|
#define MEDIA_TYPE_FOOTAGE 0
|
||||||
#define MEDIA_TYPE_SEQUENCE 1
|
#define MEDIA_TYPE_SEQUENCE 1
|
||||||
|
|||||||
+32
-8
@@ -35,7 +35,6 @@ Timeline::Timeline(QWidget *parent) :
|
|||||||
edit_tool_selects_links(false),
|
edit_tool_selects_links(false),
|
||||||
edit_tool_also_seeks(false),
|
edit_tool_also_seeks(false),
|
||||||
select_also_seeks(false),
|
select_also_seeks(false),
|
||||||
using_workarea(false),
|
|
||||||
paste_seeks(true),
|
paste_seeks(true),
|
||||||
snapping(true),
|
snapping(true),
|
||||||
last_frame(0),
|
last_frame(0),
|
||||||
@@ -206,6 +205,14 @@ int Timeline::calculate_track_height(int track, int value) {
|
|||||||
return vector.at(index);
|
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() {
|
void Timeline::update_sequence() {
|
||||||
bool null_sequence = (sequence == NULL);
|
bool null_sequence = (sequence == NULL);
|
||||||
|
|
||||||
@@ -216,16 +223,14 @@ void Timeline::update_sequence() {
|
|||||||
ui->pushButton_4->setEnabled(!null_sequence);
|
ui->pushButton_4->setEnabled(!null_sequence);
|
||||||
ui->pushButton_5->setEnabled(!null_sequence);
|
ui->pushButton_5->setEnabled(!null_sequence);
|
||||||
ui->headers->setEnabled(!null_sequence);
|
ui->headers->setEnabled(!null_sequence);
|
||||||
// ui->video_area->setEnabled(!null_sequence);
|
|
||||||
// ui->audio_area->setEnabled(!null_sequence);
|
|
||||||
|
|
||||||
if (null_sequence) {
|
if (null_sequence) {
|
||||||
setWindowTitle("Timeline: <none>");
|
setWindowTitle("Timeline: <none>");
|
||||||
} else {
|
} else {
|
||||||
setWindowTitle("Timeline: " + sequence->name);
|
setWindowTitle("Timeline: " + sequence->name);
|
||||||
|
reset_all_audio();
|
||||||
redraw_all_clips(false);
|
redraw_all_clips(false);
|
||||||
playback_updater.setInterval(qFloor(1000 / sequence->frame_rate));
|
playback_updater.setInterval(qFloor(1000 / sequence->frame_rate));
|
||||||
reset_all_audio();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,6 +284,27 @@ void Timeline::select_all() {
|
|||||||
repaint_timeline();
|
repaint_timeline();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Timeline::delete_in_out(bool ripple) {
|
||||||
|
if (sequence != NULL && sequence->using_workarea) {
|
||||||
|
QVector<Selection> 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) {
|
void Timeline::delete_selection(bool ripple_delete) {
|
||||||
if (selections.size() > 0) {
|
if (selections.size() > 0) {
|
||||||
panel_effect_controls->clear_effects(true);
|
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
|
// it feels a little more intuitive with this here
|
||||||
ripple_point++;
|
ripple_point++;
|
||||||
|
|
||||||
QVector<int> ignore;
|
|
||||||
bool can_ripple = true;
|
bool can_ripple = true;
|
||||||
for (int i=0;i<sequence->clip_count();i++) {
|
for (int i=0;i<sequence->clip_count();i++) {
|
||||||
Clip* c = sequence->get_clip(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();
|
selections.clear();
|
||||||
@@ -743,10 +768,9 @@ void Timeline::ripple_to_in_point(bool in) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// trim and move clips around the in point
|
// trim and move clips around the in point
|
||||||
QVector<int> ignore;
|
|
||||||
TimelineAction* ta = new TimelineAction();
|
TimelineAction* ta = new TimelineAction();
|
||||||
delete_areas_and_relink(ta, areas);
|
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);
|
undo_stack.push(ta);
|
||||||
|
|
||||||
redraw_all_clips(true);
|
redraw_all_clips(true);
|
||||||
|
|||||||
+4
-5
@@ -85,6 +85,9 @@ public:
|
|||||||
bool has_clip_been_split(int c);
|
bool has_clip_been_split(int c);
|
||||||
void toggle_links();
|
void toggle_links();
|
||||||
void ripple_to_in_point(bool in);
|
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 get_snap_range();
|
||||||
int getScreenPointFromFrame(long frame);
|
int getScreenPointFromFrame(long frame);
|
||||||
@@ -93,11 +96,7 @@ public:
|
|||||||
bool snap_to_point(long point, long* l);
|
bool snap_to_point(long point, long* l);
|
||||||
void snap_to_clip(long* l, bool playhead_inclusive);
|
void snap_to_clip(long* l, bool playhead_inclusive);
|
||||||
|
|
||||||
long playhead;
|
long playhead;
|
||||||
|
|
||||||
bool using_workarea;
|
|
||||||
long workarea_in;
|
|
||||||
long workarea_out;
|
|
||||||
|
|
||||||
// playback functions
|
// playback functions
|
||||||
void go_to_start();
|
void go_to_start();
|
||||||
|
|||||||
@@ -5,7 +5,11 @@
|
|||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
Sequence::Sequence() {}
|
Sequence::Sequence() :
|
||||||
|
using_workarea(false),
|
||||||
|
workarea_in(0),
|
||||||
|
workarea_out(0)
|
||||||
|
{}
|
||||||
|
|
||||||
Sequence::~Sequence() {
|
Sequence::~Sequence() {
|
||||||
// dealloc all clips
|
// dealloc all clips
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ public:
|
|||||||
double frame_rate;
|
double frame_rate;
|
||||||
int audio_frequency;
|
int audio_frequency;
|
||||||
int audio_layout;
|
int audio_layout;
|
||||||
|
|
||||||
|
bool using_workarea;
|
||||||
|
long workarea_in;
|
||||||
|
long workarea_out;
|
||||||
private:
|
private:
|
||||||
QVector<Clip*> clips;
|
QVector<Clip*> clips;
|
||||||
};
|
};
|
||||||
|
|||||||
+40
-1
@@ -24,7 +24,12 @@ QUndoStack undo_stack;
|
|||||||
#define TA_ADD_CLIP_IN 7
|
#define TA_ADD_CLIP_IN 7
|
||||||
#define TA_ADD_TRACK 8
|
#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() {
|
TimelineAction::~TimelineAction() {
|
||||||
for (int i=0;i<clips_to_add.size();i++) {
|
for (int i=0;i<clips_to_add.size();i++) {
|
||||||
@@ -129,6 +134,25 @@ void TimelineAction::delete_media(QTreeWidgetItem* item) {
|
|||||||
deleted_media.append(item);
|
deleted_media.append(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TimelineAction::ripple(Sequence* s, long point, long length) {
|
||||||
|
QVector<int> 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<int>& ignore) {
|
void TimelineAction::ripple(Sequence* s, long point, long length, QVector<int>& ignore) {
|
||||||
ripple_enabled = true;
|
ripple_enabled = true;
|
||||||
ripple_point = point;
|
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) {
|
if (change_seq) {
|
||||||
set_sequence(old_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
|
// change current sequence
|
||||||
if (change_seq) {
|
if (change_seq) {
|
||||||
old_seq = sequence;
|
old_seq = sequence;
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ public:
|
|||||||
void delete_clip(Sequence* s, int clip);
|
void delete_clip(Sequence* s, int clip);
|
||||||
void add_media(QTreeWidgetItem* item);
|
void add_media(QTreeWidgetItem* item);
|
||||||
void delete_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<int> &ignore);
|
void ripple(Sequence* s, long point, long length, QVector<int> &ignore);
|
||||||
|
void set_in_out(Sequence* s, bool enabled, long in, long out);
|
||||||
void undo();
|
void undo();
|
||||||
void redo();
|
void redo();
|
||||||
private:
|
private:
|
||||||
@@ -73,6 +75,15 @@ private:
|
|||||||
QVector<int> rippled_clips;
|
QVector<int> rippled_clips;
|
||||||
QVector<int> ripple_ignores;
|
QVector<int> 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 new_action(Sequence* s, int action, int clip, long old_val, long new_val);
|
||||||
void offset_links(QVector<Clip*>& clips, int offset);
|
void offset_links(QVector<Clip*>& clips, int offset);
|
||||||
};
|
};
|
||||||
|
|||||||
+85
-17
@@ -3,42 +3,110 @@
|
|||||||
#include "panels/panels.h"
|
#include "panels/panels.h"
|
||||||
#include "panels/timeline.h"
|
#include "panels/timeline.h"
|
||||||
#include "project/sequence.h"
|
#include "project/sequence.h"
|
||||||
|
#include "project/undo.h"
|
||||||
|
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
#define CLICK_RANGE 5
|
#define CLICK_RANGE 5
|
||||||
#define PLAYHEAD_SIZE 6
|
#define PLAYHEAD_SIZE 6
|
||||||
|
|
||||||
TimelineHeader::TimelineHeader(QWidget *parent) : QWidget(parent)
|
TimelineHeader::TimelineHeader(QWidget *parent) : QWidget(parent), dragging(false), resizing_workarea(false) {
|
||||||
{
|
|
||||||
dragging = false;
|
|
||||||
setCursor(Qt::ArrowCursor);
|
setCursor(Qt::ArrowCursor);
|
||||||
|
setMouseTracking(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_playhead(QMouseEvent* event) {
|
void set_playhead(int mouse_x) {
|
||||||
long frame = panel_timeline->getFrameFromScreenPoint(event->pos().x());
|
long frame = panel_timeline->getFrameFromScreenPoint(mouse_x);
|
||||||
panel_timeline->snap_to_clip(&frame, false);
|
panel_timeline->snap_to_clip(&frame, false);
|
||||||
panel_timeline->seek(frame);
|
panel_timeline->seek(frame);
|
||||||
panel_timeline->repaint_timeline();
|
panel_timeline->repaint_timeline();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimelineHeader::mousePressEvent(QMouseEvent* event) {
|
void TimelineHeader::set_in_point(long new_in) {
|
||||||
/*if (panel_timeline->using_workarea) {
|
long new_out = sequence->workarea_out;
|
||||||
event->pos().x()
|
if (new_out == new_in) {
|
||||||
if (panel_timeline->workarea_in)
|
new_in--;
|
||||||
} else {
|
} else if (new_out < new_in) {
|
||||||
|
new_out = sequence->getEndFrame();
|
||||||
|
}
|
||||||
|
|
||||||
}*/
|
TimelineAction* ta = new TimelineAction();
|
||||||
set_playhead(event);
|
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;
|
dragging = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimelineHeader::mouseMoveEvent(QMouseEvent* event) {
|
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;
|
dragging = false;
|
||||||
panel_timeline->snapped = false;
|
panel_timeline->snapped = false;
|
||||||
panel_timeline->repaint_timeline();
|
panel_timeline->repaint_timeline();
|
||||||
@@ -60,9 +128,9 @@ void TimelineHeader::paintEvent(QPaintEvent*) {
|
|||||||
|
|
||||||
// draw in/out selection
|
// draw in/out selection
|
||||||
int in_x;
|
int in_x;
|
||||||
if (panel_timeline->using_workarea) {
|
if (sequence->using_workarea) {
|
||||||
in_x = panel_timeline->getScreenPointFromFrame(panel_timeline->workarea_in);
|
in_x = panel_timeline->getScreenPointFromFrame(resizing_workarea ? temp_workarea_in : sequence->workarea_in);
|
||||||
int out_x = panel_timeline->getScreenPointFromFrame(panel_timeline->workarea_out);
|
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.fillRect(QRect(in_x, 0, out_x-in_x, height()), QColor(0, 192, 255, 128));
|
||||||
p.setPen(Qt::white);
|
p.setPen(Qt::white);
|
||||||
p.drawLine(in_x, 0, in_x, height());
|
p.drawLine(in_x, 0, in_x, height());
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ class TimelineHeader : public QWidget
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit TimelineHeader(QWidget *parent = 0);
|
explicit TimelineHeader(QWidget *parent = 0);
|
||||||
|
void set_in_point(long p);
|
||||||
|
void set_out_point(long p);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent*);
|
void paintEvent(QPaintEvent*);
|
||||||
@@ -18,6 +20,12 @@ protected:
|
|||||||
private:
|
private:
|
||||||
bool dragging;
|
bool dragging;
|
||||||
|
|
||||||
|
bool resizing_workarea;
|
||||||
|
bool resizing_workarea_in;
|
||||||
|
long temp_workarea_in;
|
||||||
|
long temp_workarea_out;
|
||||||
|
long sequence_end;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|||||||
@@ -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
|
// apply changes to ghosts
|
||||||
for (int i=0;i<panel_timeline->ghosts.size();i++) {
|
for (int i=0;i<panel_timeline->ghosts.size();i++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user