Commit ccbf1d5e authored by Thiago Santini's avatar Thiago Santini

Implements basic keyboard commands from any window

Creates a base class for EyeRec widgets
parent 56779e9b
......@@ -42,7 +42,9 @@ SOURCES +=\
$${TOP}/src/PerformanceMonitorWidget.cpp \
$${TOP}/src/CameraCalibration.cpp \
$${TOP}/src/pupil-detection/PupilDetectionMethod.cpp \
$${TOP}/src/Overlay.cpp
$${TOP}/src/Overlay.cpp \
$${TOP}/src/CommandManager.cpp \
$${TOP}/src/ERWidget.cpp
HEADERS += \
$${TOP}/src/MainWindow.h\
......@@ -70,7 +72,9 @@ HEADERS += \
$${TOP}/src/PerformanceMonitor.h \
$${TOP}/src/PerformanceMonitorWidget.h \
$${TOP}/src/CameraCalibration.h \
$${TOP}/src/Overlay.h
$${TOP}/src/Overlay.h \
$${TOP}/src/CommandManager.h \
$${TOP}/src/ERWidget.h
FORMS += \
$${TOP}/src/MainWindow.ui \
......
......@@ -5,7 +5,7 @@ using namespace std;
using namespace cv;
CameraWidget::CameraWidget(QString id, ImageProcessor::Type type, QWidget *parent) :
QMainWindow(parent),
ERWidget(parent),
id(id),
type(type),
sROI(QPoint(0,0)),
......@@ -482,10 +482,3 @@ void CameraWidget::updateWidgetSize(const int &width, const int &height)
else
this->setMaximumSize( maxSize );
}
/*
* Drawing Functions
*/
......@@ -10,6 +10,8 @@
#include <QFont>
#include <QMessageBox>
#include "ERWidget.h"
#include "opencv2/imgproc.hpp"
#include "opencv2/calib3d.hpp"
......@@ -31,7 +33,7 @@ namespace Ui {
class CameraWidget;
}
class CameraWidget : public QMainWindow, InputWidget
class CameraWidget : public ERWidget, InputWidget
{
Q_OBJECT
......@@ -45,7 +47,6 @@ signals:
void newData(EyeData data);
void newData(FieldData data);
void newClick(Timestamp,QPoint,QSize);
void closed();
public slots:
void preview(Timestamp t, const cv::Mat &frame);
......@@ -113,9 +114,6 @@ private:
EyeOverlay eyeOverlay;
FieldOverlay fieldOverlay;
protected:
void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE { Q_UNUSED(event) emit closed(); }
};
#endif // CAMERAWIDGET_H
#include "CommandManager.h"
#include <QDebug>
void CommandManager::keyPress(QKeyEvent *event)
{
if (event->isAutoRepeat())
return;
switch (event->key()) {
case Qt::Key_C:
case Qt::Key_PageDown:
emit enableMarkerCollection();
break;
case Qt::Key_S:
case Qt::Key_PageUp:
emit toggleCalibration();
break;
case Qt::Key_R:
emit toggleRecording();
break;
case Qt::Key_F:
emit freezeCameraImages();
break;
default:
break;
}
}
void CommandManager::keyRelease(QKeyEvent *event)
{
if (event->isAutoRepeat())
return;
switch (event->key()) {
case Qt::Key_C:
case Qt::Key_PageDown:
emit disableMarkerCollection();
break;
case Qt::Key_F:
emit unfreezeCameraImages();
break;
default:
break;
}
}
#ifndef COMMANDMANAGER_H
#define COMMANDMANAGER_H
#include <QObject>
#include <QEvent>
#include <QKeyEvent>
class CommandManager : public QObject
{
Q_OBJECT
public slots:
void keyPress(QKeyEvent *event);
void keyRelease(QKeyEvent *event);
signals:
void toggleCalibration();
void toggleRecording();
void enableMarkerCollection();
void disableMarkerCollection();
void freezeCameraImages();
void unfreezeCameraImages();
};
#endif // COMMANDMANAGER_H
#include "ERWidget.h"
ERWidget::ERWidget(QWidget *parent) : QMainWindow(parent)
{
}
#ifndef ERWIDGET_H
#define ERWIDGET_H
#include <QMainWindow>
#include <QObject>
class ERWidget : public QMainWindow
{
Q_OBJECT
public:
explicit ERWidget(QWidget *parent = 0);
signals:
void closed();
void keyPress(QKeyEvent *event);
void keyRelease(QKeyEvent *event);
public slots:
protected:
void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE { Q_UNUSED(event) emit closed(); }
void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE { emit keyPress(event); }
void keyReleaseEvent(QKeyEvent *event) Q_DECL_OVERRIDE { emit keyRelease(event); }
};
#endif // ERWIDGET_H
......@@ -605,7 +605,7 @@ void GazeEstimation::drawGazeEstimationInfo(DataTuple &dataTuple)
dataTuple.showGazeEstimationVisualization = true;
// frame is already old; display old visualization instead to save processing
if (current - dataTuple.field.timestamp > 100)
if (current - dataTuple.field.timestamp > 100)
return;
vis = dataTuple.field.input.clone();
......
......@@ -9,7 +9,7 @@ static int gVectorCollectionTupleId = qRegisterMetaType<std::vector<CollectionTu
static int gCollectionTupleTypeId = qRegisterMetaType<CollectionTuple::TupleType>("CollectionTuple::TupleType");
GazeEstimationWidget::GazeEstimationWidget(QWidget *parent) :
QMainWindow(parent),
ERWidget(parent),
isCollecting(false),
isSampling(false),
lastStatus(false),
......@@ -284,6 +284,7 @@ void GazeEstimationWidget::on_collectionTypeComboBox_currentIndexChanged(int ind
currentTupleType = static_cast<CollectionTuple::TupleType>( ui->collectionTypeComboBox->itemData(index).toInt() );
}
/*
void GazeEstimationWidget::keyPressEvent(QKeyEvent *event)
{
if (event->isAutoRepeat())
......@@ -316,6 +317,29 @@ void GazeEstimationWidget::keyReleaseEvent(QKeyEvent *event)
break;
}
}
*/
void GazeEstimationWidget::toggleCalibration()
{
ui->startFinishButton->click();
//ui->startFinishButton->setChecked(!ui->startFinishButton->isChecked());
}
void GazeEstimationWidget::enableMarkerCollection()
{
if (isCollecting) {
connect(this, SIGNAL(inDataTuple(DataTuple)), this, SLOT(collectMarkerTuple(DataTuple)) );
collectedSound.play();
}
}
void GazeEstimationWidget::disableMarkerCollection()
{
disconnect(this, SIGNAL(inDataTuple(DataTuple)), this, SLOT(collectMarkerTuple(DataTuple)) );
if (isCollecting)
collectedSound.play();
}
void GazeEstimationWidget::collectMarkerTuple(DataTuple dataTuple)
{
if (dataTuple.field.collectionMarker.id == -1)
......
......@@ -9,6 +9,8 @@
#include <QKeyEvent>
#include <QSoundEffect>
#include "ERWidget.h"
#include "Synchronizer.h"
#include "GazeEstimation.h"
......@@ -16,7 +18,7 @@ namespace Ui {
class GazeEstimationWidget;
}
class GazeEstimationWidget : public QMainWindow
class GazeEstimationWidget : public ERWidget
{
Q_OBJECT
......@@ -35,9 +37,11 @@ signals:
void loadTuplesFromFile(CollectionTuple::TupleType type, QString fileName);
void calibrationRequest();
void setCalibrating(bool v);
void closed();
public slots:
void toggleCalibration();
void enableMarkerCollection();
void disableMarkerCollection();
private:
QThread *gazeEstimationThread;
......@@ -56,10 +60,11 @@ private:
QLabel *statusBarLabel;
QSoundEffect startSound, successSound, failureSound, collectedSound;
QSoundEffect startSound, successSound, failureSound, collectedSound;
private slots:
void startSampling(Timestamp timestamp, QPoint calibrationPoint, QSize previewSize);
void startSampling(Timestamp timestamp, QPoint calibrationPoint, QSize previewSize);
void newSample(DataTuple dataTuple);
void finishSampling();
void collectMarkerTuple(DataTuple dataTuple);
......@@ -70,9 +75,6 @@ private slots:
void on_startFinishButton_toggled(bool checked);
void on_collectionTypeComboBox_currentIndexChanged(int index);
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
void updateConfig();
void on_samplingTimeMsCheckBox_editingFinished();
void on_samplingMedianCheckBox_toggled(bool checked);
......@@ -90,8 +92,6 @@ private slots:
void on_visualizationGroupBox_toggled(bool arg1);
void on_visualizationTimeSpinBox_valueChanged(int arg1);
protected:
void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE { Q_UNUSED(event) emit closed(); }
};
#endif // GAZEESTIMATIONWIDGET_H
......@@ -2,7 +2,7 @@
#include "ui_LogWidget.h"
LogWidget::LogWidget(QWidget *parent) :
QMainWindow(parent),
ERWidget(parent),
ui(new Ui::LogWidget)
{
ui->setupUi(this);
......
......@@ -2,13 +2,16 @@
#define LOGWIDGET_H
#include <QMainWindow>
#include <QKeyEvent>
#include <QDebug>
#include "ERWidget.h"
namespace Ui {
class LogWidget;
}
class LogWidget : public QMainWindow
class LogWidget : public ERWidget
{
Q_OBJECT
......@@ -16,22 +19,16 @@ public:
explicit LogWidget(QWidget *parent = 0);
~LogWidget();
signals:
void closed();
public slots:
void appendMessage(const QString &msg);
private slots:
void on_usrMsg_returnPressed();
void on_addMsg_clicked();
private:
Ui::LogWidget *ui;
protected:
void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE { Q_UNUSED(event) emit closed(); }
};
#endif // LOGWIDGET_H
#include "MainWindow.h"
#include "ui_MainWindow.h"
// TODO: refactor MainWindow into a config aware class that can be shared by the
// widgets. Also add the gui interface there.
// TODO: factor config aware class into ERWidget
void MainWindow::createExtraMenus()
{
......@@ -11,7 +10,7 @@ void MainWindow::createExtraMenus()
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ERWidget(parent),
lEyeWidget(NULL),
rEyeWidget(NULL),
fieldWidget(NULL),
......@@ -55,14 +54,10 @@ MainWindow::MainWindow(QWidget *parent) :
lEyeWidget = new CameraWidget("LeftEye", ImageProcessor::Eye);
lEyeWidget->setWindowIcon(QIcon(":/icons/lEyeWidget.png"));
setupWidget(lEyeWidget, cfg.leftEyeWidgetPos, cfg.leftEyeWidgetSize, cfg.leftEyeWidgetVisible, ui->leftEyeCam);
connect(lEyeWidget, SIGNAL(closed()),
this, SLOT(lEyeWidgetClosed()) );
QThread::msleep(200);
rEyeWidget = new CameraWidget("RightEye", ImageProcessor::Eye);
rEyeWidget->setWindowIcon(QIcon(":/icons/rEyeWidget.png"));
setupWidget(rEyeWidget, cfg.rightEyeWidgetPos, cfg.rightEyeWidgetSize, cfg.rightEyeWidgetVisible, ui->rightEyeCam);
connect(rEyeWidget, SIGNAL(closed()),
this, SLOT(rEyeWidgetClosed()) );
QThread::msleep(200);
fieldWidget = new CameraWidget("Field", ImageProcessor::Field);
fieldWidget->setWindowIcon(QIcon(":/icons/fieldWidget.png"));
......@@ -132,12 +127,26 @@ MainWindow::MainWindow(QWidget *parent) :
connect(this, SIGNAL(startRecording()),
journal, SIGNAL(startRecording()) );
connect(this, SIGNAL(stopRecording()),
journal, SIGNAL(stopRecording()) );
journal, SIGNAL(stopRecording()) );
loadSoundEffect(recStartSound, "rec-start.wav");
loadSoundEffect(recStopSound, "rec-stop.wav");
setupWidget(this, cfg.mainWindowPos, cfg.mainWindowSize, true);
setupWidget(this, cfg.mainWindowPos, cfg.mainWindowSize, true);
// Commands
connect(&commandManager, SIGNAL(toggleCalibration()),
gazeEstimationWidget, SLOT(toggleCalibration()) );
connect(&commandManager, SIGNAL(enableMarkerCollection()),
gazeEstimationWidget, SLOT(enableMarkerCollection()) );
connect(&commandManager, SIGNAL(disableMarkerCollection()),
gazeEstimationWidget, SLOT(disableMarkerCollection()) );
connect(&commandManager, SIGNAL(toggleRecording()),
this, SLOT(toggleRecording()) );
connect(&commandManager, SIGNAL(freezeCameraImages()),
this, SLOT(freezeCameraImages()) );
connect(&commandManager, SIGNAL(unfreezeCameraImages()),
this, SLOT(unfreezeCameraImages()) );
}
MainWindow::~MainWindow()
......@@ -444,35 +453,20 @@ void MainWindow::on_performanceMonitor_clicked()
widgetButtonReact(performanceMonitorWidget, ui->performanceMonitor->isChecked());
}
void MainWindow::keyPressEvent(QKeyEvent *event)
void MainWindow::freezeCameraImages()
{
if (event->isAutoRepeat())
return;
switch (event->key()) {
case Qt::Key_F:
disconnect(gazeEstimationWidget, SIGNAL(outDataTuple(DataTuple)),
fieldWidget, SLOT(preview(DataTuple)) );
break;
default:
break;
}
disconnect(gazeEstimationWidget, SIGNAL(outDataTuple(DataTuple)),
fieldWidget, SLOT(preview(DataTuple)) );
// TODO: freeze eye cameras
}
void MainWindow::keyReleaseEvent(QKeyEvent *event)
void MainWindow::unfreezeCameraImages()
{
if (event->isAutoRepeat())
return;
switch (event->key()) {
case Qt::Key_F:
connect(gazeEstimationWidget, SIGNAL(outDataTuple(DataTuple)),
fieldWidget, SLOT(preview(DataTuple)) );
break;
default:
break;
}
connect(gazeEstimationWidget, SIGNAL(outDataTuple(DataTuple)),
fieldWidget, SLOT(preview(DataTuple)) );
// TODO: unfreeze eye cameras
}
void MainWindow::menuOption(QAction* action)
{
if (action->text().toLower() == "references")
......@@ -546,7 +540,7 @@ void MainWindow::showAboutDialog()
QMessageBox::about(this, "About", msg);
}
void MainWindow::setupWidget(QMainWindow *window, QPoint &position, const QSize &size, const bool &visible, QPushButton *button)
void MainWindow::setupWidget(ERWidget *widget, QPoint &position, const QSize &size, const bool &visible, QPushButton *button)
{
// Sanitize position first
bool inScreen = false;
......@@ -556,14 +550,19 @@ void MainWindow::setupWidget(QMainWindow *window, QPoint &position, const QSize
if (!inScreen)
position = QApplication::desktop()->screenGeometry().topLeft();
window->move(position);
window->resize(size);
widget->move(position);
widget->resize(size);
if (visible)
window->show();
widget->show();
if (button)
button->setChecked(visible);
connect(widget, SIGNAL(keyPress(QKeyEvent*)),
&commandManager, SLOT(keyPress(QKeyEvent*)) );
connect(widget, SIGNAL(keyRelease(QKeyEvent*)),
&commandManager, SLOT(keyRelease(QKeyEvent*)) );
}
void MainWindow::logWidgetClosed() { ui->log->setChecked(false); }
......@@ -572,3 +571,12 @@ void MainWindow::rEyeWidgetClosed() { ui->rightEyeCam->setChecked(false); }
void MainWindow::fieldWidgetClosed() { ui->fieldCam->setChecked(false); }
void MainWindow::gazeEstimationWidgetClosed() { ui->gazeEstimation->setChecked(false); }
void MainWindow::performanceMonitorWidgetClosed() { ui->performanceMonitor->setChecked(false); }
void MainWindow::toggleRecording()
{
if ( ! ui->recordingToggle->isChecked()) {
if (ui->subject->text().isEmpty()) // Unset remote recording
setSubjectName("remote");
}
ui->recordingToggle->click();
}
......@@ -14,6 +14,8 @@
#include <QDesktopWidget>
#include <QDebug>
#include "ERWidget.h"
#include "CameraWidget.h"
#include "Synchronizer.h"
......@@ -25,6 +27,8 @@
#include "LogWidget.h"
#include "PerformanceMonitorWidget.h"
#include "CommandManager.h"
#include "utils.h"
class MainWindowConfig
......@@ -134,7 +138,7 @@ namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
class MainWindow : public ERWidget
{
Q_OBJECT
......@@ -160,7 +164,8 @@ private:
DataRecorderThread *journal;
NetworkStream * networkStream;
LogWidget *logWidget;
PerformanceMonitorWidget *performanceMonitorWidget;
PerformanceMonitorWidget *performanceMonitorWidget;
CommandManager commandManager;
QElapsedTimer elapsedTime;
int elapsedTimeUpdateTimer;
......@@ -173,7 +178,7 @@ private:
void setWorkingDirectory(QString dir);
void widgetButtonReact(QMainWindow *window, bool checked);
void createExtraMenus();
void setupWidget(QMainWindow *window, QPoint &position, const QSize &size, const bool &visible=true, QPushButton *button=NULL);
void setupWidget(ERWidget *widget, QPoint &position, const QSize &size, const bool &visible=true, QPushButton *button=NULL);
protected:
void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE;
......@@ -188,9 +193,7 @@ private slots:
void on_fieldCam_clicked();
void on_gazeEstimation_clicked();
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
void effectiveRecordingStart();
void effectiveRecordingStart();
void menuOption(QAction*);
void showReferencesDialog();
......@@ -198,6 +201,10 @@ private slots:
void on_log_clicked();
void on_performanceMonitor_clicked();
void toggleRecording();
void freezeCameraImages();
void unfreezeCameraImages();
void logWidgetClosed();
void lEyeWidgetClosed();
void rEyeWidgetClosed();
......
......@@ -10,7 +10,7 @@
class Overlay {
protected:
Overlay() { font.setStyleHint(QFont::Monospace); qDebug() << "Called"; }
Overlay() { font.setStyleHint(QFont::Monospace); }
void epilogue(const cv::Mat &frame, QPaintDevice &paintDevice) {
painter.begin(&paintDevice);
scale = { paintDevice.width() / (float) frame.cols, paintDevice.height() / (float) frame.rows };
......
......@@ -4,7 +4,7 @@
using namespace std;
PerformanceMonitorWidget::PerformanceMonitorWidget(QWidget *parent) :
QMainWindow(parent),
ERWidget(parent),
updateTimeMs(250),
formLayout(NULL),
ui(new Ui::PerformanceMonitorWidget)
......
......@@ -8,13 +8,15 @@
#include <QFormLayout>
#include <QLabel>
#include "ERWidget.h"
#include "utils.h"
namespace Ui {
class PerformanceMonitorWidget;
}
class PerformanceMonitorWidget : public QMainWindow
class PerformanceMonitorWidget : public ERWidget
{
Q_OBJECT
......@@ -22,9 +24,6 @@ public:
explicit PerformanceMonitorWidget(QWidget *parent = 0);
~PerformanceMonitorWidget();
signals:
void closed();
private:
Ui::PerformanceMonitorWidget *ui;
......@@ -38,9 +37,6 @@ private:
private slots:
void update();
void on_resetCounters_clicked();
protected:
void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE { Q_UNUSED(event) emit closed(); }
};