feat: add deep shuffle in genre browse and tighten toolbar layout
Some checks failed
Build for Windows / build-windows (push) Has been cancelled
Some checks failed
Build for Windows / build-windows (push) Has been cancelled
This commit is contained in:
@@ -15,9 +15,10 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
GenreBrowserView::GenreBrowserView(QobuzBackend *backend, QWidget *parent)
|
||||
GenreBrowserView::GenreBrowserView(QobuzBackend *backend, PlayQueue *queue, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_backend(backend)
|
||||
, m_queue(queue)
|
||||
{
|
||||
auto *layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
@@ -26,31 +27,34 @@ GenreBrowserView::GenreBrowserView(QobuzBackend *backend, QWidget *parent)
|
||||
auto *topBar = new QWidget(this);
|
||||
auto *topLayout = new QHBoxLayout(topBar);
|
||||
topLayout->setContentsMargins(8, 6, 8, 6);
|
||||
topLayout->setSpacing(6);
|
||||
|
||||
m_browseLabel = new QLabel(tr("Show:"), this);
|
||||
topLayout->addWidget(m_browseLabel);
|
||||
m_kindCombo = new QComboBox(this);
|
||||
m_kindCombo->addItem(tr("Albums"), QStringLiteral("albums"));
|
||||
m_kindCombo->addItem(tr("Playlists"), QStringLiteral("playlists"));
|
||||
m_kindCombo->setMinimumWidth(110);
|
||||
topLayout->addWidget(m_kindCombo);
|
||||
|
||||
m_gapAfterKind = new QWidget(this);
|
||||
m_gapAfterKind->setFixedWidth(12);
|
||||
m_gapAfterKind->setFixedWidth(6);
|
||||
topLayout->addWidget(m_gapAfterKind);
|
||||
|
||||
m_genreLabel = new QLabel(tr("Genre:"), this);
|
||||
topLayout->addWidget(m_genreLabel);
|
||||
m_genreCombo = new QComboBox(this);
|
||||
m_genreCombo->setMinimumWidth(160);
|
||||
m_genreCombo->setMinimumWidth(180);
|
||||
topLayout->addWidget(m_genreCombo);
|
||||
|
||||
m_gapAfterGenre = new QWidget(this);
|
||||
m_gapAfterGenre->setFixedWidth(16);
|
||||
m_gapAfterGenre->setFixedWidth(10);
|
||||
topLayout->addWidget(m_gapAfterGenre);
|
||||
|
||||
m_typeLabel = new QLabel(tr("Type:"), this);
|
||||
topLayout->addWidget(m_typeLabel);
|
||||
m_typeCombo = new QComboBox(this);
|
||||
m_typeCombo->setMinimumWidth(180);
|
||||
topLayout->addWidget(m_typeCombo);
|
||||
|
||||
m_playlistSearchLabel = new QLabel(tr("Search:"), this);
|
||||
@@ -61,14 +65,18 @@ GenreBrowserView::GenreBrowserView(QobuzBackend *backend, QWidget *parent)
|
||||
m_playlistSearchBox->setPlaceholderText(tr("Search playlists..."));
|
||||
m_playlistSearchBox->setClearButtonEnabled(true);
|
||||
m_playlistSearchBox->setVisible(false);
|
||||
m_playlistSearchBox->setMinimumWidth(180);
|
||||
m_playlistSearchBox->setMinimumWidth(220);
|
||||
m_playlistSearchBox->setMaximumWidth(320);
|
||||
topLayout->addWidget(m_playlistSearchBox);
|
||||
|
||||
m_playlistSearchBtn = new QPushButton(tr("Search"), this);
|
||||
m_playlistSearchBtn = new QPushButton(tr("Go"), this);
|
||||
m_playlistSearchBtn->setVisible(false);
|
||||
topLayout->addWidget(m_playlistSearchBtn);
|
||||
|
||||
m_deepShuffleBtn = new QPushButton(tr("⇄ Deep Shuffle"), this);
|
||||
m_deepShuffleBtn->setVisible(false);
|
||||
topLayout->addWidget(m_deepShuffleBtn);
|
||||
|
||||
topLayout->addStretch();
|
||||
layout->addWidget(topBar);
|
||||
|
||||
@@ -137,6 +145,8 @@ GenreBrowserView::GenreBrowserView(QobuzBackend *backend, QWidget *parent)
|
||||
this, &GenreBrowserView::onSelectionChanged);
|
||||
connect(m_playlistSearchBtn, &QPushButton::clicked,
|
||||
this, &GenreBrowserView::onSelectionChanged);
|
||||
connect(m_deepShuffleBtn, &QPushButton::clicked,
|
||||
this, &GenreBrowserView::onDeepShuffleClicked);
|
||||
connect(m_albumList, &AlbumListView::albumSelected,
|
||||
this, &GenreBrowserView::albumSelected);
|
||||
connect(m_albumList, &QTreeWidget::customContextMenuRequested,
|
||||
@@ -183,6 +193,7 @@ void GenreBrowserView::refreshModeUi()
|
||||
m_playlistSearchBox->setVisible(false);
|
||||
m_playlistSearchLabel->setVisible(false);
|
||||
m_playlistSearchBtn->setVisible(false);
|
||||
m_deepShuffleBtn->setVisible(m_kindCombo->currentData().toString() == QStringLiteral("albums"));
|
||||
refreshGenreTypeChoices();
|
||||
return;
|
||||
}
|
||||
@@ -194,6 +205,7 @@ void GenreBrowserView::refreshModeUi()
|
||||
m_playlistSearchLabel->setVisible(true);
|
||||
m_playlistSearchBox->setVisible(true);
|
||||
m_playlistSearchBtn->setVisible(true);
|
||||
m_deepShuffleBtn->setVisible(false);
|
||||
m_resultsStack->setCurrentIndex(1);
|
||||
}
|
||||
|
||||
@@ -210,6 +222,7 @@ void GenreBrowserView::refreshGenreTypeChoices()
|
||||
m_typeCombo->addItem(tr("Discover: Focus"), QStringLiteral("discover-focus"));
|
||||
m_typeCombo->addItem(tr("Discover: Qobuz Digs"), QStringLiteral("discover-qobuzdigs"));
|
||||
m_resultsStack->setCurrentIndex(1);
|
||||
m_deepShuffleBtn->setVisible(false);
|
||||
} else {
|
||||
m_typeCombo->addItem(tr("New Releases"), QStringLiteral("new-releases"));
|
||||
m_typeCombo->addItem(tr("Best Sellers"), QStringLiteral("best-sellers"));
|
||||
@@ -217,6 +230,7 @@ void GenreBrowserView::refreshGenreTypeChoices()
|
||||
m_typeCombo->addItem(tr("Editor Picks"), QStringLiteral("editor-picks"));
|
||||
m_typeCombo->addItem(tr("Press Awards"), QStringLiteral("press-awards"));
|
||||
m_resultsStack->setCurrentIndex(0);
|
||||
m_deepShuffleBtn->setVisible(m_mode == BrowseMode::Genres);
|
||||
}
|
||||
|
||||
m_typeCombo->blockSignals(false);
|
||||
@@ -351,6 +365,7 @@ void GenreBrowserView::onSelectionChanged()
|
||||
m_playlistSearchLabel->setVisible(true);
|
||||
m_playlistSearchBox->setVisible(true);
|
||||
m_playlistSearchBtn->setVisible(true);
|
||||
m_deepShuffleBtn->setVisible(false);
|
||||
const QString query = m_playlistSearchBox->text().trimmed();
|
||||
if (query.size() < 2) {
|
||||
m_playlistList->clear();
|
||||
@@ -384,10 +399,55 @@ void GenreBrowserView::onSelectionChanged()
|
||||
m_backend->getFeaturedPlaylists(genreIds, type, 25, 0);
|
||||
} else {
|
||||
m_resultsStack->setCurrentIndex(0);
|
||||
m_deepShuffleBtn->setVisible(m_mode == BrowseMode::Genres);
|
||||
m_backend->getFeaturedAlbums(genreIds, type, 50, 0);
|
||||
}
|
||||
}
|
||||
|
||||
QStringList GenreBrowserView::currentAlbumIds() const
|
||||
{
|
||||
QStringList ids;
|
||||
for (int i = 0; i < m_albumList->topLevelItemCount(); ++i) {
|
||||
const QString id = m_albumList->topLevelItem(i)->data(1, Qt::UserRole).toString();
|
||||
if (!id.isEmpty())
|
||||
ids.push_back(id);
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
void GenreBrowserView::onDeepShuffleClicked()
|
||||
{
|
||||
const QStringList albumIds = currentAlbumIds();
|
||||
if (albumIds.isEmpty())
|
||||
return;
|
||||
|
||||
m_waitingDeepShuffle = true;
|
||||
m_deepShuffleBtn->setEnabled(false);
|
||||
m_deepShuffleBtn->setText(tr("Loading…"));
|
||||
m_backend->getAlbumsTracks(albumIds);
|
||||
}
|
||||
|
||||
bool GenreBrowserView::tryHandleDeepShuffleTracks(const QJsonArray &tracks)
|
||||
{
|
||||
if (!m_waitingDeepShuffle)
|
||||
return false;
|
||||
|
||||
m_waitingDeepShuffle = false;
|
||||
m_deepShuffleBtn->setEnabled(true);
|
||||
m_deepShuffleBtn->setText(tr("⇄ Deep Shuffle"));
|
||||
|
||||
if (tracks.isEmpty())
|
||||
return true;
|
||||
|
||||
m_queue->setContext(tracks, 0);
|
||||
m_queue->shuffleNow();
|
||||
const QJsonObject first = m_queue->current();
|
||||
const qint64 id = static_cast<qint64>(first["id"].toDouble());
|
||||
if (id > 0)
|
||||
emit playTrackRequested(id);
|
||||
return true;
|
||||
}
|
||||
|
||||
void GenreBrowserView::onAlbumContextMenu(const QPoint &pos)
|
||||
{
|
||||
QTreeWidgetItem *item = m_albumList->itemAt(pos);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../backend/qobuzbackend.hpp"
|
||||
#include "../playqueue.hpp"
|
||||
#include "albumlistview.hpp"
|
||||
|
||||
#include <QComboBox>
|
||||
@@ -24,15 +25,17 @@ public:
|
||||
PlaylistSearch,
|
||||
};
|
||||
|
||||
explicit GenreBrowserView(QobuzBackend *backend, QWidget *parent = nullptr);
|
||||
explicit GenreBrowserView(QobuzBackend *backend, PlayQueue *queue, QWidget *parent = nullptr);
|
||||
|
||||
void ensureGenresLoaded();
|
||||
void setBrowseMode(BrowseMode mode);
|
||||
bool tryHandleDeepShuffleTracks(const QJsonArray &tracks);
|
||||
|
||||
signals:
|
||||
void albumSelected(const QString &albumId);
|
||||
void artistSelected(qint64 artistId);
|
||||
void playlistSelected(qint64 playlistId);
|
||||
void playTrackRequested(qint64 trackId);
|
||||
|
||||
private slots:
|
||||
void onGenresLoaded(const QJsonObject &result);
|
||||
@@ -44,9 +47,11 @@ private slots:
|
||||
void onAlbumContextMenu(const QPoint &pos);
|
||||
void onPlaylistActivated(QTreeWidgetItem *item, int column);
|
||||
void onPlaylistContextMenu(const QPoint &pos);
|
||||
void onDeepShuffleClicked();
|
||||
|
||||
private:
|
||||
QobuzBackend *m_backend = nullptr;
|
||||
PlayQueue *m_queue = nullptr;
|
||||
QLabel *m_browseLabel = nullptr;
|
||||
QLabel *m_genreLabel = nullptr;
|
||||
QLabel *m_typeLabel = nullptr;
|
||||
@@ -58,6 +63,7 @@ private:
|
||||
QComboBox *m_typeCombo = nullptr;
|
||||
QLineEdit *m_playlistSearchBox = nullptr;
|
||||
QPushButton *m_playlistSearchBtn = nullptr;
|
||||
QPushButton *m_deepShuffleBtn = nullptr;
|
||||
QStackedWidget *m_resultsStack = nullptr;
|
||||
AlbumListView *m_albumList = nullptr;
|
||||
QTreeWidget *m_playlistList = nullptr;
|
||||
@@ -65,10 +71,12 @@ private:
|
||||
bool m_genresLoaded = false;
|
||||
int m_lastGenreComboIndex = 0;
|
||||
QSet<qint64> m_multiGenreIds;
|
||||
bool m_waitingDeepShuffle = false;
|
||||
|
||||
void refreshModeUi();
|
||||
void refreshGenreTypeChoices();
|
||||
QString currentGenreIds() const;
|
||||
QStringList currentAlbumIds() const;
|
||||
bool chooseMultiGenres();
|
||||
void updateMultiGenreLabel();
|
||||
void setPlaylistItems(const QJsonArray &items);
|
||||
|
||||
@@ -52,7 +52,7 @@ MainContent::MainContent(QobuzBackend *backend, PlayQueue *queue, QWidget *paren
|
||||
m_albumList = new AlbumListView(this);
|
||||
m_artistList = new ArtistListView(this);
|
||||
m_artistView = new ArtistView(backend, queue, this);
|
||||
m_genreBrowser = new GenreBrowserView(backend, this);
|
||||
m_genreBrowser = new GenreBrowserView(backend, queue, this);
|
||||
|
||||
m_stack->addWidget(m_welcome); // 0
|
||||
m_stack->addWidget(tracksPage); // 1
|
||||
@@ -70,6 +70,7 @@ MainContent::MainContent(QobuzBackend *backend, PlayQueue *queue, QWidget *paren
|
||||
connect(m_genreBrowser, &GenreBrowserView::albumSelected, this, &MainContent::albumRequested);
|
||||
connect(m_genreBrowser, &GenreBrowserView::artistSelected, this, &MainContent::artistRequested);
|
||||
connect(m_genreBrowser, &GenreBrowserView::playlistSelected, this, &MainContent::playlistRequested);
|
||||
connect(m_genreBrowser, &GenreBrowserView::playTrackRequested, this, &MainContent::playTrackRequested);
|
||||
}
|
||||
|
||||
void MainContent::showWelcome() { m_stack->setCurrentIndex(0); }
|
||||
@@ -132,6 +133,8 @@ void MainContent::setFavArtistIds(const QSet<qint64> &ids)
|
||||
|
||||
void MainContent::onDeepShuffleTracks(const QJsonArray &tracks)
|
||||
{
|
||||
if (m_genreBrowser->tryHandleDeepShuffleTracks(tracks))
|
||||
return;
|
||||
m_artistView->onDeepShuffleTracks(tracks);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user