mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-02 15:45:21 +00:00
feat: 快捷面板支持插件控制区域的显示
目前将声音的功能移到插件中实现,支持声音插件的面板的展示 Log: 简化任务栏代码,优化插件加载逻辑 Influence: 快捷面板,观察声音、亮度调整和音乐播放等功能是否显示正常 Task: https://pms.uniontech.com/task-view-208579.html Change-Id: I8fd7917e06dd7505da65dc36767166a779ffb0e6
This commit is contained in:
parent
ae74a6133f
commit
dd1ed1c0d4
@ -74,6 +74,13 @@ void QuickSettingController::pluginItemRemoved(PluginsItemInterface * const item
|
||||
Q_EMIT pluginRemoved(itemInter);
|
||||
}
|
||||
|
||||
void QuickSettingController::requestSetPluginAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool show)
|
||||
{
|
||||
// 设置插件列表可见事件
|
||||
if (show)
|
||||
Q_EMIT requestAppletShow(itemInter, itemKey);
|
||||
}
|
||||
|
||||
void QuickSettingController::updateDockInfo(PluginsItemInterface * const itemInter, const DockPart &part)
|
||||
{
|
||||
Q_EMIT pluginUpdated(itemInter, part);
|
||||
|
@ -52,6 +52,7 @@ Q_SIGNALS:
|
||||
void pluginInserted(PluginsItemInterface *itemInter, const PluginAttribute &);
|
||||
void pluginRemoved(PluginsItemInterface *itemInter);
|
||||
void pluginUpdated(PluginsItemInterface *, const DockPart &);
|
||||
void requestAppletShow(PluginsItemInterface * itemInter, const QString &itemKey);
|
||||
|
||||
protected:
|
||||
explicit QuickSettingController(QObject *parent = Q_NULLPTR);
|
||||
@ -63,7 +64,7 @@ protected:
|
||||
void pluginItemRemoved(PluginsItemInterface * const itemInter, const QString &) override;
|
||||
void requestPluginWindowAutoHide(PluginsItemInterface * const, const QString &, const bool) override {}
|
||||
void requestRefreshPluginWindowVisible(PluginsItemInterface * const, const QString &) override {}
|
||||
void requestSetPluginAppletVisible(PluginsItemInterface * const, const QString &, const bool) override {}
|
||||
void requestSetPluginAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool show) override;
|
||||
|
||||
void updateDockInfo(PluginsItemInterface * const itemInter, const DockPart &part) override;
|
||||
|
||||
|
@ -1,394 +0,0 @@
|
||||
#include "volumemodel.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QVariantMap>
|
||||
#include <QDebug>
|
||||
|
||||
/**
|
||||
* @brief 声音控制的类
|
||||
* @param parent
|
||||
*/
|
||||
|
||||
static const QString serviceName = QString("org.deepin.daemon.Audio1");
|
||||
static const QString servicePath = QString("/org/deepin/daemon/Audio1");
|
||||
|
||||
VolumeModel::VolumeModel(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_audio(new DBusAudio(serviceName, servicePath, QDBusConnection::sessionBus(), this))
|
||||
{
|
||||
reloadSinks();
|
||||
reloadPorts();
|
||||
connect(m_audio, &DBusAudio::DefaultSinkChanged, this, &VolumeModel::onDefaultSinkChanged);
|
||||
}
|
||||
|
||||
VolumeModel::~VolumeModel()
|
||||
{
|
||||
clearPorts();
|
||||
clearSinks();
|
||||
}
|
||||
|
||||
void VolumeModel::setActivePort(AudioPorts *port)
|
||||
{
|
||||
m_audio->SetPort(port->cardId(), port->name(), port->direction());
|
||||
}
|
||||
|
||||
QList<AudioSink *> VolumeModel::sinks() const
|
||||
{
|
||||
return m_sinks;
|
||||
}
|
||||
|
||||
QList<AudioPorts *> VolumeModel::ports() const
|
||||
{
|
||||
return m_ports;
|
||||
}
|
||||
|
||||
AudioSink *VolumeModel::defaultSink() const
|
||||
{
|
||||
for (AudioSink *sink : m_sinks) {
|
||||
if (sink->isDefault())
|
||||
return sink;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void VolumeModel::setVolume(int volumn)
|
||||
{
|
||||
for (AudioSink *audiosink : m_sinks) {
|
||||
if (audiosink->isDefault()) {
|
||||
audiosink->setVolume(volumn, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VolumeModel::setMute(bool value)
|
||||
{
|
||||
for (AudioSink *audiosink : m_sinks) {
|
||||
if (audiosink->isDefault()) {
|
||||
audiosink->setMute(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int VolumeModel::volume()
|
||||
{
|
||||
for (AudioSink *audiosink : m_sinks) {
|
||||
if (audiosink->isDefault())
|
||||
return audiosink->volume();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool VolumeModel::isMute()
|
||||
{
|
||||
for (AudioSink *audiosink : m_sinks) {
|
||||
if (audiosink->isDefault())
|
||||
return audiosink->isMute();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VolumeModel::existActiveOutputDevice()
|
||||
{
|
||||
for (AudioPorts *port : m_ports) {
|
||||
if (port->direction() == 1)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void VolumeModel::reloadSinks()
|
||||
{
|
||||
clearSinks();
|
||||
const QString defaultSinkPath = m_audio->defaultSink().path();
|
||||
QList<QDBusObjectPath> sinkPaths = m_audio->sinks();
|
||||
for (const QDBusObjectPath &sinkPath : sinkPaths) {
|
||||
const QString path = sinkPath.path();
|
||||
AudioSink *sink = new AudioSink(path, (path == defaultSinkPath), this);
|
||||
connect(sink, &AudioSink::volumeChanged, this, [ = ](int volume) {
|
||||
if (sink->isDefault())
|
||||
Q_EMIT volumeChanged(volume);
|
||||
});
|
||||
connect(sink, &AudioSink::muteChanged, this, [ = ](bool isMute) {
|
||||
if (sink->isDefault())
|
||||
Q_EMIT muteChanged(isMute);
|
||||
});
|
||||
|
||||
m_sinks << sink;
|
||||
}
|
||||
}
|
||||
|
||||
void VolumeModel::reloadPorts()
|
||||
{
|
||||
clearPorts();
|
||||
QString cards = m_audio->cardsWithoutUnavailable();
|
||||
QJsonParseError error;
|
||||
QJsonDocument json = QJsonDocument::fromJson(cards.toLocal8Bit(), &error);
|
||||
if (error.error != QJsonParseError::NoError)
|
||||
return;
|
||||
|
||||
uint sinkCardId = 0;
|
||||
QString sinkCardName;
|
||||
AudioSink *sink = defaultSink();
|
||||
if (sink) {
|
||||
sinkCardId = sink->cardId();
|
||||
sinkCardName = sink->name();
|
||||
}
|
||||
|
||||
QJsonArray array = json.array();
|
||||
for (const QJsonValue value : array) {
|
||||
QJsonObject cardObject = value.toObject();
|
||||
uint cardId = static_cast<uint>(cardObject.value("Id").toInt());
|
||||
QString cardName = cardObject.value("Name").toString();
|
||||
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;
|
||||
|
||||
AudioPorts *port = new AudioPorts(cardId, cardName);
|
||||
port->setName(jPort.value("Name").toString());
|
||||
port->setDescription(jPort.value("Description").toString());
|
||||
port->setDirection(direction);
|
||||
if (port->cardId() == sinkCardId && port->name() == sinkCardName)
|
||||
port->setIsChecked(true);
|
||||
|
||||
m_ports << port;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VolumeModel::onDefaultSinkChanged(const QDBusObjectPath &value)
|
||||
{
|
||||
AudioSink *audioSink = nullptr;
|
||||
const QString defaultPath = value.path();
|
||||
for (AudioSink *sink : m_sinks) {
|
||||
sink->setDefault(defaultPath == sink->m_devicePath);
|
||||
if (sink->isDefault())
|
||||
audioSink = sink;
|
||||
}
|
||||
|
||||
if (!audioSink)
|
||||
return;
|
||||
|
||||
bool checkChanged = false;
|
||||
for (AudioPorts *port : m_ports) {
|
||||
bool oldChecked = port->isChecked();
|
||||
port->setIsChecked(port->cardId() == audioSink->cardId()
|
||||
&& port->name() == audioSink->name());
|
||||
|
||||
if (oldChecked != port->isChecked() && port->isChecked())
|
||||
checkChanged = true;
|
||||
}
|
||||
|
||||
if (checkChanged)
|
||||
Q_EMIT checkPortChanged();
|
||||
|
||||
Q_EMIT defaultSinkChanged(audioSink);
|
||||
}
|
||||
|
||||
void VolumeModel::clearSinks()
|
||||
{
|
||||
for (AudioSink *sink : m_sinks)
|
||||
delete sink;
|
||||
|
||||
m_sinks.clear();
|
||||
}
|
||||
|
||||
void VolumeModel::clearPorts()
|
||||
{
|
||||
for (AudioPorts *port : m_ports)
|
||||
delete port;
|
||||
|
||||
m_ports.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 具体的声音设备
|
||||
* @param parent
|
||||
*/
|
||||
|
||||
AudioSink::AudioSink(QString path, bool isDefault, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_devicePath(path)
|
||||
, m_sink(new DBusSink(serviceName, path, QDBusConnection::sessionBus(), this))
|
||||
, m_isDefault(isDefault)
|
||||
{
|
||||
connect(m_sink, &DBusSink::MuteChanged, this, &AudioSink::muteChanged);
|
||||
connect(m_sink, &DBusSink::VolumeChanged, this, [ this ](double value) {
|
||||
Q_EMIT this->volumeChanged(static_cast<int>(value * 100));
|
||||
});
|
||||
}
|
||||
|
||||
AudioSink::~AudioSink()
|
||||
{
|
||||
}
|
||||
|
||||
void AudioSink::setDefault(bool isDefaultSink)
|
||||
{
|
||||
m_isDefault = isDefaultSink;
|
||||
}
|
||||
|
||||
bool AudioSink::isDefault()
|
||||
{
|
||||
return m_isDefault;
|
||||
}
|
||||
|
||||
bool AudioSink::isHeadPhone()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void AudioSink::setBalance(double value, bool isPlay)
|
||||
{
|
||||
m_sink->SetBalance(value, isPlay);
|
||||
}
|
||||
|
||||
void AudioSink::setFade(double value)
|
||||
{
|
||||
m_sink->SetFade(value);
|
||||
}
|
||||
|
||||
void AudioSink::setMute(bool mute)
|
||||
{
|
||||
m_sink->SetMute(mute);
|
||||
}
|
||||
|
||||
void AudioSink::setPort(QString name)
|
||||
{
|
||||
m_sink->SetPort(name);
|
||||
}
|
||||
|
||||
void AudioSink::setVolume(int value, bool isPlay)
|
||||
{
|
||||
m_sink->SetVolume((value * 0.01), isPlay);
|
||||
}
|
||||
|
||||
bool AudioSink::isMute()
|
||||
{
|
||||
return m_sink->mute();
|
||||
}
|
||||
|
||||
bool AudioSink::supportBalance()
|
||||
{
|
||||
return m_sink->supportBalance();
|
||||
}
|
||||
|
||||
bool AudioSink::suoportFade()
|
||||
{
|
||||
return m_sink->supportFade();
|
||||
}
|
||||
|
||||
double AudioSink::balance()
|
||||
{
|
||||
return m_sink->balance();
|
||||
}
|
||||
|
||||
double AudioSink::baseVolume()
|
||||
{
|
||||
return m_sink->baseVolume();
|
||||
}
|
||||
|
||||
double AudioSink::fade()
|
||||
{
|
||||
return m_sink->fade();
|
||||
}
|
||||
|
||||
int AudioSink::volume()
|
||||
{
|
||||
return static_cast<int>(m_sink->volume() * 100);
|
||||
}
|
||||
|
||||
QString AudioSink::description()
|
||||
{
|
||||
return m_sink->activePort().description;
|
||||
}
|
||||
|
||||
QString AudioSink::name()
|
||||
{
|
||||
return m_sink->activePort().name;
|
||||
}
|
||||
|
||||
uint AudioSink::cardId()
|
||||
{
|
||||
return m_sink->card();
|
||||
}
|
||||
|
||||
AudioPorts::AudioPorts(uint cardId, QString cardName)
|
||||
: m_cardId(cardId)
|
||||
, m_cardName(cardName)
|
||||
, m_direction(0)
|
||||
, m_isCheck(false)
|
||||
, m_isHeadPhone(false)
|
||||
{
|
||||
}
|
||||
|
||||
AudioPorts::~AudioPorts()
|
||||
{
|
||||
}
|
||||
|
||||
uint AudioPorts::cardId() const
|
||||
{
|
||||
return m_cardId;
|
||||
}
|
||||
|
||||
QString AudioPorts::cardName() const
|
||||
{
|
||||
return m_cardName;
|
||||
}
|
||||
|
||||
void AudioPorts::setName(const QString &name)
|
||||
{
|
||||
m_portName = name;
|
||||
}
|
||||
|
||||
QString AudioPorts::name() const
|
||||
{
|
||||
return m_portName;
|
||||
}
|
||||
|
||||
void AudioPorts::setDescription(const QString &desc)
|
||||
{
|
||||
m_description = desc;
|
||||
}
|
||||
|
||||
QString AudioPorts::description() const
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
|
||||
void AudioPorts::setDirection(int dir)
|
||||
{
|
||||
m_direction = dir;
|
||||
}
|
||||
|
||||
void AudioPorts::setIsChecked(bool isChecked)
|
||||
{
|
||||
m_isCheck = isChecked;
|
||||
}
|
||||
|
||||
int AudioPorts::direction() const
|
||||
{
|
||||
return m_direction;
|
||||
}
|
||||
|
||||
bool AudioPorts::isChecked() const
|
||||
{
|
||||
return m_isCheck;
|
||||
}
|
||||
|
||||
bool AudioPorts::isHeadPhone() const
|
||||
{
|
||||
return m_isHeadPhone;
|
||||
}
|
@ -1,135 +0,0 @@
|
||||
#ifndef VOLUMNMODEL_H
|
||||
#define VOLUMNMODEL_H
|
||||
|
||||
#include "org_deepin_daemon_audio.h"
|
||||
#include "org_deepin_daemon_audio_sink.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
using DBusAudio = org::deepin::daemon::Audio1;
|
||||
using DBusSink = org::deepin::daemon::audio1::Sink;
|
||||
|
||||
class QDBusMessage;
|
||||
class AudioSink;
|
||||
class AudioPorts;
|
||||
|
||||
class VolumeModel : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit VolumeModel(QObject *parent);
|
||||
~VolumeModel();
|
||||
|
||||
void setActivePort(AudioPorts *port);
|
||||
|
||||
QList<AudioSink *> sinks() const;
|
||||
QList<AudioPorts *> ports() const;
|
||||
|
||||
AudioSink *defaultSink() const;
|
||||
|
||||
void setVolume(int volume);
|
||||
void setMute(bool value);
|
||||
|
||||
int volume();
|
||||
bool isMute();
|
||||
bool existActiveOutputDevice();
|
||||
|
||||
Q_SIGNALS:
|
||||
void defaultSinkChanged(AudioSink *);
|
||||
void volumeChanged(int);
|
||||
void muteChanged(bool);
|
||||
void checkPortChanged();
|
||||
|
||||
private Q_SLOTS:
|
||||
void onDefaultSinkChanged(const QDBusObjectPath & value);
|
||||
|
||||
private:
|
||||
void reloadSinks();
|
||||
void reloadPorts();
|
||||
void clearSinks();
|
||||
void clearPorts();
|
||||
|
||||
private:
|
||||
QList<AudioSink *> m_sinks;
|
||||
QList<AudioPorts *> m_ports;
|
||||
|
||||
DBusAudio *m_audio;
|
||||
};
|
||||
|
||||
class AudioSink : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
friend class VolumeModel;
|
||||
|
||||
Q_SIGNALS:
|
||||
void volumeChanged(int);
|
||||
void muteChanged(bool);
|
||||
|
||||
public:
|
||||
bool isDefault();
|
||||
bool isHeadPhone();
|
||||
|
||||
void setBalance(double value, bool isPlay);
|
||||
void setFade(double value);
|
||||
void setMute(bool mute);
|
||||
void setPort(QString name);
|
||||
void setVolume(int value, bool isPlay);
|
||||
|
||||
bool isMute();
|
||||
bool supportBalance();
|
||||
bool suoportFade();
|
||||
double balance();
|
||||
double baseVolume();
|
||||
double fade();
|
||||
int volume();
|
||||
QString description();
|
||||
QString name();
|
||||
uint cardId();
|
||||
|
||||
protected:
|
||||
explicit AudioSink(QString path, bool isDefault, QObject *parent = nullptr);
|
||||
~AudioSink();
|
||||
void setDefault(bool isDefaultSink);
|
||||
|
||||
private:
|
||||
QString m_devicePath;
|
||||
DBusSink *m_sink;
|
||||
bool m_isDefault;
|
||||
};
|
||||
|
||||
class AudioPorts : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
friend class VolumeModel;
|
||||
|
||||
public:
|
||||
uint cardId() const;
|
||||
QString cardName() const;
|
||||
QString name() const;
|
||||
QString description() const;
|
||||
int direction() const;
|
||||
bool isChecked() const;
|
||||
bool isHeadPhone() const;
|
||||
|
||||
protected:
|
||||
AudioPorts(uint cardId, QString cardName);
|
||||
~AudioPorts();
|
||||
void setName(const QString &name);
|
||||
void setDescription(const QString &desc);
|
||||
void setDirection(int dir);
|
||||
void setIsChecked(bool isChecked);
|
||||
|
||||
private:
|
||||
uint m_cardId;
|
||||
QString m_cardName;
|
||||
QString m_portName;
|
||||
QString m_description;
|
||||
int m_direction;
|
||||
bool m_isCheck;
|
||||
bool m_isHeadPhone;
|
||||
};
|
||||
|
||||
#endif // VOLUMNMODEL_H
|
@ -1,260 +0,0 @@
|
||||
/*
|
||||
* 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 "volumedeviceswidget.h"
|
||||
#include "brightnessmodel.h"
|
||||
#include "volumemodel.h"
|
||||
#include "settingdelegate.h"
|
||||
#include "imageutil.h"
|
||||
#include "slidercontainer.h"
|
||||
#include "dbusutil.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
|
||||
|
||||
VolumeDevicesWidget::VolumeDevicesWidget(VolumeModel *model, 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(model)
|
||||
, m_audioSink(nullptr)
|
||||
, m_model(new QStandardItemModel(this))
|
||||
, m_delegate(new SettingDelegate(m_deviceList))
|
||||
{
|
||||
initUi();
|
||||
initConnection();
|
||||
reloadAudioDevices();
|
||||
m_sliderParent->installEventFilter(this);
|
||||
|
||||
QMetaObject::invokeMethod(this, [ this ] {
|
||||
resetVolumeInfo();
|
||||
resizeHeight();
|
||||
}, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
VolumeDevicesWidget::~VolumeDevicesWidget()
|
||||
{
|
||||
}
|
||||
|
||||
bool VolumeDevicesWidget::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 VolumeDevicesWidget::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 VolumeDevicesWidget::reloadAudioDevices()
|
||||
{
|
||||
QList<AudioPorts *> ports = m_volumeModel->ports();
|
||||
for (AudioPorts *port : ports) {
|
||||
DStandardItem *item = new DStandardItem;
|
||||
item->setText(QString("%1(%2)").arg(port->description()).arg(port->cardName()));
|
||||
item->setIcon(QIcon(soundIconFile(port)));
|
||||
item->setFlags(Qt::NoItemFlags);
|
||||
item->setData(port->isChecked(), itemCheckRole);
|
||||
item->setData(QVariant::fromValue(port), itemDataRole);
|
||||
m_model->appendRow(item);
|
||||
if (port->isChecked())
|
||||
m_deviceList->setCurrentIndex(m_model->indexFromItem(item));
|
||||
}
|
||||
|
||||
DStandardItem *settingItem = new DStandardItem;
|
||||
settingItem->setText(tr("Sound settings"));
|
||||
settingItem->setFlags(Qt::NoItemFlags);
|
||||
settingItem->setData(false, itemCheckRole);
|
||||
m_model->appendRow(settingItem);
|
||||
}
|
||||
|
||||
void VolumeDevicesWidget::initConnection()
|
||||
{
|
||||
m_audioSink = m_volumeModel->defaultSink();
|
||||
|
||||
if (m_audioSink)
|
||||
connect(m_audioSink, &AudioSink::volumeChanged, m_sliderContainer, &SliderContainer::updateSliderValue);
|
||||
connect(m_volumeModel, &VolumeModel::defaultSinkChanged, this, [ this ](AudioSink *sink) {
|
||||
if (m_audioSink)
|
||||
disconnect(m_audioSink);
|
||||
|
||||
m_audioSink = sink;
|
||||
if (sink)
|
||||
connect(sink, &AudioSink::volumeChanged, m_sliderContainer, &SliderContainer::updateSliderValue);
|
||||
|
||||
resetVolumeInfo();
|
||||
m_deviceList->update();
|
||||
});
|
||||
|
||||
connect(m_sliderContainer, &SliderContainer::sliderValueChanged, this, [ this ](int value) {
|
||||
AudioSink *defSink = m_volumeModel->defaultSink();
|
||||
if (!defSink)
|
||||
return;
|
||||
|
||||
defSink->setVolume(value, true);
|
||||
});
|
||||
connect(m_volumeModel, &VolumeModel::checkPortChanged, this, [ this ] {
|
||||
for (int i = 0; i < m_model->rowCount(); i++) {
|
||||
QModelIndex index = m_model->index(i, 0);
|
||||
AudioPorts *port = index.data(itemDataRole).value<AudioPorts *>();
|
||||
if (port)
|
||||
m_model->setData(index, port->isChecked(), itemCheckRole);
|
||||
}
|
||||
m_deviceList->update();
|
||||
});
|
||||
|
||||
connect(m_delegate, &SettingDelegate::selectIndexChanged, this, [ this ](const QModelIndex &index) {
|
||||
AudioPorts *port = index.data(itemDataRole).value<AudioPorts *>();
|
||||
if (port) {
|
||||
m_volumeModel->setActivePort(port);
|
||||
m_deviceList->update();
|
||||
} else {
|
||||
// 打开控制中心的声音模块
|
||||
DDBusSender().service(controllCenterService)
|
||||
.path(controllCenterPath)
|
||||
.interface(controllCenterInterface)
|
||||
.method("ShowPage").arg(QString("sound")).call();
|
||||
hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
QString VolumeDevicesWidget::leftIcon()
|
||||
{
|
||||
QString iconLeft = QString(":/icons/resources/audio-volume-%1").arg(m_volumeModel->isMute() ? "muted" : "low");
|
||||
if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType)
|
||||
iconLeft.append("-dark");
|
||||
|
||||
return iconLeft;
|
||||
}
|
||||
|
||||
QString VolumeDevicesWidget::rightIcon()
|
||||
{
|
||||
QString iconRight = QString(":/icons/resources/audio-volume-high");
|
||||
if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType)
|
||||
iconRight.append("-dark");
|
||||
|
||||
return iconRight;
|
||||
}
|
||||
|
||||
const QString VolumeDevicesWidget::soundIconFile(AudioPorts *port) const
|
||||
{
|
||||
if (!port)
|
||||
return QString();
|
||||
|
||||
if (port->isHeadPhone()) {
|
||||
if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType)
|
||||
return QString(":/icons/resources/ICON_Device_Headphone_dark.svg");
|
||||
|
||||
return QString(":/icons/resources/ICON_Device_Headphone.svg");
|
||||
}
|
||||
|
||||
if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType)
|
||||
return QString(":/icons/resources/ICON_Device_Laptop_dark.svg");
|
||||
|
||||
return QString(":/icons/resources/ICON_Device_Laptop.svg");
|
||||
}
|
||||
|
||||
void VolumeDevicesWidget::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 VolumeDevicesWidget::resetVolumeInfo()
|
||||
{
|
||||
AudioSink *defaultSink = m_volumeModel->defaultSink();
|
||||
if (!defaultSink)
|
||||
return;
|
||||
|
||||
m_sliderContainer->updateSliderValue(defaultSink->volume());
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
/*
|
||||
* 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 VOLUMEDEVICESWIDGET_H
|
||||
#define VOLUMEDEVICESWIDGET_H
|
||||
|
||||
#include <DStyledItemDelegate>
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Dtk { namespace Widget { class DListView; } }
|
||||
|
||||
using namespace Dtk::Widget;
|
||||
|
||||
class SliderContainer;
|
||||
class QStandardItemModel;
|
||||
class QLabel;
|
||||
class VolumeModel;
|
||||
class AudioPorts;
|
||||
class AudioSink;
|
||||
class SettingDelegate;
|
||||
|
||||
class VolumeDevicesWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit VolumeDevicesWidget(VolumeModel *model, QWidget *parent = nullptr);
|
||||
~VolumeDevicesWidget() override;
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watcher, QEvent *event) override;
|
||||
|
||||
private:
|
||||
void initUi();
|
||||
void reloadAudioDevices();
|
||||
void initConnection();
|
||||
QString leftIcon();
|
||||
QString rightIcon();
|
||||
const QString soundIconFile(AudioPorts *port) const;
|
||||
|
||||
void resizeHeight();
|
||||
|
||||
void resetVolumeInfo();
|
||||
|
||||
private:
|
||||
QWidget *m_sliderParent;
|
||||
SliderContainer *m_sliderContainer;
|
||||
QLabel *m_descriptionLabel;
|
||||
DListView *m_deviceList;
|
||||
VolumeModel *m_volumeModel;
|
||||
AudioSink *m_audioSink;
|
||||
QStandardItemModel *m_model;
|
||||
SettingDelegate *m_delegate;
|
||||
};
|
||||
|
||||
#endif // VOLUMEDEVICESWIDGET_H
|
@ -1,150 +0,0 @@
|
||||
/*
|
||||
* 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 "volumewidget.h"
|
||||
#include "brightnessmodel.h"
|
||||
#include "imageutil.h"
|
||||
#include "volumemodel.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
|
||||
|
||||
VolumeWidget::VolumeWidget(VolumeModel *model, QWidget *parent)
|
||||
: DBlurEffectWidget(parent)
|
||||
, m_model(model)
|
||||
, m_sliderContainer(new SliderContainer(this))
|
||||
, m_defaultSink(m_model->defaultSink())
|
||||
{
|
||||
initUi();
|
||||
initConnection();
|
||||
}
|
||||
|
||||
VolumeWidget::~VolumeWidget()
|
||||
{
|
||||
}
|
||||
|
||||
void VolumeWidget::initUi()
|
||||
{
|
||||
if (m_defaultSink)
|
||||
m_sliderContainer->updateSliderValue(m_defaultSink->volume());
|
||||
|
||||
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);
|
||||
|
||||
bool existActiveOutputDevice = m_model->existActiveOutputDevice();
|
||||
setEnabled(existActiveOutputDevice);
|
||||
}
|
||||
|
||||
void VolumeWidget::initConnection()
|
||||
{
|
||||
if (m_defaultSink)
|
||||
connect(m_defaultSink, &AudioSink::volumeChanged, m_sliderContainer, &SliderContainer::updateSliderValue);
|
||||
|
||||
connect(m_model, &VolumeModel::defaultSinkChanged, this, [ this ](AudioSink *sink) {
|
||||
if (m_defaultSink)
|
||||
disconnect(m_defaultSink);
|
||||
|
||||
m_defaultSink = sink;
|
||||
if (sink) {
|
||||
m_sliderContainer->updateSliderValue(sink->volume());
|
||||
connect(sink, &AudioSink::volumeChanged, m_sliderContainer, &SliderContainer::updateSliderValue);
|
||||
}
|
||||
});
|
||||
|
||||
connect(m_sliderContainer, &SliderContainer::sliderValueChanged, this, [ this ](int value) {
|
||||
AudioSink *sink = m_model->defaultSink();
|
||||
if (sink)
|
||||
sink->setVolume(value, true);
|
||||
});
|
||||
|
||||
connect(m_model, &VolumeModel::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 (m_model->existActiveOutputDevice())
|
||||
m_model->setMute(!m_model->isMute());
|
||||
break;
|
||||
}
|
||||
case SliderContainer::IconPosition::RightIcon: {
|
||||
// 弹出音量选择对话框
|
||||
Q_EMIT rightIconClick();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void VolumeWidget::showEvent(QShowEvent *event)
|
||||
{
|
||||
DBlurEffectWidget::showEvent(event);
|
||||
Q_EMIT visibleChanged(true);
|
||||
}
|
||||
|
||||
void VolumeWidget::hideEvent(QHideEvent *event)
|
||||
{
|
||||
DBlurEffectWidget::hideEvent(event);
|
||||
Q_EMIT visibleChanged(false);
|
||||
}
|
||||
|
||||
const QString VolumeWidget::leftIcon()
|
||||
{
|
||||
bool existActiveOutputDevice = m_model->existActiveOutputDevice();
|
||||
const bool mute = existActiveOutputDevice ? m_model->isMute() : true;
|
||||
if (mute)
|
||||
return QString(":/icons/resources/audio-volume-muted-dark");
|
||||
|
||||
return QString(":/icons/resources/volume");
|
||||
}
|
||||
|
||||
const QString VolumeWidget::rightIcon()
|
||||
{
|
||||
return QString(":/icons/resources/broadcast");
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
/*
|
||||
* 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 VOLUMEWIDGET_H
|
||||
#define VOLUMEWIDGET_H
|
||||
|
||||
#include <DBlurEffectWidget>
|
||||
#include <QWidget>
|
||||
|
||||
class VolumeModel;
|
||||
class QDBusMessage;
|
||||
class SliderContainer;
|
||||
class QLabel;
|
||||
class AudioSink;
|
||||
|
||||
DWIDGET_USE_NAMESPACE
|
||||
|
||||
class VolumeWidget : public DBlurEffectWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit VolumeWidget(VolumeModel *model, QWidget *parent = nullptr);
|
||||
~VolumeWidget() override;
|
||||
|
||||
Q_SIGNALS:
|
||||
void visibleChanged(bool);
|
||||
void rightIconClick();
|
||||
|
||||
protected:
|
||||
void initUi();
|
||||
void initConnection();
|
||||
|
||||
void showEvent(QShowEvent *event) override;
|
||||
void hideEvent(QHideEvent *event) override;
|
||||
|
||||
private:
|
||||
const QString leftIcon();
|
||||
const QString rightIcon();
|
||||
|
||||
private:
|
||||
VolumeModel *m_model;
|
||||
SliderContainer *m_sliderContainer;
|
||||
AudioSink *m_defaultSink;
|
||||
};
|
||||
|
||||
#endif // VOLUMEWIDGET_H
|
@ -27,10 +27,7 @@
|
||||
#include "dockpopupwindow.h"
|
||||
#include "brightnesswidget.h"
|
||||
#include "slidercontainer.h"
|
||||
#include "volumewidget.h"
|
||||
#include "volumedeviceswidget.h"
|
||||
#include "pluginchildpage.h"
|
||||
#include "volumemodel.h"
|
||||
#include "utils.h"
|
||||
#include "displaysettingwidget.h"
|
||||
|
||||
@ -47,11 +44,13 @@ DWIDGET_USE_NAMESPACE
|
||||
|
||||
struct QuickDragInfo {
|
||||
QPoint dragPosition;
|
||||
QuickSettingItem *dragItem = nullptr;
|
||||
QWidget *dragItem = nullptr;
|
||||
PluginsItemInterface *pluginInter = nullptr;
|
||||
void reset() {
|
||||
dragPosition.setX(0);
|
||||
dragPosition.setY(0);
|
||||
dragItem = nullptr;
|
||||
pluginInter = nullptr;
|
||||
}
|
||||
bool isNull() {
|
||||
return !dragItem;
|
||||
@ -76,11 +75,8 @@ QuickSettingContainer::QuickSettingContainer(QWidget *parent)
|
||||
, m_mainlayout(new QVBoxLayout(m_mainWidget))
|
||||
, m_pluginLoader(QuickSettingController::instance())
|
||||
, m_playerWidget(new MediaWidget(m_componentWidget))
|
||||
, m_volumeModel(new VolumeModel(this))
|
||||
, m_brightnessModel(new BrightnessModel(this))
|
||||
, m_volumnWidget(new VolumeWidget(m_volumeModel, m_componentWidget))
|
||||
, m_brihtnessWidget(new BrightnessWidget(m_brightnessModel, m_componentWidget))
|
||||
, m_volumeSettingWidget(new VolumeDevicesWidget(m_volumeModel, this))
|
||||
, m_displaySettingWidget(new DisplaySettingWidget(this))
|
||||
, m_childPage(new PluginChildPage(this))
|
||||
, m_dragInfo(new struct QuickDragInfo)
|
||||
@ -190,13 +186,27 @@ bool QuickSettingContainer::eventFilter(QObject *watched, QEvent *event)
|
||||
break;
|
||||
}
|
||||
case QEvent::MouseButtonPress: {
|
||||
QuickSettingItem *item = qobject_cast<QuickSettingItem *>(watched);
|
||||
if (!item)
|
||||
break;
|
||||
|
||||
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
||||
m_dragInfo->dragPosition = mouseEvent->pos();
|
||||
m_dragInfo->dragItem = item;
|
||||
QuickSettingItem *item = qobject_cast<QuickSettingItem *>(watched);
|
||||
if (item) {
|
||||
m_dragInfo->dragPosition = mouseEvent->pos();
|
||||
m_dragInfo->dragItem = item;
|
||||
m_dragInfo->pluginInter = item->pluginItem();
|
||||
} else {
|
||||
QList<PluginsItemInterface *> plugins = QuickSettingController::instance()->pluginItems(QuickSettingController::PluginAttribute::Quick);
|
||||
for (PluginsItemInterface *plugin : plugins) {
|
||||
if (!isApplet(plugin))
|
||||
continue;
|
||||
|
||||
if (plugin->itemWidget(QUICK_ITEM_DETAIL_KEY) != watched)
|
||||
continue;
|
||||
|
||||
m_dragInfo->dragPosition = mouseEvent->pos();
|
||||
m_dragInfo->dragItem = plugin->itemWidget(QUICK_ITEM_DETAIL_KEY);
|
||||
m_dragInfo->pluginInter = plugin;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QEvent::MouseButtonRelease: {
|
||||
@ -228,36 +238,103 @@ QPoint QuickSettingContainer::hotSpot(const QPixmap &pixmap)
|
||||
return QPoint(pixmap.width(), pixmap.height());
|
||||
}
|
||||
|
||||
bool QuickSettingContainer::isApplet(PluginsItemInterface *itemInter) const
|
||||
{
|
||||
if (!itemInter->itemWidget(QUICK_ITEM_DETAIL_KEY))
|
||||
return false;
|
||||
|
||||
QJsonObject json = QuickSettingController::instance()->metaData(itemInter);
|
||||
if (!json.contains("applet"))
|
||||
return false;
|
||||
|
||||
return json.value("applet").toBool();
|
||||
}
|
||||
|
||||
void QuickSettingContainer::onPluginInsert(PluginsItemInterface * itemInter)
|
||||
{
|
||||
initQuickItem(itemInter);
|
||||
updateItemLayout();
|
||||
QWidget *itemWidget = itemInter->itemWidget(QUICK_ITEM_DETAIL_KEY);
|
||||
if (isApplet(itemInter)) {
|
||||
// 如果存在这个窗体,就让其显示在下方
|
||||
DBlurEffectWidget *effectWidget = new DBlurEffectWidget(m_componentWidget);
|
||||
QVBoxLayout *layout = new QVBoxLayout(effectWidget);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
itemWidget->setParent(effectWidget);
|
||||
itemWidget->setVisible(true);
|
||||
layout->addWidget(itemWidget);
|
||||
effectWidget->setFixedHeight(itemWidget->height());
|
||||
effectWidget->setMaskColor(QColor(239, 240, 245));
|
||||
effectWidget->setBlurRectXRadius(8);
|
||||
effectWidget->setBlurRectYRadius(8);
|
||||
m_componentWidget->layout()->addWidget(effectWidget);
|
||||
|
||||
itemWidget->installEventFilter(this);
|
||||
} else {
|
||||
// 如果不存在获取到的子窗体,就让其显示在上方插件显示的位置
|
||||
initQuickItem(itemInter);
|
||||
updateItemLayout();
|
||||
}
|
||||
onResizeView();
|
||||
}
|
||||
|
||||
void QuickSettingContainer::onPluginRemove(PluginsItemInterface * itemInter)
|
||||
{
|
||||
QuickSettingItem *quickItem = nullptr;
|
||||
for (QuickSettingItem *settingItem : m_quickSettings) {
|
||||
if (settingItem->pluginItem() != itemInter)
|
||||
continue;
|
||||
QWidget *itemWidget = itemInter->itemWidget(QUICK_ITEM_DETAIL_KEY);
|
||||
if (itemWidget) {
|
||||
for (int i = 0; i < m_componentWidget->layout()->count(); i++) {
|
||||
QLayoutItem *layoutItem = m_componentWidget->layout()->itemAt(i);
|
||||
if (!layoutItem)
|
||||
continue;
|
||||
|
||||
quickItem = settingItem;
|
||||
break;
|
||||
DBlurEffectWidget *effectWidget = qobject_cast<DBlurEffectWidget *>(layoutItem->widget());
|
||||
if (!effectWidget || !effectWidget->layout())
|
||||
continue;
|
||||
|
||||
bool found = false;
|
||||
for (int j = 0; j < effectWidget->layout()->count(); j++) {
|
||||
QLayoutItem *layoutItem = effectWidget->layout()->itemAt(i);
|
||||
if (!layoutItem)
|
||||
continue;
|
||||
|
||||
if (layoutItem->widget() == itemWidget) {
|
||||
effectWidget->layout()->removeWidget(itemWidget);
|
||||
itemWidget->setParent(nullptr);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
continue;
|
||||
|
||||
m_componentWidget->layout()->removeWidget(effectWidget);
|
||||
effectWidget->setParent(nullptr);
|
||||
effectWidget->deleteLater();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
QuickSettingItem *quickItem = nullptr;
|
||||
for (QuickSettingItem *settingItem : m_quickSettings) {
|
||||
if (settingItem->pluginItem() != itemInter)
|
||||
continue;
|
||||
|
||||
quickItem = settingItem;
|
||||
break;
|
||||
}
|
||||
if (!quickItem)
|
||||
return;
|
||||
|
||||
m_pluginLayout->removeWidget(quickItem);
|
||||
m_quickSettings.removeOne(quickItem);
|
||||
disconnect(quickItem, &QuickSettingItem::detailClicked, this, &QuickSettingContainer::onItemDetailClick);
|
||||
quickItem->setParent(nullptr);
|
||||
quickItem->removeEventFilter(this);
|
||||
quickItem->setMouseTracking(false);
|
||||
quickItem->deleteLater();
|
||||
|
||||
//调整子控件的位置
|
||||
updateItemLayout();
|
||||
}
|
||||
if (!quickItem)
|
||||
return;
|
||||
|
||||
m_pluginLayout->removeWidget(quickItem);
|
||||
m_quickSettings.removeOne(quickItem);
|
||||
disconnect(quickItem, &QuickSettingItem::detailClicked, this, &QuickSettingContainer::onItemDetailClick);
|
||||
quickItem->setParent(nullptr);
|
||||
quickItem->removeEventFilter(this);
|
||||
quickItem->setMouseTracking(false);
|
||||
quickItem->deleteLater();
|
||||
|
||||
//调整子控件的位置
|
||||
updateItemLayout();
|
||||
onResizeView();
|
||||
}
|
||||
|
||||
@ -269,16 +346,23 @@ void QuickSettingContainer::mouseMoveEvent(QMouseEvent *event)
|
||||
QPoint pointCurrent = event->pos();
|
||||
if (qAbs(m_dragInfo->dragPosition.x() - pointCurrent.x()) > 5
|
||||
|| qAbs(m_dragInfo->dragPosition.y() - pointCurrent.y()) > 5) {
|
||||
QuickSettingItem *moveItem = m_dragInfo->dragItem;
|
||||
m_dragInfo->reset();
|
||||
|
||||
QDrag *drag = new QDrag(this);
|
||||
QuickPluginMimeData *mimedata = new QuickPluginMimeData(moveItem->pluginItem());
|
||||
QuickSettingItem *moveItem = qobject_cast<QuickSettingItem *>(m_dragInfo->dragItem);
|
||||
QuickPluginMimeData *mimedata = new QuickPluginMimeData(m_dragInfo->pluginInter);
|
||||
drag->setMimeData(mimedata);
|
||||
QPixmap dragPixmap = moveItem->dragPixmap();
|
||||
drag->setPixmap(dragPixmap);
|
||||
drag->setHotSpot(hotSpot(dragPixmap));
|
||||
if (moveItem) {
|
||||
QPixmap dragPixmap = moveItem->dragPixmap();
|
||||
drag->setPixmap(dragPixmap);
|
||||
drag->setHotSpot(hotSpot(dragPixmap));
|
||||
} else {
|
||||
// 如果拖动的是声音等插件
|
||||
QPixmap dragPixmap = m_dragInfo->dragItem->grab();
|
||||
drag->setPixmap(dragPixmap);
|
||||
drag->setHotSpot(hotSpot(dragPixmap));
|
||||
}
|
||||
|
||||
m_dragInfo->reset();
|
||||
drag->exec(Qt::MoveAction | Qt::CopyAction);
|
||||
}
|
||||
}
|
||||
@ -312,11 +396,9 @@ void QuickSettingContainer::initUi()
|
||||
|
||||
// 添加音乐播放插件
|
||||
m_playerWidget->setFixedHeight(ITEMHEIGHT);
|
||||
m_volumnWidget->setFixedHeight(ITEMHEIGHT);
|
||||
m_brihtnessWidget->setFixedHeight(ITEMHEIGHT);
|
||||
|
||||
setWidgetStyle(m_playerWidget);
|
||||
setWidgetStyle(m_volumnWidget);
|
||||
setWidgetStyle(m_brihtnessWidget);
|
||||
|
||||
m_mainlayout->setSpacing(ITEMSPACE);
|
||||
@ -336,20 +418,17 @@ void QuickSettingContainer::initUi()
|
||||
ctrlLayout->setSpacing(ITEMSPACE);
|
||||
|
||||
ctrlLayout->addWidget(m_playerWidget);
|
||||
ctrlLayout->addWidget(m_volumnWidget);
|
||||
ctrlLayout->addWidget(m_brihtnessWidget);
|
||||
|
||||
m_mainlayout->addWidget(m_componentWidget);
|
||||
// 加载所有的插件
|
||||
QList<PluginsItemInterface *> plugins = m_pluginLoader->pluginItems(QuickSettingController::PluginAttribute::Quick);
|
||||
for (PluginsItemInterface *plugin : plugins)
|
||||
initQuickItem(plugin);
|
||||
onPluginInsert(plugin);
|
||||
|
||||
m_switchLayout->addWidget(m_mainWidget);
|
||||
m_switchLayout->addWidget(m_childPage);
|
||||
|
||||
m_volumeSettingWidget->hide();
|
||||
|
||||
setMouseTracking(true);
|
||||
setAcceptDrops(true);
|
||||
|
||||
@ -373,12 +452,8 @@ void QuickSettingContainer::initConnection()
|
||||
onPluginInsert(itemInter);
|
||||
});
|
||||
connect(m_pluginLoader, &QuickSettingController::pluginRemoved, this, &QuickSettingContainer::onPluginRemove);
|
||||
connect(m_pluginLoader, &QuickSettingController::requestAppletShow, this, &QuickSettingContainer::onRequestAppletShow);
|
||||
connect(m_playerWidget, &MediaWidget::visibleChanged, this, &QuickSettingContainer::onResizeView);
|
||||
connect(m_volumnWidget, &VolumeWidget::visibleChanged, this, &QuickSettingContainer::onResizeView);
|
||||
connect(m_volumnWidget, &VolumeWidget::rightIconClick, this, [ this ] {
|
||||
showWidget(m_volumeSettingWidget, tr("voice"));
|
||||
onResizeView();
|
||||
});
|
||||
connect(m_brihtnessWidget, &BrightnessWidget::visibleChanged, this, &QuickSettingContainer::onResizeView);
|
||||
connect(m_brihtnessWidget->sliderContainer(), &SliderContainer::iconClicked, this, [ this ](const SliderContainer::IconPosition &iconPosition) {
|
||||
if (iconPosition == SliderContainer::RightIcon) {
|
||||
@ -412,17 +487,50 @@ void QuickSettingContainer::onResizeView()
|
||||
|
||||
m_pluginWidget->setFixedHeight(ITEMHEIGHT * rowCount + ITEMSPACE * (rowCount - 1));
|
||||
|
||||
int panelCount = 0;
|
||||
if (m_playerWidget->isVisible())
|
||||
panelCount++;
|
||||
if (m_volumnWidget->isVisible())
|
||||
panelCount++;
|
||||
if (m_brihtnessWidget->isVisible())
|
||||
panelCount++;
|
||||
int height = 0;
|
||||
int widgetCount = 0;
|
||||
for (int i = 0; i < m_componentWidget->layout()->count(); i++) {
|
||||
QLayoutItem *layoutItem = m_componentWidget->layout()->itemAt(i);
|
||||
if (!layoutItem)
|
||||
continue;
|
||||
|
||||
DBlurEffectWidget *widget = qobject_cast<DBlurEffectWidget *>(layoutItem->widget());
|
||||
if (!widget)
|
||||
continue;
|
||||
|
||||
if (widget == m_playerWidget || widget == m_brihtnessWidget)
|
||||
continue;
|
||||
|
||||
height += widget->height();
|
||||
widgetCount++;
|
||||
}
|
||||
|
||||
if (m_playerWidget->isVisible()) {
|
||||
height += m_playerWidget->height();
|
||||
widgetCount++;
|
||||
}
|
||||
if (m_brihtnessWidget->isVisible()) {
|
||||
height += m_brihtnessWidget->height();
|
||||
widgetCount++;
|
||||
}
|
||||
|
||||
m_componentWidget->setFixedHeight(height + (widgetCount - 1) * ITEMSPACE);
|
||||
|
||||
m_componentWidget->setFixedHeight(ITEMHEIGHT * panelCount + ITEMSPACE * (panelCount - 1));
|
||||
setFixedHeight(ITEMSPACE * 3 + m_pluginWidget->height() + m_componentWidget->height());
|
||||
} else if (m_switchLayout->currentWidget() == m_childPage) {
|
||||
setFixedHeight(m_childPage->height());
|
||||
}
|
||||
}
|
||||
|
||||
void QuickSettingContainer::onRequestAppletShow(PluginsItemInterface *itemInter, const QString &itemKey)
|
||||
{
|
||||
if (itemKey == QUICK_ITEM_DETAIL_KEY) {
|
||||
// 显示弹出的内容
|
||||
QWidget *itemApplet = itemInter->itemPopupApplet(itemKey);
|
||||
if (!itemApplet)
|
||||
return;
|
||||
|
||||
showWidget(itemApplet, itemInter->pluginDisplayName());
|
||||
onResizeView();
|
||||
}
|
||||
}
|
||||
|
@ -33,9 +33,7 @@ class DockItem;
|
||||
class QVBoxLayout;
|
||||
class QuickSettingController;
|
||||
class MediaWidget;
|
||||
class VolumeModel;
|
||||
class BrightnessModel;
|
||||
class VolumeWidget;
|
||||
class BrightnessWidget;
|
||||
class QuickSettingItem;
|
||||
class DockPopupWindow;
|
||||
@ -70,6 +68,7 @@ private Q_SLOTS:
|
||||
void onPluginRemove(PluginsItemInterface * itemInter);
|
||||
void onItemDetailClick(PluginsItemInterface *pluginInter);
|
||||
void onResizeView();
|
||||
void onRequestAppletShow(PluginsItemInterface * itemInter, const QString &itemKey);
|
||||
|
||||
private:
|
||||
// 加载UI
|
||||
@ -84,6 +83,8 @@ private:
|
||||
void showWidget(QWidget *widget, const QString &title);
|
||||
// 获取拖动图标的热点
|
||||
QPoint hotSpot(const QPixmap &pixmap);
|
||||
// 判断是否支持显示在面板上
|
||||
bool isApplet(PluginsItemInterface * itemInter) const;
|
||||
|
||||
private:
|
||||
static DockPopupWindow *m_popWindow;
|
||||
@ -96,12 +97,9 @@ private:
|
||||
QVBoxLayout *m_mainlayout;
|
||||
QuickSettingController *m_pluginLoader;
|
||||
MediaWidget *m_playerWidget;
|
||||
VolumeModel *m_volumeModel;
|
||||
BrightnessModel *m_brightnessModel;
|
||||
VolumeWidget *m_volumnWidget;
|
||||
BrightnessWidget *m_brihtnessWidget;
|
||||
|
||||
VolumeDevicesWidget *m_volumeSettingWidget;
|
||||
DisplaySettingWidget *m_displaySettingWidget;
|
||||
PluginChildPage *m_childPage;
|
||||
QuickDragInfo *m_dragInfo;
|
||||
|
@ -27,6 +27,7 @@ DWIDGET_USE_NAMESPACE
|
||||
|
||||
static const int itemCheckRole = Dtk::UserRole + 1;
|
||||
static const int itemDataRole = Dtk::UserRole + 2;
|
||||
static const int itemFlagRole = Dtk::UserRole + 3;
|
||||
|
||||
class SettingDelegate : public DStyledItemDelegate
|
||||
{
|
Loading…
x
Reference in New Issue
Block a user