From 217cfc5514c63561900def080097c821dd1a6a59 Mon Sep 17 00:00:00 2001 From: wang fei Date: Wed, 28 Dec 2022 17:03:25 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E7=89=B9=E6=80=A7?= =?UTF-8?q?=E5=B1=95=E7=A4=BA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 增加特性对话框类接口; 2. dapplication增加特性对话框相关接口; 3. 重新布局关于对话框; Log: 新增特性介绍功能 Task: https://pms.uniontech.com/task-view-227391.html Influence: 特性介绍,关于介绍 Change-Id: Ie6244bd313bb385846f4c5c066108b65f5afcb4f --- docs/widgets/dfeaturedisplaydialog.zh_CN.dox | 83 +++++ .../collections/CMakeLists.txt | 1 + .../collections/buttonexample.cpp | 1 + .../dwidget-examples/collections/main.cpp | 5 + .../collections/mainwindow.cpp | 11 + .../org.deepin.dtkwiget.feature-display.json | 16 + .../dtkwidget/DWidget/DFeatureDisplayDialog | 1 + include/dtkwidget/widgets/daboutdialog.h | 4 + include/dtkwidget/widgets/dapplication.h | 4 + .../dtkwidget/widgets/dfeaturedisplaydialog.h | 60 ++++ include/dtkwidget/widgets/dmainwindow.h | 1 + include/dtkwidget/widgets/dstyle.h | 1 + src/CMakeLists.txt | 5 +- src/org.deepin.dtkwidget.feature-display.json | 26 ++ src/widgets/daboutdialog.cpp | 120 +++++-- src/widgets/dapplication.cpp | 25 +- src/widgets/dfeaturedisplaydialog.cpp | 332 ++++++++++++++++++ src/widgets/diconbutton.cpp | 2 +- src/widgets/dmainwindow.cpp | 31 +- src/widgets/dstyle.cpp | 7 +- src/widgets/dtitlebar.cpp | 19 + src/widgets/private/daboutdialog_p.h | 16 +- src/widgets/private/dapplication_p.h | 2 + src/widgets/private/dfeaturedisplaydialog_p.h | 71 ++++ src/widgets/private/dmainwindow_p.h | 1 + tests/src/widgets/ut_diconbutton.cpp | 2 +- tests/testcases/widgets/ut_diconbutton.cpp | 2 +- 27 files changed, 812 insertions(+), 37 deletions(-) create mode 100644 docs/widgets/dfeaturedisplaydialog.zh_CN.dox create mode 100644 examples/dwidget-examples/collections/org.deepin.dtkwiget.feature-display.json create mode 100644 include/dtkwidget/DWidget/DFeatureDisplayDialog create mode 100644 include/dtkwidget/widgets/dfeaturedisplaydialog.h create mode 100644 src/org.deepin.dtkwidget.feature-display.json create mode 100644 src/widgets/dfeaturedisplaydialog.cpp create mode 100644 src/widgets/private/dfeaturedisplaydialog_p.h diff --git a/docs/widgets/dfeaturedisplaydialog.zh_CN.dox b/docs/widgets/dfeaturedisplaydialog.zh_CN.dox new file mode 100644 index 000000000..93924d118 --- /dev/null +++ b/docs/widgets/dfeaturedisplaydialog.zh_CN.dox @@ -0,0 +1,83 @@ +/*! +@~chinese +@file dfeaturedisplaydialog.h +@ingroup dtkwidget + +@class Dtk::Widget::DFeatureItem +@brief 特性介绍中的每项特性 + +@fn explicit Dtk::Widget::DFeatureItem::DFeatureItem(const QIcon &icon, const QString &name, const QString &description, QObject *parent) +@brief 特性项的构造函数 +@param[in] icon 特性项的图标 +@param[in] name 特性项的名称 +@param[in] description 特性项的内容描述 +@param[in] parent 特性项的父对象 + +@fn explicit Dtk::Widget::DFeatureItem::~DFeatureItem() +@brief 特性项的析构函数 + +@fn QIcon Dtk::Widget::DFeatureItem::icon() const +@brief 获取特性项的图标 +@return 特性项的图标 + +@fn void Dtk::Widget::DFeatureItem::setIcon(const QIcon &icon) +@brief 设置特性项的图标 +@param[in] icon 特性项的图标 + +@fn QIcon Dtk::Widget::DFeatureItem::name() const +@brief 获取特性项的名称 +@return 特性项的名称 + +@fn QIcon Dtk::Widget::DFeatureItem::setName(const QString &name) const +@brief 设置特性项的名称 +@param[in] name 特性项的名称 + +@fn QIcon Dtk::Widget::DFeatureItem::description() const +@brief 获取特性项的内容描述 +@return 特性项的内容描述 + +@fn QIcon Dtk::Widget::DFeatureItem::setDescription(const QString &description) const +@brief 设置特性项的内容描述 +@param[in] description 特性项的内容描述 + +@class Dtk::Widget::DFeatureDisplayDialog +@brief 特性介绍对话框,展示应用更新的新特性 + +@fn Dtk::Widget::DFeatureDisplayDialog::DFeatureDisplayDialog(QWidget *parent) +@brief 特性介绍对话框的构造函数 +@param[in] parent 特性介绍对话框的父对象 + +@fn explicit Dtk::Widget::DFeatureDisplayDialog::~DFeatureDisplayDialog() +@brief 特性介绍对话框的析构函数 + +@fn void Dtk::Widget::DFeatureDisplayDialog::setTitle(const QString &title) +@brief 设置特性介绍对话框的主题 +@param[in] title 特性介绍对话框的主题 + +@fn void Dtk::Widget::DFeatureDisplayDialog::addItem(DFeatureItem *item) +@brief 增加特性介绍对话框的特性项 +@param[in] item 特性介绍对话框的特性项 + +@fn void Dtk::Widget::DFeatureDisplayDialog::removeItem(DFeatureItem *item) +@brief 移除特性介绍对话框的特性项 +@param[in] item 特性介绍对话框的特性项 + +@fn void Dtk::Widget::DFeatureDisplayDialog::addItems(QList items) +@brief 增加多个特性介绍对话框的特性项 +@param[in] items 特性介绍对话框的特性项列表 + +@fn void Dtk::Widget::DFeatureDisplayDialog::clearItems() +@brief 清除特性介绍对话框的所有特性项 + +@fn void Dtk::Widget::DFeatureDisplayDialog::setLinkButtonVisible(bool isVisible) +@brief 设置链接按钮是否可见 +@param[in] isVisible 链接按钮是否可见 + +@fn void Dtk::Widget::DFeatureDisplayDialog::setLinkUrl(const QString &url) +@brief 设置链接按钮链接地址 +@param[in] isVisible 链接按钮的链接地址 + +@fn void Dtk::Widget::DFeatureDisplayDialog::show() +@brief 显示特性介绍对话框 + +*/ diff --git a/examples/dwidget-examples/collections/CMakeLists.txt b/examples/dwidget-examples/collections/CMakeLists.txt index 5fce439ad..81075fab0 100644 --- a/examples/dwidget-examples/collections/CMakeLists.txt +++ b/examples/dwidget-examples/collections/CMakeLists.txt @@ -88,3 +88,4 @@ target_include_directories(${BIN_NAME} PUBLIC ${Qt5Gui_PRIVATE_INCLUDE_DIRS} ) install(TARGETS ${BIN_NAME} DESTINATION "${CMAKE_INSTALL_LIBDIR}/libdtk-${CMAKE_PROJECT_VERSION}/DWidget/examples/") +dconfig_override_files(APPID dtk-example META_NAME org.deepin.dtkwidget.feature-display FILES ./org.deepin.dtkwiget.feature-display.json) diff --git a/examples/dwidget-examples/collections/buttonexample.cpp b/examples/dwidget-examples/collections/buttonexample.cpp index 4f511b475..07047b821 100644 --- a/examples/dwidget-examples/collections/buttonexample.cpp +++ b/examples/dwidget-examples/collections/buttonexample.cpp @@ -341,6 +341,7 @@ DIconButtonExample::DIconButtonExample(QWidget *parent) pHBoxLayout->setSpacing(0); DIconButton *pButton_1 = new DIconButton(DStyle::SP_IncreaseElement, this); + pButton_1->setNewNotification(true); DIconButton *pButton_2 = new DIconButton(DStyle::SP_ArrowEnter, this); diff --git a/examples/dwidget-examples/collections/main.cpp b/examples/dwidget-examples/collections/main.cpp index 3be1b841e..819dfca99 100644 --- a/examples/dwidget-examples/collections/main.cpp +++ b/examples/dwidget-examples/collections/main.cpp @@ -38,6 +38,11 @@ int main(int argc, char *argv[]) a->setApplicationName("dtk-example"); a->setOrganizationName("deepin"); a->setApplicationVersion("1.0"); + a->setProductIcon(QIcon(":/images/logo_icon.svg")); + a->setWindowIcon(QIcon(":/images/logo_icon.svg")); + a->setApplicationDescription(QApplication::translate("main", "Collections provides the examples for dtk applications.")); + a->setApplicationDisplayName(QObject::tr("Collections")); + a->setApplicationLicense(QObject::tr("2023 UnionTech Software Technology Co., Ltd.")); DApplicationSettings as; Q_UNUSED(as) diff --git a/examples/dwidget-examples/collections/mainwindow.cpp b/examples/dwidget-examples/collections/mainwindow.cpp index 6c81867dd..6c6269897 100644 --- a/examples/dwidget-examples/collections/mainwindow.cpp +++ b/examples/dwidget-examples/collections/mainwindow.cpp @@ -47,6 +47,7 @@ #include "dsettingsdialog.h" #include "dsettingsoption.h" #include "dsettings.h" +#include "dfeaturedisplaydialog.h" DCORE_USE_NAMESPACE DWIDGET_USE_NAMESPACE @@ -147,6 +148,16 @@ MainWindow::MainWindow(QWidget *parent) //初始化选中主菜单第一项 m_pListView->setCurrentIndex(m_pListViewModel->index(0, 0)); + + DFeatureDisplayDialog *dlg = qApp->featureDisplayDialog(); + dlg->setLinkButtonVisible(true); + dlg->setLinkUrl("http://www.chinauos.com"); + dlg->setTitle("欢迎使用dtk"); + dlg->addItem(new DFeatureItem(QIcon::fromTheme("dialog-warning"), "按钮", "普通的文字按钮(DPushButton),带警告颜色的按钮(DWarningButton),起引导作用的按钮(DSuggestButton),工具栏按钮(DToolButton),图标按钮(DIconButton)等。", dlg)); + dlg->addItem(new DFeatureItem(QIcon::fromTheme("dialog-warning"), "提示", "悬停显示(DToolTip),提示出现有延迟,鼠标是悬停2妙左右出现,触屏是按住就出现,带尖角的popup窗口(DArrowRectangle)。", dlg)); + dlg->addItem(new DFeatureItem(QIcon::fromTheme("dialog-warning"), "对话框", "普通对话框(DDialog),用于需要用户处理事务,又不希望跳转页面以致打断工作流程时。", dlg)); + dlg->addItem(new DFeatureItem(QIcon::fromTheme("dialog-warning"), "DSpinner", "所有需要用户等待的地方,且没有具体的等待时间,不知道进度,可能很快也可能需要比较久。", dlg)); + dlg->addItem(new DFeatureItem(QIcon::fromTheme("dialog-warning"), "进度条", "进度条(DWaterProgress)一种带趣味的展示形式,作用是减少用户枯燥的等待。", dlg)); } #if 1 diff --git a/examples/dwidget-examples/collections/org.deepin.dtkwiget.feature-display.json b/examples/dwidget-examples/collections/org.deepin.dtkwiget.feature-display.json new file mode 100644 index 000000000..b544339ea --- /dev/null +++ b/examples/dwidget-examples/collections/org.deepin.dtkwiget.feature-display.json @@ -0,0 +1,16 @@ +{ + "magic": "dsg.config.override", + "version": "1.0", + "contents": { + "autoDisplayFeature": { + "value": true, + "serial": 1, + "permissions": "readwrite" + }, + "featureUpdated": { + "value": true, + "serial": 1, + "permissions": "readwrite" + } + } +} diff --git a/include/dtkwidget/DWidget/DFeatureDisplayDialog b/include/dtkwidget/DWidget/DFeatureDisplayDialog new file mode 100644 index 000000000..f3fde2f97 --- /dev/null +++ b/include/dtkwidget/DWidget/DFeatureDisplayDialog @@ -0,0 +1 @@ +#include "dfeaturedisplaydialog.h" diff --git a/include/dtkwidget/widgets/daboutdialog.h b/include/dtkwidget/widgets/daboutdialog.h index 2ef88f28d..2a5377d58 100644 --- a/include/dtkwidget/widgets/daboutdialog.h +++ b/include/dtkwidget/widgets/daboutdialog.h @@ -36,6 +36,9 @@ class DAboutDialog : public DDialog QString acknowledgementLink() const; QString license() const; +Q_SIGNALS: + void featureActivated(); + public Q_SLOTS: void setWindowTitle(const QString &windowTitle); void setProductIcon(const QIcon &icon); @@ -55,6 +58,7 @@ public Q_SLOTS: private: Q_PRIVATE_SLOT(d_func(), void _q_onLinkActivated(const QString &link)) + Q_PRIVATE_SLOT(d_func(), void _q_onFeatureActivated(const QString &link)) Q_DISABLE_COPY(DAboutDialog) D_DECLARE_PRIVATE(DAboutDialog) diff --git a/include/dtkwidget/widgets/dapplication.h b/include/dtkwidget/widgets/dapplication.h index 1456876cd..7ff4984d1 100644 --- a/include/dtkwidget/widgets/dapplication.h +++ b/include/dtkwidget/widgets/dapplication.h @@ -20,6 +20,7 @@ DWIDGET_BEGIN_NAMESPACE class DApplication; class DApplicationPrivate; class DAboutDialog; +class DFeatureDisplayDialog; class DAppHandler; #if defined(qApp) @@ -99,6 +100,9 @@ class LIBDTKWIDGETSHARED_EXPORT DApplication : public QApplication, public DTK_C DAboutDialog *aboutDialog(); void setAboutDialog(DAboutDialog *aboutDialog); + DFeatureDisplayDialog *featureDisplayDialog(); + void setFeatureDisplayDialog(DFeatureDisplayDialog *featureDisplayDialog); + bool visibleMenuShortcutText() const; void setVisibleMenuShortcutText(bool value); diff --git a/include/dtkwidget/widgets/dfeaturedisplaydialog.h b/include/dtkwidget/widgets/dfeaturedisplaydialog.h new file mode 100644 index 000000000..710e3ff42 --- /dev/null +++ b/include/dtkwidget/widgets/dfeaturedisplaydialog.h @@ -0,0 +1,60 @@ +// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#ifndef DFEATUREDISPLAYDIALOG_H +#define DFEATUREDISPLAYDIALOG_H + +#include + +class QLabel; +DWIDGET_BEGIN_NAMESPACE + +class DFeatureItemPrivate; +class DFeatureItem :public QObject, public DTK_CORE_NAMESPACE::DObject +{ + Q_OBJECT +public: + explicit DFeatureItem(const QIcon &icon = QIcon(), const QString &name = QString(), + const QString &description = QString(), QObject *parent = nullptr); + ~DFeatureItem() override; + + QIcon icon() const; + void setIcon(const QIcon &icon); + + QString name() const; + void setName(const QString &name); + + QString description() const; + void setDescription(const QString &description); + +private: + D_DECLARE_PRIVATE(DFeatureItem) +}; + +class DFeatureDisplayDialogPrivate; +class DFeatureDisplayDialog : public DDialog +{ + Q_OBJECT +public: + explicit DFeatureDisplayDialog(QWidget *parent = nullptr); + ~DFeatureDisplayDialog() override; + + void setTitle(const QString &title); + void addItem(DFeatureItem *item); + void removeItem(DFeatureItem* item); + void addItems(QList items); + void clearItems(); + void setLinkButtonVisible(bool isVisible); + void setLinkUrl(const QString &url); + void show(); + +private: + D_DECLARE_PRIVATE(DFeatureDisplayDialog) + D_PRIVATE_SLOT(void _q_toggleLinkBtn()) + +}; + +DWIDGET_END_NAMESPACE + +#endif // DFEATUREDISPLAYDIALOG_H diff --git a/include/dtkwidget/widgets/dmainwindow.h b/include/dtkwidget/widgets/dmainwindow.h index 26d25ed2c..0514ab21b 100644 --- a/include/dtkwidget/widgets/dmainwindow.h +++ b/include/dtkwidget/widgets/dmainwindow.h @@ -131,6 +131,7 @@ public Q_SLOTS: private: D_DECLARE_PRIVATE(DMainWindow) + D_PRIVATE_SLOT(void _q_autoShowFeatureDialog()) }; DWIDGET_END_NAMESPACE diff --git a/include/dtkwidget/widgets/dstyle.h b/include/dtkwidget/widgets/dstyle.h index ab3714a4e..68ebd34e0 100644 --- a/include/dtkwidget/widgets/dstyle.h +++ b/include/dtkwidget/widgets/dstyle.h @@ -224,6 +224,7 @@ class DStyle : public QCommonStyle static void setFocusRectVisible(QWidget *widget, bool visible); static void setFrameRadius(QWidget *widget, int radius); static void setUncheckedItemIndicatorVisible(QWidget *widget, bool visible); + static void setRedPointVisible(QObject *object, bool visible); DStyle(); static void drawPrimitive(const QStyle *style, DStyle::PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w = nullptr); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 253ffa944..56e7bfd4c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -13,8 +13,7 @@ set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # find_package -find_package(DtkGui 5.6 REQUIRED) -find_package(DtkCore 5.6 REQUIRED) +find_package(Dtk REQUIRED COMPONENTS Core Gui) find_package(Qt5 REQUIRED COMPONENTS Core) find_package(Qt5 REQUIRED COMPONENTS Network) @@ -110,3 +109,5 @@ install(DIRECTORY ../include/dtkwidget/global/ DESTINATION "${INCLUDE_INSTALL_DI install(DIRECTORY ../include/dtkwidget/widgets/ DESTINATION "${INCLUDE_INSTALL_DIR}" FILES_MATCHING PATTERN "*") install(FILES ${TRANSLATEDFILES} DESTINATION "${CMAKE_INSTALL_DATADIR}/libdtk-${CMAKE_PROJECT_VERSION}/DWidget/translations") + +DCONFIG_META_FILES(COMMONID org.deepin.dtkwidget FILES "./org.deepin.dtkwidget.feature-display.json") diff --git a/src/org.deepin.dtkwidget.feature-display.json b/src/org.deepin.dtkwidget.feature-display.json new file mode 100644 index 000000000..ec79b3373 --- /dev/null +++ b/src/org.deepin.dtkwidget.feature-display.json @@ -0,0 +1,26 @@ +{ + "magic": "dsg.config.meta", + "version": "1.0", + "contents": { + "featureUpdated": { + "value": false, + "serial": 0, + "flags": [], + "name": "Whether the application has new feature updates", + "name[zh_CN]": "配置应用的更新状态", + "description": "Configure the update status of the application", + "permissions": "readwrite", + "visibility": "public" + }, + "autoDisplayFeature": { + "value": false, + "serial": 0, + "flags": [], + "name": "The application automatically display new features once", + "name[zh_CN]": "配置应用是否自动展示一次新特性", + "description": "The application automatically display updated contents once", + "permissions": "readwrite", + "visibility": "public" + } + } +} diff --git a/src/widgets/daboutdialog.cpp b/src/widgets/daboutdialog.cpp index 723b62635..384de1cc6 100644 --- a/src/widgets/daboutdialog.cpp +++ b/src/widgets/daboutdialog.cpp @@ -8,6 +8,9 @@ #include #include #include +#include +#include +#include #include #include @@ -15,10 +18,10 @@ #include #include #include -#include #include -#include #include +#include +#include #ifdef Q_OS_UNIX #include @@ -30,6 +33,24 @@ DWIDGET_BEGIN_NAMESPACE const QString DAboutDialogPrivate::websiteLinkTemplate = "%2"; +DRedPointLabel::DRedPointLabel(QWidget *parent) + : QLabel(parent) +{ +} + +void DRedPointLabel::paintEvent(QPaintEvent *e) +{ + Q_UNUSED(e) + QPainter painter(this); + QRectF rcf(0, 0, 4, 4); + QPainterPath path; + path.addEllipse(rcf); + painter.setRenderHint(QPainter::Antialiasing); + painter.fillPath(path, QColor("#FF0000")); + painter.setPen(QColor(0, 0, 0, 255 * 0.05)); + painter.drawEllipse(rcf); +} + DAboutDialogPrivate::DAboutDialogPrivate(DAboutDialog *qq) : DDialogPrivate(qq) { @@ -50,9 +71,12 @@ void DAboutDialogPrivate::init() productNameLabel = new QLabel(); productNameLabel->setObjectName("ProductNameLabel"); + DFontSizeManager *fontManager = DFontSizeManager::instance(); + fontManager->bind(productNameLabel, DFontSizeManager::T5, QFont::DemiBold); versionLabel = new QLabel(); versionLabel->setObjectName("VersionLabel"); + fontManager->bind(versionLabel, DFontSizeManager::T8, QFont::DemiBold); companyLogoLabel = new QLabel(); companyLogoLabel->setPixmap(loadPixmap(logoPath)); @@ -71,9 +95,10 @@ void DAboutDialogPrivate::init() descriptionLabel = new QLabel(); descriptionLabel->setObjectName("DescriptionLabel"); - descriptionLabel->setAlignment(Qt::AlignHCenter); + descriptionLabel->setAlignment(Qt::AlignLeft); descriptionLabel->setWordWrap(true); descriptionLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + fontManager->bind(descriptionLabel, DFontSizeManager::T8, QFont::DemiBold); licenseLabel = new QLabel(); licenseLabel->setObjectName("LicenseLabel"); @@ -81,36 +106,63 @@ void DAboutDialogPrivate::init() licenseLabel->setWordWrap(true); licenseLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); licenseLabel->hide(); + fontManager->bind(licenseLabel, DFontSizeManager::T10, QFont::Medium); + + QLabel *versionTipLabel = new QLabel(QObject::tr("Version")); + fontManager->bind(versionTipLabel, DFontSizeManager::T10, QFont::Normal); + featureLabel = new QLabel(websiteLinkTemplate.arg(websiteLink).arg(QObject::tr("Features"))); + featureLabel->setContextMenuPolicy(Qt::NoContextMenu); + featureLabel->setOpenExternalLinks(false); + redPointLabel = new DRedPointLabel(); + redPointLabel->setFixedSize(10, 10); + QHBoxLayout *vFeatureLayout = new QHBoxLayout; + vFeatureLayout->setMargin(0); + vFeatureLayout->setSpacing(0); + vFeatureLayout->addWidget(featureLabel, 0, Qt::AlignLeft); + vFeatureLayout->addWidget(redPointLabel, 0, Qt::AlignLeft); + vFeatureLayout->addStretch(0); + QLabel *homePageTipLabel = new QLabel(QObject::tr("Homepage")); + fontManager->bind(homePageTipLabel, DFontSizeManager::T10, QFont::Normal); + QLabel *descriptionTipLabel = new QLabel(QObject::tr("Description")); + fontManager->bind(descriptionTipLabel, DFontSizeManager::T10, QFont::Normal); q->connect(websiteLabel, SIGNAL(linkActivated(QString)), q, SLOT(_q_onLinkActivated(QString))); + q->connect(featureLabel, SIGNAL(linkActivated(QString)), q, SLOT(_q_onFeatureActivated(QString))); q->connect(acknowledgementLabel, SIGNAL(linkActivated(QString)), q, SLOT(_q_onLinkActivated(QString))); q->connect(descriptionLabel, SIGNAL(linkActivated(QString)), q, SLOT(_q_onLinkActivated(QString))); q->connect(licenseLabel, SIGNAL(linkActivated(QString)), q, SLOT(_q_onLinkActivated(QString))); - QVBoxLayout *mainLayout = new QVBoxLayout; - mainLayout->setContentsMargins(11, 20, 11, 10); + QVBoxLayout *leftVLayout = new QVBoxLayout; + leftVLayout->setContentsMargins(30, 3, 0, 20); + leftVLayout->setSpacing(0); + leftVLayout->addWidget(logoLabel, 0, Qt::AlignCenter); + leftVLayout->addSpacing(8); + leftVLayout->addWidget(productNameLabel, 0, Qt::AlignCenter); + leftVLayout->addSpacing(31); + leftVLayout->addWidget(companyLogoLabel, 0, Qt::AlignCenter); + leftVLayout->addSpacing(3); + leftVLayout->addWidget(licenseLabel, 0, Qt::AlignHCenter); + leftVLayout->addStretch(0); + + QVBoxLayout *rightVLayout = new QVBoxLayout; + rightVLayout->setContentsMargins(0, 3, 30, 20); + rightVLayout->setSpacing(0); + rightVLayout->addWidget(versionTipLabel, 0, Qt::AlignLeft); + rightVLayout->addWidget(versionLabel, 0, Qt::AlignLeft); + rightVLayout->addLayout(vFeatureLayout); + rightVLayout->addSpacing(9); + rightVLayout->addWidget(homePageTipLabel, 0, Qt::AlignLeft); + rightVLayout->addWidget(websiteLabel, 0, Qt::AlignLeft); + rightVLayout->addSpacing(10); + rightVLayout->addWidget(descriptionTipLabel, 0, Qt::AlignLeft); + rightVLayout->addWidget(descriptionLabel, 0, Qt::AlignLeft); + rightVLayout->addStretch(0); + + QHBoxLayout *mainLayout = new QHBoxLayout; mainLayout->setSpacing(0); - mainLayout->addWidget(logoLabel); - mainLayout->setAlignment(logoLabel, Qt::AlignCenter); - mainLayout->addSpacing(3); - mainLayout->addWidget(productNameLabel); - mainLayout->setAlignment(productNameLabel, Qt::AlignCenter); - mainLayout->addSpacing(6); - mainLayout->addWidget(versionLabel); - mainLayout->setAlignment(versionLabel, Qt::AlignCenter); - mainLayout->addSpacing(8); - mainLayout->addWidget(companyLogoLabel); - mainLayout->setAlignment(companyLogoLabel, Qt::AlignCenter); -// mainLayout->addSpacing(6); - mainLayout->addWidget(websiteLabel); - mainLayout->setAlignment(websiteLabel, Qt::AlignCenter); - mainLayout->addSpacing(5); -// mainLayout->addWidget(acknowledgementLabel); -// mainLayout->setAlignment(acknowledgementLabel, Qt::AlignCenter); - mainLayout->addSpacing(12); - mainLayout->addWidget(descriptionLabel, Qt::AlignHCenter); - mainLayout->addSpacing(7); - mainLayout->addWidget(licenseLabel, Qt::AlignHCenter); + mainLayout->setMargin(0); + mainLayout->addLayout(leftVLayout); + mainLayout->addLayout(rightVLayout); QScrollArea *mainScrollArea = new QScrollArea; QWidget *mainContent = new QWidget; @@ -125,6 +177,9 @@ void DAboutDialogPrivate::init() mainContent->setLayout(mainLayout); q->addContent(mainScrollArea); + DConfig config("org.deepin.dtkwidget.feature-display"); + bool isUpdated = config.value("featureUpdated", false).toBool(); + redPointLabel->setVisible(isUpdated); // make active q->setFocus(); } @@ -154,6 +209,17 @@ void DAboutDialogPrivate::_q_onLinkActivated(const QString &link) DGUI_NAMESPACE::DGuiApplicationHelper::openUrl(link); } +void DAboutDialogPrivate::_q_onFeatureActivated(const QString &) +{ + D_Q(DAboutDialog); + DConfig config("org.deepin.dtkwidget.feature-display"); + if (config.value("featureUpdated", false).toBool()) { + config.setValue("featureUpdated", false); + redPointLabel->setVisible(false); + } + Q_EMIT q->featureActivated(); +} + QPixmap DAboutDialogPrivate::loadPixmap(const QString &file) { D_Q(DAboutDialog); @@ -334,7 +400,7 @@ void DAboutDialog::setProductIcon(const QIcon &icon) { D_D(DAboutDialog); - d->logoLabel->setPixmap(icon.pixmap(windowHandle(), QSize(96, 96))); + d->logoLabel->setPixmap(icon.pixmap(windowHandle(), QSize(128, 128))); } /*! diff --git a/src/widgets/dapplication.cpp b/src/widgets/dapplication.cpp index 0b4600ec4..1342f8a47 100644 --- a/src/widgets/dapplication.cpp +++ b/src/widgets/dapplication.cpp @@ -40,6 +40,7 @@ #include "dthememanager.h" #include "private/dapplication_p.h" #include "daboutdialog.h" +#include "dfeaturedisplaydialog.h" #include "dmainwindow.h" #include "dsizemode.h" @@ -1106,6 +1107,26 @@ void DApplication::setAboutDialog(DAboutDialog *aboutDialog) d->aboutDialog = aboutDialog; } +DFeatureDisplayDialog *DApplication::featureDisplayDialog() +{ + D_D(DApplication); + if (d->featureDisplayDialog == nullptr) { + d->featureDisplayDialog = new DFeatureDisplayDialog(activeWindow()); + } + return d->featureDisplayDialog; +} + +void DApplication::setFeatureDisplayDialog(DFeatureDisplayDialog *featureDisplayDialog) +{ + D_D(DApplication); + + if (d->featureDisplayDialog && d->featureDisplayDialog != featureDisplayDialog) { + d->featureDisplayDialog->deleteLater(); + } + + d->featureDisplayDialog = featureDisplayDialog; +} + /*! \property DApplication::visibleMenuShortcutText @@ -1391,7 +1412,9 @@ void DApplication::handleAboutAction() connect(d->aboutDialog, &DAboutDialog::destroyed, this, [=] { d->aboutDialog = nullptr; }); - + connect(d->aboutDialog, &DAboutDialog::featureActivated, this, [this] { + featureDisplayDialog()->show(); + }); if (DGuiApplicationHelper::isTabletEnvironment()) { aboutDialog->exec(); } else { diff --git a/src/widgets/dfeaturedisplaydialog.cpp b/src/widgets/dfeaturedisplaydialog.cpp new file mode 100644 index 000000000..69b082765 --- /dev/null +++ b/src/widgets/dfeaturedisplaydialog.cpp @@ -0,0 +1,332 @@ +// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#include "dfeaturedisplaydialog.h" +#include "private/dfeaturedisplaydialog_p.h" +#include "dcommandlinkbutton.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +DWIDGET_BEGIN_NAMESPACE + +static constexpr int DefaultTextLineWidth = 410; +static constexpr int DefaultIconWidth = 48; +static constexpr int DefaultIconHeight = 48; + +DFeatureItemWidget::DFeatureItemWidget(const QIcon &icon, const QString &name, + const QString &description, QWidget *parent) + : QWidget(parent) + , m_iconLabel(new QLabel) + , m_featureNameLabel(new QLabel(name)) + , m_featureDescriptionLabel(new QLabel(description)) +{ + m_featureDescriptionLabel->setWordWrap(true); + DFontSizeManager *fontManager = DFontSizeManager::instance(); + fontManager->bind(m_featureNameLabel, DFontSizeManager::T5, QFont::DemiBold); + fontManager->bind(m_featureDescriptionLabel, DFontSizeManager::T6, QFont::Medium); + + m_iconLabel->setFixedSize(DefaultIconWidth, DefaultIconHeight); + m_iconLabel->setPixmap(icon.pixmap(DefaultIconWidth, DefaultIconHeight)); + QHBoxLayout *hLayout = new QHBoxLayout(); + hLayout->setMargin(10); + hLayout->setSpacing(0); + hLayout->addWidget(m_iconLabel); + QVBoxLayout *vLayout = new QVBoxLayout(); + vLayout->setMargin(10); + vLayout->setSpacing(0); + vLayout->addStretch(0); + vLayout->addWidget(m_featureNameLabel, 0, Qt::AlignVCenter); + vLayout->addWidget(m_featureDescriptionLabel, 0, Qt::AlignVCenter); + vLayout->addStretch(0); + QHBoxLayout *mLayout = new QHBoxLayout(this); + mLayout->setMargin(0); + mLayout->setSpacing(0); + mLayout->addLayout(hLayout); + mLayout->addSpacing(2); + mLayout->addLayout(vLayout); + + setMinimumWidth(360); + auto fontMetrics = m_featureDescriptionLabel->fontMetrics(); + auto size = fontMetrics.size(Qt::TextShowMnemonic, description); + setFixedHeight(size.width() <= DefaultTextLineWidth ? 66 : 86); +} + +DFeatureItemWidget::~DFeatureItemWidget() +{ +} + +void DFeatureItemWidget::setDescriptionLabelWidth(const int width) +{ + m_featureDescriptionLabel->setFixedWidth(width); +} + +int DFeatureItemWidget::descriptionLabelWidth() +{ + auto fontMetrics = m_featureDescriptionLabel->fontMetrics(); + auto size = fontMetrics.size(Qt::TextShowMnemonic, m_featureDescriptionLabel->text()); + return size.width(); +} + +DFeatureItemPrivate::DFeatureItemPrivate(Core::DObject *qq, const QIcon &icon, + const QString &name, const QString &description) + : Core::DObjectPrivate(qq) + , m_icon(icon) + , m_name(name) + , m_description(description) +{ +} + +DFeatureItemPrivate::~DFeatureItemPrivate() +{ +} + +DFeatureItem::DFeatureItem(const QIcon &icon, const QString &name, + const QString &description, QObject *parent) + : QObject(parent) + , DObject(*new DFeatureItemPrivate(this, icon, name, description)) +{ +} + +DFeatureItem::~DFeatureItem() +{ +} + +QIcon DFeatureItem::icon() const +{ + Q_D(const DFeatureItem); + return d->m_icon; +} + +void DFeatureItem::setIcon(const QIcon &icon) +{ + Q_D(DFeatureItem); + d->m_icon = icon; +} + +QString DFeatureItem::name() const +{ + Q_D(const DFeatureItem); + return d->m_name; +} + +void DFeatureItem::setName(const QString &name) +{ + Q_D(DFeatureItem); + d->m_name = name; +} + +QString DFeatureItem::description() const +{ + Q_D(const DFeatureItem); + return d->m_description; +} + +void DFeatureItem::setDescription(const QString &description) +{ + Q_D(DFeatureItem); + d->m_description = description; +} + +DFeatureDisplayDialogPrivate::DFeatureDisplayDialogPrivate(DFeatureDisplayDialog *qq) + : DDialogPrivate(qq) +{ +} + +void DFeatureDisplayDialogPrivate::init() +{ + Q_Q(DFeatureDisplayDialog); + q->setMinimumSize(660, 620); + q->setMaximumHeight(720); + q->setWindowFlags(q->windowFlags() | Qt::CustomizeWindowHint); + q->addButton(QObject::tr("Continue"), true, DDialog::ButtonRecommend); + q->getButton(0)->setFixedSize(256, 36); + q->setModal(true); + + m_title = new QLabel; + DFontSizeManager *fontManager = DFontSizeManager::instance(); + fontManager->bind(m_title, DFontSizeManager::T2, QFont::DemiBold); + + QWidget *itemWidget = new QWidget; + itemWidget->setMinimumSize(360, 66); + itemWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_vBoxLayout = new QVBoxLayout(itemWidget); + m_vBoxLayout->setMargin(0); + m_vBoxLayout->setSpacing(12); + QScrollArea *scrollWidget = new QScrollArea; + scrollWidget->setWidget(itemWidget); + scrollWidget->setWidgetResizable(true); + scrollWidget->setMaximumHeight(490); + scrollWidget->setAutoFillBackground(false); + scrollWidget->setFrameShape(QFrame::NoFrame); + QPalette pt = scrollWidget->palette(); + pt.setBrush(QPalette::Window, Qt::transparent); + scrollWidget->setPalette(pt); + + m_linkBtn = new DCommandLinkButton(QObject::tr("Learn More") + " >"); + m_linkBtn->setVisible(false); + + QWidget *contentWidget = new QWidget; + QVBoxLayout *vContentLayout = new QVBoxLayout(contentWidget); + vContentLayout->setContentsMargins(150, 0, 150, 0); + vContentLayout->setSpacing(0); + vContentLayout->addWidget(m_title, 0, Qt::AlignCenter); + vContentLayout->addSpacing(30); + vContentLayout->addWidget(scrollWidget); + vContentLayout->addWidget(m_linkBtn); + vContentLayout->addStretch(0); + vContentLayout->setSizeConstraint(QLayout::SetFixedSize); + + q->insertContent(0, contentWidget, Qt::AlignTop | Qt::AlignHCenter); +} + +void DFeatureDisplayDialogPrivate::addFeatureItem(const QIcon &icon, const QString &name, const QString &description) +{ + m_vBoxLayout->addWidget(new DFeatureItemWidget(icon, name, description)); +} + +int DFeatureDisplayDialogPrivate::getDescriptionMaxWidth() +{ + int maxWidth = 0; + for (int i = 0; i < m_vBoxLayout->count(); ++i) { + QWidget* widget = m_vBoxLayout->itemAt(i)->widget(); + if (widget == nullptr) + continue; + DFeatureItemWidget* w = qobject_cast(widget); + if (w == nullptr) + continue; + maxWidth = maxWidth > w->descriptionLabelWidth() ? maxWidth : w->descriptionLabelWidth(); + } + return maxWidth; +} + +void DFeatureDisplayDialogPrivate::updateItemWidth() +{ + int maxWidth = getDescriptionMaxWidth(); + if (maxWidth > DefaultTextLineWidth) { + maxWidth = (maxWidth / 2 < DefaultTextLineWidth) ? DefaultTextLineWidth: qCeil(maxWidth / 2.0); + } + for (int i = 0; i < m_vBoxLayout->count(); ++i) { + QWidget* widget = m_vBoxLayout->itemAt(i)->widget(); + if (widget == nullptr) + continue; + DFeatureItemWidget* w = qobject_cast(widget); + if (w == nullptr) + continue; + w->setDescriptionLabelWidth(maxWidth); + } +} + +void DFeatureDisplayDialogPrivate::createWidgetItems() +{ + clearLayout(); + for (auto item : m_featureItems) { + if (item == nullptr) + continue; + addFeatureItem(item->icon(), item->name(), item->description()); + } +} + +void DFeatureDisplayDialogPrivate::deleteItems() +{ + for (auto item : m_featureItems) { + if (item) + item->deleteLater(); + } + m_featureItems.clear(); +} + +void DFeatureDisplayDialogPrivate::clearLayout() +{ + QLayoutItem *item; + while((item = m_vBoxLayout->takeAt(0))) { + if (item->widget()) { + delete item->widget(); + } + delete item; + } +} + +void DFeatureDisplayDialogPrivate::_q_toggleLinkBtn() +{ + DGuiApplicationHelper::openUrl(m_linkUrl); +} + +DFeatureDisplayDialog::DFeatureDisplayDialog(QWidget *parent) + : DDialog(*new DFeatureDisplayDialogPrivate(this), parent) +{ + Q_D(DFeatureDisplayDialog); + d->init(); +} + +DFeatureDisplayDialog::~DFeatureDisplayDialog() +{ + D_D(DFeatureDisplayDialog); + d->deleteItems(); +} + +void DFeatureDisplayDialog::setTitle(const QString &title) +{ + Q_D(DFeatureDisplayDialog); + d->m_title->setText(title); +} + +void DFeatureDisplayDialog::addItem(DFeatureItem *item) +{ + Q_D(DFeatureDisplayDialog); + d->m_featureItems.append(item); +} + +void DFeatureDisplayDialog::removeItem(DFeatureItem *item) +{ + Q_D(DFeatureDisplayDialog); + d->m_featureItems.removeOne(item); +} + +void DFeatureDisplayDialog::addItems(QList items) +{ + Q_D(DFeatureDisplayDialog); + for (auto item : items) { + d->m_featureItems.append(item); + } +} + +void DFeatureDisplayDialog::clearItems() +{ + Q_D(DFeatureDisplayDialog); + d->deleteItems(); +} + +void DFeatureDisplayDialog::setLinkButtonVisible(bool isVisible) +{ + Q_D(DFeatureDisplayDialog); + d->m_linkBtn->setVisible(isVisible); + if (isVisible) { + connect(d->m_linkBtn, SIGNAL(clicked()), this, SLOT(_q_toggleLinkBtn()), Qt::UniqueConnection); + } +} + +void DFeatureDisplayDialog::setLinkUrl(const QString &url) +{ + Q_D(DFeatureDisplayDialog); + d->m_linkUrl = url; +} + +void DFeatureDisplayDialog::show() +{ + Q_D(DFeatureDisplayDialog); + d->createWidgetItems(); + d->updateItemWidth(); + DDialog::show(); +} + +DWIDGET_END_NAMESPACE +#include "moc_dfeaturedisplaydialog.cpp" diff --git a/src/widgets/diconbutton.cpp b/src/widgets/diconbutton.cpp index c7220acf7..621dfdd6a 100644 --- a/src/widgets/diconbutton.cpp +++ b/src/widgets/diconbutton.cpp @@ -274,7 +274,7 @@ void DIconButton::keyPressEvent(QKeyEvent *event) */ void DIconButton::setNewNotification(const bool set_new) { - this->setProperty("_d_dtk_newNotification", set_new); + DStyle::setRedPointVisible(this, set_new); } void DIconButton::paintEvent(QPaintEvent *event) diff --git a/src/widgets/dmainwindow.cpp b/src/widgets/dmainwindow.cpp index c6ae016d9..536c616d2 100644 --- a/src/widgets/dmainwindow.cpp +++ b/src/widgets/dmainwindow.cpp @@ -9,7 +9,7 @@ #include "dmessagemanager.h" #include "DBlurEffectWidget" #include "dsizemode.h" - +#include "dfeaturedisplaydialog.h" #include "private/dmainwindow_p.h" #include "private/dapplication_p.h" @@ -21,6 +21,9 @@ #include #include #include +#include + +#include #ifdef Q_OS_MAC #include "osxwindow.h" @@ -131,6 +134,24 @@ void DMainWindowPrivate::updateTitleShadowGeometry() titleShadow->raise(); } +void DMainWindowPrivate::_q_autoShowFeatureDialog() +{ + D_QC(DMainWindow); + if (q->windowHandle()->isActive()) { + qApp->featureDisplayDialog()->show(); + const QPoint pos = q->pos(); + QRect rect; + for (QScreen *screen : qApp->screens()) { + if (screen->geometry().contains(pos)) { + rect = screen->geometry(); + break; + } + } + qApp->featureDisplayDialog()->moveToCenterByRect(rect); + q->disconnect(q->windowHandle(), SIGNAL(activeChanged()), q, SLOT(_q_autoShowFeatureDialog())); + } +} + /*! \class Dtk::Widget::DMainWindow \inmodule dtkwidget @@ -158,6 +179,12 @@ DMainWindow::DMainWindow(QWidget *parent) if (DGuiApplicationHelper::isTabletEnvironment()) { setWindowFlags(windowFlags() & ~(Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint)); } + DConfig config("org.deepin.dtkwidget.feature-display"); + bool isAutoDisplayFeature = config.value("autoDisplayFeature", false).toBool(); + if (isAutoDisplayFeature) { + connect(this->windowHandle(), SIGNAL(activeChanged()), this, SLOT(_q_autoShowFeatureDialog())); + config.setValue("autoDisplayFeature", false); + } } /*! @@ -796,3 +823,5 @@ void DMainWindow::changeEvent(QEvent *event) } DWIDGET_END_NAMESPACE + +#include "moc_dmainwindow.cpp" diff --git a/src/widgets/dstyle.cpp b/src/widgets/dstyle.cpp index a1bea649a..8b96b081e 100644 --- a/src/widgets/dstyle.cpp +++ b/src/widgets/dstyle.cpp @@ -158,6 +158,11 @@ void DStyle::setUncheckedItemIndicatorVisible(QWidget *widget, bool visible) widget->setProperty("_d_dtk_UncheckedItemIndicator", visible); } +void DStyle::setRedPointVisible(QObject *object, bool visible) +{ + object->setProperty("_d_menu_item_redpoint", visible); +} + namespace DDrawUtils { static QImage dropShadow(const QPixmap &px, qreal radius, const QColor &color) { @@ -1348,7 +1353,7 @@ void DStyle::drawControl(const QStyle *style, DStyle::ControlElement ce, const Q } // 有新信息时添加小红点 - if (w && w->property("_d_dtk_newNotification").toBool()){ + if (w && w->property("_d_menu_item_redpoint").toBool()){ DPalette pa = DGuiApplicationHelper::instance()->standardPalette(DGuiApplicationHelper::LightType); // 按图标大小50x50时,小红点大小6x6,距离右边和上面8个像素的比例绘制 const int redPointRadius = 3; diff --git a/src/widgets/dtitlebar.cpp b/src/widgets/dtitlebar.cpp index 9be14f71f..61ae8a693 100644 --- a/src/widgets/dtitlebar.cpp +++ b/src/widgets/dtitlebar.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -195,6 +196,10 @@ void DTitlebarPrivate::init() optionButton = new DWindowOptionButton; } + auto config = new DConfig("org.deepin.dtkwidget.feature-display", "", q); + bool isUpdated = config->value("featureUpdated", false).toBool(); + DStyle::setRedPointVisible(optionButton, isUpdated); + separatorTop = new DHorizontalLine(q); separator = new DHorizontalLine(q); titleLabel = centerArea; @@ -305,6 +310,16 @@ void DTitlebarPrivate::init() if (splitWidget && splitWidget->isVisible()) splitWidget->isMaxButtonPressAndHold = true; }); + if (isUpdated) { + q->connect(config, &DConfig::valueChanged, q, [config, this](const QString &key){ + if (key == "featureUpdated") { + auto result = config->value("featureUpdated", false); + DStyle::setRedPointVisible(optionButton, result.toBool()); + optionButton->update(); + config->deleteLater(); + } + }); + } // 默认需要构造一个空的选项菜单 q->setMenu(new QMenu(q)); @@ -924,6 +939,10 @@ void DTitlebar::showMenu() action->setChecked(true); } + DConfig config("org.deepin.dtkwidget.feature-display"); + bool isUpdated = config.value("featureUpdated", false).toBool(); + DStyle::setRedPointVisible(d->aboutAction, isUpdated); + d->menu->exec(d->optionButton->mapToGlobal(d->optionButton->rect().bottomLeft())); d->optionButton->update(); // FIX: bug-25253 sometimes optionButton not udpate after menu exec(but why?) } diff --git a/src/widgets/private/daboutdialog_p.h b/src/widgets/private/daboutdialog_p.h index 748095e1c..db907a69c 100644 --- a/src/widgets/private/daboutdialog_p.h +++ b/src/widgets/private/daboutdialog_p.h @@ -6,10 +6,20 @@ #define DABOUTDIALOG_P_H #include +#include + #include "ddialog_p.h" DWIDGET_BEGIN_NAMESPACE +class DRedPointLabel : public QLabel +{ +public: + DRedPointLabel(QWidget *parent = nullptr); +protected: + void paintEvent(QPaintEvent *e) override; +}; + class DAboutDialogPrivate : public DDialogPrivate { public: @@ -20,6 +30,8 @@ class DAboutDialogPrivate : public DDialogPrivate void updateWebsiteLabel(); void updateAcknowledgementLabel(); void _q_onLinkActivated(const QString &link); + void _q_onFeatureActivated(const QString &link); + QPixmap loadPixmap(const QString &file); static const QString websiteLinkTemplate; @@ -33,12 +45,12 @@ class DAboutDialogPrivate : public DDialogPrivate QLabel *companyLogoLabel = nullptr; QLabel *websiteLabel = nullptr; QLabel *acknowledgementLabel = nullptr; - + QLabel *featureLabel = nullptr; + DRedPointLabel *redPointLabel = nullptr; QString logoPath; QString websiteName; QString websiteLink; QString acknowledgementLink; - Q_DECLARE_PUBLIC(DAboutDialog) }; diff --git a/src/widgets/private/dapplication_p.h b/src/widgets/private/dapplication_p.h index c986ebe54..73aa75125 100644 --- a/src/widgets/private/dapplication_p.h +++ b/src/widgets/private/dapplication_p.h @@ -21,6 +21,7 @@ DCORE_USE_NAMESPACE DWIDGET_BEGIN_NAMESPACE class DAboutDialog; +class DFeatureDisplayDialog; class DApplicationPrivate : public DObjectPrivate { @@ -72,6 +73,7 @@ class DApplicationPrivate : public DObjectPrivate DAppHandler *appHandler = Q_NULLPTR; DAboutDialog *aboutDialog = Q_NULLPTR; + DFeatureDisplayDialog *featureDisplayDialog = Q_NULLPTR; // 需要自适应虚拟键盘环境的窗口 QPointer activeInputWindow; diff --git a/src/widgets/private/dfeaturedisplaydialog_p.h b/src/widgets/private/dfeaturedisplaydialog_p.h new file mode 100644 index 000000000..b1f83cbe3 --- /dev/null +++ b/src/widgets/private/dfeaturedisplaydialog_p.h @@ -0,0 +1,71 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#ifndef DFEATUREDISPLAYDIALOG_P_H +#define DFEATUREDISPLAYDIALOG_P_H + +#include "dfeaturedisplaydialog.h" +#include "ddialog_p.h" + +DWIDGET_BEGIN_NAMESPACE +class DCommandLinkButton; + +class DFeatureItemWidget : public QWidget +{ + Q_OBJECT +public: + explicit DFeatureItemWidget(const QIcon &icon = QIcon(), const QString &name = QString(), const QString &description = QString(), QWidget *parent = nullptr); + virtual ~DFeatureItemWidget() override; + + void setDescriptionLabelWidth(const int width); + int descriptionLabelWidth(); + +private: + QLabel *m_iconLabel = nullptr; + QLabel *m_featureNameLabel = nullptr; + QLabel *m_featureDescriptionLabel = nullptr; +}; + +class DFeatureItemPrivate: public Core::DObjectPrivate +{ +public: + explicit DFeatureItemPrivate(Core::DObject *qq, const QIcon &icon, + const QString &name = QString(), const QString &description = QString()); + ~DFeatureItemPrivate() override; + + QIcon m_icon; + QString m_name; + QString m_description; +}; + +class DFeatureDisplayDialogPrivate : public DDialogPrivate +{ +protected: + explicit DFeatureDisplayDialogPrivate(DFeatureDisplayDialog *qq); + +private: + void init(); + void addFeatureItem(const QIcon &icon, const QString &name, const QString &description); + int getDescriptionMaxWidth(); + void updateItemWidth(); + void createWidgetItems(); + void deleteItems(); + void clearLayout(); + +private: + QLabel *m_title = nullptr; + QVBoxLayout *m_vBoxLayout = nullptr; + DCommandLinkButton *m_linkBtn = nullptr; + QString m_linkUrl; + QList> m_featureItems; + + Q_DECLARE_PUBLIC(DFeatureDisplayDialog) + +private: + void _q_toggleLinkBtn(); +}; + +DWIDGET_END_NAMESPACE + +#endif // DFEATUREDISPLAYDIALOG_P_H diff --git a/src/widgets/private/dmainwindow_p.h b/src/widgets/private/dmainwindow_p.h index 11b43a1c7..e7ecb26fe 100644 --- a/src/widgets/private/dmainwindow_p.h +++ b/src/widgets/private/dmainwindow_p.h @@ -116,6 +116,7 @@ class DMainWindowPrivate : public DTK_CORE_NAMESPACE::DObjectPrivate private: D_DECLARE_PUBLIC(DMainWindow) + void _q_autoShowFeatureDialog(); }; DWIDGET_END_NAMESPACE diff --git a/tests/src/widgets/ut_diconbutton.cpp b/tests/src/widgets/ut_diconbutton.cpp index 6d11dcfe8..f17fc5b7e 100644 --- a/tests/src/widgets/ut_diconbutton.cpp +++ b/tests/src/widgets/ut_diconbutton.cpp @@ -48,5 +48,5 @@ TEST_F(ut_IConButton, testIConButton) ASSERT_TRUE(button->enabledCircle()); button->setNewNotification(true); - ASSERT_TRUE(button->property("_d_dtk_newNotification").toBool()); + ASSERT_TRUE(button->property("_d_menu_item_redpoint").toBool()); } diff --git a/tests/testcases/widgets/ut_diconbutton.cpp b/tests/testcases/widgets/ut_diconbutton.cpp index ebf7d9dc9..8bf3b4847 100644 --- a/tests/testcases/widgets/ut_diconbutton.cpp +++ b/tests/testcases/widgets/ut_diconbutton.cpp @@ -48,7 +48,7 @@ TEST_F(ut_IConButton, testIConButton) ASSERT_TRUE(button->enabledCircle()); button->setNewNotification(true); - ASSERT_TRUE(button->property("_d_dtk_newNotification").toBool()); + ASSERT_TRUE(button->property("_d_menu_item_redpoint").toBool()); button->setFlat(true); ASSERT_TRUE(button->isFlat());