You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
327 lines
8.6 KiB
327 lines
8.6 KiB
#include "mainwindow.h"
|
|
#include "ui_mainwindow.h"
|
|
|
|
/*
|
|
* TODO
|
|
* o should we use tick marks in QSlider?
|
|
*/
|
|
|
|
MainWindow::MainWindow(QWidget *parent) :
|
|
QMainWindow(parent),
|
|
ui(new Ui::MainWindow)
|
|
{
|
|
ui->setupUi(this);
|
|
acceptSliderMove = false;
|
|
decoderThread = new DecoderThread();
|
|
setupUI();
|
|
|
|
/* LK_TODO */
|
|
#if 0
|
|
decoder = new Decoder(this);
|
|
connect(this, SIGNAL(onGeometryChanged(int, int, int, int)),
|
|
decoder, SLOT(onGeometryChanged(int, int, int, int)));
|
|
#endif
|
|
|
|
/* register for signals/slots with decoderThread */
|
|
connect(this, SIGNAL(on_geometryChanged(int,int,int,int)),
|
|
decoderThread, SLOT(on_geometryChanged(int,int,int,int)));
|
|
|
|
connect(decoderThread, SIGNAL(on_elapsedtime(int)),
|
|
this, SLOT(on_elapsedTime(int)));
|
|
|
|
connect(decoderThread, SIGNAL(on_decoderErrorMsg(QString, QString)),
|
|
this, SLOT(on_decoderError(QString, QString)));
|
|
|
|
connect(decoderThread, SIGNAL(on_mediaDurationInSeconds(int)),
|
|
this, SLOT(on_mediaDurationInSeconds(int)));
|
|
|
|
connect(this, SIGNAL(on_mediaSeek(int)), decoderThread, SLOT(on_mediaSeek(int)));
|
|
}
|
|
|
|
MainWindow::~MainWindow()
|
|
{
|
|
delete ui;
|
|
}
|
|
|
|
void MainWindow::closeEvent(QCloseEvent *event)
|
|
{
|
|
int rv;
|
|
|
|
rv = QMessageBox::question(this, "Closing application",
|
|
"Do you really want to close vrplayer?",
|
|
QMessageBox::Yes | QMessageBox::No);
|
|
|
|
if (rv == QMessageBox::No)
|
|
{
|
|
event->ignore();
|
|
return;
|
|
}
|
|
decoderThread->exit(0);
|
|
event->accept();
|
|
}
|
|
|
|
void MainWindow::resizeEvent(QResizeEvent *e)
|
|
{
|
|
QRect rect;
|
|
|
|
getVdoGeometry(&rect);
|
|
emit on_geometryChanged(rect.x(), rect.y(), rect.width(), rect.height());
|
|
}
|
|
|
|
void MainWindow::moveEvent(QMoveEvent *e)
|
|
{
|
|
QRect rect;
|
|
|
|
getVdoGeometry(&rect);
|
|
emit on_geometryChanged(rect.x(), rect.y(), rect.width(), rect.height());
|
|
}
|
|
|
|
void MainWindow::setupUI()
|
|
{
|
|
/* setup area to display video */
|
|
lblVideo = new QLabel();
|
|
lblVideo->setMinimumWidth(320);
|
|
lblVideo->setMinimumHeight(200);
|
|
QPalette palette = lblVideo->palette();
|
|
palette.setColor(lblVideo->backgroundRole(), Qt::black);
|
|
palette.setColor(lblVideo->foregroundRole(), Qt::black);
|
|
lblVideo->setAutoFillBackground(true);
|
|
lblVideo->setPalette(palette);
|
|
hboxLayoutTop = new QHBoxLayout;
|
|
hboxLayoutTop->addWidget(lblVideo);
|
|
|
|
/* setup label to display current pos in media */
|
|
lblCurrentPos = new QLabel("00:00:00");
|
|
lblCurrentPos->setMinimumHeight(20);
|
|
lblCurrentPos->setMaximumHeight(20);
|
|
|
|
/* setup slider to seek into media */
|
|
slider = new QSlider();
|
|
slider->setOrientation(Qt::Horizontal);
|
|
slider->setMinimumHeight(20);
|
|
slider->setMaximumHeight(20);
|
|
connect(slider, SIGNAL(actionTriggered(int)), this, SLOT(on_sliderActionTriggered(int)));
|
|
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(on_sliderValueChanged(int)));
|
|
|
|
/* setup label to display media duration */
|
|
lblDuration = new QLabel("00:00:00");
|
|
lblDuration->setMinimumHeight(20);
|
|
lblDuration->setMaximumHeight(20);
|
|
|
|
/* add above three widgets to mid layout */
|
|
hboxLayoutMiddle = new QHBoxLayout;
|
|
hboxLayoutMiddle->addWidget(lblCurrentPos);
|
|
hboxLayoutMiddle->addWidget(slider);
|
|
hboxLayoutMiddle->addWidget(lblDuration);
|
|
|
|
/* setup play button */
|
|
btnPlay = new QPushButton("P");
|
|
btnPlay->setMinimumHeight(40);
|
|
btnPlay->setMaximumHeight(40);
|
|
btnPlay->setMinimumWidth(40);
|
|
btnPlay->setMaximumWidth(40);
|
|
connect(btnPlay, SIGNAL(clicked(bool)), this, SLOT(on_btnPlayClicked(bool)));
|
|
|
|
/* setup stop button */
|
|
btnStop = new QPushButton("S");
|
|
btnStop->setMinimumHeight(40);
|
|
btnStop->setMaximumHeight(40);
|
|
btnStop->setMinimumWidth(40);
|
|
btnStop->setMaximumWidth(40);
|
|
|
|
/* setup rewind button */
|
|
btnRewind = new QPushButton("R");
|
|
btnRewind->setMinimumHeight(40);
|
|
btnRewind->setMaximumHeight(40);
|
|
btnRewind->setMinimumWidth(40);
|
|
btnRewind->setMaximumWidth(40);
|
|
|
|
/* add buttons to bottom panel */
|
|
hboxLayoutBottom = new QHBoxLayout;
|
|
hboxLayoutBottom->addWidget(btnPlay);
|
|
hboxLayoutBottom->addWidget(btnStop);
|
|
hboxLayoutBottom->addWidget(btnRewind);
|
|
hboxLayoutBottom->addStretch();
|
|
|
|
/* add all three layouts to one vertical layout */
|
|
vboxLayout = new QVBoxLayout;
|
|
vboxLayout->addLayout(hboxLayoutTop);
|
|
vboxLayout->addLayout(hboxLayoutMiddle);
|
|
vboxLayout->addLayout(hboxLayoutBottom);
|
|
|
|
/* add all of them to central widget */
|
|
window = new QWidget;
|
|
window->setLayout(vboxLayout);
|
|
this->setCentralWidget(window);
|
|
}
|
|
|
|
void MainWindow::openMediaFile()
|
|
{
|
|
/* TODO take last stored value from QSettings */
|
|
|
|
if (filename.length() == 0)
|
|
{
|
|
/* no previous selection - open user's home folder TODO */
|
|
// TODO filename = QFileDialog::getOpenFileName(this, "Select Media File", "/");
|
|
filename = QFileDialog::getOpenFileName(this, "Select Media File", "/home/lk/vbox_share");
|
|
}
|
|
else
|
|
{
|
|
/* show last selected file */
|
|
filename = QFileDialog::getOpenFileName(this, "Select Media File",
|
|
filename);
|
|
}
|
|
decoderThread->setFilename(filename);
|
|
}
|
|
|
|
void MainWindow::getVdoGeometry(QRect *rect)
|
|
{
|
|
int x = geometry().x() + lblVideo->geometry().x();
|
|
|
|
int y = pos().y() + lblVideo->geometry().y() +
|
|
ui->mainToolBar->geometry().height() * 4 + 10;
|
|
|
|
rect->setX(x);
|
|
rect->setY(y);
|
|
rect->setWidth(lblVideo->geometry().width());
|
|
rect->setHeight(lblVideo->geometry().height());
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* actions and slots go here *
|
|
******************************************************************************/
|
|
|
|
void MainWindow::on_actionOpen_Media_File_triggered()
|
|
{
|
|
openMediaFile();
|
|
}
|
|
|
|
void MainWindow::on_actionExit_triggered()
|
|
{
|
|
/* TODO: confirm app exit */
|
|
this->close();
|
|
}
|
|
|
|
void MainWindow::on_actionPlay_Media_triggered()
|
|
{
|
|
// LK_TODO do we need this? if yes, should be same as on_btnPlayClicked()
|
|
#if 1
|
|
decoderThread->start();
|
|
#else
|
|
if (!decoder)
|
|
return;
|
|
|
|
decoder->init(filename);
|
|
#endif
|
|
}
|
|
|
|
void MainWindow::on_decoderError(QString title, QString msg)
|
|
{
|
|
QMessageBox::information(this, title, msg);
|
|
}
|
|
|
|
void MainWindow::on_btnPlayClicked(bool flag)
|
|
{
|
|
if (filename.length() == 0)
|
|
openMediaFile();
|
|
|
|
decoderThread->start();
|
|
}
|
|
|
|
void MainWindow::on_mediaDurationInSeconds(int duration)
|
|
{
|
|
int hours = 0;
|
|
int minutes = 0;
|
|
int secs = 0;
|
|
char buf[20];
|
|
|
|
/* setup progress bar */
|
|
slider->setMinimum(0);
|
|
slider->setMaximum(duration * 100); /* in hundredth of a sec */
|
|
slider->setValue(0);
|
|
|
|
/* convert from seconds to hours:minutes:seconds */
|
|
hours = duration / 3600;
|
|
if (hours)
|
|
duration -= (hours * 3600);
|
|
|
|
minutes = duration / 60;
|
|
if (minutes)
|
|
duration -= minutes * 60;
|
|
|
|
secs = duration;
|
|
|
|
sprintf(buf, "%.2d:%.2d:%.2d", hours, minutes, secs);
|
|
lblDuration->setText(QString(buf));
|
|
}
|
|
|
|
/**
|
|
* time elapsed in 1/100th sec units since play started
|
|
******************************************************************************/
|
|
void MainWindow::on_elapsedTime(int val)
|
|
{
|
|
int hours = 0;
|
|
int minutes = 0;
|
|
int secs = 0;
|
|
int duration = val / 100;
|
|
char buf[20];
|
|
|
|
/* if slider bar is down, do not update */
|
|
if (slider->isSliderDown())
|
|
return;
|
|
|
|
/* update progress bar */
|
|
slider->setSliderPosition(val);
|
|
|
|
/* convert from seconds to hours:minutes:seconds */
|
|
hours = duration / 3600;
|
|
if (hours)
|
|
duration -= (hours * 3600);
|
|
|
|
minutes = duration / 60;
|
|
if (minutes)
|
|
duration -= minutes * 60;
|
|
|
|
secs = duration;
|
|
|
|
/* update current position in progress bar */
|
|
sprintf(buf, "%.2d:%.2d:%.2d", hours, minutes, secs);
|
|
lblCurrentPos->setText(QString(buf));
|
|
}
|
|
|
|
void MainWindow::on_sliderValueChanged(int value)
|
|
{
|
|
if (acceptSliderMove)
|
|
{
|
|
acceptSliderMove = false;
|
|
emit on_mediaSeek(value / 100);
|
|
}
|
|
}
|
|
|
|
void MainWindow::on_sliderActionTriggered(int action)
|
|
{
|
|
switch (action)
|
|
{
|
|
case QAbstractSlider::SliderPageStepAdd:
|
|
acceptSliderMove = true;
|
|
break;
|
|
|
|
case QAbstractSlider::SliderPageStepSub:
|
|
acceptSliderMove = true;
|
|
break;
|
|
|
|
case QAbstractSlider::SliderMove:
|
|
if (slider->isSliderDown())
|
|
acceptSliderMove = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
#if 1
|
|
// LK_TODO delete this
|
|
void MainWindow::mouseMoveEvent(QMouseEvent *e)
|
|
{
|
|
//qDebug() << "mouseMoveEvent: x=" << e->globalX() << "y=" << e->globalY();
|
|
}
|
|
#endif
|