mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-03 00:15:21 +00:00
fix: dock代码中移除音乐插件
从dock代码中移除音乐插件,适配不同插件的显示 Log: Influence: 打开音乐播放器,任务栏快捷面板中显示音乐播放面板 Task: https://pms.uniontech.com/task-view-220489.html Change-Id: Ib52383990489336bb6213b79963b151d4e1a7a14
This commit is contained in:
parent
6d14fd1be7
commit
f11366a27d
@ -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());
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
@ -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();
|
||||
}
|
@ -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
|
@ -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;
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
|
@ -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")
|
||||
|
@ -1,3 +1,4 @@
|
||||
{
|
||||
"api": "2.0.0"
|
||||
"api": "2.0.0",
|
||||
"order": 2
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
{
|
||||
"api": "2.0.0",
|
||||
"order": 1,
|
||||
"depends-daemon-dbus-service": "org.deepin.daemon.Audio1"
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user