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/qstring.h \
/opt/homebrew/lib/QtCore.framework/Headers/QStringList \ /opt/homebrew/lib/QtCore.framework/Headers/QStringList \
/opt/homebrew/lib/QtCore.framework/Headers/qstringlist.h \ /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 \ moc_predefs.h \
/opt/homebrew/share/qt/libexec/moc /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 /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/QtGui.framework/Headers/qpixmap.h \
/opt/homebrew/lib/QtCore.framework/Headers/QTimer \ /opt/homebrew/lib/QtCore.framework/Headers/QTimer \
/opt/homebrew/lib/QtCore.framework/Headers/qtimer.h \ /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 \ moc_predefs.h \
/opt/homebrew/share/qt/libexec/moc /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 /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/qstring.h \
/opt/homebrew/lib/QtCore.framework/Headers/QStringList \ /opt/homebrew/lib/QtCore.framework/Headers/QStringList \
/opt/homebrew/lib/QtCore.framework/Headers/qstringlist.h \ /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 \
/opt/homebrew/lib/QtWidgets.framework/Headers/qlabel.h \ /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 \
/opt/homebrew/lib/QtMultimedia.framework/Headers/qmediaplayer.h \ /opt/homebrew/lib/QtMultimedia.framework/Headers/qmediaplayer.h \
/opt/homebrew/lib/QtMultimedia.framework/Headers/QAudioOutput \ /opt/homebrew/lib/QtMultimedia.framework/Headers/QAudioOutput \
/opt/homebrew/lib/QtMultimedia.framework/Headers/qaudiooutput.h \ /opt/homebrew/lib/QtMultimedia.framework/Headers/qaudiooutput.h \
/opt/homebrew/lib/QtCore.framework/Headers/QTimer \ /opt/homebrew/lib/QtCore.framework/Headers/QTimer \
/opt/homebrew/lib/QtCore.framework/Headers/qtimer.h \ /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 \ ../../src/layout/flowlayout/flowLayout.h \
/opt/homebrew/lib/QtWidgets.framework/Headers/QLayout \ /opt/homebrew/lib/QtWidgets.framework/Headers/QLayout \
/opt/homebrew/lib/QtWidgets.framework/Headers/qlayout.h \ /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/qstring.h \
/opt/homebrew/lib/QtCore.framework/Headers/QStringList \ /opt/homebrew/lib/QtCore.framework/Headers/QStringList \
/opt/homebrew/lib/QtCore.framework/Headers/qstringlist.h \ /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/QVBoxLayout \
/opt/homebrew/lib/QtWidgets.framework/Headers/qboxlayout.h \ /opt/homebrew/lib/QtWidgets.framework/Headers/qboxlayout.h \
/opt/homebrew/lib/QtCore.framework/Headers/QFileInfo \ /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/QtGui.framework/Headers/qpixmap.h \
/opt/homebrew/lib/QtCore.framework/Headers/QTimer \ /opt/homebrew/lib/QtCore.framework/Headers/QTimer \
/opt/homebrew/lib/QtCore.framework/Headers/qtimer.h \ /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 \
/opt/homebrew/lib/QtGui.framework/Headers/qpainter.h \ /opt/homebrew/lib/QtGui.framework/Headers/qpainter.h \
/opt/homebrew/lib/QtGui.framework/Headers/QPainterPath \ /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 $(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 \ 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 "spinningalbumart.h"
#include <QPainter> #include <QPainter>
#include <QPainterPath> #include <QPainterPath>
#include <QMouseEvent>
#include <QRadialGradient>
#include <QLinearGradient>
SpinningAlbumArt::SpinningAlbumArt(const QString& imagePath, int size, QWidget* parent) SpinningAlbumArt::SpinningAlbumArt(const QString& imagePath, int size, QWidget* parent)
: QWidget(parent), size_(size) : QWidget(parent), size_(size)
{ {
artLabel_ = new QLabel(this); artLabel_ = new QLabel(this);
artLabel_->setAlignment(Qt::AlignCenter); artLabel_->setAlignment(Qt::AlignCenter);
setFixedSize(size, size); setFixedSize(size, size);
// Load and crop square // Load album art and square-crop it
QPixmap pix(imagePath); QPixmap pix(imagePath);
QPixmap scaled = pix.scaled(size, size, QPixmap scaled = pix.scaled(size, size,
Qt::KeepAspectRatioByExpanding, Qt::KeepAspectRatioByExpanding,
@@ -24,33 +26,121 @@ SpinningAlbumArt::SpinningAlbumArt(const QString& imagePath, int size, QWidget*
side side
); );
// Mask into circle // Build full realistic vinyl disc with grooves + sheen + hole + label
discArt_ = createCircularDisc(square, size); disc_ = buildRecord(square, size);
artLabel_->setPixmap(discArt_);
artLabel_->setPixmap(disc_);
// Setup spin timer
timer_ = new QTimer(this); timer_ = new QTimer(this);
timer_->setInterval(16); timer_->setInterval(16);
connect(timer_, &QTimer::timeout, this, &SpinningAlbumArt::updateRotation); 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); QPixmap disc(size, size);
disc.fill(Qt::transparent); disc.fill(Qt::transparent);
QPointF center(size / 2.0, size / 2.0);
QPainter p(&disc); QPainter p(&disc);
p.setRenderHint(QPainter::Antialiasing); p.setRenderHint(QPainter::Antialiasing);
p.setRenderHint(QPainter::SmoothPixmapTransform);
QPainterPath path; //
path.addEllipse(0, 0, size, size); // 1. Base vinyl gradient
p.setClipPath(path); //
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; 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() void SpinningAlbumArt::start()
{ {
timer_->start(); timer_->start();
@@ -63,7 +153,7 @@ void SpinningAlbumArt::stop()
void SpinningAlbumArt::updateRotation() void SpinningAlbumArt::updateRotation()
{ {
rotationAngle_ += 0.6; rotationAngle_ += 0.5;
QPixmap frame(size_, size_); QPixmap frame(size_, size_);
frame.fill(Qt::transparent); frame.fill(Qt::transparent);
@@ -76,7 +166,7 @@ void SpinningAlbumArt::updateRotation()
p.rotate(rotationAngle_); p.rotate(rotationAngle_);
p.translate(-size_ / 2, -size_ / 2); p.translate(-size_ / 2, -size_ / 2);
p.drawPixmap(0, 0, discArt_); p.drawPixmap(0, 0, disc_);
artLabel_->setPixmap(frame); artLabel_->setPixmap(frame);
} }

View File

@@ -4,14 +4,15 @@
#include <QLabel> #include <QLabel>
#include <QPixmap> #include <QPixmap>
#include <QTimer> #include <QTimer>
#include <QMouseEvent>
class SpinningAlbumArt : public QWidget class SpinningAlbumArt : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: 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: public slots:
void start(); void start();
@@ -20,18 +21,20 @@ public slots:
signals: signals:
void artClicked(); void artClicked();
private slots:
void updateRotation();
protected: protected:
void mousePressEvent(QMouseEvent* event) override; void mousePressEvent(QMouseEvent* event) override;
private: private slots:
QPixmap discArt_; // circular-masked album image void updateRotation();
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); 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_;
}; };