]> git.sesse.net Git - kdenlive/commitdiff
Some progress on the stop motion widget (improve management of existing sequences...
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Sat, 9 Oct 2010 21:45:10 +0000 (21:45 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Sat, 9 Oct 2010 21:45:10 +0000 (21:45 +0000)
svn path=/trunk/kdenlive/; revision=4974

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

index e93c51ea4b67db795f7ee7783684d70f96cc4ed6..6b93efe0469fabb30a273df28c7e13819aa3c4ff 100644 (file)
@@ -554,7 +554,7 @@ HRESULT DeckLinkCaptureDelegate::VideoInputFormatChanged(BMDVideoInputFormatChan
 
 
 
-CaptureHandler::CaptureHandler(QLayout *lay, QWidget *parent):
+CaptureHandler::CaptureHandler(QVBoxLayout *lay, QWidget *parent):
     m_layout(lay)
     , m_parent(parent)
     , previewView(NULL)
@@ -854,8 +854,14 @@ void CaptureHandler::hideOverlay()
     if (previewView) previewView->hideOverlay();
 }
 
+void CaptureHandler::hidePreview(bool hide)
+{
+    if (previewView) previewView->setHidden(hide);
+}
+
 void CaptureHandler::stopPreview()
 {
+    if (!previewView) return;
       if (deckLinkInput != NULL) deckLinkInput->StopStreams();
       if (videoOutputFile)
                close(videoOutputFile);
@@ -880,11 +886,15 @@ void CaptureHandler::stopPreview()
         deckLink = NULL;
     }
 
-       if (deckLinkIterator != NULL)
-               deckLinkIterator->Release();  
+    if (deckLinkIterator != NULL) {
+       deckLinkIterator->Release();
+       deckLinkIterator = NULL;
+    }
 
-    if (previewView != NULL)
+    if (previewView != NULL) {
        delete previewView;
+       previewView = NULL;
+    }
 
     /*if (delegate != NULL)
        delete delegate;*/
index 81da15db19fd94c92088a8e7d337cf2743763058..d97a515caf2aac2a4e59be66abc45d66b3292a11 100644 (file)
@@ -30,7 +30,7 @@ private:
 class CaptureHandler
 {
 public:
-       CaptureHandler(QLayout *lay, QWidget *parent = 0);
+       CaptureHandler(QVBoxLayout *lay, QWidget *parent = 0);
        ~CaptureHandler();
        CDeckLinkGLWidget *previewView;
        void startPreview(int deviceId, int captureMode);
@@ -40,6 +40,7 @@ public:
        void captureFrame(const QString &fname);
        void showOverlay(QImage img, bool transparent = true);
        void hideOverlay();
+       void hidePreview(bool hide);
        
 private:
        IDeckLinkIterator               *deckLinkIterator;
@@ -48,7 +49,7 @@ private:
        IDeckLink                       *deckLink;
        IDeckLinkInput                  *deckLinkInput;
        IDeckLinkDisplayModeIterator    *displayModeIterator;
-       QLayout *m_layout;
+       QVBoxLayout *m_layout;
        QWidget *m_parent;
 };
 
index be4f92ebd2a88ddef85576ec348a4fbcfe3c6e49..698fb564f1368592bc27e8b08965d8ee41b7f3cf 100644 (file)
 #include <kdeversion.h>
 #include <KNotification>
 
+#include <QInputDialog>
 #include <QComboBox>
 #include <QVBoxLayout>
 #include <QTimer>
 #include <QPainter>
 #include <QAction>
+#include <QWheelEvent>
+
+MyLabel::MyLabel(QWidget *parent)
+{
+}
+
+void MyLabel::setImage(QImage img)
+{
+    m_img = img;
+}
+
+//virtual
+void MyLabel::wheelEvent(QWheelEvent * event)
+{
+    if (event->delta() > 0) emit seek(true);
+    else emit seek(false);
+}
+
+//virtual
+void MyLabel::paintEvent( QPaintEvent * event)
+{
+    QRect r(0, 0, width(), height());
+    QPainter p(this);
+    p.fillRect(r, QColor(KdenliveSettings::window_background()));
+    double aspect_ratio = (double) m_img.width() / m_img.height();
+    int pictureHeight = height();
+    int pictureWidth = width();
+    int calculatedWidth = aspect_ratio * height();
+    if (calculatedWidth > width()) pictureHeight = width() / aspect_ratio;
+    else {
+       int calculatedHeight = width() / aspect_ratio;
+       if (calculatedHeight > height()) pictureWidth = height() * aspect_ratio;
+    }
+    p.drawImage(QRect((width() - pictureWidth) / 2, (height() - pictureHeight) / 2, pictureWidth, pictureHeight), m_img, QRect(0, 0, m_img.width(), m_img.height()));
+    p.end();
+}
+
 
 StopmotionWidget::StopmotionWidget(KUrl projectFolder, QWidget *parent) :
-       m_projectFolder(projectFolder)
-        , QDialog(parent)
+        QDialog(parent)
         , Ui::Stopmotion_UI()
+       , m_projectFolder(projectFolder)
        , m_sequenceFrame(0)
        , m_animatedIndex(-1)
 {
@@ -55,18 +93,18 @@ 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);
-
-#if KDE_IS_VERSION(4,4,0)
-    sequence_name->setClickMessage(i18n("Enter sequence name..."));
-#endif
+    capture_button->setEnabled(false);
 
     connect(sequence_name, SIGNAL(textChanged(const QString &)), this, SLOT(sequenceNameChanged(const QString &)));
     BMInterface::getBlackMagicDeviceList(capture_device, NULL);
     QVBoxLayout *lay = new QVBoxLayout;
     m_bmCapture = new CaptureHandler(lay);
+    m_frame_preview = new MyLabel(this);
+    connect(m_frame_preview, SIGNAL(seek(bool)), this, SLOT(slotSeekFrame(bool)));
+    lay->addWidget(m_frame_preview);
+    m_frame_preview->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
     video_preview->setLayout(lay);
     live_button->setChecked(false);
     frameoverlay_button->setChecked(false);
@@ -76,7 +114,10 @@ StopmotionWidget::StopmotionWidget(KUrl projectFolder, QWidget *parent) :
     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()));
+    connect(frame_list, SIGNAL(currentRowChanged(int)), this, SLOT(slotShowSelectedFrame()));
+
+    
+    parseExistingSequences();
 }
 
 StopmotionWidget::~StopmotionWidget()
@@ -84,11 +125,28 @@ StopmotionWidget::~StopmotionWidget()
     m_bmCapture->stopPreview();
 }
 
+void StopmotionWidget::parseExistingSequences()
+{
+    sequence_name->clear();
+    sequence_name->addItem(QString());
+    QDir dir(m_projectFolder.path());
+    QStringList filters;
+    filters << "*_0000.png";
+    //dir.setNameFilters(filters);
+    QStringList sequences = dir.entryList(filters, QDir::Files, QDir::Name);
+    //kDebug()<<"PF: "<<<<", sm: "<<sequences;
+    foreach(QString sequencename, sequences) {
+       sequence_name->addItem(sequencename.section("_", 0, -2));
+    }
+}
+
 void StopmotionWidget::slotLive(bool isOn)
 {
     if (isOn) {
+       m_frame_preview->setImage(QImage());
+       m_frame_preview->setHidden(true);
        m_bmCapture->startPreview(KdenliveSettings::hdmicapturedevice(), KdenliveSettings::hdmicapturemode());
-       capture_button->setEnabled(sequence_name->text().isEmpty() == false);
+       capture_button->setEnabled(true);
     }
     else {
        m_bmCapture->stopPreview();
@@ -125,7 +183,6 @@ void StopmotionWidget::sequenceNameChanged(const QString &name)
     frame_list->clear();
     if (name.isEmpty()) {
        button_addsequence->setEnabled(false);
-       capture_button->setEnabled(false);
        frame_number->blockSignals(true);
        frame_number->setValue(m_sequenceFrame);
        frame_number->blockSignals(false);
@@ -135,10 +192,10 @@ void StopmotionWidget::sequenceNameChanged(const QString &name)
     else {
        // Check if we are editing an existing sequence
        int count = 0;
-       QString pattern = SlideshowClip::selectedPath(getPathForFrame(0, sequence_name->text()), false, QString(), &count);
+       QString pattern = SlideshowClip::selectedPath(getPathForFrame(0, sequence_name->currentText()), false, QString(), &count);
        m_sequenceFrame = count;
        if (count > 0) {
-           m_sequenceName = sequence_name->text();
+           m_sequenceName = sequence_name->currentText();
            //TODO: Do the thumbnail stuff in a thread
            for (int i = 0; i < count; i++) {
                slotUpdateFrameList(i);
@@ -160,8 +217,15 @@ void StopmotionWidget::sequenceNameChanged(const QString &name)
 
 void StopmotionWidget::slotCaptureFrame()
 {
-    if (m_sequenceName != sequence_name->text()) {
-       m_sequenceName = sequence_name->text();
+    if (sequence_name->currentText().isEmpty()) {
+       QString seqName = QInputDialog::getText(this, i18n("Create New Sequence"), i18n("Enter sequence name"));
+       if (seqName.isEmpty()) return;
+       sequence_name->blockSignals(true);
+       sequence_name->setItemText(sequence_name->currentIndex(), seqName);
+       sequence_name->blockSignals(false);
+    }
+    if (m_sequenceName != sequence_name->currentText()) {
+       m_sequenceName = sequence_name->currentText();
        m_sequenceFrame = 0;
     }
     capture_button->setEnabled(false);
@@ -228,12 +292,25 @@ void StopmotionWidget::slotShowFrame(int ix)
     frameoverlay_button->blockSignals(false);
     if (ix < m_sequenceFrame) {
        // Show previous frame
+       slotLive(false);
+       live_button->setChecked(false);
        QImage img(getPathForFrame(ix));
        capture_button->setEnabled(false);
-       if (!img.isNull()) m_bmCapture->showOverlay(img, false);
+       if (!img.isNull()) {
+           //m_bmCapture->showOverlay(img, false);
+           m_bmCapture->hidePreview(true);
+           m_frame_preview->setImage(img);
+           m_frame_preview->setHidden(false);
+           m_frame_preview->update();
+           selectFrame(ix);
+       }
     }
     else {
+       slotLive(true);
+       m_frame_preview->setImage(QImage());
+       m_frame_preview->setHidden(true);
        m_bmCapture->hideOverlay();
+       m_bmCapture->hidePreview(false);
        capture_button->setEnabled(true);
     }    
 }
@@ -275,4 +352,46 @@ void StopmotionWidget::slotAnimate()
     m_animatedIndex++;
     if (m_animatedIndex < m_sequenceFrame) QTimer::singleShot(200, this, SLOT(slotAnimate()));
     else m_animatedIndex = -1;
-}
\ No newline at end of file
+}
+
+void StopmotionWidget::selectFrame(int ix)
+{
+    frame_list->blockSignals(true);
+    QListWidgetItem *item = frame_list->item(ix);
+    int current = item->data(Qt::UserRole + 1).toInt();
+    if (current == ix) {
+       frame_list->setCurrentItem(item);
+    }
+    else if (current < ix) {
+       for (int i = ix; i < frame_list->count(); i++) {
+           item = frame_list->item(i);
+           current = item->data(Qt::UserRole + 1).toInt();
+           if (current == ix) {
+               frame_list->setCurrentItem(item);
+               break;
+           }
+       }
+    }
+    else {
+       for (int i = ix; i >= 0; i--) {
+           item = frame_list->item(i);
+           current = item->data(Qt::UserRole + 1).toInt();
+           if (current == ix) {
+               frame_list->setCurrentItem(item);
+               break;
+           }
+       }
+    }
+    frame_list->blockSignals(false);
+}
+
+void StopmotionWidget::slotSeekFrame(bool forward)
+{
+    int ix = frame_list->currentRow();
+    if (forward) {
+       if (ix < frame_list->count() - 1) frame_list->setCurrentRow(ix + 1);
+    }
+    else if (ix > 0) frame_list->setCurrentRow(ix - 1);
+}
+
+
index 7742447b840f733e8549862802a96739bf00de09..59544c395d3dc7728139ea29863fb411c27bae8e 100644 (file)
 #include "../blackmagic/capture.h"
 
 #include <KUrl>
+#include <QLabel>
+
+class MyLabel : public QLabel
+{
+  Q_OBJECT
+public:
+    MyLabel(QWidget *parent = 0);
+    void setImage(QImage img);
+
+protected:
+    virtual void paintEvent( QPaintEvent * event);
+    virtual void wheelEvent(QWheelEvent * event);
+
+private:
+    QImage m_img;
+
+signals:
+    /** @brief Seek to next or previous frame.
+     *  @param forward set to true to go to next frame, fals to go to previous frame */
+    void seek(bool forward);
+};
 
 class StopmotionWidget : public QDialog , public Ui::Stopmotion_UI
 {
@@ -57,6 +78,15 @@ private:
   
   /** @brief Holds the index of the frame to be displayed in the frame preview mode. */
   int m_animatedIndex;
+
+  /** @brief Find all stopmotion sequences in current project folder. */
+  void parseExistingSequences();
+
+  /** @brief Select a frame in the list. */
+  void selectFrame(int ix);
+
+  /** @brief This widget will hold the frame preview. */
+  MyLabel *m_frame_preview;
   
 private slots:
   /** @brief Display the live feed from capture device.
@@ -98,6 +128,10 @@ private slots:
   
   /** @brief Simulate animation. */
   void slotAnimate();
+  
+  /** @brief Seek to previous or next captured frame.
+   *  @param forward set to true for next frame, false for previous one. */
+  void slotSeekFrame(bool forward);
 
 signals:
   /** @brief Ask to add sequence to current project. */
index 40d87b3b14d3930a6050dcd4bde93f5e7fcc3d72..010b093bb684ee201135719b97adff666617ac1d 100644 (file)
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>662</width>
-    <height>418</height>
+    <width>619</width>
+    <height>434</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -81,6 +81,9 @@
      <property name="checkable">
       <bool>true</bool>
      </property>
+     <property name="autoRaise">
+      <bool>true</bool>
+     </property>
     </widget>
    </item>
    <item row="1" column="1">
      <property name="checkable">
       <bool>true</bool>
      </property>
+     <property name="autoRaise">
+      <bool>true</bool>
+     </property>
     </widget>
    </item>
    <item row="1" column="2">
      </property>
     </widget>
    </item>
-   <item row="1" column="3">
-    <widget class="KLineEdit" name="sequence_name">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="toolTip">
-      <string>Sequence name</string>
-     </property>
-     <property name="whatsThis">
-      <string/>
-     </property>
-    </widget>
-   </item>
    <item row="1" column="4">
     <widget class="QSpinBox" name="frame_number">
      <property name="toolTip">
      </property>
     </widget>
    </item>
+   <item row="1" column="3">
+    <widget class="KComboBox" name="sequence_name">
+     <property name="toolTip">
+      <string>Sequence name</string>
+     </property>
+     <property name="editable">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
   </layout>
  </widget>
  <customwidgets>
-  <customwidget>
-   <class>KLineEdit</class>
-   <extends>QLineEdit</extends>
-   <header>klineedit.h</header>
-  </customwidget>
   <customwidget>
    <class>KComboBox</class>
    <extends>QComboBox</extends>