From 9a1a798f92708ac5c5b152ef36b503aa907769b3 Mon Sep 17 00:00:00 2001 From: APTX Date: Sat, 16 Feb 2013 18:20:17 +0100 Subject: [PATCH] Port more things --- aniplayer2/aniplayer.cpp | 80 +++- aniplayer2/aniplayer.h | 50 ++- aniplayer2/videowidget.cpp | 27 +- aniplayer2/videowidget.h | 10 + aniplayer2_dshow/aniplayerdshow.cpp | 61 +++- aniplayer2_dshow/aniplayerdshow.h | 18 +- aniplayer2_dshow/aniplayerdshowinternal.cpp | 114 +++++- aniplayer2_dshow/aniplayerdshowinternal.h | 14 +- aniplayer2_dshow/videowidgetdshow.cpp | 25 ++ aniplayer2_dshow/videowidgetdshow.h | 3 + player/mainwindow.cpp | 385 +++++++++++++++++++- player/mainwindow.h | 54 ++- player/mainwindow.ui | 25 +- player/player.pro | 11 +- 14 files changed, 811 insertions(+), 66 deletions(-) diff --git a/aniplayer2/aniplayer.cpp b/aniplayer2/aniplayer.cpp index 4937394..cb750cc 100644 --- a/aniplayer2/aniplayer.cpp +++ b/aniplayer2/aniplayer.cpp @@ -14,30 +14,98 @@ AniPlayer::State AniPlayer::state() const return m_state; } -void AniPlayer::open(const QString &file) +QString AniPlayer::currentFile() const { - iopen(file); + return m_currentFile; +} + +bool AniPlayer::open(const QString &file) +{ + if (file == m_currentFile) + return true; + + if (!iopen(file)) + return false; + + setState(Stopped); + m_currentFile = file; + emit currentFileChanged(m_currentFile); + emit totalTimeChanged(totalTime()); + return true; } void AniPlayer::play() { - iplay(); + if (state() == Paused || state() == Stopped) + if (iplay()) + setState(Playing); } void AniPlayer::pause() { - ipause(); + if (state() != Playing) + return; + + if (ipause()) + setState(Paused); } void AniPlayer::stop() { - istop(); + if (state() == Playing || state() == Paused) + if (istop()) + setState(Stopped); } void AniPlayer::togglePause() { - if (m_state == Paused) + if (state() == Paused) play(); else pause(); } + +bool AniPlayer::seek(qint64 position) +{ + return iseek(position); +} + +void AniPlayer::skip(qint64 msec) +{ + seek(currentTime() + msec); +} + +bool AniPlayer::setVolume(double percent) +{ + return isetVolume(percent); +} + +void AniPlayer::volumeUp(int by) +{ + double newVolume = qBound(double(0), volume() + double(by) * 0.01, double(1.0)); + setVolume(newVolume); +} + +void AniPlayer::volumeDown(int by) +{ + double newVolume = qBound(double(0), volume() - double(by) * 0.01, double(1.0)); + setVolume(newVolume); +} + +void AniPlayer::changeVolume(int by) +{ + double newVolume = qBound(double(0), volume() + double(by) * 0.01, double(1.0)); + setVolume(newVolume); +} + + +void AniPlayer::setState(AniPlayer::State newState) +{ + if (m_state == newState) + return; + + State oldState = m_state; + m_state = newState; + emit stateChanged(newState); + emit stateChanged(newState, oldState); +} diff --git a/aniplayer2/aniplayer.h b/aniplayer2/aniplayer.h index 6601c6d..418c1bd 100644 --- a/aniplayer2/aniplayer.h +++ b/aniplayer2/aniplayer.h @@ -5,12 +5,20 @@ #include #include +#include class VideoWidget; class ANIPLAYER2SHARED_EXPORT AniPlayer : public QObject { Q_OBJECT + Q_PROPERTY(State state READ state NOTIFY stateChanged) + Q_PROPERTY(qint64 currentTime READ currentTime WRITE seek STORED false) + Q_PROPERTY(qint64 totalTime READ totalTime STORED false) + Q_PROPERTY(double volume READ volume WRITE setVolume NOTIFY volumeChanged STORED false) + Q_PROPERTY(QSize videoSize READ videoSize) + Q_PROPERTY(QString currentFile READ currentFile NOTIFY currentFileChanged) + public: enum State { @@ -25,25 +33,57 @@ public: virtual VideoWidget *videoWidget() = 0; virtual void widgetChanged() = 0; + virtual void handleNotifications() = 0; State state() const; + virtual qint64 currentTime() const = 0; + virtual qint64 totalTime() const = 0; + + virtual double volume() const = 0; + + virtual QSize videoSize() const = 0; + + QString currentFile() const; + public slots: - void open(const QString &file); + bool open(const QString &file); void play(); void pause(); void stop(); void togglePause(); + bool seek(qint64 position); + void skip(qint64 msec = 85000); + + + bool setVolume(double percent); + void volumeUp(int by = 5); + void volumeDown(int by = 5); + void changeVolume(int by = 5); + +signals: + void stateChanged(AniPlayer::State newState); + void stateChanged(AniPlayer::State newState, AniPlayer::State oldState); + void volumeChanged(double newPercent); + void currentFileChanged(QString file); + + void totalTimeChanged(qint64 newTotalTime); protected: - virtual void iopen(const QString &file) = 0; - virtual void iplay() = 0; - virtual void ipause() = 0; - virtual void istop() = 0; + virtual bool iopen(const QString &file) = 0; + virtual bool iplay() = 0; + virtual bool ipause() = 0; + virtual bool istop() = 0; + + virtual bool iseek(qint64) = 0; + virtual bool isetVolume(double) = 0; + + void setState(State newState); State m_state; + QString m_currentFile; }; #endif // ANIPLAYER_H diff --git a/aniplayer2/videowidget.cpp b/aniplayer2/videowidget.cpp index de69e87..e3beeae 100644 --- a/aniplayer2/videowidget.cpp +++ b/aniplayer2/videowidget.cpp @@ -1,6 +1,31 @@ #include "videowidget.h" VideoWidget::VideoWidget(QWidget *parent) : - QWidget(parent) + QWidget(parent), m_fullScreen(false) { } + +bool VideoWidget::isFullScreen() const +{ + return m_fullScreen; +} + + +void VideoWidget::setFullScreen(bool fullScreen) +{ + if (m_fullScreen == fullScreen) + return; + + if (fullScreen) + window()->showFullScreen(); + else + window()->showNormal(); + + m_fullScreen = fullScreen; + emit fullScreenChanged(fullScreen); +} + +void VideoWidget::toggleFullScreen() +{ + setFullScreen(!isFullScreen()); +} diff --git a/aniplayer2/videowidget.h b/aniplayer2/videowidget.h index 67648ad..64b0075 100644 --- a/aniplayer2/videowidget.h +++ b/aniplayer2/videowidget.h @@ -4,16 +4,26 @@ #include "aniplayer2_global.h" #include +class AniPlayer; + class ANIPLAYER2SHARED_EXPORT VideoWidget : public QWidget { Q_OBJECT + Q_PROPERTY(bool fullScreen READ isFullScreen WRITE setFullScreen NOTIFY fullScreenChanged) public: explicit VideoWidget(QWidget *parent = 0); + bool isFullScreen() const; + signals: + void fullScreenChanged(bool arg); public slots: + void setFullScreen(bool fullScreen); + void toggleFullScreen(); +protected: + bool m_fullScreen; }; #endif // VIDEOWIDGET_H diff --git a/aniplayer2_dshow/aniplayerdshow.cpp b/aniplayer2_dshow/aniplayerdshow.cpp index 63e6f34..67e603e 100644 --- a/aniplayer2_dshow/aniplayerdshow.cpp +++ b/aniplayer2_dshow/aniplayerdshow.cpp @@ -23,6 +23,11 @@ AniPlayerDShow::~AniPlayerDShow() CoUninitialize(); } +QSize AniPlayerDShow::videoSize() const +{ + return d->videoSize(); +} + VideoWidget *AniPlayerDShow::videoWidget() { return m_videoWidget; @@ -34,30 +39,56 @@ void AniPlayerDShow::widgetChanged() d->Repaint(); } -void AniPlayerDShow::iopen(const QString &file) +void AniPlayerDShow::handleNotifications() +{ + d->handleNotifications(); +} + +qint64 AniPlayerDShow::currentTime() const +{ + return d->currentTime(); +} + +qint64 AniPlayerDShow::totalTime() const +{ + return d->totalTime(); +} + +double AniPlayerDShow::volume() const +{ + return d->volume(); +} + +bool AniPlayerDShow::iopen(const QString &file) +{ + if (!d->OpenFile(reinterpret_cast(file.utf16()))) + return false; + d->Repaint(); + d->UpdateVideoWindow(0); + return true; +} + +bool AniPlayerDShow::iplay() { - d->OpenFile(reinterpret_cast(file.utf16())); + return d->play(); } -void AniPlayerDShow::iplay() +bool AniPlayerDShow::ipause() { - if (m_state == Paused || m_state == Stopped) - if (d->play()) - m_state = Playing; + return d->pause(); } -void AniPlayerDShow::ipause() +bool AniPlayerDShow::istop() { - if (m_state != Playing) - return; + return d->stop(); +} - if (d->pause()) - m_state = Paused; +bool AniPlayerDShow::iseek(qint64 position) +{ + return d->seek(position); } -void AniPlayerDShow::istop() +bool AniPlayerDShow::isetVolume(double volume) { - if (m_state == Playing || m_state == Paused) - if (d->stop()) - m_state = Stopped; + return d->setVolume(volume); } diff --git a/aniplayer2_dshow/aniplayerdshow.h b/aniplayer2_dshow/aniplayerdshow.h index 6b6f4ac..6d176d7 100644 --- a/aniplayer2_dshow/aniplayerdshow.h +++ b/aniplayer2_dshow/aniplayerdshow.h @@ -15,17 +15,27 @@ public: explicit AniPlayerDShow(QObject *parent = 0); ~AniPlayerDShow(); + QSize videoSize() const; + VideoWidget *videoWidget(); void widgetChanged(); + void handleNotifications(); + + qint64 currentTime() const; + qint64 totalTime() const; + double volume() const; signals: protected: - void iopen(const QString &file); - void iplay(); - void ipause(); - void istop(); + bool iopen(const QString &file); + bool iplay(); + bool ipause(); + bool istop(); + + bool iseek(qint64 position); + bool isetVolume(double volume); private: AniPlayerDShowInternal *d; diff --git a/aniplayer2_dshow/aniplayerdshowinternal.cpp b/aniplayer2_dshow/aniplayerdshowinternal.cpp index 51fe5cd..f181be6 100644 --- a/aniplayer2_dshow/aniplayerdshowinternal.cpp +++ b/aniplayer2_dshow/aniplayerdshowinternal.cpp @@ -20,14 +20,13 @@ AniPlayerDShowInternal::AniPlayerDShowInternal(AniPlayerDShow *player_) : player pEVR = 0; pVideoDisplay = 0; + + pAudioControl = 0; } AniPlayerDShowInternal::~AniPlayerDShowInternal() { - SafeRelease(&pControl); - SafeRelease(&pEvent); - SafeRelease(&pGraph); - SafeRelease(&pSeeking) + TearDownGraph(); } bool AniPlayerDShowInternal::play() @@ -61,6 +60,85 @@ QSize AniPlayerDShowInternal::videoSize() const return QSize(nativeSize.cx, nativeSize.cy); } +qint64 AniPlayerDShowInternal::totalTime() const +{ + HRESULT hr = pSeeking->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME); + if (FAILED(hr)) + return -1; + + LONGLONG currentPos, stopPos; + hr = pSeeking->GetPositions(¤tPos, &stopPos); + if (FAILED(hr)) + return -1; + + // Positions are in 100-nanoseconds, convert to miliseconds + return static_cast(stopPos / 10000); +} + +qint64 AniPlayerDShowInternal::currentTime() const +{ + HRESULT hr = pSeeking->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME); + if (FAILED(hr)) + return -1; + + LONGLONG currentPos, stopPos; + hr = pSeeking->GetPositions(¤tPos, &stopPos); + if (FAILED(hr)) + return -1; + + // Positions are in 100-nanoseconds, convert to miliseconds + return static_cast(currentPos / 10000); +} + +bool AniPlayerDShowInternal::seek(qint64 position) +{ + // Positions are in 100-nanoseconds, convert from miliseconds + position *= 10000; + + HRESULT hr = pSeeking->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME); + if (FAILED(hr)) + return false; + + LONGLONG seekPos = static_cast(position); + + hr = pSeeking->SetPositions(&seekPos, AM_SEEKING_AbsolutePositioning, + NULL, AM_SEEKING_NoPositioning); + if (FAILED(hr)) + return false; + + return true; +} + +double AniPlayerDShowInternal::volume() const +{ + long lvolume; + + HRESULT hr = pAudioControl->get_Volume(&lvolume); + if (FAILED(hr)) + return -1; + + double currentVolume = double(-lvolume) / 10000.0; + currentVolume = 1 - currentVolume; + + return currentVolume; +} + +bool AniPlayerDShowInternal::setVolume(double volume) +{ + volume = 1 - volume; + long lvolume = -long(volume * 10000.0); + + HRESULT hr = pAudioControl->put_Volume(lvolume); + if (FAILED(hr)) + return false; + + return true; +} + +void AniPlayerDShowInternal::handleNotifications() +{ +} + HRESULT AniPlayerDShowInternal::InitializeGraph() { TearDownGraph(); @@ -79,6 +157,18 @@ HRESULT AniPlayerDShowInternal::InitializeGraph() goto done; } + hr = pGraph->QueryInterface(IID_PPV_ARGS(&pSeeking)); + if (FAILED(hr)) + { + goto done; + } + + hr = pGraph->QueryInterface(IID_PPV_ARGS(&pAudioControl)); + if (FAILED(hr)) + { + goto done; + } + hr = pGraph->QueryInterface(IID_PPV_ARGS(&pEvent)); if (FAILED(hr)) { @@ -111,6 +201,7 @@ void AniPlayerDShowInternal::TearDownGraph() SafeRelease(&pControl); SafeRelease(&pEvent); SafeRelease(&pSeeking); + SafeRelease(&pAudioControl); // delete m_pVideo; // pVideo = NULL; @@ -222,16 +313,16 @@ HRESULT AniPlayerDShowInternal::RemoveUnconnectedRenderer(IGraphBuilder *pGraph, HRESULT AniPlayerDShowInternal::AddVideoRenderer() { - IBaseFilter *npEVR = NULL; + IBaseFilter *newpEVR = NULL; - HRESULT hr = AddFilterByCLSID(pGraph, CLSID_EnhancedVideoRenderer, &npEVR, L"EVR"); + HRESULT hr = AddFilterByCLSID(pGraph, CLSID_EnhancedVideoRenderer, &newpEVR, L"EVR"); if (FAILED(hr)) { goto done; } - hr = InitializeEVR(npEVR, &pVideoDisplay); + hr = InitializeEVR(newpEVR, &pVideoDisplay); if (FAILED(hr)) { goto done; @@ -241,11 +332,11 @@ HRESULT AniPlayerDShowInternal::AddVideoRenderer() // you cannot QI the pointer to get back the IBaseFilter pointer. // Therefore, we need to cache the IBaseFilter pointer. - pEVR = npEVR; + pEVR = newpEVR; pEVR->AddRef(); done: - SafeRelease(&npEVR); + SafeRelease(&newpEVR); return hr; } @@ -256,7 +347,7 @@ HRESULT AniPlayerDShowInternal::CreateVideoRenderer() return hr; } -HRESULT AniPlayerDShowInternal::OpenFile(PCWSTR pszFileName) +bool AniPlayerDShowInternal::OpenFile(PCWSTR pszFileName) { IBaseFilter *pSource = NULL; @@ -283,7 +374,7 @@ done: TearDownGraph(); } SafeRelease(&pSource); - return hr; + return SUCCEEDED(hr); } HRESULT AniPlayerDShowInternal::Repaint() @@ -311,7 +402,6 @@ HRESULT AniPlayerDShowInternal::UpdateVideoWindow(const LPRECT prc) } else { - RECT rc; GetClientRect(hwnd(), &rc); return pVideoDisplay->SetVideoPosition(NULL, &rc); diff --git a/aniplayer2_dshow/aniplayerdshowinternal.h b/aniplayer2_dshow/aniplayerdshowinternal.h index 8a72dfe..fe4274a 100644 --- a/aniplayer2_dshow/aniplayerdshowinternal.h +++ b/aniplayer2_dshow/aniplayerdshowinternal.h @@ -13,6 +13,7 @@ struct IMediaControl; struct IMediaEvent; struct IMediaSeeking; struct IMFVideoDisplayControl; +struct IBasicAudio; struct AniPlayerDShowInternal { @@ -26,6 +27,15 @@ public: QSize videoSize() const; + qint64 totalTime() const; + qint64 currentTime() const; + bool seek(qint64 position); + + double volume() const; + bool setVolume(double volume); + + void handleNotifications(); + HRESULT InitializeGraph(); void TearDownGraph(); HRESULT CreateVideoRenderer(); @@ -37,7 +47,7 @@ public: HRESULT AddVideoRenderer(); HRESULT FinalizeGraph(); - HRESULT OpenFile(PCWSTR pszFileName); + bool OpenFile(PCWSTR pszFileName); IGraphBuilder *pGraph; IMediaControl *pControl; @@ -47,6 +57,8 @@ public: IBaseFilter *pEVR; IMFVideoDisplayControl *pVideoDisplay; + IBasicAudio *pAudioControl; + HRESULT Repaint(); HRESULT UpdateVideoWindow(const LPRECT prc); diff --git a/aniplayer2_dshow/videowidgetdshow.cpp b/aniplayer2_dshow/videowidgetdshow.cpp index 41cc994..5fec830 100644 --- a/aniplayer2_dshow/videowidgetdshow.cpp +++ b/aniplayer2_dshow/videowidgetdshow.cpp @@ -1,6 +1,9 @@ #include "videowidgetdshow.h" #include "aniplayerdshow.h" +#ifdef Q_OS_WIN +# include +#endif VideoWidgetDShow::VideoWidgetDShow(AniPlayerDShow *player_, QWidget *parent) : VideoWidget(parent), player(player_) @@ -12,8 +15,30 @@ VideoWidgetDShow::VideoWidgetDShow(AniPlayerDShow *player_, QWidget *parent) : setAutoFillBackground(false); } +QSize VideoWidgetDShow::sizeHint() const +{ + return player->videoSize(); +} + void VideoWidgetDShow::resizeEvent(QResizeEvent *e) { player->widgetChanged(); VideoWidget::resizeEvent(e); } + +bool VideoWidgetDShow::nativeEvent(const QByteArray &eventType, void *message, long *result) +{ +#ifdef Q_OS_WIN + if (eventType != "windows_generic_MSG") + return false; + + MSG *msg = static_cast(message); + if (msg->message != WM_APP + 1) + return false; +// player->ha + *result = 0; + return true; +#else + return false; +#endif +} diff --git a/aniplayer2_dshow/videowidgetdshow.h b/aniplayer2_dshow/videowidgetdshow.h index 1d36cfd..399349a 100644 --- a/aniplayer2_dshow/videowidgetdshow.h +++ b/aniplayer2_dshow/videowidgetdshow.h @@ -16,12 +16,15 @@ public: { return 0; } + + QSize sizeHint() const; signals: public slots: protected: void resizeEvent(QResizeEvent *e); + bool nativeEvent(const QByteArray &eventType, void *message, long *result); private: AniPlayerDShow *player; diff --git a/player/mainwindow.cpp b/player/mainwindow.cpp index 2c7dbef..42ee150 100644 --- a/player/mainwindow.cpp +++ b/player/mainwindow.cpp @@ -1,32 +1,405 @@ #include "mainwindow.h" #include "ui_mainwindow.h" +#include +#include +#include +#include + #ifdef Q_OS_WIN # include +# include #endif #include +#include "menu.h" +#include "seekslider.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { + dragged = mouseMoved = false; + player = new AniPlayerDShow(this); - player->open("E:/Anime/Accel World OVA/Accel World OVA - 01 - OVA - [UTW][3e56ee18].mkv"); - player->play(); ui->setupUi(this); - QAction *a = new QAction("Pause", this); - a->setShortcut(QKeySequence("Space")); - connect(a, SIGNAL(triggered()), player, SLOT(togglePause())); - addAction(a); + addAction("open", "&Open...", QKeySequence::Open); + addAction("play", "Play", style()->standardIcon(QStyle::SP_MediaPlay), QKeySequence("P")); + addAction("pause", "Pause", style()->standardIcon(QStyle::SP_MediaPause), QKeySequence("W")); + addAction("stop", "Stop", style()->standardIcon(QStyle::SP_MediaStop), QKeySequence("X")); + addAction("previous", "Previous", style()->standardIcon(QStyle::SP_MediaSkipBackward), QKeySequence("CTRL+,")); + addAction("next", "Next", style()->standardIcon(QStyle::SP_MediaSkipForward), QKeySequence("CTRL+.")); + addAction("toggleStayOnTop", "Stay on top", QKeySequence("T"), true); + addAction("toggleFrameless", "Frameless", QKeySequence("Y"), true); + addAction("toggleOverlay", "Overlay", QKeySequence("U"), true); + + m_actions["toggleStayOnTop"]->setChecked(false); + m_actions["toggleFrameless"]->setChecked(false); + m_actions["toggleOverlay"]->setChecked(false); + + addAction("markWatched", "Mark Watched", QKeySequence("CTRL+M")); + addAction("settings", "Settings", QKeySequence("F7")); + + addAction("about", "About", QKeySequence()); + + menu = new Menu(this); + menu->addActions(QWidget::actions()); +/* tray->setContextMenu(new QMenu); + tray->contextMenu()->addActions(QWidget::actions()); + tray->setIcon(QIcon(":/icon.png")); + tray->show(); +*/ + addAction("togglePlay", "Play/Pause", QKeySequence(" ")); + addAction("volUp", "Volume Up", QKeySequence("+")); + addAction("volDown", "Volume Down", QKeySequence("-")); + + addAction("opSkip", "OP/ED Skip", QKeySequence("/")); + addAction("back1sec", "Back 1 second", QKeySequence("m")); + + connect(player, SIGNAL(stateChanged(AniPlayer::State, AniPlayer::State)), this, SLOT(handleStateChange(AniPlayer::State,AniPlayer::State))); +// connect(videoPlayer->mediaController(), SIGNAL(availableSubtitlesChanged()), this, SLOT(updateSubtitles())); +// connect(m_actions["markWatched"], SIGNAL(triggered()), this, SLOT(markWatched())); +// connect(m_actions["settings"], SIGNAL(triggered()), this, SLOT(anidbSettings())); +// connect(m_actions["about"], SIGNAL(triggered()), this, SLOT(about())); + + connect(m_actions["open"], SIGNAL(triggered()), this, SLOT(open())); + connect(m_actions["play"], SIGNAL(triggered()), player, SLOT(play())); + connect(m_actions["togglePlay"], SIGNAL(triggered()), player, SLOT(togglePause())); + connect(m_actions["pause"], SIGNAL(triggered()), player, SLOT(pause())); + connect(m_actions["stop"], SIGNAL(triggered()), player, SLOT(stop())); + +// connect(m_actions["toggleStayOnTop"], SIGNAL(toggled(bool)), this, SLOT(toggleStayOnTop())); +// connect(m_actions["toggleFrameless"], SIGNAL(toggled(bool)), this, SLOT(toggleFrameless())); +// connect(m_actions["toggleOverlay"], SIGNAL(toggled(bool)), this, SLOT(toggleOverlay())); + + connect(m_actions["volUp"], SIGNAL(triggered()), player, SLOT(volumeUp())); + connect(m_actions["volDown"], SIGNAL(triggered()), player, SLOT(volumeDown())); + + connect(m_actions["opSkip"], SIGNAL(triggered()), this, SLOT(opSkip())); + connect(m_actions["back1sec"], SIGNAL(triggered()), this, SLOT(skipback())); + +// connect(videoPlayer->videoWidget(), SIGNAL(menuToggleRequested()), this, SLOT(toggleMenu())); + +// connect(m_actions["next"], SIGNAL(triggered()), playlist, SLOT(next())); +// connect(m_actions["previous"], SIGNAL(triggered()), playlist, SLOT(previous())); + connect(player, SIGNAL(totalTimeChanged(qint64)), menu->seekSlider(), SLOT(totalTimeChanged(qint64))); + connect(menu->seekSlider(), SIGNAL(seekRequested(qint64)), player, SLOT(seek(qint64))); setCentralWidget(player->videoWidget()); + + open("E:/Anime/Accel World OVA/Accel World OVA - 01 - OVA - [UTW][3e56ee18].mkv"); + } MainWindow::~MainWindow() { delete ui; } + +bool MainWindow::open() +{ + QString dir; + + if (player->currentFile() == "") + { + dir = QStandardPaths::writableLocation(QStandardPaths::MoviesLocation); + } + else + { + QFileInfo fileInfo(player->currentFile()); + QDir dirObj = fileInfo.absoluteDir(); + while (!dirObj.exists()) + dirObj = dirObj.absolutePath() + "/.."; + + dir = dirObj.absolutePath(); + } + + QString file = QFileDialog::getOpenFileName( + this, + tr("Open media"), + dir, + tr("Video files (*.mkv *.mp4 *.ogg *.ogm *.wmv *.avi *.mpg *.flv);;All files (*)") + ); + + if (file == "") + return false; + + play(file); + return true; +} + +bool MainWindow::open(const QString &file) +{ + if (file == "") + return false; + + QFileInfo fileInfo(file); + if (!fileInfo.exists()) + { + menu->showMessage(tr("File %1 does not exist").arg(file)); + return false; + } + +// playlist->setDirectory(fileInfo.absoluteDir()); +// playlist->setCurrent(playlist->indexOfFile(file)); + + menu->showMessage(tr("Opening: %1").arg(file)); + + player->open(file); + +// updateAutomarkable(); + + updateWindowTitle(fileInfo); + return true; +} + +void MainWindow::play() +{ + if (player->currentFile().isEmpty()) + { + if (!open()) + return; + } + + player->play(); +} + +void MainWindow::play(const QString &file) +{ + open(file); + play(); +} + +void MainWindow::skipback() +{ + player->skip(-1000); +} + +void MainWindow::opSkip() +{ + player->skip(/*m_opSkip*/85 * 1000); +} + +void MainWindow::toggleMenu() +{ + menu->setVisible(!menu->isVisible()); + updateCursor(); +} + +void MainWindow::resizeToVideo() +{ + resize(player->videoWidget()->sizeHint()); +} + +void MainWindow::toggleStayOnTop() +{ + updateWindowFlags(); +} + +void MainWindow::toggleFrameless() +{ + updateWindowFlags(); +} + +void MainWindow::toggleOverlay() +{ + updateWindowFlags(); +} + +void MainWindow::about() +{ +// VersionDialog dialog(this); + // dialog.exec(); +} + +void MainWindow::handleStateChange(AniPlayer::State newState, AniPlayer::State oldState) +{ + Q_UNUSED(oldState); + + switch(newState) + { + case AniPlayer::Error: + //menu->showMessage(playerlayer->errorString()); + + m_actions["play"]->setDisabled(false); + m_actions["pause"]->setDisabled(true); + m_actions["stop"]->setDisabled(true); + break; + case AniPlayer::Stopped: + m_actions["play"]->setDisabled(false); + m_actions["pause"]->setDisabled(true); + m_actions["stop"]->setDisabled(true); + + break; + case AniPlayer::Playing: + m_actions["play"]->setDisabled(true); + m_actions["pause"]->setDisabled(false); + m_actions["stop"]->setDisabled(false); + break; + case AniPlayer::Paused: + m_actions["play"]->setDisabled(false); + m_actions["pause"]->setDisabled(true); + m_actions["stop"]->setDisabled(false); + break; + default: + break; + } +} + +void MainWindow::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) + { + dragPosition = event->globalPos() - frameGeometry().topLeft(); + dragged = true; + event->accept(); + } +} + +void MainWindow::mouseMoveEvent(QMouseEvent *event) +{ + mouseMoved = true; + if (!dragged) + return; + + if (event->buttons() & Qt::LeftButton) + { + move(event->globalPos() - dragPosition); + event->accept(); + } +} + +void MainWindow::mouseReleaseEvent(QMouseEvent *event) +{ + dragged = false; + if (mouseMoved) + { + mouseMoved = false; + return; + } + + if (event->button() == Qt::LeftButton) + { + toggleMenu(); + event->accept(); + } + else if (event->button() == Qt::RightButton) + { + + player->videoWidget()->toggleFullScreen(); + updateCursor(); + + event->accept(); + } + else + { + QMainWindow::mouseReleaseEvent(event); + } +} + +void MainWindow::moveEvent(QMoveEvent *event) +{ + QMainWindow::moveEvent(event); +} + +void MainWindow::resizeEvent(QResizeEvent *event) +{ + QMainWindow::resizeEvent(event); +} + +void MainWindow::wheelEvent(QWheelEvent *event) +{ + // Wheel Up + if (event->delta() > 0) + player->changeVolume(5); + // Wheel Down + else + player->changeVolume(-5); + + event->accept(); +} + + +void MainWindow::addAction(const QString &name, const QString &text, const QKeySequence &shortcut, bool checkable) +{ + QAction *action = new QAction(text, this); + action->setShortcut(shortcut); + action->setCheckable(checkable); + QWidget::addAction(action); + m_actions[name] = action; +} + +void MainWindow::addAction(const QString &name, const QString &text, const QIcon& icon, const QKeySequence &shortcut, bool checkable) +{ + QAction *action = new QAction(text, this); + action->setIcon(icon); + action->setShortcut(shortcut); + action->setCheckable(checkable); + QWidget::addAction(action); + m_actions[name] = action; +} + +void MainWindow::updateWindowTitle(const QFileInfo &file) +{ + static const QString appTitle = qApp->applicationName() + QLatin1String(" v") + qApp->applicationVersion(); + if (!file.exists()) + { + setWindowTitle(appTitle); + return; + } + setWindowTitle(file.fileName() + QLatin1Char(' ') + QChar(0x2014) + QLatin1Char(' ') + appTitle); + setWindowFilePath(file.absoluteFilePath()); +} + +void MainWindow::updateCursor() +{ +#ifdef Q_WS_X11 + if (isFullScreen() && menu->isHidden()) + setCursor(QCursor(Qt::BlankCursor)); + else + setCursor(QCursor(Qt::ArrowCursor)); +#else +// if (videoPlayer->videoWidget()->isFullScreen() && menu->isHidden()) +// videoPlayer->videoWidget()->setCursor(QCursor(Qt::BlankCursor)); +// else +// videoPlayer->videoWidget()->setCursor(QCursor(Qt::ArrowCursor)); +#endif +} + +void MainWindow::updateWindowFlags() +{ + if (m_actions["toggleStayOnTop"]->isChecked()) + setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); + else + setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint); + +#ifdef Q_WS_X11 + bool menuVisible = menu->isVisible(); + menu->setWindowFlags(menu->windowFlags() ^ Qt::WindowStaysOnTopHint); + menu->setVisible(menuVisible); +#endif + + if (m_actions["toggleFrameless"]->isChecked()) + setWindowFlags((windowFlags() & (Qt::Window | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint)) | Qt::FramelessWindowHint); + else + setWindowFlags((windowFlags() & (Qt::Window | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint)) & ~Qt::FramelessWindowHint); + + +#ifdef Q_OS_WIN + if (m_actions["toggleOverlay"]->isChecked()) + { + setWindowOpacity(.5); + SetWindowLongPtr((HWND) winId(), GWL_EXSTYLE, GetWindowLongPtr((HWND) winId(), GWL_EXSTYLE) | WS_EX_LAYERED | WS_EX_TRANSPARENT); + } + else + { + setWindowOpacity(1); + SetWindowLongPtr((HWND) winId(), GWL_EXSTYLE, GetWindowLongPtr((HWND) winId(), GWL_EXSTYLE) & ~WS_EX_TRANSPARENT); + } +#endif + + show(); +} diff --git a/player/mainwindow.h b/player/mainwindow.h index b87b77c..8a4690a 100644 --- a/player/mainwindow.h +++ b/player/mainwindow.h @@ -2,25 +2,71 @@ #define MAINWINDOW_H #include +#include +#include + +#include namespace Ui { class MainWindow; } -class AniPlayer; +class Menu; class MainWindow : public QMainWindow { Q_OBJECT - + public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); - + +public slots: + bool open(); + bool open(const QString &file); + void play(); + void play(const QString &file); + + void skipback(); + void opSkip(); + + void toggleMenu(); + void resizeToVideo(); + void toggleStayOnTop(); + void toggleFrameless(); + void toggleOverlay(); + void about(); + +private slots: + void handleStateChange(AniPlayer::State newState, AniPlayer::State oldState); + +protected: + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + + void moveEvent(QMoveEvent *event); + void resizeEvent(QResizeEvent *event); + void wheelEvent(QWheelEvent *event); + private: - Ui::MainWindow *ui; + void addAction(const QString &name, const QString &text, const QKeySequence &shortcut = QKeySequence(), bool checkable = false); + void addAction(const QString &name, const QString &text, const QIcon& icon, const QKeySequence &shortcut = QKeySequence(), bool checkable = false); + + void updateWindowTitle(const QFileInfo &file = QFileInfo()); + void updateCursor(); + + void updateWindowFlags(); + QMap m_actions; + + Ui::MainWindow *ui; + Menu *menu; AniPlayer *player; + + bool mouseMoved; + QPoint dragPosition; + bool dragged; }; #endif // MAINWINDOW_H diff --git a/player/mainwindow.ui b/player/mainwindow.ui index 6050363..eadeec3 100644 --- a/player/mainwindow.ui +++ b/player/mainwindow.ui @@ -1,7 +1,8 @@ + MainWindow - - + + 0 0 @@ -9,16 +10,22 @@ 300 - + MainWindow - - - - + + + + + 0 + 0 + 400 + 21 + + + - - + diff --git a/player/player.pro b/player/player.pro index b1c0092..16b2888 100644 --- a/player/player.pro +++ b/player/player.pro @@ -9,11 +9,16 @@ DESTDIR = ../build SOURCES += main.cpp\ - mainwindow.cpp + mainwindow.cpp \ + menu.cpp \ + seekslider.cpp -HEADERS += mainwindow.h +HEADERS += mainwindow.h \ + menu.h \ + seekslider.h -FORMS += mainwindow.ui +FORMS += mainwindow.ui \ + menu.ui include(../config.pri) include(../aniplayer2/aniplayer2.pri) -- 2.52.0