diff --git a/CMakeLists.txt b/CMakeLists.txt index 88134c9..5a6d7aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,7 @@ endif () find_package(PkgConfig REQUIRED) find_package(Dtk COMPONENTS Widget Core REQUIRED) find_package(Qt5 COMPONENTS Core Gui Widgets DBus Test Concurrent REQUIRED) +find_package(DdeTrayLoader REQUIRED) find_package(ECM REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) @@ -246,3 +247,38 @@ target_link_libraries(${UT_BIN_NAME} PRIVATE -lgcov -lgtest ) + +#--------------------------dock-plugin--------------------------- +set(PLUGIN_NAME dock-clipboard-plugin) + +file(GLOB_RECURSE SRCS + "dock-clipboard-plugin/*.h" + "dock-clipboard-plugin/*.cpp" + "dock-clipboard-plugin/widget/*.h" + "dock-clipboard-plugin/widget/*.cpp" +) + +add_definitions("${QT_DEFINITIONS} -DQT_PLUGIN") +add_library(${PLUGIN_NAME} SHARED ${SRCS} dock-clipboard-plugin/resources/clipboard.qrc) +target_include_directories(${PLUGIN_NAME} PUBLIC + ${DtkWidget_INCLUDE_DIRS} + ${DtkCore_INCLUDE_DIRS} + ${OBJECT_BINARY_DIR} + ${DDE_DOCK_INCLUDE_DIR} + ${QGSettings_INCLUDE_DIRS} + ${DFrameworkDBus_INCLUDE_DIRS} + dock-clipboard-plugin/widget/ +) +target_link_libraries(${PLUGIN_NAME} PRIVATE + ${DtkWidget_LIBRARIES} + ${QGSettings_LIBRARIES} + ${DFrameworkDBus_LIBRARIES} + ${Qt5DBus_LIBRARIES} + ${Qt5Widgets_LIBRARIES} + ${Qt5Svg_LIBRARIES} + ${DtkCore_LIBRARIES} +) + +# 设置执行 make install 时哪个目标应该被 install 到哪个位置 +install(TARGETS ${PLUGIN_NAME} LIBRARY DESTINATION lib/dde-dock/plugins) +install(FILES "dock-clipboard-plugin/resources/clipboard.svg" DESTINATION share/dde-dock/icons/dcc-setting) diff --git a/dde-clipboard/dbus/iteminfo.h b/dde-clipboard/dbus/iteminfo.h index 74b34fd..972f39b 100644 --- a/dde-clipboard/dbus/iteminfo.h +++ b/dde-clipboard/dbus/iteminfo.h @@ -8,7 +8,7 @@ #include #include -#include "constants.h" +#include "dde-clipboard/constants.h" enum DataType { Unknown, diff --git a/dock-clipboard-plugin/clipboard.json b/dock-clipboard-plugin/clipboard.json new file mode 100644 index 0000000..bec81f0 --- /dev/null +++ b/dock-clipboard-plugin/clipboard.json @@ -0,0 +1,3 @@ +{ + "api": "2.0.0" +} diff --git a/dock-clipboard-plugin/clipboardcontroller.h b/dock-clipboard-plugin/clipboardcontroller.h new file mode 100644 index 0000000..01beefb --- /dev/null +++ b/dock-clipboard-plugin/clipboardcontroller.h @@ -0,0 +1,37 @@ +// SPDX-FileCopyrightText: 2019 - 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#ifndef CLIPBOARDCONTROLLER_H +#define CLIPBOARDCONTROLLER_H + +#include + +#include +#include + +class ClipboardController : public QObject, public Dtk::Core::DSingleton +{ + friend Dtk::Core::DSingleton; + + Q_OBJECT +public: + ClipboardController() + { + } + + ~ClipboardController() { } + + void toggle() + { + QDBusInterface interface("org.deepin.dde.ClipboardLoader1", + "/org/deepin/dde/ClipboardLoader1", + "org.deepin.dde.ClipboardLoader1", + QDBusConnection::sessionBus()); + if (interface.isValid()) { + interface.call("quit"); + } + } +}; + +#endif diff --git a/dock-clipboard-plugin/clipboarditem.cpp b/dock-clipboard-plugin/clipboarditem.cpp new file mode 100644 index 0000000..99f9378 --- /dev/null +++ b/dock-clipboard-plugin/clipboarditem.cpp @@ -0,0 +1,107 @@ +// SPDX-FileCopyrightText: 2020 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#include "clipboarditem.h" +#include "constants.h" +#include "clipboardcontroller.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +DGUI_USE_NAMESPACE + +#define SHIFT "shift" + +ClipboardItem::ClipboardItem(QWidget* parent) + : QWidget(parent) + , m_tipsLabel(new TipsWidget(this)) + , m_icon(new CommonIconButton(this)) +{ + init(); +} + +void ClipboardItem::init() +{ + m_tipsLabel->setVisible(false); + m_tipsLabel->setText(tr("Clipboard")); + + m_icon->setFixedSize(Dock::DOCK_PLUGIN_ITEM_FIXED_SIZE); + m_icon->setIcon(QIcon::fromTheme("clipboard")); + m_icon->setClickable(true); + + auto vLayout = new QVBoxLayout(this); + vLayout->setSpacing(0); + vLayout->setMargin(0); + vLayout->addWidget(m_icon, 0, Qt::AlignCenter); + + refreshIcon(); + + connect(DGuiApplicationHelper::instance(), &DGuiApplicationHelper::themeTypeChanged, this, &ClipboardItem::refreshIcon); + connect(m_icon, &CommonIconButton::clicked, this, [] { + ClipboardController::ref().toggle(); + }); +} + +QWidget* ClipboardItem::tipsWidget() +{ + return m_tipsLabel; +} + +const QString ClipboardItem::contextMenu() const +{ + QList items; + items.reserve(1); + + QMap shift; + shift["itemId"] = SHIFT; + shift["itemText"] = tr("Open"); + shift["isActive"] = true; + items.push_back(shift); + + QMap menu; + menu["items"] = items; + menu["checkableMenu"] = false; + menu["singleCheck"] = false; + + return QJsonDocument::fromVariant(menu).toJson(); +} + +void ClipboardItem::invokeMenuItem(const QString menuId, const bool checked) +{ + Q_UNUSED(menuId); + Q_UNUSED(checked); + + if (menuId == SHIFT) { + ClipboardController::ref().toggle(); + Q_EMIT requestHideApplet(); + } +} + +void ClipboardItem::refreshIcon() +{ + m_icon->setState(CommonIconButton::Default); +} + +void ClipboardItem::resizeEvent(QResizeEvent* e) +{ + QWidget::resizeEvent(e); + + const Dock::Position position = qApp->property(PROP_POSITION).value(); + if (position == Dock::Bottom || position == Dock::Top) { + setMaximumWidth(height()); + setMaximumHeight(QWIDGETSIZE_MAX); + } else { + setMaximumHeight(width()); + setMaximumWidth(QWIDGETSIZE_MAX); + } + + refreshIcon(); +} diff --git a/dock-clipboard-plugin/clipboarditem.h b/dock-clipboard-plugin/clipboarditem.h new file mode 100644 index 0000000..86bf6ed --- /dev/null +++ b/dock-clipboard-plugin/clipboarditem.h @@ -0,0 +1,40 @@ +// SPDX-FileCopyrightText: 2020 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#ifndef CLIPBOARDITEM_H +#define CLIPBOARDITEM_H + +#include "commoniconbutton.h" +#include "widget/tipswidget.h" + +#include + +class ClipboardItem : public QWidget +{ + Q_OBJECT + +public: + explicit ClipboardItem(QWidget *parent = nullptr); + + QWidget *tipsWidget(); + const QString contextMenu() const; + void invokeMenuItem(const QString menuId, const bool checked); + void refreshIcon(); + +protected: + void resizeEvent(QResizeEvent *e) override; + +signals: + void requestHideApplet(); + +private: + void init(); + +private: + TipsWidget *m_tipsLabel; + CommonIconButton *m_icon; + QPixmap m_iconPixmap; +}; + +#endif // CLIPBOARDITEM_H diff --git a/dock-clipboard-plugin/clipboardplugin.cpp b/dock-clipboard-plugin/clipboardplugin.cpp new file mode 100644 index 0000000..67d9e6f --- /dev/null +++ b/dock-clipboard-plugin/clipboardplugin.cpp @@ -0,0 +1,151 @@ +// SPDX-FileCopyrightText: 2020 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#include "clipboardplugin.h" + +#include + +#define CLIPBOARD_KEY "clipboard-key" +DCORE_USE_NAMESPACE + +ClipboardPlugin::ClipboardPlugin(QObject *parent) + : QObject(parent) + , m_quickPanelWidget(nullptr) + , m_item(nullptr) + , m_messageCallback(nullptr) +{ + QTranslator *translator = new QTranslator(this); + translator->load(QString("/usr/share/dde-clipboard/translations/dde-clipboard_%1.qm").arg(QLocale::system().name())); + QCoreApplication::installTranslator(translator); +} + +ClipboardPlugin::~ClipboardPlugin() +{ + if (m_quickPanelWidget) { + delete m_quickPanelWidget; + m_quickPanelWidget = nullptr; + } + + if (m_item) { + delete m_item; + m_item = nullptr; + } +} + +const QString ClipboardPlugin::pluginName() const +{ + return "clipboard"; +} + +const QString ClipboardPlugin::pluginDisplayName() const +{ + return tr("Clipboard"); +} + +void ClipboardPlugin::init(PluginProxyInterface *proxyInter) +{ + m_proxyInter = proxyInter; + + if (m_item || m_quickPanelWidget) { + return; + } + m_item = new ClipboardItem(); + m_quickPanelWidget = new QuickPanelWidget(); + + m_proxyInter->itemAdded(this, CLIPBOARD_KEY); + m_quickPanelWidget->setDescription(pluginDisplayName()); + m_quickPanelWidget->setIcon(QIcon::fromTheme("clipboard")); + + connect(m_item, &ClipboardItem::requestHideApplet, this, [this] { + m_proxyInter->requestSetAppletVisible(this, CLIPBOARD_KEY, false); + }); + connect(m_quickPanelWidget, &QuickPanelWidget::requestHideApplet, this, [this] { + m_proxyInter->requestSetAppletVisible(this, CLIPBOARD_KEY, false); + }); + QDBusConnection::sessionBus().connect("com.deepin.dde.Clipboard", "/com/deepin/dde/Clipboard", "com.deepin.dde.Clipboard", "clipboardVisibleChanged", this, SLOT(onClipboardVisibleChanged(bool))); +} + +QWidget *ClipboardPlugin::itemWidget(const QString &itemKey) +{ + if (itemKey == CLIPBOARD_KEY) { + return m_item; + } + + if (itemKey == Dock::QUICK_ITEM_KEY) { + return m_quickPanelWidget; + } + + return nullptr; +} + +QWidget *ClipboardPlugin::itemTipsWidget(const QString &itemKey) +{ + if (itemKey == CLIPBOARD_KEY) { + return m_item->tipsWidget(); + } + + return nullptr; +} + +QWidget *ClipboardPlugin::itemPopupApplet(const QString &itemKey) +{ + return nullptr; +} + +const QString ClipboardPlugin::itemContextMenu(const QString &itemKey) +{ + if (itemKey == CLIPBOARD_KEY) { + return m_item->contextMenu(); + } + + return QString(); +} + +void ClipboardPlugin::invokedMenuItem(const QString &itemKey, const QString &menuId, const bool checked) +{ + if (itemKey == CLIPBOARD_KEY) { + m_item->invokeMenuItem(menuId, checked); + } +} + +int ClipboardPlugin::itemSortKey(const QString &itemKey) +{ + const QString key = QString("pos_%1_%2").arg(itemKey).arg(Dock::Efficient); + + return m_proxyInter->getValue(this, key, -1).toInt(); +} + +void ClipboardPlugin::setSortKey(const QString &itemKey, const int order) +{ + const QString key = QString("pos_%1_%2").arg(itemKey).arg(Dock::Efficient); + + m_proxyInter->saveValue(this, key, order); +} + +void ClipboardPlugin::refreshIcon(const QString &itemKey) +{ + if (itemKey == CLIPBOARD_KEY) { + m_item->refreshIcon(); + } +} + +const QString ClipboardPlugin::itemCommand(const QString &itemKey) +{ + Q_UNUSED(itemKey); + return QString("dbus-send --session --print-reply --dest=org.deepin.dde.Clipboard1 /org/deepin/dde/Clipboard1 org.deepin.dde.Clipboard1.Toggle"); +} + +void ClipboardPlugin::onClipboardVisibleChanged(bool visible) +{ + if (!m_messageCallback) { + qWarning() << "Message callback function is nullptr"; + return; + } + QJsonObject msg; + msg[Dock::MSG_TYPE] = Dock::MSG_ITEM_ACTIVE_STATE; + msg[Dock::MSG_DATA] = visible; + QJsonDocument doc; + doc.setObject(msg); + m_messageCallback(this, doc.toJson()); +} diff --git a/dock-clipboard-plugin/clipboardplugin.h b/dock-clipboard-plugin/clipboardplugin.h new file mode 100644 index 0000000..e18d967 --- /dev/null +++ b/dock-clipboard-plugin/clipboardplugin.h @@ -0,0 +1,47 @@ +// SPDX-FileCopyrightText: 2020 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#ifndef CLIPBOARDPLUGIN_H +#define CLIPBOARDPLUGIN_H + +#include +#include "quickpanelwidget.h" +#include "clipboarditem.h" + +class ClipboardPlugin : public QObject, public PluginsItemInterfaceV2 +{ + Q_OBJECT + Q_INTERFACES(PluginsItemInterfaceV2) + Q_PLUGIN_METADATA(IID ModuleInterface_iid_V2 FILE "clipboard.json") + +public: + explicit ClipboardPlugin(QObject *parent = nullptr); + ~ClipboardPlugin(); + + const QString pluginName() const Q_DECL_OVERRIDE; + const QString pluginDisplayName() const Q_DECL_OVERRIDE; + void init(PluginProxyInterface *proxyInter) Q_DECL_OVERRIDE; + bool pluginIsAllowDisable() override { return true; } + QWidget *itemWidget(const QString &itemKey) Q_DECL_OVERRIDE; + QWidget *itemPopupApplet(const QString &itemKey) Q_DECL_OVERRIDE; + QWidget *itemTipsWidget(const QString &itemKey) Q_DECL_OVERRIDE; + const QString itemContextMenu(const QString &itemKey) Q_DECL_OVERRIDE; + void invokedMenuItem(const QString &itemKey, const QString &menuId, const bool checked) Q_DECL_OVERRIDE; + int itemSortKey(const QString &itemKey) Q_DECL_OVERRIDE; + void setSortKey(const QString &itemKey, const int order) Q_DECL_OVERRIDE; + void refreshIcon(const QString &itemKey) Q_DECL_OVERRIDE; + Dock::PluginFlags flags() const override { return Dock::Type_Quick | Dock::Quick_Panel_Single | Dock::Attribute_Normal; } + virtual void setMessageCallback(MessageCallbackFunc cb) override { m_messageCallback = cb; } + const QString itemCommand(const QString &itemKey) override; + +private slots: + void onClipboardVisibleChanged(bool); + +private: + QuickPanelWidget *m_quickPanelWidget; + ClipboardItem *m_item; + MessageCallbackFunc m_messageCallback; +}; + +#endif // CLIPBOARDPLUGIN_H diff --git a/dock-clipboard-plugin/quickpanelwidget.cpp b/dock-clipboard-plugin/quickpanelwidget.cpp new file mode 100644 index 0000000..b56e617 --- /dev/null +++ b/dock-clipboard-plugin/quickpanelwidget.cpp @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: 2019 - 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#include "quickpanelwidget.h" +#include "clipboardcontroller.h" + +QuickPanelWidget::QuickPanelWidget(QWidget* parent) + : SignalQuickPanel(parent) +{ + connect(this, &QuickPanelWidget::clicked, [this] { + ClipboardController::ref().toggle(); + Q_EMIT requestHideApplet(); + }); +} + +QuickPanelWidget::~QuickPanelWidget() +{ +} \ No newline at end of file diff --git a/dock-clipboard-plugin/quickpanelwidget.h b/dock-clipboard-plugin/quickpanelwidget.h new file mode 100644 index 0000000..2fa7096 --- /dev/null +++ b/dock-clipboard-plugin/quickpanelwidget.h @@ -0,0 +1,24 @@ +// SPDX-FileCopyrightText: 2019 - 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#ifndef QUICKPANELWIDGET_H +#define QUICKPANELWIDGET_H + +#include "singlequickpanel.h" + +class QuickPanelWidget : public SignalQuickPanel +{ + Q_OBJECT +public: + QuickPanelWidget(QWidget *parent = nullptr); + ~QuickPanelWidget(); + +signals: + void requestHideApplet(); + +private: + +}; + +#endif \ No newline at end of file diff --git a/dock-clipboard-plugin/resources/clipboard.qrc b/dock-clipboard-plugin/resources/clipboard.qrc new file mode 100644 index 0000000..e43c45d --- /dev/null +++ b/dock-clipboard-plugin/resources/clipboard.qrc @@ -0,0 +1,6 @@ + + + texts/clipboard_24px.svg + texts/clipboard_16px.svg + + diff --git a/dock-clipboard-plugin/resources/clipboard.svg b/dock-clipboard-plugin/resources/clipboard.svg new file mode 100644 index 0000000..2bd8f9a --- /dev/null +++ b/dock-clipboard-plugin/resources/clipboard.svg @@ -0,0 +1,7 @@ + + + clipboard-dark + + + + \ No newline at end of file diff --git a/dock-clipboard-plugin/resources/texts/clipboard_16px.svg b/dock-clipboard-plugin/resources/texts/clipboard_16px.svg new file mode 100644 index 0000000..2bd8f9a --- /dev/null +++ b/dock-clipboard-plugin/resources/texts/clipboard_16px.svg @@ -0,0 +1,7 @@ + + + clipboard-dark + + + + \ No newline at end of file diff --git a/dock-clipboard-plugin/resources/texts/clipboard_24px.svg b/dock-clipboard-plugin/resources/texts/clipboard_24px.svg new file mode 100644 index 0000000..25a8423 --- /dev/null +++ b/dock-clipboard-plugin/resources/texts/clipboard_24px.svg @@ -0,0 +1,7 @@ + + + clipboard-dark + + + + \ No newline at end of file diff --git a/dock-clipboard-plugin/widget/commoniconbutton.cpp b/dock-clipboard-plugin/widget/commoniconbutton.cpp new file mode 100644 index 0000000..50a8d27 --- /dev/null +++ b/dock-clipboard-plugin/widget/commoniconbutton.cpp @@ -0,0 +1,197 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later +#include "commoniconbutton.h" + +#include +#include +#include + +#include + +DGUI_USE_NAMESPACE + +CommonIconButton::CommonIconButton(QWidget *parent) + : QWidget(parent) + , m_refreshTimer(nullptr) + , m_rotateAngle(0) + , m_clickable(false) + , m_rotatable(false) + , m_hover(false) + , m_state(Default) + , m_lightThemeColor(Qt::black) + , m_darkThemeColor(Qt::white) + , m_activeState(false) +{ + setAccessibleName("IconButton"); + setFixedSize(24, 24); + if (parent) + setForegroundRole(parent->foregroundRole()); + + connect(DGuiApplicationHelper::instance(), &DGuiApplicationHelper::themeTypeChanged, this, &CommonIconButton::refreshIcon); +} + +void CommonIconButton::setStateIconMapping(QMap> mapping) +{ + m_fileMapping = mapping; +} + +void CommonIconButton::setState(State state) +{ + m_state = state; + if (m_fileMapping.contains(state)) { + auto pair = m_fileMapping.value(state); + setIcon(pair.first, pair.second); + } + if (!m_icon.isNull()) { + setIcon(m_icon, m_lightThemeColor, m_darkThemeColor); + } +} + +void CommonIconButton::setIcon(const QIcon &icon, QColor lightThemeColor, QColor darkThemeColor) +{ + m_icon = icon; + if (lightThemeColor.isValid() && darkThemeColor.isValid()) { + m_lightThemeColor = lightThemeColor; + m_darkThemeColor = darkThemeColor; + QColor color = DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType ? m_lightThemeColor : m_darkThemeColor; + if (m_activeState) + color = palette().color(QPalette::Highlight); + auto pa = palette(); + pa.setColor(QPalette::WindowText, color); + setPalette(pa); + } + + update(); +} + +void CommonIconButton::setActiveState(bool state) +{ + m_activeState = state; + if (m_lightThemeColor.isValid() && m_darkThemeColor.isValid()) { + setIcon(m_icon, m_lightThemeColor, m_darkThemeColor); + } else { + setForegroundRole(state ? QPalette::Highlight : QPalette::NoRole); + } +} + +void CommonIconButton::setIcon(const QString &icon, const QString &fallback, const QString &suffix) +{ + if (!m_fileMapping.contains(Default)) { + m_fileMapping.insert(Default, QPair(icon, fallback)); + } + + QString tmp = icon; + QString tmpFallback = fallback; + + static auto addDarkMark = [suffix] (QString &file) { + if (file.contains(suffix)) { + file.replace(suffix, "-dark" + suffix); + } else { + file.append("-dark"); + } + }; + if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType) { + addDarkMark(tmp); + addDarkMark(tmpFallback); + } + + m_icon = QIcon(tmpFallback); + update(); +} + +void CommonIconButton::setHoverIcon(const QIcon &icon) +{ + m_hoverIcon = icon; +} + +void CommonIconButton::setClickable(bool clickable) +{ + m_clickable = clickable; +} + +void CommonIconButton::setRotatable(bool rotatable) +{ + m_rotatable = rotatable; + if (!m_rotatable) { + if (m_refreshTimer) + delete m_refreshTimer; + m_refreshTimer = nullptr; + } +} + +void CommonIconButton::startRotate() +{ + if (!m_refreshTimer) { + m_refreshTimer = new QTimer(this); + m_refreshTimer->setInterval(50); + connect(m_refreshTimer, &QTimer::timeout, this, &CommonIconButton::startRotate); + } + m_refreshTimer->start(); + m_rotateAngle += 54; + update(); + if (m_rotateAngle >= 360) { + stopRotate(); + } +} + +void CommonIconButton::stopRotate() +{ + m_refreshTimer->stop(); + m_rotateAngle = 0; + update(); +} + +bool CommonIconButton::event(QEvent *e) +{ + switch (e->type()) { + case QEvent::Leave: + case QEvent::Enter: + m_hover = e->type() == QEvent::Enter; + update(); + break; + default: + break; + } + return QWidget::event(e); +} + +void CommonIconButton::paintEvent(QPaintEvent *e) +{ + QWidget::paintEvent(e); + QPainter painter(this); + painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); + + if (m_rotateAngle != 0) { + painter.translate(this->width() / 2, this->height() / 2); + painter.rotate(m_rotateAngle); + painter.translate(-(this->width() / 2), -(this->height() / 2)); + } + + if (m_hover && !m_hoverIcon.isNull()) { + m_hoverIcon.paint(&painter, rect()); + } else if (!m_icon.isNull()) { + m_icon.paint(&painter, rect()); + } +} + +void CommonIconButton::mousePressEvent(QMouseEvent *event) +{ + m_pressPos = event->pos(); + return QWidget::mousePressEvent(event); +} + +void CommonIconButton::mouseReleaseEvent(QMouseEvent *event) +{ + if (m_clickable && rect().contains(m_pressPos) && event->button() == Qt::LeftButton && rect().contains(event->pos()) && (!m_refreshTimer || !m_refreshTimer->isActive())) { + if (m_rotatable) + startRotate(); + Q_EMIT clicked(); + } + return QWidget::mouseReleaseEvent(event); +} + +void CommonIconButton::refreshIcon() +{ + setState(m_state); +} diff --git a/dock-clipboard-plugin/widget/commoniconbutton.h b/dock-clipboard-plugin/widget/commoniconbutton.h new file mode 100644 index 0000000..63029b6 --- /dev/null +++ b/dock-clipboard-plugin/widget/commoniconbutton.h @@ -0,0 +1,68 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later +#ifndef ICONBUTTON_H +#define ICONBUTTON_H + +#include +#include +#include + +class CommonIconButton : public QWidget +{ +public: + enum State { + Default, + On, + Off + }; + + Q_OBJECT +public: + explicit CommonIconButton(QWidget *parent = nullptr); + + void setStateIconMapping(QMap> mapping); + void setState(State state); + void setActiveState(bool state); + bool activeState() const { return m_activeState; } + +public Q_SLOTS: + void setIcon(const QString &icon, const QString &fallback = "", const QString &suffix = ".svg"); + void setIcon(const QIcon &icon, QColor lightThemeColor = QColor(QColor::Invalid), QColor darkThemeColor = QColor(QColor::Invalid)); + void setHoverIcon(const QIcon &icon); + + void setClickable(bool clickable); + void setRotatable(bool rotatable); + +signals: + void clicked(); + +protected: + bool event(QEvent *e) override; + void paintEvent(QPaintEvent *e) override; + void mousePressEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; + + void startRotate(); + void stopRotate(); + +private: + void refreshIcon(); + +private: + QTimer *m_refreshTimer; + QIcon m_icon; + QIcon m_hoverIcon; + QPoint m_pressPos; + int m_rotateAngle; + bool m_clickable; + bool m_rotatable; + bool m_hover; + QMap> m_fileMapping; + State m_state; + QColor m_lightThemeColor; + QColor m_darkThemeColor; + bool m_activeState; +}; + +#endif // DOCKICONBUTTON_H diff --git a/dock-clipboard-plugin/widget/singlequickpanel.cpp b/dock-clipboard-plugin/widget/singlequickpanel.cpp new file mode 100644 index 0000000..2adfad9 --- /dev/null +++ b/dock-clipboard-plugin/widget/singlequickpanel.cpp @@ -0,0 +1,93 @@ +// SPDX-FileCopyrightText: 2019 - 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#include "singlequickpanel.h" + +#include + +#include +#include +#include +#include + +SignalQuickPanel::SignalQuickPanel(QWidget *parent) + :QWidget(parent) + , m_icon(new CommonIconButton(this)) + , m_description(new DLabel(this)) +{ + initUI(); + connect(DGuiApplicationHelper::instance(), &DGuiApplicationHelper::themeTypeChanged, this, &SignalQuickPanel::refreshBg); +} + +SignalQuickPanel::~SignalQuickPanel() +{ + +} + +void SignalQuickPanel::initUI() +{ + m_icon->setFixedSize(QSize(24, 24)); + + m_description->setElideMode(Qt::ElideRight); + DToolTip::setToolTipShowMode(m_description, DToolTip::ShowWhenElided); + DFontSizeManager::instance()->bind(m_description, DFontSizeManager::T10); + + auto layout = new QVBoxLayout; + layout->setMargin(8); + layout->setSpacing(0); + layout->addStretch(1); + layout->addWidget(m_icon, 0, Qt::AlignCenter); + layout->addSpacing(10); + layout->addWidget(m_description, 0, Qt::AlignCenter); + layout->addStretch(1); + + setLayout(layout); +} + +void SignalQuickPanel::setIcon(const QIcon &icon) +{ + m_icon->setIcon(icon, Qt::black, Qt::white); +} + +void SignalQuickPanel::setDescription(const QString &description) +{ + m_description->setText(description); +} + +void SignalQuickPanel::setWidgetState(WidgetState state) +{ + if (m_icon) + m_icon->setActiveState(WS_ACTIVE == state); + + refreshBg(); +} + +void SignalQuickPanel::mouseReleaseEvent(QMouseEvent *event) +{ + if (underMouse()) { + Q_EMIT clicked(); + } + return QWidget::mouseReleaseEvent(event); +} + +void SignalQuickPanel::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + painter.setRenderHint(QPainter::RenderHint::Antialiasing); + if (m_icon->activeState() && DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::DarkType) { + painter.setBrush(QColor(255, 255, 255, 255 * 0.8)); + } else { + painter.setBrush(Qt::transparent); + } + painter.setPen(Qt::NoPen); + painter.drawRoundedRect(rect(), 8, 8); + + QWidget::paintEvent(event); +} + +void SignalQuickPanel::refreshBg() +{ + m_description->setForegroundRole(m_icon->activeState() && DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::DarkType ? QPalette::Highlight : QPalette::NoRole); + update(); +} diff --git a/dock-clipboard-plugin/widget/singlequickpanel.h b/dock-clipboard-plugin/widget/singlequickpanel.h new file mode 100644 index 0000000..55cdf0f --- /dev/null +++ b/dock-clipboard-plugin/widget/singlequickpanel.h @@ -0,0 +1,51 @@ +// SPDX-FileCopyrightText: 2019 - 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#ifndef QUICKPANELBASE_H +#define QUICKPANELBASE_H + +#include "commoniconbutton.h" + +#include +#include + +DWIDGET_USE_NAMESPACE + +class SignalQuickPanel : public QWidget +{ + Q_OBJECT + +public: + enum WidgetState { + WS_NORMAL, + WS_ACTIVE, + }; + +public: + SignalQuickPanel(QWidget *parent = nullptr); + virtual ~SignalQuickPanel(); + + void setIcon(const QIcon &icon); + void setDescription(const QString &description); + void setWidgetState(WidgetState state); + +Q_SIGNALS: + void clicked(); + +protected: + void mouseReleaseEvent(QMouseEvent *event) override; + void paintEvent(QPaintEvent *event) override; + +private: + void initUI(); + +private slots: + void refreshBg(); + +private: + CommonIconButton *m_icon; + DLabel *m_description; +}; + +#endif \ No newline at end of file diff --git a/dock-clipboard-plugin/widget/tipswidget.cpp b/dock-clipboard-plugin/widget/tipswidget.cpp new file mode 100644 index 0000000..0e92509 --- /dev/null +++ b/dock-clipboard-plugin/widget/tipswidget.cpp @@ -0,0 +1,101 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#include "tipswidget.h" + +#include +#include +#include + +#define PADDING 4 + +TipsWidget::TipsWidget(QWidget *parent) + : QFrame(parent) + , m_type(SingleLine) +{ +} + +void TipsWidget::setText(const QString &text) +{ + m_type = TipsWidget::SingleLine; + m_text = text; + + setFixedSize(fontMetrics().width(m_text) + 20, fontMetrics().boundingRect(m_text).height() + PADDING); + + update(); +} + +void TipsWidget::setTextList(const QStringList &textList) +{ + m_type = TipsWidget::MultiLine; + m_textList = textList; + + int width = 0; + int height = 0; + for (const QString& text : m_textList) { + width = qMax(width, fontMetrics().width(text)); + height += fontMetrics().boundingRect(text).height(); + } + + setFixedSize(width + 20, height + PADDING); + + update(); +} + +/** + * @brief TipsWidget::paintEvent 任务栏插件提示信息绘制 + * @param event + */ +void TipsWidget::paintEvent(QPaintEvent *event) +{ + QFrame::paintEvent(event); + + QPainter painter(this); + painter.setPen(QPen(palette().brightText(), 1)); + + QTextOption option; + option.setAlignment(Qt::AlignCenter); + + switch (m_type) { + case SingleLine: { + painter.drawText(rect(), m_text, option); + } + break; + case MultiLine: { + int x = rect().x(); + int y = rect().y(); + if (m_textList.size() != 1) { + x += 10; + option.setAlignment(Qt::AlignLeft | Qt::AlignVCenter); + } + for (const QString& text : m_textList) { + int lineHeight = fontMetrics().boundingRect(text).height(); + painter.drawText(QRect(x, y, rect().width(), lineHeight), text, option); + y += lineHeight; + } + } break; + } +} + +bool TipsWidget::event(QEvent *event) +{ + if (event->type() == QEvent::FontChange) { + switch (m_type) { + case SingleLine: + { + setText(m_text); + break; + } + case MultiLine: + { + setTextList(m_textList); + break; + } + } + } else if (event->type() == QEvent::MouseButtonRelease + && static_cast(event)->button() == Qt::RightButton) { + return true; + } + return QFrame::event(event); +} diff --git a/dock-clipboard-plugin/widget/tipswidget.h b/dock-clipboard-plugin/widget/tipswidget.h new file mode 100644 index 0000000..4425083 --- /dev/null +++ b/dock-clipboard-plugin/widget/tipswidget.h @@ -0,0 +1,36 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#ifndef TIPSWIDGET_H +#define TIPSWIDGET_H + +#include + +class TipsWidget : public QFrame +{ + Q_OBJECT + enum ShowType + { + SingleLine, + MultiLine + }; +public: + explicit TipsWidget(QWidget *parent = nullptr); + + const QString& text(){return m_text;} + const QStringList &textList() { return m_textList; } + void setText(const QString &text); + void setTextList(const QStringList &textList); + +protected: + void paintEvent(QPaintEvent *event) override; + bool event(QEvent *event) override; + +private: + QString m_text; + QStringList m_textList; + ShowType m_type; +}; + +#endif // TIPSWIDGET_H