Initial implementation of qobuz-qt
- Rust backend (qobuz-backend static lib): Qobuz API client (reqwest/tokio), Symphonia audio decoder, CPAL audio output, extern "C" FFI bridge - Qt 6 frontend mirroring spotify-qt layout: toolbar with playback controls, left library dock, central track list, right search panel - Auth: email/password login with MD5-signed requests; session token persisted via QSettings - Playback: double-click a track → Rust fetches stream URL → Symphonia decodes → CPAL outputs to default audio device - Dark Fusion palette matching spotify-qt feel Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
75
src/widget/volumebutton.hpp
Normal file
75
src/widget/volumebutton.hpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
|
||||
#include "clickableslider.hpp"
|
||||
#include "../util/icon.hpp"
|
||||
|
||||
#include <QToolButton>
|
||||
#include <QWidgetAction>
|
||||
#include <QMenu>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
/// A toolbar button that shows a volume slider popup when clicked.
|
||||
class VolumeButton : public QToolButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit VolumeButton(QWidget *parent = nullptr) : QToolButton(parent)
|
||||
{
|
||||
setPopupMode(QToolButton::InstantPopup);
|
||||
setIcon(Icon::volumeHigh());
|
||||
|
||||
auto *menu = new QMenu(this);
|
||||
auto *widget = new QWidget(menu);
|
||||
auto *layout = new QVBoxLayout(widget);
|
||||
layout->setContentsMargins(6, 6, 6, 6);
|
||||
|
||||
m_label = new QLabel("80%", widget);
|
||||
m_label->setAlignment(Qt::AlignCenter);
|
||||
|
||||
m_slider = new ClickableSlider(Qt::Vertical, widget);
|
||||
m_slider->setRange(0, 100);
|
||||
m_slider->setValue(80);
|
||||
m_slider->setFixedHeight(120);
|
||||
|
||||
layout->addWidget(m_label);
|
||||
layout->addWidget(m_slider);
|
||||
|
||||
auto *action = new QWidgetAction(menu);
|
||||
action->setDefaultWidget(widget);
|
||||
menu->addAction(action);
|
||||
setMenu(menu);
|
||||
|
||||
connect(m_slider, &QSlider::valueChanged, this, [this](int v) {
|
||||
m_label->setText(QString::number(v) + "%");
|
||||
updateIcon(v);
|
||||
emit volumeChanged(v);
|
||||
});
|
||||
}
|
||||
|
||||
int value() const { return m_slider->value(); }
|
||||
|
||||
void setValue(int v)
|
||||
{
|
||||
m_slider->blockSignals(true);
|
||||
m_slider->setValue(v);
|
||||
m_slider->blockSignals(false);
|
||||
m_label->setText(QString::number(v) + "%");
|
||||
updateIcon(v);
|
||||
}
|
||||
|
||||
signals:
|
||||
void volumeChanged(int volume);
|
||||
|
||||
private:
|
||||
ClickableSlider *m_slider = nullptr;
|
||||
QLabel *m_label = nullptr;
|
||||
|
||||
void updateIcon(int v)
|
||||
{
|
||||
if (v == 0) setIcon(Icon::volumeMute());
|
||||
else if (v < 50) setIcon(Icon::volumeMid());
|
||||
else setIcon(Icon::volumeHigh());
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user