Add widget to seek through songs on an album
This commit is contained in:
42
src/components/tracklistWidget/tracklistwidget.cpp
Normal file
42
src/components/tracklistWidget/tracklistwidget.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "tracklistwidget.h"
|
||||
#include <QFileInfo>
|
||||
#include <QVBoxLayout>
|
||||
#include "src/data/cleanerScripts.h"
|
||||
|
||||
TrackListWidget::TrackListWidget(const QStringList& audioFiles, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
list_ = new QListWidget(this);
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->addWidget(list_);
|
||||
|
||||
int trackNum = 1;
|
||||
|
||||
for (const QString& f : audioFiles) {
|
||||
|
||||
// Extract just the filename
|
||||
QString fileName = QFileInfo(f).fileName();
|
||||
|
||||
// Run through your cleaner
|
||||
QString songTitle = cleanTrackTitle(fileName);
|
||||
|
||||
// Format display text: "1. Song Title"
|
||||
QString display = QString("%1. %2")
|
||||
.arg(trackNum++)
|
||||
.arg(songTitle);
|
||||
|
||||
list_->addItem(display);
|
||||
}
|
||||
|
||||
// Emit signal when clicked
|
||||
connect(list_, &QListWidget::itemClicked, this, [=](QListWidgetItem* item){
|
||||
int index = list_->row(item);
|
||||
emit trackSelected(index);
|
||||
});
|
||||
}
|
||||
|
||||
void TrackListWidget::setCurrentRow(int row)
|
||||
{
|
||||
list_->setCurrentRow(row);
|
||||
}
|
||||
23
src/components/tracklistWidget/tracklistwidget.h
Normal file
23
src/components/tracklistWidget/tracklistwidget.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef TRACKLISTWIDGET_H
|
||||
#define TRACKLISTWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QListWidget>
|
||||
|
||||
class TrackListWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TrackListWidget(const QStringList& audioFiles, QWidget* parent = nullptr);
|
||||
|
||||
void setCurrentRow(int row); // <-- THIS must be here
|
||||
|
||||
signals:
|
||||
void trackSelected(int index);
|
||||
|
||||
private:
|
||||
QListWidget* list_;
|
||||
};
|
||||
|
||||
#endif // TRACKLISTWIDGET_H
|
||||
@@ -1,7 +1,5 @@
|
||||
#include "playerWindow.h"
|
||||
#include <QVBoxLayout>
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QFileInfo>
|
||||
#include <QCloseEvent>
|
||||
#include "src/data/cleanerScripts.h"
|
||||
@@ -9,24 +7,31 @@
|
||||
PlayerWindow::PlayerWindow(const AlbumData& item, QWidget* parent)
|
||||
: QWidget(parent), item_(item)
|
||||
{
|
||||
this->setWindowTitle("Now Playing");
|
||||
this->resize(300, 370);
|
||||
setWindowTitle("Now Playing");
|
||||
resize(350, 500);
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
|
||||
// SUPER SIMPLE now:
|
||||
// Album artwork
|
||||
spinningArt_ = new SpinningAlbumArt(item.imagePath, 250);
|
||||
layout->addWidget(spinningArt_);
|
||||
layout->addWidget(spinningArt_, 0, Qt::AlignCenter);
|
||||
|
||||
trackLabel_ = new QLabel("Track 1");
|
||||
// Track label
|
||||
trackLabel_ = new QLabel("Track");
|
||||
trackLabel_->setAlignment(Qt::AlignCenter);
|
||||
trackLabel_->setStyleSheet("font-size: 14px; font-weight: 500;");
|
||||
layout->addWidget(trackLabel_);
|
||||
|
||||
// Track list widget
|
||||
trackList_ = new TrackListWidget(item_.audioFiles, this);
|
||||
layout->addWidget(trackList_);
|
||||
|
||||
// Audio backend
|
||||
player_ = new QMediaPlayer(this);
|
||||
audio_ = new QAudioOutput(this);
|
||||
player_->setAudioOutput(audio_);
|
||||
|
||||
// Spin album art based on playback
|
||||
connect(player_, &QMediaPlayer::playbackStateChanged, this,
|
||||
[this](QMediaPlayer::PlaybackState st){
|
||||
if (st == QMediaPlayer::PlayingState)
|
||||
@@ -35,35 +40,60 @@ PlayerWindow::PlayerWindow(const AlbumData& item, QWidget* parent)
|
||||
spinningArt_->stop();
|
||||
});
|
||||
|
||||
playNext();
|
||||
// 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_);
|
||||
}
|
||||
|
||||
void PlayerWindow::playNext()
|
||||
void PlayerWindow::playTrack(int idx)
|
||||
{
|
||||
if (index_ >= item_.audioFiles.size()) {
|
||||
this->close();
|
||||
if (idx < 0 || idx >= item_.audioFiles.size())
|
||||
return;
|
||||
}
|
||||
|
||||
QString filePath = item_.audioFiles[index_];
|
||||
index_ = idx;
|
||||
|
||||
QString filePath = item_.audioFiles[idx];
|
||||
QString fileName = QFileInfo(filePath).fileName();
|
||||
QString title = cleanTrackTitle(fileName);
|
||||
|
||||
trackLabel_->setText(
|
||||
QString("Track %1: %2").arg(index_ + 1).arg(title)
|
||||
);
|
||||
trackLabel_->setText(QString("Track %1: %2").arg(idx + 1).arg(title));
|
||||
|
||||
player_->setSource(QUrl::fromLocalFile(filePath));
|
||||
player_->play();
|
||||
|
||||
index_++;
|
||||
// Highlight in the list
|
||||
trackList_->setCurrentRow(idx);
|
||||
}
|
||||
|
||||
void PlayerWindow::handleTrackFinished()
|
||||
{
|
||||
int nextIndex = index_ + 1;
|
||||
|
||||
if (nextIndex >= item_.audioFiles.size()) {
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
playTrack(nextIndex);
|
||||
}
|
||||
|
||||
void PlayerWindow::closeEvent(QCloseEvent* event)
|
||||
{
|
||||
if (player_) {
|
||||
if (player_)
|
||||
player_->stop();
|
||||
spinTimer_->stop();
|
||||
}
|
||||
|
||||
QWidget::closeEvent(event);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#ifndef PLAYERWINDOW_H
|
||||
#define PLAYERWINDOW_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
@@ -7,33 +8,32 @@
|
||||
#include <QTimer>
|
||||
#include "src/data/albumInformation.h"
|
||||
#include "src/components/spinningalbumart/spinningAlbumArt.h"
|
||||
#include "src/components/tracklistWidget/tracklistwidget.h"
|
||||
|
||||
class PlayerWindow : public QWidget {
|
||||
class PlayerWindow : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
SpinningAlbumArt* spinningArt_;
|
||||
|
||||
public:
|
||||
explicit PlayerWindow(const AlbumData& item, QWidget* parent = nullptr);
|
||||
void setCurrentRow(int row);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent* event) override;
|
||||
|
||||
private slots:
|
||||
void playNext();
|
||||
|
||||
private:
|
||||
void playTrack(int index);
|
||||
void handleTrackFinished();
|
||||
|
||||
AlbumData item_;
|
||||
int index_ = 0;
|
||||
int index_ = 0; // active track index
|
||||
|
||||
SpinningAlbumArt* spinningArt_;
|
||||
QLabel* trackLabel_;
|
||||
TrackListWidget* trackList_;
|
||||
|
||||
QMediaPlayer* player_;
|
||||
QAudioOutput* audio_;
|
||||
|
||||
QLabel* artLabel_;
|
||||
QLabel* trackLabel_;
|
||||
|
||||
QPixmap discArt_; // circular cropped album art
|
||||
QPixmap overlayArt_; // optional overlay (not required)
|
||||
qreal rotationAngle_ = 0;
|
||||
|
||||
QTimer* spinTimer_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user