diff --git a/dialogs/speeddialog.cpp b/dialogs/speeddialog.cpp index bb2de5ffe..ba35fc5f1 100644 --- a/dialogs/speeddialog.cpp +++ b/dialogs/speeddialog.cpp @@ -25,6 +25,7 @@ SpeedDialog::SpeedDialog(QWidget *parent) : QDialog(parent) { percent = new LabelSlider(); percent->decimal_places = 2; percent->set_display_type(LABELSLIDER_PERCENT); + percent->set_default_value(1); grid->addWidget(percent, 0, 1); grid->addWidget(new QLabel("Frame Rate:"), 1, 0); @@ -56,53 +57,93 @@ SpeedDialog::SpeedDialog(QWidget *parent) : QDialog(parent) { } void SpeedDialog::run() { - if (clips.size() > 1) { - qDebug() << "[WARNING] Setting multiple clip speeds at once is unsupported and may break things - sorry!"; + bool enable_frame_rate = false; + + default_frame_rate = NAN; + current_frame_rate = NAN; + current_percent = NAN; + default_length = -1; + current_length = -1; + + for (int i=0;itrack < 0) { + double media_frame_rate = c->getMediaFrameRate(); + + clip_percent = c->frame_rate / media_frame_rate; + + // get "default" frame rate" + if (enable_frame_rate) { + // check if frame rate is equal to default + if (!qIsNaN(default_frame_rate) && media_frame_rate != default_frame_rate) { + default_frame_rate = NAN; + } + } else { + default_frame_rate = media_frame_rate; + } + + enable_frame_rate = true; + } else { + clip_percent = c->frame_rate; + + if (i > 0) { + if (!qIsNaN(default_percent) && c->frame_rate != default_percent) { + default_percent = NAN; + } + } else { + default_percent = c->frame_rate; + } + } + + // get default length + if (i == 0) { + current_length = c->getLength(); + default_length = qRound(c->getLength() * clip_percent); + } else if (current_length != -1 && c->getLength() != current_length) { + current_length = -1; + } } - normal_fr = 1; - - Clip* first_clip = clips.at(0); - - switch (first_clip->media_type) { - case MEDIA_TYPE_FOOTAGE: - normal_fr = static_cast(first_clip->media)->get_stream_from_file_index(true, first_clip->media_stream)->video_frame_rate; - break; - case MEDIA_TYPE_SEQUENCE: - normal_fr = static_cast(first_clip->media)->frame_rate; - break; - } - - frame_rate->set_default_value(first_clip->frame_rate); - percent->set_default_value((first_clip->frame_rate / normal_fr) * 100); - duration->set_default_value(first_clip->getLength()); + frame_rate->setEnabled(enable_frame_rate); + frame_rate->set_default_value(default_frame_rate); + frame_rate->set_value(current_frame_rate, false); + percent->set_value(current_percent, false); + duration->set_default_value(default_length); exec(); } void SpeedDialog::percent_update() { - double pc = (percent->value()*0.01); - frame_rate->set_value(normal_fr * pc, false); - duration->set_value(clips.at(0)->getLength() / pc, false); + frame_rate->set_value(default_frame_rate * percent->value(), false); + duration->set_value(clips.at(0)->getLength() / percent->value(), false); } void SpeedDialog::duration_update() { double pc = clips.at(0)->getLength() / duration->value(); - frame_rate->set_value(normal_fr * pc, false); - percent->set_value(pc * 100, false); + frame_rate->set_value(default_frame_rate * pc, false); + percent->set_value(pc, false); } void SpeedDialog::frame_rate_update() { double fr = (frame_rate->value()); - double pc = (fr / normal_fr); - percent->set_value(pc * 100, false); + double pc = (fr / default_frame_rate); + percent->set_value(pc, false); duration->set_value(clips.at(0)->getLength() / pc, false); } void SpeedDialog::accept() { for (int i=0;iframe_rate = frame_rate->value(); - close_clip(clips.at(i)); + Clip* c = clips.at(i); + if (c->track < 0) { + c->frame_rate = frame_rate->value(); + } else { + c->frame_rate = percent->value(); + } + close_clip(c); } QDialog::accept(); } diff --git a/dialogs/speeddialog.h b/dialogs/speeddialog.h index c6f1e51bc..e466cfc70 100644 --- a/dialogs/speeddialog.h +++ b/dialogs/speeddialog.h @@ -27,7 +27,11 @@ private: QCheckBox* reverse; - double normal_fr; + double default_frame_rate; + double current_frame_rate; + double current_percent; + long default_length; + long current_length; }; #endif // SPEEDDIALOG_H diff --git a/project/clip.cpp b/project/clip.cpp index f67679c8f..0e6c4935a 100644 --- a/project/clip.cpp +++ b/project/clip.cpp @@ -192,6 +192,16 @@ long Clip::getMediaLength(double framerate) { return 0; } +double Clip::getMediaFrameRate() { + Q_ASSERT(track < 0); + switch (media_type) { + case MEDIA_TYPE_FOOTAGE: return static_cast(media)->get_stream_from_file_index(track < 0, media_stream)->video_frame_rate; + case MEDIA_TYPE_SEQUENCE: return static_cast(media)->frame_rate; + } + if (sequence != NULL) return sequence->frame_rate; + return NAN; +} + int Clip::getWidth() { if (media == NULL && sequence != NULL) return sequence->width; switch (media_type) { diff --git a/project/clip.h b/project/clip.h index 5e1f2407b..51e9186bc 100644 --- a/project/clip.h +++ b/project/clip.h @@ -64,6 +64,7 @@ struct Clip quint8 color_b; long getLength(); long getMediaLength(double framerate); + double getMediaFrameRate(); void* media; // attached media int media_type; int media_stream; diff --git a/ui/labelslider.cpp b/ui/labelslider.cpp index 1a5316ab3..ac2ef918a 100644 --- a/ui/labelslider.cpp +++ b/ui/labelslider.cpp @@ -53,11 +53,15 @@ bool LabelSlider::is_dragging() { } QString LabelSlider::valueToString(double v) { - switch (display_type) { - case LABELSLIDER_FRAMENUMBER: return frame_to_timecode(v, config.timecode_view, sequence->frame_rate); - case LABELSLIDER_PERCENT: return QString::number(v, 'f', decimal_places) + "%"; + if (qIsNaN(v)) { + return "---"; + } else { + switch (display_type) { + case LABELSLIDER_FRAMENUMBER: return frame_to_timecode(v, config.timecode_view, sequence->frame_rate); + case LABELSLIDER_PERCENT: return QString::number((v*100), 'f', decimal_places) + "%"; + } + return QString::number(v, 'f', decimal_places); } - return QString::number(v, 'f', decimal_places); } double LabelSlider::getPreviousValue() { @@ -98,6 +102,8 @@ void LabelSlider::mousePressEvent(QMouseEvent *ev) { set_value(default_value, true); } } else { + if (qIsNaN(internal_value)) internal_value = 0; + qApp->setOverrideCursor(Qt::BlankCursor); drag_start = true; drag_start_x = cursor().pos().x(); @@ -108,7 +114,12 @@ 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); + int diff = (cursor().pos().x()-drag_start_x) + (drag_start_y-cursor().pos().y()); + if (display_type == LABELSLIDER_PERCENT) { + set_value(internal_value + (diff*0.01), true); + } else { + set_value(internal_value + diff, true); + } cursor().setPos(drag_start_x, drag_start_y); } }