]> git.sesse.net Git - kdenlive/blobdiff - src/effectstackedit.cpp
Fix small display issue in render widget
[kdenlive] / src / effectstackedit.cpp
index 2c20c8fd4e558388f91913f1bfea92d5823eb97e..f3184f298b20248bbd4e38b54a909b9ccdde7f4d 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          effecstackview.cpp  -  description
+                          effecstackedit.cpp  -  description
                              -------------------
     begin                : Feb 15 2008
     copyright            : (C) 2008 by Marco Gittler
@@ -16,7 +16,6 @@
  ***************************************************************************/
 
 #include "effectstackedit.h"
-#include "ui_constval_ui.h"
 #include "ui_listval_ui.h"
 #include "ui_boolval_ui.h"
 #include "ui_wipeval_ui.h"
 #include "kis_cubic_curve.h"
 #include "choosecolorwidget.h"
 #include "geometrywidget.h"
+#include "colortools.h"
+#include "doubleparameterwidget.h"
+#include "cornerswidget.h"
 
 #include <KDebug>
 #include <KLocale>
 #include <KFileDialog>
 
 #include <QVBoxLayout>
-#include <QSlider>
 #include <QLabel>
 #include <QPushButton>
 #include <QCheckBox>
@@ -49,10 +50,6 @@ class Boolval: public QWidget, public Ui::Boolval_UI
 {
 };
 
-class Constval: public QWidget, public Ui::Constval_UI
-{
-};
-
 class Listval: public QWidget, public Ui::Listval_UI
 {
 };
@@ -68,12 +65,12 @@ class Urlval: public QWidget, public Ui::Urlval_UI
 QMap<QString, QImage> EffectStackEdit::iconCache;
 
 EffectStackEdit::EffectStackEdit(Monitor *monitor, QWidget *parent) :
-        QScrollArea(parent),
-        m_in(0),
-        m_out(0),
-        m_frameSize(QPoint()),
-        m_keyframeEditor(NULL),
-        m_monitor(monitor)
+    QScrollArea(parent),
+    m_in(0),
+    m_out(0),
+    m_frameSize(QPoint()),
+    m_keyframeEditor(NULL),
+    m_monitor(monitor)
 {
     m_baseWidget = new QWidget(this);
     setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
@@ -117,6 +114,7 @@ void EffectStackEdit::updateTimecodeFormat()
 {
     if (m_keyframeEditor)
         m_keyframeEditor->updateTimecodeFormat();
+
     QDomNodeList namenode = m_params.elementsByTagName("parameter");
     for (int i = 0; i < namenode.count() ; i++) {
         QDomNode pa = namenode.item(i);
@@ -142,6 +140,17 @@ void EffectStackEdit::updateTimecodeFormat()
     }
 }
 
+void EffectStackEdit::meetDependency(const QString& name, QString type, QString value)
+{
+    if (type == "curve") {
+        KisCurveWidget *curve = (KisCurveWidget*)m_valueItems[name];
+        if (curve) {
+            int color = value.toInt();
+            curve->setPixmap(QPixmap::fromImage(ColorTools::rgbCurvePlane(curve->size(), (ColorTools::ColorsRGB)color, 0.8)));
+        }
+    }
+}
+
 void EffectStackEdit::updateProjectFormat(MltVideoProfile profile, Timecode t)
 {
     m_profile = profile;
@@ -151,6 +160,26 @@ void EffectStackEdit::updateProjectFormat(MltVideoProfile profile, Timecode t)
 void EffectStackEdit::updateParameter(const QString &name, const QString &value)
 {
     m_params.setAttribute(name, value);
+
+    if (name == "disable") {
+        // if effect is disabled, disable parameters widget
+        setEnabled(value.toInt() == 0 || !KdenliveSettings::disable_effect_parameters());
+        if (KdenliveSettings::on_monitor_effects()) {
+            // effect disabled, hide monitor scene if any
+            QDomNodeList namenode = m_params.elementsByTagName("parameter");
+            for (int i = 0; i < namenode.count() ; i++) {
+                QDomNode pa = namenode.item(i);
+                QDomNode na = pa.firstChildElement("name");
+                QString type = pa.attributes().namedItem("type").nodeValue();
+                if (type == "geometry") {
+                    QString paramName = i18n(na.toElement().text().toUtf8().data());
+                    paramName.append("geometry");
+                    GeometryWidget *geometry = ((GeometryWidget*)m_valueItems.value(paramName));
+                    geometry->slotShowScene(value.toInt() == 0 || !KdenliveSettings::disable_effect_parameters());
+                }
+            }
+        }
+    }
 }
 
 void EffectStackEdit::transferParamDesc(const QDomElement d, int pos, int in, int out, bool isEffect)
@@ -166,21 +195,24 @@ void EffectStackEdit::transferParamDesc(const QDomElement d, int pos, int in, in
         return;
     }
 
-    /*QDomDocument doc;
-    doc.appendChild(doc.importNode(m_params, true));
-    kDebug() << "IMPORTED TRANS: " << doc.toString();*/
-
     QDomNodeList namenode = m_params.elementsByTagName("parameter");
     QDomElement e = m_params.toElement();
     const int minFrame = e.attribute("start").toInt();
     const int maxFrame = e.attribute("end").toInt();
 
+    bool disable = d.attribute("disable") == "1" && KdenliveSettings::disable_effect_parameters();
+    setEnabled(!disable);
+
 
     for (int i = 0; i < namenode.count() ; i++) {
         QDomElement pa = namenode.item(i).toElement();
-        QDomNode na = pa.firstChildElement("name");
+        QDomElement na = pa.firstChildElement("name");
+        QDomElement commentElem = pa.firstChildElement("comment");
         QString type = pa.attribute("type");
-        QString paramName = i18n(na.toElement().text().toUtf8().data());
+        QString paramName = i18n(na.text().toUtf8().data());
+        QString comment;
+        if (!commentElem.isNull())
+            comment = i18n(commentElem.text().toUtf8().data());
         QWidget * toFillin = new QWidget(m_baseWidget);
         QString value = pa.attribute("value").isNull() ?
                         pa.attribute("default") : pa.attribute("value");
@@ -209,16 +241,20 @@ void EffectStackEdit::transferParamDesc(const QDomElement d, int pos, int in, in
                 max = (int) ProfilesDialog::getStringEval(m_profile, pa.attribute("max"));
             else
                 max = pa.attribute("max").toInt();
-            createSliderItem(paramName, (int)(value.toDouble() + 0.5) , min, max, pa.attribute("suffix", QString()));
-            delete toFillin;
-            toFillin = NULL;
+
+            DoubleParameterWidget *doubleparam = new DoubleParameterWidget(paramName, (int)(value.toDouble() + 0.5), min, max,
+                    pa.attribute("default").toInt(), comment, pa.attribute("suffix"), this);
+            m_vbox->addWidget(doubleparam);
+            m_valueItems[paramName] = doubleparam;
+            connect(doubleparam, SIGNAL(valueChanged(int)), this, SLOT(collectAllParameters()));
+            connect(this, SIGNAL(showComments()), doubleparam, SLOT(slotShowComment()));
         } else if (type == "list") {
             Listval *lsval = new Listval;
             lsval->setupUi(toFillin);
             QStringList listitems = pa.attribute("paramlist").split(',');
             QStringList listitemsdisplay = pa.attribute("paramlistdisplay").split(',');
-            if (listitemsdisplay.count() != listitems.count()) listitemsdisplay = listitems;
-            //lsval->list->addItems(listitems);
+            if (listitemsdisplay.count() != listitems.count())
+                listitemsdisplay = listitems;
             lsval->list->setIconSize(QSize(30, 30));
             for (int i = 0; i < listitems.count(); i++) {
                 lsval->list->addItem(listitemsdisplay.at(i), listitems.at(i));
@@ -232,7 +268,7 @@ void EffectStackEdit::transferParamDesc(const QDomElement d, int pos, int in, in
                 }
             }
             if (!value.isEmpty()) lsval->list->setCurrentIndex(listitems.indexOf(value));
-            lsval->title->setTitle(paramName);
+            lsval->name->setText(paramName);
             m_valueItems[paramName] = lsval;
             connect(lsval->list, SIGNAL(currentIndexChanged(int)) , this, SLOT(collectAllParameters()));
             m_uiItems.append(lsval);
@@ -240,24 +276,11 @@ void EffectStackEdit::transferParamDesc(const QDomElement d, int pos, int in, in
             Boolval *bval = new Boolval;
             bval->setupUi(toFillin);
             bval->checkBox->setCheckState(value == "0" ? Qt::Unchecked : Qt::Checked);
-            bval->checkBox->setText(paramName);
+            bval->name->setText(paramName);
             m_valueItems[paramName] = bval;
             connect(bval->checkBox, SIGNAL(stateChanged(int)) , this, SLOT(collectAllParameters()));
             m_uiItems.append(bval);
         } else if (type == "complex") {
-            /*QStringList names=nodeAtts.namedItem("name").nodeValue().split(';');
-            QStringList max=nodeAtts.namedItem("max").nodeValue().split(';');
-            QStringList min=nodeAtts.namedItem("min").nodeValue().split(';');
-            QStringList val=value.split(';');
-            kDebug() << "in complex"<<names.size() << " " << max.size() << " " << min.size() << " " << val.size()  ;
-            if ( (names.size() == max.size() ) &&
-                 (names.size()== min.size()) &&
-                 (names.size()== val.size()) )
-            {
-             for (int i=0;i< names.size();i++){
-              createSliderItem(names[i],val[i].toInt(),min[i].toInt(),max[i].toInt());
-             };
-            }*/
             ComplexParameter *pl = new ComplexParameter;
             pl->setupParam(d, pa.attribute("name"), 0, 100);
             m_vbox->addWidget(pl);
@@ -265,15 +288,16 @@ void EffectStackEdit::transferParamDesc(const QDomElement d, int pos, int in, in
             connect(pl, SIGNAL(parameterChanged()), this, SLOT(collectAllParameters()));
         } else if (type == "geometry") {
             if (KdenliveSettings::on_monitor_effects()) {
-                GeometryWidget *geometry = new GeometryWidget(m_monitor, m_timecode, pos, isEffect, this);
+                GeometryWidget *geometry = new GeometryWidget(m_monitor, m_timecode, pos, isEffect, disable, this);
+                // connect this before setupParam to make sure the monitor scene shows up at startup
+                connect(geometry, SIGNAL(checkMonitorPosition(int)), this, SIGNAL(checkMonitorPosition(int)));
+                connect(geometry, SIGNAL(parameterChanged()), this, SLOT(collectAllParameters()));
                 if (minFrame == maxFrame)
                     geometry->setupParam(pa, m_in, m_out);
                 else
                     geometry->setupParam(pa, minFrame, maxFrame);
                 m_vbox->addWidget(geometry);
                 m_valueItems[paramName+"geometry"] = geometry;
-                connect(geometry, SIGNAL(parameterChanged()), this, SLOT(collectAllParameters()));
-                connect(geometry, SIGNAL(checkMonitorPosition(int)), this, SIGNAL(checkMonitorPosition(int)));
                 connect(geometry, SIGNAL(seekToPos(int)), this, SIGNAL(seekTimeline(int)));
                 connect(this, SIGNAL(syncEffectsPos(int)), geometry, SLOT(slotSyncPosition(int)));
             } else {
@@ -289,15 +313,15 @@ void EffectStackEdit::transferParamDesc(const QDomElement d, int pos, int in, in
                 connect(this, SIGNAL(syncEffectsPos(int)), geo, SLOT(slotSyncPosition(int)));
             }
         } else if (type == "keyframe" || type == "simplekeyframe") {
-            // keyframe editor widget
-            kDebug() << "min: " << m_in << ", MAX: " << m_out;
+            // keyframe editor widget
             if (m_keyframeEditor == NULL) {
-                KeyframeEdit *geo = new KeyframeEdit(pa, m_in, m_in + m_out, pa.attribute("min").toInt(), pa.attribute("max").toInt(), m_timecode, e.attribute("active_keyframe", "-1").toInt());
+                KeyframeEdit *geo = new KeyframeEdit(pa, m_in, m_in + m_out, m_timecode, e.attribute("active_keyframe", "-1").toInt());
                 m_vbox->addWidget(geo);
                 m_valueItems[paramName+"keyframe"] = geo;
                 m_keyframeEditor = geo;
                 connect(geo, SIGNAL(parameterChanged()), this, SLOT(collectAllParameters()));
                 connect(geo, SIGNAL(seekToPos(int)), this, SIGNAL(seekTimeline(int)));
+                connect(this, SIGNAL(showComments()), geo, SIGNAL(showComments()));
             } else {
                 // we already have a keyframe editor, so just add another column for the new param
                 m_keyframeEditor->addParameter(pa);
@@ -317,9 +341,9 @@ void EffectStackEdit::transferParamDesc(const QDomElement d, int pos, int in, in
                 pos = pos - m_in;
             } else if (d.attribute("id") == "fadeout" || d.attribute("id") == "fade_to_black") {
                 // fadeout position starts from clip end
-                pos = m_out - (pos - m_in);
+                pos = m_out - pos;
             }
-            PositionEdit *posedit = new PositionEdit(paramName, pos, 1, m_out, m_timecode);
+            PositionEdit *posedit = new PositionEdit(paramName, pos, 0, m_out - m_in, m_timecode);
             m_vbox->addWidget(posedit);
             m_valueItems[paramName+"position"] = posedit;
             connect(posedit, SIGNAL(parameterChanged()), this, SLOT(collectAllParameters()));
@@ -348,8 +372,35 @@ void EffectStackEdit::transferParamDesc(const QDomElement d, int pos, int in, in
             m_vbox->addWidget(curve);
             m_vbox->addWidget(spinin);
             m_vbox->addWidget(spinout);
+
             connect(curve, SIGNAL(modified()), this, SLOT(collectAllParameters()));
             m_valueItems[paramName] = curve;
+
+            QString depends = pa.attribute("depends");
+            if (!depends.isEmpty())
+                meetDependency(paramName, type, EffectsList::parameter(e, depends));
+        } else if (type == "corners") {
+            CornersWidget *corners = new CornersWidget(m_monitor, pos, isEffect, pa.attribute("factor").toInt(), this);
+            connect(corners, SIGNAL(checkMonitorPosition(int)), this, SIGNAL(checkMonitorPosition(int)));
+            if (minFrame == maxFrame)
+                corners->setRange(m_in, m_out);
+            else
+                corners->setRange(minFrame, maxFrame);
+
+            QString xName = pa.attribute("xpoints");
+            QString yName = pa.attribute("ypoints");
+            QPolygon points;
+            int x, y;
+            for (int j = 1; j <= 4; ++j) {
+                x = EffectsList::parameter(e, QString(xName).replace("%i", QString::number(j))).toInt();
+                y = EffectsList::parameter(e, QString(yName).replace("%i", QString::number(j))).toInt();
+                points << QPoint(x, y);
+            }
+            corners->setValue(points);
+
+            m_vbox->addWidget(corners);
+            connect(corners, SIGNAL(parameterChanged()), this, SLOT(collectAllParameters()));
+            m_valueItems[paramName] = corners;
         } else if (type == "wipe") {
             Wipeval *wpval = new Wipeval;
             wpval->setupUi(toFillin);
@@ -424,6 +475,9 @@ void EffectStackEdit::transferParamDesc(const QDomElement d, int pos, int in, in
             m_vbox->addWidget(toFillin);
     }
     m_vbox->addStretch();
+
+    if (m_keyframeEditor)
+        m_keyframeEditor->checkVisibleParam();
 }
 
 wipeInfo EffectStackEdit::getWipeInfo(QString value)
@@ -539,8 +593,8 @@ void EffectStackEdit::collectAllParameters()
 
         QString setValue;
         if (type == "double" || type == "constant") {
-            QSlider* slider = ((Constval*)m_valueItems.value(paramName))->horizontalSlider;
-            setValue = QString::number(slider->value());
+            DoubleParameterWidget *doubleparam = (DoubleParameterWidget*)m_valueItems.value(paramName);
+            setValue = QString::number(doubleparam->getValue());
         } else if (type == "list") {
             KComboBox *box = ((Listval*)m_valueItems.value(paramName))->list;
             setValue = box->itemData(box->currentIndex()).toString();
@@ -580,8 +634,8 @@ void EffectStackEdit::collectAllParameters()
                     pos = m_out;
                     pedit->setPosition(pos);
                 }*/
-                EffectsList::setParameter(newparam, "in", QString::number(m_out + m_in - pos));
-                EffectsList::setParameter(newparam, "out", QString::number(m_out + m_in));
+                EffectsList::setParameter(newparam, "in", QString::number(m_out - pos));
+                EffectsList::setParameter(newparam, "out", QString::number(m_out));
                 setValue.clear();
             }
         } else if (type == "curve") {
@@ -601,6 +655,20 @@ void EffectStackEdit::collectAllParameters()
                 EffectsList::setParameter(newparam, in, QString::number(points.at(j).x()));
                 EffectsList::setParameter(newparam, out, QString::number(points.at(j).y()));
             }
+            QString depends = pa.attributes().namedItem("depends").nodeValue();
+            if (!depends.isEmpty())
+                meetDependency(paramName, type, EffectsList::parameter(newparam, depends));
+        } else if (type == "corners") {
+            CornersWidget *corners = ((CornersWidget*)m_valueItems.value(paramName));
+            QString xName = pa.attributes().namedItem("xpoints").nodeValue();
+            QString yName = pa.attributes().namedItem("ypoints").nodeValue();
+            QPolygon points = corners->getValue();
+            QPoint p;
+            for (int j = 1; j <= 4; ++j) {
+                p = points.at(j - 1);
+                EffectsList::setParameter(newparam, QString(xName).replace("%i", QString::number(j)), QString::number(p.x()));
+                EffectsList::setParameter(newparam, QString(yName).replace("%i", QString::number(j)), QString::number(p.y()));
+            }
         } else if (type == "wipe") {
             Wipeval *wp = (Wipeval*)m_valueItems.value(paramName);
             wipeInfo info;
@@ -634,10 +702,15 @@ void EffectStackEdit::collectAllParameters()
 
             setValue = getWipeString(info);
         } else if ((type == "simplekeyframe" || type == "keyframe") && m_keyframeEditor) {
+            QDomElement elem = pa.toElement();
             QString realName = i18n(na.toElement().text().toUtf8().data());
             QString val = m_keyframeEditor->getValue(realName);
-            kDebug() << "SET VALUE: " << val;
-            namenode.item(i).toElement().setAttribute("keyframes", val);
+            elem.setAttribute("keyframes", val);
+
+            if (m_keyframeEditor->isVisibleParam(realName))
+                elem.setAttribute("intimeline", "1");
+            else if (elem.hasAttribute("intimeline"))
+                elem.removeAttribute("intimeline");
         } else if (type == "url") {
             KUrlRequester *req = ((Urlval*)m_valueItems.value(paramName))->urlwidget;
             setValue = req->url().path();
@@ -650,30 +723,6 @@ void EffectStackEdit::collectAllParameters()
     emit parameterChanged(oldparam, newparam);
 }
 
-void EffectStackEdit::createSliderItem(const QString& name, int val , int min, int max, const QString suffix)
-{
-    QWidget* toFillin = new QWidget(m_baseWidget);
-    Constval *ctval = new Constval;
-    ctval->setupUi(toFillin);
-    ctval->horizontalSlider->setMinimum(min);
-    ctval->horizontalSlider->setMaximum(max);
-    if (!suffix.isEmpty()) ctval->spinBox->setSuffix(suffix);
-    ctval->spinBox->setMinimum(min);
-    ctval->spinBox->setMaximum(max);
-    ctval->horizontalSlider->setPageStep((int)(max - min) / 10);
-    ctval->horizontalSlider->setValue(val);
-    ctval->label->setText(name);
-    m_valueItems[name] = ctval;
-    m_uiItems.append(ctval);
-    connect(ctval->horizontalSlider, SIGNAL(valueChanged(int)) , this, SLOT(collectAllParameters()));
-    m_vbox->addWidget(toFillin);
-}
-
-void EffectStackEdit::slotSliderMoved(int)
-{
-    collectAllParameters();
-}
-
 void EffectStackEdit::clearAllItems()
 {
     blockSignals(true);