Add record/vinyl look to now playing screen

This commit is contained in:
2025-11-20 02:09:43 -07:00
parent e709f8978c
commit c41fe4be1b
28 changed files with 150 additions and 31 deletions

View File

@@ -1355,6 +1355,15 @@ moc_nowPlaying.cpp: ../../src/windows/nowPlaying/nowPlaying.h \
/opt/homebrew/lib/QtCore.framework/Headers/qstring.h \
/opt/homebrew/lib/QtCore.framework/Headers/QStringList \
/opt/homebrew/lib/QtCore.framework/Headers/qstringlist.h \
../../src/components/nowPlaying/spinningAlbumArt/spinningAlbumArt.h \
/opt/homebrew/lib/QtGui.framework/Headers/QPixmap \
/opt/homebrew/lib/QtGui.framework/Headers/qpixmap.h \
../../src/components/nowPlaying/tracklistWidget/tracklistWidget.h \
/opt/homebrew/lib/QtWidgets.framework/Headers/QListWidget \
/opt/homebrew/lib/QtWidgets.framework/Headers/qlistwidget.h \
../../src/components/nowPlaying/timePlayedWidget/timePlayedWidget.h \
/opt/homebrew/lib/QtWidgets.framework/Headers/QVBoxLayout \
/opt/homebrew/lib/QtWidgets.framework/Headers/qboxlayout.h \
moc_predefs.h \
/opt/homebrew/share/qt/libexec/moc
/opt/homebrew/share/qt/libexec/moc $(DEFINES) --include /Users/lucas/Developer/FA25_Qt-Music-Player/build/Desktop-Debug/moc_predefs.h -I/opt/homebrew/share/qt/mkspecs/macx-clang -I/Users/lucas/Developer/FA25_Qt-Music-Player -I/opt/homebrew/lib/QtWidgets.framework/Headers -I/opt/homebrew/lib/QtMultimedia.framework/Headers -I/opt/homebrew/lib/QtGui.framework/Headers -I/opt/homebrew/lib/QtNetwork.framework/Headers -I/opt/homebrew/lib/QtCore.framework/Headers -I. -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1 -I/Library/Developer/CommandLineTools/usr/lib/clang/17/include -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -I/Library/Developer/CommandLineTools/usr/include -F/opt/homebrew/lib ../../src/windows/nowPlaying/nowPlaying.h -o moc_nowPlaying.cpp
@@ -1386,8 +1395,6 @@ moc_spinningalbumart.cpp: ../../src/components/nowPlaying/spinningAlbumArt/spinn
/opt/homebrew/lib/QtGui.framework/Headers/qpixmap.h \
/opt/homebrew/lib/QtCore.framework/Headers/QTimer \
/opt/homebrew/lib/QtCore.framework/Headers/qtimer.h \
/opt/homebrew/lib/QtGui.framework/Headers/QMouseEvent \
/opt/homebrew/lib/QtGui.framework/Headers/qevent.h \
moc_predefs.h \
/opt/homebrew/share/qt/libexec/moc
/opt/homebrew/share/qt/libexec/moc $(DEFINES) --include /Users/lucas/Developer/FA25_Qt-Music-Player/build/Desktop-Debug/moc_predefs.h -I/opt/homebrew/share/qt/mkspecs/macx-clang -I/Users/lucas/Developer/FA25_Qt-Music-Player -I/opt/homebrew/lib/QtWidgets.framework/Headers -I/opt/homebrew/lib/QtMultimedia.framework/Headers -I/opt/homebrew/lib/QtGui.framework/Headers -I/opt/homebrew/lib/QtNetwork.framework/Headers -I/opt/homebrew/lib/QtCore.framework/Headers -I. -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1 -I/Library/Developer/CommandLineTools/usr/lib/clang/17/include -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -I/Library/Developer/CommandLineTools/usr/include -F/opt/homebrew/lib ../../src/components/nowPlaying/spinningAlbumArt/spinningalbumart.h -o moc_spinningalbumart.cpp
@@ -1463,15 +1470,27 @@ albumSelector.o: ../../src/windows/albumSelector/albumSelector.cpp ../../src/win
/opt/homebrew/lib/QtCore.framework/Headers/qstring.h \
/opt/homebrew/lib/QtCore.framework/Headers/QStringList \
/opt/homebrew/lib/QtCore.framework/Headers/qstringlist.h \
../../src/windows/nowPlaying/nowPlaying.h \
../../src/components/albumSelector/albumTile/albumTile.h \
/opt/homebrew/lib/QtWidgets.framework/Headers/QLabel \
/opt/homebrew/lib/QtWidgets.framework/Headers/qlabel.h \
/opt/homebrew/lib/QtWidgets.framework/Headers/QVBoxLayout \
/opt/homebrew/lib/QtWidgets.framework/Headers/qboxlayout.h \
/opt/homebrew/lib/QtGui.framework/Headers/QMouseEvent \
/opt/homebrew/lib/QtGui.framework/Headers/qevent.h \
../../src/windows/nowPlaying/nowPlaying.h \
/opt/homebrew/lib/QtMultimedia.framework/Headers/QMediaPlayer \
/opt/homebrew/lib/QtMultimedia.framework/Headers/qmediaplayer.h \
/opt/homebrew/lib/QtMultimedia.framework/Headers/QAudioOutput \
/opt/homebrew/lib/QtMultimedia.framework/Headers/qaudiooutput.h \
/opt/homebrew/lib/QtCore.framework/Headers/QTimer \
/opt/homebrew/lib/QtCore.framework/Headers/qtimer.h \
../../src/components/nowPlaying/spinningAlbumArt/spinningAlbumArt.h \
/opt/homebrew/lib/QtGui.framework/Headers/QPixmap \
/opt/homebrew/lib/QtGui.framework/Headers/qpixmap.h \
../../src/components/nowPlaying/tracklistWidget/tracklistWidget.h \
/opt/homebrew/lib/QtWidgets.framework/Headers/QListWidget \
/opt/homebrew/lib/QtWidgets.framework/Headers/qlistwidget.h \
../../src/components/nowPlaying/timePlayedWidget/timePlayedWidget.h \
../../src/layout/flowlayout/flowLayout.h \
/opt/homebrew/lib/QtWidgets.framework/Headers/QLayout \
/opt/homebrew/lib/QtWidgets.framework/Headers/qlayout.h \
@@ -1503,6 +1522,13 @@ nowPlaying.o: ../../src/windows/nowPlaying/nowPlaying.cpp ../../src/windows/nowP
/opt/homebrew/lib/QtCore.framework/Headers/qstring.h \
/opt/homebrew/lib/QtCore.framework/Headers/QStringList \
/opt/homebrew/lib/QtCore.framework/Headers/qstringlist.h \
../../src/components/nowPlaying/spinningAlbumArt/spinningAlbumArt.h \
/opt/homebrew/lib/QtGui.framework/Headers/QPixmap \
/opt/homebrew/lib/QtGui.framework/Headers/qpixmap.h \
../../src/components/nowPlaying/tracklistWidget/tracklistWidget.h \
/opt/homebrew/lib/QtWidgets.framework/Headers/QListWidget \
/opt/homebrew/lib/QtWidgets.framework/Headers/qlistwidget.h \
../../src/components/nowPlaying/timePlayedWidget/timePlayedWidget.h \
/opt/homebrew/lib/QtWidgets.framework/Headers/QVBoxLayout \
/opt/homebrew/lib/QtWidgets.framework/Headers/qboxlayout.h \
/opt/homebrew/lib/QtCore.framework/Headers/QFileInfo \
@@ -1671,12 +1697,12 @@ spinningalbumart.o: ../../src/components/nowPlaying/spinningAlbumArt/spinningalb
/opt/homebrew/lib/QtGui.framework/Headers/qpixmap.h \
/opt/homebrew/lib/QtCore.framework/Headers/QTimer \
/opt/homebrew/lib/QtCore.framework/Headers/qtimer.h \
/opt/homebrew/lib/QtGui.framework/Headers/QMouseEvent \
/opt/homebrew/lib/QtGui.framework/Headers/qevent.h \
/opt/homebrew/lib/QtGui.framework/Headers/QPainter \
/opt/homebrew/lib/QtGui.framework/Headers/qpainter.h \
/opt/homebrew/lib/QtGui.framework/Headers/QPainterPath \
/opt/homebrew/lib/QtGui.framework/Headers/qpainterpath.h
/opt/homebrew/lib/QtGui.framework/Headers/qpainterpath.h \
/opt/homebrew/lib/QtGui.framework/Headers/QMouseEvent \
/opt/homebrew/lib/QtGui.framework/Headers/qevent.h
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o spinningalbumart.o ../../src/components/nowPlaying/spinningAlbumArt/spinningalbumart.cpp
timePlayedWidget.o: ../../src/components/nowPlaying/timePlayedWidget/timePlayedWidget.cpp ../../src/components/nowPlaying/timePlayedWidget/timePlayedWidget.h \

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 849 KiB

View File

@@ -1,16 +1,18 @@
#include "spinningalbumart.h"
#include <QPainter>
#include <QPainterPath>
#include <QMouseEvent>
#include <QRadialGradient>
#include <QLinearGradient>
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
// Load album art and square-crop it
QPixmap pix(imagePath);
QPixmap scaled = pix.scaled(size, size,
Qt::KeepAspectRatioByExpanding,
@@ -24,33 +26,121 @@ SpinningAlbumArt::SpinningAlbumArt(const QString& imagePath, int size, QWidget*
side
);
// Mask into circle
discArt_ = createCircularDisc(square, size);
artLabel_->setPixmap(discArt_);
// Build full realistic vinyl disc with grooves + sheen + hole + label
disc_ = buildRecord(square, size);
artLabel_->setPixmap(disc_);
// 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 SpinningAlbumArt::buildRecord(const QPixmap& src, int size)
{
QPixmap disc(size, size);
disc.fill(Qt::transparent);
QPointF center(size / 2.0, size / 2.0);
QPainter p(&disc);
p.setRenderHint(QPainter::Antialiasing);
p.setRenderHint(QPainter::SmoothPixmapTransform);
QPainterPath path;
path.addEllipse(0, 0, size, size);
p.setClipPath(path);
//
// 1. Base vinyl gradient
//
QRadialGradient vinylGrad(center, size / 2);
vinylGrad.setColorAt(0.0, QColor(55, 55, 55));
vinylGrad.setColorAt(1.0, QColor(10, 10, 10));
p.setBrush(vinylGrad);
p.setPen(Qt::NoPen);
p.drawEllipse(0, 0, size, size);
p.drawPixmap(0, 0, src);
//
// 2. Grooves (2px spacing, soft alpha)
//
p.setPen(QPen(QColor(255, 255, 255, 22), 1));
int labelRadius = size * 0.35;
for (int r = labelRadius; r < size / 2; r += 2)
p.drawEllipse(center, r, r);
//
// 3. Directional sheen (angled elliptical gradient)
//
QPixmap sheen(size, size);
sheen.fill(Qt::transparent);
{
QPainter sp(&sheen);
sp.setRenderHint(QPainter::Antialiasing);
QLinearGradient lg(0, size * 0.25, size, size * 0.75);
lg.setColorAt(0.0, QColor(255, 255, 255, 40));
lg.setColorAt(0.5, QColor(255, 255, 255, 5));
lg.setColorAt(1.0, QColor(0, 0, 0, 0));
sp.setBrush(lg);
sp.setPen(Qt::NoPen);
sp.drawEllipse(0, 0, size, size);
}
p.drawPixmap(0, 0, sheen);
//
// 4. Recessed label shadow
//
QRadialGradient labelGrad(center, size * 0.36);
labelGrad.setColorAt(0.0, QColor(0, 0, 0, 80));
labelGrad.setColorAt(1.0, Qt::transparent);
p.setBrush(labelGrad);
p.drawEllipse(center, size * 0.36, size * 0.36);
//
// 5. Album art masked to label circle
//
QPixmap label = buildLabelMask(src, size);
p.drawPixmap(0, 0, label);
//
// 6. Spindle hole (cutout)
//
int holeDiameter = size * 0.17;
QPainterPath hole;
hole.addEllipse(
(size - holeDiameter) / 2,
(size - holeDiameter) / 2,
holeDiameter,
holeDiameter
);
p.setCompositionMode(QPainter::CompositionMode_Clear);
p.fillPath(hole, Qt::transparent);
return disc;
}
QPixmap SpinningAlbumArt::buildLabelMask(const QPixmap& src, int size)
{
QPixmap label(size, size);
label.fill(Qt::transparent);
QPainter p(&label);
p.setRenderHint(QPainter::Antialiasing);
int labelDiameter = size * 0.70;
QPainterPath mask;
mask.addEllipse(
(size - labelDiameter) / 2,
(size - labelDiameter) / 2,
labelDiameter,
labelDiameter
);
p.setClipPath(mask);
p.drawPixmap(0, 0, src);
return label;
}
void SpinningAlbumArt::start()
{
timer_->start();
@@ -63,7 +153,7 @@ void SpinningAlbumArt::stop()
void SpinningAlbumArt::updateRotation()
{
rotationAngle_ += 0.6;
rotationAngle_ += 0.5;
QPixmap frame(size_, size_);
frame.fill(Qt::transparent);
@@ -76,7 +166,7 @@ void SpinningAlbumArt::updateRotation()
p.rotate(rotationAngle_);
p.translate(-size_ / 2, -size_ / 2);
p.drawPixmap(0, 0, discArt_);
p.drawPixmap(0, 0, disc_);
artLabel_->setPixmap(frame);
}

View File

@@ -4,14 +4,15 @@
#include <QLabel>
#include <QPixmap>
#include <QTimer>
#include <QMouseEvent>
class SpinningAlbumArt : public QWidget
{
Q_OBJECT
public:
explicit SpinningAlbumArt(const QString& imagePath, int size = 250, QWidget* parent = nullptr);
explicit SpinningAlbumArt(const QString& imagePath,
int size = 250,
QWidget* parent = nullptr);
public slots:
void start();
@@ -20,18 +21,20 @@ public slots:
signals:
void artClicked();
private slots:
void updateRotation();
protected:
void mousePressEvent(QMouseEvent* event) override;
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
private slots:
void updateRotation();
QPixmap createCircularDisc(const QPixmap& src, int size);
private:
QPixmap buildRecord(const QPixmap& src, int size);
QPixmap buildLabelMask(const QPixmap& src, int size);
QLabel* artLabel_;
QPixmap disc_; // final assembled vinyl-only disc (with grooves + sheen + hole + label)
QTimer* timer_;
qreal rotationAngle_ = 0;
int size_;
};