mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-03 00:15:21 +00:00
fix: 完善音量功能
1、只要存在音量设备,就显示设备列表 2、当设备在控制中心被禁用后,快捷面板音量滑块不可调节,并且变灰显示 Log: 完善音量功能 Influence: 从控制中心关闭设备,观察任务栏设备状态是否发生变化 Bug: https://pms.uniontech.com/bug-view-172429.html Change-Id: Ib98f77f49998d6f55f9ad69a18e7fbb30081acf1
This commit is contained in:
parent
4386f13cd9
commit
6bcaead473
@ -44,6 +44,10 @@ DWIDGET_USE_NAMESPACE
|
||||
|
||||
#define HEADERHEIGHT 30
|
||||
#define ITEMSPACE 16
|
||||
#define ROWSPACE 10
|
||||
#define DESCRIPTIONHEIGHT 15
|
||||
#define ITEMRADIUS 12
|
||||
#define SLIDERHEIGHT 36
|
||||
|
||||
#define AUDIOPORT 0
|
||||
#define AUDIOSETTING 1
|
||||
@ -60,15 +64,13 @@ SoundDevicesWidget::SoundDevicesWidget(QWidget *parent)
|
||||
, m_sinkInter(new DBusSink("org.deepin.daemon.Audio1", m_soundInter->defaultSink().path(), QDBusConnection::sessionBus(), this))
|
||||
, m_model(new QStandardItemModel(this))
|
||||
, m_delegate(new SettingDelegate(m_deviceList))
|
||||
, m_lastPort(nullptr)
|
||||
{
|
||||
initUi();
|
||||
initConnection();
|
||||
onAudioDevicesChanged();
|
||||
m_sliderParent->installEventFilter(this);
|
||||
|
||||
QMetaObject::invokeMethod(this, [ this ] {
|
||||
resetVolumeInfo();
|
||||
deviceEnabled(m_ports.size() > 0);
|
||||
resizeHeight();
|
||||
}, Qt::QueuedConnection);
|
||||
}
|
||||
@ -98,7 +100,7 @@ void SoundDevicesWidget::initUi()
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setSpacing(6);
|
||||
|
||||
m_sliderParent->setFixedHeight(36);
|
||||
m_sliderParent->setFixedHeight(SLIDERHEIGHT);
|
||||
|
||||
QHBoxLayout *sliderLayout = new QHBoxLayout(m_sliderParent);
|
||||
sliderLayout->setContentsMargins(11, 0, 11, 0);
|
||||
@ -119,22 +121,22 @@ void SoundDevicesWidget::initUi()
|
||||
topLayout->addWidget(m_sliderParent);
|
||||
|
||||
layout->addLayout(topLayout);
|
||||
layout->addSpacing(4);
|
||||
layout->addWidget(m_descriptionLabel);
|
||||
|
||||
m_deviceList->setModel(m_model);
|
||||
m_deviceList->setViewMode(QListView::ListMode);
|
||||
m_deviceList->setMovement(QListView::Free);
|
||||
m_deviceList->setItemRadius(12);
|
||||
m_deviceList->setItemRadius(ITEMRADIUS);
|
||||
m_deviceList->setWordWrap(false);
|
||||
m_deviceList->verticalScrollBar()->setVisible(false);
|
||||
m_deviceList->horizontalScrollBar()->setVisible(false);
|
||||
m_deviceList->setOrientation(QListView::Flow::TopToBottom, false);
|
||||
layout->addWidget(m_deviceList);
|
||||
m_deviceList->setSpacing(10);
|
||||
m_deviceList->setSpacing(ROWSPACE);
|
||||
|
||||
m_deviceList->setItemDelegate(m_delegate);
|
||||
m_model->setSortRole(sortRole);
|
||||
m_descriptionLabel->setFixedHeight(DESCRIPTIONHEIGHT);
|
||||
|
||||
// 增加音量设置
|
||||
DStandardItem *settingItem = new DStandardItem;
|
||||
@ -143,6 +145,8 @@ void SoundDevicesWidget::initUi()
|
||||
settingItem->setData(false, itemCheckRole);
|
||||
settingItem->setData(AUDIOSETTING, itemFlagRole);
|
||||
m_model->appendRow(settingItem);
|
||||
|
||||
m_sliderParent->installEventFilter(this);
|
||||
}
|
||||
|
||||
void SoundDevicesWidget::onAudioDevicesChanged()
|
||||
@ -150,61 +154,55 @@ void SoundDevicesWidget::onAudioDevicesChanged()
|
||||
QMap<uint, QStringList> tmpCardIds;
|
||||
const QString cards = m_soundInter->cardsWithoutUnavailable();
|
||||
QJsonDocument doc = QJsonDocument::fromJson(cards.toUtf8());
|
||||
QJsonArray jCards = doc.array();
|
||||
for (QJsonValue cV : jCards) {
|
||||
QJsonObject jCard = cV.toObject();
|
||||
const uint cardId = jCard["Id"].toInt();
|
||||
const QString cardName = jCard["Name"].toString();
|
||||
QJsonArray jPorts = jCard["Ports"].toArray();
|
||||
QJsonArray jCards = doc.array();
|
||||
for (QJsonValue cV : jCards) {
|
||||
QJsonObject jCard = cV.toObject();
|
||||
const uint cardId = jCard["Id"].toInt();
|
||||
const QString cardName = jCard["Name"].toString();
|
||||
QJsonArray jPorts = jCard["Ports"].toArray();
|
||||
|
||||
QStringList tmpPorts;
|
||||
QStringList tmpPorts;
|
||||
|
||||
for (QJsonValue pV : jPorts) {
|
||||
QJsonObject jPort = pV.toObject();
|
||||
const double portAvai = jPort["Available"].toDouble();
|
||||
if (portAvai == 2 || portAvai == 0 ) {
|
||||
const QString portId = jPort["Name"].toString();
|
||||
const QString portName = jPort["Description"].toString();
|
||||
for (QJsonValue pV : jPorts) {
|
||||
QJsonObject jPort = pV.toObject();
|
||||
const double portAvai = jPort["Available"].toDouble();
|
||||
if (portAvai != 2 && portAvai != 0 )
|
||||
continue;
|
||||
|
||||
SoundDevicePort *port = findPort(portId, cardId);
|
||||
bool includePort = (port != nullptr);
|
||||
if (!port)
|
||||
port = new SoundDevicePort(m_model);
|
||||
const QString portId = jPort["Name"].toString();
|
||||
const QString portName = jPort["Description"].toString();
|
||||
|
||||
port->setId(portId);
|
||||
port->setName(portName);
|
||||
port->setDirection(SoundDevicePort::Direction(jPort["Direction"].toDouble()));
|
||||
port->setCardId(cardId);
|
||||
port->setCardName(cardName);
|
||||
SoundDevicePort *port = findPort(portId, cardId);
|
||||
bool includePort = (port != nullptr);
|
||||
if (!port)
|
||||
port = new SoundDevicePort(m_model);
|
||||
|
||||
if (!includePort)
|
||||
startAddPort(port);
|
||||
port->setId(portId);
|
||||
port->setName(portName);
|
||||
port->setDirection(SoundDevicePort::Direction(jPort["Direction"].toDouble()));
|
||||
port->setCardId(cardId);
|
||||
port->setCardName(cardName);
|
||||
|
||||
tmpPorts << portId;
|
||||
}
|
||||
}
|
||||
tmpCardIds.insert(cardId, tmpPorts);
|
||||
if (!includePort)
|
||||
startAddPort(port);
|
||||
|
||||
tmpPorts << portId;
|
||||
}
|
||||
tmpCardIds.insert(cardId, tmpPorts);
|
||||
}
|
||||
|
||||
onDefaultSinkChanged(m_soundInter->defaultSink());//重新获取切换的设备信息
|
||||
// 重新获取切换的设备信息
|
||||
onDefaultSinkChanged(m_soundInter->defaultSink());
|
||||
|
||||
for (SoundDevicePort *port : m_ports) {
|
||||
//只要有一个设备在控制中心被禁用后,在任务栏声音设备列表中该设备会被移除,
|
||||
if (!m_soundInter->IsPortEnabled(port->cardId(), port->id())) {
|
||||
removeDisabledDevice(port->id(), port->cardId());
|
||||
}
|
||||
//判断端口是否在最新的设备列表中
|
||||
if (tmpCardIds.contains(port->cardId())) {
|
||||
if (!tmpCardIds[port->cardId()].contains(port->id())) {
|
||||
startRemovePort(port->id(), port->cardId());
|
||||
}
|
||||
}
|
||||
else {
|
||||
startRemovePort(port->id(), port->cardId());
|
||||
}
|
||||
}
|
||||
//当只有一个设备剩余时,该设备也需要移除
|
||||
removeLastDevice();
|
||||
for (SoundDevicePort *port : m_ports) {
|
||||
// 只要有一个设备在控制中心被禁用后,在任务栏声音设备列表中该设备会被移除,
|
||||
if (!m_soundInter->IsPortEnabled(port->cardId(), port->id()))
|
||||
removeDisabledDevice(port->id(), port->cardId());
|
||||
|
||||
// 判断端口是否在最新的设备列表中
|
||||
if (!tmpCardIds.contains(port->cardId()) || !tmpCardIds[port->cardId()].contains(port->id()))
|
||||
startRemovePort(port->id(), port->cardId());
|
||||
}
|
||||
}
|
||||
|
||||
void SoundDevicesWidget::initConnection()
|
||||
@ -288,6 +286,10 @@ void SoundDevicesWidget::addPort(const SoundDevicePort *port)
|
||||
}
|
||||
|
||||
m_model->sort(0);
|
||||
if (m_ports.size() == 1)
|
||||
deviceEnabled(true);
|
||||
|
||||
resizeHeight();
|
||||
}
|
||||
|
||||
void SoundDevicesWidget::removePort(const QString &portId, const uint &cardId)
|
||||
@ -307,6 +309,11 @@ void SoundDevicesWidget::removePort(const QString &portId, const uint &cardId)
|
||||
|
||||
if (removeRow >= 0)
|
||||
m_model->removeRow(removeRow);
|
||||
|
||||
if (m_ports.size() == 0)
|
||||
deviceEnabled(false);
|
||||
|
||||
resizeHeight();
|
||||
}
|
||||
|
||||
void SoundDevicesWidget::activePort(const QString &portId, const uint &cardId)
|
||||
@ -315,20 +322,6 @@ void SoundDevicesWidget::activePort(const QString &portId, const uint &cardId)
|
||||
it->setIsActive(it->id() == portId && it->cardId() == cardId);
|
||||
}
|
||||
|
||||
void SoundDevicesWidget::removeLastDevice()
|
||||
{
|
||||
if (m_ports.count() == 1 && m_ports.at(0)) {
|
||||
m_lastPort = new SoundDevicePort(m_model);
|
||||
m_lastPort->setId(m_ports.at(0)->id());
|
||||
m_lastPort->setName(m_ports.at(0)->name());
|
||||
m_lastPort->setDirection(m_ports.at(0)->direction());
|
||||
m_lastPort->setCardId(m_ports.at(0)->cardId());
|
||||
m_lastPort->setCardName(m_ports.at(0)->cardName());
|
||||
startRemovePort(m_ports.at(0)->id(), m_ports.at(0)->cardId());
|
||||
qDebug() << "remove last output device";
|
||||
}
|
||||
}
|
||||
|
||||
void SoundDevicesWidget::removeDisabledDevice(QString portId, unsigned int cardId)
|
||||
{
|
||||
startRemovePort(portId, cardId);
|
||||
@ -338,6 +331,12 @@ void SoundDevicesWidget::removeDisabledDevice(QString portId, unsigned int cardI
|
||||
}
|
||||
}
|
||||
|
||||
void SoundDevicesWidget::deviceEnabled(bool enable)
|
||||
{
|
||||
m_sliderContainer->setEnabled(enable);
|
||||
Q_EMIT enableChanged(enable);
|
||||
}
|
||||
|
||||
QString SoundDevicesWidget::leftIcon()
|
||||
{
|
||||
QString iconLeft = QString(":/icons/resources/audio-volume-%1").arg(m_sinkInter->mute() ? "muted" : "low");
|
||||
@ -366,7 +365,14 @@ const QString SoundDevicesWidget::soundIconFile() const
|
||||
|
||||
void SoundDevicesWidget::resizeHeight()
|
||||
{
|
||||
m_deviceList->adjustSize();
|
||||
int deviceListHeight = 0;
|
||||
for (int i = 0; i < m_model->rowCount(); i++) {
|
||||
QModelIndex index = m_model->index(i, 0);
|
||||
deviceListHeight += m_deviceList->visualRect(index).height() + m_deviceList->spacing() * 2;
|
||||
if (i >= 9) // 最大显示12个条目,包含标题、滑块和设备标题、设备列表,因此,设备列表最多显示9个条目
|
||||
break;
|
||||
}
|
||||
m_deviceList->setFixedHeight(deviceListHeight);
|
||||
QMargins m = layout()->contentsMargins();
|
||||
int height = m.top() + m.bottom() + HEADERHEIGHT + m_sliderContainer->height() + ITEMSPACE
|
||||
+ m_descriptionLabel->height() + m_deviceList->height();
|
||||
@ -453,10 +459,6 @@ void SoundDevicesWidget::onDefaultSinkChanged(const QDBusObjectPath &value)
|
||||
|
||||
QString portId = m_sinkInter->activePort().name;
|
||||
uint cardId = m_sinkInter->card();
|
||||
//最后一个设备会被移除,但是当在控制中心选中此设备后需要添加,并勾选
|
||||
if (m_lastPort && m_lastPort->cardId() == cardId && m_lastPort->id() == portId)
|
||||
startAddPort(m_lastPort);
|
||||
|
||||
activePort(portId, cardId);
|
||||
|
||||
for (int i = 0; i < m_model->rowCount() ; i++) {
|
||||
|
@ -51,6 +51,9 @@ public:
|
||||
explicit SoundDevicesWidget(QWidget *parent = nullptr);
|
||||
~SoundDevicesWidget() override;
|
||||
|
||||
Q_SIGNALS:
|
||||
void enableChanged(bool);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watcher, QEvent *event) override;
|
||||
|
||||
@ -75,9 +78,10 @@ private:
|
||||
|
||||
void activePort(const QString &portId, const uint &cardId);
|
||||
|
||||
void removeLastDevice();
|
||||
void removeDisabledDevice(QString portId, unsigned int cardId);
|
||||
|
||||
void deviceEnabled(bool enable);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onSelectIndexChanged(const QModelIndex &index);
|
||||
void onDefaultSinkChanged(const QDBusObjectPath & value);
|
||||
@ -93,7 +97,6 @@ private:
|
||||
QStandardItemModel *m_model;
|
||||
SettingDelegate *m_delegate;
|
||||
QList<SoundDevicePort *> m_ports;
|
||||
SoundDevicePort *m_lastPort;
|
||||
};
|
||||
|
||||
#endif // VOLUMEDEVICESWIDGET_H
|
||||
|
@ -66,6 +66,8 @@ void SoundPlugin::init(PluginProxyInterface *proxyInter)
|
||||
proxyInter->requestSetAppletVisible(this, QUICK_ITEM_KEY, true);
|
||||
});
|
||||
}
|
||||
|
||||
connect(m_soundDeviceWidget.data(), &SoundDevicesWidget::enableChanged, m_soundWidget.data(), &SoundWidget::setEnabled);
|
||||
}
|
||||
|
||||
void SoundPlugin::pluginStateSwitched()
|
||||
|
@ -239,29 +239,36 @@ void SliderProxyStyle::drawComplexControl(QStyle::ComplexControl control, const
|
||||
QRect rectGroove = subControlRect(CC_Slider, sliderOption, SC_SliderGroove, widget);
|
||||
QRect rectHandle = subControlRect(CC_Slider, sliderOption, SC_SliderHandle, widget);
|
||||
if (m_drawSpecial == RoundHandler)
|
||||
drawRoundSlider(painter, rectGroove, rectHandle);
|
||||
drawRoundSlider(painter, rectGroove, rectHandle, widget);
|
||||
else
|
||||
drawNormalSlider(painter, rectGroove, rectHandle, const_cast<QWidget *>(widget));
|
||||
drawNormalSlider(painter, rectGroove, rectHandle, widget);
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
// 绘制通用的滑动条
|
||||
void SliderProxyStyle::drawNormalSlider(QPainter *painter, QRect rectGroove, QRect rectHandle, QWidget *wigdet) const
|
||||
void SliderProxyStyle::drawNormalSlider(QPainter *painter, QRect rectGroove, QRect rectHandle, const QWidget *wigdet) const
|
||||
{
|
||||
DPalette dpa = DPaletteHelper::instance()->palette(wigdet);
|
||||
QPen penLine = QPen(dpa.color(DPalette::Highlight), 2);
|
||||
QColor color = dpa.color(DPalette::Highlight);
|
||||
QColor rightColor(Qt::gray);
|
||||
if (!wigdet->isEnabled()) {
|
||||
color.setAlphaF(0.8);
|
||||
rightColor.setAlphaF(0.8);
|
||||
}
|
||||
|
||||
QPen penLine = QPen(color, 2);
|
||||
// 绘制上下的竖线,一根竖线的宽度是2,+4个像素刚好保证中间也是间隔2个像素
|
||||
for (int i = rectGroove.x(); i < rectGroove.x() + rectGroove.width(); i = i + 4) {
|
||||
if (i < rectHandle.x())
|
||||
painter->setPen(penLine);
|
||||
else
|
||||
painter->setPen(QPen(Qt::gray, 2));
|
||||
painter->setPen(QPen(rightColor, 2));
|
||||
|
||||
painter->drawLine(i, rectGroove.y() + 2, i, rectGroove.y() + rectGroove.height() - 2);
|
||||
}
|
||||
// 绘制滚动区域
|
||||
painter->setBrush(dpa.color(DPalette::Highlight));
|
||||
painter->setBrush(color);
|
||||
painter->setPen(Qt::NoPen);
|
||||
QPainterPath path;
|
||||
path.addRoundedRect(rectHandle, 6, 6);
|
||||
@ -269,10 +276,12 @@ void SliderProxyStyle::drawNormalSlider(QPainter *painter, QRect rectGroove, QRe
|
||||
}
|
||||
|
||||
// 绘制设计师定义的那种圆形滑块,黑色的滑条
|
||||
void SliderProxyStyle::drawRoundSlider(QPainter *painter, QRect rectGroove, QRect rectHandle) const
|
||||
void SliderProxyStyle::drawRoundSlider(QPainter *painter, QRect rectGroove, QRect rectHandle, const QWidget *wigdet) const
|
||||
{
|
||||
// 深色背景下,滑块和滑动条白色,浅色背景下,滑块和滑动条黑色
|
||||
QBrush brush(DGuiApplicationHelper::DarkType == DGuiApplicationHelper::instance()->themeType() ? Qt::white : Qt::black);
|
||||
QColor color = wigdet->isEnabled() ? (DGuiApplicationHelper::DarkType == DGuiApplicationHelper::instance()->themeType() ? Qt::white : Qt::black) : Qt::gray;
|
||||
|
||||
QBrush brush(color);
|
||||
// 此处中绘制圆形滑动条,需要绘制圆角,圆角大小为其高度的一半
|
||||
QPainterPath pathGroove;
|
||||
int radius = rectGroove.height() / 2;
|
||||
|
@ -100,8 +100,8 @@ protected:
|
||||
void drawComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = nullptr) const override;
|
||||
|
||||
private:
|
||||
void drawNormalSlider(QPainter *painter, QRect rectGroove, QRect rectHandle, QWidget *wigdet) const;
|
||||
void drawRoundSlider(QPainter *painter, QRect rectGroove, QRect rectHandle) const;
|
||||
void drawNormalSlider(QPainter *painter, QRect rectGroove, QRect rectHandle, const QWidget *wigdet) const;
|
||||
void drawRoundSlider(QPainter *painter, QRect rectGroove, QRect rectHandle, const QWidget *wigdet) const;
|
||||
|
||||
private:
|
||||
StyleType m_drawSpecial;
|
||||
|
Loading…
x
Reference in New Issue
Block a user