diff --git a/Plugins/org.mitk.gui.qt.moviemaker2/files.cmake b/Plugins/org.mitk.gui.qt.moviemaker2/files.cmake index cf08e2cdb0..30ee551c36 100644 --- a/Plugins/org.mitk.gui.qt.moviemaker2/files.cmake +++ b/Plugins/org.mitk.gui.qt.moviemaker2/files.cmake @@ -1,49 +1,51 @@ set(SRC_CPP_FILES ) set(INTERNAL_CPP_FILES org_mitk_gui_qt_moviemaker2_Activator.cpp QmitkAnimationItem.cpp QmitkAnimationItemDelegate.cpp QmitkAnimationWidget.cpp + QmitkFFmpegWriter.cpp QmitkMovieMaker2View.cpp QmitkOrbitAnimationItem.cpp QmitkOrbitAnimationWidget.cpp QmitkSliceAnimationItem.cpp QmitkSliceAnimationWidget.cpp ) set(UI_FILES src/internal/QmitkMovieMaker2View.ui src/internal/QmitkOrbitAnimationWidget.ui src/internal/QmitkSliceAnimationWidget.ui ) set(MOC_H_FILES src/internal/org_mitk_gui_qt_moviemaker2_Activator.h src/internal/QmitkAnimationItemDelegate.h src/internal/QmitkAnimationWidget.h + src/internal/QmitkFFmpegWriter.h src/internal/QmitkMovieMaker2View.h src/internal/QmitkOrbitAnimationWidget.h src/internal/QmitkSliceAnimationWidget.h ) set(CACHED_RESOURCE_FILES resources/camera-video.png plugin.xml ) set(QRC_FILES resources/org_mitk_gui_qt_moviemaker2.qrc ) set(CPP_FILES ) foreach(file ${SRC_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/${file}) endforeach() foreach(file ${INTERNAL_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/internal/${file}) endforeach() diff --git a/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkFFmpegWriter.cpp b/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkFFmpegWriter.cpp new file mode 100644 index 0000000000..b80b90ffc5 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkFFmpegWriter.cpp @@ -0,0 +1,156 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "QmitkFFmpegWriter.h" +#include +#include + +QmitkFFmpegWriter::QmitkFFmpegWriter(QObject* parent) + : QObject(parent), + m_Process(new QProcess(this)) +{ + this->connect(m_Process, SIGNAL(error(QProcess::ProcessError)), + this, SLOT(OnProcessError(QProcess::ProcessError))); + + this->connect(m_Process, SIGNAL(finished(int, QProcess::ExitStatus)), + this, SLOT(OnProcessFinished(int, QProcess::ExitStatus))); +} + +QmitkFFmpegWriter::~QmitkFFmpegWriter() +{ +} + +QString QmitkFFmpegWriter::GetFFmpegPath() const +{ + return m_FFmpegPath; +} + +void QmitkFFmpegWriter::SetFFmpegPath(const QString& path) +{ + m_FFmpegPath = path; +} + +QSize QmitkFFmpegWriter::GetSize() const +{ + return m_Size; +} + +void QmitkFFmpegWriter::SetSize(const QSize& size) +{ + m_Size = size; +} + +void QmitkFFmpegWriter::SetSize(int width, int height) +{ + m_Size = QSize(width, height); +} + +int QmitkFFmpegWriter::GetFramerate() const +{ + return m_Framerate; +} + +void QmitkFFmpegWriter::SetFramerate(int framerate) +{ + m_Framerate = framerate; +} + +QString QmitkFFmpegWriter::GetOutputPath() const +{ + return m_OutputPath; +} + +void QmitkFFmpegWriter::SetOutputPath(const QString& path) +{ + m_OutputPath = path; +} + +void QmitkFFmpegWriter::Start() +{ + m_Process->start(m_FFmpegPath, QStringList() + << "-y" + << "-f" << "rawvideo" + << "-pix_fmt" << "rgb24" + << "-s" << QString("%1x%2").arg(m_Size.width()).arg(m_Size.height()) + << "-r" << QString("%1").arg(m_Framerate) + << "-i" << "-" + << "-vf" << "vflip" + << "-pix_fmt" << "yuv420p" + << "-crf" << "18" + << m_OutputPath); + + m_Process->waitForStarted(); +} + +void QmitkFFmpegWriter::WriteFrame(const unsigned char* frame) +{ + if (frame == NULL || !m_Process->isOpen()) + return; + + m_Process->write(reinterpret_cast(frame), m_Size.width() * m_Size.height() * 3); + m_Process->waitForBytesWritten(); +} + +void QmitkFFmpegWriter::Stop() +{ + m_Process->closeWriteChannel(); +} + +void QmitkFFmpegWriter::OnProcessError(QProcess::ProcessError error) +{ + switch (error) + { + case QProcess::FailedToStart: + QMessageBox::critical(NULL, "FFmpeg Writer", "FFmpeg failed to start!"); + break; + + case QProcess::Crashed: + QMessageBox::critical(NULL, "FFmpeg Writer", "FFmpeg crashed!"); + break; + + case QProcess::Timedout: + QMessageBox::critical(NULL, "FFmpeg Writer", "FFmpeg timed out!"); + break; + + case QProcess::WriteError: + QMessageBox::critical(NULL, "FFmpeg Writer", "Could not write to FFmpeg!"); + break; + + case QProcess::ReadError: + QMessageBox::critical(NULL, "FFmpeg Writer", "Could not read from FFmpeg!"); + break; + + default: + QMessageBox::critical(NULL, "FFmpeg Writer", "An unknown error occurred!"); + break; + } + + MITK_ERROR << QString::fromLatin1(m_Process->readAllStandardError()).toStdString(); +} + +void QmitkFFmpegWriter::OnProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) +{ + if (exitStatus != QProcess::CrashExit) + { + if (exitCode != 0) + { + QMessageBox::critical(NULL, "FFmpeg Writer", QString("FFmpeg exit code: %1").arg(exitCode)); + MITK_ERROR << QString::fromLatin1(m_Process->readAllStandardError()).toStdString(); + } + } + + m_Process->close(); +} diff --git a/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkFFmpegWriter.h b/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkFFmpegWriter.h new file mode 100644 index 0000000000..0380823040 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkFFmpegWriter.h @@ -0,0 +1,60 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef QmitkFFmpegWriter_h +#define QmitkFFmpegWriter_h + +#include +#include + +class QmitkFFmpegWriter : public QObject +{ + Q_OBJECT + +public: + explicit QmitkFFmpegWriter(QObject* parent = NULL); + ~QmitkFFmpegWriter(); + + QString GetFFmpegPath() const; + void SetFFmpegPath(const QString& path); + + QSize GetSize() const; + void SetSize(const QSize& size); + void SetSize(int width, int height); + + int GetFramerate() const; + void SetFramerate(int framerate); + + QString GetOutputPath() const; + void SetOutputPath(const QString& path); + + void Start(); + void WriteFrame(const unsigned char* frame); + void Stop(); + +private slots: + void OnProcessError(QProcess::ProcessError error); + void OnProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); + +private: + QProcess* m_Process; + QString m_FFmpegPath; + QSize m_Size; + int m_Framerate; + QString m_OutputPath; +}; + +#endif diff --git a/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkMovieMaker2View.cpp b/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkMovieMaker2View.cpp index c73d39a4c1..d951ed76c2 100644 --- a/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkMovieMaker2View.cpp +++ b/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkMovieMaker2View.cpp @@ -1,385 +1,453 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkAnimationItemDelegate.h" +#include "QmitkFFmpegWriter.h" #include "QmitkMovieMaker2View.h" #include "QmitkOrbitAnimationItem.h" #include "QmitkOrbitAnimationWidget.h" #include "QmitkSliceAnimationItem.h" #include "QmitkSliceAnimationWidget.h" #include #include #include #include #include +#include static QmitkAnimationItem* CreateDefaultAnimation(const QString& widgetKey) { if (widgetKey == "Orbit") return new QmitkOrbitAnimationItem(360.0, false); if (widgetKey == "Slice") return new QmitkSliceAnimationItem(0, 0, 999, false); return NULL; } +static unsigned char* ReadPixels(vtkRenderWindow* renderWindow, int x, int y, int width, int height) +{ + if (renderWindow == NULL) + return NULL; + + const int* size = renderWindow->GetSize(); + unsigned char* frame = new unsigned char[width * height * 3]; + + renderWindow->MakeCurrent(); + glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, frame); + + return frame; +} + const std::string QmitkMovieMaker2View::VIEW_ID = "org.mitk.views.moviemaker2"; QmitkMovieMaker2View::QmitkMovieMaker2View() - : m_Ui(new Ui::QmitkMovieMaker2View), + : m_FFmpegWriter(NULL), + m_Ui(new Ui::QmitkMovieMaker2View), m_AnimationModel(NULL), m_AddAnimationMenu(NULL), m_RecordMenu(NULL) { } QmitkMovieMaker2View::~QmitkMovieMaker2View() { } void QmitkMovieMaker2View::CreateQtPartControl(QWidget* parent) { + m_FFmpegWriter = new QmitkFFmpegWriter(parent); + m_Ui->setupUi(parent); this->InitializeAnimationWidgets(); this->InitializeAnimationTreeViewWidgets(); this->InitializePlaybackAndRecordWidgets(); m_Ui->animationWidgetGroupBox->setVisible(false); } void QmitkMovieMaker2View::InitializeAnimationWidgets() { m_AnimationWidgets["Orbit"] = new QmitkOrbitAnimationWidget; m_AnimationWidgets["Slice"] = new QmitkSliceAnimationWidget; Q_FOREACH(QWidget* widget, m_AnimationWidgets.values()) { if (widget != NULL) { widget->setVisible(false); m_Ui->animationWidgetGroupBoxLayout->addWidget(widget); } } this->ConnectAnimationWidgets(); } void QmitkMovieMaker2View::InitializeAnimationTreeViewWidgets() { this->InitializeAnimationModel(); this->InitializeAddAnimationMenu(); this->ConnectAnimationTreeViewWidgets(); } void QmitkMovieMaker2View::InitializePlaybackAndRecordWidgets() { this->InitializeRecordMenu(); this->ConnectPlaybackAndRecordWidgets(); } void QmitkMovieMaker2View::InitializeAnimationModel() { m_AnimationModel = new QStandardItemModel(m_Ui->animationTreeView); m_AnimationModel->setHorizontalHeaderLabels(QStringList() << "Animation" << "Timeline"); m_Ui->animationTreeView->setModel(m_AnimationModel); m_Ui->animationTreeView->setItemDelegateForColumn(1, new QmitkAnimationItemDelegate(m_Ui->animationTreeView)); } void QmitkMovieMaker2View::InitializeAddAnimationMenu() { m_AddAnimationMenu = new QMenu(m_Ui->addAnimationButton); Q_FOREACH(const QString& key, m_AnimationWidgets.keys()) { m_AddAnimationMenu->addAction(key); } } void QmitkMovieMaker2View::InitializeRecordMenu() { + typedef QPair PairOfStrings; + m_RecordMenu = new QMenu(m_Ui->recordButton); - m_RecordMenu->addAction("Axial"); - m_RecordMenu->addAction("Sagittal"); - m_RecordMenu->addAction("Coronal"); - m_RecordMenu->addAction("3D"); + QVector renderWindows; + renderWindows.push_back(qMakePair(QString("Axial"), QString("stdmulti.widget1"))); + renderWindows.push_back(qMakePair(QString("Sagittal"), QString("stdmulti.widget2"))); + renderWindows.push_back(qMakePair(QString("Coronal"), QString("stdmulti.widget3"))); + renderWindows.push_back(qMakePair(QString("3D"), QString("stdmulti.widget4"))); + + Q_FOREACH(const PairOfStrings& renderWindow, renderWindows) + { + QAction* action = new QAction(m_RecordMenu); + action->setText(renderWindow.first); + action->setData(renderWindow.second); + + m_RecordMenu->addAction(action); + } } void QmitkMovieMaker2View::ConnectAnimationTreeViewWidgets() { this->connect(m_AnimationModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)), this, SLOT(OnAnimationTreeViewRowsInserted(const QModelIndex&, int, int))); this->connect(m_AnimationModel, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), this, SLOT(OnAnimationTreeViewRowsRemoved(const QModelIndex&, int, int))); this->connect(m_Ui->animationTreeView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(OnAnimationTreeViewSelectionChanged(const QItemSelection&, const QItemSelection&))); this->connect(m_Ui->moveAnimationUpButton, SIGNAL(clicked()), this, SLOT(OnMoveAnimationUpButtonClicked())); this->connect(m_Ui->moveAnimationDownButton, SIGNAL(clicked()), this, SLOT(OnMoveAnimationDownButtonClicked())); this->connect(m_Ui->addAnimationButton, SIGNAL(clicked()), this, SLOT(OnAddAnimationButtonClicked())); this->connect(m_Ui->removeAnimationButton, SIGNAL(clicked()), this, SLOT(OnRemoveAnimationButtonClicked())); } void QmitkMovieMaker2View::ConnectAnimationWidgets() { this->connect(m_Ui->startComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(OnStartComboBoxCurrentIndexChanged(int))); this->connect(m_Ui->durationSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnDurationSpinBoxValueChanged(double))); this->connect(m_Ui->delaySpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnDelaySpinBoxValueChanged(double))); } void QmitkMovieMaker2View::ConnectPlaybackAndRecordWidgets() { this->connect(m_Ui->recordButton, SIGNAL(clicked()), this, SLOT(OnRecordButtonClicked())); } void QmitkMovieMaker2View::SetFocus() { m_Ui->addAnimationButton->setFocus(); } void QmitkMovieMaker2View::OnMoveAnimationUpButtonClicked() { const QItemSelection selection = m_Ui->animationTreeView->selectionModel()->selection(); if (!selection.isEmpty()) { const int selectedRow = selection[0].top(); if (selectedRow > 0) m_AnimationModel->insertRow(selectedRow - 1, m_AnimationModel->takeRow(selectedRow)); } } void QmitkMovieMaker2View::OnMoveAnimationDownButtonClicked() { const QItemSelection selection = m_Ui->animationTreeView->selectionModel()->selection(); if (!selection.isEmpty()) { const int rowCount = m_AnimationModel->rowCount(); const int selectedRow = selection[0].top(); if (selectedRow < rowCount - 1) m_AnimationModel->insertRow(selectedRow + 1, m_AnimationModel->takeRow(selectedRow)); } } void QmitkMovieMaker2View::OnAddAnimationButtonClicked() { QAction* action = m_AddAnimationMenu->exec(QCursor::pos()); if (action != NULL) { const QString widgetKey = action->text(); m_AnimationModel->appendRow(QList() << new QStandardItem(widgetKey) << CreateDefaultAnimation(widgetKey)); m_Ui->playbackAndRecordingGroupBox->setEnabled(true); } } void QmitkMovieMaker2View::OnRecordButtonClicked() { QAction* action = m_RecordMenu->exec(QCursor::pos()); - if (action != NULL) + if (action == NULL) + return; + + vtkRenderWindow* renderWindow = mitk::BaseRenderer::GetRenderWindowByName(action->data().toString().toStdString()); + + if (renderWindow == NULL) + return; + + // TODO: Refactor size calculation + + const int border = 3; + const int x = border; + const int y = border; + int width = renderWindow->GetSize()[0] - border * 2; + int height = renderWindow->GetSize()[1] - border * 2; + + if (width & 1) + --width; + + if (height & 1) + --height; + + if (width < 16 || height < 16) + return; + + m_FFmpegWriter->SetFFmpegPath("D:\\FFmpeg\\bin\\ffmpeg.exe"); //TODO: Get FFmpeg path from preferences + m_FFmpegWriter->SetSize(width, height); + m_FFmpegWriter->SetFramerate(m_Ui->fpsSpinBox->value()); + m_FFmpegWriter->SetOutputPath("C:\\Users\\Stefan\\Desktop\\output.mp4"); // TODO: Ask user for output path + + m_FFmpegWriter->Start(); + + // TODO: Play animation + + for (int i = 0; i < 30; ++i) { - // TODO: Ensure render window is opened - // TODO + unsigned char* frame = ReadPixels(renderWindow, x, y, width, height); + m_FFmpegWriter->WriteFrame(frame); + delete[] frame; } + + m_FFmpegWriter->Stop(); } void QmitkMovieMaker2View::OnRemoveAnimationButtonClicked() { const QItemSelection selection = m_Ui->animationTreeView->selectionModel()->selection(); if (!selection.isEmpty()) m_AnimationModel->removeRow(selection[0].top()); } void QmitkMovieMaker2View::OnAnimationTreeViewRowsInserted(const QModelIndex& parent, int start, int) { m_Ui->animationTreeView->selectionModel()->select( m_AnimationModel->index(start, 0, parent), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); } void QmitkMovieMaker2View::OnAnimationTreeViewRowsRemoved(const QModelIndex&, int, int) { this->UpdateWidgets(); } void QmitkMovieMaker2View::OnAnimationTreeViewSelectionChanged(const QItemSelection&, const QItemSelection&) { this->UpdateWidgets(); } void QmitkMovieMaker2View::OnStartComboBoxCurrentIndexChanged(int index) { QmitkAnimationItem* item = this->GetSelectedAnimationItem(); if (item != NULL) { item->SetStartWithPrevious(index); this->RedrawTimeline(); } } void QmitkMovieMaker2View::OnDurationSpinBoxValueChanged(double value) { QmitkAnimationItem* item = this->GetSelectedAnimationItem(); if (item != NULL) { item->SetDuration(value); this->RedrawTimeline(); } } void QmitkMovieMaker2View::OnDelaySpinBoxValueChanged(double value) { QmitkAnimationItem* item = this->GetSelectedAnimationItem(); if (item != NULL) { item->SetDelay(value); this->RedrawTimeline(); } } void QmitkMovieMaker2View::UpdateWidgets() { const QItemSelection selection = m_Ui->animationTreeView->selectionModel()->selection(); if (selection.isEmpty()) { m_Ui->moveAnimationUpButton->setEnabled(false); m_Ui->moveAnimationDownButton->setEnabled(false); m_Ui->removeAnimationButton->setEnabled(false); m_Ui->playbackAndRecordingGroupBox->setEnabled(false); this->HideCurrentAnimationWidget(); } else { const int rowCount = m_AnimationModel->rowCount(); const int selectedRow = selection[0].top(); m_Ui->moveAnimationUpButton->setEnabled(rowCount > 1 && selectedRow != 0); m_Ui->moveAnimationDownButton->setEnabled(rowCount > 1 && selectedRow < rowCount - 1); m_Ui->removeAnimationButton->setEnabled(true); m_Ui->playbackAndRecordingGroupBox->setEnabled(true); this->ShowAnimationWidget(dynamic_cast(m_AnimationModel->item(selectedRow, 1))); } this->UpdateAnimationWidgets(); } void QmitkMovieMaker2View::UpdateAnimationWidgets() { QmitkAnimationItem* item = this->GetSelectedAnimationItem(); if (item != NULL) { m_Ui->startComboBox->setCurrentIndex(item->GetStartWithPrevious()); m_Ui->durationSpinBox->setValue(item->GetDuration()); m_Ui->delaySpinBox->setValue(item->GetDelay()); m_Ui->animationGroupBox->setEnabled(true); } else { m_Ui->animationGroupBox->setEnabled(false); } } void QmitkMovieMaker2View::HideCurrentAnimationWidget() { if (m_Ui->animationWidgetGroupBox->isVisible()) { m_Ui->animationWidgetGroupBox->setVisible(false); int numWidgets = m_Ui->animationWidgetGroupBoxLayout->count(); for (int i = 0; i < numWidgets; ++i) m_Ui->animationWidgetGroupBoxLayout->itemAt(i)->widget()->setVisible(false); } } void QmitkMovieMaker2View::ShowAnimationWidget(QmitkAnimationItem* animationItem) { this->HideCurrentAnimationWidget(); if (animationItem == NULL) return; const QString widgetKey = animationItem->GetWidgetKey(); QmitkAnimationWidget* animationWidget = NULL; if (m_AnimationWidgets.contains(widgetKey)) { animationWidget = m_AnimationWidgets[widgetKey]; if (animationWidget != NULL) { m_Ui->animationWidgetGroupBox->setTitle(widgetKey); animationWidget->SetAnimationItem(animationItem); animationWidget->setVisible(true); } } m_Ui->animationWidgetGroupBox->setVisible(animationWidget != NULL); } void QmitkMovieMaker2View::RedrawTimeline() { if (m_AnimationModel->rowCount() > 1) { m_Ui->animationTreeView->dataChanged( m_AnimationModel->index(0, 1), m_AnimationModel->index(m_AnimationModel->rowCount() - 1, 1)); } } QmitkAnimationItem* QmitkMovieMaker2View::GetSelectedAnimationItem() const { const QItemSelection selection = m_Ui->animationTreeView->selectionModel()->selection(); return !selection.isEmpty() ? dynamic_cast(m_AnimationModel->item(selection[0].top(), 1)) : NULL; } diff --git a/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkMovieMaker2View.h b/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkMovieMaker2View.h index 2dd3187d0e..bdee4c52e4 100644 --- a/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkMovieMaker2View.h +++ b/Plugins/org.mitk.gui.qt.moviemaker2/src/internal/QmitkMovieMaker2View.h @@ -1,82 +1,84 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QmitkMovieMaker2View_h #define QmitkMovieMaker2View_h #include class QmitkAnimationItem; class QmitkAnimationWidget; +class QmitkFFmpegWriter; class QMenu; class QStandardItemModel; namespace Ui { class QmitkMovieMaker2View; } class QmitkMovieMaker2View : public QmitkAbstractView { Q_OBJECT public: static const std::string VIEW_ID; QmitkMovieMaker2View(); ~QmitkMovieMaker2View(); void CreateQtPartControl(QWidget* parent); void SetFocus(); private slots: void OnMoveAnimationUpButtonClicked(); void OnMoveAnimationDownButtonClicked(); void OnAddAnimationButtonClicked(); void OnRemoveAnimationButtonClicked(); void OnAnimationTreeViewRowsInserted(const QModelIndex& parent, int start, int end); void OnAnimationTreeViewRowsRemoved(const QModelIndex& parent, int start, int end); void OnAnimationTreeViewSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected); void OnStartComboBoxCurrentIndexChanged(int index); void OnDurationSpinBoxValueChanged(double value); void OnDelaySpinBoxValueChanged(double value); void OnRecordButtonClicked(); private: void InitializeAnimationWidgets(); void InitializeAnimationTreeViewWidgets(); void InitializeAnimationModel(); void InitializeAddAnimationMenu(); void InitializePlaybackAndRecordWidgets(); void InitializeRecordMenu(); void ConnectAnimationTreeViewWidgets(); void ConnectAnimationWidgets(); void ConnectPlaybackAndRecordWidgets(); void UpdateWidgets(); void UpdateAnimationWidgets(); void HideCurrentAnimationWidget(); void ShowAnimationWidget(QmitkAnimationItem* animationItem); void RedrawTimeline(); QmitkAnimationItem* GetSelectedAnimationItem() const; + QmitkFFmpegWriter* m_FFmpegWriter; Ui::QmitkMovieMaker2View* m_Ui; QStandardItemModel* m_AnimationModel; QMap m_AnimationWidgets; QMenu* m_AddAnimationMenu; QMenu* m_RecordMenu; }; #endif