Files
一把伞南星andfanlusky 71960b8301 feat(server,ui): 悬浮工具栏图片模式与装饰图叠加候选词 (#1046)
* feat(server,ui): 悬浮工具栏图片模式与装饰图叠加候选词

在 #1046 的基础上按最新 develop 重做。

悬浮工具栏 [toolbar] mode = "image":一整张背景图,按钮按
[toolbar.buttons.<按钮>] 的 x_dip / y_dip / width_dip / height_dip 摆放,
可按状态换图([images]),没图时画矢量图标。窗口按背景图的透明区域裁成
异形,透明处点得穿;图上除按钮外都能拖动。v2 皮肤的动图会播放,工具栏
隐藏或淡出后停帧。

候选窗装饰图可用 candidate_overlay_* 叠加一个候选词,太宽时缩字号;
设置页的皮肤预览一并显示。

ui 新增 OverlayPanel(绝对定位)与 ImageMask(按 alpha 生成区域)。

* fix(ui): 动图工具栏的窗口形状取所有帧的并集

窗口区域连画面一起裁,只按首帧裁形状时,动画里伸出首帧轮廓的部分
(抬头、飞出的纸)会被裁掉。改为把所有帧的 alpha 合起来再生成区域。

* fix(server): 工具栏按钮框始终算在异形窗口里

窗口形状只取背景图不透明的部分时,摆在图片透明处的按钮会被一起裁掉、
点不到。形状改为背景图轮廓并上每个按钮的框,按钮可以放在人物旁边的空白处,
不必在背景图里垫底。

* feat(server): 工具栏按钮可单独设内置图标的字号

[toolbar.buttons.<按钮>] 新增 icon_size_dip,内置 Segoe Fluent Icons 图标的
字号不再只能跟着按钮框走:按钮框铺满背景图里的圆底、图标单独调大小。
不写时仍是按钮框短边的 0.82 倍。

* feat(server): 设置页按图片模式预览悬浮工具栏

皮肤页的卡片与悬浮工具栏页的预览原来只会画矩形条。皮肤是图片模式时,
改按工具栏的画法预览:背景图(v2 皮肤的动图会播放)、按皮肤坐标摆放的
按钮、按钮贴图或内置图标(含 icon_size_dip),设置页关掉的按钮不画,
缩放与图标尺寸设置一并生效。

---------

Co-authored-by: fanlusky <1730976608@qq.com>
2026-10-20 23:08:01 +08:00

13 KiB
Raw Permalink Blame History

msime-skins

水杉输入法(Metasequoia IME)的外部皮肤合集。

皮肤列表

目录 名称 说明
green_leaf 绿叶 官方贴图皮肤(canvas 全贴图,原 canvas-demo):深色夜蓝、浅色薄荷白的九宫格玻璃面板,面板后探出的叶子与右上角闪烁的 APNG 星光。设置页把它列在内置皮肤之后,不在「外部皮肤」里
sakura-night 夜樱 v2 全贴图皮肤(canvas,取自 examples/skin-examples):紫夜玻璃九宫格面板、面板后的月亮、APNG 飘落花瓣与 GIF 闪烁星星
acrylic 亚克力 Acrylic 候选卡片背后垫系统亚克力,模糊后面的窗口
mica 云母 Mica 候选卡片背后垫系统云母,取样桌面壁纸(Windows 11;更早的系统按亚克力画)
niya-demo Niya Demo 官方外部皮肤样例:候选框上方的人物装饰图、星点背景图、12dip 圆角,以及配套的悬浮工具栏配色
bigfish 蓝色大肥鱼 鲸鱼女仆角色装饰、海底气泡背景,深海蓝配色搭配金色序号
bigfish-national-day 大肥鱼·国庆 红裙敬礼的大肥鱼站在卡片右上方、金色星星背景,中国红高亮搭配金色序号
bigfish-peek 大肥鱼·探头 黑白女仆装的大肥鱼从卡片上沿探出头、气泡与蕾丝背景,深蓝底色搭配浅蓝高亮
qq-blue QQ 经典蓝 腾讯 QQ 配色:亮蓝光标与序号,深蓝选中块
sogou 搜狗经典 搜狗经典配色:白底、蓝色候选、橙红高亮、红色光标
sogou-classic 搜狗经典·石墨 基于石墨,仿经典搜狗:白底浅蓝边框、蓝字候选、首选红字不铺底色、拼音下方浅蓝分隔线
wechat_glass 微信玻璃 移植自 rime-wechat-glass 的微信绿配色与紧凑几何,磨砂玻璃用自绘噪点底图近似

除 sogou-classic 基于 graphite、shoudao-blue 基于 willow_green、green_leaf 与 sakura-night 基于 canvas 外,其余皮肤均基于 fluent;全部支持横排 / 竖排布局以及深色 / 浅色主题。

官方皮肤包的名单在 Server 的 CandidateSkinCatalog::OfficialPackageIds()(目前只有 green_leaf)。它们和其他随包皮肤一样装到 skins\<id>、照外部皮肤加载,只是设置页的展示位置不同;用户删掉目录后设置页就不再列出。

所有皮肤的悬浮工具栏拖动条([toolbar.*].handle)都与同一主题的 accent 同色,没写 handle 时自动取 accent;examples/skin-examples/tests/test_manifests.py 会检查写了的两者是否一致。

内置皮肤(default/)

default/ 不是外部皮肤,而是七个内置皮肤(fluent、wechat、wechat_scroll、graphite、willow_green、autumn_osmanthus、microsoft)与全贴图基底 canvas 的出厂清单:皮肤级的开关和完整外观(配色、圆角、版式、悬浮工具栏)都写在这里,候选框与悬浮工具栏按它绘制,输入法的代码里不再写死任何一个内置皮肤的参数。canvas 不能单独选用,开关沿用 fluent 的。

  • 这些清单在构建时编进程序,同时随安装包放到数据目录的 skins\default\<id>\skin.toml,每次安装或升级都整份覆盖。
  • 数据目录里那一份写了的键会覆盖出厂值,所以技术上可以直接改;但不建议这样做,升级会冲掉改动。那份清单缺失或有一项写错时,整份退回出厂外观。
  • 想要自己的样式,复制一个内置清单的内容到 skins\<新 id>\skin.toml 做成外部皮肤:补上 version、base(填这个内置皮肤的 id)和 [supports],只留想改的键即可。

外部皮肤没写的开关与外观都沿用它 base 对应的这份清单。清单里除了下面「皮肤结构」一节的通用键,还有这些只跟开关相关的键:

表 / 键 说明
schema_version / id / name / description id 必须与目录名一致;name 与 description 是设置页皮肤卡片上的名称和说明
[candidate_window] page_arrows 候选框里是否显示翻页箭头(true / false;只有 microsoft 出厂打开)
[candidate_window] fit_content 候选框是否严格按文字所需的宽度收紧(true / false,出厂关闭)。打开后不再垫出厂的最小宽度(160 DIP),同一次输入里后到的翻译等内容消失时宽度也立刻跟着缩回
[candidate_window] expand_panel 横排候选是否用卷轴展开代替翻页(true / false,出厂关闭),见下文卷轴展开

改完后在设置页刷新皮肤列表,或重新选择一次皮肤即可生效。设置页「外观」和「皮肤」里的候选框预览目前仍按内置样式绘制,只跟随这几个开关。

安装

除 niya-demo(素材授权未核实)外,这里的皮肤都随安装包装到数据目录的 skins\<id>。用户那边已有同名皮肤且内容和随包的不一样(改过、多了或少了文件)时,安装器先把它改名成 <id>.bak 保留下来(已有 .bak 则用 <id>.2.bak……),再装新版本;输入法不会把 .bak 目录列成皮肤。

手动安装时,把想用的皮肤目录整个复制到:

%LOCALAPPDATA%\metasequoiaime\skins\

例如 %LOCALAPPDATA%\metasequoiaime\skins\qq-blue\skin.toml,然后在输入法设置中选择对应皮肤即可。

皮肤结构

每个皮肤是一个独立目录,至少包含一个 skin.toml,图片等资源放在目录内(如 assets/):

my-skin/
├── skin.toml
└── assets/          # 可选
    ├── background.png
    └── character.png

skin.toml 主要字段:

表 / 键 说明
schema_version 皮肤格式版本,1 或 2;2 是全贴图皮肤,必须以 canvas 为 base
id / name / version / author / description 基本信息,id 建议与目录名一致
base 继承的内置皮肤,如 fluent;未写的键沿用 base。canvas 是只给 v2 皮肤用的全贴图基底(透明面板,外观来自九宫格面板图与挂件),不能单独选用,见 schema 说明
[supports] layouts(horizontal / vertical)、themes(dark / light)
[candidate_window] min_width_dip、corner_radius_dip(0–32)、border_width_dip(0–4)、item_corner_radius_dip(高亮圆角,0–16)、shadow(none / soft / strong)、font_family(排在用户字体前面)、page_arrows(翻页箭头:横排在候选右侧,竖排在最后一行下方、与序号左对齐;不写时沿用 base 的内置清单,出厂关闭)、fit_content(卡片严格按文字宽度收紧,min_width_dip 与装饰图宽度仍然生效;不写时沿用 base 的内置清单,出厂关闭)、expand_panel(横排卷轴展开,见卷轴展开;不写时沿用 base 的内置清单,出厂关闭)、expand_rows(展开后一屏的网格行数,2–8,缺省 4)
[candidate_window] 版式 长度可以写 DIP 数值,也可以写 "0.3em" 按候选字号缩放(换算后取整):padding(卡片内边距)、item_gap(候选项间距)、item_extra_height(候选项比 1.35 倍字号多出的高度)、number_inset(高亮左缘到序号的距离,不小于 5)、item_padding_right(候选文字后的留白)、item_min_width(横排每项最小宽度)、number_gap(序号与候选的间距)、selected_bar_width(选中竖条宽);以及 number_scale(序号字号比例)、selected_bar_height_em(选中竖条高,按字号倍数)、selected_bar_inside、item_corners_follow_card(落在卡片四角上的高亮角跟卡片同圆角)、justify_rows(横排时高亮铺满到卡片右边)、trim_hidden_preedit_gap、page_arrow_style(chevron / triangle)、preedit_margin_dip(预编辑行外边距,上右下左)
[candidate_window.horizontal] / [candidate_window.vertical] 同上的版式键,只对横排 / 竖排生效,并且优先于 [candidate_window] 里写的
[candidate_window.decoration] 卡片上方的装饰图:image、top_inset_dip、width_dip、align(left / center / right);candidate_overlay = true 时把一个候选词叠加在装饰图上,字号、颜色、对齐、偏移等见 schema 说明
[candidate_window.background] 卡片背景图:image、fit(cover / contain / stretch)、opacity(0–1)
[candidate.dark] / [candidate.light] 候选配色:accent、selected、hover、surface、border、text、number、translation、show_selected_bar;细分配色 candidate_text、preedit_text、preedit_caret、selected_text、selected_number、selected_translation、translation_pos、translation_separator、selected_translation_pos、selected_translation_separator、selected_bar、preedit_background、preedit_divider、page_arrow_divider(三角翻页箭头前的分隔线)
[candidate.dark.menu] / [candidate.light.menu] 候选窗右键菜单:background、border、text、hover
[candidate_window.border_image] v2 九宫格面板图:source、light_source(浅色主题换用的面板图,几何与 source 相同)、slice_dip、stretch_dip、width_dip、fill,见 schema 说明
[toolbar] / [toolbar.dark] / [toolbar.light] 悬浮工具栏:corner_radius_dip、icon_corner_radius_dip(图标悬停底色的圆角,0–16),以及 background、border、handle(不写时取同主题的 accent)、divider、icon、hover;mode = "image" 时整个工具栏换成一张背景图(image、image_width_dip、image_height_dip),窗口按图片透明区域裁成异形,按钮用 [toolbar.buttons.<按钮>] 的 x_dip、y_dip、width_dip、height_dip、icon_size_dip、visible、image 与按状态的 [images] 摆放,见 schema 说明
[license] code、assets、source:代码与素材的授权信息

所有颜色键([candidate.*] 里除 show_selected_bar 外的键、[candidate.*.menu] 与 [toolbar.*] 的全部键)都支持十六进制 #RGB、#RGBA、#RRGGBB、#RRGGBBAA,以及 rgb(r, g, b)、rgba(r, g, b, a) 和 transparent。十六进制必须带 #(清单格式的约定,与 CSS 写法一致;渲染器对不带 # 的写法有容错,但不要依赖它),不透明度在末尾(#RRGGBBAA,不是 #AARRGGBB),例如 rgba(224, 138, 168, 0.28) 与 #e08aa847 等价。图片路径相对于皮肤目录,且不能指向目录之外。完整的带注释示例见 niya-demo/skin.toml。

卷轴展开(expand_panel)

[candidate_window] expand_panel = true 把横排候选窗换成微信输入法式的卷轴展开,内置皮肤 wechat_scroll(微信绿(卷轴)) 就是这样配置的:

  • 候选行右端是一个“∨”按钮,不显示翻页箭头(这时 page_arrows 被忽略);设置页的横排预览也会画出这个按钮。
  • 点按钮展开:首行仍是当前页(带序号、可用数字键选),下面是后续候选的等宽网格,一屏是首行加 expand_rows 行网格,右侧一条细滚动条;点网格里的候选直接上屏。滚到底部时会自动再加载一批候选。
  • 滚轮:展开后首行与网格一起上下滚动,滚到顶或底就停住;其他皮肤的滚轮是翻页,两者互不影响。展开后的滚动不受设置里「滚轮翻页」开关约束;收起时滚轮和其他皮肤一样按这个开关翻页。
  • 展开与收起都只能点按钮(展开后变成“∧”,固定在右上角、不随内容滚动)。继续输入时保持展开,换了候选就回到顶部;候选窗关闭(上屏或取消输入)时收起。
  • 只在横排生效;竖排时照常显示候选列表与翻页。

展开按钮、滚动条用 number 色,网格的悬停底色用 hover,字体、字号、行高都跟随首行。外部皮肤写 base = "wechat_scroll" 就沿用这套卷轴展开和配色,也可以在任何外部皮肤里写 expand_panel = true 打开。

授权说明

本仓库以 GNU General Public License v3.0 开源。单个皮肤如在 skin.toml 的 [license] 中另有声明,以该声明为准。

niya-demo 中的图片素材授权尚未核实(assets = "UNVERIFIED-DEMO-ONLY"),仅作演示用途,请勿直接用于再分发的皮肤。