diff --git a/plugins/bluetooth/bluetoothmainwidget.cpp b/plugins/bluetooth/bluetoothmainwidget.cpp new file mode 100644 index 000000000..ab8649af2 --- /dev/null +++ b/plugins/bluetooth/bluetoothmainwidget.cpp @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd. + * + * Author: donghualin + * + * Maintainer: donghualin + * + * 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 . + */ +#include "bluetoothmainwidget.h" +#include "bluetoothitem.h" +#include "adaptersmanager.h" +#include "adapter.h" + +#include +#include + +#include +#include +#include +#include + +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)->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 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(); +} diff --git a/plugins/bluetooth/bluetoothmainwidget.h b/plugins/bluetooth/bluetoothmainwidget.h new file mode 100644 index 000000000..083fcc275 --- /dev/null +++ b/plugins/bluetooth/bluetoothmainwidget.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd. + * + * Author: donghualin + * + * Maintainer: donghualin + * + * 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 . + */ +#ifndef BLUETOOTHMAINWIDGET_H +#define BLUETOOTHMAINWIDGET_H + +#include + +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 diff --git a/plugins/bluetooth/bluetoothplugin.cpp b/plugins/bluetooth/bluetoothplugin.cpp index d41225505..e64b25b76 100644 --- a/plugins/bluetooth/bluetoothplugin.cpp +++ b/plugins/bluetooth/bluetoothplugin.cpp @@ -22,6 +22,7 @@ #include "bluetoothplugin.h" #include "adaptersmanager.h" +#include "bluetoothmainwidget.h" #include @@ -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"); diff --git a/plugins/bluetooth/bluetoothplugin.h b/plugins/bluetooth/bluetoothplugin.h index 83f907040..7190e538f 100644 --- a/plugins/bluetooth/bluetoothplugin.h +++ b/plugins/bluetooth/bluetoothplugin.h @@ -28,6 +28,8 @@ #include +class BluetoothMainWidget; + class AdaptersManager; class BluetoothPlugin : public QObject, PluginsItemInterface @@ -65,6 +67,7 @@ private: private: AdaptersManager *m_adapterManager; QScopedPointer m_bluetoothItem; + QScopedPointer m_bluetoothWidget; bool m_enableState = true; }; diff --git a/plugins/bluetooth/resources/arrow-right-dark.svg b/plugins/bluetooth/resources/arrow-right-dark.svg new file mode 100644 index 000000000..04d121e0b --- /dev/null +++ b/plugins/bluetooth/resources/arrow-right-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/plugins/bluetooth/resources/arrow-right.svg b/plugins/bluetooth/resources/arrow-right.svg new file mode 100644 index 000000000..25a187ff1 --- /dev/null +++ b/plugins/bluetooth/resources/arrow-right.svg @@ -0,0 +1,18 @@ + + + + arrow-right + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/bluetooth/resources/bluetooth.qrc b/plugins/bluetooth/resources/bluetooth.qrc index ece8036ac..0433881a9 100644 --- a/plugins/bluetooth/resources/bluetooth.qrc +++ b/plugins/bluetooth/resources/bluetooth.qrc @@ -6,6 +6,8 @@ bluetooth-disable-symbolic.svg bluetooth-waiting-symbolic-dark.svg bluetooth-waiting-symbolic.svg + arrow-right.svg + arrow-right-dark.svg list_select.png list_select@2x.png notify_close_press.png