143 lines
7.6 KiB
C++
143 lines
7.6 KiB
C++
#pragma once
|
||
|
||
// 全局视觉主题(浅色专业方向):Fusion 风格 + 浅色 QPalette + 结构化 QSS。
|
||
// 仅外观——不改任何信号槽 / 渲染 / 数据逻辑。在 QApplication 构造后、弹登录窗前调用一次。
|
||
//
|
||
// 设计令牌(与登录窗、视图详情浮层共享,保证全项目一脉相承):
|
||
// 外壳底 #F4F6FA 面板白 #FFFFFF 抬升/表头 #EDF1F7
|
||
// 强调 #2D6CB5 悬停 #2862A6 按下 #234F87 选中行 #DCE9F8
|
||
// 文字 #1F2A3D 次要文字 #5A6B85 边框 #D5DBE5 强边框 #C2CCDA
|
||
// 危险 #C0392B
|
||
|
||
#include <QColor>
|
||
#include <QObject>
|
||
#include <QString>
|
||
|
||
class QApplication;
|
||
class QWidget;
|
||
|
||
namespace geopro::app {
|
||
|
||
// 主题管理器(纯 Qt,替代 ElaTheme):持有当前明暗 + 是否跟随系统;切换发 changed() 信号,
|
||
// 全 UI(全局 QSS 由 main 重应用、内联 chrome 由 applyTokenizedStyleSheet)据此热切重着色。
|
||
class ThemeManager : public QObject {
|
||
Q_OBJECT
|
||
public:
|
||
static ThemeManager& instance();
|
||
bool isDark() const { return dark_; }
|
||
void setMode(const QString& mode); // "system"|"light"|"dark":持久化 + 应用 + 发 changed
|
||
void applyPersisted(); // 按持久化偏好设置状态(系统模式则取系统明暗)
|
||
signals:
|
||
void changed();
|
||
private:
|
||
explicit ThemeManager(QObject* parent = nullptr);
|
||
bool dark_ = false;
|
||
bool follow_ = true;
|
||
};
|
||
|
||
// ── 排版令牌(全项目唯一字号阶 + 字重角色)──────────────────────────
|
||
// 各处 QSS 的 font-size / font-weight 一律引用这些值,不再散落硬编码 px。
|
||
// 阶比 ~1.18(body→title→heading),刻意拉开层级——避免 11/12/13/14
|
||
// 这类只差 1px 的"糊层级",让标题/正文/说明三档一眼可分。
|
||
// 单位:px(与全局 px 化的 QSS、固定像素行高对齐;后续若做无障碍字号
|
||
// 缩放再统一切 pt)。字重:400 正文 / 500 可交互激活 /
|
||
// 600 标签·标题 / 700 仅展示性大标题。
|
||
namespace type {
|
||
|
||
inline constexpr int kCaption = 12; // 徽标·提示·角色名·错误·副标题·字段标签
|
||
inline constexpr int kBody = 13; // 树/列表/菜单/正文(= 全局基准字号)
|
||
inline constexpr int kLabel = 13; // 表头·用户名等需加粗的同级标签(配 600)
|
||
inline constexpr int kTitle = 15; // 面板/停靠区/区段标题·主操作按钮
|
||
inline constexpr int kHeading = 18; // 视图/对话框级标题(预留)
|
||
inline constexpr int kDisplay = 24; // 登录品牌名(唯一展示性大字)
|
||
|
||
inline constexpr int kWeightRegular = 400;
|
||
inline constexpr int kWeightMedium = 500;
|
||
inline constexpr int kWeightSemibold = 600;
|
||
inline constexpr int kWeightBold = 700;
|
||
|
||
} // namespace type
|
||
|
||
// ── 间距令牌(全项目唯一间距阶)──────────────────────────────────
|
||
// 取代散落的 5/7/9/11/13/15/26 等任意值。这是密集专业工具的实际节奏
|
||
// (非外加的 8pt 网格):相邻档 2px 粒度,足够紧凑又不糊成一片。
|
||
// 用法:布局 setContentsMargins/setSpacing/addSpacing 与 QSS padding/margin
|
||
// 一律引用这些档;明显的奇数值就近归档(13/15→lg, 11→ml, 26→xxl)。
|
||
namespace space {
|
||
|
||
inline constexpr int kXxs = 2; // 发丝级:下划线偏移、滚动条边距
|
||
inline constexpr int kXs = 4; // 紧凑内边距、最小间隙
|
||
inline constexpr int kSm = 6; // 行内紧凑(控件竖向 padding)
|
||
inline constexpr int kMd = 8; // 标准间隔(最常用)
|
||
inline constexpr int kMl = 10; // 偏大行距(密集行/验证码行)
|
||
inline constexpr int kLg = 12; // 分组间隔、面板内左右边距
|
||
inline constexpr int kXl = 16; // 区块内边距
|
||
inline constexpr int kXxl = 24; // 区块间距、表单纵向边距
|
||
inline constexpr int kXxxl = 32; // 页面级留白(登录窗左右边距)
|
||
|
||
} // namespace space
|
||
|
||
// ── 圆角令牌(统一原先 4/5/6/7/8/9 共 6 档为 3 档)────────────────
|
||
// 圆形元素(头像等)用 直径/2 单独写字面量,不入档。
|
||
namespace radius {
|
||
|
||
inline constexpr int kSm = 6; // 按钮·输入·菜单项·滚动条·进度条
|
||
inline constexpr int kMd = 8; // 卡片·面板·对话框·菜单·分组框
|
||
inline constexpr int kPill = 9; // 数量徽标胶囊
|
||
|
||
} // namespace radius
|
||
|
||
// ── 语义色令牌(状态/反馈,产品语境:只在承载含义处用,不作装饰)──────────
|
||
// 文字值均针对白底面板(#FFFFFF)选深色,对比度 ≥4.5:1(正文级);与冷调中性
|
||
// 调色板调和。danger 沿用既有红,避免引入第二种红。
|
||
namespace semantic {
|
||
|
||
inline constexpr const char* kInfo = "#2D6CB5"; // 信息·进行中(= 品牌蓝)
|
||
inline constexpr const char* kSuccess = "#15803D"; // 成功·已完成(深绿)
|
||
inline constexpr const char* kWarning = "#B45309"; // 警告·需注意(深琥珀)
|
||
inline constexpr const char* kDanger = "#C0392B"; // 危险·错误(沿用既有红)
|
||
|
||
// 浅色填充(徽标/标签底色,配同族深色文字使用)。
|
||
inline constexpr const char* kWarningFill = "#FBEAD2"; // 警告底纹(配 kWarning 文字)
|
||
|
||
} // namespace semantic
|
||
|
||
// 应用专业主题(Fusion + 调色板 + 全局样式表)。dark=true 走暗色(P2 主题桥用)。
|
||
// 暗色复用同一 QSS 结构,颜色全由 kTokens 双值(fillTokens/tokenHex)驱动;幂等,可随主题切换重复调用。
|
||
void applyThemeMode(QApplication& app, bool dark);
|
||
|
||
// 浅色主题快捷入口(= applyThemeMode(app,false))。经典壳启动调用一次。
|
||
void applyTheme(QApplication& app);
|
||
|
||
// ── 设置:主题 / 界面字号 偏好(QSettings 持久化)────────────────────────
|
||
// 启动时(eApp->init + applyBrandAccent 之后、弹登录窗之前)各调一次,使登录页与主页统一。
|
||
void applyPersistedThemeMode(); // 应用持久化主题:跟随系统 / 浅色 / 深色 → ElaTheme
|
||
void applyPersistedFontScale(); // 应用持久化字号:设 qApp 基准字体 + 记录缩放(供 scaledPx)
|
||
|
||
QString themeModePreference(); // "system" | "light" | "dark"(默认 system)
|
||
void setThemeModePreference(const QString& mode); // 持久化 + 立即应用(主题可热切)
|
||
|
||
int fontScalePreference(); // 缩放百分比 90/100/115/130(默认 100)
|
||
void setFontScalePreference(int percent); // 仅持久化(字号改动重启后生效)
|
||
|
||
int scaledPx(int basePx); // basePx × 当前字号% / 100(内联 QSS 字号用,使自定义 chrome 也随字号缩放)
|
||
|
||
// 当前 ElaTheme 是否暗色(供内联样式判断)。
|
||
bool isDarkTheme();
|
||
|
||
// VTK 渲染器背景色(随当前主题,取 ElaTheme 窗口底色)。写入 r/g/b(0–1)。
|
||
void vtkBackground(double& r, double& g, double& b);
|
||
|
||
// ── 语义令牌(单一事实来源,取值见 Theme.cpp kTokens;规范 §1.5 + 附录 A + §1.3)──
|
||
// 组件只引语义 token,禁止散落硬编码 hex。token 名形如 "bg/panel"、"accent/primary"。
|
||
QString token(const char* name); // 当前明暗下的 hex(未知名返回品红 "#FF00FF" 以便一眼发现漏配)
|
||
QColor tokenColor(const char* name); // 同上,QColor 形式
|
||
|
||
// 把 QSS 模板里的 {{token}} 占位替换为当前明暗的 hex 后返回。
|
||
QString fillTokens(const QString& tmpl);
|
||
|
||
// 应用一段 {{token}} 模板 QSS 到 widget,并随主题切换自动重填。
|
||
void applyTokenizedStyleSheet(QWidget* w, const QString& tmpl);
|
||
|
||
} // namespace geopro::app
|