[multimedia/kdenlive] src: timeremap: add keyframe type selector to remap dialog
Jean-Baptiste Mardelle <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit 0dd7b3a9b542b9b2f350eaaf83f0c8aa3277ee0e by Jean-Baptiste Mardelle, on behalf of Yash Bavadiya.
Committed on 18/08/2026 at 08:31.
Pushed by mardelle into branch 'master'.
timeremap: add keyframe type selector to remap dialog
M +30 -0 src/dialogs/timeremap.cpp
M +2 -0 src/dialogs/timeremap.h
M +14 -0 src/ui/timeremap_ui.ui
https://invent.kde.org/multimedia/kdenlive/-/commit/0dd7b3a9b542b9b2f350eaaf83f0c8aa3277ee0e
diff --git a/src/dialogs/timeremap.cpp b/src/dialogs/timeremap.cpp
index b24d5c9e8f..f0537efe19 100644
--- a/src/dialogs/timeremap.cpp
+++ b/src/dialogs/timeremap.cpp
@@ -6,6 +6,7 @@ SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#include "timeremap.h"
+#include "assets/keyframes/model/keyframemodel.hpp"
#include "bin/projectclip.h"
#include "core.h"
#include "doc/kdenlivedoc.h"
@@ -1356,6 +1357,25 @@ std::pair<double, double> RemapView::getSpeed(std::pair<int, int> kf)
return speeds;
}
+void RemapView::slotSetKeyframeType(int type)
+{
+ if (m_currentKeyframe.first == -1 || !m_keyframes.contains(m_currentKeyframe.first)) {
+ return;
+ }
+ if (keyframeTypeAt(m_currentKeyframe.first) == type) {
+ return;
+ }
+ m_keyframesOrigin = m_keyframes;
+ m_keyframeTypesOrigin = m_keyframeTypes;
+ if (type == KeyframeType::Linear) {
+ m_keyframeTypes.remove(m_currentKeyframe.first);
+ } else {
+ m_keyframeTypes.insert(m_currentKeyframe.first, type);
+ }
+ Q_EMIT updateKeyframesWithUndo(m_keyframes, m_keyframesOrigin);
+ update();
+}
+
void RemapView::addKeyframe()
{
// insert or remove keyframe at interpolated position
@@ -1692,7 +1712,17 @@ TimeRemap::TimeRemap(QWidget *parent)
speedBefore->setValue(100. * speeds.first);
speedAfter->setEnabled(!atEnd.second);
speedAfter->setValue(100. * speeds.second);
+ QSignalBlocker bk5(kfr_type);
+ kfr_type->setCurrentIndex(qMax(0, kfr_type->findData(m_view->keyframeTypeAt(selection.first))));
});
+ // TODO: the list is restricted to non overshooting interpolation types for
+ // now, pending a decision on how to handle types like bounce and elastic
+ // whose overshoot makes the source time briefly play backwards
+ const QMap<KeyframeType::KeyframeEnum, QString> kfrTypes = KeyframeModel::getKeyframeTypes();
+ for (auto type : {KeyframeType::Linear, KeyframeType::CurveSmooth, KeyframeType::CubicIn, KeyframeType::CubicOut}) {
+ kfr_type->addItem(kfrTypes.value(type), int(type));
+ }
+ connect(kfr_type, &QComboBox::activated, this, [this](int ix) { m_view->slotSetKeyframeType(kfr_type->itemData(ix).toInt()); });
connect(m_view, &RemapView::updateSpeeds, this, [this](std::pair<double, double> speeds) {
QSignalBlocker bk3(speedBefore);
QSignalBlocker bk4(speedAfter);
diff --git a/src/dialogs/timeremap.h b/src/dialogs/timeremap.h
index 71720fafc2..f5ad3b1929 100644
--- a/src/dialogs/timeremap.h
+++ b/src/dialogs/timeremap.h
@@ -74,6 +74,8 @@ public Q_SLOTS:
void goPrev();
void updateBeforeSpeed(double speed);
void updateAfterSpeed(double speed);
+ /** @brief Set the interpolation type of the currently selected keyframe */
+ void slotSetKeyframeType(int type);
void toggleMoveNext(bool moveNext);
void reloadProducer();
void centerCurrentKeyframe();
diff --git a/src/ui/timeremap_ui.ui b/src/ui/timeremap_ui.ui
index 545afda8e9..a9271f75bb 100644
--- a/src/ui/timeremap_ui.ui
+++ b/src/ui/timeremap_ui.ui
@@ -286,6 +286,20 @@ SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
</item>
</layout>
</item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_15">
+ <item>
+ <widget class="QLabel" name="label_type">
+ <property name="text">
+ <string>Type</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="kfr_type"/>
+ </item>
+ </layout>
+ </item>
</layout>
</widget>
</item>