Move code that handles spinning album art to own class

This commit is contained in:
2025-11-19 21:46:02 -07:00
parent 58ecda86a9
commit 3df5097e60
19 changed files with 291 additions and 94 deletions

View File

@@ -0,0 +1,82 @@
#include "spinningalbumart.h"
#include <QPainter>
#include <QPainterPath>
SpinningAlbumArt::SpinningAlbumArt(const QString& imagePath, int size, QWidget* parent)
: QWidget(parent), size_(size)
{
artLabel_ = new QLabel(this);
artLabel_->setAlignment(Qt::AlignCenter);
setFixedSize(size, size);
// Load and crop square
QPixmap pix(imagePath);
QPixmap scaled = pix.scaled(size, size,
Qt::KeepAspectRatioByExpanding,
Qt::SmoothTransformation);
int side = qMin(scaled.width(), scaled.height());
QPixmap square = scaled.copy(
(scaled.width() - side) / 2,
(scaled.height() - side) / 2,
side,
side
);
// Mask into circle
discArt_ = createCircularDisc(square, size);
artLabel_->setPixmap(discArt_);
// Setup spin timer
timer_ = new QTimer(this);
timer_->setInterval(16);
connect(timer_, &QTimer::timeout, this, &SpinningAlbumArt::updateRotation);
}
QPixmap SpinningAlbumArt::createCircularDisc(const QPixmap& src, int size)
{
QPixmap disc(size, size);
disc.fill(Qt::transparent);
QPainter p(&disc);
p.setRenderHint(QPainter::Antialiasing);
QPainterPath path;
path.addEllipse(0, 0, size, size);
p.setClipPath(path);
p.drawPixmap(0, 0, src);
return disc;
}
void SpinningAlbumArt::start()
{
timer_->start();
}
void SpinningAlbumArt::stop()
{
timer_->stop();
}
void SpinningAlbumArt::updateRotation()
{
rotationAngle_ += 0.6;
QPixmap frame(size_, size_);
frame.fill(Qt::transparent);
QPainter p(&frame);
p.setRenderHint(QPainter::Antialiasing);
p.setRenderHint(QPainter::SmoothPixmapTransform);
p.translate(size_ / 2, size_ / 2);
p.rotate(rotationAngle_);
p.translate(-size_ / 2, -size_ / 2);
p.drawPixmap(0, 0, discArt_);
artLabel_->setPixmap(frame);
}

View File

@@ -0,0 +1,30 @@
#pragma once
#include <QWidget>
#include <QLabel>
#include <QPixmap>
#include <QTimer>
class SpinningAlbumArt : public QWidget
{
Q_OBJECT
public:
explicit SpinningAlbumArt(const QString& imagePath, int size = 250, QWidget* parent = nullptr);
public slots:
void start();
void stop();
private slots:
void updateRotation();
private:
QPixmap discArt_; // circular-masked album image
QLabel* artLabel_; // widget that displays the spinning frame
QTimer* timer_; // animation timer
qreal rotationAngle_ = 0;
int size_; // final diameter of the disc
QPixmap createCircularDisc(const QPixmap& src, int size);
};

View File

@@ -14,110 +14,27 @@ PlayerWindow::PlayerWindow(const AlbumData& item, QWidget* parent)
QVBoxLayout* layout = new QVBoxLayout(this);
// --------------------------------------
// 1. CREATE ALBUM ART (CIRCULAR)
// --------------------------------------
artLabel_ = new QLabel;
artLabel_->setAlignment(Qt::AlignCenter);
layout->addWidget(artLabel_);
// SUPER SIMPLE now:
spinningArt_ = new SpinningAlbumArt(item.imagePath, 250);
layout->addWidget(spinningArt_);
QPixmap pix(item.imagePath);
// Scale, crop square
QPixmap scaled = pix.scaled(250, 250,
Qt::KeepAspectRatioByExpanding,
Qt::SmoothTransformation);
int side = qMin(scaled.width(), scaled.height());
QPixmap square = scaled.copy(
(scaled.width() - side) / 2,
(scaled.height() - side) / 2,
side,
side
);
// Mask to circle
discArt_ = QPixmap(side, side);
discArt_.fill(Qt::transparent);
{
QPainter p(&discArt_);
p.setRenderHint(QPainter::Antialiasing);
QPainterPath path;
path.addEllipse(0, 0, side, side);
p.setClipPath(path);
p.drawPixmap(0, 0, square);
}
artLabel_->setPixmap(discArt_);
// --------------------------------------
// 2. TRACK LABEL
// --------------------------------------
trackLabel_ = new QLabel("Track 1");
trackLabel_->setAlignment(Qt::AlignCenter);
trackLabel_->setStyleSheet("font-size: 14px; font-weight: 500;");
layout->addWidget(trackLabel_);
// --------------------------------------
// 3. SPINNING TIMER
// --------------------------------------
spinTimer_ = new QTimer(this);
spinTimer_->setInterval(16);
connect(spinTimer_, &QTimer::timeout, this, [this]() {
rotationAngle_ += 0.6;
int side = discArt_.width();
QPixmap frame(side, side);
frame.fill(Qt::transparent);
QPainter p(&frame);
p.setRenderHint(QPainter::Antialiasing);
p.setRenderHint(QPainter::SmoothPixmapTransform);
// rotate around center
p.translate(side / 2, side / 2);
p.rotate(rotationAngle_);
p.translate(-side / 2, -side / 2);
p.drawPixmap(0, 0, discArt_);
// If you eventually add overlay:
// p.resetTransform();
// p.drawPixmap(0, 0, overlayArt_);
artLabel_->setPixmap(frame);
});
// --------------------------------------
// 4. MEDIA PLAYER SETUP
// --------------------------------------
player_ = new QMediaPlayer(this);
audio_ = new QAudioOutput(this);
player_->setAudioOutput(audio_);
connect(player_, &QMediaPlayer::mediaStatusChanged, this,
[this](QMediaPlayer::MediaStatus s) {
if (s == QMediaPlayer::EndOfMedia) {
spinTimer_->stop();
playNext();
}
});
connect(player_, &QMediaPlayer::playbackStateChanged, this,
[this](QMediaPlayer::PlaybackState st) {
[this](QMediaPlayer::PlaybackState st){
if (st == QMediaPlayer::PlayingState)
spinTimer_->start();
spinningArt_->start();
else
spinTimer_->stop();
spinningArt_->stop();
});
// --------------------------------------
// 5. PLAY FIRST TRACK
// --------------------------------------
playNext();
}

View File

@@ -6,9 +6,11 @@
#include <QAudioOutput>
#include <QTimer>
#include "src/data/albumInformation.h"
#include "src/components/spinningalbumart/spinningAlbumArt.h"
class PlayerWindow : public QWidget {
Q_OBJECT
SpinningAlbumArt* spinningArt_;
public:
explicit PlayerWindow(const AlbumData& item, QWidget* parent = nullptr);