feat: 设置窗口新增字体颜色选择,任务栏网速数值色可自定义并持久化
- 新增 TextColorPicker.qml 颜色选择器组件:预设 8 色 + 跟随系统选项, 2px 深色边框高亮选中态,白色圆角卡片与设置窗口其他区视觉一致 - C++ 后端新增 textColor Q_PROPERTY:QString 存储,空串=跟随系统主题, 非空用 QColor 校验,写入 ~/.config/jnetapplet/settings.ini 持久化 - networkview.qml 新增 speedTextColor 属性回退逻辑:applet.textColor 优先,空串时回退到 DockPalette 派生的 primaryText(深浅色自适应) - 任务栏 4 处数值 Text(横向/竖向 × 下载/上传)color 绑定改为 speedTextColor;设置窗口网络接口区下方新增字体颜色选择区
This commit is contained in:
@@ -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 }
|
||||||
|
}
|
||||||
|
}
|
||||||
+26
-5
@@ -135,6 +135,11 @@ AppletItem {
|
|||||||
// 上传值颜色:固定绿色,不做高速警示
|
// 上传值颜色:固定绿色,不做高速警示
|
||||||
readonly property color uploadValueColor: accentGreen
|
readonly property color uploadValueColor: accentGreen
|
||||||
|
|
||||||
|
// 任务栏网速数值字体色:用户自定义色优先(持久化),未设置时跟随系统主题
|
||||||
|
// 设计原因:primaryText 派生自 DockPalette,深浅色任务栏自动适配;
|
||||||
|
// 用户主动选色后覆盖,空串回退到 primaryText 保持自适应
|
||||||
|
readonly property color speedTextColor: (applet && applet.textColor.length > 0) ? applet.textColor : primaryText
|
||||||
|
|
||||||
// 任务栏图标区:双行紧凑数值,箭头与数值紧贴、左对齐
|
// 任务栏图标区:双行紧凑数值,箭头与数值紧贴、左对齐
|
||||||
// 设计原因:箭头与数值作为一组固定在左侧,数值左对齐紧贴箭头;
|
// 设计原因:箭头与数值作为一组固定在左侧,数值左对齐紧贴箭头;
|
||||||
// 不给每行固定高度,让 RowLayout 按内容自然高度排列,
|
// 不给每行固定高度,让 RowLayout 按内容自然高度排列,
|
||||||
@@ -161,7 +166,7 @@ AppletItem {
|
|||||||
text: root.formatSpeedShort(root.downloadSpeed)
|
text: root.formatSpeedShort(root.downloadSpeed)
|
||||||
font.pixelSize: root.dockSize * 0.25
|
font.pixelSize: root.dockSize * 0.25
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
color: root.primaryText
|
color: root.speedTextColor
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
horizontalAlignment: Text.AlignLeft
|
horizontalAlignment: Text.AlignLeft
|
||||||
}
|
}
|
||||||
@@ -182,7 +187,7 @@ AppletItem {
|
|||||||
text: root.formatSpeedShort(root.uploadSpeed)
|
text: root.formatSpeedShort(root.uploadSpeed)
|
||||||
font.pixelSize: root.dockSize * 0.25
|
font.pixelSize: root.dockSize * 0.25
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
color: root.primaryText
|
color: root.speedTextColor
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
horizontalAlignment: Text.AlignLeft
|
horizontalAlignment: Text.AlignLeft
|
||||||
}
|
}
|
||||||
@@ -220,7 +225,7 @@ AppletItem {
|
|||||||
font.pixelSize: root.dockSize * 0.25
|
font.pixelSize: root.dockSize * 0.25
|
||||||
height: font.pixelSize
|
height: font.pixelSize
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
color: root.primaryText
|
color: root.speedTextColor
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -245,7 +250,7 @@ AppletItem {
|
|||||||
font.pixelSize: root.dockSize * 0.25
|
font.pixelSize: root.dockSize * 0.25
|
||||||
height: font.pixelSize
|
height: font.pixelSize
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
color: root.primaryText
|
color: root.speedTextColor
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -706,7 +711,7 @@ AppletItem {
|
|||||||
Window {
|
Window {
|
||||||
id: settingsWindow
|
id: settingsWindow
|
||||||
width: 340
|
width: 340
|
||||||
height: 350
|
height: 450
|
||||||
visible: false
|
visible: false
|
||||||
flags: Qt.FramelessWindowHint | Qt.Window
|
flags: Qt.FramelessWindowHint | Qt.Window
|
||||||
// NonModal:不阻塞桌面其他区域,用户可同时操作任务栏
|
// 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 }
|
Item { Layout.fillHeight: true }
|
||||||
|
|
||||||
// 卸载插件按钮:文字可动态切换(复制命令后显示提示)
|
// 卸载插件按钮:文字可动态切换(复制命令后显示提示)
|
||||||
|
|||||||
@@ -11,6 +11,9 @@
|
|||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <QNetworkInterface>
|
#include <QNetworkInterface>
|
||||||
|
#include <QColor>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
|
||||||
DS_BEGIN_NAMESPACE
|
DS_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@@ -25,7 +28,22 @@ NetworkMonitorApplet::NetworkMonitorApplet(QObject *parent)
|
|||||||
, m_totalUpload(0)
|
, m_totalUpload(0)
|
||||||
, m_ready(false)
|
, m_ready(false)
|
||||||
, m_firstUpdate(true)
|
, 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()
|
NetworkMonitorApplet::~NetworkMonitorApplet()
|
||||||
@@ -127,6 +145,42 @@ QString NetworkMonitorApplet::version() const
|
|||||||
return pluginMetaData().value("Version").toString();
|
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 使用
|
// 返回当前活动接口的下行速度历史,转换为 QVariantList of QPointF 供 QML 使用
|
||||||
// 设计原因:QPointF 仅携带 x/y 两个值,上传与下载分别对应两个列表
|
// 设计原因:QPointF 仅携带 x/y 两个值,上传与下载分别对应两个列表
|
||||||
QVariantList NetworkMonitorApplet::speedHistoryDownload() const
|
QVariantList NetworkMonitorApplet::speedHistoryDownload() const
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QPointF>
|
#include <QPointF>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
#include <QColor>
|
||||||
|
#include <QSettings>
|
||||||
|
|
||||||
DS_BEGIN_NAMESPACE
|
DS_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@@ -56,6 +58,9 @@ class NetworkMonitorApplet : public DApplet
|
|||||||
Q_PROPERTY(QString ipv6Address READ ipv6Address NOTIFY ipv6AddressChanged)
|
Q_PROPERTY(QString ipv6Address READ ipv6Address NOTIFY ipv6AddressChanged)
|
||||||
// 插件版本号,从 dde-shell 元数据读取,版本唯一源为 CMakeLists.txt project(VERSION)
|
// 插件版本号,从 dde-shell 元数据读取,版本唯一源为 CMakeLists.txt project(VERSION)
|
||||||
Q_PROPERTY(QString version READ version CONSTANT)
|
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)
|
// 当前活动接口的下行速度历史采样点(QPointF 列表:x=时间戳秒, y=速度 bytes/sec)
|
||||||
// 用于趋势图绘制下载折线,每次 calculateSpeed 追加一个点并发射 speedHistoryChanged
|
// 用于趋势图绘制下载折线,每次 calculateSpeed 追加一个点并发射 speedHistoryChanged
|
||||||
Q_PROPERTY(QVariantList speedHistoryDownload READ speedHistoryDownload NOTIFY speedHistoryChanged)
|
Q_PROPERTY(QVariantList speedHistoryDownload READ speedHistoryDownload NOTIFY speedHistoryChanged)
|
||||||
@@ -85,6 +90,10 @@ public:
|
|||||||
QVariantList speedHistoryUpload() const;
|
QVariantList speedHistoryUpload() const;
|
||||||
// 返回插件版本号,从 dde-shell 插件元数据(metadata.json)读取
|
// 返回插件版本号,从 dde-shell 插件元数据(metadata.json)读取
|
||||||
QString version() const;
|
QString version() const;
|
||||||
|
// 返回任务栏网速字体颜色,空串表示跟随系统主题
|
||||||
|
QString textColor() const;
|
||||||
|
// 设置任务栏网速字体颜色,空串表示跟随系统主题
|
||||||
|
void setTextColor(const QString &color);
|
||||||
|
|
||||||
Q_INVOKABLE void refresh();
|
Q_INVOKABLE void refresh();
|
||||||
Q_INVOKABLE void setActiveInterface(const QString &interface);
|
Q_INVOKABLE void setActiveInterface(const QString &interface);
|
||||||
@@ -99,6 +108,8 @@ signals:
|
|||||||
void ipAddressChanged();
|
void ipAddressChanged();
|
||||||
void ipv6AddressChanged();
|
void ipv6AddressChanged();
|
||||||
void speedHistoryChanged();
|
void speedHistoryChanged();
|
||||||
|
// 任务栏网速字体颜色变化时通知 QML 更新
|
||||||
|
void textColorChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void readNetworkStats();
|
void readNetworkStats();
|
||||||
@@ -131,6 +142,10 @@ private:
|
|||||||
|
|
||||||
bool m_ready;
|
bool m_ready;
|
||||||
bool m_firstUpdate;
|
bool m_firstUpdate;
|
||||||
|
// 任务栏网速字体颜色,空串表示跟随系统主题
|
||||||
|
// 设计原因:空串作为"跟随系统"的语义值,QML 层用 textColor ? textColor : primaryText
|
||||||
|
// 做回退,避免后端硬编码系统色
|
||||||
|
QString m_textColor;
|
||||||
|
|
||||||
// 速度历史环形缓冲:每个接口独立维护一份,key 为接口名
|
// 速度历史环形缓冲:每个接口独立维护一份,key 为接口名
|
||||||
// 设计原因:接口切换时趋势图不出现跳变,切回时仍能看到该接口历史
|
// 设计原因:接口切换时趋势图不出现跳变,切回时仍能看到该接口历史
|
||||||
|
|||||||
Reference in New Issue
Block a user