}
}
+bool ClipItem::checkKeyFrames() {
+ bool clipEffectsModified = false;
+ for (int ix = 0; ix < m_effectList.count(); ix ++) {
+ QString kfr = keyframes(ix);
+ if (!kfr.isEmpty()) {
+ const QStringList keyframes = kfr.split(";", QString::SkipEmptyParts);
+ QStringList newKeyFrames;
+ bool cutKeyFrame = false;
+ bool modified = false;
+ int lastPos = -1;
+ double lastValue = -1;
+ int start = m_cropStart.frames(m_fps);
+ int end = (m_cropStart + m_cropDuration).frames(m_fps);
+ foreach(const QString str, keyframes) {
+ int pos = str.section(":", 0, 0).toInt();
+ double val = str.section(":", 1, 1).toDouble();
+ if (pos - start < 0) {
+ // a keyframe is defined before the start of the clip
+ cutKeyFrame = true;
+ } else if (cutKeyFrame) {
+ // create new keyframe at clip start, calculate interpolated value
+ if (pos > start) {
+ int diff = pos - lastPos;
+ double ratio = (double)(start - lastPos) / diff;
+ double newValue = lastValue + (val - lastValue) * ratio;
+ newKeyFrames.append(QString::number(start) + ":" + QString::number(newValue));
+ modified = true;
+ }
+ cutKeyFrame = false;
+ }
+ if (!cutKeyFrame) {
+ if (pos > end) {
+ // create new keyframe at clip end, calculate interpolated value
+ int diff = pos - lastPos;
+ if (diff != 0) {
+ double ratio = (double)(end - lastPos) / diff;
+ double newValue = lastValue + (val - lastValue) * ratio;
+ newKeyFrames.append(QString::number(end) + ":" + QString::number(newValue));
+ modified = true;
+ }
+ break;
+ } else {
+ newKeyFrames.append(QString::number(pos) + ":" + QString::number(val));
+ }
+ }
+ lastPos = pos;
+ lastValue = val;
+ }
+ if (modified) {
+ // update KeyFrames
+ setKeyframes(ix, newKeyFrames.join(";"));
+ clipEffectsModified = true;
+ }
+ }
+ }
+ return clipEffectsModified;
+}
+
void ClipItem::setKeyframes(const int ix, const QString keyframes) {
QDomElement effect = effectAt(ix);
if (effect.attribute("disabled") == "1") return;
double maximumOffset;
if (scale > 3) maximumOffset = 25 / scale;
else maximumOffset = 6 / scale;
- QMatrix matrix;
- matrix.scale(scale, 0);
+
//kDebug()<<"// Item rect: "<<rect.x()<<". pos. "<<pos.x()<<", scale: "<<scale<<", ratio: "<<qAbs((int)(pos.x() - rect.x())) / scale;
if (qAbs((int)(pos.x() - (rect.x() + m_startFade))) < maximumOffset && qAbs((int)(pos.y() - rect.y())) < 6) {
}
}
-void ClipItem::resizeEnd(int posx) {
+void ClipItem::resizeEnd(int posx, bool updateKeyFrames) {
const int max = (startPos() - cropStart() + maxDuration()).frames(m_fps) + 1;
if (posx > max) posx = max;
if (posx == endPos().frames(m_fps)) return;
const int previous = (cropStart() + duration()).frames(m_fps);
AbstractClipItem::resizeEnd(posx);
- checkEffectsKeyframesPos(previous, (cropStart() + duration()).frames(m_fps), false);
+ if (updateKeyFrames) checkEffectsKeyframesPos(previous, (cropStart() + duration()).frames(m_fps), false);
if (m_hasThumbs && KdenliveSettings::videothumbnails()) {
/*connect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap)));*/
endThumbTimer->start(100);
// parse keyframes and adjust values
const QStringList keyframes = e.attribute("keyframes").split(";", QString::SkipEmptyParts);
QMap <int, double> kfr;
+ int pos;
+ double val;
foreach(const QString str, keyframes) {
- int pos = str.section(":", 0, 0).toInt();
- double val = str.section(":", 1, 1).toDouble();
+ pos = str.section(":", 0, 0).toInt();
+ val = str.section(":", 1, 1).toDouble();
if (pos == previous) kfr[current] = val;
else {
if (fromStart && pos >= current) kfr[pos] = val;
newPos.track = info.track;
ClipItem *dup = item->clone(newPos);
kDebug() << "// REsizing item to: " << cutPos;
- item->resizeEnd(cutPos);
+ item->resizeEnd(cutPos, false);
scene()->addItem(dup);
+ if (item->checkKeyFrames()) slotRefreshEffects(item);
+ if (dup->checkKeyFrames()) slotRefreshEffects(dup);
item->baseClip()->addReference();
m_document->updateClip(item->baseClip()->getId());
kDebug() << "///////// CUTTING CLIP RESULT: (" << item->startPos().frames(25) << "-" << item->endPos().frames(25) << "), DUP: (" << dup->startPos().frames(25) << "-" << dup->endPos().frames(25) << ")" << ", CUT: " << cutTime.frames(25);
Transition *tr = new Transition(transitionInfo, endTrack, m_document->fps(), params);
scene()->addItem(tr);
- //kDebug() << "---- ADDING transition " << e.attribute("tag") << ", on tracks " << m_scene->m_tracksList.count() - e.attribute("transition_track").toInt() << " / " << getPreviousVideoTrack(e.attribute("transition_track").toInt());
+ //kDebug() << "---- ADDING transition " << params.attribute("value");
m_document->renderer()->mltAddTransition(tr->transitionTag(), endTrack, m_scene->m_tracksList.count() - transitionInfo.track, transitionInfo.startPos, transitionInfo.endPos, tr->toXML());
m_document->setModified(true);
}