]> git.sesse.net Git - kdenlive/commitdiff
Improve stopmotion widget (show thumbs of previous frames)
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Sat, 9 Oct 2010 01:06:07 +0000 (01:06 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Sat, 9 Oct 2010 01:06:07 +0000 (01:06 +0000)
svn path=/trunk/kdenlive/; revision=4971

src/blackmagic/capture.cpp
src/stopmotion/stopmotion.cpp
src/stopmotion/stopmotion.h
src/widgets/stopmotion_ui.ui

index 825231f0f756c71ba90f79b4bf426493bb65c978..e93c51ea4b67db795f7ee7783684d70f96cc4ed6 100644 (file)
@@ -846,12 +846,12 @@ void CaptureHandler::captureFrame(const QString &fname)
 
 void CaptureHandler::showOverlay(QImage img, bool transparent)
 {
-    previewView->showOverlay(img, transparent);
+    if (previewView) previewView->showOverlay(img, transparent);
 }
 
 void CaptureHandler::hideOverlay()
 {
-    previewView->hideOverlay();
+    if (previewView) previewView->hideOverlay();
 }
 
 void CaptureHandler::stopPreview()
index aaa35eed8fa5b7da3d4b4b89d83d19a0ac795a2f..be4f92ebd2a88ddef85576ec348a4fbcfe3c6e49 100644 (file)
@@ -32,6 +32,7 @@
 #include <QComboBox>
 #include <QVBoxLayout>
 #include <QTimer>
+#include <QPainter>
 #include <QAction>
 
 StopmotionWidget::StopmotionWidget(KUrl projectFolder, QWidget *parent) :
@@ -39,6 +40,7 @@ StopmotionWidget::StopmotionWidget(KUrl projectFolder, QWidget *parent) :
         , QDialog(parent)
         , Ui::Stopmotion_UI()
        , m_sequenceFrame(0)
+       , m_animatedIndex(-1)
 {
     setupUi(this);
     setWindowTitle(i18n("Stop Motion Capture"));
@@ -53,7 +55,6 @@ StopmotionWidget::StopmotionWidget(KUrl projectFolder, QWidget *parent) :
     
     preview_button->setIcon(KIcon("media-playback-start"));
     removelast_button->setIcon(KIcon("edit-delete"));
-
     capture_button->setEnabled(false);
     frameoverlay_button->setEnabled(false);
     removelast_button->setEnabled(false);
@@ -74,6 +75,8 @@ StopmotionWidget::StopmotionWidget(KUrl projectFolder, QWidget *parent) :
     connect(frameoverlay_button, SIGNAL(clicked(bool)), this, SLOT(slotShowOverlay(bool)));
     connect(frame_number, SIGNAL(valueChanged(int)), this, SLOT(slotShowFrame(int)));
     connect(button_addsequence, SIGNAL(clicked(bool)), this, SLOT(slotAddSequence()));
+    connect(preview_button, SIGNAL(clicked(bool)), this, SLOT(slotPlayPreview()));
+    connect(frame_list, SIGNAL(activated(const QModelIndex &)), this, SLOT(slotShowSelectedFrame()));
 }
 
 StopmotionWidget::~StopmotionWidget()
@@ -119,6 +122,7 @@ void StopmotionWidget::slotUpdateOverlay()
 
 void StopmotionWidget::sequenceNameChanged(const QString &name)
 {
+    frame_list->clear();
     if (name.isEmpty()) {
        button_addsequence->setEnabled(false);
        capture_button->setEnabled(false);
@@ -135,6 +139,10 @@ void StopmotionWidget::sequenceNameChanged(const QString &name)
        m_sequenceFrame = count;
        if (count > 0) {
            m_sequenceName = sequence_name->text();
+           //TODO: Do the thumbnail stuff in a thread
+           for (int i = 0; i < count; i++) {
+               slotUpdateFrameList(i);
+           }
            button_addsequence->setEnabled(true);
            frameoverlay_button->setEnabled(true);
        }
@@ -156,7 +164,7 @@ void StopmotionWidget::slotCaptureFrame()
        m_sequenceName = sequence_name->text();
        m_sequenceFrame = 0;
     }
-    
+    capture_button->setEnabled(false);
     m_bmCapture->captureFrame(getPathForFrame(m_sequenceFrame));
     KNotification::event("FrameCaptured");
     frameoverlay_button->setEnabled(true);
@@ -166,7 +174,41 @@ void StopmotionWidget::slotCaptureFrame()
     frame_number->setValue(m_sequenceFrame);
     frame_number->blockSignals(false);
     button_addsequence->setEnabled(true);
-    if (frameoverlay_button->isChecked()) QTimer::singleShot(1000, this, SLOT(slotUpdateOverlay()));
+    //if (frameoverlay_button->isChecked()) QTimer::singleShot(1000, this, SLOT(slotUpdateOverlay()));
+    QTimer::singleShot(1000, this, SLOT(slotUpdateFrameList()));
+}
+
+void StopmotionWidget::slotUpdateFrameList(int ix)
+{
+    kDebug()<< "// GET FRAME: "<<ix;
+    if (ix == -1) ix = m_sequenceFrame - 1;
+    QString path = getPathForFrame(ix);
+    if (!QFile::exists(path)) {
+       capture_button->setEnabled(true);
+       return;
+    }
+    QImage img(path);
+    if (img.isNull()) {
+       if (ix == m_sequenceFrame - 1) QTimer::singleShot(1000, this, SLOT(slotUpdateFrameList()));
+       return;
+    }
+    int height = 90;
+    int width = height * img.width() / img.height();
+    frame_list->setIconSize(QSize(width, height));
+    QPixmap pix = QPixmap::fromImage(img).scaled(width, height);
+    QString nb = QString::number(ix);
+    QPainter p(&pix);
+    QFontInfo finfo(font());
+    p.fillRect(0, 0, finfo.pixelSize() * nb.count() + 6, finfo.pixelSize() + 6, QColor(0, 0, 0, 150));
+    p.setPen(Qt::white);
+    p.drawText(QPoint(3, finfo.pixelSize() + 3), nb);
+    p.end();
+    QIcon icon(pix);
+    QListWidgetItem *item = new QListWidgetItem(icon, QString(), frame_list);
+    item->setData(Qt::UserRole, path);
+    item->setData(Qt::UserRole + 1, ix);
+    item->setToolTip(path);
+    capture_button->setEnabled(true);
 }
 
 QString StopmotionWidget::getPathForFrame(int ix, QString seqName)
@@ -193,11 +235,44 @@ void StopmotionWidget::slotShowFrame(int ix)
     else {
        m_bmCapture->hideOverlay();
        capture_button->setEnabled(true);
+    }    
+}
+
+void StopmotionWidget::slotShowSelectedFrame()
+{
+    QListWidgetItem *item = frame_list->currentItem();
+    if (item) {
+       int ix = item->data(Qt::UserRole + 1).toInt();
+       //frame_number->blockSignals(true);
+       frame_number->setValue(ix);
+       //frame_number->blockSignals(false);
+       //slotShowFrame(ix);
     }
-    
 }
 
 void StopmotionWidget::slotAddSequence()
 {
     emit addOrUpdateSequence(getPathForFrame(0));
 }
+
+void StopmotionWidget::slotPlayPreview()
+{
+    if (m_animatedIndex != -1) {
+       // stop animation
+       m_animatedIndex = -1;
+       return;
+    }
+    QListWidgetItem *item = frame_list->currentItem();
+    if (item) {
+       m_animatedIndex = item->data(Qt::UserRole + 1).toInt();
+    }
+    QTimer::singleShot(200, this, SLOT(slotAnimate()));
+}
+
+void StopmotionWidget::slotAnimate()
+{
+    slotShowFrame(m_animatedIndex);
+    m_animatedIndex++;
+    if (m_animatedIndex < m_sequenceFrame) QTimer::singleShot(200, this, SLOT(slotAnimate()));
+    else m_animatedIndex = -1;
+}
\ No newline at end of file
index d86e2c0090cd4c35f33fc24fcff42a5810f63810..7742447b840f733e8549862802a96739bf00de09 100644 (file)
@@ -55,6 +55,9 @@ private:
 
   QAction *m_captureAction;
   
+  /** @brief Holds the index of the frame to be displayed in the frame preview mode. */
+  int m_animatedIndex;
+  
 private slots:
   /** @brief Display the live feed from capture device.
    @param isOn enable or disable the feature */
@@ -84,6 +87,18 @@ private slots:
   /** @brief Add sequence to current project. */
   void slotAddSequence();
 
+  /** @brief Update the frame list widget with newly created frame. */
+  void slotUpdateFrameList(int ix = -1);
+  
+  /** @brief Display selected fram in monitor. */
+  void slotShowSelectedFrame();
+
+  /** @brief Start animation preview mode. */
+  void slotPlayPreview();
+  
+  /** @brief Simulate animation. */
+  void slotAnimate();
+
 signals:
   /** @brief Ask to add sequence to current project. */
   void addOrUpdateSequence(const QString);
index c3cab8fb139388aa62bb3cc68af1d793164cc0d0..40d87b3b14d3930a6050dcd4bde93f5e7fcc3d72 100644 (file)
@@ -6,31 +6,65 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>778</width>
-    <height>411</height>
+    <width>662</width>
+    <height>418</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Dialog</string>
   </property>
   <layout class="QGridLayout" name="gridLayout">
-   <item row="0" column="0" colspan="12">
-    <widget class="QFrame" name="video_preview">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="frameShape">
-      <enum>QFrame::NoFrame</enum>
-     </property>
-     <property name="frameShadow">
-      <enum>QFrame::Plain</enum>
-     </property>
-     <property name="lineWidth">
-      <number>0</number>
-     </property>
+   <item row="0" column="0" colspan="10">
+    <widget class="QSplitter" name="splitter">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <widget class="QFrame" name="video_preview">
+      <property name="sizePolicy">
+       <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+        <horstretch>0</horstretch>
+        <verstretch>0</verstretch>
+       </sizepolicy>
+      </property>
+      <property name="frameShape">
+       <enum>QFrame::NoFrame</enum>
+      </property>
+      <property name="frameShadow">
+       <enum>QFrame::Plain</enum>
+      </property>
+      <property name="lineWidth">
+       <number>0</number>
+      </property>
+     </widget>
+     <widget class="QListWidget" name="frame_list">
+      <property name="maximumSize">
+       <size>
+        <width>16777215</width>
+        <height>120</height>
+       </size>
+      </property>
+      <property name="frameShape">
+       <enum>QFrame::StyledPanel</enum>
+      </property>
+      <property name="verticalScrollBarPolicy">
+       <enum>Qt::ScrollBarAlwaysOff</enum>
+      </property>
+      <property name="horizontalScrollBarPolicy">
+       <enum>Qt::ScrollBarAlwaysOn</enum>
+      </property>
+      <property name="movement">
+       <enum>QListView::Static</enum>
+      </property>
+      <property name="isWrapping" stdset="0">
+       <bool>false</bool>
+      </property>
+      <property name="viewMode">
+       <enum>QListView::IconMode</enum>
+      </property>
+      <property name="uniformItemSizes">
+       <bool>true</bool>
+      </property>
+     </widget>
     </widget>
    </item>
    <item row="1" column="0">
@@ -49,7 +83,7 @@
      </property>
     </widget>
    </item>
-   <item row="1" column="2">
+   <item row="1" column="1">
     <widget class="QToolButton" name="frameoverlay_button">
      <property name="toolTip">
       <string>Overlay last frame</string>
@@ -65,7 +99,7 @@
      </property>
     </widget>
    </item>
-   <item row="1" column="3">
+   <item row="1" column="2">
     <widget class="QToolButton" name="preview_button">
      <property name="toolTip">
       <string>Preview sequence</string>
      </property>
     </widget>
    </item>
-   <item row="1" column="4">
+   <item row="1" column="3">
     <widget class="KLineEdit" name="sequence_name">
      <property name="sizePolicy">
       <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
      </property>
     </widget>
    </item>
-   <item row="1" column="5">
+   <item row="1" column="4">
     <widget class="QSpinBox" name="frame_number">
      <property name="toolTip">
       <string>Frame number</string>
      </property>
     </widget>
    </item>
-   <item row="1" column="11">
-    <widget class="QDialogButtonBox" name="buttonBox">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="standardButtons">
-      <set>QDialogButtonBox::Close</set>
-     </property>
-    </widget>
-   </item>
-   <item row="1" column="6">
+   <item row="1" column="5">
     <widget class="QToolButton" name="capture_button">
      <property name="toolTip">
       <string>Capture frame</string>
      </property>
     </widget>
    </item>
-   <item row="1" column="7">
+   <item row="1" column="6">
     <widget class="QToolButton" name="removelast_button">
      <property name="toolTip">
       <string>Remove current frame</string>
      </property>
     </widget>
    </item>
-   <item row="1" column="9">
+   <item row="1" column="7">
     <widget class="KComboBox" name="capture_device">
      <property name="toolTip">
       <string>Capture device</string>
     </widget>
    </item>
    <item row="1" column="8">
-    <spacer name="horizontalSpacer">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="sizeHint" stdset="0">
-      <size>
-       <width>40</width>
-       <height>20</height>
-      </size>
-     </property>
-    </spacer>
-   </item>
-   <item row="1" column="10">
     <widget class="QPushButton" name="button_addsequence">
      <property name="text">
       <string>Add sequence to project</string>
      </property>
     </widget>
    </item>
+   <item row="1" column="9">
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Close</set>
+     </property>
+    </widget>
+   </item>
   </layout>
  </widget>
  <customwidgets>