From 6ce2533ada47f46fc25d0f266c88e68706a1a087 Mon Sep 17 00:00:00 2001 From: scribblemaniac Date: Sat, 5 Sep 2020 17:46:55 -0600 Subject: [PATCH 1/4] Add retiming feature This feature allows you to change the fps without affecting the speed of the animation. --- app/app.pro | 9 +- app/src/actioncommands.cpp | 13 +++ app/src/actioncommands.h | 1 + app/src/mainwindow2.cpp | 3 + app/src/retimedialog.cpp | 25 +++++ app/src/retimedialog.h | 25 +++++ app/ui/retimedialog.ui | 132 ++++++++++++++++++++++++ core_lib/src/interface/editor.cpp | 72 +++++++++++++ core_lib/src/interface/editor.h | 3 + core_lib/src/interface/timecontrols.cpp | 12 +++ core_lib/src/interface/timecontrols.h | 2 + core_lib/src/interface/timeline.cpp | 3 + core_lib/src/interface/timeline.h | 2 + 13 files changed, 299 insertions(+), 3 deletions(-) create mode 100644 app/src/retimedialog.cpp create mode 100644 app/src/retimedialog.h create mode 100644 app/ui/retimedialog.ui diff --git a/app/app.pro b/app/app.pro index 327028e6d8..1be96e368c 100644 --- a/app/app.pro +++ b/app/app.pro @@ -73,7 +73,8 @@ HEADERS += \ src/doubleprogressdialog.h \ src/colorslider.h \ src/checkupdatesdialog.h \ - src/presetdialog.h + src/presetdialog.h \ + src/retimedialog.h SOURCES += \ src/importlayersdialog.cpp \ @@ -109,7 +110,8 @@ SOURCES += \ src/colorslider.cpp \ src/checkupdatesdialog.cpp \ src/presetdialog.cpp \ - src/app_util.cpp + src/app_util.cpp \ + src/retimedialog.cpp FORMS += \ ui/importimageseqpreview.ui \ @@ -137,7 +139,8 @@ FORMS += \ ui/filespage.ui \ ui/toolspage.ui \ ui/toolboxwidget.ui \ - ui/presetdialog.ui + ui/presetdialog.ui \ + ui/retimedialog.ui diff --git a/app/src/actioncommands.cpp b/app/src/actioncommands.cpp index cbbc143b69..5fa3759e24 100644 --- a/app/src/actioncommands.cpp +++ b/app/src/actioncommands.cpp @@ -56,6 +56,7 @@ GNU General Public License for more details. #include "doubleprogressdialog.h" #include "checkupdatesdialog.h" #include "errordialog.h" +#include "retimedialog.h" ActionCommands::ActionCommands(QWidget* parent) : QObject(parent) @@ -578,6 +579,18 @@ void ActionCommands::deselectAll() mEditor->deselectAll(); } +void ActionCommands::retime() +{ + auto dialog = new RetimeDialog(mParent); + dialog->setOrigFps(mEditor->fps()); + dialog->exec(); + + if (dialog->result() == QDialog::Accepted) + { + mEditor->retime(dialog->getNewFps()); + } +} + void ActionCommands::ZoomIn() { mEditor->view()->scaleUp(); diff --git a/app/src/actioncommands.h b/app/src/actioncommands.h index e6603762fb..5c9ffa3a7b 100644 --- a/app/src/actioncommands.h +++ b/app/src/actioncommands.h @@ -49,6 +49,7 @@ class ActionCommands : public QObject void flipSelectionY(); void selectAll(); void deselectAll(); + void retime(); // view void ZoomIn(); diff --git a/app/src/mainwindow2.cpp b/app/src/mainwindow2.cpp index a2d63e955c..0f074fb61a 100644 --- a/app/src/mainwindow2.cpp +++ b/app/src/mainwindow2.cpp @@ -1452,6 +1452,7 @@ void MainWindow2::makeConnections(Editor* pEditor, TimeLine* pTimeline) connect(pTimeline, &TimeLine::newCameraLayer, mCommands, &ActionCommands::addNewCameraLayer); connect(mTimeLine, &TimeLine::playButtonTriggered, mCommands, &ActionCommands::PlayStop); + connect(mTimeLine, &TimeLine::retimeTriggered, mCommands, &ActionCommands::retime); connect(pEditor->layers(), &LayerManager::currentLayerChanged, pTimeline, &TimeLine::updateUI); connect(pEditor->layers(), &LayerManager::layerCountChanged, pTimeline, &TimeLine::updateUI); @@ -1461,6 +1462,8 @@ void MainWindow2::makeConnections(Editor* pEditor, TimeLine* pTimeline) connect(pEditor, &Editor::objectLoaded, pTimeline, &TimeLine::onObjectLoaded); connect(pEditor, &Editor::updateTimeLine, pTimeline, &TimeLine::updateUI); + connect(pEditor, &Editor::retimed, pTimeline, &TimeLine::updateFps); + connect(pEditor->layers(), &LayerManager::currentLayerChanged, mToolOptions, &ToolOptionWidget::updateUI); } diff --git a/app/src/retimedialog.cpp b/app/src/retimedialog.cpp new file mode 100644 index 0000000000..d9798a70dc --- /dev/null +++ b/app/src/retimedialog.cpp @@ -0,0 +1,25 @@ +#include "retimedialog.h" +#include "ui_retimedialog.h" + +RetimeDialog::RetimeDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::RetimeDialog) +{ + ui->setupUi(this); +} + +RetimeDialog::~RetimeDialog() +{ + delete ui; +} + +void RetimeDialog::setOrigFps(int origFps) +{ + ui->origFps->setText(QString("%1 %2").arg(origFps).arg(tr("fps"))); + ui->newFpsBox->setValue(origFps); +} + +int RetimeDialog::getNewFps() +{ + return ui->newFpsBox->value(); +} diff --git a/app/src/retimedialog.h b/app/src/retimedialog.h new file mode 100644 index 0000000000..cbc303a639 --- /dev/null +++ b/app/src/retimedialog.h @@ -0,0 +1,25 @@ +#ifndef RETIMEDIALOG_H +#define RETIMEDIALOG_H + +#include + +namespace Ui { +class RetimeDialog; +} + +class RetimeDialog : public QDialog +{ + Q_OBJECT + +public: + explicit RetimeDialog(QWidget *parent = nullptr); + ~RetimeDialog(); + + void setOrigFps(int origFps); + int getNewFps(); + +private: + Ui::RetimeDialog *ui; +}; + +#endif // RETIMEDIALOG_H diff --git a/app/ui/retimedialog.ui b/app/ui/retimedialog.ui new file mode 100644 index 0000000000..44245e8bb1 --- /dev/null +++ b/app/ui/retimedialog.ui @@ -0,0 +1,132 @@ + + + RetimeDialog + + + + 0 + 0 + 400 + 261 + + + + Dialog + + + + + + <h1>Retime Project</h1> + + + + + + + Retiming allows you to change the FPS of your project without affecting the speed of your project. It accomplishes this by moving the frames closer together or further apart. + + + true + + + + + + + + + Original: + + + + + + + <span style=" font-weight:600;">12 fps</span> + + + + + + + New: + + + + + + + fps + + + 1 + + + 90 + + + 12 + + + + + + + + + <html><head/><body><p><span style=" color:red;">Warning: Retiming while decreasing the FPS may result in the loss of frames. This action cannot be undone.</span></p></body></html> + + + true + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + RetimeDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + RetimeDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/core_lib/src/interface/editor.cpp b/core_lib/src/interface/editor.cpp index 1b38db6361..8941781611 100644 --- a/core_lib/src/interface/editor.cpp +++ b/core_lib/src/interface/editor.cpp @@ -126,10 +126,82 @@ void Editor::setFps(int fps) mPreferenceManager->set(SETTING::FPS, fps); } +void Editor::retime(int newFps) +{ + const int origFps = fps(); + if(origFps == newFps) return; + const qreal multiplier = static_cast(newFps) / origFps; + + for (int i = 0; i < mObject->getLayerCount(); i++) + { + Layer* layer = mObject->getLayer(i); + QMap frameRemap; // New frame -> old frame + QList deleteFrames; + for (int origPos = layer->firstKeyFramePosition(); origPos <= layer->getMaxKeyFramePosition(); origPos++) + { + if (layer->keyExists(origPos)) + { + // Scale the current position to the new fps + // The offset is to make sure that frame 1 stays at frame 1 + int newPos = qRound((origPos-1)*multiplier)+1; + if (frameRemap.contains(newPos)) + { + // If two frames get mapped to the same new frame, choose the closer of them + if (qAbs((frameRemap.value(newPos)-1)*multiplier+1-newPos) > qAbs((origPos-1)*multiplier+1-newPos)) + { + deleteFrames.append(frameRemap.value(newPos)); + frameRemap.insert(newPos, origPos); + } + else + { + deleteFrames.append(origPos); + } + } + else + { + frameRemap.insert(newPos, origPos); + } + } + } + + foreach (const int frame, deleteFrames) + { + layer->removeKeyFrame(frame); + } + + if (multiplier < 1) + { + for (auto iter = frameRemap.constBegin(); iter != frameRemap.constEnd(); iter++) + { + if (iter.value() != iter.key()) + { + layer->swapKeyFrames(iter.value(), iter.key()); + } + } + } + else + { + for (auto iter = frameRemap.keys().crbegin(); iter != frameRemap.keys().crend(); iter++) + { + if (frameRemap.value(*iter) != *iter) + { + layer->swapKeyFrames(frameRemap.value(*iter), *iter); + } + } + } + } + + setFps(newFps); + layers()->notifyAnimationLengthChanged(); + emit retimed(newFps); +} + void Editor::makeConnections() { connect(mPreferenceManager, &PreferenceManager::optionChanged, this, &Editor::settingUpdated); connect(QApplication::clipboard(), &QClipboard::dataChanged, this, &Editor::clipboardChanged); + + connect(this, &Editor::retimed, playback(), &PlaybackManager::setFps); } void Editor::dragEnterEvent(QDragEnterEvent* event) diff --git a/core_lib/src/interface/editor.h b/core_lib/src/interface/editor.h index 6f9dd72a6d..fc602c939d 100644 --- a/core_lib/src/interface/editor.h +++ b/core_lib/src/interface/editor.h @@ -91,6 +91,7 @@ class Editor : public QObject int currentFrame(); int fps(); void setFps(int fps); + void retime(int newFps); int currentLayerIndex() { return mCurrentLayerIndex; } void setCurrentLayerIndex(int i); @@ -131,6 +132,8 @@ class Editor : public QObject void needDisplayInfo(const QString& title, const QString& body); void needDisplayInfoNoTitle(const QString& body); + void retimed(int newFps); + public: //slots void clearCurrentFrame(); diff --git a/core_lib/src/interface/timecontrols.cpp b/core_lib/src/interface/timecontrols.cpp index fffd6e0aeb..989418123a 100644 --- a/core_lib/src/interface/timecontrols.cpp +++ b/core_lib/src/interface/timecontrols.cpp @@ -18,6 +18,7 @@ GNU General Public License for more details. #include "timecontrols.h" #include +#include #include #include "editor.h" @@ -46,6 +47,11 @@ void TimeControls::initUI() mFpsBox->setSuffix(tr(" fps")); mFpsBox->setToolTip(tr("Frames per second")); mFpsBox->setFocusPolicy(Qt::WheelFocus); + mFpsBox->setContextMenuPolicy(Qt::ActionsContextMenu); + QMenu *mFpsMenu = new QMenu(mFpsBox); + QAction *retimeAction = new QAction(tr("Retime"), mFpsMenu); + connect(retimeAction, &QAction::triggered, this, &TimeControls::retimeTriggered); + mFpsBox->addAction(retimeAction); mLoopStartSpinBox = new QSpinBox(this); mLoopStartSpinBox->setFixedHeight(24); @@ -209,6 +215,12 @@ void TimeControls::updatePlayState() } } +void TimeControls::updateFps(int fps) +{ + QSignalBlocker b(mFpsBox); + mFpsBox->setValue(fps); +} + void TimeControls::jumpToStartButtonClicked() { if (mPlaybackRangeCheckBox->isChecked()) diff --git a/core_lib/src/interface/timecontrols.h b/core_lib/src/interface/timecontrols.h index 0c15c7138a..bf33033bd1 100644 --- a/core_lib/src/interface/timecontrols.h +++ b/core_lib/src/interface/timecontrols.h @@ -52,8 +52,10 @@ class TimeControls : public QToolBar void soundScrubToggled(bool); void fpsChanged(int); void playButtonTriggered(); + void retimeTriggered(); public slots: + void updateFps(int fps); /// Work-around in case the FPS spin-box "valueChanged" signal doesn't work. void onFpsEditingFinished(); diff --git a/core_lib/src/interface/timeline.cpp b/core_lib/src/interface/timeline.cpp index af9f7d6a1c..8ffa2a6c78 100644 --- a/core_lib/src/interface/timeline.cpp +++ b/core_lib/src/interface/timeline.cpp @@ -209,6 +209,7 @@ void TimeLine::initUI() connect(mTimeControls, &TimeControls::fpsChanged, this, &TimeLine::fpsChanged); connect(mTimeControls, &TimeControls::fpsChanged, this, &TimeLine::updateLength); connect(mTimeControls, &TimeControls::playButtonTriggered, this, &TimeLine::playButtonTriggered); + connect(mTimeControls, &TimeControls::retimeTriggered, this, &TimeLine::retimeTriggered); connect(newBitmapLayerAct, &QAction::triggered, this, &TimeLine::newBitmapLayer); connect(newVectorLayerAct, &QAction::triggered, this, &TimeLine::newVectorLayer); @@ -222,6 +223,8 @@ void TimeLine::initUI() connect(editor(), &Editor::currentFrameChanged, this, &TimeLine::updateFrame); + connect(this, &TimeLine::updateFps, mTimeControls, &TimeControls::updateFps); + LayerManager* layer = editor()->layers(); connect(layer, &LayerManager::layerCountChanged, this, &TimeLine::updateLayerNumber); mNumLayers = layer->count(); diff --git a/core_lib/src/interface/timeline.h b/core_lib/src/interface/timeline.h index c457bb8cc8..9ed5db14a0 100644 --- a/core_lib/src/interface/timeline.h +++ b/core_lib/src/interface/timeline.h @@ -70,6 +70,8 @@ class TimeLine : public BaseDockWidget void onionPrevClick(); void onionNextClick(); void playButtonTriggered(); + void retimeTriggered(); + void updateFps(int fps); public: bool scrubbing = false; From e256c75b089a522cb72c7170147154e87c2684e1 Mon Sep 17 00:00:00 2001 From: scribblemaniac Date: Sat, 5 Sep 2020 20:38:47 -0600 Subject: [PATCH 2/4] Add retime menu item and shortcut --- app/src/actioncommands.cpp | 24 ++++++++++++------------ app/src/actioncommands.h | 2 +- app/src/mainwindow2.cpp | 2 ++ app/src/shortcutspage.cpp | 1 + app/ui/mainwindow2.ui | 8 +++++++- core_lib/data/resources/kb.ini | 1 + core_lib/src/util/pencildef.h | 1 + 7 files changed, 25 insertions(+), 14 deletions(-) diff --git a/app/src/actioncommands.cpp b/app/src/actioncommands.cpp index 5fa3759e24..74b60484e2 100644 --- a/app/src/actioncommands.cpp +++ b/app/src/actioncommands.cpp @@ -579,18 +579,6 @@ void ActionCommands::deselectAll() mEditor->deselectAll(); } -void ActionCommands::retime() -{ - auto dialog = new RetimeDialog(mParent); - dialog->setOrigFps(mEditor->fps()); - dialog->exec(); - - if (dialog->result() == QDialog::Accepted) - { - mEditor->retime(dialog->getNewFps()); - } -} - void ActionCommands::ZoomIn() { mEditor->view()->scaleUp(); @@ -773,6 +761,18 @@ void ActionCommands::moveFrameBackward() } } +void ActionCommands::retime() +{ + auto dialog = new RetimeDialog(mParent); + dialog->setOrigFps(mEditor->fps()); + dialog->exec(); + + if (dialog->result() == QDialog::Accepted) + { + mEditor->retime(dialog->getNewFps()); + } +} + Status ActionCommands::addNewBitmapLayer() { bool ok; diff --git a/app/src/actioncommands.h b/app/src/actioncommands.h index 5c9ffa3a7b..d0688a09c1 100644 --- a/app/src/actioncommands.h +++ b/app/src/actioncommands.h @@ -49,7 +49,6 @@ class ActionCommands : public QObject void flipSelectionY(); void selectAll(); void deselectAll(); - void retime(); // view void ZoomIn(); @@ -71,6 +70,7 @@ class ActionCommands : public QObject void duplicateKey(); void moveFrameForward(); void moveFrameBackward(); + void retime(); // Layer Status addNewBitmapLayer(); diff --git a/app/src/mainwindow2.cpp b/app/src/mainwindow2.cpp index 0f074fb61a..0579e1f90c 100644 --- a/app/src/mainwindow2.cpp +++ b/app/src/mainwindow2.cpp @@ -352,6 +352,7 @@ void MainWindow2::createMenus() connect(ui->actionDuplicate_Frame, &QAction::triggered, mCommands, &ActionCommands::duplicateKey); connect(ui->actionMove_Frame_Forward, &QAction::triggered, mCommands, &ActionCommands::moveFrameForward); connect(ui->actionMove_Frame_Backward, &QAction::triggered, mCommands, &ActionCommands::moveFrameBackward); + connect(ui->actionRetime, &QAction::triggered, mCommands, &ActionCommands::retime); //--- Tool Menu --- connect(ui->actionMove, &QAction::triggered, mToolBox, &ToolBoxWidget::moveOn); @@ -1243,6 +1244,7 @@ void MainWindow2::setupKeyboardShortcuts() ui->actionRemove_Frame->setShortcut(cmdKeySeq(CMD_REMOVE_FRAME)); ui->actionMove_Frame_Backward->setShortcut(cmdKeySeq(CMD_MOVE_FRAME_BACKWARD)); ui->actionMove_Frame_Forward->setShortcut(cmdKeySeq(CMD_MOVE_FRAME_FORWARD)); + ui->actionRetime->setShortcut(cmdKeySeq(CMD_RETIME)); ui->actionFlip_inbetween->setShortcut(cmdKeySeq(CMD_FLIP_INBETWEEN)); ui->actionFlip_rolling->setShortcut(cmdKeySeq(CMD_FLIP_ROLLING)); diff --git a/app/src/shortcutspage.cpp b/app/src/shortcutspage.cpp index 355f78549b..82733255fe 100644 --- a/app/src/shortcutspage.cpp +++ b/app/src/shortcutspage.cpp @@ -330,6 +330,7 @@ static QString getHumanReadableShortcutName(const QString& cmdName) {CMD_LOOP, QObject::tr("Toggle Loop", "Shortcut")}, {CMD_MOVE_FRAME_BACKWARD, QObject::tr("Move Frame Backward", "Shortcut")}, {CMD_MOVE_FRAME_FORWARD, QObject::tr("Move Frame Forward", "Shortcut")}, + {CMD_RETIME, QObject::tr("Retime Animation", "Shortcut")}, {CMD_NEW_BITMAP_LAYER, QObject::tr("New Bitmap Layer", "Shortcut")}, {CMD_NEW_CAMERA_LAYER, QObject::tr("New Camera Layer", "Shortcut")}, {CMD_NEW_FILE, QObject::tr("New File", "Shortcut")}, diff --git a/app/ui/mainwindow2.ui b/app/ui/mainwindow2.ui index 3e312785d2..ae41f6e776 100644 --- a/app/ui/mainwindow2.ui +++ b/app/ui/mainwindow2.ui @@ -49,7 +49,7 @@ 0 0 831 - 30 + 24 @@ -197,6 +197,7 @@ + @@ -1089,6 +1090,11 @@ Open Temporary Directory + + + Retime Animation + + diff --git a/core_lib/data/resources/kb.ini b/core_lib/data/resources/kb.ini index 40e0ac7e3e..45a507f42f 100644 --- a/core_lib/data/resources/kb.ini +++ b/core_lib/data/resources/kb.ini @@ -50,6 +50,7 @@ CmdGotoNextKeyFrame=Alt+. CmdGotoPreviousKeyFrame=Alt+"," CmdMoveFrameForward=Ctrl+. CmdMoveFrameBackward=ctrl+"," +CmdRetime= CmdAddFrame=F7 CmdDuplicateFrame=F6 CmdRemoveFrame=Shift+F5 diff --git a/core_lib/src/util/pencildef.h b/core_lib/src/util/pencildef.h index f638ebbd12..8879524518 100644 --- a/core_lib/src/util/pencildef.h +++ b/core_lib/src/util/pencildef.h @@ -151,6 +151,7 @@ const static int MaxFramesBound = 9999; #define CMD_REMOVE_FRAME "CmdRemoveFrame" #define CMD_MOVE_FRAME_BACKWARD "CmdMoveFrameBackward" #define CMD_MOVE_FRAME_FORWARD "CmdMoveFrameForward" +#define CMD_RETIME "CmdRetime" #define CMD_TOOL_MOVE "CmdToolMove" #define CMD_TOOL_SELECT "CmdToolSelect" #define CMD_TOOL_BRUSH "CmdToolBrush" From f2d1656f46be8a9e0a49879f182ce4eb69dc4ded Mon Sep 17 00:00:00 2001 From: scribblemaniac Date: Sat, 5 Sep 2020 21:12:09 -0600 Subject: [PATCH 3/4] Add speed option to retiming dialog --- app/src/actioncommands.cpp | 2 +- app/src/retimedialog.cpp | 5 +++ app/src/retimedialog.h | 2 + app/ui/retimedialog.ui | 74 +++++++++++++++++++++++++++---- core_lib/src/interface/editor.cpp | 7 +-- core_lib/src/interface/editor.h | 2 +- 6 files changed, 79 insertions(+), 13 deletions(-) diff --git a/app/src/actioncommands.cpp b/app/src/actioncommands.cpp index 74b60484e2..665a6d4c1d 100644 --- a/app/src/actioncommands.cpp +++ b/app/src/actioncommands.cpp @@ -769,7 +769,7 @@ void ActionCommands::retime() if (dialog->result() == QDialog::Accepted) { - mEditor->retime(dialog->getNewFps()); + mEditor->retime(dialog->getNewFps(), dialog->getNewSpeed()); } } diff --git a/app/src/retimedialog.cpp b/app/src/retimedialog.cpp index d9798a70dc..d6e1bcd4ce 100644 --- a/app/src/retimedialog.cpp +++ b/app/src/retimedialog.cpp @@ -23,3 +23,8 @@ int RetimeDialog::getNewFps() { return ui->newFpsBox->value(); } + +qreal RetimeDialog::getNewSpeed() +{ + return ui->newSpeedBox->value(); +} diff --git a/app/src/retimedialog.h b/app/src/retimedialog.h index cbc303a639..dc78d0b9e4 100644 --- a/app/src/retimedialog.h +++ b/app/src/retimedialog.h @@ -18,6 +18,8 @@ class RetimeDialog : public QDialog void setOrigFps(int origFps); int getNewFps(); + qreal getNewSpeed(); + private: Ui::RetimeDialog *ui; }; diff --git a/app/ui/retimedialog.ui b/app/ui/retimedialog.ui index 44245e8bb1..ecc9ea06f0 100644 --- a/app/ui/retimedialog.ui +++ b/app/ui/retimedialog.ui @@ -6,8 +6,8 @@ 0 0 - 400 - 261 + 456 + 335 @@ -17,14 +17,14 @@ - <h1>Retime Project</h1> + <h1>Retime Animation</h1> - Retiming allows you to change the FPS of your project without affecting the speed of your project. It accomplishes this by moving the frames closer together or further apart. + Retiming allows you to adjust the FPS and playback speed of your project independently. It accomplishes this by moving the frames closer together or further apart to reach the desired speed and frame rate. true @@ -32,9 +32,16 @@ - + + + <span style=" text-decoration: underline;">Frame Rate</span> + + + + + - + Original: @@ -48,7 +55,7 @@ - + New: @@ -72,10 +79,61 @@ + + + + <span style=" text-decoration: underline;">Speed</span> + + + + + + + + + Original: + + + + + + + <span style=" font-weight:600;">1.00x</span> + + + + + + + New: + + + + + + + x + + + 0.010000000000000 + + + 90.000000000000000 + + + 0.100000000000000 + + + 1.000000000000000 + + + + + - <html><head/><body><p><span style=" color:red;">Warning: Retiming while decreasing the FPS may result in the loss of frames. This action cannot be undone.</span></p></body></html> + <html><head/><body><p><span style=" color:red;">Warning: Retiming to a lower fps or higher speed may result in the loss of frames. This action cannot be undone.</span></p></body></html> true diff --git a/core_lib/src/interface/editor.cpp b/core_lib/src/interface/editor.cpp index 8941781611..d45b309611 100644 --- a/core_lib/src/interface/editor.cpp +++ b/core_lib/src/interface/editor.cpp @@ -126,11 +126,11 @@ void Editor::setFps(int fps) mPreferenceManager->set(SETTING::FPS, fps); } -void Editor::retime(int newFps) +void Editor::retime(int newFps, qreal speed) { const int origFps = fps(); - if(origFps == newFps) return; - const qreal multiplier = static_cast(newFps) / origFps; + const qreal multiplier = (static_cast(newFps) / origFps) * (1 / speed); + if (qFuzzyCompare(multiplier, 1)) return; for (int i = 0; i < mObject->getLayerCount(); i++) { @@ -194,6 +194,7 @@ void Editor::retime(int newFps) setFps(newFps); layers()->notifyAnimationLengthChanged(); emit retimed(newFps); + emit updateTimeLine(); } void Editor::makeConnections() diff --git a/core_lib/src/interface/editor.h b/core_lib/src/interface/editor.h index fc602c939d..cc0c8a9ff4 100644 --- a/core_lib/src/interface/editor.h +++ b/core_lib/src/interface/editor.h @@ -91,7 +91,7 @@ class Editor : public QObject int currentFrame(); int fps(); void setFps(int fps); - void retime(int newFps); + void retime(int newFps, qreal speed); int currentLayerIndex() { return mCurrentLayerIndex; } void setCurrentLayerIndex(int i); From da03577c830cacea76533f5cfe3d4f21689d69cd Mon Sep 17 00:00:00 2001 From: scribblemaniac Date: Sat, 5 Sep 2020 23:22:41 -0600 Subject: [PATCH 4/4] Fix retime dialog title --- app/ui/retimedialog.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/ui/retimedialog.ui b/app/ui/retimedialog.ui index ecc9ea06f0..04a105729c 100644 --- a/app/ui/retimedialog.ui +++ b/app/ui/retimedialog.ui @@ -11,7 +11,7 @@ - Dialog + Retime Animation