[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [kdenlive/Applications/16.12] src: Fix several issues with effect keyframes behaving incorrectly
From: Jean-Baptiste Mardelle <jb () kdenlive ! org>
Date: 2016-11-28 23:27:40
Message-ID: E1cBVKm-000286-Hy () code ! kde ! org
[Download RAW message or body]
Git commit b2235e3ff5fea9c987752cdbd3899e87abedf4d0 by Jean-Baptiste Mardelle.
Committed on 28/11/2016 at 23:25.
Pushed by mardelle into branch 'Applications/16.12'.
Fix several issues with effect keyframes behaving incorrectly
M +0 -1 src/effectstack/dragvalue.cpp
M +14 -3 src/effectstack/effectstackview2.cpp
M +3 -0 src/effectstack/effectstackview2.h
M +3 -3 src/effectstack/widgets/animationwidget.cpp
M +15 -0 src/timeline/abstractclipitem.cpp
M +1 -0 src/timeline/abstractclipitem.h
M +16 -4 src/timeline/clipitem.cpp
M +2 -2 src/timeline/clipitem.h
M +0 -4 src/timeline/customtrackview.cpp
M +24 -1 src/timeline/keyframeview.cpp
M +2 -0 src/timeline/keyframeview.h
https://commits.kde.org/kdenlive/b2235e3ff5fea9c987752cdbd3899e87abedf4d0
diff --git a/src/effectstack/dragvalue.cpp b/src/effectstack/dragvalue.cpp
index fd79856..1f8ab01 100644
--- a/src/effectstack/dragvalue.cpp
+++ b/src/effectstack/dragvalue.cpp
@@ -363,7 +363,6 @@ void DragValue::setInTimelineProperty(bool intimeline)
style()->polish(m_doubleEdit);
m_doubleEdit->update();
}
-
}
CustomLabel::CustomLabel(const QString &label, bool showSlider, int range, QWidget* \
parent) :
diff --git a/src/effectstack/effectstackview2.cpp \
b/src/effectstack/effectstackview2.cpp index 77037cf..9fdc97d 100644
--- a/src/effectstack/effectstackview2.cpp
+++ b/src/effectstack/effectstackview2.cpp
@@ -67,6 +67,10 @@ EffectStackView2::EffectStackView2(Monitor *projectMonitor, \
QWidget *parent) :
connect(m_effect->checkAll, SIGNAL(stateChanged(int)), this, \
SLOT(slotCheckAll(int)));
connect(m_effect->effectCompare, &QToolButton::toggled, this, \
&EffectStackView2::slotSwitchCompare);
+ m_scrollTimer.setSingleShot(true);
+ m_scrollTimer.setInterval(200);
+ connect(&m_scrollTimer, &QTimer::timeout, this, \
&EffectStackView2::slotCheckWheelEventFilter); +
m_layout.addWidget(m_effect);
m_layout.addWidget(m_transition);
m_transition->setHidden(true);
@@ -278,12 +282,19 @@ void EffectStackView2::slotTrackItemSelected(int ix, const \
TrackInfo &info, Moni void EffectStackView2::setupListView()
{
blockSignals(true);
+ m_scrollTimer.stop();
m_monitorSceneWanted = MonitorSceneDefault;
m_draggedEffect = NULL;
m_draggedGroup = NULL;
disconnect(m_effectMetaInfo.monitor, SIGNAL(renderPosition(int)), this, \
SLOT(slotRenderPos(int))); QWidget *view = m_effect->container->takeWidget();
if (view) {
+ /*QList<CollapsibleEffect *> allChildren = \
view->findChildren<CollapsibleEffect *>(); + qDebug()<<" * * *FOUND CHLD: \
"<<allChildren.count(); + foreach(CollapsibleEffect *eff, allChildren) {
+ eff->setEnabled(false);
+ }*/
+ //delete view;
view->setEnabled(false);
view->setHidden(true);
view->deleteLater();
@@ -409,7 +420,7 @@ void EffectStackView2::setupListView()
slotUpdateCheckAllButton();
// Wait a little bit for the new layout to be ready, then check if we have a \
scrollbar
- QTimer::singleShot(200, this, SLOT(slotCheckWheelEventFilter()));
+ m_scrollTimer.start();
}
int EffectStackView2::activeEffectIndex() const
@@ -759,7 +770,7 @@ void EffectStackView2::slotUpdateEffectParams(const QDomElement \
&old, const QDom else if (m_status == MASTER_CLIP) {
emit updateMasterEffect(m_masterclipref->clipId(), old, e, ix);
}
- QTimer::singleShot(200, this, SLOT(slotCheckWheelEventFilter()));
+ m_scrollTimer.start();
}
void EffectStackView2::slotSetCurrentEffect(int ix)
@@ -992,7 +1003,7 @@ void EffectStackView2::slotCreateRegion(int ix, QUrl url)
// Check drag & drop
currentEffect->installEventFilter( this );
- QTimer::singleShot(200, this, SLOT(slotCheckWheelEventFilter()));
+ m_scrollTimer.start();
}
diff --git a/src/effectstack/effectstackview2.h b/src/effectstack/effectstackview2.h
index 4a80911..9b97619 100644
--- a/src/effectstack/effectstackview2.h
+++ b/src/effectstack/effectstackview2.h
@@ -27,6 +27,8 @@
#include "collapsibleeffect.h"
#include "collapsiblegroup.h"
+#include <QTimer>
+
class EffectsList;
class ClipItem;
class Transition;
@@ -124,6 +126,7 @@ private:
/** @brief The current effect may require an on monitor scene. */
MonitorSceneType m_monitorSceneWanted;
QMutex m_mutex;
+ QTimer m_scrollTimer;
/** If in track mode: Info of the edited track to be able to access its \
duration. */ TrackInfo m_trackInfo;
diff --git a/src/effectstack/widgets/animationwidget.cpp \
b/src/effectstack/widgets/animationwidget.cpp index 31417d4..71ab9d2 100644
--- a/src/effectstack/widgets/animationwidget.cpp
+++ b/src/effectstack/widgets/animationwidget.cpp
@@ -269,11 +269,11 @@ void AnimationWidget::slotPrevious()
void AnimationWidget::slotNext()
{
int next = m_animController.next_key(m_timePos->getValue() - m_offset + 1) + \
m_offset;
- if (!m_animController.is_key(next)) {
+ if (!m_animController.is_key(next - m_offset)) {
// No keyframe after current pos, return end position
next = m_timePos->maximum();
} else {
- m_ruler->setActiveKeyframe(next);
+ m_ruler->setActiveKeyframe(next - m_offset);
}
slotPositionChanged(next, true);
}
@@ -350,7 +350,7 @@ void AnimationWidget::slotAddDeleteKeyframe(bool add, int pos)
for (int i = 0; i < paramNames.count(); i++) {
m_animController = \
m_animProperties.get_animation(paramNames.at(i).toUtf8().constData()); if \
(!m_animController.is_key(pos - m_offset)) {
- doAddKeyframe(pos - m_offset, paramNames.at(i), false);
+ doAddKeyframe(pos, paramNames.at(i), false);
}
}
m_ruler->setActiveKeyframe(pos);
diff --git a/src/timeline/abstractclipitem.cpp b/src/timeline/abstractclipitem.cpp
index 0f0f325..09c318e 100644
--- a/src/timeline/abstractclipitem.cpp
+++ b/src/timeline/abstractclipitem.cpp
@@ -624,3 +624,18 @@ QString AbstractClipItem::resizeAnimations(QDomElement effect, \
int previousDurat }
return keyframes;
}
+
+bool AbstractClipItem::switchKeyframes(QDomElement param, int in, int oldin, int \
out, int oldout) +{
+ QString animation = param.attribute(QStringLiteral("value"));
+ if (in != oldin)
+ animation = KeyframeView::switchAnimation(animation, in, oldin, out, oldout, \
param.attribute(QStringLiteral("type")) == QLatin1String("animatedrect")); + if \
(out != oldout) + animation = KeyframeView::switchAnimation(animation, out - \
1, oldout - 1, out, oldout, param.attribute(QStringLiteral("type")) == \
QLatin1String("animatedrect")); + if (animation != \
param.attribute(QStringLiteral("value"))) { + \
param.setAttribute(QStringLiteral("value"), animation); + return true;
+ }
+ return false;
+}
+
diff --git a/src/timeline/abstractclipitem.h b/src/timeline/abstractclipitem.h
index 5b1ebbd..fcd33f8 100644
--- a/src/timeline/abstractclipitem.h
+++ b/src/timeline/abstractclipitem.h
@@ -123,6 +123,7 @@ protected:
int posForTrack(int track);
bool resizeGeometries(QDomElement effect, int width, int height, int \
previousDuration, int start, int duration, int cropstart);
QString resizeAnimations(QDomElement effect, int previousDuration, int start, \
int duration, int cropstart); + bool switchKeyframes(QDomElement param, int in, \
int oldin, int out, int oldout);
signals:
void selectItem(AbstractClipItem*);
diff --git a/src/timeline/clipitem.cpp b/src/timeline/clipitem.cpp
index eefa5ff..579a7d8 100644
--- a/src/timeline/clipitem.cpp
+++ b/src/timeline/clipitem.cpp
@@ -1735,7 +1735,7 @@ void ClipItem::setState(PlaylistState::ClipState state)
QMap<int, QDomElement> ClipItem::adjustEffectsToDuration(const ItemInfo &oldInfo)
{
QMap<int, QDomElement> effects;
- qDebug()<<"Adjusting effect to duraion";
+ //qDebug()<<"Adjusting effect to duration: "<<oldInfo.cropStart.frames(25)<<" - \
"<<cropStart().frames(25); for (int i = 0; i < m_effectList.count(); ++i) {
QDomElement effect = m_effectList.at(i);
@@ -1790,7 +1790,6 @@ QMap<int, QDomElement> ClipItem::adjustEffectsToDuration(const \
ItemInfo &oldInfo
QDomNodeList params = effect.elementsByTagName(QStringLiteral("parameter"));
for (int j = 0; j < params.count(); ++j) {
QDomElement param = params.item(j).toElement();
-
QString type = param.attribute(QStringLiteral("type"));
if (type == QLatin1String("geometry") && \
!param.hasAttribute(QStringLiteral("fixed"))) { if (!effects.contains(i)) {
@@ -1805,10 +1804,13 @@ QMap<int, QDomElement> \
ClipItem::adjustEffectsToDuration(const ItemInfo &oldInfo if (!effects.contains(i))
effects[i] = effect.cloneNode().toElement();
updateNormalKeyframes(param, oldInfo);
- } else if (type == QLatin1String("animated")) {
+ } else if (type.startsWith(QLatin1String("animated"))) {
if (effect.attribute(QStringLiteral("sync_in_out")) == \
QLatin1String("1")) {
effect.setAttribute(QStringLiteral("in"), \
cropStart().frames(m_fps));
effect.setAttribute(QStringLiteral("out"), (cropStart() + \
cropDuration()).frames(m_fps) - 1); + } else {
+ // Check if we have keyframes at in/out points
+ updateAnimatedKeyframes(i, param, oldInfo);
}
effects[i] = effect.cloneNode().toElement();
} else if (type == QLatin1String("roto-spline")) {
@@ -1823,7 +1825,17 @@ QMap<int, QDomElement> ClipItem::adjustEffectsToDuration(const \
ItemInfo &oldInfo return effects;
}
-bool ClipItem::updateNormalKeyframes(QDomElement parameter, ItemInfo oldInfo)
+
+bool ClipItem::updateAnimatedKeyframes(int ix, QDomElement parameter, const ItemInfo \
&oldInfo) +{
+ int in = cropStart().frames(m_fps);
+ int out = (cropStart() + cropDuration()).frames(m_fps) - 1;
+ int oldin = oldInfo.cropStart.frames(m_fps);
+ int oldout = oldin + oldInfo.cropDuration.frames(m_fps) - 1;
+ return switchKeyframes(parameter, in, oldin, out, oldout);
+}
+
+bool ClipItem::updateNormalKeyframes(QDomElement parameter, const ItemInfo &oldInfo)
{
int in = cropStart().frames(m_fps);
int out = (cropStart() + cropDuration()).frames(m_fps) - 1;
diff --git a/src/timeline/clipitem.h b/src/timeline/clipitem.h
index ecc2839..88a0794 100644
--- a/src/timeline/clipitem.h
+++ b/src/timeline/clipitem.h
@@ -166,8 +166,8 @@ public:
QPixmap endThumb() const;
void setState(PlaylistState::ClipState state);
void updateState(const QString &id, int aIndex, int vIndex, \
PlaylistState::ClipState originalState);
-
- bool updateNormalKeyframes(QDomElement parameter, ItemInfo oldInfo);
+ bool updateAnimatedKeyframes(int ix, QDomElement parameter, const ItemInfo \
&oldInfo); + bool updateNormalKeyframes(QDomElement parameter, const ItemInfo \
&oldInfo);
/** @brief Adjusts effects after a clip duration change. */
QMap<int, QDomElement> adjustEffectsToDuration(const ItemInfo &oldInfo);
diff --git a/src/timeline/customtrackview.cpp b/src/timeline/customtrackview.cpp
index 0d112fc..6700af7 100644
--- a/src/timeline/customtrackview.cpp
+++ b/src/timeline/customtrackview.cpp
@@ -7791,10 +7791,6 @@ void CustomTrackView::adjustEffects(ClipItem* item, ItemInfo \
oldInfo, QUndoComma ++i;
}
}
- if (item == m_dragItem) {
- // clip is selected, update effect stack
- emit clipItemSelected(item);
- }
}
diff --git a/src/timeline/keyframeview.cpp b/src/timeline/keyframeview.cpp
index 45885f7..93b5028 100644
--- a/src/timeline/keyframeview.cpp
+++ b/src/timeline/keyframeview.cpp
@@ -529,7 +529,7 @@ void KeyframeView::updateKeyFramePos(QRectF br, int frame, const \
double y) }
int prev = m_keyAnim.key_count() <= 1 || m_keyAnim.key_get_frame(0) == \
activeKeyframe ? 0 : m_keyAnim.previous_key(activeKeyframe - 1) + 1; prev = \
qMax(prev, -m_offset);
- int next = m_keyAnim.key_count() <= 1 || \
m_keyAnim.key_get_frame(m_keyAnim.key_count() - 1) == activeKeyframe ? duration - \
m_offset : m_keyAnim.next_key(activeKeyframe + 1) - 1; + int next = \
m_keyAnim.key_count() <= 1 || m_keyAnim.key_get_frame(m_keyAnim.key_count() - 1) == \
activeKeyframe ? duration - m_offset - 1 : m_keyAnim.next_key(activeKeyframe + 1) - \
1; if (next < 0) next += duration;
int newpos = qBound(prev, frame - m_offset, next);
double newval = keyframeUnmap(br, y);
@@ -961,6 +961,29 @@ QString KeyframeView::cutAnimation(const QString &animation, int \
start, int dura return anim.serialize_cut(start, start + duration);
}
+//static
+QString KeyframeView::switchAnimation(QString animation, int newPos, int oldPos, int \
newDuration, int oldDuration, bool isRect) +{
+ Mlt::Properties props;
+ props.set("keyframes", animation.toUtf8().constData());
+ props.anim_get_double("keyframes", 0, oldDuration);
+ Mlt::Animation anim = props.get_animation("keyframes");
+ if (anim.is_key(oldPos)) {
+ // insert new keyframe at start
+ if (isRect) {
+ mlt_rect rect = props.anim_get_rect("keyframes", oldPos);
+ props.anim_set("keyframes", rect, newPos, newDuration, \
anim.keyframe_type(oldPos)); + anim.remove(oldPos);
+ } else {
+ double value = props.anim_get_double("keyframes", oldPos, oldDuration);
+ props.anim_set("keyframes", value, newPos, newDuration, \
anim.keyframe_type(oldPos)); + anim.remove(oldPos);
+ }
+ }
+ return anim.serialize_cut();
+ //return anim.serialize_cut(start, start + duration);
+}
+
/*
void KeyframeView::updateAnimatedKeyframes(QDomElement effect, int paramIndex, \
ItemInfo oldInfo)
diff --git a/src/timeline/keyframeview.h b/src/timeline/keyframeview.h
index 5b16715..2eef776 100644
--- a/src/timeline/keyframeview.h
+++ b/src/timeline/keyframeview.h
@@ -93,6 +93,8 @@ public:
void showMenu(QWidget *parent, QPoint pos);
QAction *parseKeyframeActions(QList <QAction *>actions);
static QString cutAnimation(const QString &animation, int start, int duration, \
int fullduration, bool doCut = true); + /** @brief when an animation is resized, \
update in / out point keyframes */ + static QString switchAnimation(QString \
animation, int newPos, int oldPos, int newDuration, int oldDuration, \
bool isRect);
/** @brief when loading an animation from a serialized string, check where is \
the first negative keyframe) */ static int checkNegatives(const QString &data, int \
maxDuration); /** @brief returns true if currently edited parameter name is name */
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic