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

Fix markers and snapping for clips with speed effect.

Fixes #193
parent 50e1cb63
Pipeline #3660 passed with stage
in 20 minutes and 24 seconds
......@@ -84,7 +84,7 @@ int ClipModel::construct(const std::shared_ptr<TimelineModel> &parent, const QSt
TRACE_CONSTR(clip.get(), parent, binClipId, id, state, speed);
clip->setClipState_lambda(state)();
parent->registerClip(clip);
clip->m_clipMarkerModel->setReferenceModel(binClip->getMarkerModel());
clip->m_clipMarkerModel->setReferenceModel(binClip->getMarkerModel(), speed);
return id;
}
......@@ -114,7 +114,7 @@ int ClipModel::construct(const std::shared_ptr<TimelineModel> &parent, const QSt
clip->setClipState_lambda(state)();
clip->m_effectStack->importEffects(producer, state, result.second);
parent->registerClip(clip);
clip->m_clipMarkerModel->setReferenceModel(binClip->getMarkerModel());
clip->m_clipMarkerModel->setReferenceModel(binClip->getMarkerModel(), speed);
return id;
}
......@@ -543,7 +543,7 @@ void ClipModel::setCurrentTrackId(int tid, bool finalMove)
MoveableItem::setCurrentTrackId(tid, finalMove);
if (registerSnap) {
if (auto ptr = m_parent.lock()) {
m_clipMarkerModel->registerSnapModel(ptr->m_snaps, getPosition(), getIn(), getOut());
m_clipMarkerModel->registerSnapModel(ptr->m_snaps, getPosition(), getIn(), getOut(), m_speed);
}
}
......@@ -735,3 +735,12 @@ int ClipModel::getOffset() const
{
return m_positionOffset;
}
int ClipModel::getMaxDuration() const
{
READ_LOCK();
if (m_endlessResize) {
return -1;
}
return m_producer->get_length();
}
......@@ -200,6 +200,8 @@ protected:
/** @brief Clears the clip offset (calculated in the model between 2 clips from same bin clip */
void clearOffset();
int getOffset() const;
/** @brief Returns the producer's duration, or -1 if it can be resized without limit */
int getMaxDuration() const;
/*@brief This is a debug function to ensure the clip is in a valid state */
bool checkConsistency();
......
......@@ -34,8 +34,8 @@ void ClipSnapModel::addPoint(int position)
if (position <= m_inPoint || position >= m_outPoint) {
return;
}
if (auto ptr = m_registeredSnap.lock()) {
ptr->addPoint(m_position + position - m_inPoint);
if (auto ptr = m_registeredSnap.lock()) {
ptr->addPoint(m_speed < 0 ? m_outPoint + m_position + (position - m_inPoint) / m_speed : m_position + (position - m_inPoint) / m_speed);
}
}
......@@ -46,7 +46,7 @@ void ClipSnapModel::removePoint(int position)
return;
}
if (auto ptr = m_registeredSnap.lock()) {
ptr->removePoint(m_position + position - m_inPoint);
ptr->removePoint(m_speed < 0 ? m_outPoint + m_position + (position - m_inPoint) / m_speed : m_position + (position - m_inPoint) / m_speed);
}
}
......@@ -66,14 +66,14 @@ void ClipSnapModel::updateSnapModelInOut(std::pair<int, int> newInOut)
m_inPoint = newInOut.first;
m_outPoint = newInOut.second;
addAllSnaps();
}
}
void ClipSnapModel::addAllSnaps()
{
if (auto ptr = m_registeredSnap.lock()) {
for (const auto &snap : m_snapPoints) {
if (snap >= m_inPoint && snap < m_outPoint) {
ptr->addPoint(m_position + snap - m_inPoint);
if (snap >= m_inPoint * m_speed && snap < m_outPoint * m_speed) {
ptr->addPoint(m_speed < 0 ? m_outPoint + m_position + (snap - m_inPoint) / m_speed : m_position + (snap - m_inPoint) / m_speed);
}
}
}
......@@ -83,18 +83,19 @@ void ClipSnapModel::removeAllSnaps()
{
if (auto ptr = m_registeredSnap.lock()) {
for (const auto &snap : m_snapPoints) {
if (snap >= m_inPoint && snap < m_outPoint) {
ptr->removePoint(m_position + snap - m_inPoint);
if (snap >= m_inPoint * m_speed && snap < m_outPoint * m_speed) {
ptr->removePoint(m_speed < 0 ? m_outPoint + m_position + (snap - m_inPoint) / m_speed : m_position + (snap - m_inPoint) / m_speed);
}
}
}
}
void ClipSnapModel::registerSnapModel(const std::weak_ptr<SnapModel> &snapModel, int position, int in, int out)
void ClipSnapModel::registerSnapModel(const std::weak_ptr<SnapModel> &snapModel, int position, int in, int out, double speed)
{
// make sure ptr is valid
m_inPoint = in;
m_outPoint = out;
m_speed = speed;
m_position = qMax(0, position);
m_registeredSnap = snapModel;
addAllSnaps();
......@@ -107,9 +108,10 @@ void ClipSnapModel::deregisterSnapModel()
m_registeredSnap.reset();
}
void ClipSnapModel::setReferenceModel(const std::weak_ptr<MarkerListModel> &markerModel)
void ClipSnapModel::setReferenceModel(const std::weak_ptr<MarkerListModel> &markerModel, double speed)
{
m_parentModel = markerModel;
m_speed = speed;
if (auto ptr = m_parentModel.lock()) {
ptr->registerSnapModel(std::static_pointer_cast<SnapInterface>(shared_from_this()));
}
......
......@@ -46,11 +46,11 @@ public:
/* @brief Removes a snappoint from given position */
void removePoint(int position) override;
void registerSnapModel(const std::weak_ptr<SnapModel> &snapModel, int position, int in, int out);
void registerSnapModel(const std::weak_ptr<SnapModel> &snapModel, int position, int in, int out, double speed = 1.);
void deregisterSnapModel();
void setReferenceModel(const std::weak_ptr<MarkerListModel> &markerModel);
void setReferenceModel(const std::weak_ptr<MarkerListModel> &markerModel, double speed);
void updateSnapModelPos(int newPos);
void updateSnapModelInOut(std::pair<int, int> newInOut);
......@@ -62,6 +62,7 @@ private:
int m_inPoint;
int m_outPoint;
int m_position;
double m_speed{1.};
void addAllSnaps();
void removeAllSnaps();
......
......@@ -197,6 +197,7 @@ QHash<int, QByteArray> TimelineItemModel::roleNames() const
roles[FakePositionRole] = "fakePosition";
roles[StartRole] = "start";
roles[DurationRole] = "duration";
roles[MaxDurationRole] = "maxDuration";
roles[MarkersRole] = "markers";
roles[KeyframesRole] = "keyframeModel";
roles[ShowKeyframesRole] = "showKeyframes";
......@@ -314,6 +315,8 @@ QVariant TimelineItemModel::data(const QModelIndex &index, int role) const
return clip->getPosition();
case DurationRole:
return clip->getPlaytime();
case MaxDurationRole:
return clip->getMaxDuration();
case GroupedRole:
return m_groups->isInGroup(id);
case EffectNamesRole:
......
......@@ -125,6 +125,7 @@ public:
TypeRole, /// clip only
KeyframesRole,
DurationRole,
MaxDurationRole,
InPointRole, /// clip only
OutPointRole, /// clip only
FramerateRole, /// clip only
......
......@@ -36,6 +36,7 @@ Rectangle {
property int inPoint: 0
property int outPoint: 0
property int clipDuration: 0
property int maxDuration: 0
property bool isAudio: false
property int audioChannels
property bool showKeyframes: false
......@@ -160,7 +161,7 @@ Rectangle {
x = modelStart * timeScale;
width = clipDuration * timeScale;
labelRect.x = scrollX > modelStart * timeScale ? scrollX - modelStart * timeScale : 0
if (parentTrack && parentTrack.isAudio) {
if (parentTrack && parentTrack.isAudio && thumbsLoader.item) {
thumbsLoader.item.reload();
}
}
......@@ -409,7 +410,7 @@ Rectangle {
id: markerBase
width: 1
height: parent.height
x: (model.frame - clipRoot.inPoint) * timeScale;
x: clipRoot.speed < 0 ? clipRoot.clipDuration * timeScale + (model.frame - (clipRoot.maxDuration - clipRoot.outPoint)) * timeScale / clipRoot.speed : (model.frame - clipRoot.inPoint) * timeScale / clipRoot.speed;
color: model.color
}
Rectangle {
......
......@@ -200,6 +200,12 @@ Column{
value: model.speed
when: loader.status == Loader.Ready && isClip(model.clipType)
}
Binding {
target: loader.item
property: "maxDuration"
value: model.maxDuration
when: loader.status == Loader.Ready && isClip(model.clipType)
}
Binding {
target: loader.item
property: "forceReloadThumb"
......
......@@ -668,7 +668,7 @@ void TimelineController::editMarker(int cid, int position)
return;
}
std::shared_ptr<ProjectClip> clip = pCore->bin()->getBinClip(getClipBinId(cid));
GenTime pos(position - m_model->getClipPosition(cid) + m_model->getClipIn(cid), pCore->getCurrentFps());
GenTime pos((position - m_model->getClipPosition(cid) + m_model->getClipIn(cid)) * m_model->getClipSpeed(cid), pCore->getCurrentFps());
clip->getMarkerModel()->editMarkerGui(pos, qApp->activeWindow(), false, clip.get());
}
......@@ -683,7 +683,7 @@ void TimelineController::addMarker(int cid, int position)
return;
}
std::shared_ptr<ProjectClip> clip = pCore->bin()->getBinClip(getClipBinId(cid));
GenTime pos(position - m_model->getClipPosition(cid) + m_model->getClipIn(cid), pCore->getCurrentFps());
GenTime pos((position - m_model->getClipPosition(cid) + m_model->getClipIn(cid)) * m_model->getClipSpeed(cid), pCore->getCurrentFps());
clip->getMarkerModel()->editMarkerGui(pos, qApp->activeWindow(), true, clip.get());
}
......@@ -698,7 +698,7 @@ void TimelineController::addQuickMarker(int cid, int position)
return;
}
std::shared_ptr<ProjectClip> clip = pCore->bin()->getBinClip(getClipBinId(cid));
GenTime pos(position - m_model->getClipPosition(cid) + m_model->getClipIn(cid), pCore->getCurrentFps());
GenTime pos((position - m_model->getClipPosition(cid) + m_model->getClipIn(cid)) * m_model->getClipSpeed(cid), pCore->getCurrentFps());
CommentedTime marker(pos, pCore->currentDoc()->timecode().getDisplayTimecode(pos, false), KdenliveSettings::default_marker_type());
clip->getMarkerModel()->addMarker(marker.time(), marker.comment(), marker.markerType());
}
......@@ -714,7 +714,7 @@ void TimelineController::deleteMarker(int cid, int position)
return;
}
std::shared_ptr<ProjectClip> clip = pCore->bin()->getBinClip(getClipBinId(cid));
GenTime pos(position - m_model->getClipPosition(cid) + m_model->getClipIn(cid), pCore->getCurrentFps());
GenTime pos((position - m_model->getClipPosition(cid) + m_model->getClipIn(cid)) * m_model->getClipSpeed(cid), pCore->getCurrentFps());
clip->getMarkerModel()->removeMarker(pos);
}
......
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