From: Jean-Baptiste Mardelle Date: Tue, 26 Jan 2010 00:24:00 +0000 (+0000) Subject: Fix keyframes corruption: X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=eba492e73ecd2ccf1af379223d090a7b95a40b29;p=kdenlive Fix keyframes corruption: http://www.kdenlive.org/mantis/view.php?id=1392 svn path=/trunk/kdenlive/; revision=4249 --- diff --git a/src/abstractclipitem.cpp b/src/abstractclipitem.cpp index c9da1c32..39ed506d 100644 --- a/src/abstractclipitem.cpp +++ b/src/abstractclipitem.cpp @@ -334,45 +334,41 @@ void AbstractClipItem::updateSelectedKeyFrame() update(br.x() + maxw *(m_selectedKeyframe - cropStart().frames(m_fps)) - 3, br.bottom() - m_keyframes[m_selectedKeyframe] * maxh - 3, 12, 12); } -int AbstractClipItem::selectedKeyFramePos() const +int AbstractClipItem::editedKeyFramePos() const { return m_editedKeyframe; } -double AbstractClipItem::selectedKeyFrameValue() const +double AbstractClipItem::editedKeyFrameValue() const { return m_keyframes.value(m_editedKeyframe); } +int AbstractClipItem::selectedKeyFramePos() const +{ + return m_selectedKeyframe; +} + +double AbstractClipItem::selectedKeyFrameValue() const +{ + return m_keyframes.value(m_selectedKeyframe); +} + void AbstractClipItem::updateKeyFramePos(const GenTime pos, const double value) { - if (!m_keyframes.contains(m_selectedKeyframe)) return; + if (!m_keyframes.contains(m_editedKeyframe)) return; int newpos = (int) pos.frames(m_fps); int start = cropStart().frames(m_fps); int end = (cropStart() + cropDuration()).frames(m_fps) - 1; newpos = qMax(newpos, start); newpos = qMin(newpos, end); - if (value < -50 && m_selectedKeyframe != start && m_selectedKeyframe != end) { - // remove kexframe if it is dragged outside - m_keyframes.remove(m_selectedKeyframe); - m_selectedKeyframe = -1; - update(); - return; - } - if (value > 150 && m_selectedKeyframe != start && m_selectedKeyframe != end) { - // remove kexframe if it is dragged outside - m_keyframes.remove(m_selectedKeyframe); - m_selectedKeyframe = -1; - update(); - return; - } + double newval = qMax(value, 0.0); newval = qMin(newval, 100.0); newval = newval / m_keyframeFactor; - if (m_selectedKeyframe != newpos) m_keyframes.remove(m_selectedKeyframe); + if (m_editedKeyframe != newpos) m_keyframes.remove(m_editedKeyframe); m_keyframes[newpos] = (int) newval; - m_selectedKeyframe = newpos; - + m_editedKeyframe = newpos; update(); } diff --git a/src/abstractclipitem.h b/src/abstractclipitem.h index fdc91438..38efede3 100644 --- a/src/abstractclipitem.h +++ b/src/abstractclipitem.h @@ -48,8 +48,10 @@ public: void updateKeyFramePos(const GenTime pos, const double value); int addKeyFrame(const GenTime pos, const double value); bool hasKeyFrames() const; + int editedKeyFramePos() const; int selectedKeyFramePos() const; double selectedKeyFrameValue() const; + double editedKeyFrameValue() const; double keyFrameFactor() const; ItemInfo info() const; CustomTrackScene* projectScene(); @@ -77,7 +79,9 @@ public: protected: ItemInfo m_info; // int m_track; + /** The position of the current keyframe when it has moved */ int m_editedKeyframe; + /** The position of the current keyframe before it was moved */ int m_selectedKeyframe; /* GenTime m_cropStart; GenTime m_cropDuration; diff --git a/src/clipitem.cpp b/src/clipitem.cpp index 7c6cac2b..c59c33bf 100644 --- a/src/clipitem.cpp +++ b/src/clipitem.cpp @@ -1628,7 +1628,7 @@ bool ClipItem::isVideoOnly() const return m_videoOnly; } -void ClipItem::insertKeyframe(QDomElement effect, const int pos, const int val) +void ClipItem::insertKeyframe(QDomElement effect, int pos, int val) { if (effect.attribute("disabled") == "1") return; QDomNodeList params = effect.elementsByTagName("parameter"); @@ -1652,8 +1652,49 @@ void ClipItem::insertKeyframe(QDomElement effect, const int pos, const int val) } if (!added) newkfr.append(QString::number(pos) + ":" + QString::number(val)); e.setAttribute("keyframes", newkfr.join(";")); - kDebug() << "insert kfr: " << newkfr.join(";"); } } +void ClipItem::movedKeyframe(QDomElement effect, int oldpos, int newpos, double value) +{ + if (effect.attribute("disabled") == "1") return; + QDomNodeList params = effect.elementsByTagName("parameter"); + int start = cropStart().frames(m_fps); + int end = (cropStart() + cropDuration()).frames(m_fps) - 1; + for (int i = 0; i < params.count(); i++) { + QDomElement e = params.item(i).toElement(); + QString kfr = e.attribute("keyframes"); + const QStringList keyframes = kfr.split(';', QString::SkipEmptyParts); + QStringList newkfr; + foreach(const QString &str, keyframes) { + if (str.section(':', 0, 0).toInt() != oldpos) { + newkfr.append(str); + } else if (newpos != -1) { + newpos = qMax(newpos, start); + newpos = qMin(newpos, end); + if (i == 0) newkfr.append(QString::number(newpos) + ":" + QString::number(value)); + else newkfr.append(QString::number(newpos) + ":" + str.section(':', 1, 1)); + } + } + e.setAttribute("keyframes", newkfr.join(";")); + } + + updateKeyframes(effect); + update(); +} + +void ClipItem::updateKeyframes(QDomElement effect) +{ + m_keyframes.clear(); + // parse keyframes + QDomNodeList params = effect.elementsByTagName("parameter"); + QDomElement e = params.item(0).toElement(); + const QStringList keyframes = e.attribute("keyframes").split(';', QString::SkipEmptyParts); + foreach(const QString &str, keyframes) { + int pos = str.section(':', 0, 0).toInt(); + double val = str.section(':', 1, 1).toDouble(); + m_keyframes[pos] = val; + } + if (!m_keyframes.contains(m_selectedKeyframe)) m_selectedKeyframe = -1; +} #include "clipitem.moc" diff --git a/src/clipitem.h b/src/clipitem.h index d55c659d..e764dd64 100644 --- a/src/clipitem.h +++ b/src/clipitem.h @@ -116,7 +116,9 @@ public: bool isAudioOnly() const; /** Called when clip start is resized, adjust keyframes values */ bool checkEffectsKeyframesPos(const int previous, const int current, bool fromStart); - void insertKeyframe(QDomElement effect, const int pos, const int val); + void insertKeyframe(QDomElement effect, int pos, int val); + void movedKeyframe(QDomElement effect, int oldpos, int newpos, double value); + void updateKeyframes(QDomElement effect); protected: //virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * event); diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index 07965765..2ac23366 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -1196,11 +1196,14 @@ void CustomTrackView::mouseDoubleClickEvent(QMouseEvent *event) GenTime keyFramePos = GenTime((int)(mapToScene(event->pos()).x()), m_document->fps()) - m_dragItem->startPos() + m_dragItem->cropStart(); int val = m_dragItem->addKeyFrame(keyFramePos, mapToScene(event->pos()).toPoint().y()); ClipItem * item = static_cast (m_dragItem); - QString previous = item->keyframes(item->selectedEffectIndex()); + //QString previous = item->keyframes(item->selectedEffectIndex()); + QDomElement oldEffect = item->selectedEffect().cloneNode().toElement(); item->insertKeyframe(item->getEffectAt(item->selectedEffectIndex()), keyFramePos.frames(m_document->fps()), val); //item->updateKeyframeEffect(); - QString next = item->keyframes(item->selectedEffectIndex()); - EditKeyFrameCommand *command = new EditKeyFrameCommand(this, m_dragItem->track(), m_dragItem->startPos(), item->selectedEffectIndex(), previous, next, false); + //QString next = item->keyframes(item->selectedEffectIndex()); + QDomElement newEffect = item->selectedEffect().cloneNode().toElement(); + EditEffectCommand *command = new EditEffectCommand(this, m_document->tracksCount() - item->track(), item->startPos(), oldEffect, newEffect, item->selectedEffectIndex(), false); + //EditKeyFrameCommand *command = new EditKeyFrameCommand(this, m_dragItem->track(), m_dragItem->startPos(), item->selectedEffectIndex(), previous, next, false); m_commandStack->push(command); updateEffect(m_document->tracksCount() - item->track(), item->startPos(), item->selectedEffect(), item->selectedEffectIndex()); emit clipItemSelected(item, item->selectedEffectIndex()); @@ -3364,10 +3367,26 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) } else if (m_operationMode == KEYFRAME) { // update the MLT effect ClipItem * item = static_cast (m_dragItem); - QString previous = item->keyframes(item->selectedEffectIndex()); - item->updateKeyframeEffect(); - QString next = item->keyframes(item->selectedEffectIndex()); - EditKeyFrameCommand *command = new EditKeyFrameCommand(this, item->track(), item->startPos(), item->selectedEffectIndex(), previous, next, false); + QDomElement oldEffect = item->selectedEffect().cloneNode().toElement(); + + // check if we want to remove keyframe + double val = mapToScene(event->pos()).toPoint().y(); + QRectF br = item->sceneBoundingRect(); + double maxh = 100.0 / br.height(); + val = (br.bottom() - val) * maxh; + int start = item->cropStart().frames(m_document->fps()); + int end = (item->cropStart() + item->cropDuration()).frames(m_document->fps()) - 1; + if ((val < -50 || val > 150) && item->editedKeyFramePos() != start && item->editedKeyFramePos() != end) { + //delete keyframe + kDebug() << "// DELETE KFR: " << item->editedKeyFramePos(); + item->movedKeyframe(item->getEffectAt(item->selectedEffectIndex()), item->selectedKeyFramePos(), -1, 0); + } else item->movedKeyframe(item->getEffectAt(item->selectedEffectIndex()), item->selectedKeyFramePos(), item->editedKeyFramePos(), item->editedKeyFrameValue()); + QDomElement newEffect = item->selectedEffect().cloneNode().toElement(); + //item->updateKeyframeEffect(); + //QString next = item->keyframes(item->selectedEffectIndex()); + //EditKeyFrameCommand *command = new EditKeyFrameCommand(this, item->track(), item->startPos(), item->selectedEffectIndex(), previous, next, false); + EditEffectCommand *command = new EditEffectCommand(this, m_document->tracksCount() - item->track(), item->startPos(), oldEffect, newEffect, item->selectedEffectIndex(), false); + m_commandStack->push(command); updateEffect(m_document->tracksCount() - item->track(), item->startPos(), item->selectedEffect(), item->selectedEffectIndex()); emit clipItemSelected(item, item->selectedEffectIndex());