mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-04 17:33:05 +00:00
add application volume control
Change-Id: If25cf5e72839631932eec7b32d77ff65d29067bd
This commit is contained in:
parent
519f63415a
commit
008a2858d9
Notes:
Deepin Code Review
2016-08-03 03:26:38 +00:00
Verified+1: Anonymous Coward #1000004 Code-Review+2: 石博文 <sbw@sbw.so> Submitted-by: 石博文 <sbw@sbw.so> Submitted-at: Wed, 03 Aug 2016 03:26:38 +0000 Reviewed-on: https://cr.deepin.io/14888 Project: dde/dde-dock Branch: refs/heads/master
@ -8,6 +8,8 @@ VolumeSlider::VolumeSlider(QWidget *parent)
|
||||
: QSlider(Qt::Horizontal, parent),
|
||||
m_pressed(false)
|
||||
{
|
||||
setMinimum(0);
|
||||
setMaximum(1000);
|
||||
setTickInterval(50);
|
||||
setPageStep(50);
|
||||
setTickPosition(QSlider::NoTicks);
|
||||
@ -30,7 +32,7 @@ void VolumeSlider::mousePressEvent(QMouseEvent *e)
|
||||
if (!rect().contains(e->pos()))
|
||||
return;
|
||||
m_pressed = true;
|
||||
QSlider::setValue(minimum() + (double((maximum()) - minimum()) * e->x() / rect().width()));
|
||||
QSlider::setValue(1000.0 * e->x() / rect().width());
|
||||
}
|
||||
}
|
||||
|
||||
|
24
plugins/sound/dbus/com.deepin.daemon.Audio.SinkInput.xml
Normal file
24
plugins/sound/dbus/com.deepin.daemon.Audio.SinkInput.xml
Normal file
@ -0,0 +1,24 @@
|
||||
<interface name="com.deepin.daemon.Audio.SinkInput">
|
||||
<method name="SetBalance">
|
||||
<arg type="d" direction="in"></arg>
|
||||
<arg type="b" direction="in"></arg>
|
||||
</method>
|
||||
<method name="SetFade">
|
||||
<arg type="d" direction="in"></arg>
|
||||
</method>
|
||||
<method name="SetMute">
|
||||
<arg type="b" direction="in"></arg>
|
||||
</method>
|
||||
<method name="SetVolume">
|
||||
<arg type="d" direction="in"></arg>
|
||||
<arg type="b" direction="in"></arg>
|
||||
</method>
|
||||
<property name="Name" type="s" access="read"></property>
|
||||
<property name="Icon" type="s" access="read"></property>
|
||||
<property name="Mute" type="b" access="read"></property>
|
||||
<property name="Volume" type="d" access="read"></property>
|
||||
<property name="Balance" type="d" access="read"></property>
|
||||
<property name="SupportBalance" type="b" access="read"></property>
|
||||
<property name="Fade" type="d" access="read"></property>
|
||||
<property name="SupportFade" type="b" access="read"></property>
|
||||
</interface>
|
28
plugins/sound/dbus/dbussinkinput.cpp
Normal file
28
plugins/sound/dbus/dbussinkinput.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp version 0.8
|
||||
* Command line was: qdbusxml2cpp -c DBusSinkInput -p dbussinkinput com.deepin.daemon.Audio.SinkInput.xml
|
||||
*
|
||||
* qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* This file may have been hand-edited. Look for HAND-EDIT comments
|
||||
* before re-generating it.
|
||||
*/
|
||||
|
||||
#include "dbussinkinput.h"
|
||||
|
||||
/*
|
||||
* Implementation of interface class DBusSinkInput
|
||||
*/
|
||||
|
||||
DBusSinkInput::DBusSinkInput(const QString &path, QObject *parent)
|
||||
: QDBusAbstractInterface("com.deepin.daemon.Audio", path, staticInterfaceName(), QDBusConnection::sessionBus(), parent)
|
||||
{
|
||||
QDBusConnection::sessionBus().connect(this->service(), this->path(), "org.freedesktop.DBus.Properties", "PropertiesChanged","sa{sv}as", this, SLOT(__propertyChanged__(QDBusMessage)));
|
||||
}
|
||||
|
||||
DBusSinkInput::~DBusSinkInput()
|
||||
{
|
||||
QDBusConnection::sessionBus().disconnect(service(), path(), "org.freedesktop.DBus.Properties", "PropertiesChanged", "sa{sv}as", this, SLOT(propertyChanged(QDBusMessage)));
|
||||
}
|
||||
|
140
plugins/sound/dbus/dbussinkinput.h
Normal file
140
plugins/sound/dbus/dbussinkinput.h
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp version 0.8
|
||||
* Command line was: qdbusxml2cpp -c DBusSinkInput -p dbussinkinput com.deepin.daemon.Audio.SinkInput.xml
|
||||
*
|
||||
* qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* Do not edit! All changes made to it will be lost.
|
||||
*/
|
||||
|
||||
#ifndef DBUSSINKINPUT_H_1470190809
|
||||
#define DBUSSINKINPUT_H_1470190809
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtDBus/QtDBus>
|
||||
|
||||
/*
|
||||
* Proxy class for interface com.deepin.daemon.Audio.SinkInput
|
||||
*/
|
||||
class DBusSinkInput: public QDBusAbstractInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_SLOT void __propertyChanged__(const QDBusMessage& msg)
|
||||
{
|
||||
QList<QVariant> arguments = msg.arguments();
|
||||
if (3 != arguments.count())
|
||||
return;
|
||||
QString interfaceName = msg.arguments().at(0).toString();
|
||||
if (interfaceName !="com.deepin.daemon.Audio.SinkInput")
|
||||
return;
|
||||
QVariantMap changedProps = qdbus_cast<QVariantMap>(arguments.at(1).value<QDBusArgument>());
|
||||
foreach(const QString &prop, changedProps.keys()) {
|
||||
const QMetaObject* self = metaObject();
|
||||
for (int i=self->propertyOffset(); i < self->propertyCount(); ++i) {
|
||||
QMetaProperty p = self->property(i);
|
||||
if (p.name() == prop) {
|
||||
Q_EMIT p.notifySignal().invoke(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public:
|
||||
static inline const char *staticInterfaceName()
|
||||
{ return "com.deepin.daemon.Audio.SinkInput"; }
|
||||
|
||||
public:
|
||||
explicit DBusSinkInput(const QString &path, QObject *parent = 0);
|
||||
|
||||
~DBusSinkInput();
|
||||
|
||||
Q_PROPERTY(double Balance READ balance NOTIFY BalanceChanged)
|
||||
inline double balance() const
|
||||
{ return qvariant_cast< double >(property("Balance")); }
|
||||
|
||||
Q_PROPERTY(double Fade READ fade NOTIFY FadeChanged)
|
||||
inline double fade() const
|
||||
{ return qvariant_cast< double >(property("Fade")); }
|
||||
|
||||
Q_PROPERTY(QString Icon READ icon NOTIFY IconChanged)
|
||||
inline QString icon() const
|
||||
{ return qvariant_cast< QString >(property("Icon")); }
|
||||
|
||||
Q_PROPERTY(bool Mute READ mute NOTIFY MuteChanged)
|
||||
inline bool mute() const
|
||||
{ return qvariant_cast< bool >(property("Mute")); }
|
||||
|
||||
Q_PROPERTY(QString Name READ name NOTIFY NameChanged)
|
||||
inline QString name() const
|
||||
{ return qvariant_cast< QString >(property("Name")); }
|
||||
|
||||
Q_PROPERTY(bool SupportBalance READ supportBalance NOTIFY SupportBalanceChanged)
|
||||
inline bool supportBalance() const
|
||||
{ return qvariant_cast< bool >(property("SupportBalance")); }
|
||||
|
||||
Q_PROPERTY(bool SupportFade READ supportFade NOTIFY SupportFadeChanged)
|
||||
inline bool supportFade() const
|
||||
{ return qvariant_cast< bool >(property("SupportFade")); }
|
||||
|
||||
Q_PROPERTY(double Volume READ volume NOTIFY VolumeChanged)
|
||||
inline double volume() const
|
||||
{ return qvariant_cast< double >(property("Volume")); }
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
inline QDBusPendingReply<> SetBalance(double in0, bool in1)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetBalance"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetFade(double in0)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(in0);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetFade"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetMute(bool in0)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(in0);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetMute"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetVolume(double volume, bool feedBack)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(volume) << QVariant::fromValue(feedBack);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetVolume"), argumentList);
|
||||
}
|
||||
|
||||
Q_SIGNALS: // SIGNALS
|
||||
// begin property changed signals
|
||||
void BalanceChanged();
|
||||
void FadeChanged();
|
||||
void IconChanged();
|
||||
void MuteChanged();
|
||||
void NameChanged();
|
||||
void SupportBalanceChanged();
|
||||
void SupportFadeChanged();
|
||||
void VolumeChanged();
|
||||
};
|
||||
|
||||
namespace com {
|
||||
namespace deepin {
|
||||
namespace daemon {
|
||||
namespace Audio {
|
||||
typedef ::DBusSinkInput SinkInput;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
35
plugins/sound/sinkinputwidget.cpp
Normal file
35
plugins/sound/sinkinputwidget.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
#include "sinkinputwidget.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QIcon>
|
||||
|
||||
DWIDGET_USE_NAMESPACE
|
||||
|
||||
SinkInputWidget::SinkInputWidget(const QString &inputPath, QWidget *parent)
|
||||
: QWidget(parent),
|
||||
|
||||
m_inputInter(new DBusSinkInput(inputPath, this)),
|
||||
|
||||
m_volumeIcon(new DImageButton),
|
||||
m_volumeSlider(new VolumeSlider)
|
||||
{
|
||||
m_volumeIcon->setPixmap(QIcon::fromTheme(m_inputInter->icon()).pixmap(24, 24));
|
||||
m_volumeSlider->setValue(m_inputInter->volume() * 1000);
|
||||
|
||||
QHBoxLayout *centeralLayout = new QHBoxLayout;
|
||||
centeralLayout->addWidget(m_volumeIcon);
|
||||
centeralLayout->addWidget(m_volumeSlider);
|
||||
centeralLayout->setSpacing(2);
|
||||
centeralLayout->setMargin(0);
|
||||
|
||||
connect(m_volumeSlider, &VolumeSlider::valueChanged, this, &SinkInputWidget::setVolume);
|
||||
|
||||
setLayout(centeralLayout);
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
setFixedHeight(30);
|
||||
}
|
||||
|
||||
void SinkInputWidget::setVolume(const int value)
|
||||
{
|
||||
m_inputInter->SetVolume(double(value) / 1000.0, false);
|
||||
}
|
28
plugins/sound/sinkinputwidget.h
Normal file
28
plugins/sound/sinkinputwidget.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef SINKINPUTWIDGET_H
|
||||
#define SINKINPUTWIDGET_H
|
||||
|
||||
#include "dbus/dbussinkinput.h"
|
||||
#include "componments/volumeslider.h"
|
||||
|
||||
#include <QFrame>
|
||||
|
||||
#include <dimagebutton.h>
|
||||
|
||||
class SinkInputWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SinkInputWidget(const QString &inputPath, QWidget *parent = 0);
|
||||
|
||||
private slots:
|
||||
void setVolume(const int value);
|
||||
|
||||
private:
|
||||
DBusSinkInput *m_inputInter;
|
||||
|
||||
Dtk::Widget::DImageButton *m_volumeIcon;
|
||||
VolumeSlider *m_volumeSlider;
|
||||
};
|
||||
|
||||
#endif // SINKINPUTWIDGET_H
|
@ -17,7 +17,9 @@ HEADERS += \
|
||||
dbus/dbusaudio.h \
|
||||
dbus/dbussink.h \
|
||||
componments/horizontalseparator.h \
|
||||
componments/volumeslider.h
|
||||
componments/volumeslider.h \
|
||||
dbus/dbussinkinput.h \
|
||||
sinkinputwidget.h
|
||||
|
||||
SOURCES += \
|
||||
soundplugin.cpp \
|
||||
@ -26,7 +28,9 @@ SOURCES += \
|
||||
dbus/dbusaudio.cpp \
|
||||
dbus/dbussink.cpp \
|
||||
componments/horizontalseparator.cpp \
|
||||
componments/volumeslider.cpp
|
||||
componments/volumeslider.cpp \
|
||||
dbus/dbussinkinput.cpp \
|
||||
sinkinputwidget.cpp
|
||||
|
||||
target.path = $${PREFIX}/lib/dde-dock/plugins/
|
||||
INSTALLS += target
|
||||
|
@ -1,10 +1,12 @@
|
||||
#include "soundapplet.h"
|
||||
#include "sinkinputwidget.h"
|
||||
#include "componments/horizontalseparator.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QIcon>
|
||||
|
||||
#define WIDTH 200
|
||||
#define MAX_HEIGHT 200
|
||||
#define ICON_SIZE 24
|
||||
|
||||
DWIDGET_USE_NAMESPACE
|
||||
@ -13,7 +15,7 @@ SoundApplet::SoundApplet(QWidget *parent)
|
||||
: QScrollArea(parent),
|
||||
|
||||
m_centeralWidget(new QWidget),
|
||||
m_appControlWidget(new QWidget),
|
||||
m_applicationTitle(new QWidget),
|
||||
m_volumeBtn(new DImageButton),
|
||||
m_volumeSlider(new VolumeSlider),
|
||||
|
||||
@ -33,6 +35,7 @@ SoundApplet::SoundApplet(QWidget *parent)
|
||||
deviceLineLayout->setSpacing(10);
|
||||
|
||||
QHBoxLayout *volumeCtrlLayout = new QHBoxLayout;
|
||||
volumeCtrlLayout->addSpacing(2);
|
||||
volumeCtrlLayout->addWidget(m_volumeBtn);
|
||||
volumeCtrlLayout->addWidget(m_volumeSlider);
|
||||
volumeCtrlLayout->setSpacing(0);
|
||||
@ -48,24 +51,20 @@ SoundApplet::SoundApplet(QWidget *parent)
|
||||
appLineLayout->setMargin(0);
|
||||
appLineLayout->setSpacing(10);
|
||||
|
||||
QVBoxLayout *appLayout = new QVBoxLayout;
|
||||
appLayout->addLayout(appLineLayout);
|
||||
appLayout->setSpacing(0);
|
||||
appLayout->setMargin(0);
|
||||
m_applicationTitle->setLayout(appLineLayout);
|
||||
|
||||
m_volumeBtn->setFixedSize(ICON_SIZE, ICON_SIZE);
|
||||
m_volumeSlider->setMinimum(0);
|
||||
m_volumeSlider->setMaximum(1000);
|
||||
|
||||
m_appControlWidget->setLayout(appLayout);
|
||||
|
||||
m_centeralLayout = new QVBoxLayout;
|
||||
m_centeralLayout->addLayout(deviceLineLayout);
|
||||
m_centeralLayout->addLayout(volumeCtrlLayout);
|
||||
m_centeralLayout->addWidget(m_appControlWidget);
|
||||
m_centeralLayout->addWidget(m_applicationTitle);
|
||||
|
||||
m_centeralWidget->setLayout(m_centeralLayout);
|
||||
m_centeralWidget->setFixedWidth(WIDTH);
|
||||
m_centeralWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
|
||||
|
||||
setFixedWidth(WIDTH);
|
||||
setWidget(m_centeralWidget);
|
||||
@ -76,9 +75,11 @@ SoundApplet::SoundApplet(QWidget *parent)
|
||||
|
||||
connect(m_volumeBtn, &DImageButton::clicked, this, &SoundApplet::toggleMute);
|
||||
connect(m_volumeSlider, &VolumeSlider::valueChanged, this, &SoundApplet::volumeSliderValueChanged);
|
||||
connect(m_audioInter, &DBusAudio::SinkInputsChanged, this, &SoundApplet::sinkInputsChanged);
|
||||
connect(this, static_cast<void (SoundApplet::*)(DBusSink*) const>(&SoundApplet::defaultSinkChanged), this, &SoundApplet::onVolumeChanged);
|
||||
|
||||
QMetaObject::invokeMethod(this, "defaultSinkChanged", Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(this, "sinkInputsChanged", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void SoundApplet::defaultSinkChanged()
|
||||
@ -120,6 +121,28 @@ void SoundApplet::volumeSliderValueChanged()
|
||||
m_defSinkInter->SetVolume(double(m_volumeSlider->value()) / 1000, false);
|
||||
}
|
||||
|
||||
void SoundApplet::sinkInputsChanged()
|
||||
{
|
||||
QVBoxLayout *appLayout = m_centeralLayout;
|
||||
while (QLayoutItem *item = appLayout->takeAt(3))
|
||||
{
|
||||
delete item->widget();
|
||||
delete item;
|
||||
}
|
||||
|
||||
m_applicationTitle->setVisible(false);
|
||||
for (auto input : m_audioInter->sinkInputs())
|
||||
{
|
||||
m_applicationTitle->setVisible(true);
|
||||
SinkInputWidget *si = new SinkInputWidget(input.path());
|
||||
appLayout->addWidget(si);
|
||||
}
|
||||
|
||||
const int contentHeight = m_centeralWidget->sizeHint().height();
|
||||
m_centeralWidget->setFixedHeight(contentHeight);
|
||||
setFixedHeight(std::min(contentHeight, MAX_HEIGHT));
|
||||
}
|
||||
|
||||
void SoundApplet::toggleMute()
|
||||
{
|
||||
m_defSinkInter->SetMute(!m_defSinkInter->mute());
|
||||
|
@ -26,11 +26,12 @@ private slots:
|
||||
void defaultSinkChanged();
|
||||
void onVolumeChanged();
|
||||
void volumeSliderValueChanged();
|
||||
void sinkInputsChanged();
|
||||
void toggleMute();
|
||||
|
||||
private:
|
||||
QWidget *m_centeralWidget;
|
||||
QWidget *m_appControlWidget;
|
||||
QWidget *m_applicationTitle;
|
||||
Dtk::Widget::DImageButton *m_volumeBtn;
|
||||
VolumeSlider *m_volumeSlider;
|
||||
QVBoxLayout *m_centeralLayout;
|
||||
|
Loading…
x
Reference in New Issue
Block a user