fix: dock代码中移除音乐插件

从dock代码中移除音乐插件,适配不同插件的显示

Log:
Influence: 打开音乐播放器,任务栏快捷面板中显示音乐播放面板
Task: https://pms.uniontech.com/task-view-220489.html
Change-Id: Ib52383990489336bb6213b79963b151d4e1a7a14
This commit is contained in:
donghualin 2022-11-30 12:21:19 +08:00
parent 6d14fd1be7
commit f11366a27d
17 changed files with 103 additions and 723 deletions

View File

@ -24,6 +24,7 @@
FullQuickItem::FullQuickItem(PluginsItemInterface *const pluginInter, QWidget *parent)
: QuickSettingItem(pluginInter, parent)
, m_centerWidget(pluginInter->itemWidget(QUICK_ITEM_KEY))
, m_centerParentWidget(nullptr)
, m_effectWidget(new DBlurEffectWidget(this))
{
initUi();
@ -42,6 +43,12 @@ void FullQuickItem::updateShow()
m_centerWidget->update();
}
void FullQuickItem::detachPlugin()
{
if (m_centerWidget)
m_centerWidget->setParent(m_centerParentWidget);
}
QuickSettingItem::QuickSettingType FullQuickItem::type() const
{
return QuickSettingItem::QuickSettingType::Full;
@ -65,6 +72,9 @@ void FullQuickItem::initUi()
if (!m_centerWidget)
return;
m_centerWidget->setVisible(true);
m_centerParentWidget = m_centerWidget->parentWidget();
QHBoxLayout *layout = new QHBoxLayout(m_effectWidget);
layout->setContentsMargins(0, 0, 0, 0);
layout->setAlignment(Qt::AlignHCenter);
@ -79,6 +89,9 @@ void FullQuickItem::initUi()
void FullQuickItem::resizeSelf()
{
if (!m_centerWidget)
return;
m_effectWidget->setFixedHeight(m_centerWidget->height());
setFixedHeight(m_centerWidget->height());
}

View File

@ -31,6 +31,7 @@ public:
FullQuickItem(PluginsItemInterface *const pluginInter, QWidget *parent = nullptr);
~FullQuickItem() override;
void updateShow() override;
void detachPlugin() override;
QuickSettingType type() const override;
@ -43,6 +44,7 @@ private:
private:
QWidget *m_centerWidget;
QWidget *m_centerParentWidget;
DBlurEffectWidget *m_effectWidget;
};

View File

@ -36,6 +36,7 @@ MultiQuickItem::MultiQuickItem(PluginsItemInterface *const pluginInter, QWidget
, m_iconWidget(nullptr)
, m_nameLabel(nullptr)
, m_stateLabel(nullptr)
, m_itemWidgetParent(nullptr)
{
initUi();
}
@ -62,6 +63,13 @@ void MultiQuickItem::updateShow()
}
}
void MultiQuickItem::detachPlugin()
{
QWidget *itemWidget = pluginItem()->itemWidget(QUICK_ITEM_KEY);
if (itemWidget && itemWidget->parentWidget() == this)
itemWidget->setParent(m_itemWidgetParent);
}
QuickSettingItem::QuickSettingType MultiQuickItem::type() const
{
return QuickSettingItem::QuickSettingType::Multi;
@ -107,8 +115,10 @@ void MultiQuickItem::initUi()
{
QWidget *itemWidget = pluginItem()->itemWidget(QUICK_ITEM_KEY);
if (pluginItem()->icon(DockPart::QuickPanel).isNull() && itemWidget) {
m_itemWidgetParent = itemWidget->parentWidget();
// 如果插件没有返回图标的显示则获取插件的itemWidget
QHBoxLayout *mainLayout = new QHBoxLayout(this);
itemWidget->setVisible(true);
itemWidget->setParent(this);
mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->addWidget(itemWidget);

View File

@ -24,6 +24,7 @@
#include <quicksettingitem.h>
class QuickIconWidget;
class QWidget;
class MultiQuickItem : public QuickSettingItem
{
@ -33,6 +34,7 @@ public:
MultiQuickItem(PluginsItemInterface *const pluginInter, QWidget *parent = nullptr);
~MultiQuickItem() override;
void updateShow() override;
void detachPlugin() override;
QuickSettingType type() const override;
@ -47,6 +49,7 @@ private:
QuickIconWidget *m_iconWidget;
QLabel *m_nameLabel;
QLabel *m_stateLabel;
QWidget *m_itemWidgetParent;
};
/**

View File

@ -29,15 +29,13 @@
SingleQuickItem::SingleQuickItem(PluginsItemInterface *const pluginInter, QWidget *parent)
: QuickSettingItem(pluginInter, parent)
, m_itemParentWidget(nullptr)
{
initUi();
}
SingleQuickItem::~SingleQuickItem()
{
QWidget *itemWidget = pluginItem()->itemWidget(QUICK_ITEM_KEY);
if (itemWidget)
itemWidget->setParent(nullptr);
}
QuickSettingItem::QuickSettingType SingleQuickItem::type() const
@ -80,10 +78,12 @@ QWidget *SingleQuickItem::iconWidget(QWidget *parent)
// 如果图标为空则将获取itemWidget作为它的显示
QWidget *itemWidget = pluginItem()->itemWidget(QUICK_ITEM_KEY);
if (itemWidget) {
m_itemParentWidget = itemWidget->parentWidget();
QHBoxLayout *layout = new QHBoxLayout(widget);
layout->setContentsMargins(0, 0, 0 ,0);
itemWidget->setParent(widget);
layout->addWidget(itemWidget);
itemWidget->setVisible(true);
childIsEmpty = false;
}
}
@ -189,3 +189,10 @@ void SingleQuickItem::updateShow()
itemWidget->update();
}
}
void SingleQuickItem::detachPlugin()
{
QWidget *itemWidget = pluginItem()->itemWidget(QUICK_ITEM_KEY);
if (itemWidget && !property("paint").toBool())
itemWidget->setParent(m_itemParentWidget);
}

View File

@ -33,6 +33,7 @@ public:
QuickSettingType type() const override;
void updateShow() override;
void detachPlugin() override;
protected:
void mouseReleaseEvent(QMouseEvent *event) override;
@ -44,6 +45,9 @@ private:
QPixmap pixmap() const;
QLabel *findChildLabel(QWidget *parent, const QString &childObjectName) const;
void updatePluginName(QLabel *textLabel);
private:
QWidget *m_itemParentWidget;
};
#endif // SINGLEQUICKITEM_H

View File

@ -44,6 +44,7 @@ public:
ItemType itemType() const override;
virtual const QPixmap dragPixmap();
virtual void updateShow() {}
virtual void detachPlugin() {}
const QString itemKey() const;
virtual QuickSettingType type() const = 0;

View File

@ -1,259 +0,0 @@
#include "mediaplayermodel.h"
#include <QDBusConnectionInterface>
#include <QDBusInterface>
#include <QDBusPendingCall>
#include <QDBusReply>
#include <QDebug>
#include <QJsonDocument>
#include <QJsonObject>
#include <QMetaMethod>
#include <QDBusAbstractInterface>
MediaPlayerModel::MediaPlayerModel(QObject *parent)
: QObject(parent)
, m_isActived(false)
, m_mediaInter(nullptr)
{
initMediaPlayer();
}
MediaPlayerModel::~MediaPlayerModel()
{
}
MediaPlayerModel *MediaPlayerModel::instance()
{
static MediaPlayerModel instance;
return &instance;
}
bool MediaPlayerModel::isActived()
{
return m_isActived;
}
bool MediaPlayerModel::canGoNext()
{
return m_mediaInter ? m_mediaInter->canGoNext() : false;
}
bool MediaPlayerModel::canGoPrevious()
{
return m_mediaInter ? m_mediaInter->canGoPrevious() : false;
}
bool MediaPlayerModel::canPause()
{
return m_mediaInter ? m_mediaInter->canPause() : false;
}
MediaPlayerModel::PlayStatus MediaPlayerModel::status()
{
if (!m_isActived || !m_mediaInter)
return PlayStatus::Stop;
return convertStatus(m_mediaInter->playbackStatus());
}
const QString MediaPlayerModel::name()
{
if (m_mediaInter) {
Dict data = m_mediaInter->metadata();
return data["xesam:title"].toString();
}
return QString();
}
const QString MediaPlayerModel::iconUrl()
{
if (m_mediaInter) {
Dict data = m_mediaInter->metadata();
return data["mpris:artUrl"].toString();
}
return QString();
}
const QString MediaPlayerModel::album()
{
if (m_mediaInter) {
Dict data = m_mediaInter->metadata();
return data["xesam:album"].toString();
}
return QString();
}
const QString MediaPlayerModel::artist()
{
if (m_mediaInter) {
Dict data = m_mediaInter->metadata();
return data["xesam:artist"].toString();
}
return QString();
}
void MediaPlayerModel::setStatus(const MediaPlayerModel::PlayStatus &stat)
{
if (!m_mediaInter)
return;
switch (stat) {
case MediaPlayerModel::PlayStatus::Play: {
m_mediaInter->Play();
break;
}
case MediaPlayerModel::PlayStatus::Stop: {
m_mediaInter->Stop();
break;
}
case MediaPlayerModel::PlayStatus::Pause: {
m_mediaInter->Pause();
break;
}
default: break;
}
}
void MediaPlayerModel::playNext()
{
if (m_mediaInter)
m_mediaInter->Next();
}
void MediaPlayerModel::initMediaPlayer()
{
QDBusInterface dbusInter("org.freedesktop.DBus", "/", "org.freedesktop.DBus", QDBusConnection::sessionBus(), this);
QDBusPendingCall call = dbusInter.asyncCall("ListNames");
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this);
connect(watcher, &QDBusPendingCallWatcher::finished, [ = ] {
m_serviceName.clear();
if (call.isError())
return;
QDBusReply<QStringList> reply = call.reply();
const QStringList &serviceList = reply.value();
for (const QString &serv : serviceList) {
if (!serv.startsWith("org.mpris.MediaPlayer2"))
continue;
QDBusInterface serviceInterface(serv, "/org/mpris/MediaPlayer2",
"org.mpris.MediaPlayer2.Player", QDBusConnection::sessionBus(), this);
// 如果开启了谷歌浏览器的后台服务(org.mpris.MediaPlayer2.chromium.instance17352)
// 也符合名称要求,但是它不是音乐服务,此时需要判断是否存在这个属性
QVariant v = serviceInterface.property("CanPlay");
if (!v.isValid() || !v.value<bool>())
continue;
m_serviceName = serv;
break;
}
if (!m_serviceName.isEmpty()) {
m_isActived = true;
m_mediaInter = new MediaPlayerInterface(m_serviceName, "/org/mpris/MediaPlayer2", QDBusConnection::sessionBus(), this);
connect(m_mediaInter, &MediaPlayerInterface::PlaybackStatusChanged, this, [ this ] {
Q_EMIT statusChanged(convertStatus(m_mediaInter->playbackStatus()));
});
connect(m_mediaInter, &MediaPlayerInterface::MetadataChanged, this, &MediaPlayerModel::metadataChanged);
Dict v = m_mediaInter->metadata();
m_name = v.value("xesam:title").toString();
m_icon = v.value("mpris:artUrl").toString();
m_album = v.value("xesam:album").toString();
m_artist = v.value("xesam:artist").toString();
Q_EMIT startStop(true);
return;
}
QDBusConnectionInterface *dbusInterface = QDBusConnection::sessionBus().interface();
connect(dbusInterface, &QDBusConnectionInterface::serviceOwnerChanged, this,
[ = ](const QString &name, const QString &, const QString &newOwner) {
if (name.startsWith("org.mpris.MediaPlayer2")) {
// 启动了音乐播放
m_isActived = !newOwner.isEmpty();
if (m_isActived) {
m_serviceName = name;
m_mediaInter = new MediaPlayerInterface(m_serviceName, "/org/mpris/MediaPlayer2", QDBusConnection::sessionBus(), this);
connect(m_mediaInter, &MediaPlayerInterface::PlaybackStatusChanged, this, [ this ] {
Q_EMIT statusChanged(convertStatus(m_mediaInter->playbackStatus()));
});
connect(m_mediaInter, &MediaPlayerInterface::MetadataChanged, this, &MediaPlayerModel::metadataChanged);
Dict v = m_mediaInter->metadata();
m_name = v.value("xesam:title").toString();
m_icon = v.value("mpris:artUrl").toString();
m_album = v.value("xesam:album").toString();
m_artist = v.value("xesam:artist").toString();
} else {
if (!m_serviceName.isEmpty()) {
delete m_mediaInter;
m_mediaInter = nullptr;
}
m_serviceName.clear();
}
Q_EMIT startStop(m_isActived);
}
});
connect(dbusInterface, &QDBusConnectionInterface::serviceUnregistered, this,
[ = ](const QString &service) {
if (service.startsWith("org.mpris.MediaPlayer2")) {
// 启动了音乐播放
m_serviceName.clear();
m_isActived = false;
Q_EMIT startStop(m_isActived);
}
});
});
connect(watcher, &QDBusPendingCallWatcher::finished, watcher, &QDBusPendingCallWatcher::deleteLater);
}
MediaPlayerModel::PlayStatus MediaPlayerModel::convertStatus(const QString &stat)
{
if (stat == "Paused")
return PlayStatus::Pause;
if (stat == "Playing")
return PlayStatus::Play;
if (stat == "Stopped")
return PlayStatus::Stop;
return PlayStatus::Unknow;
}
MediaPlayerInterface::MediaPlayerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
: QDBusAbstractInterface(service, path, "org.mpris.MediaPlayer2.Player", connection, parent)
{
QDBusConnection::sessionBus().connect(this->service(), this->path(), "org.freedesktop.DBus.Properties", "PropertiesChanged","sa{sv}as", this, SLOT(onPropertyChanged(QDBusMessage)));
}
MediaPlayerInterface::~MediaPlayerInterface()
{
QDBusConnection::sessionBus().disconnect(this->service(), this->path(), "org.freedesktop.DBus.Properties", "PropertiesChanged","sa{sv}as", this, SLOT(__propertyChanged__(QDBusMessage)));
}
void MediaPlayerInterface::onPropertyChanged(const QDBusMessage& msg)
{
QList<QVariant> arguments = msg.arguments();
if (3 != arguments.count())
return;
QString interfaceName = msg.arguments().at(0).toString();
if (interfaceName !="org.mpris.MediaPlayer2.Player")
return;
QVariantMap changedProps = qdbus_cast<QVariantMap>(arguments.at(1).value<QDBusArgument>());
QStringList keys = changedProps.keys();
foreach(const QString &prop, keys) {
const QMetaObject* self = metaObject();
for (int i=self->propertyOffset(); i < self->propertyCount(); ++i) {
QMetaProperty p = self->property(i);
if (p.name() == prop) {
Q_EMIT p.notifySignal().invoke(this);
}
}
}
}

View File

@ -1,126 +0,0 @@
#ifndef MEDIAPLAYERMODEL_H
#define MEDIAPLAYERMODEL_H
#include <QObject>
#include <QDBusAbstractInterface>
#include <QDBusPendingReply>
typedef QMap<QString, QVariant> Dict;
Q_DECLARE_METATYPE(Dict)
class QDBusMessage;
class QDBusConnection;
class MediaPlayerInterface;
class MediaPlayerModel : public QObject
{
Q_OBJECT
public:
enum PlayStatus {
Unknow = 0,
Play,
Pause,
Stop
};
public:
static MediaPlayerModel *instance();
bool isActived();
bool canGoNext();
bool canGoPrevious();
bool canPause();
PlayStatus status();
const QString name();
const QString iconUrl();
const QString album();
const QString artist();
void setStatus(const PlayStatus &stat);
void playNext();
Q_SIGNALS:
void startStop(bool);
void statusChanged(const PlayStatus &);
void metadataChanged();
protected:
explicit MediaPlayerModel(QObject *parent = nullptr);
~MediaPlayerModel();
private:
void initMediaPlayer();
PlayStatus convertStatus(const QString &stat);
private:
bool m_isActived;
QString m_serviceName;
QString m_name;
QString m_icon;
QString m_album;
QString m_artist;
MediaPlayerInterface *m_mediaInter;
};
class MediaPlayerInterface : public QDBusAbstractInterface
{
Q_OBJECT
Q_SIGNALS:
void MetadataChanged();
void CanGoNextChanged();
void CanGoPreviousChanged();
void CanPauseChanged();
void PlaybackStatusChanged();
public:
MediaPlayerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr);
~MediaPlayerInterface();
public:
inline QDBusPendingReply<> Play() {
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QStringLiteral("Play"), argumentList);
}
inline QDBusPendingReply<> Stop() {
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QStringLiteral("Stop"), argumentList);
}
inline QDBusPendingReply<> Pause() {
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QStringLiteral("Pause"), argumentList);
}
inline QDBusPendingReply<> Next() {
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QStringLiteral("Next"), argumentList);
}
Q_PROPERTY(Dict Metadata READ metadata NOTIFY MetadataChanged)
inline Dict metadata() const
{ return qvariant_cast<Dict>(property("Metadata")); }
Q_PROPERTY(bool CanGoNext READ canGoNext NOTIFY CanGoNextChanged)
inline bool canGoNext() const
{ return qvariant_cast< bool >(property("CanGoNext")); }
Q_PROPERTY(bool CanGoPrevious READ canGoPrevious NOTIFY CanGoPreviousChanged)
inline bool canGoPrevious() const
{ return qvariant_cast< bool >(property("CanGoPrevious")); }
Q_PROPERTY(bool CanPause READ canPause NOTIFY CanPauseChanged)
inline bool canPause() const
{ return qvariant_cast< bool >(property("CanPause")); }
Q_PROPERTY(QString PlaybackStatus READ playbackStatus NOTIFY PlaybackStatusChanged)
inline QString playbackStatus() const
{ return qvariant_cast< QString >(property("PlaybackStatus")); }
private Q_SLOTS:
void onPropertyChanged(const QDBusMessage& msg);
};
#endif // MEDIAPLAYERLISTENER_H

View File

@ -1,213 +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 "mediawidget.h"
#include <DFontSizeManager>
#include <QLabel>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QEvent>
#include <QPainter>
#include <QDebug>
#include <QPainterPath>
DWIDGET_USE_NAMESPACE
MediaWidget::MediaWidget(QWidget *parent)
: DBlurEffectWidget(parent)
, m_musicIcon(new QLabel(this))
, m_musicName(new QLabel(this))
, m_musicSinger(new QLabel(this))
, m_pausePlayButton(new MusicButton(this))
, m_nextButton(new MusicButton(this))
{
initUi();
initConnection();
}
MediaWidget::~MediaWidget()
{
}
void MediaWidget::showEvent(QShowEvent *event)
{
DBlurEffectWidget::showEvent(event);
Q_EMIT visibleChanged(true);
}
void MediaWidget::hideEvent(QHideEvent *event)
{
DBlurEffectWidget::hideEvent(event);
Q_EMIT visibleChanged(false);
}
void MediaWidget::statusChanged(const MediaPlayerModel::PlayStatus &newStatus)
{
switch (newStatus) {
case MediaPlayerModel::PlayStatus::Play: {
m_pausePlayButton->setButtonType(MusicButton::ButtonType::Pause);
break;
}
case MediaPlayerModel::PlayStatus::Stop:
case MediaPlayerModel::PlayStatus::Pause: {
m_pausePlayButton->setButtonType(MusicButton::ButtonType::Playing);
break;
}
default: break;
}
}
void MediaWidget::onPlayClicked()
{
// 设置当前的播放状态
MediaPlayerModel *player = MediaPlayerModel::instance();
if (player->status() == MediaPlayerModel::PlayStatus::Play)
player->setStatus(MediaPlayerModel::PlayStatus::Pause);
else
player->setStatus(MediaPlayerModel::PlayStatus::Play);
}
void MediaWidget::onNext()
{
// 播放下一曲
MediaPlayerModel *player = MediaPlayerModel::instance();
player->playNext();
}
void MediaWidget::initUi()
{
m_pausePlayButton->setFixedWidth(20);
m_nextButton->setFixedWidth(20);
QHBoxLayout *mainLayout = new QHBoxLayout(this);
mainLayout->setContentsMargins(20, 0, 20, 0);
mainLayout->addWidget(m_musicIcon);
QWidget *infoWidget = new QWidget(this);
QVBoxLayout *infoLayout = new QVBoxLayout(infoWidget);
infoLayout->addWidget(m_musicName);
infoLayout->addWidget(m_musicSinger);
mainLayout->addWidget(infoWidget);
mainLayout->addWidget(m_pausePlayButton);
mainLayout->addSpacing(25);
mainLayout->addWidget(m_nextButton);
m_musicIcon->setFixedSize(32, 32);
m_musicName->setFont(DFontSizeManager::instance()->t8());
m_musicSinger->setFont(DFontSizeManager::instance()->t10());
setVisible(MediaPlayerModel::instance()->isActived());
}
void MediaWidget::initConnection()
{
MediaPlayerModel *mediaPlayer = MediaPlayerModel::instance();
connect(mediaPlayer, &MediaPlayerModel::startStop, this, [ this, mediaPlayer ](bool startOrStop) {
setVisible(startOrStop);
m_nextButton->setEnabled(mediaPlayer->canGoNext());
onUpdateMediaInfo();
statusChanged(mediaPlayer->status());
});
connect(mediaPlayer, &MediaPlayerModel::metadataChanged, this, &MediaWidget::onUpdateMediaInfo);
connect(mediaPlayer, &MediaPlayerModel::statusChanged, this, &MediaWidget::statusChanged);
connect(m_pausePlayButton, &MusicButton::clicked, this, &MediaWidget::onPlayClicked);
connect(m_nextButton, &MusicButton::clicked, this, &MediaWidget::onNext);
m_pausePlayButton->setButtonType(mediaPlayer->status() == MediaPlayerModel::PlayStatus::Play ?
MusicButton::ButtonType::Pause : MusicButton::ButtonType::Playing);
m_nextButton->setButtonType(MusicButton::ButtonType::Next);
}
void MediaWidget::onUpdateMediaInfo()
{
MediaPlayerModel *mediaPlayer = MediaPlayerModel::instance();
m_musicName->setText(mediaPlayer->name());
QString file = mediaPlayer->iconUrl();
if (file.startsWith("file:///"))
file.replace("file:///", "/");
m_musicIcon->setPixmap(QPixmap(file).scaled(m_musicIcon->size()));
m_musicSinger->setText(mediaPlayer->artist());
}
/**
* @brief
* @param parent
*/
MusicButton::MusicButton(QWidget *parent)
: QWidget(parent)
{
installEventFilter(this);
}
MusicButton::~MusicButton()
{
}
int MusicButton::getIconHeight() const
{
switch (m_buttonType) {
case ButtonType::Pause:
return 21;
case ButtonType::Next:
case ButtonType::Playing:
return 18;
}
return 18;
}
void MusicButton::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
int ctrlHeight = getIconHeight();
int width = this->width();
int height = this->height();
int startX = 2;
int startY = (height - ctrlHeight) / 2;
QColor color(0, 0, 0);
QPainter painter(this);
painter.save();
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(color);
painter.setBrush(color);
if (m_buttonType == ButtonType::Pause) {
painter.drawRect(QRect(startX, startY, 6, ctrlHeight));
painter.drawRect(QRect(width - 6 - 2, startY, 6, ctrlHeight));
} else {
QPainterPath trianglePath;
trianglePath.moveTo(startX, startY);
trianglePath.lineTo(width - 6, height / 2);
trianglePath.lineTo(startX, startY + ctrlHeight);
trianglePath.lineTo(startX, startY);
painter.drawPath(trianglePath);
if (m_buttonType == ButtonType::Next)
painter.drawRect(width - 6, startY, 2, ctrlHeight);
}
painter.restore();
}
void MusicButton::mouseReleaseEvent(QMouseEvent *event)
{
Q_UNUSED(event);
Q_EMIT clicked();
}

View File

@ -1,97 +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 MEDIAWIDGET_H
#define MEDIAWIDGET_H
#include "mediaplayermodel.h"
#include <DBlurEffectWidget>
class QLabel;
class MusicButton;
DWIDGET_USE_NAMESPACE
class MediaWidget : public DBlurEffectWidget
{
Q_OBJECT
public:
explicit MediaWidget(QWidget *parent = nullptr);
~MediaWidget() override;
Q_SIGNALS:
void visibleChanged(bool);
protected:
void showEvent(QShowEvent *event) override;
void hideEvent(QHideEvent *event) override;
private Q_SLOTS:
void statusChanged(const MediaPlayerModel::PlayStatus &newStatus);
void onPlayClicked();
void onNext();
void onUpdateMediaInfo();
private:
void initUi();
void initConnection();
private:
QLabel *m_musicIcon;
QLabel *m_musicName;
QLabel *m_musicSinger;
MusicButton *m_pausePlayButton;
MusicButton *m_nextButton;
};
// 音乐播放按钮
class MusicButton : public QWidget
{
Q_OBJECT
Q_SIGNALS:
void clicked();
public:
enum ButtonType { Playing = 0, Pause, Next };
public:
MusicButton(QWidget *parent = Q_NULLPTR);
~MusicButton() override;
inline void setButtonType(const ButtonType &bt) {
m_buttonType = bt;
update();
}
protected:
void paintEvent(QPaintEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
private:
int getIconHeight() const;
private:
ButtonType m_buttonType;
};
#endif // MEDIAWIDGER_H

View File

@ -23,6 +23,8 @@
#include "quicksettingcontroller.h"
#include "settingconfig.h"
#include <QWidget>
static QStringList fixedPluginNames { "network", "sound", "power" };
#define PLUGINNAMEKEY "Dock_Quick_Plugin_Name"
@ -166,6 +168,10 @@ void QuickPluginModel::initConnection()
if (plugAttr != QuickSettingController::PluginAttribute::Quick)
return;
QWidget *quickWidget = itemInter->itemWidget(QUICK_ITEM_KEY);
if (quickWidget && !quickWidget->parentWidget())
quickWidget->setVisible(false);
// 用来读取已经固定在下方的插件
if (!m_dockedPluginIndex.contains(itemInter->pluginName()))
return;

View File

@ -22,7 +22,6 @@
#include "quicksettingcontroller.h"
#include "pluginsiteminterface.h"
#include "quicksettingitem.h"
#include "mediawidget.h"
#include "dockpopupwindow.h"
#include "slidercontainer.h"
#include "pluginchildpage.h"
@ -71,7 +70,6 @@ QuickSettingContainer::QuickSettingContainer(QWidget *parent)
, m_componentWidget(new QWidget(m_mainWidget))
, m_mainlayout(new QVBoxLayout(m_mainWidget))
, m_pluginLoader(QuickSettingController::instance())
, m_playerWidget(new MediaWidget(m_componentWidget))
, m_childPage(new PluginChildPage(this))
, m_dragInfo(new struct QuickDragInfo)
, m_childShowPlugin(nullptr)
@ -208,6 +206,7 @@ void QuickSettingContainer::appendPlugin(PluginsItemInterface *itemInter, bool n
if (quickItem->type() == QuickSettingItem::QuickSettingType::Full) {
// 插件位置占据整行,例如声音、亮度和音乐等
m_componentWidget->layout()->addWidget(quickItem);
updateFullItemLayout();
} else if (needLayout) {
// 插件占据两行或者一行
updateItemLayout();
@ -226,6 +225,7 @@ void QuickSettingContainer::onPluginRemove(PluginsItemInterface *itemInter)
return;
QuickSettingItem *removeItem = *removeItemIter;
removeItem->detachPlugin();
if (removeItem->type() == QuickSettingItem::QuickSettingType::Full)
m_componentWidget->layout()->removeWidget(removeItem);
@ -238,6 +238,7 @@ void QuickSettingContainer::onPluginRemove(PluginsItemInterface *itemInter)
showPage(nullptr);
updateItemLayout();
updateFullItemLayout();
onResizeView();
}
@ -319,6 +320,7 @@ void QuickSettingContainer::updateItemLayout()
int usedColumn = (type == QuickSettingItem::QuickSettingType::Multi ? 2 : 1);
QList<QuickSettingItem *> quickPlugins = quickSettings[type];
for (QuickSettingItem *quickItem : quickPlugins) {
quickItem->setVisible(true);
m_pluginLayout->addWidget(quickItem, row, column, 1, usedColumn);
column += usedColumn;
if (column >= COLUMNCOUNT) {
@ -334,19 +336,48 @@ void QuickSettingContainer::updateItemLayout()
insertQuickSetting(QuickSettingItem::QuickSettingType::Single, row, column);
}
void QuickSettingContainer::updateFullItemLayout()
{
while (m_componentWidget->layout()->count() > 0)
m_componentWidget->layout()->takeAt(0);
QuickSettingController *quickController = QuickSettingController::instance();
QList<QuickSettingItem *> fullItems;
QMap<QuickSettingItem *, int> fullItemOrder;
for (QuickSettingItem *item : m_quickSettings) {
if (item->type() != QuickSettingItem::QuickSettingType::Full)
continue;
fullItems << item;
int order = -1;
QJsonObject metaData = quickController->metaData(item->pluginItem());
if (metaData.contains("order"))
order = metaData.value("order").toInt();
fullItemOrder[item] = order;
}
std::sort(fullItems.begin(), fullItems.end(), [ fullItemOrder ](QuickSettingItem *item1, QuickSettingItem *item2) {
int order1 = fullItemOrder.value(item1, -1);
int order2 = fullItemOrder.value(item2, -1);
if (order1 == order2)
return true;
if (order1 == -1)
return false;
if (order2 == -1)
return true;
return order1 < order2;
});
for (QuickSettingItem *item : fullItems) {
item->setVisible(true);
m_componentWidget->layout()->addWidget(item);
}
}
void QuickSettingContainer::initUi()
{
auto setWidgetStyle = [](DBlurEffectWidget *widget) {
widget->setMaskColor(QColor(239, 240, 245));
widget->setBlurRectXRadius(8);
widget->setBlurRectYRadius(8);
};
// 添加音乐播放插件
m_playerWidget->setFixedHeight(ITEMHEIGHT);
setWidgetStyle(m_playerWidget);
m_mainlayout->setSpacing(ITEMSPACE);
m_mainlayout->setContentsMargins(ITEMSPACE, ITEMSPACE, ITEMSPACE, ITEMSPACE);
@ -362,8 +393,7 @@ void QuickSettingContainer::initUi()
QVBoxLayout *ctrlLayout = new QVBoxLayout(m_componentWidget);
ctrlLayout->setContentsMargins(0, 0, 0, 0);
ctrlLayout->setSpacing(ITEMSPACE);
ctrlLayout->addWidget(m_playerWidget);
ctrlLayout->setDirection(QBoxLayout::BottomToTop);
m_mainlayout->addWidget(m_componentWidget);
// 加载所有的插件
@ -378,8 +408,10 @@ void QuickSettingContainer::initUi()
setAcceptDrops(true);
QMetaObject::invokeMethod(this, [ = ] {
if (plugins.size() > 0)
if (plugins.size() > 0) {
updateItemLayout();
updateFullItemLayout();
}
// 设置当前窗口的大小
onResizeView();
setFixedWidth(ITEMWIDTH * 4 + (ITEMSPACE * 5));
@ -397,7 +429,6 @@ void QuickSettingContainer::initConnection()
connect(m_pluginLoader, &QuickSettingController::pluginRemoved, this, &QuickSettingContainer::onPluginRemove);
connect(m_pluginLoader, &QuickSettingController::pluginUpdated, this, &QuickSettingContainer::onPluginUpdated);
connect(m_playerWidget, &MediaWidget::visibleChanged, this, &QuickSettingContainer::onResizeView);
connect(m_childPage, &PluginChildPage::back, this, [ this ] {
showPage(m_mainWidget);
});
@ -430,11 +461,6 @@ void QuickSettingContainer::onResizeView()
rowCount++;
m_pluginWidget->setFixedHeight(ITEMHEIGHT * rowCount + ITEMSPACE * (rowCount - 1));
if (m_playerWidget->isVisible()) {
fullItemHeight += m_playerWidget->height();
widgetCount++;
}
m_componentWidget->setFixedHeight(fullItemHeight + (widgetCount - 1) * ITEMSPACE);
setFixedHeight(ITEMSPACE * 3 + m_pluginWidget->height() + m_componentWidget->height());

View File

@ -32,7 +32,6 @@
class DockItem;
class QVBoxLayout;
class QuickSettingController;
class MediaWidget;
class BrightnessModel;
class BrightnessWidget;
class QuickSettingItem;
@ -76,6 +75,8 @@ private:
void initConnection();
// 调整控件位置
void updateItemLayout();
// 调整全列插件的位置
void updateFullItemLayout();
// 获取拖动图标的热点
QPoint hotSpot(const QPixmap &pixmap);
// 插入插件
@ -91,7 +92,6 @@ private:
QWidget *m_componentWidget;
QVBoxLayout *m_mainlayout;
QuickSettingController *m_pluginLoader;
MediaWidget *m_playerWidget;
PluginChildPage *m_childPage;
QuickDragInfo *m_dragInfo;
QList<QuickSettingItem *> m_quickSettings;

View File

@ -4,6 +4,7 @@ add_subdirectory("shutdown")
add_subdirectory("power")
add_subdirectory("sound")
add_subdirectory("display")
add_subdirectory("media")
#add_subdirectory("tray")
add_subdirectory("trash")
add_subdirectory("keyboard-layout")

View File

@ -1,3 +1,4 @@
{
"api": "2.0.0"
"api": "2.0.0",
"order": 2
}

View File

@ -1,4 +1,5 @@
{
"api": "2.0.0",
"order": 1,
"depends-daemon-dbus-service": "org.deepin.daemon.Audio1"
}