diff --git a/package/components/TextColorPicker.qml b/package/components/TextColorPicker.qml new file mode 100644 index 0000000..8aa78cc --- /dev/null +++ b/package/components/TextColorPicker.qml @@ -0,0 +1,118 @@ +// SPDX-FileCopyrightText: 2024 MyCompany +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +// 字体颜色选择器:用于设置窗口,提供预设色板与"跟随系统"选项 +// 设计要点:白色圆角卡片与设置窗口其他分区视觉一致;圆形色块 22x22, +// 当前选中色加 2px 深色边框高亮;点击只发射 colorSelected 信号, +// 由父层(networkview.qml)回写 currentColor 并同步到 C++ 后端持久化 +// 属性语义: +// currentColor - 当前选中颜色字符串,空串表示"跟随系统"(默认) +// colorSelected(string) - 用户点击色块时发射,参数为空串或 #RRGGBB +import QtQuick 2.15 +import QtQuick.Layouts 1.15 + +Rectangle { + id: root + + // 当前选中颜色:空串=跟随系统,用于显示选中态高亮 + property string currentColor: "" + + // 用户点击色块时发射,父层据此回写 currentColor 并持久化 + signal colorSelected(string color) + + // 预设色板:8 个常用色,覆盖白/黑/暖/冷,克制实用 + property var presetColors: [ + "#FFFFFF", "#000000", "#DC2626", "#F59E0B", + "#16A34A", "#1450A0", "#7C3AED", "#0891B2" + ] + + Layout.fillWidth: true + Layout.preferredHeight: 52 + color: "#ffffff" + radius: 10 + border.width: 1 + border.color: "#e0e0e0" + + RowLayout { + anchors.fill: parent + anchors.margins: 12 + spacing: 8 + + // 预设色块 + Repeater { + model: root.presetColors + delegate: Rectangle { + width: 26 + height: 26 + radius: 13 + color: "transparent" + // 当前选中态:2px 深色边框 + border.width: root.currentColor === modelData ? 2 : 0 + border.color: "#333333" + + Rectangle { + anchors.centerIn: parent + width: 22 + height: 22 + radius: 11 + // 白色色块在白卡上需细边框可见 + color: modelData + border.width: modelData === "#FFFFFF" ? 1 : 0 + border.color: "#e0e0e0" + } + + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onClicked: root.colorSelected(modelData) + } + } + } + + // 跟随系统选项:斜线色块表示恢复默认 + Rectangle { + width: 26 + height: 26 + radius: 13 + color: "transparent" + // currentColor 为空串时高亮(跟随系统选中态) + border.width: root.currentColor === "" ? 2 : 0 + border.color: "#333333" + + Rectangle { + anchors.centerIn: parent + width: 22 + height: 22 + radius: 11 + color: "#f5f5f5" + border.width: 1 + border.color: "#e0e0e0" + + // 斜线:表示"无自定义色/跟随系统" + Canvas { + anchors.fill: parent + onPaint: { + var ctx = getContext("2d") + ctx.reset() + ctx.strokeStyle = "#999999" + ctx.lineWidth = 2 + ctx.beginPath() + ctx.moveTo(2, height - 2) + ctx.lineTo(width - 2, 2) + ctx.stroke() + } + } + } + + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onClicked: root.colorSelected("") + } + } + + // 弹性空间,让色块左对齐 + Item { Layout.fillWidth: true } + } +} diff --git a/package/networkview.qml b/package/networkview.qml index 4ff2ec7..f892478 100644 --- a/package/networkview.qml +++ b/package/networkview.qml @@ -135,6 +135,11 @@ AppletItem { // 上传值颜色:固定绿色,不做高速警示 readonly property color uploadValueColor: accentGreen + // 任务栏网速数值字体色:用户自定义色优先(持久化),未设置时跟随系统主题 + // 设计原因:primaryText 派生自 DockPalette,深浅色任务栏自动适配; + // 用户主动选色后覆盖,空串回退到 primaryText 保持自适应 + readonly property color speedTextColor: (applet && applet.textColor.length > 0) ? applet.textColor : primaryText + // 任务栏图标区:双行紧凑数值,箭头与数值紧贴、左对齐 // 设计原因:箭头与数值作为一组固定在左侧,数值左对齐紧贴箭头; // 不给每行固定高度,让 RowLayout 按内容自然高度排列, @@ -161,7 +166,7 @@ AppletItem { text: root.formatSpeedShort(root.downloadSpeed) font.pixelSize: root.dockSize * 0.25 font.weight: Font.Medium - color: root.primaryText + color: root.speedTextColor Layout.alignment: Qt.AlignVCenter horizontalAlignment: Text.AlignLeft } @@ -182,7 +187,7 @@ AppletItem { text: root.formatSpeedShort(root.uploadSpeed) font.pixelSize: root.dockSize * 0.25 font.weight: Font.Medium - color: root.primaryText + color: root.speedTextColor Layout.alignment: Qt.AlignVCenter horizontalAlignment: Text.AlignLeft } @@ -220,7 +225,7 @@ AppletItem { font.pixelSize: root.dockSize * 0.25 height: font.pixelSize font.weight: Font.Medium - color: root.primaryText + color: root.speedTextColor anchors.horizontalCenter: parent.horizontalCenter } } @@ -245,7 +250,7 @@ AppletItem { font.pixelSize: root.dockSize * 0.25 height: font.pixelSize font.weight: Font.Medium - color: root.primaryText + color: root.speedTextColor anchors.horizontalCenter: parent.horizontalCenter } } @@ -706,7 +711,7 @@ AppletItem { Window { id: settingsWindow width: 340 - height: 350 + height: 450 visible: false flags: Qt.FramelessWindowHint | Qt.Window // NonModal:不阻塞桌面其他区域,用户可同时操作任务栏 @@ -861,6 +866,22 @@ AppletItem { } } + // 字体颜色选择区:预设色板 + 跟随系统选项 + // 设计原因:用户选择的颜色通过 applet.textColor 持久化到 + // ~/.config/jnetapplet/settings.ini,重启 dde-shell 后仍生效 + Text { + text: qsTr("字体颜色") + font.pixelSize: 13 + font.weight: Font.Bold + color: "#666666" + } + + TextColorPicker { + Layout.fillWidth: true + currentColor: root.applet ? root.applet.textColor : "" + onColorSelected: if (root.applet) root.applet.textColor = color + } + Item { Layout.fillHeight: true } // 卸载插件按钮:文字可动态切换(复制命令后显示提示) diff --git a/src/networkmonitorapplet.cpp b/src/networkmonitorapplet.cpp index 4a135fa..65a34b6 100644 --- a/src/networkmonitorapplet.cpp +++ b/src/networkmonitorapplet.cpp @@ -11,6 +11,9 @@ #include #include #include +#include +#include +#include DS_BEGIN_NAMESPACE @@ -25,7 +28,22 @@ NetworkMonitorApplet::NetworkMonitorApplet(QObject *parent) , m_totalUpload(0) , m_ready(false) , m_firstUpdate(true) + , m_textColor() { + // 从独立配置文件读取持久化的字体颜色 + // 设计原因:使用独立配置文件避免污染 dde-shell 的共享配置, + // 空串表示"跟随系统",由 QML 层回退到 primaryText 实现 + const QString configPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + + QStringLiteral("/jnetapplet/settings.ini"); + QSettings settings(configPath, QSettings::IniFormat); + if (settings.contains(QStringLiteral("textColor"))) { + const QString saved = settings.value(QStringLiteral("textColor")).toString(); + // 空串合法(跟随系统),非空则校验是否为合法颜色值 + if (saved.isEmpty() || QColor::isValidColorName(saved)) { + m_textColor = saved; + } + // 若校验失败则保持空串默认值(跟随系统),不抛出也不记录 + } } NetworkMonitorApplet::~NetworkMonitorApplet() @@ -127,6 +145,42 @@ QString NetworkMonitorApplet::version() const return pluginMetaData().value("Version").toString(); } +// 返回任务栏网速字体颜色,空串表示跟随系统主题 +QString NetworkMonitorApplet::textColor() const +{ + return m_textColor; +} + +// 设置任务栏网速字体颜色,空串表示跟随系统主题 +// 设计原因: +// - 空串语义:空串作为"跟随系统"的语义值,QML 层用 textColor ? textColor : primaryText 做回退, +// 避免后端硬编码系统色 +// - 校验逻辑:非空颜色值通过 QColor::isValidColor 校验,无效值直接忽略,不存储不发射信号 +// - 独立配置文件:使用 ~/.config/jnetapplet/settings.ini 而非 dde-shell 共享配置, +// 避免污染其他组件的配置空间 +void NetworkMonitorApplet::setTextColor(const QString &color) +{ + // 空串视为合法(表示跟随系统),不校验 + if (!color.isEmpty() && !QColor::isValidColorName(color)) { + return; + } + + if (m_textColor == color) { + return; + } + + m_textColor = color; + + // 持久化到独立配置文件 + const QString configPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + + QStringLiteral("/jnetapplet/settings.ini"); + QSettings settings(configPath, QSettings::IniFormat); + settings.setValue(QStringLiteral("textColor"), m_textColor); + settings.sync(); + + emit textColorChanged(); +} + // 返回当前活动接口的下行速度历史,转换为 QVariantList of QPointF 供 QML 使用 // 设计原因:QPointF 仅携带 x/y 两个值,上传与下载分别对应两个列表 QVariantList NetworkMonitorApplet::speedHistoryDownload() const diff --git a/src/networkmonitorapplet.h b/src/networkmonitorapplet.h index c4a96c9..210d380 100644 --- a/src/networkmonitorapplet.h +++ b/src/networkmonitorapplet.h @@ -14,6 +14,8 @@ #include #include #include +#include +#include DS_BEGIN_NAMESPACE @@ -56,6 +58,9 @@ class NetworkMonitorApplet : public DApplet Q_PROPERTY(QString ipv6Address READ ipv6Address NOTIFY ipv6AddressChanged) // 插件版本号,从 dde-shell 元数据读取,版本唯一源为 CMakeLists.txt project(VERSION) Q_PROPERTY(QString version READ version CONSTANT) + // 任务栏网速数值字体颜色,空串表示跟随系统主题(由 QML 回退到 primaryText), + // 用户在设置窗口选择后持久化到 ~/.config/jnetapplet/settings.ini + Q_PROPERTY(QString textColor READ textColor WRITE setTextColor NOTIFY textColorChanged) // 当前活动接口的下行速度历史采样点(QPointF 列表:x=时间戳秒, y=速度 bytes/sec) // 用于趋势图绘制下载折线,每次 calculateSpeed 追加一个点并发射 speedHistoryChanged Q_PROPERTY(QVariantList speedHistoryDownload READ speedHistoryDownload NOTIFY speedHistoryChanged) @@ -85,6 +90,10 @@ public: QVariantList speedHistoryUpload() const; // 返回插件版本号,从 dde-shell 插件元数据(metadata.json)读取 QString version() const; + // 返回任务栏网速字体颜色,空串表示跟随系统主题 + QString textColor() const; + // 设置任务栏网速字体颜色,空串表示跟随系统主题 + void setTextColor(const QString &color); Q_INVOKABLE void refresh(); Q_INVOKABLE void setActiveInterface(const QString &interface); @@ -99,6 +108,8 @@ signals: void ipAddressChanged(); void ipv6AddressChanged(); void speedHistoryChanged(); + // 任务栏网速字体颜色变化时通知 QML 更新 + void textColorChanged(); private: void readNetworkStats(); @@ -131,6 +142,10 @@ private: bool m_ready; bool m_firstUpdate; + // 任务栏网速字体颜色,空串表示跟随系统主题 + // 设计原因:空串作为"跟随系统"的语义值,QML 层用 textColor ? textColor : primaryText + // 做回退,避免后端硬编码系统色 + QString m_textColor; // 速度历史环形缓冲:每个接口独立维护一份,key 为接口名 // 设计原因:接口切换时趋势图不出现跳变,切回时仍能看到该接口历史