Commit f602f2ec authored by Stephen Thompson's avatar Stephen Thompson

Issue #5352 moved playback controls gui to a separate widget, so we can move it more easily

parent baf03cc0
......@@ -15,18 +15,21 @@
set(CPP_FILES
niftkIGIDataSourceManagerWidget.cxx
niftkIGIDataSourcePlaybackWidget.cxx
niftkIGIDataSourcePlaybackControlsWidget.cxx
niftkIGIDataSourceManager.cxx
)
set(MOC_H_FILES
niftkIGIDataSourceManagerWidget.h
niftkIGIDataSourcePlaybackWidget.h
niftkIGIDataSourcePlaybackControlsWidget.h
niftkIGIDataSourceManager.h
)
set(UI_FILES
niftkIGIDataSourceManagerWidget.ui
niftkIGIDataSourcePlaybackWidget.ui
niftkIGIDataSourcePlaybackControlsWidget.ui
)
set(QRC_FILES
......
......@@ -34,7 +34,8 @@ IGIDataSourceManagerWidget::IGIDataSourceManagerWidget(mitk::DataStorage::Pointe
{
Ui_IGIDataSourceManagerWidget::setupUi(parent);
m_PlaybackWidget = new IGIDataSourcePlaybackWidget ( dataStorage, m_Manager, groupBox_2 );
bool playbackVerticalLayout = true;
m_PlaybackWidget = new IGIDataSourcePlaybackWidget ( dataStorage, m_Manager, playbackVerticalLayout, groupBox_2 );
QList<QString> namesOfFactories = m_Manager->GetAllFactoryNames();
for (QString factory: namesOfFactories)
{
......
/*=============================================================================
NifTK: A software platform for medical image computing.
Copyright (c) University College London (UCL). 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 in the top level directory for details.
=============================================================================*/
#include "niftkIGIDataSourcePlaybackControlsWidget.h"
#include <niftkIGIInitialisationDialog.h>
#include <niftkIGIConfigurationDialog.h>
#include <QMessageBox>
#include <QTableWidgetItem>
#include <QVector>
#include <QDateTime>
#include <QTextStream>
#include <QList>
#include <QPainter>
namespace niftk
{
//-----------------------------------------------------------------------------
IGIDataSourcePlaybackControlsWidget::IGIDataSourcePlaybackControlsWidget(
QWidget *parent)
{
Ui_IGIDataSourcePlaybackControlsWidget::setupUi(parent);
}
//-----------------------------------------------------------------------------
IGIDataSourcePlaybackControlsWidget::~IGIDataSourcePlaybackControlsWidget()
{
}
} // end namespace
/*=============================================================================
NifTK: A software platform for medical image computing.
Copyright (c) University College London (UCL). 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 in the top level directory for details.
=============================================================================*/
#ifndef niftkIGIDataSourcePlaybackControlsWidget_h
#define niftkIGIDataSourcePlaybackControlsWidget_h
#include "niftkIGIDataSourcesManagerExports.h"
#include "ui_niftkIGIDataSourcePlaybackControlsWidget.h"
#include "niftkIGIDataSourceManager.h"
#include <mitkDataStorage.h>
#include <QWidget>
#include <QTimer>
#include <QTime>
namespace niftk
{
/**
* \class IGIDataSourcePlaybackWidget
* \brief Widget class to manage play back of a group of IGIDataSources (trackers, ultra-sound machines, video etc).
*
* This class must delegate all functionality to IGIDataSourceManager, and should
* only contain Widget related stuff. Conversely, IGIDataSourceManager should
* only contain non-Widget related stuff.
*/
class NIFTKIGIDATASOURCESMANAGER_EXPORT IGIDataSourcePlaybackControlsWidget :
public QWidget,
public Ui_IGIDataSourcePlaybackControlsWidget
{
Q_OBJECT
public:
IGIDataSourcePlaybackControlsWidget(QWidget *parent = 0);
virtual ~IGIDataSourcePlaybackControlsWidget();
signals:
protected:
IGIDataSourcePlaybackControlsWidget(const IGIDataSourcePlaybackControlsWidget&); // Purposefully not implemented.
IGIDataSourcePlaybackControlsWidget& operator=(const IGIDataSourcePlaybackControlsWidget&); // Purposefully not implemented.
private slots:
private:
}; // end class;
} // end namespace
#endif
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>IGIDataSourcePlaybackControlsWidget</class>
<widget class="QWidget" name="IGIDataSourcePlaybackControlsWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>988</width>
<height>190</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>QmitkIGIDataSourcePlayBackManager</string>
</property>
<property name="toolTip">
<string>Press to advance time automatically.</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="m_StartPushButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&lt;</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_PlayingPushButton">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>|&gt;</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_EndPushButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="m_TimeStampEdit"/>
</item>
</layout>
</item>
<item>
<widget class="QSlider" name="m_PlaybackSlider">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximum">
<number>9999</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::NoTicks</enum>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
</customwidgets>
<resources/>
<connections/>
</ui>
......@@ -13,6 +13,7 @@
=============================================================================*/
#include "niftkIGIDataSourcePlaybackWidget.h"
#include "niftkIGIDataSourcePlaybackControlsWidget.h"
#include <niftkIGIInitialisationDialog.h>
#include <niftkIGIConfigurationDialog.h>
#include <QMessageBox>
......@@ -29,14 +30,28 @@ namespace niftk
//-----------------------------------------------------------------------------
IGIDataSourcePlaybackWidget::IGIDataSourcePlaybackWidget(mitk::DataStorage::Pointer dataStorage,
IGIDataSourceManager* manager,
bool verticalLayout,
QWidget *parent)
: m_FixedRecordTime(0,0,0,0)
, m_RecordTime(0,0,0,0)
, m_MSecFixedRecordTime(0)
, m_VerticalLayout (verticalLayout)
{
m_Manager = manager;
Ui_IGIDataSourcePlaybackWidget::setupUi(parent);
if ( m_VerticalLayout )
{
m_PlaybackControlsWidget = new IGIDataSourcePlaybackControlsWidget ( m_ToolManagerPlaybackGroupBox_Vertical );
m_ToolManagerPlaybackGroupBox_Horizontal->setVisible (false);
}
else
{
m_PlaybackControlsWidget = new IGIDataSourcePlaybackControlsWidget ( m_ToolManagerPlaybackGroupBox_Horizontal );
m_ToolManagerPlaybackGroupBox_Vertical->setVisible (false);
}
m_PlayPushButton->setIcon(QIcon(":/niftkIGIDataSourcesManagerResources/play.png"));
m_RecordPushButton->setIcon(QIcon(":/niftkIGIDataSourcesManagerResources/record.png"));
m_StopPushButton->setIcon(QIcon(":/niftkIGIDataSourcesManagerResources/stop.png"));
......@@ -58,27 +73,12 @@ IGIDataSourcePlaybackWidget::IGIDataSourcePlaybackWidget(mitk::DataStorage::Poin
ok = QObject::connect(m_PlayPushButton, SIGNAL(clicked()),
this, SLOT(OnPlayStart()));
assert(ok);
ok = QObject::connect(m_TimeStampEdit, SIGNAL(editingFinished()),
this, SLOT(OnPlaybackTimestampEditFinished()));
assert(ok);
ok = QObject::connect(m_Manager, SIGNAL(PlaybackTimerAdvanced(int)),
this, SLOT(OnPlaybackTimeAdvanced(int)));
assert(ok);
ok = QObject::connect(m_Manager, SIGNAL(TimerUpdated(QString, QString)),
this, SLOT(OnTimerUpdated(QString, QString)));
assert(ok);
ok = QObject::connect(m_PlayingPushButton, SIGNAL(clicked(bool)),
this, SLOT(OnPlayingPushButtonClicked(bool)));
assert(ok);
ok = QObject::connect(m_EndPushButton, SIGNAL(clicked(bool)),
this, SLOT(OnEndPushButtonClicked(bool)));
assert(ok);
ok = QObject::connect(m_StartPushButton, SIGNAL(clicked(bool)),
this, SLOT(OnStartPushButtonClicked(bool)));
assert(ok);
ok = QObject::connect(m_PlaybackSlider, SIGNAL(sliderReleased()),
this, SLOT(OnSliderReleased()));
assert(ok);
ok = QObject::connect(m_GrabScreenCheckbox, SIGNAL(clicked(bool)),
this, SLOT(OnGrabScreen(bool)));
assert(ok);
......@@ -91,6 +91,23 @@ IGIDataSourcePlaybackWidget::IGIDataSourcePlaybackWidget(mitk::DataStorage::Poin
ok = QObject::connect(m_Manager, SIGNAL(UpdateFinishedRendering()),
this, SLOT(OnUpdateRecordTimeDisplay()));
assert(ok);
//signals from the playback controls widget
ok = QObject::connect(m_PlaybackControlsWidget->m_TimeStampEdit, SIGNAL(editingFinished()),
this, SLOT(OnPlaybackTimestampEditFinished()));
assert(ok);
ok = QObject::connect(m_PlaybackControlsWidget->m_PlayingPushButton, SIGNAL(clicked(bool)),
this, SLOT(OnPlayingPushButtonClicked(bool)));
assert(ok);
ok = QObject::connect(m_PlaybackControlsWidget->m_EndPushButton, SIGNAL(clicked(bool)),
this, SLOT(OnEndPushButtonClicked(bool)));
assert(ok);
ok = QObject::connect(m_PlaybackControlsWidget->m_PlaybackSlider, SIGNAL(sliderReleased()),
this, SLOT(OnSliderReleased()));
assert(ok);
ok = QObject::connect(m_PlaybackControlsWidget->m_StartPushButton, SIGNAL(clicked(bool)),
this, SLOT(OnStartPushButtonClicked(bool)));
assert(ok);
}
......@@ -111,27 +128,12 @@ IGIDataSourcePlaybackWidget::~IGIDataSourcePlaybackWidget()
ok = QObject::disconnect(m_PlayPushButton, SIGNAL(clicked()),
this, SLOT(OnPlayStart()));
assert(ok);
ok = QObject::disconnect(m_TimeStampEdit, SIGNAL(editingFinished()),
this, SLOT(OnPlaybackTimestampEditFinished()));
assert(ok);
ok = QObject::disconnect(m_Manager, SIGNAL(PlaybackTimerAdvanced(int)),
this, SLOT(OnPlaybackTimeAdvanced(int)));
assert(ok);
ok = QObject::disconnect(m_Manager, SIGNAL(TimerUpdated(QString, QString)),
this, SLOT(OnTimerUpdated(QString, QString)));
assert(ok);
ok = QObject::disconnect(m_PlayingPushButton, SIGNAL(clicked(bool)),
this, SLOT(OnPlayingPushButtonClicked(bool)));
assert(ok);
ok = QObject::disconnect(m_EndPushButton, SIGNAL(clicked(bool)),
this, SLOT(OnEndPushButtonClicked(bool)));
assert(ok);
ok = QObject::disconnect(m_StartPushButton, SIGNAL(clicked(bool)),
this, SLOT(OnStartPushButtonClicked(bool)));
assert(ok);
ok = QObject::disconnect(m_PlaybackSlider, SIGNAL(sliderReleased()),
this, SLOT(OnSliderReleased()));
assert(ok);
ok = QObject::disconnect(m_GrabScreenCheckbox, SIGNAL(clicked(bool)),
this, SLOT(OnGrabScreen(bool)));
assert(ok);
......@@ -144,6 +146,22 @@ IGIDataSourcePlaybackWidget::~IGIDataSourcePlaybackWidget()
ok = QObject::disconnect(m_Manager, SIGNAL(UpdateFinishedRendering()),
this, SLOT(OnUpdateRecordTimeDisplay()));
assert(ok);
//signals from the playback controls widget
ok = QObject::disconnect(m_PlaybackControlsWidget->m_TimeStampEdit, SIGNAL(editingFinished()),
this, SLOT(OnPlaybackTimestampEditFinished()));
assert(ok);
ok = QObject::disconnect(m_PlaybackControlsWidget->m_PlayingPushButton, SIGNAL(clicked(bool)),
this, SLOT(OnPlayingPushButtonClicked(bool)));
assert(ok);
ok = QObject::disconnect(m_PlaybackControlsWidget->m_EndPushButton, SIGNAL(clicked(bool)),
this, SLOT(OnEndPushButtonClicked(bool)));
assert(ok);
ok = QObject::disconnect(m_PlaybackControlsWidget->m_PlaybackSlider, SIGNAL(sliderReleased()),
this, SLOT(OnSliderReleased()));
assert(ok);
ok = QObject::disconnect(m_PlaybackControlsWidget->m_StartPushButton, SIGNAL(clicked(bool)),
this, SLOT(OnStartPushButtonClicked(bool)));
assert(ok);
// m_Manager belongs to the calling widget
}
......@@ -209,12 +227,19 @@ void IGIDataSourcePlaybackWidget::OnPlayStart()
sliderValue
);
m_PlaybackSlider->setMinimum(sliderValue);
m_PlaybackSlider->setMaximum(sliderMaximum);
m_PlaybackSlider->setSingleStep(sliderSingleStep);
m_PlaybackSlider->setPageStep(sliderPageStep);
m_PlaybackControlsWidget->m_PlaybackSlider->setMinimum(sliderValue);
m_PlaybackControlsWidget->m_PlaybackSlider->setMaximum(sliderMaximum);
m_PlaybackControlsWidget->m_PlaybackSlider->setSingleStep(sliderSingleStep);
m_PlaybackControlsWidget->m_PlaybackSlider->setPageStep(sliderPageStep);
m_ToolManagerPlaybackGroupBox->setCollapsed(false);
if ( m_VerticalLayout )
{
m_ToolManagerPlaybackGroupBox_Vertical->setCollapsed(false);
}
else
{
m_ToolManagerPlaybackGroupBox_Horizontal->setCollapsed(false);
}
// Can stop playback with stop button (in addition to unchecking the playbutton)
m_StopPushButton->setEnabled(true);
......@@ -223,9 +248,9 @@ void IGIDataSourcePlaybackWidget::OnPlayStart()
// could be possible: leave this enabled and simply stop all playback when user clicks on record.
m_RecordPushButton->setEnabled(false);
m_FixedRecordTimeInterval->setEnabled(false);
m_TimeStampEdit->setReadOnly(false);
m_PlaybackSlider->setEnabled(true);
m_PlaybackSlider->setValue(sliderValue);
m_PlaybackControlsWidget->m_TimeStampEdit->setReadOnly(false);
m_PlaybackControlsWidget->m_PlaybackSlider->setEnabled(true);
m_PlaybackControlsWidget->m_PlaybackSlider->setValue(sliderValue);
// Stop the user editing the path.
// In order to start editing the path, you must stop playing back.
......@@ -266,9 +291,9 @@ void IGIDataSourcePlaybackWidget::OnPlayStart()
m_StopPushButton->setEnabled(false);
m_RecordPushButton->setEnabled(true);
m_FixedRecordTimeInterval->setEnabled(true);
m_TimeStampEdit->setReadOnly(true);
m_PlaybackSlider->setEnabled(false);
m_PlaybackSlider->setValue(0);
m_PlaybackControlsWidget->m_TimeStampEdit->setReadOnly(true);
m_PlaybackControlsWidget->m_PlaybackSlider->setEnabled(false);
m_PlaybackControlsWidget->m_PlaybackSlider->setValue(0);
}
}
......@@ -387,10 +412,10 @@ void IGIDataSourcePlaybackWidget::OnStop()
//-----------------------------------------------------------------------------
void IGIDataSourcePlaybackWidget::OnPlaybackTimestampEditFinished()
{
int result = m_Manager->ComputePlaybackTimeSliderValue(m_TimeStampEdit->text());
int result = m_Manager->ComputePlaybackTimeSliderValue(m_PlaybackControlsWidget->m_TimeStampEdit->text());
if (result != -1)
{
m_PlaybackSlider->setValue(result);
m_PlaybackControlsWidget->m_PlaybackSlider->setValue(result);
this->OnSliderReleased();
}
}
......@@ -400,9 +425,9 @@ void IGIDataSourcePlaybackWidget::OnPlaybackTimeAdvanced(int newSliderValue)
{
if (newSliderValue != -1)
{
m_PlaybackSlider->blockSignals(true);
m_PlaybackSlider->setValue(newSliderValue);
m_PlaybackSlider->blockSignals(false);
m_PlaybackControlsWidget->m_PlaybackSlider->blockSignals(true);
m_PlaybackControlsWidget->m_PlaybackSlider->setValue(newSliderValue);
m_PlaybackControlsWidget->m_PlaybackSlider->blockSignals(false);
}
}
......@@ -411,20 +436,20 @@ void IGIDataSourcePlaybackWidget::OnPlaybackTimeAdvanced(int newSliderValue)
void IGIDataSourcePlaybackWidget::OnTimerUpdated(QString rawString, QString humanReadableString)
{
// Only update text if user is not editing
if (!m_TimeStampEdit->hasFocus())
if (!m_PlaybackControlsWidget->m_TimeStampEdit->hasFocus())
{
m_TimeStampEdit->blockSignals(true);
m_PlaybackControlsWidget->m_TimeStampEdit->blockSignals(true);
// Avoid flickering the text field. it makes copy-n-paste impossible
// during playback mode because it resets the selection every few milliseconds.
if (m_TimeStampEdit->text() != humanReadableString)
if (m_PlaybackControlsWidget->m_TimeStampEdit->text() != humanReadableString)
{
m_TimeStampEdit->setText(humanReadableString);
m_PlaybackControlsWidget->m_TimeStampEdit->setText(humanReadableString);
}
if (m_TimeStampEdit->toolTip() != rawString)
if (m_PlaybackControlsWidget->m_TimeStampEdit->toolTip() != rawString)
{
m_TimeStampEdit->setToolTip(rawString);
m_PlaybackControlsWidget->m_TimeStampEdit->setToolTip(rawString);
}
m_TimeStampEdit->blockSignals(false);
m_PlaybackControlsWidget->m_TimeStampEdit->blockSignals(false);
}
}
......@@ -438,7 +463,7 @@ void IGIDataSourcePlaybackWidget::OnPlayingPushButtonClicked(bool isChecked)
//-----------------------------------------------------------------------------
void IGIDataSourcePlaybackWidget::OnEndPushButtonClicked(bool /*isChecked*/)
{
m_PlaybackSlider->setValue(m_PlaybackSlider->maximum());
m_PlaybackControlsWidget->m_PlaybackSlider->setValue(m_PlaybackControlsWidget->m_PlaybackSlider->maximum());
this->OnSliderReleased();
}
......@@ -446,7 +471,7 @@ void IGIDataSourcePlaybackWidget::OnEndPushButtonClicked(bool /*isChecked*/)
//-----------------------------------------------------------------------------
void IGIDataSourcePlaybackWidget::OnStartPushButtonClicked(bool /*isChecked*/)
{
m_PlaybackSlider->setValue(m_PlaybackSlider->minimum());
m_PlaybackControlsWidget->m_PlaybackSlider->setValue(m_PlaybackControlsWidget->m_PlaybackSlider->minimum());
this->OnSliderReleased();
}
......@@ -454,7 +479,7 @@ void IGIDataSourcePlaybackWidget::OnStartPushButtonClicked(bool /*isChecked*/)
//-----------------------------------------------------------------------------
void IGIDataSourcePlaybackWidget::OnSliderReleased()
{
IGIDataSourceI::IGITimeType time = m_Manager->ComputeTimeFromSlider(m_PlaybackSlider->value());
IGIDataSourceI::IGITimeType time = m_Manager->ComputeTimeFromSlider(m_PlaybackControlsWidget->m_PlaybackSlider->value());
m_Manager->SetPlaybackTime(time);
}
......
......@@ -17,6 +17,7 @@
#include "niftkIGIDataSourcesManagerExports.h"
#include "ui_niftkIGIDataSourcePlaybackWidget.h"
#include "niftkIGIDataSourcePlaybackControlsWidget.h"
#include "niftkIGIDataSourceManager.h"
#include <mitkDataStorage.h>
......@@ -46,6 +47,7 @@ public:
IGIDataSourcePlaybackWidget(mitk::DataStorage::Pointer dataStorage,
IGIDataSourceManager* manager,
bool verticalLayout,
QWidget *parent = 0);
virtual ~IGIDataSourcePlaybackWidget();
......@@ -155,6 +157,9 @@ private:
QTime m_FixedRecordTime; // To hold the amount of time the user specified.
int m_MSecFixedRecordTime; // Same time in milliseconds.
QTime m_RecordTime; // Total amount of time of current recording.
bool m_VerticalLayout; // Allows some customisation of the GUI layout.
IGIDataSourcePlaybackControlsWidget* m_PlaybackControlsWidget;
}; // end class;
......
......@@ -79,7 +79,7 @@
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<spacer name="m_horiz_spacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
......@@ -91,94 +91,37 @@
</property>
</spacer>
</item>
<item>
<widget class="ctkCollapsibleGroupBox" name="m_ToolManagerPlaybackGroupBox_Horizontal">
<property name="title">
<string>Playback Controls</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="ctkCollapsibleGroupBox" name="m_ToolManagerPlaybackGroupBox">
<widget class="ctkCollapsibleGroupBox" name="m_ToolManagerPlaybackGroupBox_Vertical">
<property name="title">
<string>Playback controls</string>
<string>Playback Controls</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="m_StartPushButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&lt;</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_PlayingPushButton">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>|&gt;</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>