mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-02 15:45:21 +00:00
feat: 声音插件适配v23
将声音的相关功能移到sound插件中,方便扩展,并适配v23的接口 Log: 声音插件适配v23 Influence: 观察任务栏是否存在声音插件 Task: https://pms.uniontech.com/task-view-210309.html Change-Id: I7f782af6955a017af940e639a02eedab8f459905
This commit is contained in:
parent
dd1ed1c0d4
commit
9985c9b239
@ -2,7 +2,7 @@
|
||||
#add_subdirectory("disk-mount")
|
||||
add_subdirectory("shutdown")
|
||||
add_subdirectory("power")
|
||||
#add_subdirectory("sound")
|
||||
add_subdirectory("sound")
|
||||
#add_subdirectory("tray")
|
||||
add_subdirectory("trash")
|
||||
add_subdirectory("keyboard-layout")
|
||||
|
@ -28,12 +28,13 @@ pkg_check_modules(QGSettings REQUIRED gsettings-qt)
|
||||
|
||||
add_definitions("${QT_DEFINITIONS} -DQT_PLUGIN")
|
||||
add_library(${PLUGIN_NAME} SHARED ${SRCS} resources/sound.qrc)
|
||||
set_target_properties(${PLUGIN_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ../system-trays)
|
||||
set_target_properties(${PLUGIN_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ../quick-trays)
|
||||
target_include_directories(${PLUGIN_NAME} PUBLIC ${DtkWidget_INCLUDE_DIRS}
|
||||
${QGSettings_INCLUDE_DIRS}
|
||||
./dbusinterface
|
||||
./dbusinterface/generation_dbus_interface
|
||||
../../interfaces
|
||||
../../widgets
|
||||
../../frame
|
||||
../../frame/accessible
|
||||
../../frame/qtdbusextended
|
||||
@ -48,4 +49,4 @@ target_link_libraries(${PLUGIN_NAME} PRIVATE
|
||||
${Qt5Svg_LIBRARIES}
|
||||
)
|
||||
|
||||
install(TARGETS ${PLUGIN_NAME} LIBRARY DESTINATION lib/dde-dock/plugins/system-trays)
|
||||
install(TARGETS ${PLUGIN_NAME} LIBRARY DESTINATION lib/dde-dock/plugins/quick-trays)
|
||||
|
@ -1,4 +1,5 @@
|
||||
{
|
||||
"api": "2.0.0",
|
||||
"depends-daemon-dbus-service": "org.deepin.daemon.Audio1"
|
||||
"depends-daemon-dbus-service": "org.deepin.daemon.Audio1",
|
||||
"applet": true
|
||||
}
|
||||
|
@ -285,7 +285,7 @@ void SoundApplet::onDefaultSinkChanged()
|
||||
|
||||
connect(m_defSinkInter, &DBusSink::VolumeChanged, this, &SoundApplet::onVolumeChanged);
|
||||
connect(m_defSinkInter, &DBusSink::MuteChanged, this, [ = ] {
|
||||
onVolumeChanged(m_defSinkInter->volume());
|
||||
onVolumeChanged(m_defSinkInter->volume() * 100);
|
||||
});
|
||||
|
||||
QString portId = m_defSinkInter->activePort().name;
|
||||
@ -297,7 +297,7 @@ void SoundApplet::onDefaultSinkChanged()
|
||||
activePort(portId,cardId);
|
||||
|
||||
//无声卡状态下,会有伪sink设备,显示音量为0
|
||||
onVolumeChanged(findPort(portId, cardId) != nullptr ? m_defSinkInter->volume() : 0);
|
||||
onVolumeChanged(findPort(portId, cardId) != nullptr ? m_defSinkInter->volume() * 100 : 0);
|
||||
emit defaultSinkChanged(m_defSinkInter);
|
||||
}
|
||||
|
||||
|
282
plugins/sound/sounddeviceswidget.cpp
Normal file
282
plugins/sound/sounddeviceswidget.cpp
Normal file
@ -0,0 +1,282 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "sounddeviceswidget.h"
|
||||
#include "brightnessmodel.h"
|
||||
#include "settingdelegate.h"
|
||||
#include "imageutil.h"
|
||||
#include "slidercontainer.h"
|
||||
|
||||
#include <DListView>
|
||||
#include <DPushButton>
|
||||
#include <DLabel>
|
||||
#include <DGuiApplicationHelper>
|
||||
#include <DDBusSender>
|
||||
#include <DBlurEffectWidget>
|
||||
#include <DPaletteHelper>
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QScrollBar>
|
||||
#include <QEvent>
|
||||
#include <QProcess>
|
||||
#include <QDBusInterface>
|
||||
#include <QDBusConnection>
|
||||
|
||||
DWIDGET_USE_NAMESPACE
|
||||
|
||||
#define HEADERHEIGHT 30
|
||||
#define ITEMSPACE 16
|
||||
|
||||
#define AUDIOPORT 0
|
||||
#define AUDIOSETTING 1
|
||||
|
||||
const int cardIdRole = itemFlagRole + 1;
|
||||
|
||||
SoundDevicesWidget::SoundDevicesWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_sliderParent(new QWidget(this))
|
||||
, m_sliderContainer(new SliderContainer(m_sliderParent))
|
||||
, m_descriptionLabel(new QLabel(tr("Output Device"), this))
|
||||
, m_deviceList(new DListView(this))
|
||||
, m_volumeModel(new DBusAudio("org.deepin.daemon.Audio1", "/org/deepin/daemon/Audio1", QDBusConnection::sessionBus(), this))
|
||||
, m_audioSink(new DBusSink("org.deepin.daemon.Audio1", m_volumeModel->defaultSink().path(), QDBusConnection::sessionBus(), this))
|
||||
, m_model(new QStandardItemModel(this))
|
||||
, m_delegate(new SettingDelegate(m_deviceList))
|
||||
{
|
||||
initUi();
|
||||
initConnection();
|
||||
onAudioDevicesChanged();
|
||||
m_sliderParent->installEventFilter(this);
|
||||
|
||||
QMetaObject::invokeMethod(this, [ this ] {
|
||||
resetVolumeInfo();
|
||||
resizeHeight();
|
||||
}, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
SoundDevicesWidget::~SoundDevicesWidget()
|
||||
{
|
||||
}
|
||||
|
||||
bool SoundDevicesWidget::eventFilter(QObject *watcher, QEvent *event)
|
||||
{
|
||||
if ((watcher == m_sliderParent) && (event->type() == QEvent::Paint)) {
|
||||
QPainter painter(m_sliderParent);
|
||||
painter.setRenderHint(QPainter::Antialiasing); // 抗锯齿
|
||||
painter.setPen(Qt::NoPen);
|
||||
|
||||
DPalette dpa = DPaletteHelper::instance()->palette(m_sliderParent);
|
||||
painter.setBrush(dpa.brush(DPalette::ColorRole::Midlight));
|
||||
painter.drawRoundedRect(m_sliderParent->rect(), 10, 10);
|
||||
}
|
||||
|
||||
return QWidget::eventFilter(watcher, event);
|
||||
}
|
||||
|
||||
void SoundDevicesWidget::initUi()
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setSpacing(6);
|
||||
|
||||
m_sliderParent->setFixedHeight(36);
|
||||
|
||||
QHBoxLayout *sliderLayout = new QHBoxLayout(m_sliderParent);
|
||||
sliderLayout->setContentsMargins(11, 0, 11, 0);
|
||||
sliderLayout->setSpacing(0);
|
||||
|
||||
QPixmap leftPixmap = ImageUtil::loadSvg(leftIcon(), QSize(24, 24));
|
||||
m_sliderContainer->setIcon(SliderContainer::IconPosition::LeftIcon, leftPixmap, QSize(), 5);
|
||||
QPixmap rightPixmap = ImageUtil::loadSvg(rightIcon(), QSize(24, 24));
|
||||
m_sliderContainer->setIcon(SliderContainer::IconPosition::RightIcon, rightPixmap, QSize(), 7);
|
||||
|
||||
SliderProxyStyle *proxy = new SliderProxyStyle(SliderProxyStyle::Normal);
|
||||
m_sliderContainer->setSliderProxyStyle(proxy);
|
||||
sliderLayout->addWidget(m_sliderContainer);
|
||||
|
||||
QHBoxLayout *topLayout = new QHBoxLayout(this);
|
||||
topLayout->setContentsMargins(10, 0, 10, 0);
|
||||
topLayout->setSpacing(0);
|
||||
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->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->setItemDelegate(m_delegate);
|
||||
}
|
||||
|
||||
void SoundDevicesWidget::onAudioDevicesChanged()
|
||||
{
|
||||
QList<AudioPort> ports = m_audioSink->ports();
|
||||
for (AudioPort port : ports) {
|
||||
if (port.availability != 0 && port.availability != 2)
|
||||
continue;
|
||||
|
||||
uint cardId = audioPortCardId(port);
|
||||
if (!m_volumeModel->IsPortEnabled(cardId, port.name))
|
||||
continue;
|
||||
|
||||
DStandardItem *item = new DStandardItem;
|
||||
item->setText(QString("%1(%2)").arg(port.description).arg(port.name));
|
||||
item->setIcon(QIcon(soundIconFile(port)));
|
||||
item->setFlags(Qt::NoItemFlags);
|
||||
item->setData(port.availability == 2, itemCheckRole);
|
||||
item->setData(QVariant::fromValue(port), itemDataRole);
|
||||
item->setData(AUDIOPORT, itemFlagRole);
|
||||
item->setData(cardId, cardIdRole);
|
||||
m_model->appendRow(item);
|
||||
if (port.availability == 2)
|
||||
m_deviceList->setCurrentIndex(m_model->indexFromItem(item));
|
||||
}
|
||||
|
||||
DStandardItem *settingItem = new DStandardItem;
|
||||
settingItem->setText(tr("Sound settings"));
|
||||
settingItem->setFlags(Qt::NoItemFlags);
|
||||
settingItem->setData(false, itemCheckRole);
|
||||
settingItem->setData(AUDIOSETTING, itemFlagRole);
|
||||
m_model->appendRow(settingItem);
|
||||
}
|
||||
|
||||
void SoundDevicesWidget::initConnection()
|
||||
{
|
||||
connect(m_audioSink, &DBusSink::VolumeChanged, m_sliderContainer, &SliderContainer::updateSliderValue);
|
||||
connect(m_volumeModel, &DBusAudio::DefaultSinkChanged, this, &SoundDevicesWidget::onDefaultSinkChanged);
|
||||
connect(m_delegate, &SettingDelegate::selectIndexChanged, this, &SoundDevicesWidget::onSelectIndexChanged);
|
||||
connect(m_volumeModel, &DBusAudio::PortEnabledChanged, this, &SoundDevicesWidget::onAudioDevicesChanged);
|
||||
connect(m_volumeModel, &DBusAudio::CardsWithoutUnavailableChanged, this, &SoundDevicesWidget::onAudioDevicesChanged);
|
||||
|
||||
connect(m_sliderContainer, &SliderContainer::sliderValueChanged, this, [ this ](int value) {
|
||||
m_audioSink->SetVolume(value, true);
|
||||
});
|
||||
}
|
||||
|
||||
QString SoundDevicesWidget::leftIcon()
|
||||
{
|
||||
QString iconLeft = QString(":/icons/resources/audio-volume-%1").arg(m_audioSink->mute() ? "muted" : "low");
|
||||
if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType)
|
||||
iconLeft.append("-dark");
|
||||
|
||||
return iconLeft;
|
||||
}
|
||||
|
||||
QString SoundDevicesWidget::rightIcon()
|
||||
{
|
||||
QString iconRight = QString(":/icons/resources/audio-volume-high");
|
||||
if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType)
|
||||
iconRight.append("-dark");
|
||||
|
||||
return iconRight;
|
||||
}
|
||||
|
||||
const QString SoundDevicesWidget::soundIconFile(const AudioPort port) const
|
||||
{
|
||||
if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType)
|
||||
return QString(":/icons/resources/ICON_Device_Laptop_dark.svg");
|
||||
|
||||
return QString(":/icons/resources/ICON_Device_Laptop.svg");
|
||||
}
|
||||
|
||||
void SoundDevicesWidget::resizeHeight()
|
||||
{
|
||||
m_deviceList->adjustSize();
|
||||
QMargins m = layout()->contentsMargins();
|
||||
int height = m.top() + m.bottom() + HEADERHEIGHT + m_sliderContainer->height() + ITEMSPACE
|
||||
+ m_descriptionLabel->height() + m_deviceList->height();
|
||||
|
||||
setFixedHeight(height);
|
||||
}
|
||||
|
||||
void SoundDevicesWidget::resetVolumeInfo()
|
||||
{
|
||||
m_sliderContainer->updateSliderValue(m_audioSink->volume() * 100);
|
||||
}
|
||||
|
||||
uint SoundDevicesWidget::audioPortCardId(const AudioPort &audioport) const
|
||||
{
|
||||
QString cards = m_volumeModel->cardsWithoutUnavailable();
|
||||
QJsonParseError error;
|
||||
QJsonDocument json = QJsonDocument::fromJson(cards.toLocal8Bit(), &error);
|
||||
if (error.error != QJsonParseError::NoError)
|
||||
return -1;
|
||||
|
||||
QJsonArray array = json.array();
|
||||
for (const QJsonValue value : array) {
|
||||
QJsonObject cardObject = value.toObject();
|
||||
uint cardId = static_cast<uint>(cardObject.value("Id").toInt());
|
||||
QJsonArray jPorts = cardObject.value("Ports").toArray();
|
||||
for (const QJsonValue jPortValue : jPorts) {
|
||||
QJsonObject jPort = jPortValue.toObject();
|
||||
if (!jPort.value("Enabled").toBool())
|
||||
continue;
|
||||
|
||||
int direction = jPort.value("Direction").toInt();
|
||||
if (direction != 1)
|
||||
continue;
|
||||
|
||||
if (jPort.value("Name").toString() == audioport.name)
|
||||
return cardId;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void SoundDevicesWidget::onSelectIndexChanged(const QModelIndex &index)
|
||||
{
|
||||
int flag = index.data(itemFlagRole).toInt();
|
||||
if (flag == AUDIOPORT) {
|
||||
// 如果是点击具体的声音设备
|
||||
AudioPort port = index.data(itemDataRole).value<AudioPort>();
|
||||
uint cardId = index.data(cardIdRole).toUInt();
|
||||
if (cardId >= 0) {
|
||||
m_volumeModel->SetPort(cardId, port.name, 1);
|
||||
m_deviceList->update();
|
||||
}
|
||||
} else {
|
||||
// 如果是点击声音设置,则打开控制中心的声音模块
|
||||
DDBusSender().service("org.deepin.dde.ControlCenter1")
|
||||
.path("/org/deepin/dde/ControlCenter1")
|
||||
.interface("org.deepin.dde.ControlCenter1")
|
||||
.method("ShowPage").arg(QString("sound")).call();
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
void SoundDevicesWidget::onDefaultSinkChanged(const QDBusObjectPath &value)
|
||||
{
|
||||
delete m_audioSink;
|
||||
m_audioSink = new DBusSink("org.deepin.daemon.Audio1", m_volumeModel->defaultSink().path(), QDBusConnection::sessionBus(), this);
|
||||
connect(m_audioSink, &DBusSink::VolumeChanged, m_sliderContainer, &SliderContainer::updateSliderValue);
|
||||
|
||||
resetVolumeInfo();
|
||||
m_deviceList->update();
|
||||
}
|
84
plugins/sound/sounddeviceswidget.h
Normal file
84
plugins/sound/sounddeviceswidget.h
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef SOUNDDEVICESWIDGET_H
|
||||
#define SOUNDDEVICESWIDGET_H
|
||||
|
||||
#include "org_deepin_daemon_audio.h"
|
||||
#include "org_deepin_daemon_audio_sink.h"
|
||||
|
||||
#include <DStyledItemDelegate>
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Dtk { namespace Widget { class DListView; } }
|
||||
|
||||
using namespace Dtk::Widget;
|
||||
|
||||
class SliderContainer;
|
||||
class QStandardItemModel;
|
||||
class QLabel;
|
||||
class VolumeModel;
|
||||
class AudioSink;
|
||||
class SettingDelegate;
|
||||
|
||||
using DBusAudio = org::deepin::daemon::Audio1;
|
||||
using DBusSink = org::deepin::daemon::audio1::Sink;
|
||||
|
||||
class SoundDevicesWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SoundDevicesWidget(QWidget *parent = nullptr);
|
||||
~SoundDevicesWidget() override;
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watcher, QEvent *event) override;
|
||||
|
||||
private:
|
||||
void initUi();
|
||||
void initConnection();
|
||||
QString leftIcon();
|
||||
QString rightIcon();
|
||||
const QString soundIconFile(const AudioPort port) const;
|
||||
|
||||
void resizeHeight();
|
||||
|
||||
void resetVolumeInfo();
|
||||
uint audioPortCardId(const AudioPort &audioport) const;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onSelectIndexChanged(const QModelIndex &index);
|
||||
void onDefaultSinkChanged(const QDBusObjectPath & value);
|
||||
void onAudioDevicesChanged();
|
||||
|
||||
private:
|
||||
QWidget *m_sliderParent;
|
||||
SliderContainer *m_sliderContainer;
|
||||
QLabel *m_descriptionLabel;
|
||||
DListView *m_deviceList;
|
||||
DBusAudio *m_volumeModel;
|
||||
DBusSink *m_audioSink;
|
||||
QStandardItemModel *m_model;
|
||||
SettingDelegate *m_delegate;
|
||||
};
|
||||
|
||||
#endif // VOLUMEDEVICESWIDGET_H
|
@ -249,6 +249,11 @@ void SoundItem::refreshTips(const int volume, const bool force)
|
||||
}
|
||||
}
|
||||
|
||||
QPixmap SoundItem::pixmap() const
|
||||
{
|
||||
return m_iconPixmap;
|
||||
}
|
||||
|
||||
void SoundItem::sinkChanged(DBusSink *sink)
|
||||
{
|
||||
m_sinkInter = sink;
|
||||
|
@ -50,6 +50,7 @@ public:
|
||||
|
||||
void refreshIcon();
|
||||
void refreshTips(const int volume, const bool force = false);
|
||||
QPixmap pixmap() const;
|
||||
|
||||
signals:
|
||||
void requestContextMenu() const;
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
#include "soundplugin.h"
|
||||
#include "soundaccessible.h"
|
||||
#include "soundwidget.h"
|
||||
#include "sounddeviceswidget.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QAccessible>
|
||||
@ -28,8 +30,9 @@
|
||||
#define STATE_KEY "enable"
|
||||
|
||||
SoundPlugin::SoundPlugin(QObject *parent)
|
||||
: QObject(parent),
|
||||
m_soundItem(nullptr)
|
||||
: QObject(parent)
|
||||
, m_soundItem(nullptr)
|
||||
, m_soundWidget(nullptr)
|
||||
{
|
||||
QAccessible::installFactory(soundAccessibleFactory);
|
||||
}
|
||||
@ -52,9 +55,17 @@ void SoundPlugin::init(PluginProxyInterface *proxyInter)
|
||||
return;
|
||||
|
||||
m_soundItem.reset(new SoundItem);
|
||||
m_soundWidget.reset(new SoundWidget);
|
||||
m_soundWidget->setFixedHeight(60);
|
||||
|
||||
if (!pluginIsDisable())
|
||||
m_soundDeviceWidget.reset(new SoundDevicesWidget);
|
||||
|
||||
if (!pluginIsDisable()) {
|
||||
m_proxyInter->itemAdded(this, SOUND_KEY);
|
||||
connect(m_soundWidget.data(), &SoundWidget::rightIconClick, this, [ this, proxyInter ] {
|
||||
proxyInter->requestSetAppletVisible(this, QUICK_ITEM_DETAIL_KEY, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void SoundPlugin::pluginStateSwitched()
|
||||
@ -71,18 +82,19 @@ bool SoundPlugin::pluginIsDisable()
|
||||
|
||||
QWidget *SoundPlugin::itemWidget(const QString &itemKey)
|
||||
{
|
||||
if (itemKey == SOUND_KEY) {
|
||||
if (itemKey == SOUND_KEY)
|
||||
return m_soundItem.data();
|
||||
}
|
||||
|
||||
if (itemKey == QUICK_ITEM_DETAIL_KEY)
|
||||
return m_soundWidget.data();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QWidget *SoundPlugin::itemTipsWidget(const QString &itemKey)
|
||||
{
|
||||
if (itemKey == SOUND_KEY) {
|
||||
if (itemKey == SOUND_KEY)
|
||||
return m_soundItem->tipsWidget();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@ -92,6 +104,8 @@ QWidget *SoundPlugin::itemPopupApplet(const QString &itemKey)
|
||||
if (itemKey == SOUND_KEY) {
|
||||
return m_soundItem->popupApplet();
|
||||
}
|
||||
if (itemKey == QUICK_ITEM_DETAIL_KEY)
|
||||
return m_soundDeviceWidget.data();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@ -138,6 +152,16 @@ void SoundPlugin::pluginSettingsChanged()
|
||||
refreshPluginItemsVisible();
|
||||
}
|
||||
|
||||
QIcon SoundPlugin::icon(const DockPart &)
|
||||
{
|
||||
return m_soundItem->pixmap();
|
||||
}
|
||||
|
||||
PluginsItemInterface::PluginStatus SoundPlugin::status() const
|
||||
{
|
||||
return SoundPlugin::Active;
|
||||
}
|
||||
|
||||
void SoundPlugin::refreshPluginItemsVisible()
|
||||
{
|
||||
if (pluginIsDisable())
|
||||
|
@ -25,6 +25,9 @@
|
||||
#include "pluginsiteminterface.h"
|
||||
#include "sounditem.h"
|
||||
|
||||
class SoundWidget;
|
||||
class SoundDevicesWidget;
|
||||
|
||||
class SoundPlugin : public QObject, PluginsItemInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -49,12 +52,16 @@ public:
|
||||
void setSortKey(const QString &itemKey, const int order) override;
|
||||
void refreshIcon(const QString &itemKey) override;
|
||||
void pluginSettingsChanged() override;
|
||||
QIcon icon(const DockPart &) override;
|
||||
PluginStatus status() const override;
|
||||
|
||||
private:
|
||||
void refreshPluginItemsVisible();
|
||||
|
||||
private:
|
||||
QScopedPointer<SoundItem> m_soundItem;
|
||||
QScopedPointer<SoundWidget> m_soundWidget;
|
||||
QScopedPointer<SoundDevicesWidget> m_soundDeviceWidget;
|
||||
};
|
||||
|
||||
#endif // SOUNDPLUGIN_H
|
||||
|
154
plugins/sound/soundwidget.cpp
Normal file
154
plugins/sound/soundwidget.cpp
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "soundwidget.h"
|
||||
#include "brightnessmodel.h"
|
||||
#include "imageutil.h"
|
||||
#include "imageutil.h"
|
||||
#include "slidercontainer.h"
|
||||
|
||||
#include <DGuiApplicationHelper>
|
||||
|
||||
#include <QDBusConnectionInterface>
|
||||
#include <QDBusInterface>
|
||||
#include <QDBusPendingCall>
|
||||
#include <QDBusPendingReply>
|
||||
#include <QDebug>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QLabel>
|
||||
#include <QEvent>
|
||||
#include <QHBoxLayout>
|
||||
#include <QMetaMethod>
|
||||
|
||||
DGUI_USE_NAMESPACE
|
||||
|
||||
#define ICON_SIZE 24
|
||||
#define BACKSIZE 36
|
||||
|
||||
SoundWidget::SoundWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_dbusAudio(new DBusAudio("org.deepin.daemon.Audio1", "/org/deepin/daemon/Audio1", QDBusConnection::sessionBus(), this))
|
||||
, m_sliderContainer(new SliderContainer(this))
|
||||
, m_defaultSink(new DBusSink("org.deepin.daemon.Audio1", m_dbusAudio->defaultSink().path(), QDBusConnection::sessionBus(), this))
|
||||
{
|
||||
initUi();
|
||||
initConnection();
|
||||
}
|
||||
|
||||
SoundWidget::~SoundWidget()
|
||||
{
|
||||
}
|
||||
|
||||
void SoundWidget::initUi()
|
||||
{
|
||||
if (m_defaultSink)
|
||||
m_sliderContainer->updateSliderValue(m_defaultSink->volume() * 100);
|
||||
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout(this);
|
||||
mainLayout->setContentsMargins(17, 0, 12, 0);
|
||||
mainLayout->addWidget(m_sliderContainer);
|
||||
|
||||
QPixmap leftPixmap = ImageUtil::loadSvg(leftIcon(), QSize(ICON_SIZE, ICON_SIZE));
|
||||
QPixmap rightPixmap = ImageUtil::loadSvg(rightIcon(), QSize(ICON_SIZE, ICON_SIZE));
|
||||
m_sliderContainer->setIcon(SliderContainer::IconPosition::LeftIcon, leftPixmap, QSize(), 12);
|
||||
m_sliderContainer->setIcon(SliderContainer::IconPosition::RightIcon, rightPixmap, QSize(BACKSIZE, BACKSIZE), 12);
|
||||
|
||||
SliderProxyStyle *proxy = new SliderProxyStyle;
|
||||
m_sliderContainer->setSliderProxyStyle(proxy);
|
||||
|
||||
setEnabled(existActiveOutputDevice());
|
||||
}
|
||||
|
||||
void SoundWidget::initConnection()
|
||||
{
|
||||
connect(m_defaultSink, &DBusSink::VolumeChanged, m_sliderContainer, &SliderContainer::updateSliderValue);
|
||||
|
||||
connect(m_dbusAudio, &DBusAudio::DefaultSinkChanged, this, [ this ](const QDBusObjectPath &value) {
|
||||
if (m_defaultSink)
|
||||
delete m_defaultSink;
|
||||
|
||||
m_defaultSink = new DBusSink("org.deepin.daemon.Audio1", value.path(), QDBusConnection::sessionBus(), this);
|
||||
m_sliderContainer->updateSliderValue(m_defaultSink->volume() * 100);
|
||||
connect(m_defaultSink, &DBusSink::VolumeChanged, m_sliderContainer, &SliderContainer::updateSliderValue);
|
||||
});
|
||||
|
||||
connect(m_sliderContainer, &SliderContainer::sliderValueChanged, this, [ this ](int value) {
|
||||
m_defaultSink->SetVolume(value, true);
|
||||
});
|
||||
|
||||
connect(m_defaultSink, &DBusSink::MuteChanged, this, [ this ] {
|
||||
m_sliderContainer->setIcon(SliderContainer::IconPosition::LeftIcon, QIcon(leftIcon()));
|
||||
});
|
||||
|
||||
connect(m_sliderContainer, &SliderContainer::iconClicked, this, [ this ](const SliderContainer::IconPosition icon) {
|
||||
switch (icon) {
|
||||
case SliderContainer::IconPosition::LeftIcon: {
|
||||
if (existActiveOutputDevice())
|
||||
m_defaultSink->SetMute(!m_defaultSink->mute());
|
||||
break;
|
||||
}
|
||||
case SliderContainer::IconPosition::RightIcon: {
|
||||
// 弹出音量选择对话框
|
||||
Q_EMIT rightIconClick();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const QString SoundWidget::leftIcon()
|
||||
{
|
||||
const bool mute = existActiveOutputDevice() ? m_defaultSink->mute() : true;
|
||||
if (mute)
|
||||
return QString(":/icons/resources/audio-volume-muted-dark");
|
||||
|
||||
return QString(":/icons/resources/volume");
|
||||
}
|
||||
|
||||
const QString SoundWidget::rightIcon()
|
||||
{
|
||||
return QString(":/icons/resources/broadcast");
|
||||
}
|
||||
|
||||
/** 判断是否存在未禁用的声音输出设备
|
||||
* @brief SoundApplet::existActiveOutputDevice
|
||||
* @return 存在返回true,否则返回false
|
||||
*/
|
||||
bool SoundWidget::existActiveOutputDevice() const
|
||||
{
|
||||
QString info = m_dbusAudio->property("CardsWithoutUnavailable").toString();
|
||||
|
||||
QJsonDocument doc = QJsonDocument::fromJson(info.toUtf8());
|
||||
QJsonArray jCards = doc.array();
|
||||
for (QJsonValue cV : jCards) {
|
||||
QJsonObject jCard = cV.toObject();
|
||||
QJsonArray jPorts = jCard["Ports"].toArray();
|
||||
|
||||
for (QJsonValue pV : jPorts) {
|
||||
QJsonObject jPort = pV.toObject();
|
||||
if (jPort["Direction"].toInt() == 1 && jPort["Enabled"].toBool())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
66
plugins/sound/soundwidget.h
Normal file
66
plugins/sound/soundwidget.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef SOUNDWIDGET_H
|
||||
#define SOUNDWIDGET_H
|
||||
|
||||
#include "org_deepin_daemon_audio.h"
|
||||
#include "org_deepin_daemon_audio_sink.h"
|
||||
|
||||
#include <DBlurEffectWidget>
|
||||
#include <QWidget>
|
||||
|
||||
class QDBusMessage;
|
||||
class SliderContainer;
|
||||
class QLabel;
|
||||
class AudioSink;
|
||||
|
||||
DWIDGET_USE_NAMESPACE
|
||||
|
||||
using DBusAudio = org::deepin::daemon::Audio1;
|
||||
using DBusSink = org::deepin::daemon::audio1::Sink;
|
||||
|
||||
class SoundWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SoundWidget(QWidget *parent = nullptr);
|
||||
~SoundWidget() override;
|
||||
|
||||
Q_SIGNALS:
|
||||
void rightIconClick();
|
||||
|
||||
protected:
|
||||
void initUi();
|
||||
void initConnection();
|
||||
|
||||
private:
|
||||
const QString leftIcon();
|
||||
const QString rightIcon();
|
||||
bool existActiveOutputDevice() const;
|
||||
|
||||
private:
|
||||
DBusAudio *m_dbusAudio;
|
||||
SliderContainer *m_sliderContainer;
|
||||
DBusSink *m_defaultSink;
|
||||
};
|
||||
|
||||
#endif // VOLUMEWIDGET_H
|
Loading…
x
Reference in New Issue
Block a user