]> git.sesse.net Git - kdenlive/blobdiff - src/geometryval.cpp
Allow to add image sequence through the usual "add clip" dialog
[kdenlive] / src / geometryval.cpp
index 2edcf86f9c644052f759c6351397b7dacc12a3b1..a4879463a0cd30241e1c2cb413d070a0b8c1e091 100644 (file)
@@ -28,7 +28,7 @@
 #include <QInputDialog>
 
 
-Geometryval::Geometryval(const MltVideoProfile profile, QPoint frame_size, int startPoint, QWidget* parent) :
+Geometryval::Geometryval(const MltVideoProfile profile, Timecode t, QPoint frame_size, int startPoint, QWidget* parent) :
         QWidget(parent),
         m_profile(profile),
         m_paramRect(NULL),
@@ -36,9 +36,13 @@ Geometryval::Geometryval(const MltVideoProfile profile, QPoint frame_size, int s
         m_path(NULL),
         m_fixedMode(false),
         m_frameSize(frame_size),
-        m_startPoint(startPoint)
+        m_startPoint(startPoint),
+        m_timePos(t)
 {
     setupUi(this);
+    toolbarlayout->addWidget(&m_timePos);
+    toolbarlayout->insertStretch(-1);
+
     QVBoxLayout* vbox = new QVBoxLayout(widget);
     m_sceneview = new QGraphicsView(this);
     m_sceneview->setBackgroundBrush(QBrush(Qt::black));
@@ -75,11 +79,11 @@ Geometryval::Geometryval(const MltVideoProfile profile, QPoint frame_size, int s
     buttonAdd->setToolTip(i18n("Add keyframe"));
     buttonDelete->setIcon(KIcon("edit-delete"));
     buttonDelete->setToolTip(i18n("Delete keyframe"));
-    
+
     m_configMenu = new QMenu(i18n("Misc..."), this);
     buttonMenu->setMenu(m_configMenu);
     buttonMenu->setPopupMode(QToolButton::MenuButtonPopup);
-    
+
     m_editOptions = m_configMenu->addAction(KIcon("system-run"), i18n("Show/Hide options"));
     m_editOptions->setCheckable(true);
     buttonMenu->setDefaultAction(m_editOptions);
@@ -87,7 +91,7 @@ Geometryval::Geometryval(const MltVideoProfile profile, QPoint frame_size, int s
     slotSwitchOptions();
 
     m_reset = m_configMenu->addAction(KIcon("view-refresh"), i18n("Reset"), this, SLOT(slotResetPosition()));
-    
+
     m_syncAction = m_configMenu->addAction(i18n("Sync timeline cursor"), this, SLOT(slotSyncCursor()));
     m_syncAction->setCheckable(true);
     m_syncAction->setChecked(KdenliveSettings::transitionfollowcursor());
@@ -105,8 +109,7 @@ Geometryval::Geometryval(const MltVideoProfile profile, QPoint frame_size, int s
     connect(buttonDelete , SIGNAL(clicked()) , this , SLOT(slotDeleteFrame()));
     connect(buttonAdd , SIGNAL(clicked()) , this , SLOT(slotAddFrame()));
     connect(m_scene, SIGNAL(actionFinished()), this, SLOT(slotUpdateTransitionProperties()));
-    connect(m_scene, SIGNAL(doubleClickEvent()), this, SLOT(slotGeometry()));
-    
+
     buttonhcenter->setIcon(KIcon("kdenlive-align-hor"));
     buttonhcenter->setToolTip(i18n("Align item horizontally"));
     buttonvcenter->setIcon(KIcon("kdenlive-align-vert"));
@@ -119,7 +122,7 @@ Geometryval::Geometryval(const MltVideoProfile profile, QPoint frame_size, int s
     buttonright->setToolTip(i18n("Align item to right"));
     buttonleft->setIcon(KIcon("kdenlive-align-left"));
     buttonleft->setToolTip(i18n("Align item to left"));
-    
+
     connect(buttonhcenter, SIGNAL(clicked()), this, SLOT(slotAlignHCenter()));
     connect(buttonvcenter, SIGNAL(clicked()), this, SLOT(slotAlignVCenter()));
     connect(buttontop, SIGNAL(clicked()), this, SLOT(slotAlignTop()));
@@ -129,10 +132,10 @@ Geometryval::Geometryval(const MltVideoProfile profile, QPoint frame_size, int s
     connect(spinX, SIGNAL(valueChanged(int)), this, SLOT(slotGeometryX(int)));
     connect(spinY, SIGNAL(valueChanged(int)), this, SLOT(slotGeometryY(int)));
     connect(spinWidth, SIGNAL(valueChanged(int)), this, SLOT(slotGeometryWidth(int)));
-    connect(spinHeight, SIGNAL(valueChanged(int)), this, SLOT(slotGeometryHeight(int)));    
-    connect(spinResize, SIGNAL(valueChanged(int)), this, SLOT(slotResizeCustom(int)));
+    connect(spinHeight, SIGNAL(valueChanged(int)), this, SLOT(slotGeometryHeight(int)));
+    connect(spinResize, SIGNAL(editingFinished()), this, SLOT(slotResizeCustom()));
     connect(buttonResize, SIGNAL(clicked()), this, SLOT(slotResizeOriginal()));
-    
+
     connect(this, SIGNAL(parameterChanged()), this, SLOT(slotUpdateGeometry()));
 }
 
@@ -210,17 +213,18 @@ void Geometryval::slotResizeOriginal()
     slotUpdateTransitionProperties();
 }
 
-void Geometryval::slotResizeCustom(int value)
+void Geometryval::slotResizeCustom()
 {
     if (!keyframeSelected())
         return;
+    int value = spinResize->value();
     m_paramRect->setRect(0, 0, m_realWidth * value / 100, m_profile.height * value / 100);
     slotUpdateTransitionProperties();
 }
 
 void Geometryval::slotTransparencyChanged(int transp)
 {
-    int pos = spinPos->value();
+    int pos = m_timePos.getValue();
     Mlt::GeometryItem item;
     int error = m_geom->fetch(&item, pos);
     if (error || item.key() == false) {
@@ -238,11 +242,22 @@ void Geometryval::slotSyncCursor()
     KdenliveSettings::setTransitionfollowcursor(m_syncAction->isChecked());
 }
 
+void Geometryval::updateTimecodeFormat()
+{
+    m_timePos.slotUpdateTimeCodeFormat();
+}
+
 void Geometryval::slotPositionChanged(int pos, bool seek)
 {
+    if (pos == -1) {
+        pos = m_timePos.getValue();
+    }
     if (seek && KdenliveSettings::transitionfollowcursor()) emit seekToPos(pos + m_startPoint);
-    spinPos->setValue(pos);
+    m_timePos.setValue(pos);
+    //spinPos->setValue(pos);
+    m_helper->blockSignals(true);
     m_helper->setValue(pos);
+    m_helper->blockSignals(false);
     Mlt::GeometryItem item;
     int error = m_geom->fetch(&item, pos);
     if (error || item.key() == false) {
@@ -252,38 +267,43 @@ void Geometryval::slotPositionChanged(int pos, bool seek)
         widget->setEnabled(false);
         spinTransp->setEnabled(false);
         frameOptions->setEnabled(false);
+        m_reset->setEnabled(false);
     } else {
         buttonAdd->setEnabled(false);
         buttonDelete->setEnabled(true);
         widget->setEnabled(true);
         spinTransp->setEnabled(true);
         frameOptions->setEnabled(true);
-        slotUpdateGeometry();
+        m_reset->setEnabled(true);
     }
 
     m_paramRect->setPos(item.x() * m_dar, item.y());
     m_paramRect->setRect(0, 0, item.w() * m_dar, item.h());
     spinTransp->setValue(item.mix());
     m_paramRect->setBrush(QColor(255, 0, 0, item.mix()));
+    slotUpdateGeometry();
 }
 
 void Geometryval::slotDeleteFrame(int pos)
 {
     // check there is more than one keyframe
     Mlt::GeometryItem item;
-    if (pos == -1) pos = spinPos->value();
+    int frame = m_timePos.getValue();
+
+    if (pos == -1) pos = frame;
     int error = m_geom->next_key(&item, pos + 1);
     if (error) {
         error = m_geom->prev_key(&item, pos - 1);
         if (error || item.frame() == pos) return;
     }
 
-    m_geom->remove(spinPos->value());
+    m_geom->remove(frame);
     buttonAdd->setEnabled(true);
     buttonDelete->setEnabled(false);
     widget->setEnabled(false);
     spinTransp->setEnabled(false);
     frameOptions->setEnabled(false);
+    m_reset->setEnabled(false);
     m_helper->update();
     slotPositionChanged(pos, false);
     updateTransitionPath();
@@ -292,7 +312,8 @@ void Geometryval::slotDeleteFrame(int pos)
 
 void Geometryval::slotAddFrame(int pos)
 {
-    if (pos == -1) pos = spinPos->value();
+    int frame = m_timePos.getValue();
+    if (pos == -1) pos = frame;
     Mlt::GeometryItem item;
     item.frame(pos);
     QRectF r = m_paramRect->rect().normalized();
@@ -308,6 +329,7 @@ void Geometryval::slotAddFrame(int pos)
     widget->setEnabled(true);
     spinTransp->setEnabled(true);
     frameOptions->setEnabled(true);
+    m_reset->setEnabled(true);
     m_helper->update();
     emit parameterChanged();
 }
@@ -316,14 +338,14 @@ void Geometryval::slotNextFrame()
 {
     Mlt::GeometryItem item;
     int error = m_geom->next_key(&item, m_helper->value() + 1);
+    int pos;
     kDebug() << "// SEEK TO NEXT KFR: " << error;
     if (error) {
         // Go to end
-        spinPos->setValue(spinPos->maximum());
-        return;
-    }
-    int pos = item.frame();
-    spinPos->setValue(pos);
+        pos = m_helper->frameLength;
+    } else pos = item.frame();
+    m_timePos.setValue(pos);
+    slotPositionChanged();
 }
 
 void Geometryval::slotPreviousFrame()
@@ -333,7 +355,8 @@ void Geometryval::slotPreviousFrame()
     kDebug() << "// SEEK TO NEXT KFR: " << error;
     if (error) return;
     int pos = item.frame();
-    spinPos->setValue(pos);
+    m_timePos.setValue(pos);
+    slotPositionChanged();
 }
 
 
@@ -354,8 +377,11 @@ void Geometryval::setupParam(const QDomElement par, int minFrame, int maxFrame)
         spinTransp->setMaximum(500);
         label_pos->setHidden(true);
         m_helper->setHidden(true);
-        spinPos->setHidden(true);
-
+        m_timePos.setHidden(true);
+    }
+    if (par.attribute("opacity") == "false") {
+        label_opacity->setHidden(true);
+        spinTransp->setHidden(true);
     }
     char *tmp = (char *) qstrdup(val.toUtf8().data());
     if (m_geom) m_geom->parse(tmp, maxFrame - minFrame, m_profile.width, m_profile.height);
@@ -370,7 +396,6 @@ void Geometryval::setupParam(const QDomElement par, int minFrame, int maxFrame)
         /*QDomDocument doc;
         doc.appendChild(doc.importNode(par, true));
         kDebug() << "IMPORTED TRANS: " << doc.toString();*/
-        spinPos->setMaximum(maxFrame - minFrame - 1);
         if (m_path == NULL) {
             m_path = new QGraphicsPathItem();
             m_path->setPen(QPen(Qt::red));
@@ -392,11 +417,22 @@ void Geometryval::setupParam(const QDomElement par, int minFrame, int maxFrame)
     slotPositionChanged(0, false);
     slotUpdateGeometry();
     if (!m_fixedMode) {
-        connect(spinPos, SIGNAL(valueChanged(int)), this , SLOT(slotPositionChanged(int)));
+        m_timePos.setRange(0, maxFrame - minFrame - 1);
+        connect(&m_timePos, SIGNAL(editingFinished()), this , SLOT(slotPositionChanged()));
     }
     connect(spinTransp, SIGNAL(valueChanged(int)), this , SLOT(slotTransparencyChanged(int)));
 }
 
+void Geometryval::slotSyncPosition(int relTimelinePos)
+{
+    if (m_timePos.maximum() > 0 && KdenliveSettings::transitionfollowcursor()) {
+        relTimelinePos = qMax(0, relTimelinePos);
+        relTimelinePos = qMin(relTimelinePos, m_timePos.maximum());
+        if (relTimelinePos != m_timePos.getValue())
+            slotPositionChanged(relTimelinePos, false);
+    }
+}
+
 void Geometryval::updateTransitionPath()
 {
     if (m_fixedMode) return;
@@ -420,7 +456,7 @@ void Geometryval::updateTransitionPath()
 
 void Geometryval::slotUpdateTransitionProperties()
 {
-    int pos = spinPos->value();
+    int pos = m_timePos.getValue();
     Mlt::GeometryItem item;
     int error = m_geom->next_key(&item, pos);
     if (error || item.frame() != pos) {
@@ -473,7 +509,7 @@ void Geometryval::slotSwitchOptions()
         frameOptions->setHidden(true);
         m_editOptions->setChecked(false);
     }
-    adjustSize();
+    //adjustSize();
 }
 
 void Geometryval::slotGeometryX(int value)
@@ -510,22 +546,20 @@ void Geometryval::slotGeometryHeight(int value)
 
 void Geometryval::slotUpdateGeometry()
 {
-    if (!keyframeSelected())
-        return;
     QRectF r = m_paramRect->rect().normalized();
-    
+
     spinX->blockSignals(true);
     spinY->blockSignals(true);
     spinWidth->blockSignals(true);
     spinHeight->blockSignals(true);
     spinResize->blockSignals(true);
-    
+
     spinX->setValue(m_paramRect->pos().x());
     spinY->setValue(m_paramRect->pos().y());
     spinWidth->setValue(r.width());
     spinHeight->setValue(r.height());
     spinResize->setValue(m_paramRect->rect().width() * 100 / m_realWidth);
-    
+
     spinX->blockSignals(false);
     spinY->blockSignals(false);
     spinWidth->blockSignals(false);
@@ -536,7 +570,8 @@ void Geometryval::slotUpdateGeometry()
 bool Geometryval::keyframeSelected()
 {
     Mlt::GeometryItem item;
-    if (m_geom->fetch(&item, spinPos->value()) || item.key() == false) return false;
+    int pos = m_timePos.getValue();
+    if (m_geom->fetch(&item, pos) || item.key() == false) return false;
     return true;
 }