[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