[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