2025-11-20 01:55:14 -07:00
|
|
|
#include "nowPlaying.h"
|
2025-11-19 20:50:15 -07:00
|
|
|
#include <QVBoxLayout>
|
2025-11-19 21:20:27 -07:00
|
|
|
#include <QFileInfo>
|
2025-11-19 21:39:36 -07:00
|
|
|
#include <QCloseEvent>
|
|
|
|
|
#include "src/data/cleanerScripts.h"
|
2025-11-19 20:50:15 -07:00
|
|
|
|
2025-11-20 01:55:14 -07:00
|
|
|
NowPlaying::NowPlaying(const AlbumData& item, QWidget* parent)
|
2025-11-19 20:50:15 -07:00
|
|
|
: QWidget(parent), item_(item)
|
|
|
|
|
{
|
2025-11-19 22:33:32 -07:00
|
|
|
setWindowTitle("Now Playing");
|
2025-11-20 03:27:47 -07:00
|
|
|
resize(350, 600);
|
2025-11-19 20:50:15 -07:00
|
|
|
|
2025-11-19 21:20:27 -07:00
|
|
|
QVBoxLayout* layout = new QVBoxLayout(this);
|
2025-11-19 20:50:15 -07:00
|
|
|
|
2025-11-19 22:33:32 -07:00
|
|
|
// Album artwork
|
2025-11-19 21:46:02 -07:00
|
|
|
spinningArt_ = new SpinningAlbumArt(item.imagePath, 250);
|
2025-11-19 22:33:32 -07:00
|
|
|
layout->addWidget(spinningArt_, 0, Qt::AlignCenter);
|
2025-11-19 21:39:36 -07:00
|
|
|
|
2025-11-19 22:33:32 -07:00
|
|
|
// Track label
|
|
|
|
|
trackLabel_ = new QLabel("Track");
|
2025-11-19 21:20:27 -07:00
|
|
|
trackLabel_->setAlignment(Qt::AlignCenter);
|
2025-11-20 03:27:47 -07:00
|
|
|
trackLabel_->setStyleSheet("font-size: 20px; font-weight: 700; margin-top: 10px");
|
2025-11-19 21:20:27 -07:00
|
|
|
layout->addWidget(trackLabel_);
|
2025-11-19 20:50:15 -07:00
|
|
|
|
2025-11-19 23:30:03 -07:00
|
|
|
// Time played in Song Indicator
|
|
|
|
|
timeIndicator_ = new TimePlayedWidget(this);
|
|
|
|
|
layout->addWidget(timeIndicator_);
|
|
|
|
|
|
|
|
|
|
// Volume slider (NEW)
|
|
|
|
|
volumeSlider_ = new QSlider(Qt::Horizontal);
|
|
|
|
|
volumeSlider_->setRange(0, 100);
|
|
|
|
|
volumeSlider_->setValue(80);
|
|
|
|
|
volumeSlider_->setStyleSheet("margin: 0 12px;");
|
|
|
|
|
layout->addWidget(volumeSlider_);
|
|
|
|
|
|
2025-11-19 22:33:32 -07:00
|
|
|
// Track list widget
|
|
|
|
|
trackList_ = new TrackListWidget(item_.audioFiles, this);
|
|
|
|
|
layout->addWidget(trackList_);
|
|
|
|
|
|
|
|
|
|
// Audio backend
|
2025-11-19 21:20:27 -07:00
|
|
|
player_ = new QMediaPlayer(this);
|
2025-11-19 21:39:36 -07:00
|
|
|
audio_ = new QAudioOutput(this);
|
2025-11-19 21:20:27 -07:00
|
|
|
player_->setAudioOutput(audio_);
|
2025-11-19 20:50:15 -07:00
|
|
|
|
2025-11-19 23:30:03 -07:00
|
|
|
audio_->setVolume(0.8f); // match slider
|
|
|
|
|
connect(volumeSlider_, &QSlider::valueChanged, this,
|
|
|
|
|
[this](int v){ audio_->setVolume(v / 100.0); });
|
|
|
|
|
|
2025-11-19 22:33:32 -07:00
|
|
|
// Spin album art based on playback
|
2025-11-19 21:39:36 -07:00
|
|
|
connect(player_, &QMediaPlayer::playbackStateChanged, this,
|
2025-11-19 21:46:02 -07:00
|
|
|
[this](QMediaPlayer::PlaybackState st){
|
2025-11-19 21:39:36 -07:00
|
|
|
if (st == QMediaPlayer::PlayingState)
|
2025-11-19 21:46:02 -07:00
|
|
|
spinningArt_->start();
|
2025-11-19 21:39:36 -07:00
|
|
|
else
|
2025-11-19 21:46:02 -07:00
|
|
|
spinningArt_->stop();
|
2025-11-19 21:39:36 -07:00
|
|
|
});
|
|
|
|
|
|
2025-11-19 23:30:03 -07:00
|
|
|
// Get song duration and played time
|
|
|
|
|
connect(player_, &QMediaPlayer::durationChanged,
|
|
|
|
|
timeIndicator_, &TimePlayedWidget::setDuration);
|
|
|
|
|
|
|
|
|
|
connect(player_, &QMediaPlayer::positionChanged,
|
|
|
|
|
timeIndicator_, &TimePlayedWidget::setPosition);
|
|
|
|
|
|
|
|
|
|
// Pause/Play on album art click
|
|
|
|
|
connect(spinningArt_, &SpinningAlbumArt::artClicked, this, [this]() {
|
|
|
|
|
if (player_->playbackState() == QMediaPlayer::PlayingState) {
|
|
|
|
|
player_->pause();
|
|
|
|
|
spinningArt_->stop();
|
|
|
|
|
} else {
|
|
|
|
|
player_->play();
|
|
|
|
|
spinningArt_->start();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2025-11-19 22:33:32 -07:00
|
|
|
// When a track finishes, auto-play next
|
|
|
|
|
connect(player_, &QMediaPlayer::mediaStatusChanged, this,
|
|
|
|
|
[this](QMediaPlayer::MediaStatus st){
|
|
|
|
|
if (st == QMediaPlayer::EndOfMedia)
|
|
|
|
|
handleTrackFinished();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// When a track is clicked
|
|
|
|
|
connect(trackList_, &TrackListWidget::trackSelected, this,
|
|
|
|
|
[this](int i){
|
|
|
|
|
index_ = i;
|
|
|
|
|
playTrack(index_);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Start with track 0
|
|
|
|
|
playTrack(index_);
|
2025-11-19 20:50:15 -07:00
|
|
|
}
|
|
|
|
|
|
2025-11-20 01:55:14 -07:00
|
|
|
void NowPlaying::playTrack(int idx)
|
2025-11-19 20:50:15 -07:00
|
|
|
{
|
2025-11-19 22:33:32 -07:00
|
|
|
if (idx < 0 || idx >= item_.audioFiles.size())
|
2025-11-19 21:20:27 -07:00
|
|
|
return;
|
|
|
|
|
|
2025-11-19 22:33:32 -07:00
|
|
|
index_ = idx;
|
|
|
|
|
|
|
|
|
|
QString filePath = item_.audioFiles[idx];
|
2025-11-19 21:20:27 -07:00
|
|
|
QString fileName = QFileInfo(filePath).fileName();
|
|
|
|
|
QString title = cleanTrackTitle(fileName);
|
|
|
|
|
|
2025-11-20 03:27:47 -07:00
|
|
|
trackLabel_->setText(QString(title));
|
2025-11-19 21:20:27 -07:00
|
|
|
|
|
|
|
|
player_->setSource(QUrl::fromLocalFile(filePath));
|
|
|
|
|
player_->play();
|
|
|
|
|
|
2025-11-19 22:33:32 -07:00
|
|
|
// Highlight in the list
|
|
|
|
|
trackList_->setCurrentRow(idx);
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-20 01:55:14 -07:00
|
|
|
void NowPlaying::handleTrackFinished()
|
2025-11-19 22:33:32 -07:00
|
|
|
{
|
|
|
|
|
int nextIndex = index_ + 1;
|
|
|
|
|
|
|
|
|
|
if (nextIndex >= item_.audioFiles.size()) {
|
|
|
|
|
close();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
playTrack(nextIndex);
|
2025-11-19 20:50:15 -07:00
|
|
|
}
|
|
|
|
|
|
2025-11-20 01:55:14 -07:00
|
|
|
void NowPlaying::closeEvent(QCloseEvent* event)
|
2025-11-19 20:50:15 -07:00
|
|
|
{
|
2025-11-19 22:33:32 -07:00
|
|
|
if (player_)
|
2025-11-19 20:50:15 -07:00
|
|
|
player_->stop();
|
2025-11-19 22:33:32 -07:00
|
|
|
|
2025-11-19 21:39:36 -07:00
|
|
|
QWidget::closeEvent(event);
|
2025-11-19 20:50:15 -07:00
|
|
|
}
|