feat(plugin):add notifications plugin

This commit is contained in:
蔡瑞 2019-10-25 14:24:25 +08:00
parent 48661bd429
commit 8733c9bc25
11 changed files with 532 additions and 0 deletions

View File

@ -9,5 +9,6 @@ usr/lib/dde-dock/plugins/liboverlay-warning.so
usr/lib/dde-dock/plugins/system-trays
usr/lib/dde-dock/plugins/libmultitasking.so
usr/lib/dde-dock/plugins/libshow-desktop.so
usr/lib/dde-dock/plugins/libnotifications.so
usr/share
etc/dde-dock

View File

@ -12,3 +12,4 @@ add_subdirectory("onboard")
add_subdirectory("overlay-warning")
add_subdirectory("show-desktop")
add_subdirectory("multitasking")
add_subdirectory("notifications")

View File

@ -0,0 +1,32 @@
set(PLUGIN_NAME "notifications")
project(${PLUGIN_NAME})
# Sources files
file(GLOB_RECURSE SRCS "*.h" "*.cpp" "../../widgets/*.h" "../../widgets/*.cpp")
find_package(PkgConfig REQUIRED)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5Svg REQUIRED)
find_package(Qt5DBus REQUIRED)
find_package(DtkWidget REQUIRED)
if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
add_definitions("-DDISABLE_POWER_OPTIONS")
endif()
add_definitions("${QT_DEFINITIONS} -DQT_PLUGIN")
add_library(${PLUGIN_NAME} SHARED ${SRCS} resources.qrc)
set_target_properties(${PLUGIN_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ../)
target_include_directories(${PLUGIN_NAME} PUBLIC ${DtkWidget_INCLUDE_DIRS}
${Qt5DBus_INCLUDE_DIRS}
../../interfaces)
target_link_libraries(${PLUGIN_NAME} PRIVATE
${DtkWidget_LIBRARIES}
${Qt5Widgets_LIBRARIES}
${Qt5Svg_LIBRARIES}
${Qt5DBus_LIBRARIES}
)
install(TARGETS ${PLUGIN_NAME} LIBRARY DESTINATION lib/dde-dock/plugins)

View File

@ -0,0 +1,3 @@
{
"api": "1.1.1"
}

View File

@ -0,0 +1,183 @@
/*
* Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
*
* Author: sbw <sbw@sbw.so>
*
* Maintainer: sbw <sbw@sbw.so>
*
* 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 "notificationsplugin.h"
#include <QDBusConnectionInterface>
#include <QIcon>
#include <QSettings>
#define PLUGIN_STATE_KEY "enable"
NotificationsPlugin::NotificationsPlugin(QObject *parent)
: QObject(parent)
, m_pluginLoaded(false)
, m_tipsLabel(new TipsWidget)
{
m_tipsLabel->setVisible(false);
getNotifyInterface();
}
QDBusInterface *NotificationsPlugin::getNotifyInterface()
{
if (!m_interface && QDBusConnection::sessionBus().interface()->isServiceRegistered("com.deepin.dde.Notification"))
m_interface = new QDBusInterface("com.deepin.dde.Notification", "/com/deepin/dde/Notification", "com.deepin.dde.Notification");
return m_interface;
}
const QString NotificationsPlugin::pluginName() const
{
return "notifications";
}
const QString NotificationsPlugin::pluginDisplayName() const
{
return tr("Notifications");
}
QWidget *NotificationsPlugin::itemWidget(const QString &itemKey)
{
Q_UNUSED(itemKey);
return m_itemWidget;
}
QWidget *NotificationsPlugin::itemTipsWidget(const QString &itemKey)
{
Q_UNUSED(itemKey);
if (!getNotifyInterface())
return nullptr;
QDBusMessage msg = m_interface->call("recordCount");
uint recordCount = msg.arguments()[0].toUInt();
if (recordCount)
m_tipsLabel->setText(QString(tr("%1 Notifications")).arg(recordCount));
else
m_tipsLabel->setText(tr("Notifications"));
return m_tipsLabel;
}
void NotificationsPlugin::init(PluginProxyInterface *proxyInter)
{
m_proxyInter = proxyInter;
if (!pluginIsDisable()) {
loadPlugin();
}
}
void NotificationsPlugin::pluginStateSwitched()
{
m_proxyInter->saveValue(this, PLUGIN_STATE_KEY, !m_proxyInter->getValue(this, PLUGIN_STATE_KEY, true).toBool());
refreshPluginItemsVisible();
}
bool NotificationsPlugin::pluginIsDisable()
{
return !m_proxyInter->getValue(this, PLUGIN_STATE_KEY, true).toBool();
}
const QString NotificationsPlugin::itemCommand(const QString &itemKey)
{
Q_UNUSED(itemKey);
if (getNotifyInterface())
m_interface->call("Toggle");
return "";
}
void NotificationsPlugin::displayModeChanged(const Dock::DisplayMode displayMode)
{
Q_UNUSED(displayMode);
if (!pluginIsDisable()) {
m_itemWidget->update();
}
}
int NotificationsPlugin::itemSortKey(const QString &itemKey)
{
Dock::DisplayMode mode = displayMode();
const QString key = QString("pos_%1_%2").arg(itemKey).arg(mode);
if (mode == Dock::DisplayMode::Fashion) {
return m_proxyInter->getValue(this, key, 2).toInt();
} else {
return m_proxyInter->getValue(this, key, 5).toInt();
}
}
void NotificationsPlugin::setSortKey(const QString &itemKey, const int order)
{
const QString key = QString("pos_%1_%2").arg(itemKey).arg(displayMode());
m_proxyInter->saveValue(this, key, order);
}
void NotificationsPlugin::pluginSettingsChanged()
{
refreshPluginItemsVisible();
}
void NotificationsPlugin::loadPlugin()
{
if (m_pluginLoaded)
return;
m_pluginLoaded = true;
m_itemWidget = new NotificationsWidget;
m_proxyInter->itemAdded(this, pluginName());
displayModeChanged(displayMode());
}
bool NotificationsPlugin::checkSwap()
{
QFile file("/proc/swaps");
if (file.open(QIODevice::Text | QIODevice::ReadOnly)) {
const QString &body = file.readAll();
file.close();
QRegularExpression re("\\spartition\\s");
QRegularExpressionMatch match = re.match(body);
return match.hasMatch();
}
return false;
}
void NotificationsPlugin::refreshPluginItemsVisible()
{
if (pluginIsDisable()) {
m_proxyInter->itemRemoved(this, pluginName());
} else {
if (!m_pluginLoaded) {
loadPlugin();
return;
}
m_proxyInter->itemAdded(this, pluginName());
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
*
* Author: sbw <sbw@sbw.so>
*
* Maintainer: sbw <sbw@sbw.so>
*
* 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 NOTIFITIONPLUGIN_H
#define NOTIFITIONPLUGIN_H
#include "pluginsiteminterface.h"
#include "notificationswidget.h"
#include "../widgets/tipswidget.h"
#include <QDBusInterface>
class NotificationsPlugin : public QObject, PluginsItemInterface
{
Q_OBJECT
Q_INTERFACES(PluginsItemInterface)
Q_PLUGIN_METADATA(IID "com.deepin.dock.PluginsItemInterface" FILE "notifications.json")
public:
explicit NotificationsPlugin(QObject *parent = 0);
const QString pluginName() const override;
const QString pluginDisplayName() const override;
void init(PluginProxyInterface *proxyInter) override;
void pluginStateSwitched() override;
bool pluginIsAllowDisable() override { return true; }
bool pluginIsDisable() override;
QWidget *itemWidget(const QString &itemKey) override;
QWidget *itemTipsWidget(const QString &itemKey) override;
const QString itemCommand(const QString &itemKey) override;
void displayModeChanged(const Dock::DisplayMode displayMode) override;
int itemSortKey(const QString &itemKey) Q_DECL_OVERRIDE;
void setSortKey(const QString &itemKey, const int order) Q_DECL_OVERRIDE;
void pluginSettingsChanged() override;
QDBusInterface *getNotifyInterface();
private:
void loadPlugin();
bool checkSwap();
void refreshPluginItemsVisible();
private:
bool m_pluginLoaded;
QDBusInterface *m_interface = nullptr;
NotificationsWidget *m_itemWidget;
TipsWidget *m_tipsLabel;
};
#endif // NOTIFITIONPLUGIN_H

View File

@ -0,0 +1,176 @@
/*
* Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
*
* Author: sbw <sbw@sbw.so>
*
* Maintainer: sbw <sbw@sbw.so>
*
* 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 "notificationswidget.h"
#include <QSvgRenderer>
#include <QPainter>
#include <QMouseEvent>
#include <QApplication>
#include <QIcon>
#include <DStyle>
#include <DGuiApplicationHelper>
DWIDGET_USE_NAMESPACE;
NotificationsWidget::NotificationsWidget(QWidget *parent)
: QWidget(parent)
, m_hover(false)
, m_pressed(false)
{
setMouseTracking(true);
setMinimumSize(PLUGIN_BACKGROUND_MIN_SIZE, PLUGIN_BACKGROUND_MIN_SIZE);
connect(DGuiApplicationHelper::instance(), &DGuiApplicationHelper::themeTypeChanged, this, [ = ] {
update();
});
m_icon = QIcon::fromTheme(":/icons/resources/icons/notification.svg");
}
QSize NotificationsWidget::sizeHint() const
{
return QSize(PLUGIN_BACKGROUND_MAX_SIZE, PLUGIN_BACKGROUND_MAX_SIZE);
}
void NotificationsWidget::paintEvent(QPaintEvent *e)
{
Q_UNUSED(e);
QPixmap pixmap;
QString iconName = "notification";
int iconSize = PLUGIN_ICON_MAX_SIZE;
QPainter painter(this);
if (rect().height() > PLUGIN_BACKGROUND_MIN_SIZE) {
QColor color;
if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType) {
color = Qt::black;
painter.setOpacity(0.5);
if (m_hover) {
painter.setOpacity(0.6);
}
if (m_pressed) {
painter.setOpacity(0.3);
}
} else {
color = Qt::white;
painter.setOpacity(0.1);
if (m_hover) {
painter.setOpacity(0.2);
}
if (m_pressed) {
painter.setOpacity(0.05);
}
}
painter.setRenderHint(QPainter::Antialiasing, true);
DStyleHelper dstyle(style());
const int radius = dstyle.pixelMetric(DStyle::PM_FrameRadius);
QPainterPath path;
int minSize = std::min(width(), height());
QRect rc(0, 0, minSize, minSize);
rc.moveTo(rect().center() - rc.center());
path.addRoundedRect(rc, radius, radius);
painter.fillPath(path, color);
} else if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType) {
// 最小尺寸时,不画背景,采用深色图标
iconName.append(PLUGIN_MIN_ICON_NAME);
}
painter.setOpacity(1);
pixmap = loadSvg(iconName, QSize(iconSize, iconSize));
const QRectF &rf = QRectF(rect());
const QRectF &rfp = QRectF(pixmap.rect());
painter.drawPixmap(rf.center() - rfp.center() / pixmap.devicePixelRatioF(), pixmap);
}
const QPixmap NotificationsWidget::loadSvg(const QString &fileName, const QSize &size) const
{
const auto ratio = devicePixelRatioF();
QPixmap pixmap;
pixmap = QIcon::fromTheme(fileName, m_icon).pixmap(size * ratio);
pixmap.setDevicePixelRatio(ratio);
return pixmap;
}
void NotificationsWidget::mousePressEvent(QMouseEvent *event)
{
m_pressed = true;
update();
QWidget::mousePressEvent(event);
}
void NotificationsWidget::mouseReleaseEvent(QMouseEvent *event)
{
m_pressed = false;
m_hover = false;
update();
QWidget::mouseReleaseEvent(event);
}
void NotificationsWidget::mouseMoveEvent(QMouseEvent *event)
{
m_hover = true;
QWidget::mouseMoveEvent(event);
}
void NotificationsWidget::leaveEvent(QEvent *event)
{
if (!rect().contains(mapFromGlobal(QCursor::pos()))) {
m_hover = false;
m_pressed = false;
update();
}
QWidget::leaveEvent(event);
}
void NotificationsWidget::resizeEvent(QResizeEvent *event)
{
const Dock::Position position = qApp->property(PROP_POSITION).value<Dock::Position>();
// 保持横纵比
if (position == Dock::Bottom || position == Dock::Top) {
setMaximumWidth(height());
setMaximumHeight(QWIDGETSIZE_MAX);
} else {
setMaximumHeight(width());
setMaximumWidth(QWIDGETSIZE_MAX);
}
QWidget::resizeEvent(event);
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
*
* Author: sbw <sbw@sbw.so>
*
* Maintainer: sbw <sbw@sbw.so>
*
* 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 NOTIFICATIONSWIDGET_H
#define NOTIFICATIONSWIDGET_H
#include "constants.h"
#include <QWidget>
#include <QIcon>
class NotificationsWidget: public QWidget
{
Q_OBJECT
public:
explicit NotificationsWidget(QWidget *parent = 0);
protected:
QSize sizeHint() const override;
void paintEvent(QPaintEvent *e) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void leaveEvent(QEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
private:
const QPixmap loadSvg(const QString &fileName, const QSize &size) const;
private:
Dock::DisplayMode m_displayMode;
bool m_hover;
bool m_pressed;
QIcon m_icon;
};
#endif // NOTIFICATIONSWIDGET_H

View File

@ -0,0 +1,6 @@
<RCC>
<qresource prefix="/icons">
<file>resources/icons/notification-dark.svg</file>
<file>resources/icons/notification.svg</file>
</qresource>
</RCC>

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M7,16 L13,16 C13,17.6568542 11.6568542,19 10,19 C8.40231912,19 7.09633912,17.75108 7.00509269,16.1762728 L7,16 L13,16 Z M10.3773685,1 C12.8942381,1 15.0585627,3.06738216 15.2115228,5.6176273 L15.2344541,5.999952 C15.4012564,8.78098309 16.3249519,11.5195476 17.9830894,13.9755256 L18,14 L2,14 L2.01691063,13.9755256 C3.6750481,11.5195476 4.59874356,8.78098309 4.76554589,5.999952 L4.78847718,5.6176273 C4.94143729,3.06738216 7.1057619,1 9.62263149,1 L10.3773685,1 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 590 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="#FFF" fill-rule="evenodd" d="M7,16 L13,16 C13,17.6568542 11.6568542,19 10,19 C8.40231912,19 7.09633912,17.75108 7.00509269,16.1762728 L7,16 L13,16 Z M10.3773685,1 C12.8942381,1 15.0585627,3.06738216 15.2115228,5.6176273 L15.2344541,5.999952 C15.4012564,8.78098309 16.3249519,11.5195476 17.9830894,13.9755256 L18,14 L2,14 L2.01691063,13.9755256 C3.6750481,11.5195476 4.59874356,8.78098309 4.76554589,5.999952 L4.78847718,5.6176273 C4.94143729,3.06738216 7.1057619,1 9.62263149,1 L10.3773685,1 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 602 B