fix(ela): 工作台配色改为取自 ElaTheme(里外一致) — 修明暗都不对

根因: 我那套自挑的浅/暗配色与 ElaWindow 外壳的 Fluent 配色不一致, 里外两种色, 明暗都割裂。
改法: kRoleMap 把设计稿色令牌按语义角色映射到 ElaTheme 颜色角色, styleSheetForMode/
buildPalette 用 eTheme->getThemeColor(当前模式,角色) 取真实颜色, 与外壳同源。
(已知: #FFFFFF 兼作面板底与按钮文字, 全局替换后暗色下默认按钮文字对比度略弱, 影响很小)
This commit is contained in:
gaozheng 2026-06-10 08:53:00 +08:00
parent 9091d8c929
commit 8a82029553
1 changed files with 79 additions and 93 deletions

View File

@ -6,6 +6,9 @@
#include <QPalette> #include <QPalette>
#include <QStyleFactory> #include <QStyleFactory>
#include <ElaDef.h>
#include <ElaTheme.h>
namespace geopro::app { namespace geopro::app {
namespace { namespace {
@ -369,111 +372,94 @@ ads--CDockWidgetTab[activeTab="true"] QLabel {
} }
)QSS"; )QSS";
// ── 暗色映射P2 主题桥):把浅色 QSS 里每个浅色令牌就近替换为暗色等价, // ── 主题桥配色:工作台标准控件的 QSS/调色板颜色直接取自 ElaTheme
// 复用同一 kStyleSheet 结构(选择器/度量不变仅换色。ads--* 规则同在 kStyleSheet 内, // 保证里外ElaWindow 外壳 ↔ 内部工作台)在明/暗两模下完全一致——这是关键,
// 故停靠区也随之暗化。品牌蓝在暗底略提亮以保对比度danger 同理。 // 否则外壳一种灰、工作台另一种灰,明暗都显得割裂。
struct HexPair { // 做法:把浅色设计稿里每个色令牌按语义角色替换为 ElaTheme 当前模式的真实颜色。
const char* light; struct RoleMap {
const char* dark; const char* token; // 浅色设计稿中的占位 hex
ElaThemeType::ThemeColor role; // 对应 ElaTheme 颜色角色
}; };
constexpr HexPair kDarkMap[] = { const RoleMap kRoleMap[] = {
{"#1F2A3D", "#E3E5E8"}, // 主文字 → 亮 {"#F4F6FA", ElaThemeType::WindowBase}, // 外壳/停靠区底
{"#F4F6FA", "#1E1F22"}, // 外壳底 {"#FFFFFF", ElaThemeType::BasicBase}, // 面板/输入/菜单 底
{"#FFFFFF", "#2B2D30"}, // 面板白 {"#EDF1F7", ElaThemeType::BasicBaseDeep}, // 抬升/表头底
{"#EDF1F7", "#323539"}, // 抬升/表头 {"#1F2A3D", ElaThemeType::BasicText}, // 主文字
{"#EAEEF4", "#3A3D42"}, // 细分隔/边框线 {"#5A6B85", ElaThemeType::BasicTextNoFocus}, // 次要文字
{"#EEF3FB", "#3A3D42"}, // 悬停底 {"#3A475C", ElaThemeType::BasicTextCategory}, // 表头文字
{"#DCE9F8", "#2E3F54"}, // 选中行底 {"#1B3D67", ElaThemeType::BasicText}, // 选中行文字
{"#1B3D67", "#CFE0F5"}, // 选中行文字 {"#DCE9F8", ElaThemeType::BasicPress}, // 选中行/按下 底
{"#3A475C", "#C4C9D0"}, // 表头文字 {"#EEF3FB", ElaThemeType::BasicHover}, // 悬停底
{"#5A6B85", "#A9B0BC"}, // 次要文字 {"#EAEEF4", ElaThemeType::BasicBorder}, // 细分隔/边框
{"#D5DBE5", "#3A3D42"}, // 边框 {"#D5DBE5", ElaThemeType::BasicBorder}, // 边框
{"#C2CCDA", "#4A4E55"}, // 强边框/滚动条柄 {"#C2CCDA", ElaThemeType::BasicBorderDeep}, // 强边框/滚动条柄
{"#C7D2E0", "#4A4E55"}, // 输入边框 {"#C7D2E0", ElaThemeType::BasicBorder}, // 输入边框
{"#2D6CB5", "#4A90E2"}, // 强调(品牌蓝,暗底提亮) {"#2D6CB5", ElaThemeType::PrimaryNormal}, // 强调
{"#2862A6", "#5C9CE8"}, // 强调悬停 {"#2862A6", ElaThemeType::PrimaryHover}, // 强调悬停
{"#234F87", "#3A7BC8"}, // 强调按下 {"#234F87", ElaThemeType::PrimaryPress}, // 强调按下
{"#9AA6B6", "#6E747C"}, // 禁用文字 {"#9AA6B6", ElaThemeType::BasicTextDisable}, // 禁用文字
{"#F0F2F6", "#26282B"}, // 禁用底 {"#F0F2F6", ElaThemeType::BasicDisable}, // 禁用底
{"#8A93A3", "#7A8088"}, // 禁用文字2 {"#8A93A3", ElaThemeType::BasicTextDisable}, // 禁用文字2
{"#DCE0E7", "#3A3D42"}, // 禁用边框 {"#DCE0E7", ElaThemeType::BasicBorder}, // 禁用边框
{"#A7B4C7", "#5A5F66"}, // 滚动条柄悬停 {"#A7B4C7", ElaThemeType::BasicBorderDeep}, // 滚动条柄悬停
{"#E1E6EE", "#3A3D42"}, // 菜单分隔 {"#E1E6EE", ElaThemeType::BasicBorder}, // 菜单分隔
{"#DCE6F4", "#34373C"}, // 菜单栏选中 {"#DCE6F4", ElaThemeType::BasicHover}, // 菜单栏选中
{"#E6EBF3", "#3A3D42"}, // 进度条底 {"#E6EBF3", ElaThemeType::BasicDisable}, // 进度条底
{"#EAF1FB", "#2E3F54"}, // 工具按钮选中底 {"#EAF1FB", ElaThemeType::BasicHover}, // 工具按钮选中底
{"#C0392B", "#E0685C"}, // 危险(暗底提亮) {"#C0392B", ElaThemeType::StatusDanger}, // 危险
{"#E6EAF1", "#3A3D42"}, // 面板表头分隔(与 PanelHeader 一致)
}; };
// 浅/暗专业调色板:让标准控件在无 QSS 覆盖处也保持一致底色/选中色。 QColor roleColor(bool dark, ElaThemeType::ThemeColor role)
QPalette buildPalette(bool dark)
{ {
QPalette p; return eTheme->getThemeColor(dark ? ElaThemeType::Dark : ElaThemeType::Light, role);
if (!dark) {
const QColor shell("#F4F6FA"), panel("#FFFFFF"), text("#1F2A3D"),
mutedText("#5A6B85"), accent("#2D6CB5");
p.setColor(QPalette::Window, shell);
p.setColor(QPalette::WindowText, text);
p.setColor(QPalette::Base, panel);
p.setColor(QPalette::AlternateBase, QColor("#F0F3F8"));
p.setColor(QPalette::Text, text);
p.setColor(QPalette::Button, QColor("#EDF1F7"));
p.setColor(QPalette::ButtonText, text);
p.setColor(QPalette::ToolTipBase, QColor("#1F2A3D"));
p.setColor(QPalette::ToolTipText, shell);
p.setColor(QPalette::Highlight, accent);
p.setColor(QPalette::HighlightedText, panel);
p.setColor(QPalette::PlaceholderText, mutedText);
p.setColor(QPalette::Link, accent);
// 把 Fusion 的明暗 3D 角色压成相近浅灰,立体效果塌成平面。
p.setColor(QPalette::Light, QColor("#FFFFFF"));
p.setColor(QPalette::Midlight, QColor("#EEF1F5"));
p.setColor(QPalette::Mid, QColor("#E1E6EE"));
p.setColor(QPalette::Dark, QColor("#D7DEE8"));
p.setColor(QPalette::Shadow, QColor("#D7DEE8"));
p.setColor(QPalette::Disabled, QPalette::Text, QColor("#9AA6B6"));
p.setColor(QPalette::Disabled, QPalette::WindowText, QColor("#9AA6B6"));
p.setColor(QPalette::Disabled, QPalette::ButtonText, QColor("#9AA6B6"));
} else {
const QColor shell("#1E1F22"), panel("#2B2D30"), text("#E3E5E8"),
mutedText("#A9B0BC"), accent("#4A90E2");
p.setColor(QPalette::Window, shell);
p.setColor(QPalette::WindowText, text);
p.setColor(QPalette::Base, panel);
p.setColor(QPalette::AlternateBase, QColor("#303236"));
p.setColor(QPalette::Text, text);
p.setColor(QPalette::Button, QColor("#323539"));
p.setColor(QPalette::ButtonText, text);
p.setColor(QPalette::ToolTipBase, QColor("#E3E5E8"));
p.setColor(QPalette::ToolTipText, QColor("#1E1F22"));
p.setColor(QPalette::Highlight, accent);
p.setColor(QPalette::HighlightedText, QColor("#0E1013"));
p.setColor(QPalette::PlaceholderText, mutedText);
p.setColor(QPalette::Link, accent);
p.setColor(QPalette::Light, QColor("#34373C"));
p.setColor(QPalette::Midlight, QColor("#303236"));
p.setColor(QPalette::Mid, QColor("#3A3D42"));
p.setColor(QPalette::Dark, QColor("#3A3D42"));
p.setColor(QPalette::Shadow, QColor("#3A3D42"));
p.setColor(QPalette::Disabled, QPalette::Text, QColor("#6E747C"));
p.setColor(QPalette::Disabled, QPalette::WindowText, QColor("#6E747C"));
p.setColor(QPalette::Disabled, QPalette::ButtonText, QColor("#6E747C"));
}
return p;
} }
// 当前模式的全局 QSS暗色 = 在浅色 kStyleSheet 上逐一替换色令牌 // 当前模式的全局 QSS按 kRoleMap 把设计稿色令牌换成 ElaTheme 真实颜色(明/暗同源于外壳)。
QString styleSheetForMode(bool dark) QString styleSheetForMode(bool dark)
{ {
QString s = QString::fromUtf8(kStyleSheet); QString s = QString::fromUtf8(kStyleSheet);
if (dark) { for (const auto& rm : kRoleMap)
for (const auto& hp : kDarkMap) s.replace(QLatin1String(rm.token), roleColor(dark, rm.role).name());
s.replace(QLatin1String(hp.light), QLatin1String(hp.dark));
}
return s; return s;
} }
// 调色板同样取自 ElaTheme让无 QSS 覆盖处的标准控件也与外壳一致。
QPalette buildPalette(bool dark)
{
QPalette p;
const QColor shell = roleColor(dark, ElaThemeType::WindowBase);
const QColor panel = roleColor(dark, ElaThemeType::BasicBase);
const QColor text = roleColor(dark, ElaThemeType::BasicText);
const QColor muted = roleColor(dark, ElaThemeType::BasicTextNoFocus);
const QColor accent = roleColor(dark, ElaThemeType::PrimaryNormal);
const QColor border = roleColor(dark, ElaThemeType::BasicBorder);
const QColor disabled = roleColor(dark, ElaThemeType::BasicTextDisable);
p.setColor(QPalette::Window, shell);
p.setColor(QPalette::WindowText, text);
p.setColor(QPalette::Base, panel);
p.setColor(QPalette::AlternateBase, roleColor(dark, ElaThemeType::BasicAlternating));
p.setColor(QPalette::Text, text);
p.setColor(QPalette::Button, roleColor(dark, ElaThemeType::BasicBaseDeep));
p.setColor(QPalette::ButtonText, text);
p.setColor(QPalette::ToolTipBase, text);
p.setColor(QPalette::ToolTipText, shell);
p.setColor(QPalette::Highlight, accent);
p.setColor(QPalette::HighlightedText, panel);
p.setColor(QPalette::PlaceholderText, muted);
p.setColor(QPalette::Link, accent);
// Fusion 的明暗 3D 角色统一压成边框色,立体效果塌成平面(去斜角/凹槽)。
p.setColor(QPalette::Light, panel);
p.setColor(QPalette::Midlight, border);
p.setColor(QPalette::Mid, border);
p.setColor(QPalette::Dark, border);
p.setColor(QPalette::Shadow, border);
p.setColor(QPalette::Disabled, QPalette::Text, disabled);
p.setColor(QPalette::Disabled, QPalette::WindowText, disabled);
p.setColor(QPalette::Disabled, QPalette::ButtonText, disabled);
return p;
}
} // namespace } // namespace
void applyThemeMode(QApplication& app, bool dark) void applyThemeMode(QApplication& app, bool dark)