CI / fmt (rustfmt --check) (push) Canceled after 0s
CI / clippy (ubuntu-latest) (push) Canceled after 0s
CI / clippy (windows-latest) (push) Canceled after 0s
CI / test (ubuntu-latest) (push) Canceled after 0s
CI / test (windows-latest) (push) Canceled after 0s
CI / build release (ubuntu-latest) (push) Canceled after 0s
CI / build release (windows-latest) (push) Canceled after 0s
Guards / core 零 UI 守门 (push) Canceled after 0s
Guards / 文件行数 ≤400 守门 (push) Canceled after 0s
Guards / 依赖许可与来源(cargo-deny) (push) Canceled after 0s
Rust 原生单文件 Minecraft 启动器:CLI 完整可用(install/launch/accounts/java/diagnose/agent), MCP server 接入外部 Agent 工具,GUI 开发中。
209 lines
13 KiB
Plaintext
209 lines
13 KiB
Plaintext
// 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 <color> bg-canvas: #F3F3F3;
|
||
out property <color> bg-surface: #FFFFFF;
|
||
out property <color> bg-elevated: #FFFFFF;
|
||
out property <color> bg-titlebar: #EDEDED;
|
||
out property <color> bg-hover: #E9E9E9;
|
||
out property <color> bg-pressed: #DEDEDE;
|
||
out property <color> bg-input: #FFFFFF;
|
||
|
||
out property <color> fg-primary: #1A1A1A;
|
||
out property <color> fg-secondary: #5F5F5F;
|
||
out property <color> fg-disabled: #9A9A9A;
|
||
|
||
out property <color> stroke: #E1E1E1;
|
||
out property <color> stroke-strong: #C8C8C8;
|
||
out property <color> shadow: #00000026;
|
||
out property <color> scrim: #00000099;
|
||
|
||
out property <color> accent-soft: #E5F1FB;
|
||
out property <color> accent-hover: #106EBE;
|
||
out property <color> accent-pressed: #005A9E;
|
||
|
||
out property <color> state-success: #107C10;
|
||
out property <color> state-success-soft: #DFF6DD;
|
||
out property <color> state-warn: #9D5D00;
|
||
out property <color> state-warn-soft: #FFF4CE;
|
||
out property <color> state-danger: #C42B1C;
|
||
out property <color> state-danger-hover: #A82214;
|
||
out property <color> state-danger-soft: #FDE7E9;
|
||
out property <color> state-info-soft: #E7F1FA;
|
||
}
|
||
|
||
// ── 暗色色板 ────────────────────────────────────────────────────
|
||
export global DarkPalette {
|
||
out property <color> bg-canvas: #1B1B1B;
|
||
out property <color> bg-surface: #232323;
|
||
out property <color> bg-elevated: #2B2B2B;
|
||
out property <color> bg-titlebar: #161616;
|
||
out property <color> bg-hover: #2F2F2F;
|
||
out property <color> bg-pressed: #383838;
|
||
out property <color> bg-input: #1E1E1E;
|
||
|
||
out property <color> fg-primary: #F2F2F2;
|
||
out property <color> fg-secondary: #A6A6A6;
|
||
out property <color> fg-disabled: #6B6B6B;
|
||
|
||
out property <color> stroke: #3A3A3A;
|
||
out property <color> stroke-strong: #4A4A4A;
|
||
out property <color> shadow: #000000CC;
|
||
out property <color> scrim: #00000099;
|
||
|
||
out property <color> accent-soft: #0F2A3F;
|
||
out property <color> accent-hover: #2B8FE0;
|
||
out property <color> accent-pressed: #005A9E;
|
||
|
||
out property <color> state-success: #4CCB4C;
|
||
out property <color> state-success-soft: #16321A;
|
||
out property <color> state-warn: #FFD24C;
|
||
out property <color> state-warn-soft: #3A2E0F;
|
||
out property <color> state-danger: #FF6B6B;
|
||
out property <color> state-danger-hover: #FF8A8A;
|
||
out property <color> state-danger-soft: #3A1A1A;
|
||
out property <color> state-info-soft: #10263A;
|
||
}
|
||
|
||
// ── 解析器 ──────────────────────────────────────────────────────
|
||
export global Theme {
|
||
// ── 主题三态(D17 设置页「外观」分组,出厂 auto)──────────────────
|
||
// D17 主题三态(设置页「外观」分组,出厂 auto)
|
||
in-out property <ThemeMode> theme-mode: ThemeMode.auto;
|
||
// 系统主题来源(M41):0 = 未知(此时回落到 Slint 后端 `Palette.color-scheme`),
|
||
// 1 = 浅色 / 2 = 深色。由 Rust 的 `core::platform::theme_probe` 探测后灌入:
|
||
// 启动时给首帧对齐,之后按需轮询兜底(后端不支持系统主题时 auto 仍可用)。
|
||
in-out property <int> system-theme: 0;
|
||
// 后端是否认得系统主题(`unknown` 表示不支持/无 portal)。
|
||
out property <bool> system-theme-known: Palette.color-scheme != ColorScheme.unknown;
|
||
// 是否深色:显式钉死(light/dark)优先;auto 时用探测值,探测未知才问后端。
|
||
out property <bool> 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 <float> panel-alpha: 1.0;
|
||
// 自定义窗口背景图(空 image = 纯色背景,出厂态)。
|
||
in-out property <image> bg-image;
|
||
// 背景图暗化层强度(0~0.95,越大前景越清晰)。Rust 侧夹到 schema 范围。
|
||
in-out property <float> bg-dim: 0.35;
|
||
// 玻璃拟态:预生成模糊层(Rust 侧降采样 + box blur),卡片内按 `absolute-position`
|
||
// 反向偏移对齐整窗,得到 Slint 版「毛玻璃」(无 backdrop-filter 的替代手法)。
|
||
in-out property <bool> glass: false;
|
||
in-out property <image> bg-blur;
|
||
// 玻璃层对齐用的窗口逻辑尺寸(AppShell 在 init/changed 里灌入)。
|
||
in-out property <length> window-width: 1180px;
|
||
in-out property <length> window-height: 760px;
|
||
|
||
// ── 强调色(accent 令牌全域生效;两套色板共享)──────────────────
|
||
// `accent-override` 的 alpha == 0 表示「未自定义」,走 D14 出厂 Metro 蓝。
|
||
// (color 的 `.alpha` 字段是 0~255 整数,不是 0~1 浮点。)
|
||
in-out property <color> accent-override: transparent;
|
||
out property <bool> accent-custom: accent-override.alpha > 1;
|
||
out property <color> accent: accent-custom ? accent-override : #0078D4;
|
||
// 自定义时由覆盖色派生 hover/pressed/soft(未自定义仍走双色板常量,出场观感不变)。
|
||
out property <color> accent-hover: accent-custom
|
||
? (dark ? accent.brighter(0.18) : accent.darker(0.12))
|
||
: (dark ? DarkPalette.accent-hover : LightPalette.accent-hover);
|
||
out property <color> accent-pressed: accent-custom
|
||
? (dark ? accent.brighter(0.28) : accent.darker(0.24))
|
||
: (dark ? DarkPalette.accent-pressed : LightPalette.accent-pressed);
|
||
out property <color> accent-soft: accent-custom
|
||
? accent.mix(surface-solid, 0.82)
|
||
: (dark ? DarkPalette.accent-soft : LightPalette.accent-soft);
|
||
out property <color> accent-contrast: #FFFFFF;
|
||
// accent 上的前景色按相对亮度自动选黑/白(自定义亮黄、浅青时白字会糊)。
|
||
// 注意:Slint 的 color 通道字段(`.red` 等)是 0~255 的**整数**。
|
||
out property <float> accent-luma: accent.red * 0.299 + accent.green * 0.587 + accent.blue * 0.114;
|
||
out property <color> 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,
|
||
// 赋给 `<color>` 属性会类型不符(Slint 无 Brush → color 隐式回退)。
|
||
out property <color> surface-solid: dark ? DarkPalette.bg-surface : LightPalette.bg-surface;
|
||
out property <color> canvas-solid: dark ? DarkPalette.bg-canvas : LightPalette.bg-canvas;
|
||
out property <color> surface-elevated-solid: dark ? DarkPalette.bg-elevated : LightPalette.bg-elevated;
|
||
out property <color> titlebar-solid: dark ? DarkPalette.bg-titlebar : LightPalette.bg-titlebar;
|
||
out property <color> hover-solid: dark ? DarkPalette.bg-hover : LightPalette.bg-hover;
|
||
out property <color> pressed-solid: dark ? DarkPalette.bg-pressed : LightPalette.bg-pressed;
|
||
out property <color> input-solid: dark ? DarkPalette.bg-input : LightPalette.bg-input;
|
||
|
||
out property <color> bg-canvas: rgba(
|
||
canvas-solid.red, canvas-solid.green, canvas-solid.blue, panel-alpha);
|
||
out property <color> bg-surface: rgba(
|
||
surface-solid.red, surface-solid.green, surface-solid.blue, panel-alpha);
|
||
out property <color> bg-elevated: rgba(
|
||
surface-elevated-solid.red, surface-elevated-solid.green, surface-elevated-solid.blue, panel-alpha);
|
||
out property <color> bg-titlebar: rgba(
|
||
titlebar-solid.red, titlebar-solid.green, titlebar-solid.blue, panel-alpha);
|
||
out property <color> bg-hover: rgba(
|
||
hover-solid.red, hover-solid.green, hover-solid.blue, panel-alpha);
|
||
out property <color> bg-pressed: rgba(
|
||
pressed-solid.red, pressed-solid.green, pressed-solid.blue, panel-alpha);
|
||
out property <color> bg-input: rgba(
|
||
input-solid.red, input-solid.green, input-solid.blue, panel-alpha);
|
||
|
||
out property <color> fg-primary: dark ? DarkPalette.fg-primary : LightPalette.fg-primary;
|
||
out property <color> fg-secondary: dark ? DarkPalette.fg-secondary : LightPalette.fg-secondary;
|
||
out property <color> fg-disabled: dark ? DarkPalette.fg-disabled : LightPalette.fg-disabled;
|
||
|
||
out property <color> stroke: dark ? DarkPalette.stroke : LightPalette.stroke;
|
||
out property <color> stroke-strong: dark ? DarkPalette.stroke-strong : LightPalette.stroke-strong;
|
||
out property <color> shadow: dark ? DarkPalette.shadow : LightPalette.shadow;
|
||
out property <color> scrim: dark ? DarkPalette.scrim : LightPalette.scrim;
|
||
|
||
out property <color> state-success: dark ? DarkPalette.state-success : LightPalette.state-success;
|
||
out property <color> state-success-soft: dark ? DarkPalette.state-success-soft : LightPalette.state-success-soft;
|
||
out property <color> state-warn: dark ? DarkPalette.state-warn : LightPalette.state-warn;
|
||
out property <color> state-warn-soft: dark ? DarkPalette.state-warn-soft : LightPalette.state-warn-soft;
|
||
out property <color> state-danger: dark ? DarkPalette.state-danger : LightPalette.state-danger;
|
||
out property <color> state-danger-hover: dark ? DarkPalette.state-danger-hover : LightPalette.state-danger-hover;
|
||
out property <color> state-danger-soft: dark ? DarkPalette.state-danger-soft : LightPalette.state-danger-soft;
|
||
out property <color> 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 <string> font-family: "Selawik";
|
||
in-out property <string> font-family-mono: "Cascadia Mono";
|
||
// 中文回退(思源黑体/微软雅黑由系统字体匹配,这里仅作显式声明)
|
||
in-out property <string> font-family-cjk: "Microsoft YaHei UI";
|
||
|
||
// 排版层级(Metro typography ramp)
|
||
out property <length> font-size-display: 24px;
|
||
out property <length> font-size-title: 20px;
|
||
out property <length> font-size-subtitle: 16px;
|
||
out property <length> font-size-body: 14px;
|
||
out property <length> font-size-caption: 12px;
|
||
out property <length> line-height-body: 20px;
|
||
out property <length> line-height-caption: 16px;
|
||
|
||
// ── 动效(Metro 快速、克制)───────────────────────────────────
|
||
out property <duration> motion-fast: 90ms;
|
||
out property <duration> motion-normal: 160ms;
|
||
out property <duration> motion-slow: 240ms;
|
||
// D17 动画强度倍率(P0 占位,P1 接设置页滑条与「减少动画」无障碍开关)
|
||
in-out property <float> motion-scale: 1.0;
|
||
}
|