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();
}
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();
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;
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");
}
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"
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);
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 <ClipItem *>(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());
} else if (m_operationMode == KEYFRAME) {
// update the MLT effect
ClipItem * item = static_cast <ClipItem *>(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());