add application volume control

Change-Id: If25cf5e72839631932eec7b32d77ff65d29067bd
This commit is contained in:
石博文 2016-08-03 11:23:18 +08:00
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
9 changed files with 297 additions and 12 deletions

View File

@ -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());
}
}

View 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>

View 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)));
}

View 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

View 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);
}

View 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

View File

@ -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

View File

@ -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());

View File

@ -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;