diff --git a/src/view/maintoolbar.cpp b/src/view/maintoolbar.cpp index 61adc64..0530096 100644 --- a/src/view/maintoolbar.cpp +++ b/src/view/maintoolbar.cpp @@ -2,11 +2,8 @@ #include "../util/settings.hpp" #include "../model/tracklistmodel.hpp" -#include -#include -#include -#include #include +#include MainToolBar::MainToolBar(QobuzBackend *backend, PlayQueue *queue, QWidget *parent) : QToolBar(parent) @@ -21,123 +18,79 @@ MainToolBar::MainToolBar(QobuzBackend *backend, PlayQueue *queue, QWidget *paren m_nam = new QNetworkAccessManager(this); connect(m_nam, &QNetworkAccessManager::finished, this, &MainToolBar::onAlbumArtReady); - // ---------------------------------------------------------------- - // Root container — three equal-stretch columns - // ---------------------------------------------------------------- - auto *root = new QWidget(this); - auto *rootLo = new QHBoxLayout(root); - rootLo->setContentsMargins(6, 2, 6, 2); - rootLo->setSpacing(0); - - // ---- LEFT: album art | track info | prev/play/next ---- - auto *leftWidget = new QWidget(root); - auto *leftLo = new QHBoxLayout(leftWidget); - leftLo->setContentsMargins(0, 0, 0, 0); - leftLo->setSpacing(8); - - m_artLabel = new QLabel(leftWidget); - m_artLabel->setFixedSize(44, 44); + // ---- Album art ---- + m_artLabel = new QLabel(this); + m_artLabel->setFixedSize(36, 36); m_artLabel->setScaledContents(true); m_artLabel->setStyleSheet("border: 1px solid #444; background: #1a1a1a; border-radius: 3px;"); - m_artLabel->setPixmap(QIcon(":/res/icons/view-media-album-cover.svg").pixmap(40, 40)); + m_artLabel->setPixmap(QIcon(":/res/icons/view-media-album-cover.svg").pixmap(32, 32)); + addWidget(m_artLabel); - m_trackLabel = new QLabel(tr("Not playing"), leftWidget); - m_trackLabel->setMinimumWidth(100); - m_trackLabel->setMaximumWidth(220); + // ---- Track label ---- + m_trackLabel = new QLabel(tr("Not playing"), this); + m_trackLabel->setMinimumWidth(80); + m_trackLabel->setMaximumWidth(200); m_trackLabel->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); - m_trackLabel->setWordWrap(false); + addWidget(m_trackLabel); - auto makeBtn = [&](const QIcon &icon, const QString &tip) -> QToolButton * { - auto *btn = new QToolButton(leftWidget); - btn->setIcon(icon); - btn->setToolTip(tip); - btn->setAutoRaise(true); - btn->setIconSize(QSize(22, 22)); - return btn; - }; + addSeparator(); - m_prevBtn = makeBtn(Icon::previous(), tr("Previous")); - m_playBtn = makeBtn(Icon::play(), tr("Play")); - m_playBtn->setIconSize(QSize(28, 28)); - m_nextBtn = makeBtn(Icon::next(), tr("Next")); + // ---- Media controls ---- + m_previous = addAction(Icon::previous(), tr("Previous")); + connect(m_previous, &QAction::triggered, this, &MainToolBar::onPrevious); - connect(m_prevBtn, &QToolButton::clicked, this, &MainToolBar::onPrevious); - connect(m_playBtn, &QToolButton::clicked, this, &MainToolBar::onPlayPause); - connect(m_nextBtn, &QToolButton::clicked, this, &MainToolBar::onNext); + m_playPause = addAction(Icon::play(), tr("Play")); + connect(m_playPause, &QAction::triggered, this, &MainToolBar::onPlayPause); - leftLo->addWidget(m_artLabel); - leftLo->addWidget(m_trackLabel); - leftLo->addWidget(m_prevBtn); - leftLo->addWidget(m_playBtn); - leftLo->addWidget(m_nextBtn); + m_next = addAction(Icon::next(), tr("Next")); + connect(m_next, &QAction::triggered, this, &MainToolBar::onNext); - // ---- CENTER: elapsed | progress slider | total ---- - auto *centerWidget = new QWidget(root); - auto *centerLo = new QHBoxLayout(centerWidget); - centerLo->setContentsMargins(0, 0, 0, 0); - centerLo->setSpacing(6); + // ---- Left spacer (pushes progress toward center) ---- + m_leftSpacer = new QWidget(this); + m_leftSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + addWidget(m_leftSpacer); - m_elapsedLabel = new QLabel(QStringLiteral("0:00"), centerWidget); - m_elapsedLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); - m_elapsedLabel->setMinimumWidth(36); - - m_progress = new ClickableSlider(Qt::Horizontal, centerWidget); + // ---- Progress slider ---- + m_progress = new ClickableSlider(Qt::Horizontal, this); m_progress->setRange(0, 1000); m_progress->setValue(0); - m_progress->setMinimumWidth(160); - - m_totalLabel = new QLabel(QStringLiteral("0:00"), centerWidget); - m_totalLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); - m_totalLabel->setMinimumWidth(36); - + m_progress->setMinimumWidth(200); + m_progress->setMaximumWidth(500); + addWidget(m_progress); connect(m_progress, &QSlider::sliderPressed, this, [this] { m_seeking = true; }); connect(m_progress, &QSlider::sliderReleased, this, &MainToolBar::onProgressReleased); - centerLo->addWidget(m_elapsedLabel); - centerLo->addWidget(m_progress, 1); - centerLo->addWidget(m_totalLabel); + // ---- Position label ---- + m_position = new QLabel(QStringLiteral("0:00 / 0:00"), this); + m_position->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); + m_position->setMinimumWidth(80); + addWidget(m_position); - // ---- RIGHT: volume + shuffle + queue + search ---- - auto *rightWidget = new QWidget(root); - auto *rightLo = new QHBoxLayout(rightWidget); - rightLo->setContentsMargins(0, 0, 0, 0); - rightLo->setSpacing(4); + // ---- Right spacer (mirrors left spacer) ---- + m_rightSpacer = new QWidget(this); + m_rightSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + addWidget(m_rightSpacer); - m_volume = new VolumeButton(rightWidget); + // ---- Shuffle ---- + m_shuffle = addAction(Icon::get(QStringLiteral("media-playlist-shuffle")), tr("Shuffle")); + m_shuffle->setCheckable(true); + connect(m_shuffle, &QAction::toggled, this, &MainToolBar::onShuffleToggled); + + // ---- Volume ---- + m_volume = new VolumeButton(this); m_volume->setValue(AppSettings::instance().volume()); + addWidget(m_volume); connect(m_volume, &VolumeButton::volumeChanged, this, &MainToolBar::onVolumeChanged); - auto makeToggle = [&](const QIcon &icon, const QString &tip) -> QToolButton * { - auto *btn = new QToolButton(rightWidget); - btn->setIcon(icon); - btn->setToolTip(tip); - btn->setCheckable(true); - btn->setAutoRaise(true); - btn->setIconSize(QSize(22, 22)); - return btn; - }; + // ---- Queue toggle ---- + m_queueBtn = addAction(Icon::queue(), tr("Queue")); + m_queueBtn->setCheckable(true); + connect(m_queueBtn, &QAction::toggled, this, &MainToolBar::queueToggled); - m_shuffleBtn = makeToggle(Icon::get(QStringLiteral("media-playlist-shuffle")), tr("Shuffle")); - m_queueBtn = makeToggle(Icon::queue(), tr("Queue")); - m_searchBtn = makeToggle(Icon::search(), tr("Search")); - - connect(m_shuffleBtn, &QToolButton::toggled, this, &MainToolBar::onShuffleToggled); - connect(m_queueBtn, &QToolButton::toggled, this, &MainToolBar::queueToggled); - connect(m_searchBtn, &QToolButton::toggled, this, &MainToolBar::searchToggled); - - rightLo->addStretch(1); - rightLo->addWidget(m_volume); - rightLo->addWidget(m_shuffleBtn); - rightLo->addWidget(m_queueBtn); - rightLo->addWidget(m_searchBtn); - - // ---- Assemble root: equal stretch keeps center bar centred ---- - rootLo->addWidget(leftWidget, 1); - rootLo->addWidget(centerWidget, 2); - rootLo->addWidget(rightWidget, 1); - - root->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - addWidget(root); + // ---- Search toggle ---- + m_search = addAction(Icon::search(), tr("Search")); + m_search->setCheckable(true); + connect(m_search, &QAction::toggled, this, &MainToolBar::searchToggled); // ---- Backend signals ---- connect(m_backend, &QobuzBackend::stateChanged, this, &MainToolBar::onBackendStateChanged); @@ -150,13 +103,23 @@ MainToolBar::MainToolBar(QobuzBackend *backend, PlayQueue *queue, QWidget *paren onQueueChanged(); } +// ---- resize: keep spacers equal so progress stays centred ---- + +void MainToolBar::resizeEvent(QResizeEvent *event) +{ + QToolBar::resizeEvent(event); + const int spacerWidth = event->size().width() / 6; + m_leftSpacer->setMinimumWidth(spacerWidth); + m_rightSpacer->setMinimumWidth(spacerWidth); +} + // ---- public ---- void MainToolBar::setPlaying(bool playing) { m_playing = playing; - m_playBtn->setIcon(playing ? Icon::pause() : Icon::play()); - m_playBtn->setToolTip(playing ? tr("Pause") : tr("Play")); + m_playPause->setIcon(playing ? Icon::pause() : Icon::play()); + m_playPause->setText(playing ? tr("Pause") : tr("Play")); } void MainToolBar::setCurrentTrack(const QJsonObject &track) @@ -171,7 +134,7 @@ void MainToolBar::setCurrentTrack(const QJsonObject &track) } else if (artist.isEmpty()) { m_trackLabel->setText(title); } else { - m_trackLabel->setText(QStringLiteral("%1\n%2").arg(title, artist)); + m_trackLabel->setText(QStringLiteral("%1 — %2").arg(title, artist)); } const QString artUrl = track["album"].toObject()["image"].toObject()["small"].toString(); @@ -189,8 +152,10 @@ void MainToolBar::updateProgress(quint64 position, quint64 duration) m_progress->blockSignals(true); m_progress->setValue(sliderPos); m_progress->blockSignals(false); - m_elapsedLabel->setText(TrackListModel::formatDuration(static_cast(position))); - m_totalLabel->setText(TrackListModel::formatDuration(static_cast(duration))); + m_position->setText( + QStringLiteral("%1 / %2") + .arg(TrackListModel::formatDuration(static_cast(position)), + TrackListModel::formatDuration(static_cast(duration)))); } // ---- private slots ---- @@ -257,15 +222,14 @@ void MainToolBar::onTrackFinished() } else { setPlaying(false); m_progress->setValue(0); - m_elapsedLabel->setText(QStringLiteral("0:00")); - m_totalLabel->setText(QStringLiteral("0:00")); + m_position->setText(QStringLiteral("0:00 / 0:00")); } } void MainToolBar::onQueueChanged() { - m_prevBtn->setEnabled(m_queue->canGoPrev()); - m_nextBtn->setEnabled(m_queue->canGoNext()); + m_previous->setEnabled(m_queue->canGoPrev()); + m_next->setEnabled(m_queue->canGoNext()); } void MainToolBar::onShuffleToggled(bool checked) diff --git a/src/view/maintoolbar.hpp b/src/view/maintoolbar.hpp index 77492db..2b30a0e 100644 --- a/src/view/maintoolbar.hpp +++ b/src/view/maintoolbar.hpp @@ -7,8 +7,8 @@ #include "../util/icon.hpp" #include -#include #include +#include #include #include #include @@ -28,6 +28,9 @@ signals: void searchToggled(bool visible); void queueToggled(bool visible); +protected: + void resizeEvent(QResizeEvent *event) override; + private slots: void onPlayPause(); void onPrevious(); @@ -49,23 +52,19 @@ private: QobuzBackend *m_backend = nullptr; PlayQueue *m_queue = nullptr; - // Left - QLabel *m_artLabel = nullptr; - QLabel *m_trackLabel = nullptr; - - // Center - QToolButton *m_prevBtn = nullptr; - QToolButton *m_playBtn = nullptr; - QToolButton *m_nextBtn = nullptr; - ClickableSlider *m_progress = nullptr; - QLabel *m_elapsedLabel = nullptr; - QLabel *m_totalLabel = nullptr; - - // Right - VolumeButton *m_volume = nullptr; - QToolButton *m_shuffleBtn = nullptr; - QToolButton *m_queueBtn = nullptr; - QToolButton *m_searchBtn = nullptr; + QLabel *m_artLabel = nullptr; + QLabel *m_trackLabel = nullptr; + QAction *m_previous = nullptr; + QAction *m_playPause = nullptr; + QAction *m_next = nullptr; + QWidget *m_leftSpacer = nullptr; + ClickableSlider *m_progress = nullptr; + QLabel *m_position = nullptr; + QWidget *m_rightSpacer = nullptr; + QAction *m_shuffle = nullptr; + VolumeButton *m_volume = nullptr; + QAction *m_queueBtn = nullptr; + QAction *m_search = nullptr; QNetworkAccessManager *m_nam = nullptr; QString m_currentArtUrl;