// Metro 主题令牌(D14 + D17 主题三态 + 09 §101-104「外观(高级)」):palette + 排版层级 + 字体栈 + // 动效时长 + 外观令牌(背景图 / 面板半透明度 / 玻璃拟态 / 强调色)。 // // 结构约定: // - `LightPalette` / `DarkPalette` = 两套完整色板(**不是**一套加条件),换肤只改这两处。 // - `Theme` = 解析器:按主题三态(auto/light/dark)挑一套,并持有**共享**的 accent 与字体/排版。 // - auto 跟随系统:`Theme.system-theme` 由 Rust 的 `core::platform::theme_probe` 灌入(启动对齐 + // 未知时兜底轮询),后端支持时另有 `Palette.color-scheme` 实时热切;两者都不认识就按浅色。 // - 「外观(高级)」四件全部默认关闭:`panel-alpha` 1.0 / `glass` false / `bg-image` 空 / // `accent-override` 透明——出厂观感与 M17 骨架逐像素一致(09 §111 硬约束)。 // - 组件只准用 `Theme.*`,不得出现裸色字面量(背景图暗化层是唯一例外,它是「遮罩」而非配色)。 import { ThemeMode } from "../models.slint"; import { Palette } from "std-widgets.slint"; // ── 亮色色板 ──────────────────────────────────────────────────── export global LightPalette { out property bg-canvas: #F3F3F3; out property bg-surface: #FFFFFF; out property bg-elevated: #FFFFFF; out property bg-titlebar: #EDEDED; out property bg-hover: #E9E9E9; out property bg-pressed: #DEDEDE; out property bg-input: #FFFFFF; out property fg-primary: #1A1A1A; out property fg-secondary: #5F5F5F; out property fg-disabled: #9A9A9A; out property stroke: #E1E1E1; out property stroke-strong: #C8C8C8; out property shadow: #00000026; out property scrim: #00000099; out property accent-soft: #E5F1FB; out property accent-hover: #106EBE; out property accent-pressed: #005A9E; out property state-success: #107C10; out property state-success-soft: #DFF6DD; out property state-warn: #9D5D00; out property state-warn-soft: #FFF4CE; out property state-danger: #C42B1C; out property state-danger-hover: #A82214; out property state-danger-soft: #FDE7E9; out property state-info-soft: #E7F1FA; } // ── 暗色色板 ──────────────────────────────────────────────────── export global DarkPalette { out property bg-canvas: #1B1B1B; out property bg-surface: #232323; out property bg-elevated: #2B2B2B; out property bg-titlebar: #161616; out property bg-hover: #2F2F2F; out property bg-pressed: #383838; out property bg-input: #1E1E1E; out property fg-primary: #F2F2F2; out property fg-secondary: #A6A6A6; out property fg-disabled: #6B6B6B; out property stroke: #3A3A3A; out property stroke-strong: #4A4A4A; out property shadow: #000000CC; out property scrim: #00000099; out property accent-soft: #0F2A3F; out property accent-hover: #2B8FE0; out property accent-pressed: #005A9E; out property state-success: #4CCB4C; out property state-success-soft: #16321A; out property state-warn: #FFD24C; out property state-warn-soft: #3A2E0F; out property state-danger: #FF6B6B; out property state-danger-hover: #FF8A8A; out property state-danger-soft: #3A1A1A; out property state-info-soft: #10263A; } // ── 解析器 ────────────────────────────────────────────────────── export global Theme { // ── 主题三态(D17 设置页「外观」分组,出厂 auto)────────────────── // D17 主题三态(设置页「外观」分组,出厂 auto) in-out property theme-mode: ThemeMode.auto; // 系统主题来源(M41):0 = 未知(此时回落到 Slint 后端 `Palette.color-scheme`), // 1 = 浅色 / 2 = 深色。由 Rust 的 `core::platform::theme_probe` 探测后灌入: // 启动时给首帧对齐,之后按需轮询兜底(后端不支持系统主题时 auto 仍可用)。 in-out property system-theme: 0; // 后端是否认得系统主题(`unknown` 表示不支持/无 portal)。 out property system-theme-known: Palette.color-scheme != ColorScheme.unknown; // 是否深色:显式钉死(light/dark)优先;auto 时用探测值,探测未知才问后端。 out property dark: theme-mode == ThemeMode.dark || (theme-mode == ThemeMode.auto && (system-theme == 2 || (system-theme != 1 && Palette.color-scheme == ColorScheme.dark))); // ── 外观(高级)令牌(09 §101-104 / §111:出厂全部关闭)───────── // 全局面板半透明度:`bg-*` 令牌统一按 `panel-alpha` 重建(见下方「面板底色」段), // 组件侧零改动即透出背景图。出厂 1.0 = 完全不透明,Metro 纯色外观与 M17 骨架一致。 in-out property panel-alpha: 1.0; // 自定义窗口背景图(空 image = 纯色背景,出厂态)。 in-out property bg-image; // 背景图暗化层强度(0~0.95,越大前景越清晰)。Rust 侧夹到 schema 范围。 in-out property bg-dim: 0.35; // 玻璃拟态:预生成模糊层(Rust 侧降采样 + box blur),卡片内按 `absolute-position` // 反向偏移对齐整窗,得到 Slint 版「毛玻璃」(无 backdrop-filter 的替代手法)。 in-out property glass: false; in-out property bg-blur; // 玻璃层对齐用的窗口逻辑尺寸(AppShell 在 init/changed 里灌入)。 in-out property window-width: 1180px; in-out property window-height: 760px; // ── 强调色(accent 令牌全域生效;两套色板共享)────────────────── // `accent-override` 的 alpha == 0 表示「未自定义」,走 D14 出厂 Metro 蓝。 // (color 的 `.alpha` 字段是 0~255 整数,不是 0~1 浮点。) in-out property accent-override: transparent; out property accent-custom: accent-override.alpha > 1; out property accent: accent-custom ? accent-override : #0078D4; // 自定义时由覆盖色派生 hover/pressed/soft(未自定义仍走双色板常量,出场观感不变)。 out property accent-hover: accent-custom ? (dark ? accent.brighter(0.18) : accent.darker(0.12)) : (dark ? DarkPalette.accent-hover : LightPalette.accent-hover); out property accent-pressed: accent-custom ? (dark ? accent.brighter(0.28) : accent.darker(0.24)) : (dark ? DarkPalette.accent-pressed : LightPalette.accent-pressed); out property accent-soft: accent-custom ? accent.mix(surface-solid, 0.82) : (dark ? DarkPalette.accent-soft : LightPalette.accent-soft); out property accent-contrast: #FFFFFF; // accent 上的前景色按相对亮度自动选黑/白(自定义亮黄、浅青时白字会糊)。 // 注意:Slint 的 color 通道字段(`.red` 等)是 0~255 的**整数**。 out property accent-luma: accent.red * 0.299 + accent.green * 0.587 + accent.blue * 0.114; out property fg-on-accent: accent-luma > 160 ? #1A1A1A : #FFFFFF; // ── 面板底色(`panel-alpha` 统一透出背景图)──────────────────── // `*-solid` 是不透明原件(窗口自身底色 / accent.mix 的混合基准必须不透明, // 否则浮点叠加会让 accent-soft 随 panel-alpha 一起变淡)。 // 半透明色用 `rgba(r, g, b, a)` 重建而不是 `.with-alpha()`:后者返回 Brush, // 赋给 `` 属性会类型不符(Slint 无 Brush → color 隐式回退)。 out property surface-solid: dark ? DarkPalette.bg-surface : LightPalette.bg-surface; out property canvas-solid: dark ? DarkPalette.bg-canvas : LightPalette.bg-canvas; out property surface-elevated-solid: dark ? DarkPalette.bg-elevated : LightPalette.bg-elevated; out property titlebar-solid: dark ? DarkPalette.bg-titlebar : LightPalette.bg-titlebar; out property hover-solid: dark ? DarkPalette.bg-hover : LightPalette.bg-hover; out property pressed-solid: dark ? DarkPalette.bg-pressed : LightPalette.bg-pressed; out property input-solid: dark ? DarkPalette.bg-input : LightPalette.bg-input; out property bg-canvas: rgba( canvas-solid.red, canvas-solid.green, canvas-solid.blue, panel-alpha); out property bg-surface: rgba( surface-solid.red, surface-solid.green, surface-solid.blue, panel-alpha); out property bg-elevated: rgba( surface-elevated-solid.red, surface-elevated-solid.green, surface-elevated-solid.blue, panel-alpha); out property bg-titlebar: rgba( titlebar-solid.red, titlebar-solid.green, titlebar-solid.blue, panel-alpha); out property bg-hover: rgba( hover-solid.red, hover-solid.green, hover-solid.blue, panel-alpha); out property bg-pressed: rgba( pressed-solid.red, pressed-solid.green, pressed-solid.blue, panel-alpha); out property bg-input: rgba( input-solid.red, input-solid.green, input-solid.blue, panel-alpha); out property fg-primary: dark ? DarkPalette.fg-primary : LightPalette.fg-primary; out property fg-secondary: dark ? DarkPalette.fg-secondary : LightPalette.fg-secondary; out property fg-disabled: dark ? DarkPalette.fg-disabled : LightPalette.fg-disabled; out property stroke: dark ? DarkPalette.stroke : LightPalette.stroke; out property stroke-strong: dark ? DarkPalette.stroke-strong : LightPalette.stroke-strong; out property shadow: dark ? DarkPalette.shadow : LightPalette.shadow; out property scrim: dark ? DarkPalette.scrim : LightPalette.scrim; out property state-success: dark ? DarkPalette.state-success : LightPalette.state-success; out property state-success-soft: dark ? DarkPalette.state-success-soft : LightPalette.state-success-soft; out property state-warn: dark ? DarkPalette.state-warn : LightPalette.state-warn; out property state-warn-soft: dark ? DarkPalette.state-warn-soft : LightPalette.state-warn-soft; out property state-danger: dark ? DarkPalette.state-danger : LightPalette.state-danger; out property state-danger-hover: dark ? DarkPalette.state-danger-hover : LightPalette.state-danger-hover; out property state-danger-soft: dark ? DarkPalette.state-danger-soft : LightPalette.state-danger-soft; out property state-info-soft: dark ? DarkPalette.state-info-soft : LightPalette.state-info-soft; // ── 字体 ──────────────────────────────────────────────────── // Segoe UI 不可再分发(微软许可)→ Windows 用系统自带,其他平台用 Selawik // (微软官方开源、Segoe UI 度量兼容)+ Open Sans 回退栈(01c §7 第 5 条)。 // Slint 的 font-family 只吃单个家族名,回退链由 Rust 侧启动时按平台选择 + 注册字体族实现: // windows → "Segoe UI",macos/linux → "Selawik"(随包)+ "Open Sans" 兜底。 in-out property font-family: "Selawik"; in-out property font-family-mono: "Cascadia Mono"; // 中文回退(思源黑体/微软雅黑由系统字体匹配,这里仅作显式声明) in-out property font-family-cjk: "Microsoft YaHei UI"; // 排版层级(Metro typography ramp) out property font-size-display: 24px; out property font-size-title: 20px; out property font-size-subtitle: 16px; out property font-size-body: 14px; out property font-size-caption: 12px; out property line-height-body: 20px; out property line-height-caption: 16px; // ── 动效(Metro 快速、克制)─────────────────────────────────── out property motion-fast: 90ms; out property motion-normal: 160ms; out property motion-slow: 240ms; // D17 动画强度倍率(P0 占位,P1 接设置页滑条与「减少动画」无障碍开关) in-out property motion-scale: 1.0; }