]> git.sesse.net Git - kdenlive/commitdiff
Implement drag & drop of effects in effect stack
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Mon, 26 Mar 2012 09:36:24 +0000 (11:36 +0200)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Mon, 26 Mar 2012 09:36:24 +0000 (11:36 +0200)
src/clipitem.cpp
src/customtrackview.cpp
src/effectstack/collapsibleeffect.cpp
src/effectstack/collapsibleeffect.h
src/effectstack/effectstackview2.cpp
src/effectstack/effectstackview2.h

index b934e217f0202108dcb63bbd12468a1fa3ba56d7..1d0e4c7b58a694f25f2ee6ea4ead9a2e6620306a 100644 (file)
@@ -1391,7 +1391,7 @@ bool ClipItem::updateEffect(QDomElement effect)
 
 bool ClipItem::moveEffect(QDomElement effect, int ix)
 {
-    if (ix < 0 || ix > (m_effectList.count() - 1) || effect.isNull()) {
+    if (ix <= 0 || ix > (m_effectList.count()) || effect.isNull()) {
         kDebug() << "Invalid effect index: " << ix;
         return false;
     }
index 94de517ac33829b30c8996aa2cd7c1e16a9ff12a..c6abfabcd8616db1fd0fe62ca3433197f17ccd2a 100644 (file)
@@ -1999,10 +1999,14 @@ void CustomTrackView::moveEffect(int track, GenTime pos, int oldPos, int newPos)
     if (newPos > clip->effectsCount()) {
        newPos = clip->effectsCount();
     }
-    if (clip && !clip->effectAt(newPos ).isNull() && !clip->effectAt(oldPos).isNull()) {
+    if (clip) {
         QDomElement act = clip->effectAt(newPos);
         QDomElement before = clip->effectAt(oldPos);
-        clip->moveEffect(act, oldPos);
+       if (act.isNull() || before.isNull()) {
+           emit displayMessage(i18n("Cannot move effect"), ErrorMessage);
+           return;
+       }
+        //clip->moveEffect(act, oldPos);
         clip->moveEffect(before, newPos);
         // special case: speed effect, which is a pseudo-effect, not appearing in MLT's effects
         if (act.attribute("id") == "speed") {
@@ -2010,7 +2014,7 @@ void CustomTrackView::moveEffect(int track, GenTime pos, int oldPos, int newPos)
         } else if (before.attribute("id") == "speed") {
             m_document->renderer()->mltUpdateEffectPosition(track, pos, newPos, oldPos);
         } else m_document->renderer()->mltMoveEffect(track, pos, oldPos, newPos);
-        emit clipItemSelected(clip, newPos - 1);
+        emit clipItemSelected(clip, newPos);
         setDocumentModified();
     } else emit displayMessage(i18n("Cannot move effect"), ErrorMessage);
 }
index 4f1e3cc4b0e295f8cb77b1db8135aee44a51003d..49e303aa09c5373053b1d5515ff75c952adfb6b1 100644 (file)
@@ -170,12 +170,11 @@ CollapsibleEffect::CollapsibleEffect(QDomElement effect, QDomElement original_ef
        setupWidget(info, ix, metaInfo);
     }
     else {
-       setAcceptDrops(true);
        title->setText(i18n("Effect Group"));
        title->setIcon(KIcon("folder"));
        m_menu->addAction(KIcon("list-remove"), i18n("Ungroup"), this, SLOT(slotUnGroup()));
     }
-    
+    setAcceptDrops(true);
     title->setMenu(m_menu);
     
     if (m_effect.attribute("disable") == "1") {
@@ -275,11 +274,13 @@ QDomElement CollapsibleEffect::effect() const
     return m_effect;
 }
 
-void CollapsibleEffect::setActive(bool activate)
+void CollapsibleEffect::setActive(bool activate, bool focused)
 {
     m_active = activate;
-    frame->setBackgroundRole(m_active ? QPalette::Mid : QPalette::Midlight);
-    frame->setAutoFillBackground(activate);
+    if (focused) {
+       frame->setBackgroundRole(QPalette::Highlight);
+    }
+    else frame->setBackgroundRole(m_active ? QPalette::Mid : QPalette::Midlight);
 }
 
 void CollapsibleEffect::mouseDoubleClickEvent ( QMouseEvent * event )
@@ -299,8 +300,6 @@ void CollapsibleEffect::enterEvent ( QEvent * event )
     if (m_paramWidget == NULL || m_paramWidget->index() > 0) buttonUp->setVisible(true);
     if (!m_lastEffect) buttonDown->setVisible(true);
     buttonDel->setVisible(true);
-    if (!m_active) frame->setBackgroundRole(QPalette::Midlight);
-    frame->setAutoFillBackground(true);
     QWidget::enterEvent(event);
 }
 
@@ -309,7 +308,6 @@ void CollapsibleEffect::leaveEvent ( QEvent * event )
     buttonUp->setVisible(false);
     buttonDown->setVisible(false);
     buttonDel->setVisible(false);
-    if (!m_active) frame->setAutoFillBackground(false);
     QWidget::leaveEvent(event);
 }
 
@@ -546,8 +544,15 @@ void CollapsibleEffect::slotSyncEffectsPos(int pos)
 
 void CollapsibleEffect::dragEnterEvent(QDragEnterEvent *event)
 {
-    if (event->mimeData()->hasFormat("kdenlive/effectslist"))
+    if (event->mimeData()->hasFormat("kdenlive/effectslist")) {
+       setActive(m_active, true);
        event->acceptProposedAction();
+    }
+}
+
+void CollapsibleEffect::dragLeaveEvent(QDragLeaveEvent */*event*/)
+{
+    setActive(m_active, false);
 }
 
 void CollapsibleEffect::dropEvent(QDropEvent *event)
@@ -558,14 +563,22 @@ void CollapsibleEffect::dropEvent(QDropEvent *event)
     doc.setContent(effects, true);
     const QDomElement e = doc.documentElement();
     int ix = e.attribute("kdenlive_ix").toInt();
-    int last_index = -1;
+    if (ix == effectIndex()) {
+       // effect dropped on itself, reject
+       event->ignore();
+       return;
+    }
+    int new_index = -1;
     if (m_isGroup) {
        QVBoxLayout *vbox = static_cast<QVBoxLayout *>(widgetFrame->layout());
        if (vbox == NULL) return;
        CollapsibleEffect *e = static_cast<CollapsibleEffect *>(vbox->itemAt(vbox->count() -1)->widget());
-       last_index = e->effectIndex();
+       new_index = e->effectIndex() + 1;
+    }
+    else {
+       new_index = effectIndex();
     }
-    emit moveEffect(ix, this, last_index);
+    emit moveEffect(ix, new_index, this);
     event->setDropAction(Qt::MoveAction);
     event->accept();
 }
index 0a282629ffba4843c56c354e9b82057a36c1dcd9..c4112d323b990cce24824c47ed67375b0628a315 100644 (file)
@@ -119,7 +119,7 @@ public:
     static QMap<QString, QImage> iconCache;
     void setupWidget(ItemInfo info, int index, EffectMetaInfo *metaInfo);
     void updateTimecodeFormat();
-    void setActive(bool activate);
+    void setActive(bool activate, bool focused = false);
     virtual bool eventFilter( QObject * o, QEvent * e );
     /** @brief Update effect GUI to reflect parameted changes. */
     void updateWidget(ItemInfo info, int index, QDomElement effect, EffectMetaInfo *metaInfo);
@@ -171,6 +171,7 @@ protected:
     virtual void enterEvent( QEvent * event );
     virtual void leaveEvent( QEvent * event );
     virtual void dragEnterEvent(QDragEnterEvent *event);
+    virtual void dragLeaveEvent(QDragLeaveEvent *event);
     virtual void dropEvent(QDropEvent *event);
     
 signals:
@@ -190,7 +191,7 @@ signals:
     void resetEffect(int ix);
     /** @brief Ask for creation of a group. */
     void createGroup(int ix);
-    void moveEffect(int ix, CollapsibleEffect *group, int lastEffectIndex);
+    void moveEffect(int current_pos, int new_pos, CollapsibleEffect *target);
     void unGroup(CollapsibleEffect *);
 };
 
index 26131529bbef087b0dc005bd9b048f3d68ba894c..d910482853b1bb55a48f14a1ec5c0fbac1a7fc42 100644 (file)
@@ -125,14 +125,7 @@ void EffectStackView2::slotClipItemSelected(ClipItem* c, int ix)
         //TODO: clear list, reset paramdesc and info
         //ItemInfo info;
         //m_effectedit->transferParamDesc(QDomElement(), info);
-        m_effects.clear();
-       QWidget *view = m_ui.container->takeWidget();
-       if (view) {
-           delete view;
-       }
-        m_ui.checkAll->setToolTip(QString());
-        m_ui.checkAll->setText(QString());
-        setEnabled(false);
+       clear();
         return;
     }
     setEnabled(true);
@@ -198,7 +191,7 @@ void EffectStackView2::setupListView(int ix)
            if (group == NULL) {
                group = new CollapsibleEffect(QDomElement(), QDomElement(), ItemInfo(), effectInfo.groupIndex, &m_effectMetaInfo, false, true, m_ui.container->widget());
                if (!effectInfo.groupName.isEmpty()) group->title->setText(effectInfo.groupName);
-               connect(group, SIGNAL(moveEffect(int,CollapsibleEffect*,int)), this , SLOT(slotMoveEffectToGroup(int,CollapsibleEffect*,int)));
+               connect(group, SIGNAL(moveEffect(int,int,CollapsibleEffect*)), this, SLOT(slotMoveEffect(int,int,CollapsibleEffect*)));
                connect(group, SIGNAL(unGroup(CollapsibleEffect*)), this , SLOT(slotUnGroup(CollapsibleEffect*)));
                vbox1->addWidget(group);
            }
@@ -235,13 +228,13 @@ void EffectStackView2::setupListView(int ix)
         connect(currentEffect, SIGNAL(deleteEffect(const QDomElement)), this , SLOT(slotDeleteEffect(const QDomElement)));
        connect(currentEffect, SIGNAL(reloadEffects()), this , SIGNAL(reloadEffects()));
        connect(currentEffect, SIGNAL(resetEffect(int)), this , SLOT(slotResetEffect(int)));
-        connect(currentEffect, SIGNAL(changeEffectPosition(int,bool)), this , SLOT(slotMoveEffect(int , bool)));
+        connect(currentEffect, SIGNAL(changeEffectPosition(int,bool)), this , SLOT(slotMoveEffectUp(int , bool)));
         connect(currentEffect, SIGNAL(effectStateChanged(bool, int)), this, SLOT(slotUpdateEffectState(bool, int)));
         connect(currentEffect, SIGNAL(activateEffect(int)), this, SLOT(slotSetCurrentEffect(int)));
         connect(currentEffect, SIGNAL(checkMonitorPosition(int)), this, SLOT(slotCheckMonitorPosition(int)));
         connect(currentEffect, SIGNAL(seekTimeline(int)), this , SLOT(slotSeekTimeline(int)));
        connect(currentEffect, SIGNAL(createGroup(int)), this , SLOT(slotCreateGroup(int)));
-       connect(currentEffect, SIGNAL(moveEffect(int,CollapsibleEffect*,int)), this , SLOT(slotMoveEffectToGroup(int,CollapsibleEffect*,int)));
+       connect(currentEffect, SIGNAL(moveEffect(int,int,CollapsibleEffect*)), this , SLOT(slotMoveEffect(int,int,CollapsibleEffect*)));
        
         //ui.title->setPixmap(icon.pixmap(QSize(12, 12)));
     }
@@ -365,6 +358,14 @@ int EffectStackView2::isTrackMode(bool *ok) const
 
 void EffectStackView2::clear()
 {
+    m_effects.clear();
+    QWidget *view = m_ui.container->takeWidget();
+    if (view) {
+       delete view;
+    }
+    m_ui.checkAll->setToolTip(QString());
+    m_ui.checkAll->setText(QString());
+    setEnabled(false);
 }
 
 void EffectStackView2::updateProjectFormat(MltVideoProfile profile, Timecode t)
@@ -422,7 +423,7 @@ void EffectStackView2::slotDeleteEffect(const QDomElement effect)
         emit removeEffect(m_clipref, -1, effect);
 }
 
-void EffectStackView2::slotMoveEffect(int index, bool up)
+void EffectStackView2::slotMoveEffectUp(int index, bool up)
 {
     if (up && index <= 1) return;
     if (!up && index >= m_currentEffectList.count()) return;
@@ -521,26 +522,24 @@ void EffectStackView2::slotCreateGroup(int ix)
     
     CollapsibleEffect *group = new CollapsibleEffect(QDomElement(), QDomElement(), ItemInfo(), m_groupIndex, &m_effectMetaInfo, false, true, m_ui.container->widget());
     m_groupIndex++;
-    connect(group, SIGNAL(moveEffect(int,CollapsibleEffect*,int)), this , SLOT(slotMoveEffectToGroup(int,CollapsibleEffect*,int)));
+    connect(group, SIGNAL(moveEffect(int,int,CollapsibleEffect*)), this , SLOT(slotMoveEffect(int,int,CollapsibleEffect*)));
     connect(group, SIGNAL(unGroup(CollapsibleEffect*)), this , SLOT(slotUnGroup(CollapsibleEffect*)));
     l->insertWidget(groupPos, group);
     group->addGroupEffect(effectToMove);
 }
 
-void EffectStackView2::slotMoveEffectToGroup(int effectIndex, CollapsibleEffect* group, int lastEffectIndex)
+void EffectStackView2::slotMoveEffect(int currentIndex, int newIndex, CollapsibleEffect* target)
 {
     QVBoxLayout *l = static_cast<QVBoxLayout *>(m_ui.container->widget()->layout());
-    CollapsibleEffect *effectToMove = getEffectByIndex(effectIndex);
+    CollapsibleEffect *effectToMove = getEffectByIndex(currentIndex);
     if (effectToMove == NULL) return;
-    l->removeWidget(effectToMove);
-    group->addGroupEffect(effectToMove);
-    
+
     QDomElement oldeffect = effectToMove->effect();
     QDomElement neweffect = oldeffect.cloneNode().toElement();
     
     EffectInfo effectinfo;
     effectinfo.fromString(oldeffect.attribute("kdenlive_info"));
-    effectinfo.groupIndex = group->groupIndex();
+    effectinfo.groupIndex = target->groupIndex();
     neweffect.setAttribute("kdenlive_info", effectinfo.toString());
 
     ItemInfo info;
@@ -555,13 +554,13 @@ void EffectStackView2::slotMoveEffectToGroup(int effectIndex, CollapsibleEffect*
        emit updateEffect(m_clipref, -1, oldeffect, neweffect, effectToMove->index());
     }
     
-    if (effectToMove->effectIndex() == lastEffectIndex) return;
+    if (currentIndex == newIndex) return;
     // Update effect index with new position
     if (m_effectMetaInfo.trackMode) {
-       emit changeEffectPosition(NULL, m_trackindex, effectToMove->effectIndex(), lastEffectIndex + 1);
+       emit changeEffectPosition(NULL, m_trackindex, currentIndex, newIndex);
     }
     else {
-       emit changeEffectPosition(m_clipref, -1, effectToMove->effectIndex(), lastEffectIndex + 1);
+       emit changeEffectPosition(m_clipref, -1, currentIndex, newIndex);
     }
 }
 
index d169285368c29650539d302826788fc323ee67db..1ab3f1b7ce93503901a8a3ae640c19fbbd85a1e3 100644 (file)
@@ -130,7 +130,7 @@ private slots:
     /** @brief Move an effect in the stack.
      * @param index The effect index in the stack
      * @param up true if we want to move effect up, false for down */
-    void slotMoveEffect(int index, bool up);
+    void slotMoveEffectUp(int index, bool up);
 
     /** @brief Delete an effect in the stack. */
     void slotDeleteEffect(const QDomElement effect);
@@ -154,10 +154,10 @@ private slots:
     
     /** @brief Move an effect into a group.
       ** @param ix the index of effect to move in stack layout
-      ** @param group the effect group where the effect is moved
+      ** @param group the effect on which the effect was dropped
       ** @param lastEffectIndex the last effect index in the group, effect will be inserted after that index
       */
-    void slotMoveEffectToGroup(int effectIndex, CollapsibleEffect *group, int lastEffectIndex);
+    void slotMoveEffect(int currentIndex, int newIndex, CollapsibleEffect* target);
     /** @brief Remove effects from a group */
     void slotUnGroup(CollapsibleEffect* group);