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

* Fix crash on resize clip after removing keyframe effect

* Do not display Transform rotation keyframes in timeline
* Fix Keyframes for animated rect (transform) not correctly displayed
* Fix Geometry keyframes (Position and Zoom)
parent f922b502
......@@ -6,7 +6,7 @@
<parameter type="animatedrect" name="rect" default="0 0 %width %height 1">
<name>Rectangle</name>
</parameter>
<parameter type="animated" name="rotation" max="360" min="-360" default="0">
<parameter type="animated" name="rotation" max="360" min="-360" default="0" notintimeline="1">
<name>Rotation</name>
</parameter>
<parameter type="list" name="compositing" default="0" paramlist="0;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;27;28;29;6;8">
......
......@@ -717,7 +717,7 @@ void AnimationWidget::buildSliderWidget(const QString &paramTag, const QDomEleme
doubleparam->factor = factor;
connect(doubleparam, SIGNAL(valueChanged(double)), this, SLOT(slotAdjustKeyframeValue(double)));
layout()->addWidget(doubleparam);
if (!e.hasAttribute(QStringLiteral("intimeline")) || e.attribute(QStringLiteral("intimeline")) == QLatin1String("1")) {
if ((!e.hasAttribute(QStringLiteral("intimeline")) || e.attribute(QStringLiteral("intimeline")) == QLatin1String("1")) && !e.hasAttribute(QStringLiteral("notintimeline"))) {
doubleparam->setInTimelineProperty(true);
doubleparam->setChecked(true);
m_inTimeline = paramTag;
......@@ -888,7 +888,7 @@ void AnimationWidget::slotAdjustRectKeyframeValue()
{
m_animController = m_animProperties.get_animation(m_rectParameter.toUtf8().constData());
m_inTimeline = m_rectParameter;
int pos = m_ruler->position();
int pos = m_ruler->position() - m_offset;
mlt_rect rect;
rect.x = m_spinX->value();
rect.y = m_spinY->value();
......
......@@ -273,7 +273,8 @@ void EffectsController::initEffect(ItemInfo info, ProfileInfo pInfo, EffectsList
bool hasValue = e.hasAttribute(QStringLiteral("value"));
// Check if this effect has a variable parameter, init effects default value
if ((type == QLatin1String("animatedrect") || type == QLatin1String("geometry")) && !hasValue) {
QString kfr = AnimationWidget::getDefaultKeyframes(info.cropStart.frames(fps), e.attribute(QStringLiteral("default")), type == QLatin1String("geometry"));
int pos = type == QLatin1String("geometry") ? 0 : info.cropStart.frames(fps);
QString kfr = AnimationWidget::getDefaultKeyframes(pos, e.attribute(QStringLiteral("default")), type == QLatin1String("geometry"));
if (kfr.contains("%")) {
kfr = EffectsController::getStringRectEval(pInfo, kfr);
}
......
......@@ -481,7 +481,7 @@ void AbstractClipItem::movedKeyframe(QDomElement effect, int newpos, int oldpos,
QDomElement e = params.item(i).toElement();
if (e.isNull()) continue;
QString paramName = e.attribute(QStringLiteral("name"));
if (e.attribute(QStringLiteral("type")) == QLatin1String("animated")) {
if (e.attribute(QStringLiteral("type")).startsWith(QLatin1String("animated"))) {
if (m_keyframeView.activeParam(paramName)) {
// inserting a keyframe touches all animated params
for (int j = 0; j < params.count(); ++j) {
......
......@@ -74,7 +74,7 @@ QPointF KeyframeView::keyframePoint(QRectF br, int frame, double value, double f
void KeyframeView::drawKeyFrames(QRectF br, int length, bool active, QPainter *painter, const QTransform &transformation)
{
if (duration == 0 || m_keyframeType == NoKeyframe || !m_keyAnim.is_valid() || m_keyAnim.key_count() < 1)
if (duration == 0 || m_inTimeline.isEmpty() || m_keyframeType == NoKeyframe || !m_keyAnim.is_valid() || m_keyAnim.key_count() < 1)
return;
duration = length;
//m_keyAnim.set_length(length);
......@@ -133,6 +133,8 @@ void KeyframeView::drawKeyFrames(QRectF br, int length, bool active, QPainter *p
// Make sure edited param is painted last
paramNames.append(m_inTimeline);
foreach (const QString &paramName, paramNames) {
if (m_notInTimeline.contains(paramName))
continue;
ParameterInfo info = m_paramInfos.value(paramName);
if (info.max == info.min) {
// this is probably an animated rect
......@@ -547,7 +549,13 @@ void KeyframeView::updateKeyFramePos(QRectF br, int frame, const double y)
int newpos = qBound(prev, frame - m_offset, next);
double newval = keyframeUnmap(br, y);
mlt_keyframe_type type = m_keyAnim.keyframe_type(activeKeyframe);
m_keyProperties.anim_set(m_inTimeline.toUtf8().constData(), newval, newpos, duration - m_offset, type);
if (m_keyframeType == GeometryKeyframe) {
// Animated rect
mlt_rect rect = m_keyProperties.anim_get_rect(m_inTimeline.toUtf8().constData(), activeKeyframe - m_offset, duration - m_offset);
m_keyProperties.anim_set(m_inTimeline.toUtf8().constData(), rect, newpos, duration - m_offset, type);
} else {
m_keyProperties.anim_set(m_inTimeline.toUtf8().constData(), newval, newpos, duration - m_offset, type);
}
if (activeKeyframe != newpos) {
m_keyAnim.remove(activeKeyframe);
// Move keyframe in other geometries
......@@ -838,6 +846,7 @@ bool KeyframeView::loadKeyframes(const QLocale locale, QDomElement effect, int c
m_keyframeType = NoKeyframe;
duration = length;
m_inTimeline.clear();
m_notInTimeline.clear();
// reset existing properties
int max = m_keyProperties.count();
for (int i = max -1; i >= 0; i--) {
......@@ -847,15 +856,16 @@ bool KeyframeView::loadKeyframes(const QLocale locale, QDomElement effect, int c
m_useOffset = effect.attribute(QStringLiteral("kdenlive:sync_in_out")) != QLatin1String("1");
m_offset = effect.attribute(QStringLiteral("in")).toInt() - cropStart;
QDomNodeList params = effect.elementsByTagName(QStringLiteral("parameter"));
QStringList keyframeTypes;
keyframeTypes << QStringLiteral("keyframe") << QStringLiteral("simplekeyframe") << QStringLiteral("geometry") << QStringLiteral("animatedrect") << QStringLiteral("animated");
for (int i = 0; i < params.count(); ++i) {
QDomElement e = params.item(i).toElement();
if (e.isNull()) continue;
if (e.isNull()) {
continue;
}
QString type = e.attribute(QStringLiteral("type"));
if (type == QLatin1String("keyframe")) m_keyframeType = NormalKeyframe;
else if (type == QLatin1String("simplekeyframe")) m_keyframeType = SimpleKeyframe;
else if (type == QLatin1String("geometry") || type == QLatin1String("animatedrect")) m_keyframeType = GeometryKeyframe;
else if (type == QLatin1String("animated")) m_keyframeType = AnimatedKeyframe;
else continue;
if (!keyframeTypes.contains(type))
continue;
QString paramName = e.attribute(QStringLiteral("name"));
ParameterInfo info;
info.factor = locale.toDouble(e.attribute(QStringLiteral("factor")));
......@@ -866,14 +876,23 @@ bool KeyframeView::loadKeyframes(const QLocale locale, QDomElement effect, int c
info.factor = 1;
}
m_paramInfos.insert(paramName, info);
if (!e.hasAttribute(QStringLiteral("intimeline")) || e.attribute(QStringLiteral("intimeline")) == QLatin1String("1")) {
// Active parameter
m_keyframeMin = info.min;
m_keyframeMax = info.max;
m_keyframeDefault = locale.toDouble(info.defaultValue);
m_keyframeFactor = info.factor;
attachToEnd = checkNegatives(e.attribute("value").toUtf8().constData(), duration - m_offset);
m_inTimeline = paramName;
if (e.hasAttribute(QStringLiteral("notintimeline"))) {
// This param should not be drawn in timeline
m_notInTimeline << paramName;
} else {
if (type == QLatin1String("keyframe")) m_keyframeType = NormalKeyframe;
else if (type == QLatin1String("simplekeyframe")) m_keyframeType = SimpleKeyframe;
else if (type == QLatin1String("geometry") || type == QLatin1String("animatedrect")) m_keyframeType = GeometryKeyframe;
else if (type == QLatin1String("animated")) m_keyframeType = AnimatedKeyframe;
if (!e.hasAttribute(QStringLiteral("intimeline")) || e.attribute(QStringLiteral("intimeline")) == QLatin1String("1")) {
// Active parameter
m_keyframeMin = info.min;
m_keyframeMax = info.max;
m_keyframeDefault = locale.toDouble(info.defaultValue);
m_keyframeFactor = info.factor;
attachToEnd = checkNegatives(e.attribute("value").toUtf8().constData(), duration - m_offset);
m_inTimeline = paramName;
}
}
// parse keyframes
QString value = e.attribute(QStringLiteral("value"));
......@@ -904,7 +923,7 @@ bool KeyframeView::loadKeyframes(const QLocale locale, QDomElement effect, int c
void KeyframeView::setOffset(int frames)
{
if (!m_keyAnim.is_valid())
if (duration == 0 || !m_keyAnim.is_valid())
return;
if (m_keyAnim.is_key(-m_offset)) {
mlt_keyframe_type type = m_keyAnim.keyframe_type(-m_offset);
......@@ -955,6 +974,8 @@ void KeyframeView::reset()
duration = 0;
attachToEnd = -2;
activeKeyframe = -1;
m_inTimeline.clear();
m_notInTimeline.clear();
int max = m_keyProperties.count();
for (int i = max -1; i >= 0; i--) {
m_keyProperties.set(m_keyProperties.get_name(i), (char*) NULL);
......
......@@ -120,6 +120,7 @@ private:
int m_handleSize;
bool m_useOffset;
int m_offset;
QStringList m_notInTimeline;
double keyframeUnmap(QRectF br, double y);
double keyframeMap(QRectF br, double value);
QPointF keyframeMap(QRectF br, int frame, double value);
......
Supports Markdown
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