]> git.sesse.net Git - kdenlive/blobdiff - src/cornerswidget.cpp
const'ref. Fix indent
[kdenlive] / src / cornerswidget.cpp
index c919ec4aaed5b1100ef7c5de2ca9a5d634a6fb7c..20546a7900ee994918473e6834d351af69574634 100644 (file)
 #include "cornerswidget.h"
 #include "monitor.h"
 #include "monitorscene.h"
-#include "monitorscenecontrolwidget.h"
+#include "monitoreditwidget.h"
 #include "onmonitoritems/onmonitorcornersitem.h"
 #include "renderer.h"
+#include "kdenlivesettings.h"
 
 #include <QGraphicsView>
-#include <QHBoxLayout>
+#include <QGridLayout>
+#include <QToolButton>
 
 #include <KIcon>
 
-CornersWidget::CornersWidget(Monitor* monitor, int clipPos, bool isEffect, int factor, QWidget* parent) :
-        QWidget(parent),
+inline int lerp( const int a, const int b, double t )
+{
+    return a + (b - a) * t;
+}
+
+CornersWidget::CornersWidget(Monitor *monitor, const QDomElement& e, int minFrame, int maxFrame, const Timecode &tc, int activeKeyframe, QWidget* parent) :
+        KeyframeEdit(e, minFrame, maxFrame, tc, activeKeyframe, parent),
         m_monitor(monitor),
-        m_clipPos(clipPos),
-        m_inPoint(0),
-        m_outPoint(1),
-        m_isEffect(isEffect),
         m_showScene(true),
-        m_factor(factor)
+        m_pos(0)
 {
-    m_ui.setupUi(this);
-
-    m_scene = monitor->getEffectScene();
+    MonitorEditWidget *edit = monitor->getEffectEdit();
+    m_scene = edit->getScene();
+    m_scene->cleanup();
 
-    m_item = new OnMonitorCornersItem(m_scene);
+    m_item = new OnMonitorCornersItem();
     m_scene->addItem(m_item);
 
-    m_config = new MonitorSceneControlWidget(m_scene, m_ui.frameConfig);
-    QHBoxLayout *layout = new QHBoxLayout(m_ui.frameConfig);
-    layout->addWidget(m_config->getShowHideButton());
-    layout->addWidget(m_config);
-
-    int width = m_monitor->render->frameRenderWidth();
-    int height = m_monitor->render->renderHeight();
-
-    m_ui.spinX1->setRange(-width, width * 2);
-    m_ui.spinX2->setRange(-width, width * 2);
-    m_ui.spinX3->setRange(-width, width * 2);
-    m_ui.spinX4->setRange(-width, width * 2);
-    m_ui.spinY1->setRange(-height, height * 2);
-    m_ui.spinY2->setRange(-height, height * 2);
-    m_ui.spinY3->setRange(-height, height * 2);
-    m_ui.spinY4->setRange(-height, height * 2);
-
-    m_ui.toolReset1->setIcon(KIcon("edit-undo"));
-    m_ui.toolReset1->setToolTip(i18n("Reset Corner 1"));
-    m_ui.toolReset2->setIcon(KIcon("edit-undo"));
-    m_ui.toolReset2->setToolTip(i18n("Reset Corner 2"));
-    m_ui.toolReset3->setIcon(KIcon("edit-undo"));
-    m_ui.toolReset3->setToolTip(i18n("Reset Corner 3"));
-    m_ui.toolReset4->setIcon(KIcon("edit-undo"));
-    m_ui.toolReset4->setToolTip(i18n("Reset Corner 4"));
-
-    connect(m_ui.spinX1, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateItem()));
-    connect(m_ui.spinX2, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateItem()));
-    connect(m_ui.spinX3, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateItem()));
-    connect(m_ui.spinX4, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateItem()));
-    connect(m_ui.spinY1, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateItem()));
-    connect(m_ui.spinY2, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateItem()));
-    connect(m_ui.spinY3, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateItem()));
-    connect(m_ui.spinY4, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateItem()));
-
-    connect(m_config, SIGNAL(showScene(bool)), this, SLOT(slotShowScene(bool)));
-    connect(m_monitor, SIGNAL(renderPosition(int)), this, SLOT(slotCheckMonitorPosition(int)));
-    connect(m_scene, SIGNAL(actionFinished()), this, SLOT(slotUpdateProperties()));
+    // TODO: Better Icons
+    edit->removeCustomControls();
+    edit->addCustomButton(KIcon("transform-move"), i18n("Show additional controls"), this, SLOT(slotShowControls(bool)),
+                          true, KdenliveSettings::onmonitoreffects_cornersshowcontrols());
+    edit->addCustomButton(KIcon("insert-horizontal-rule"), i18n("Show/Hide the lines connecting the corners"), this, SLOT(slotShowLines(bool)),
+                          true, KdenliveSettings::onmonitoreffects_cornersshowlines());
+
+    connect(m_item, SIGNAL(changed()), this, SLOT(slotUpdateProperties()));
+    connect(m_scene, SIGNAL(addKeyframe()), this, SLOT(slotInsertKeyframe()));
+
+    connect(keyframe_list, SIGNAL(cellChanged(int,int)), this, SLOT(slotUpdateItem()));
+    m_scene->centerView();
 }
 
 CornersWidget::~CornersWidget()
 {
-    delete m_config;
     m_scene->removeItem(m_item);
     delete m_item;
-    if (m_monitor)
-        m_monitor->slotEffectScene(false);
+    if (m_monitor) {
+        MonitorEditWidget *edit = m_monitor->getEffectEdit();
+        edit->removeCustomControls();
+    }
 }
 
-void CornersWidget::setRange(int minframe, int maxframe)
+void CornersWidget::addParameter(const QDomElement &e, int activeKeyframe)
 {
-    m_inPoint = minframe;
-    m_outPoint = maxframe;
-    slotCheckMonitorPosition(m_monitor->render->seekFramePosition());
+    KeyframeEdit::addParameter(e, activeKeyframe);
+
+    if (!m_item->polygon().count())
+        slotUpdateItem();
 }
 
 void CornersWidget::slotUpdateItem()
 {
-    QPointF c1(m_ui.spinX1->value(), m_ui.spinY1->value());
-    QPointF c2(m_ui.spinX2->value(), m_ui.spinY2->value());
-    QPointF c3(m_ui.spinX3->value(), m_ui.spinY3->value());
-    QPointF c4(m_ui.spinX4->value(), m_ui.spinY4->value());
+    if (keyframe_list->columnCount() < 8)
+        return;
+
+    QTableWidgetItem *keyframe, *keyframeOld;
+    keyframe = keyframeOld = keyframe_list->item(0, 0);
+    for (int row = 0; row < keyframe_list->rowCount(); ++row) {
+        keyframeOld = keyframe;
+        keyframe = keyframe_list->item(row, 0);
+        if (getPos(row) >= m_pos)
+            break;
+    }
+
+    QList<QPointF> points, pointsPrev, pointsNext;
+    pointsPrev = getPoints(keyframeOld);
+    pointsNext = getPoints(keyframe);
+    if (pointsPrev.count() != 4 || pointsNext.count() != 4)
+        return;
+
+    qreal position = (m_pos - getPos(keyframeOld->row())) / (qreal)( getPos(keyframe->row()) - getPos(keyframeOld->row()) + 1 );
+
+    if (keyframeOld  == keyframe) {
+        points = pointsNext;
+    } else {
+        for (int i = 0; i < 4; ++i)
+            points.append(QLineF(pointsPrev.at(i), pointsNext.at(i)).pointAt(position));
+    }
 
-    m_item->setPolygon(QPolygonF() << c1 << c2 << c3 << c4);
+    m_scene->blockSignals(true);
+    m_item->setPolygon(QPolygonF() << points.at(0) << points.at(1) << points.at(2) << points.at(3));
+    m_scene->blockSignals(false);
 
-    emit parameterChanged();
+    bool enable = getPos(keyframe->row()) == m_pos || keyframe_list->rowCount() == 1;
+    m_item->setEnabled(enable);
+    m_scene->setEnabled(enable);
 }
 
-void CornersWidget::slotUpdateProperties(bool changed)
+void CornersWidget::slotUpdateProperties()
 {
-    QPolygon pol = m_item->polygon().toPolygon();
-    blockSignals(true);
-    m_ui.spinX1->setValue(pol.at(0).x());
-    m_ui.spinX2->setValue(pol.at(1).x());
-    m_ui.spinX3->setValue(pol.at(2).x());
-    m_ui.spinX4->setValue(pol.at(3).x());
-    m_ui.spinY1->setValue(pol.at(0).y());
-    m_ui.spinY2->setValue(pol.at(1).y());
-    m_ui.spinY3->setValue(pol.at(2).y());
-    m_ui.spinY4->setValue(pol.at(3).y());
-    blockSignals(false);
-
-    if (changed)
-        emit parameterChanged();
-}
+    if (keyframe_list->columnCount() < 8)
+        return;
+
+    QPolygonF pol = m_item->polygon();
+
+    QTableWidgetItem *item = keyframe_list->currentItem();
+    double val;
+    for (int col = 0; col < 8; col++) {
+        if (col % 2 == 0)
+            val = pol.at(col / 2).x() / (double)m_monitor->render->frameRenderWidth();
+        else
+            val = pol.at(col / 2).y() / (double)m_monitor->render->renderHeight();
+        val *= 2000;
+        val += 2000;
+        QTableWidgetItem *nitem = keyframe_list->item(item->row(), col);
+        if (nitem->text().toInt() != (int)val)
+            nitem->setText(QString::number((int)val));
+    }
 
+    slotAdjustKeyframeInfo(false);
+}
 
-QPolygon CornersWidget::getValue()
+QList<QPointF> CornersWidget::getPoints(QTableWidgetItem* keyframe)
 {
-    qreal width = m_monitor->render->frameRenderWidth();
-    qreal height = m_monitor->render->renderHeight();
-    QPolygon corners = m_item->polygon().toPolygon();
-    QPolygon points;
-    QPoint p;
-    for (int i = 0; i < 4; ++i) {
-        p = corners.at(i);
-        p.setX((p.x() / width + 1) / 3.0 * m_factor);
-        p.setY((p.y() / height + 1) / 3.0 * m_factor);
-        points << p;
+    QList<QPointF> points;
+
+    if (!keyframe)
+        return points;
+
+    double val;
+    for (int col = 0; col < 8; col++) {
+        if (!keyframe_list->item(keyframe->row(), col))
+            return QList<QPointF>();
+        val = (keyframe_list->item(keyframe->row(), col)->text().toInt() - 2000) / 2000.;
+        if (col % 2 == 0)
+            points << QPointF(val * m_monitor->render->frameRenderWidth(), 0);
+        else
+            points[col / 2].setY(val * m_monitor->render->renderHeight());
     }
     return points;
 }
 
-void CornersWidget::setValue(const QPolygon& points)
+
+void CornersWidget::slotShowLines(bool show)
 {
-    int width = m_monitor->render->frameRenderWidth();
-    int height = m_monitor->render->renderHeight();
-    QPolygonF corners;
-    QPoint p;
-    for (int i = 0; i < 4; ++i) {
-        p = points.at(i);
-        p.setX((p.x() / (qreal)m_factor * 3 - 1) * width);
-        p.setY((p.y() / (qreal)m_factor * 3 - 1) * height);
-        corners << p;
-    }
-    m_item->setPolygon(corners);
+    KdenliveSettings::setOnmonitoreffects_cornersshowlines(show);
+    m_item->update();
+}
 
-    slotUpdateProperties(false);
+void CornersWidget::slotShowControls(bool show)
+{
+    KdenliveSettings::setOnmonitoreffects_cornersshowcontrols(show);
+    m_item->update();
 }
 
-void CornersWidget::slotCheckMonitorPosition(int renderPos)
+void CornersWidget::slotSyncPosition(int relTimelinePos)
 {
-    if (m_showScene) {
-        /*
-           We do only get the position in timeline if this geometry belongs to a transition,
-           therefore we need two ways here.
-         */
-        if (m_isEffect) {
-            emit checkMonitorPosition(renderPos);
-        } else {
-            if (renderPos >= m_clipPos && renderPos <= m_clipPos + m_outPoint - m_inPoint) {
-                if (!m_scene->views().at(0)->isVisible())
-                    m_monitor->slotEffectScene(true);
-            } else {
-                m_monitor->slotEffectScene(false);
-            }
+    if (keyframe_list->rowCount()) {
+        relTimelinePos = qBound(0, relTimelinePos, m_max);
+        if (relTimelinePos != m_pos - m_min) {
+            m_pos = relTimelinePos + m_min;
+            slotUpdateItem();
         }
     }
 }
 
-void CornersWidget::slotShowScene(bool show)
+void CornersWidget::slotInsertKeyframe()
 {
-    m_showScene = show;
-    if (!m_showScene)
-        m_monitor->slotEffectScene(false);
-    else
-        slotCheckMonitorPosition(m_monitor->render->seekFramePosition());
+    keyframe_list->blockSignals(true);
+
+    int row;
+    QTableWidgetItem *keyframe, *keyframeOld;
+    keyframe = keyframeOld = keyframe_list->item(0, 0);
+    for (row = 0; row < keyframe_list->rowCount(); ++row) {
+        keyframeOld = keyframe;
+        keyframe = keyframe_list->item(row, 0);
+        if (getPos(row) >= m_pos)
+            break;
+    }
+
+
+    int pos2;
+    if (row == keyframe_list->rowCount()) {
+        pos2 = m_max;
+    } else {
+        pos2 = getPos(row);
+        if (pos2 == m_pos)
+            return;
+    }
+
+    int pos1 = 0;
+    if (row > 0)
+        pos1 = getPos(row - 1);
+
+    int col = keyframe_list->currentColumn();
+    double pos = (m_pos - pos1) / (double)(pos2 - pos1 + 1);
+
+    keyframe_list->insertRow(row);
+    keyframe_list->setVerticalHeaderItem(row, new QTableWidgetItem(getPosString(m_pos)));
+
+    QPolygonF pol = m_item->polygon();
+    double val;
+    for (int i = 0; i < keyframe_list->columnCount(); ++i) {
+        if (i < 8) {
+            if (i % 2 == 0)
+                val = pol.at(i / 2).x() / (double)m_monitor->render->frameRenderWidth();
+            else
+                val = pol.at(i / 2).y() / (double)m_monitor->render->renderHeight();
+            val *= 2000;
+            val += 2000;
+            keyframe_list->setItem(row, i, new QTableWidgetItem(QString::number((int)val)));
+        } else {
+            keyframe_list->setItem(row, i, new QTableWidgetItem(QString::number(lerp(keyframe_list->item(keyframeOld->row(), i)->text().toInt(), keyframe_list->item(keyframe->row(), i)->text().toInt(), pos))));
+        }
+    }
+
+    keyframe_list->resizeRowsToContents();
+    slotAdjustKeyframeInfo();
+    keyframe_list->blockSignals(false);
+    generateAllParams();
+    button_delete->setEnabled(true);
+    keyframe_list->setCurrentCell(row, col);
+    keyframe_list->selectRow(row);
 }
 
+
 #include "cornerswidget.moc"