X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Ftransition.cpp;h=eefa77bfed643e4c8bdc525deb4d71ff3229185d;hb=b1d68d8d883f9602f84b7c8a12d73baba63b52d0;hp=0d22a8ccef20013d701cea437677bf45cd591d6c;hpb=946eb05d9bfae41b6a02bd83a820d1916913d0a7;p=kdenlive diff --git a/src/transition.cpp b/src/transition.cpp index 0d22a8cc..eefa77bf 100644 --- a/src/transition.cpp +++ b/src/transition.cpp @@ -40,19 +40,19 @@ Transition::Transition(const ItemInfo info, int transitiontrack, double fps, QDo { setZValue(3); m_info.cropDuration = info.endPos - info.startPos; - setPos(info.startPos.frames(fps), (qreal)(info.track * KdenliveSettings::trackheight() + KdenliveSettings::trackheight() / 3 * 2)); + setPos(info.startPos.frames(fps), (qreal)(info.track * KdenliveSettings::trackheight() + itemOffset() + 1)); #if QT_VERSION >= 0x040600 m_startAnimation = new QPropertyAnimation(this, "rect"); m_startAnimation->setDuration(200); - QRectF r(0, 0, m_info.cropDuration.frames(fps) - 0.02, (qreal)(KdenliveSettings::trackheight() / 3 + 5)); - QRectF r2(0, 0, m_info.cropDuration.frames(fps) - 0.02, (qreal)(KdenliveSettings::trackheight() / 3 * 2 - 1)); + QRectF r(0, 0, m_info.cropDuration.frames(fps) - 0.02, (qreal) itemHeight() / 2); + QRectF r2(0, 0, m_info.cropDuration.frames(fps) - 0.02, (qreal)itemHeight()); m_startAnimation->setStartValue(r); m_startAnimation->setEndValue(r2); m_startAnimation->setEasingCurve(QEasingCurve::OutQuad); m_startAnimation->start(); #else - setRect(0, 0, m_info.cropDuration.frames(fps) - 0.02, (qreal)(KdenliveSettings::trackheight() / 3 * 2 - 1)); + setRect(0, 0, m_info.cropDuration.frames(fps) - 0.02, (qreal) itemHeight()); #endif m_info.cropStart = GenTime(); @@ -231,34 +231,56 @@ QVariant Transition::itemChange(GraphicsItemChange change, const QVariant &value QRectF sceneShape = rect(); sceneShape.translate(newPos); QList items; - if (projectScene()->editMode() == NORMALEDIT) - items = scene()->items(sceneShape, Qt::IntersectsItemShape); + // TODO: manage transitions in OVERWRITE MODE + //if (projectScene()->editMode() == NORMALEDIT) + items = scene()->items(sceneShape, Qt::IntersectsItemShape); items.removeAll(this); + bool forwardMove = newPos.x() > pos().x(); + int offset = 0; if (!items.isEmpty()) { for (int i = 0; i < items.count(); i++) { if (!items.at(i)->isEnabled()) continue; if (items.at(i)->type() == type()) { - // Collision! Don't move. - //kDebug()<<"/// COLLISION WITH ITEM: "<boundingRect()<<", POS: "<pos()<<", ME: "<pos(); - if ((int) otherPos.y() != (int) pos().y()) return pos(); - //kDebug()<<"//// CURRENT Y: "<(items.at(i))->startPos() - m_info.cropDuration).frames(m_fps); - newPos.setX(npos); + if ((int) otherPos.y() != (int) pos().y()) { + return pos(); + } + if (forwardMove) { + offset = qMax(offset, (int)(newPos.x() - (static_cast < AbstractClipItem* >(items.at(i))->startPos() - cropDuration()).frames(m_fps))); } else { - // get pos just after colliding clip - int npos = static_cast < AbstractClipItem* >(items.at(i))->endPos().frames(m_fps); - newPos.setX(npos); + offset = qMax(offset, (int)((static_cast < AbstractClipItem* >(items.at(i))->endPos().frames(m_fps)) - newPos.x())); + } + + if (offset > 0) { + if (forwardMove) { + sceneShape.translate(QPointF(-offset, 0)); + newPos.setX(newPos.x() - offset); + } else { + sceneShape.translate(QPointF(offset, 0)); + newPos.setX(newPos.x() + offset); + } + QList subitems = scene()->items(sceneShape, Qt::IntersectsItemShape); + subitems.removeAll(this); + for (int j = 0; j < subitems.count(); j++) { + if (!subitems.at(j)->isEnabled()) continue; + if (subitems.at(j)->type() == type()) { + // move was not successful, revert to previous pos + m_info.startPos = GenTime((int) pos().x(), m_fps); + return pos(); + } + } } + m_info.track = newTrack; - //kDebug()<<"// ITEM NEW POS: "<startPos().frames(m_referenceClip->fps())); @@ -345,3 +378,64 @@ int Transition::defaultZValue() const return 3; } +bool Transition::updateKeyframes() +{ + QString keyframes; + QDomElement pa; + bool modified = false; + QDomNodeList namenode = m_parameters.elementsByTagName("parameter"); + for (int i = 0; i < namenode.count() ; i++) { + pa = namenode.item(i).toElement(); + if (pa.attribute("type") == "geometry") { + keyframes = pa.attribute("value"); + break; + } + } + if (keyframes.isEmpty()) return false; + int duration = cropDuration().frames(m_fps) - 1; + QStringList values = keyframes.split(";"); + int frame; + int i = 0; + foreach(const QString &pos, values) { + if (!pos.contains('=')) { + i++; + continue; + } + frame = pos.section('=', 0, 0).toInt(); + if (frame > duration) { + modified = true; + break; + } + i++; + } + if (modified) { + if (i > 0) { + // Check if there is a keyframe at transition end + QString prev = values.at(i-1); + bool done = false; + if (prev.contains('=')) { + int previousKeyframe = prev.section('=', 0, 0).toInt(); + if (previousKeyframe == duration) { + // Remove the last keyframes + while (values.count() > i) { + values.removeLast(); + } + done = true; + } + } + if (!done) { + // Add new keyframe at end and remove last keyframes + QString last = values.at(i); + last = QString::number(duration) + '=' + last.section('=', 1); + values[i] = last; + while (values.count() > (i + 1)) { + values.removeLast(); + } + } + } + pa.setAttribute("value", values.join(";")); + } + + return true; +} +