Commit c96f9f61 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

First proof of concept ui for time remap

parent 9a65c2e8
Pipeline #67465 passed with stage
in 20 minutes and 52 seconds
......@@ -337,8 +337,8 @@ void WheelContainer::resizeEvent(QResizeEvent *event)
const QString WheelContainer::getParamValues() const
{
return QString::number(m_color.redF() * m_sizeFactor, 'g', 3) + QLatin1Char(',') + QString::number(m_color.greenF() * m_sizeFactor, 'g', 3) +
QLatin1Char(',') + QString::number(m_color.blueF() * m_sizeFactor, 'g', 3);
return QString::number(m_color.redF() * m_sizeFactor, 'f', 3) + QLatin1Char(',') + QString::number(m_color.greenF() * m_sizeFactor, 'f', 3) +
QLatin1Char(',') + QString::number(m_color.blueF() * m_sizeFactor, 'f', 3);
}
const QList <double> WheelContainer::getNiceParamValues() const
......
......@@ -4508,3 +4508,36 @@ void Bin::requestTranscoding(const QString &url, const QString &id)
m_transcodingDialog->addUrl(url, id);
m_transcodingDialog->show();
}
void Bin::remapCurrent()
{
std::shared_ptr<ProjectClip> clip = getFirstSelectedClip();
if (clip) {
QFileInfo info(clip->url());
QDir dir =info.absoluteDir();
QString fName = info.fileName().section(QLatin1Char('.'),0, -2);
fName.append("-remap");
int ix = 1;
QString renderName = QString("%1%2.mlt").arg(fName).arg(QString::number(ix, 'f', 3));
while (dir.exists(renderName)) {
ix++;
renderName = QString("%1%2.mlt").arg(fName).arg(QString::number(ix, 'f', 3));
}
Mlt::Consumer consumer(pCore->getCurrentProfile()->profile(), "xml", dir.absoluteFilePath(renderName).toUtf8().constData());
consumer.set("terminate_on_pause", 1);
consumer.set("title", "Time remap");
consumer.set("real_time", -1);
Mlt::Tractor t(pCore->getCurrentProfile()->profile());
Mlt::Chain chain(pCore->getCurrentProfile()->profile(), nullptr, clip->url().toUtf8().constData());
Mlt::Link link("timeremap");
chain.attach(link);
t.set_track(chain, 0);
consumer.connect(t);
consumer.run();
Fun undo = []() { return true; };
Fun redo = []() { return true; };
auto id = ClipCreator::createClipFromFile(dir.absoluteFilePath(renderName), getCurrentFolder(), pCore->projectItemModel(), undo, redo);
pCore->pushUndo(undo, redo, i18n("Add clip remap"));
selectClipById(id);
}
}
......@@ -461,6 +461,8 @@ public slots:
*/
void checkProjectAudioTracks(QString clipId, int minimumTracksCount);
void showTitleWidget(const std::shared_ptr<ProjectClip> &clip);
/** @brief Create a playlist clip for timeremap. */
void remapCurrent();
protected:
/* This function is called whenever an item is selected to propagate signals
......
This diff is collapsed.
......@@ -28,6 +28,8 @@
#include <QWidget>
#include "mlt++/Mlt.h"
class ProjectClip;
......@@ -39,21 +41,72 @@ class ProjectClip;
class RemapView : public QWidget
{
Q_OBJECT
public:
explicit RemapView(QWidget *parent = nullptr);
void setDuration(int duration);
void loadKeyframes(std::shared_ptr<ProjectClip> clip, const QString &mapData);
const QString getKeyframesData(std::shared_ptr<ProjectClip> clip) const;
protected:
void paintEvent(QPaintEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
public slots:
void updateInPos(int pos);
void updateOutPos(int pos);
void slotSetPosition(int pos);
void addKeyframe();
void goNext();
void goPrev();
void updateBeforeSpeed(double speed);
void updateAfterSpeed(double speed);
void toggleMoveNext(bool moveNext);
private:
enum MOVEMODE {NoMove, TopMove, BottomMove, CursorMove};
int m_duration;
int m_position;
double m_scale;
QColor m_colSelected;
QColor m_colKeyframe;
int m_zoomHeight;
int m_lineHeight;
double m_zoomFactor;
double m_zoomStart;
QMap<int, int>m_keyframes;
/** @brief The zoom factor (start, end - between 0 and 1) */
QPointF m_zoomHandle;
QPointF m_lastZoomHandle;
/** @brief Mouse is the zoom left handle */
bool m_hoverZoomIn;
/** @brief Mouse is the zoom right handle */
bool m_hoverZoomOut;
/** @brief Mouse is over the zoom bar */
bool m_hoverZoom;
std::pair<int, bool> m_hoverKeyframe;
int m_bottomView;
std::pair<int, int> m_currentKeyframe;
std::pair<int,int> m_currentKeyframeOriginal;
MOVEMODE m_moveKeyframeMode;
double m_clickOffset;
int m_clickPoint;
bool m_moveNext;
int m_clickEnd;
int m_offset;
QMap <int,int>m_selectedKeyframes;
int getClosestKeyframe(int pos, bool bottomKeyframe = false) const;
std::pair<double,double> getSpeed(std::pair<int,int>kf);
signals:
void seekToPos(int);
void selectedKf(std::pair<int,int>, std::pair<double,double>);
/** When the cursor position changes inform parent if we are on a keyframe or not. */
void atKeyframe(bool);
void updateKeyframes();
};
/**
......@@ -70,11 +123,16 @@ public:
~TimeRemap() override;
void setClip(std::shared_ptr<ProjectClip> clip, int in = -1, int out = -1);
private slots:
void updateKeyframes();
private:
std::shared_ptr<ProjectClip> m_clip;
std::shared_ptr<Mlt::Link>m_remapLink;
TimecodeDisplay *m_in;
TimecodeDisplay *m_out;
RemapView *m_view;
};
#endif
......@@ -271,7 +271,6 @@ void MainWindow::init(const QString &mltPath)
QDockWidget *subtitlesDock = addDock(i18n("Subtitles"), QStringLiteral("Subtitles"), pCore->subtitleWidget());
QDockWidget *textEditingDock = addDock(i18n("Text Edit"), QStringLiteral("textedit"), pCore->textEditWidget());
QDockWidget *timeRemapDock = addDock(i18n("Time Remapping"), QStringLiteral("timeremap"), pCore->timeRemapWidget());
m_clipMonitor = new Monitor(Kdenlive::ClipMonitor, pCore->monitorManager(), this);
pCore->bin()->setMonitor(m_clipMonitor);
connect(m_clipMonitor, &Monitor::addMarker, this, &MainWindow::slotAddMarkerGuideQuickly);
......@@ -3550,6 +3549,12 @@ void MainWindow::buildDynamicActions()
[&]() { emit pCore->jobManager()->startJob<SpeedJob>(pCore->bin()->selectedClipsIds(true), {}, i18n("Change clip speed")); });
}
if (true /* TODO: check if timeremap link is available */) {
QAction *action = new QAction(i18n("Duplicate clip with time remap"), m_extraFactory->actionCollection());
ts->addAction(action->text(), action);
connect(action, &QAction::triggered, pCore->bin(), &Bin::remapCurrent);
}
// TODO refac reimplement analyseclipjob
/*
QAction *action = new QAction(i18n("Analyse keyframes"), m_extraFactory->actionCollection());
......
......@@ -6,111 +6,163 @@
<rect>
<x>0</x>
<y>0</y>
<width>375</width>
<height>140</height>
<width>319</width>
<height>200</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="8">
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>6</number>
</property>
<property name="verticalSpacing">
<number>0</number>
</property>
<item row="0" column="0" colspan="5">
<layout class="QVBoxLayout" name="remapLayout"/>
</item>
<item row="3" column="1">
<spacer name="verticalSpacer">
<item row="1" column="2">
<widget class="QToolButton" name="button_next">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset theme="go-next">
<normaloff>../../../../.designer/backup</normaloff>../../../../.designer/backup</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="4">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>39</height>
<width>28</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Source time</string>
</property>
<item row="2" column="0" colspan="5">
<widget class="QGroupBox" name="time_box">
<property name="title">
<string>Time</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Source time</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="inLayout"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Output time</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="outLayout"/>
</item>
</layout>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="inLayout"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Output time</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QToolButton" name="toolButton">
<widget class="QToolButton" name="button_prev">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset theme="go-previous"/>
<iconset theme="go-previous">
<normaloff>../../../../.designer/backup</normaloff>../../../../.designer/backup</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="outLayout"/>
</item>
<item row="1" column="4">
<widget class="QToolButton" name="toolButton_2">
<item row="1" column="3">
<widget class="QToolButton" name="button_add">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset theme="go-next"/>
<iconset theme="list-add">
<normaloff>../../../../.designer/backup</normaloff>../../../../.designer/backup</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<spacer name="horizontalSpacer">
<item row="4" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>28</width>
<height>20</height>
<width>20</width>
<height>39</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="5">
<widget class="QToolButton" name="button_add">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset theme="list-add"/>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
<item row="3" column="0" colspan="5">
<widget class="QGroupBox" name="speed_box">
<property name="title">
<string>Speed</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Before</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="speedBefore">
<property name="maximum">
<double>100000.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>After</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="speedAfter">
<property name="maximum">
<double>100000.000000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="6">
<widget class="QToolButton" name="button_remove">
<item row="5" column="0" colspan="5">
<widget class="QCheckBox" name="move_next">
<property name="text">
<string>...</string>
<string>Preserve speed of next keyframes</string>
</property>
<property name="icon">
<iconset theme="list-remove"/>
</property>
<property name="autoRaise">
<property name="checked">
<bool>true</bool>
</property>
</widget>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment