#include "view.hpp" #include #include #include namespace Context { View::View(QobuzBackend *backend, QWidget *parent) : QDockWidget(tr("Now Playing"), parent) , m_backend(backend) { setObjectName(QStringLiteral("contextDock")); setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetClosable); m_nam = new QNetworkAccessManager(this); connect(m_nam, &QNetworkAccessManager::finished, this, &View::onArtReady); auto *container = new QWidget(this); auto *layout = new QVBoxLayout(container); layout->setContentsMargins(8, 8, 8, 8); layout->setSpacing(6); m_albumArt = new QLabel(container); m_albumArt->setAlignment(Qt::AlignCenter); m_albumArt->setStyleSheet(QStringLiteral( "background: #1a1a1a; border-radius: 4px;")); m_albumArt->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); layout->addWidget(m_albumArt); m_title = new QLabel(tr("Not playing"), container); m_title->setAlignment(Qt::AlignCenter); m_title->setWordWrap(true); QFont titleFont = m_title->font(); titleFont.setPointSizeF(titleFont.pointSizeF() * 1.05); titleFont.setBold(true); m_title->setFont(titleFont); layout->addWidget(m_title); m_artist = new QLabel(QString(), container); m_artist->setAlignment(Qt::AlignCenter); m_artist->setWordWrap(true); layout->addWidget(m_artist); layout->addStretch(); setWidget(container); setMinimumWidth(160); connect(m_backend, &QobuzBackend::trackChanged, this, &View::onTrackChanged); } void View::onTrackChanged(const QJsonObject &track) { const QString title = track["title"].toString(); const QString artist = track["performer"].toObject()["name"].toString().isEmpty() ? track["album"].toObject()["artist"].toObject()["name"].toString() : track["performer"].toObject()["name"].toString(); m_title->setText(title.isEmpty() ? tr("Not playing") : title); m_artist->setText(artist); // Prefer "large" image, fall back to "small" const QJsonObject img = track["album"].toObject()["image"].toObject(); QString artUrl = img["large"].toString(); if (artUrl.isEmpty()) artUrl = img["small"].toString(); if (!artUrl.isEmpty() && artUrl != m_currentArtUrl) { m_currentArtUrl = artUrl; m_nam->get(QNetworkRequest(QUrl(artUrl))); } } void View::onArtReady(QNetworkReply *reply) { reply->deleteLater(); if (reply->error() != QNetworkReply::NoError) return; if (m_artPixmap.loadFromData(reply->readAll())) scaleArtToWidth(); } void View::resizeEvent(QResizeEvent *event) { QDockWidget::resizeEvent(event); scaleArtToWidth(); } void View::scaleArtToWidth() { if (m_artPixmap.isNull()) return; // Available width = dock width minus the 8px margins on each side const int side = qMax(32, widget() ? widget()->width() - 16 : width() - 16); m_albumArt->setFixedSize(side, side); m_albumArt->setPixmap(m_artPixmap.scaled(side, side, Qt::KeepAspectRatio, Qt::SmoothTransformation)); } } // namespace Context