]> git.sesse.net Git - kdenlive/blobdiff - src/geometrywidget.cpp
Minor improvements to keyframe widget, allow resetting keyframes
[kdenlive] / src / geometrywidget.cpp
index fcbb90a660ccf8f50e9b913182c17428601adfe5..27c0f8eb466124e3067db387f8061d34f81abfa9 100644 (file)
@@ -65,7 +65,7 @@ GeometryWidget::GeometryWidget(Monitor* monitor, Timecode timecode, int clipPos,
         Setup of timeline and keyframe controls
     */
 
-    ((QGridLayout *)(m_ui.widgetTimeWrapper->layout()))->addWidget(m_timePos, 1, 6);
+    ((QGridLayout *)(m_ui.widgetTimeWrapper->layout()))->addWidget(m_timePos, 1, 5);
 
     QVBoxLayout *layout = new QVBoxLayout(m_ui.frameTimeline);
     m_timeline = new KeyframeHelper(m_ui.frameTimeline);
@@ -81,15 +81,10 @@ GeometryWidget::GeometryWidget(Monitor* monitor, Timecode timecode, int clipPos,
     m_ui.buttonNext->setIcon(KIcon("media-skip-forward"));
     m_ui.buttonNext->setToolTip(i18n("Go to next keyframe"));
     m_ui.buttonNext->setIconSize(iconSize);
-    m_ui.buttonAddDelete->setIcon(KIcon("document-new"));
+    m_ui.buttonAddDelete->setIcon(KIcon("list-add"));
     m_ui.buttonAddDelete->setToolTip(i18n("Add keyframe"));
     m_ui.buttonAddDelete->setIconSize(iconSize);
 
-    m_ui.buttonSync->setIcon(KIcon("insert-link"));
-    m_ui.buttonSync->setToolTip(i18n("Synchronize with timeline cursor"));
-    m_ui.buttonSync->setChecked(KdenliveSettings::transitionfollowcursor());
-    m_ui.buttonSync->setIconSize(iconSize);
-
     connect(m_timeline, SIGNAL(requestSeek(int)), this, SLOT(slotRequestSeek(int)));
     connect(m_timeline, SIGNAL(keyframeMoved(int)),   this, SLOT(slotKeyframeMoved(int)));
     connect(m_timeline, SIGNAL(addKeyframe(int)),     this, SLOT(slotAddKeyframe(int)));
@@ -98,7 +93,6 @@ GeometryWidget::GeometryWidget(Monitor* monitor, Timecode timecode, int clipPos,
     connect(m_ui.buttonPrevious,  SIGNAL(clicked()), this, SLOT(slotPreviousKeyframe()));
     connect(m_ui.buttonNext,      SIGNAL(clicked()), this, SLOT(slotNextKeyframe()));
     connect(m_ui.buttonAddDelete, SIGNAL(clicked()), this, SLOT(slotAddDeleteKeyframe()));
-    connect(m_ui.buttonSync,      SIGNAL(toggled(bool)), this, SLOT(slotSetSynchronize(bool)));
 
     m_spinX = new DragValue(i18nc("x axis position", "X"), 0, 0, -99000, 99000, -1, QString(), false, this);
     m_ui.horizontalLayout->addWidget(m_spinX, 0, 0);
@@ -115,39 +109,44 @@ GeometryWidget::GeometryWidget(Monitor* monitor, Timecode timecode, int clipPos,
     m_ui.horizontalLayout->setColumnStretch(4, 10);
 
     QMenu *menu = new QMenu(this);
-    QAction *adjustSize = new QAction(i18n("Adjust to original size"), this);
+    QAction *adjustSize = new QAction(KIcon("zoom-fit-best"), i18n("Adjust to original size"), this);
     connect(adjustSize, SIGNAL(triggered()), this, SLOT(slotAdjustToFrameSize()));
-    menu->addAction(adjustSize);
-    QAction *fitToWidth = new QAction(i18n("Fit to width"), this);
+    QAction *fitToWidth = new QAction(KIcon("zoom-fit-width"), i18n("Fit to width"), this);
     connect(fitToWidth, SIGNAL(triggered()), this, SLOT(slotFitToWidth()));
-    menu->addAction(fitToWidth);
-    QAction *fitToHeight = new QAction(i18n("Fit to height"), this);
+    QAction *fitToHeight = new QAction(KIcon("zoom-fit-height"), i18n("Fit to height"), this);
     connect(fitToHeight, SIGNAL(triggered()), this, SLOT(slotFitToHeight()));
-    menu->addAction(fitToHeight);
-    menu->addSeparator();
+
     QAction *importKeyframes = new QAction(i18n("Import keyframes from clip"), this);
     connect(importKeyframes, SIGNAL(triggered()), this, SIGNAL(importClipKeyframes()));
     menu->addAction(importKeyframes);
+    QAction *resetKeyframes = new QAction(i18n("Reset keyframes"), this);
+    connect(resetKeyframes, SIGNAL(triggered()), this, SLOT(slotResetKeyframes()));
+    menu->addAction(resetKeyframes);
     menu->addSeparator();
+
+    QAction *syncTimeline = new QAction(KIcon("insert-link"), i18n("Synchronize with timeline cursor"), this);
+    syncTimeline->setCheckable(true);
+    syncTimeline->setChecked(KdenliveSettings::transitionfollowcursor());
+    connect(syncTimeline, SIGNAL(toggled(bool)), this, SLOT(slotSetSynchronize(bool)));
+    menu->addAction(syncTimeline);
+
     QAction *alignleft = new QAction(KIcon("kdenlive-align-left"), i18n("Align left"), this);
     connect(alignleft, SIGNAL(triggered()), this, SLOT(slotMoveLeft()));
-    menu->addAction(alignleft);
     QAction *alignhcenter = new QAction(KIcon("kdenlive-align-hor"), i18n("Center horizontally"), this);
     connect(alignhcenter, SIGNAL(triggered()), this, SLOT(slotCenterH()));
-    menu->addAction(alignhcenter);
     QAction *alignright = new QAction(KIcon("kdenlive-align-right"), i18n("Align right"), this);
     connect(alignright, SIGNAL(triggered()), this, SLOT(slotMoveRight()));
-    menu->addAction(alignright);
     QAction *aligntop = new QAction(KIcon("kdenlive-align-top"), i18n("Align top"), this);
     connect(aligntop, SIGNAL(triggered()), this, SLOT(slotMoveTop()));
-    menu->addAction(aligntop);
     QAction *alignvcenter = new QAction(KIcon("kdenlive-align-vert"), i18n("Center vertically"), this);
     connect(alignvcenter, SIGNAL(triggered()), this, SLOT(slotCenterV()));
-    menu->addAction(alignvcenter);
     QAction *alignbottom = new QAction(KIcon("kdenlive-align-bottom"), i18n("Align bottom"), this);
     connect(alignbottom, SIGNAL(triggered()), this, SLOT(slotMoveBottom()));
-    menu->addAction(alignbottom);
+    
     m_ui.buttonOptions->setMenu(menu);
+    m_ui.buttonOptions->setIcon(KIcon("configure"));
+    m_ui.buttonOptions->setToolTip(i18n("Options"));
+    m_ui.buttonOptions->setIconSize(iconSize);
 
     QHBoxLayout *alignLayout = new QHBoxLayout;
     alignLayout->setSpacing(0);
@@ -180,6 +179,21 @@ GeometryWidget::GeometryWidget(Monitor* monitor, Timecode timecode, int clipPos,
     alignButton->setDefaultAction(alignbottom);
     alignButton->setAutoRaise(true);
     alignLayout->addWidget(alignButton);
+
+    alignButton = new QToolButton;
+    alignButton->setDefaultAction(adjustSize);
+    alignButton->setAutoRaise(true);
+    alignLayout->addWidget(alignButton);
+
+    alignButton = new QToolButton;
+    alignButton->setDefaultAction(fitToWidth);
+    alignButton->setAutoRaise(true);
+    alignLayout->addWidget(alignButton);
+    
+    alignButton = new QToolButton;
+    alignButton->setDefaultAction(fitToHeight);
+    alignButton->setAutoRaise(true);
+    alignLayout->addWidget(alignButton);
     alignLayout->addStretch(10);
 
     m_ui.horizontalLayout->addLayout(alignLayout, 1, 0, 1, 4);
@@ -238,7 +252,7 @@ GeometryWidget::GeometryWidget(Monitor* monitor, Timecode timecode, int clipPos,
 
 GeometryWidget::~GeometryWidget()
 {
-    m_scene->setEnabled(true);
+    m_scene->setEnabled(false);
     delete m_timePos;
     delete m_timeline;
     delete m_spinX;
@@ -246,10 +260,14 @@ GeometryWidget::~GeometryWidget()
     delete m_spinWidth;
     delete m_spinHeight;
     delete m_opacity;
-    m_scene->removeItem(m_rect);
-    m_scene->removeItem(m_geomPath);
-    if (m_rect) delete m_rect;
-    if (m_geomPath) delete m_geomPath;
+    if (m_rect) {
+       m_scene->removeItem(m_rect);
+       delete m_rect;
+    }
+    if (m_geomPath) {
+       m_scene->removeItem(m_geomPath);
+       delete m_geomPath;
+    }
     if (m_previous) delete m_previous;
     delete m_geometry;
     m_extraGeometryNames.clear();
@@ -308,7 +326,6 @@ void GeometryWidget::setupParam(const QDomElement elem, int minframe, int maxfra
     } else {
         m_ui.widgetTimeWrapper->setHidden(false);
         m_timeline->setKeyGeometry(m_geometry, m_outPoint - m_inPoint);
-        m_timeline->update();
         m_timePos->setRange(0, m_outPoint - m_inPoint);
     }
 
@@ -387,14 +404,14 @@ void GeometryWidget::slotPositionChanged(int pos, bool seek)
         m_rect->setEnabled(false);
         m_scene->setEnabled(false);
         m_ui.widgetGeometry->setEnabled(false);
-        m_ui.buttonAddDelete->setIcon(KIcon("document-new"));
+        m_ui.buttonAddDelete->setIcon(KIcon("list-add"));
         m_ui.buttonAddDelete->setToolTip(i18n("Add keyframe"));
     } else {
         // keyframe
         m_rect->setEnabled(true);
         m_scene->setEnabled(true);
         m_ui.widgetGeometry->setEnabled(true);
-        m_ui.buttonAddDelete->setIcon(KIcon("edit-delete"));
+        m_ui.buttonAddDelete->setIcon(KIcon("list-remove"));
         m_ui.buttonAddDelete->setToolTip(i18n("Delete keyframe"));
     }
     
@@ -506,6 +523,7 @@ void GeometryWidget::slotDeleteKeyframe(int pos)
     }
 
     m_timeline->update();
+    if (m_geomPath) m_geomPath->setPoints(m_geometry);
     slotPositionChanged(pos, false);
     emit parameterChanged();
 }
@@ -769,20 +787,59 @@ void GeometryWidget::slotFitToHeight()
     updateMonitorGeometry();
 }
 
-void GeometryWidget::importKeyframes(const QString &data)
+void GeometryWidget::slotResetKeyframes()
+{
+    // Delete existing keyframes
+    Mlt::GeometryItem item;
+    while (!m_geometry->next_key(&item, 1)) {
+       m_geometry->remove(item.frame());
+    }
+
+    // Create neutral first keyframe
+    item.frame(0);
+    item.x(0);
+    item.y(0);
+    item.w(m_monitor->render->frameRenderWidth());
+    item.h(m_monitor->render->renderHeight());
+    item.mix(100);
+    m_geometry->insert(item);
+    m_timeline->setKeyGeometry(m_geometry, m_outPoint - m_inPoint);
+    if (m_geomPath) {
+       m_scene->removeItem(m_geomPath);
+       m_geomPath->setPoints(m_geometry);
+       m_scene->addItem(m_geomPath);
+    }
+    slotPositionChanged(-1, false);
+    emit parameterChanged();
+    
+}
+
+void GeometryWidget::importKeyframes(const QString &data, int maximum)
 {
     QStringList list = data.split(';', QString::SkipEmptyParts);
+    if (list.isEmpty()) return;
     QPoint screenSize = m_frameSize;
     if (screenSize == QPoint() || screenSize.x() == 0 || screenSize.y() == 0) {
         screenSize = QPoint(m_monitor->render->frameRenderWidth(), m_monitor->render->renderHeight());
     }
-    for (int i = 0; i < list.count(); i++) {
-       Mlt::GeometryItem item;
+    // Clear existing keyframes
+    Mlt::GeometryItem item;
+    
+    while (!m_geometry->next_key(&item, 0)) {
+       m_geometry->remove(item.frame());
+    }
+    
+    int offset = 1;
+    if (maximum > 0 && list.count() > maximum) {
+       offset = list.count() / maximum;
+    }
+    for (int i = 0; i < list.count(); i += offset) {
        QString geom = list.at(i);
        if (geom.contains('=')) {
            item.frame(geom.section('=', 0, 0).toInt());
+           geom = geom.section('=', 1);
        }
-       geom = geom.section('=', 1);
+       else item.frame(0);
        if (geom.contains('/')) {
            item.x(geom.section('/', 0, 0).toDouble());
            item.y(geom.section('/', 1, 1).section(':', 0, 0).toDouble());
@@ -803,7 +860,11 @@ void GeometryWidget::importKeyframes(const QString &data)
        item.mix(100);
        m_geometry->insert(item);
     }
+    m_timeline->setKeyGeometry(m_geometry, m_outPoint - m_inPoint);
+    if (m_geomPath) m_geomPath->setPoints(m_geometry);
+    slotPositionChanged(-1, false);
     emit parameterChanged();
 }
 
+
 #include "geometrywidget.moc"