fix: 修复快捷面板蓝牙状态显示错误的问题

快捷面板界面,点击蓝牙图标快速打开蓝牙设备或关闭蓝牙设备,同时根据需要显示不同状态的图标

Log: 修复快捷面板蓝牙状态显示错误的问题
Influence: 点击蓝牙图标,观察快捷面板蓝牙的打开或者关闭的状态
Bug: https://pms.uniontech.com/bug-view-171419.html
Change-Id: I8aeb557463932ffa0cef0fc26fdb29a4799285bd
This commit is contained in:
donghualin 2022-11-28 13:54:13 +08:00
parent ec092bb980
commit 4386f13cd9
7 changed files with 308 additions and 1 deletions

View File

@ -0,0 +1,201 @@
/*
* 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 "bluetoothmainwidget.h"
#include "bluetoothitem.h"
#include "adaptersmanager.h"
#include "adapter.h"
#include <DGuiApplicationHelper>
#include <DFontSizeManager>
#include <QLabel>
#include <QHBoxLayout>
#include <QPainter>
#include <QPainterPath>
DGUI_USE_NAMESPACE
DWIDGET_USE_NAMESPACE
BluetoothMainWidget::BluetoothMainWidget(AdaptersManager *adapterManager, QWidget *parent)
: QWidget(parent)
, m_adapterManager(adapterManager)
, m_iconWidget(new QWidget(this))
, m_nameLabel(new QLabel(this))
, m_stateLabel(new QLabel(this))
, m_expandLabel(new QLabel(this))
{
initUi();
initConnection();
}
BluetoothMainWidget::~BluetoothMainWidget()
{
}
bool BluetoothMainWidget::eventFilter(QObject *watcher, QEvent *event)
{
if (watcher == m_iconWidget) {
switch (event->type()) {
case QEvent::Paint: {
QPainter painter(m_iconWidget);
// 在区域最中间绘制
QRect iconRect = m_iconWidget->rect();
int size = qMin(iconRect.height(), iconRect.width());
QPoint ptCenter(iconRect.center());
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
// 填充原型路径
QPainterPath path;
path.addEllipse(ptCenter, size / 2 - 1, size / 2 - 1);
// 设置黑色背景色
QColor backColor(Qt::black);
backColor.setAlphaF(0.1);
painter.setBrush(backColor);
painter.fillPath(path, backColor);
// 添加图标
bool blueStatus = isOpen();
QPixmap pixmap(bluetoothIcon(blueStatus));
if (blueStatus) {
QPainter pa(&pixmap);
pa.setCompositionMode(QPainter::CompositionMode_SourceIn);
pa.fillRect(pixmap.rect(), qApp->palette().highlight());
}
painter.drawPixmap(QPoint(ptCenter.x() - pixmap.size().width() / 2, ptCenter.y() - pixmap.size().height() / 2), pixmap);
return true;
}
case QEvent::MouseButtonRelease: {
bool status = !(isOpen());
for (const Adapter *adapter : m_adapterManager->adapters())
const_cast<Adapter *>(adapter)->setPowered(status);
return true;
}
default:
break;
}
}
if (watcher == m_expandLabel && event->type() == QEvent::MouseButtonRelease) {
Q_EMIT requestExpand();
return true;
}
if (watcher == m_nameLabel && event->type() == QEvent::Resize) {
m_nameLabel->setText(QFontMetrics(m_nameLabel->font()).elidedText(tr("Bluetooth"), Qt::TextElideMode::ElideRight, m_nameLabel->width()));
}
return QWidget::eventFilter(watcher, event);
}
void BluetoothMainWidget::initUi()
{
QHBoxLayout *mainLayout = new QHBoxLayout(this);
// 添加左侧的图标
m_iconWidget->setFixedWidth(36);
// 添加中间的文本
QWidget *textWidget = new QWidget(this);
QVBoxLayout *textLayout = new QVBoxLayout(textWidget);
textLayout->setContentsMargins(0, 10, 0, 10);
textLayout->setSpacing(0);
QFont nameFont = DFontSizeManager::instance()->t6();
nameFont.setBold(true);
QPalette pe;
pe.setColor(QPalette::WindowText, Qt::black);
m_nameLabel->setParent(textWidget);
m_nameLabel->setPalette(pe);
m_nameLabel->setFont(nameFont);
m_stateLabel->setParent(textWidget);
m_stateLabel->setFont(DFontSizeManager::instance()->t10());
textLayout->addWidget(m_nameLabel);
textLayout->addWidget(m_stateLabel);
// 添加右侧的展开按钮
QWidget *expandWidget = new QWidget(this);
QVBoxLayout *expandLayout = new QVBoxLayout(expandWidget);
expandLayout->setContentsMargins(0, 0, 0, 0);
expandLayout->setSpacing(0);
expandLayout->addWidget(m_expandLabel);
// 设置图标和文本
m_nameLabel->setText(tr("Bluetooth"));
updateExpandIcon();
// 将所有的窗体都添加到主布局中
mainLayout->setContentsMargins(10, 0, 10, 0);
mainLayout->setSpacing(0);
mainLayout->addWidget(m_iconWidget);
mainLayout->addSpacing(10);
mainLayout->addWidget(textWidget);
mainLayout->addStretch();
mainLayout->addWidget(expandWidget);
m_iconWidget->installEventFilter(this);
m_expandLabel->installEventFilter(this);
m_nameLabel->installEventFilter(this);
}
void BluetoothMainWidget::initConnection()
{
connect(m_adapterManager, &AdaptersManager::adapterIncreased, this, &BluetoothMainWidget::onAdapterChanged);
connect(m_adapterManager, &AdaptersManager::adapterDecreased, this, &BluetoothMainWidget::onAdapterChanged);
connect(m_adapterManager, &AdaptersManager::adapterIncreased, this, [ = ](Adapter *adapter) {
connect(adapter, &Adapter::poweredChanged, this, &BluetoothMainWidget::onAdapterChanged);
});
for (const Adapter *adapter : m_adapterManager->adapters())
connect(adapter, &Adapter::poweredChanged, this, &BluetoothMainWidget::onAdapterChanged);
onAdapterChanged();
}
void BluetoothMainWidget::updateExpandIcon()
{
QString expandIconFile = ":/arrow-right";
if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::ColorType::LightType)
expandIconFile += "-dark";
expandIconFile += ".svg";
m_expandLabel->setPixmap(expandIconFile);
}
bool BluetoothMainWidget::isOpen() const
{
QList<const Adapter *> adapters = m_adapterManager->adapters();
for (const Adapter *adapter : adapters) {
if (adapter->powered())
return true;
}
return false;
}
QString BluetoothMainWidget::bluetoothIcon(bool isOpen) const
{
if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::ColorType::LightType)
return isOpen ? ":/bluetooth-active-symbolic-dark.svg" : ":/bluetooth-disable-symbolic-dark.svg";
return isOpen ? ":/bluetooth-active-symbolic.svg" : ":/bluetooth-disable-symbolic.svg";
}
void BluetoothMainWidget::onAdapterChanged()
{
bool bluetoothIsOpen = isOpen();
m_stateLabel->setText(bluetoothIsOpen ? tr("open") : tr("close"));
m_iconWidget->update();
}

View File

@ -0,0 +1,64 @@
/*
* 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 BLUETOOTHMAINWIDGET_H
#define BLUETOOTHMAINWIDGET_H
#include <QWidget>
class AdaptersManager;
class QLabel;
class Adapter;
class BluetoothMainWidget : public QWidget
{
Q_OBJECT
public:
explicit BluetoothMainWidget(AdaptersManager *adapterManager, QWidget *parent = nullptr);
~BluetoothMainWidget();
Q_SIGNALS:
void requestExpand();
protected:
bool eventFilter(QObject *watcher, QEvent *event) override;
private:
void initUi();
void initConnection();
void updateExpandIcon();
bool isOpen() const;
QString bluetoothIcon(bool isOpen) const;
private Q_SLOTS:
void onAdapterChanged();
private:
AdaptersManager *m_adapterManager;
QWidget *m_iconWidget;
QLabel *m_nameLabel;
QLabel *m_stateLabel;
QLabel *m_expandLabel;
};
#endif // BLUETOOTHMAINWIDGET_H

View File

@ -22,6 +22,7 @@
#include "bluetoothplugin.h"
#include "adaptersmanager.h"
#include "bluetoothmainwidget.h"
#include <DGuiApplicationHelper>
@ -33,6 +34,7 @@ BluetoothPlugin::BluetoothPlugin(QObject *parent)
: QObject(parent)
, m_adapterManager(new AdaptersManager(this))
, m_bluetoothItem(nullptr)
, m_bluetoothWidget(nullptr)
{
}
@ -55,6 +57,8 @@ void BluetoothPlugin::init(PluginProxyInterface *proxyInter)
m_bluetoothItem.reset(new BluetoothItem(m_adapterManager));
m_bluetoothWidget.reset(new BluetoothMainWidget(m_adapterManager));
connect(m_bluetoothItem.data(), &BluetoothItem::justHasAdapter, [&] {
m_enableState = true;
refreshPluginItemsVisible();
@ -63,6 +67,9 @@ void BluetoothPlugin::init(PluginProxyInterface *proxyInter)
m_enableState = false;
refreshPluginItemsVisible();
});
connect(m_bluetoothWidget.data(), &BluetoothMainWidget::requestExpand, this, [ = ] {
m_proxyInter->requestSetAppletVisible(this, QUICK_ITEM_KEY, true);
});
m_enableState = m_bluetoothItem->hasAdapter();
@ -88,6 +95,9 @@ QWidget *BluetoothPlugin::itemWidget(const QString &itemKey)
return m_bluetoothItem.data();
}
if (itemKey == QUICK_ITEM_KEY)
return m_bluetoothWidget.data();
return nullptr;
}
@ -146,14 +156,20 @@ void BluetoothPlugin::pluginSettingsChanged()
refreshPluginItemsVisible();
}
QIcon BluetoothPlugin::icon(const DockPart &)
QIcon BluetoothPlugin::icon(const DockPart &dockPart)
{
if (dockPart == DockPart::QuickPanel)
return QIcon();
static QIcon icon(":/bluetooth-active-symbolic.svg");
return icon;
}
QIcon BluetoothPlugin::icon(const DockPart &dockPart, int themeType)
{
if (dockPart == DockPart::QuickPanel)
return QIcon();
if (themeType == DGuiApplicationHelper::ColorType::DarkType)
return QIcon(":/bluetooth-active-symbolic.svg");

View File

@ -28,6 +28,8 @@
#include <QScopedPointer>
class BluetoothMainWidget;
class AdaptersManager;
class BluetoothPlugin : public QObject, PluginsItemInterface
@ -65,6 +67,7 @@ private:
private:
AdaptersManager *m_adapterManager;
QScopedPointer<BluetoothItem> m_bluetoothItem;
QScopedPointer<BluetoothMainWidget> m_bluetoothWidget;
bool m_enableState = true;
};

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<polygon fill-rule="evenodd" points="6.5 10.693 5.793 11.4 .404 6.011 5.793 .622 6.5 1.329 1.818 6.011" transform="matrix(-1 0 0 1 14 3.978)"/>
</svg>

After

Width:  |  Height:  |  Size: 237 B

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 39.1 (31720) - http://www.bohemiancoding.com/sketch -->
<title>arrow-right</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="arrow-right">
<g id="Group" transform="translate(8.000000, 8.000000) scale(-1, -1) translate(-8.000000, -8.000000) ">
<g id="g34312">
<rect id="rect34314" x="0" y="0" width="16" height="16"></rect>
</g>
<path d="M10.4667554,2.9962 C10.3543925,3.00529746 10.2484001,3.05209509 10.1659754,3.129 L5.1659755,7.629 C5.06099923,7.7238107 5.00108933,7.85864653 5.00108933,8.0001 C5.00108933,8.14155347 5.06099923,8.2763893 5.1659755,8.3712 L10.1659754,12.8712 C10.2965671,13.0027661 10.4892264,13.0512925 10.6665597,12.9972857 C10.843893,12.9432788 10.9767985,12.7956017 11.0118864,12.6135778 C11.0469744,12.431554 10.9784866,12.2450551 10.8339354,12.129 L6.2460455,8.0001 L10.8339354,3.8712 C10.9960082,3.72944524 11.0491416,3.49985954 10.9658251,3.30131391 C10.8825085,3.10276828 10.6814521,2.97984935 10.4667554,2.9962 L10.4667554,2.9962 Z" id="polyline34316" fill="#FFFFFF"></path>
<path d="M10.4667554,2.9962 C10.3543925,3.00529746 10.2484001,3.05209509 10.1659754,3.129 L5.1659755,7.629 C5.06099923,7.7238107 5.00108933,7.85864653 5.00108933,8.0001 C5.00108933,8.14155347 5.06099923,8.2763893 5.1659755,8.3712 L10.1659754,12.8712 C10.2965671,13.0027661 10.4892264,13.0512925 10.6665597,12.9972857 C10.843893,12.9432788 10.9767985,12.7956017 11.0118864,12.6135778 C11.0469744,12.431554 10.9784866,12.2450551 10.8339354,12.129 L6.2460455,8.0001 L10.8339354,3.8712 C10.9960082,3.72944524 11.0491416,3.49985954 10.9658251,3.30131391 C10.8825085,3.10276828 10.6814521,2.97984935 10.4667554,2.9962 L10.4667554,2.9962 Z" id="polyline34316-copy" fill="#FFFFFF"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -6,6 +6,8 @@
<file>bluetooth-disable-symbolic.svg</file>
<file>bluetooth-waiting-symbolic-dark.svg</file>
<file>bluetooth-waiting-symbolic.svg</file>
<file>arrow-right.svg</file>
<file>arrow-right-dark.svg</file>
<file>list_select.png</file>
<file>list_select@2x.png</file>
<file>notify_close_press.png</file>