diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d85f48..3ec9fd7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ set(CMAKE_AUTORCC ON) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) -find_package(Qt5 COMPONENTS Widgets REQUIRED) +find_package(Qt5 COMPONENTS Widgets Multimedia REQUIRED) add_executable(pineapple-music main.cpp @@ -23,4 +23,4 @@ add_executable(pineapple-music resources.qrc ) -target_link_libraries(pineapple-music PRIVATE Qt5::Widgets) +target_link_libraries(pineapple-music PRIVATE Qt5::Widgets Qt5::Multimedia) diff --git a/icons/audio-volume-muted.png b/icons/audio-volume-muted.png new file mode 100644 index 0000000..6c7da33 Binary files /dev/null and b/icons/audio-volume-muted.png differ diff --git a/icons/media-playback-pause.png b/icons/media-playback-pause.png new file mode 100644 index 0000000..a51dc81 Binary files /dev/null and b/icons/media-playback-pause.png differ diff --git a/mainwindow.cpp b/mainwindow.cpp index 4c6c0f8..de09f1b 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -2,19 +2,63 @@ #include "./ui_mainwindow.h" #include +#include +#include #include +#include +#include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) + , m_mediaPlayer(new QMediaPlayer(this)) { ui->setupUi(this); this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint); this->setAttribute(Qt::WA_TranslucentBackground, true); + connect(m_mediaPlayer, &QMediaPlayer::currentMediaChanged, this, [=](const QMediaContent &media) { + ui->titleLabel->setText(media.canonicalUrl().fileName()); + }); + + connect(m_mediaPlayer, &QMediaPlayer::positionChanged, this, [=](qint64 pos) { + ui->nowTimeLabel->setText(ms2str(pos)); + if (m_mediaPlayer->duration() != 0) { + ui->playbackSlider->setSliderPosition(ui->playbackSlider->maximum() * pos / m_mediaPlayer->duration()); + } + }); + + connect(m_mediaPlayer, &QMediaPlayer::mutedChanged, this, [=](bool muted) { + if (muted) { + ui->volumeBtn->setIcon(QIcon(":/icons/icons/audio-volume-muted.png")); + } else { + ui->volumeBtn->setIcon(QIcon(":/icons/icons/audio-volume-high.png")); + } + }); + + connect(m_mediaPlayer, &QMediaPlayer::durationChanged, this, [=](qint64 dua) { + ui->totalTimeLabel->setText(ms2str(dua)); + }); + + connect(m_mediaPlayer, &QMediaPlayer::stateChanged, this, [=](QMediaPlayer::State newState) { + switch (newState) { + case QMediaPlayer::PlayingState: + ui->playBtn->setIcon(QIcon(":/icons/icons/media-playback-pause.png")); + break; + case QMediaPlayer::StoppedState: + case QMediaPlayer::PausedState: + ui->playBtn->setIcon(QIcon(":/icons/icons/media-playback-start.png")); + break; + } + }); + + connect(m_mediaPlayer, &QMediaPlayer::volumeChanged, this, [=](int vol) { + ui->volumeSlider->setValue(vol); + }); + m_bgLinearGradient.setColorAt(0, QColor(255, 255, 255, 25)); // a:0 - m_bgLinearGradient.setColorAt(1, QColor(255, 255, 255, 200)); + m_bgLinearGradient.setColorAt(1, QColor(255, 255, 255, 75)); // a:200 m_bgLinearGradient.setStart(0, 0); m_bgLinearGradient.setFinalStop(0, height()); @@ -39,8 +83,13 @@ void MainWindow::paintEvent(QPaintEvent * e) { QPainter painter(this); - painter.setBrush(QBrush(m_bgLinearGradient)); painter.setPen(Qt::NoPen); + + // Temp bg + painter.setBrush(QColor(20, 32, 83)); + painter.drawRect(0, 0, width(), height()); + + painter.setBrush(QBrush(m_bgLinearGradient)); painter.drawRect(0, 0, width(), height()); return QMainWindow::paintEvent(e); @@ -74,7 +123,106 @@ void MainWindow::mouseReleaseEvent(QMouseEvent *event) return QMainWindow::mouseReleaseEvent(event); } +void MainWindow::loadFile() +{ + QStringList files = QFileDialog::getOpenFileNames(this, + tr("Select songs to play"), + QDir::homePath(), + tr("Audio Files") + " (*.mp3 *.wav *.aiff *.ape *.flac *.ogg *.oga)"); + QMediaPlaylist * playlist = new QMediaPlaylist(m_mediaPlayer); + playlist->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop); + for (const QString & fileName : files) { + bool succ = playlist->addMedia(QMediaContent(fileName)); + if (!succ) { + qDebug("!!!!!!!!! break point time !!!!!!!!!"); + } + } + + m_mediaPlayer->setPlaylist(playlist); +} + void MainWindow::on_closeWindowBtn_clicked() { m_fadeOutAnimation->start(); } + +void MainWindow::on_playBtn_clicked() +{ + if (m_mediaPlayer->mediaStatus() == QMediaPlayer::NoMedia) { + loadFile(); + m_mediaPlayer->play(); + } else { + if (QList {QMediaPlayer::PausedState, QMediaPlayer::StoppedState} + .contains(m_mediaPlayer->state())) { + m_mediaPlayer->play(); + } else { + m_mediaPlayer->pause(); + } + } +} + +QString MainWindow::ms2str(qint64 ms) +{ + QTime duaTime(QTime::fromMSecsSinceStartOfDay(ms)); + if (duaTime.hour() > 0) { + return duaTime.toString("h:mm:ss"); + } else { + return duaTime.toString("m:ss"); + } +} + +void MainWindow::on_volumeSlider_valueChanged(int value) +{ + if (m_mediaPlayer->isMuted()) { + m_mediaPlayer->setMuted(false); + } + m_mediaPlayer->setVolume(value); +} + +void MainWindow::on_stopBtn_clicked() +{ + m_mediaPlayer->stop(); +} + +void MainWindow::on_playbackSlider_valueChanged(int value) +{ + qint64 currPos = m_mediaPlayer->duration() == 0 ? value : m_mediaPlayer->position() * ui->playbackSlider->maximum() / m_mediaPlayer->duration(); + if (qAbs(currPos - value) > 2) { + m_mediaPlayer->setPosition(ui->playbackSlider->value() * 1.0 / ui->playbackSlider->maximum() * m_mediaPlayer->duration()); + } +} + +void MainWindow::on_prevBtn_clicked() +{ + // QMediaPlaylist::previous() won't work when in CurrentItemInLoop playmode, + // and also works not as intended when in other playmode, so do it manually... + QMediaPlaylist * playlist = m_mediaPlayer->playlist(); + if (playlist) { + int index = playlist->currentIndex(); + int count = playlist->mediaCount(); + + m_mediaPlayer->playlist()->setCurrentIndex(index == 0 ? count - 1 : index - 1); + } +} + +void MainWindow::on_nextBtn_clicked() +{ + // see also: MainWindow::on_prevBtn_clicked() + QMediaPlaylist * playlist = m_mediaPlayer->playlist(); + if (playlist) { + int index = playlist->currentIndex(); + int count = playlist->mediaCount(); + + m_mediaPlayer->playlist()->setCurrentIndex(index == (count - 1) ? 0 : index + 1); + } +} + +void MainWindow::on_volumeBtn_clicked() +{ + m_mediaPlayer->setMuted(!m_mediaPlayer->isMuted()); +} + +void MainWindow::on_minimumWindowBtn_clicked() +{ + this->showMinimized(); +} diff --git a/mainwindow.h b/mainwindow.h index 6f9b7ec..804cfb6 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -6,6 +6,7 @@ QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } +class QMediaPlayer; class QPropertyAnimation; QT_END_NAMESPACE @@ -24,16 +25,35 @@ protected: void mouseMoveEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; + void loadFile(); + private slots: void on_closeWindowBtn_clicked(); + void on_playBtn_clicked(); + void on_volumeSlider_valueChanged(int value); + void on_stopBtn_clicked(); + + void on_playbackSlider_valueChanged(int value); + + void on_prevBtn_clicked(); + + void on_nextBtn_clicked(); + + void on_volumeBtn_clicked(); + + void on_minimumWindowBtn_clicked(); private: QPoint m_oldMousePos; bool m_clickedOnWindow = false; + bool m_playbackSliderPressed = false; QLinearGradient m_bgLinearGradient; Ui::MainWindow *ui; + QMediaPlayer *m_mediaPlayer; QPropertyAnimation *m_fadeOutAnimation; + + static QString ms2str(qint64 ms); }; #endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui index edf7775..fef3512 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -88,7 +88,11 @@ QPushButton#closeWindowBtn:hover { /****** Label ******/ -QLabel#coverLabel{ +QLabel { + color: white; +} + +QLabel#coverLabel { border: 1px solid grey; } @@ -280,6 +284,9 @@ QLabel#coverLabel{ + + 1000 + Qt::Horizontal @@ -504,8 +511,11 @@ QLabel#coverLabel{ 32 + + 100 + - 99 + 100 Qt::Horizontal diff --git a/resources.qrc b/resources.qrc index 98f22de..7eb5e16 100644 --- a/resources.qrc +++ b/resources.qrc @@ -9,5 +9,7 @@ icons/view-media-playlist.png icons/window-close.png icons/window-minimize.png + icons/media-playback-pause.png + icons/audio-volume-muted.png