用途
Makepad 2.0 主题系统为应用提供一套统一的设计令牌,通过 Splash 脚本中的 theme.* 变量访问,用于统一配色、排版、间距以及控件各状态的样式。它适用于需要在 Makepad 应用中实现一致视觉风格并支持主题切换的场景。
内置主题
系统提供三套内置主题:
- mod.themes.dark:深色桌面主题(默认)
- mod.themes.light:浅色桌面主题
- mod.themes.skeleton:使用硬编码值的最小骨架主题
核心原则:生产 UI 中任何颜色、字号或间距都应使用 theme.* 变量,而非硬编码值,以确保应用自动支持主题切换并保持视觉一致。
在 App::run 中设置主题
主题必须在控件加载之前载入。标准写法为:先载入主题定义,再选择当前主题(必须早于 widgets_mod),然后载入控件定义,最后载入应用自身脚本。若跳过前两步,则使用默认的 dark 主题(在 theme_mod 内设置)。counter 示例使用了一行式 script_mod(vm),它把前三步与默认 dark 主题打包在一起。
内部机制
theme_mod() 会调用 makepad_draw::script_mod(vm) 载入绘制原语,创建 mod.themes 模块,载入三套桌面主题,并将 mod.theme 默认设为 mod.themes.dark。随后 widgets_mod() 创建 mod.prelude.widgets_internal 并带入 theme: mod.theme,使所有使用 mod.prelude.widgets.* 的控件脚本都能访问 theme.*。
全局参数
每套主题定义了可调的全局参数以控制整体观感,包括 color_contrast(调色板扩散,默认 1.0)、color_tint(背景着色,默认 #0000ff)、color_tint_amount(着色强度 0-1,默认 0.0)、space_factor(基础间距倍数,默认 6.0)、corner_radius(基础圆角,默认 2.5)、beveling(斜角强度,默认 0.75)、font_size_base(基础字号 px,默认 10.0)、font_size_contrast(字号层级步进,默认 2.5)。
颜色变量
主色变量包括应用背景 color_bg_app、前景层 color_fg_app、容器背景 color_bg_container、交替行 color_bg_even / color_bg_odd、高亮 color_bg_highlight 与 color_bg_highlight_inline、未聚焦高亮 color_bg_unfocussed、标题栏 color_app_caption_bar,以及 color_white 与品牌色 color_makepad(#FF5C39)。
文本与标签变量区分内部元素与外部元素:color_label_inner 及其 hover、down、focus、active、inactive、disabled 变体,color_label_outer 及其 off、disabled 变体,以及通用文本 color_text、color_text_hover、color_text_focus、color_text_disabled、color_text_placeholder、color_text_meta、color_text_cursor。
控件状态颜色分为凸起类(color_outset 及 hover、down、active、focus、disabled、inactive)与凹陷类(color_inset 及 hover、focus、disabled、empty),另有选择与高亮相关变量 color_selection_focus、color_selection_hover、color_highlight、color_cursor、color_cursor_focus。
语义/状态色包括 color_error(红 #C00)、color_warning(橙 #FA0)、color_high(红 #C00)、color_mid(橙 #FA0)、color_low(黄绿 #8A0)、color_panic(品红 #f0f)。
斜角系统提供分层效果:color_bevel*、color_bevel_inset_1*、color_bevel_inset_2*、color_bevel_outset_1*、color_bevel_outset_2*,各自带 _hover、_focus、_active、_down、_disabled 后缀。其余控件颜色还包括 color_icon*、color_mark*、color_val*、color_handle*、color_shadow*、color_drag_quad、color_dock_tab_active 等。
字体变量
字号由 font_size_base 与 font_size_contrast 计算得出:font_size_1 = base + 8 * contrast(默认 30.0,最大标题)、font_size_2 = base + 4 * contrast(20.0)、font_size_3 = base + 2 * contrast(15.0)、font_size_4 = base + 1 * contrast(12.5)、font_size_p = base(10.0 正文)、font_size_code 固定 9.0。
字体样式对象包括 font_regular(IBMPlexSans-Text.ttf)、font_bold(IBMPlexSans-SemiBold.ttf)、font_italic(IBMPlexSans-Italic.ttf)、font_bold_italic(IBMPlexSans-BoldItalic.ttf)、font_code(LiberationMono-Regular.ttf)、font_label(IBMPlexSans-Text.ttf)、font_icons(fa-solid-900.ttf)。每种字体样式支持多语言:拉丁使用 IBM Plex Sans,中文使用 LXGW WenKai,Emoji 使用 Noto Color Emoji。行距常量有 font_wdgt_line_spacing(1.2,控件文本)、font_hl_line_spacing(1.05,标题)、font_longform_line_spacing(1.2,长文)。
间距与尺寸变量
间距由 space_factor(默认 6.0)派生:space_1 = 0.5 * space_factor(3.0)、space_2 = 1.0 * space_factor(6.0)、space_3 = 1.5 * space_factor(9.0)。边距预设分四类:mspace_1/2/3 为四边内边距(3/6/9px),mspace_h_1/2/3 仅左右,mspace_v_1/2/3 仅上下。尺寸变量包括 data_item_height(约 23px)、data_icon_width(约 16px)、data_icon_height(约 22px)、container_corner_radius(5.0)、textselection_corner_radius(1.25)、tab_height(36.0)。
使用方式
颜色:draw_bg.color: theme.color_bg_container;文本:draw_text.color: theme.color_label_inner;弱化文本:theme.color_label_inner_inactive,并可用乘法做透明度 theme.color_label_inner_inactive * 0.8;语义色如 theme.color_warning、theme.color_error。字号:draw_text.text_style.font_size: theme.font_size_p 等。字体样式可用 {} 覆盖字号 theme.font_bold{font_size: theme.font_size_2},或用 +: 合并语法覆盖字号。间距:padding: theme.mspace_2,可覆盖 padding: theme.mspace_2{left: theme.space_3, right: theme.space_3},水平预设 padding: theme.mspace_h_1{left: theme.space_2, right: theme.space_2},子元素间距 spacing: theme.space_2,也可做计算如 9. * theme.space_1。
颜色语法参考
Splash 支持多种颜色格式:#RGB 短十六进制、#RRGGBB 全十六进制、#RRGGBBAA 带透明度、#xRRGGBB(以 e 开头时需加 #x 前缀,如 #x2ecc71)、#N 灰度简写、vec4(r,g,b,a) RGBA 浮点、theme.* 主题变量。颜色支持运算:乘法用于透明度、mix(colorA, colorB, 0.5) 用于混色。
运行时切换主题
可在 Rust 事件处理器中动态切换,例如在 handle_actions 中判断按钮点击后执行 script_eval! 将 mod.theme 设为 mod.themes.dark 或 mod.themes.light,所有使用 theme.* 的控件会取用新值,可能需触发重渲染。也可在 App::run 中于控件加载前切换,作为静态主题选择。
完整示例与最佳实践
文档提供了一套仅使用主题变量的主题感知卡片列表示例,包含 CardItem 定义与包含标题、卡片列表、页脚的窗口布局,展示 draw_bg.color、draw_text.text_style、padding 等如何引用主题变量。最佳实践要求生产应用始终使用 theme.* 颜色,不要硬编码 #ff0000,应使用 theme.color_error;使用主题字体保持排版一致,优先使用 theme.font_bold{font_size: theme.font_size_2}。
限制
资料未说明该主题系统的版本兼容范围、性能开销、自定义主题的完整扩展方式、非桌面平台的支持情况,以及相关错误处理细节,以上暂未提供。