Skip to content

UI 插槽 ​

宿主界面上可被插件替换的组件位置。声明在 mod.json 的 ui_extensions 里。


槽位清单 ​

✅ 已消费(可替换) ​

槽位位置互斥
overlay_background字幕悬浮窗底板✅
caption_view字幕内容视图✅
audio_level右下角音柱 / 波形条✅
alert_capsule悬浮提示胶囊✅
overlay_decorations悬浮窗装饰层✅
style_bar_actions字幕条控制栏的自定义动作按钮❌
settings_background设置中心底板✅
history_background历史记录窗底板✅
dialog_background通用弹窗底板✅
window_background通用窗口底板✅
copilot_windowAI 助手顶层浮窗✅
settings_view插件独立设置表单(特殊,不在标准列表里,不互斥)❌

❌ 声明了但当前无 Loader 消费(勿依赖) ​

  • overlay_root
  • style_bar

互斥规则 ​

  • 上表标记 ✅ 的槽位同级互斥:同一槽位同时只能有一个插件生效。
  • 全量主题(style_layer=full)与局部 UI 插槽扩展可以并存 —— 启用波形条插件不会把用户的主题踢下线。
  • 同类局部挂件的互斥只在同为局部(两边都不是 full 主题)时发生。
  • settings_view 永不互斥。

级联回退:窗体会按 专用槽 → window_background → overlay_background 顺序找可用的插件背景, 找不到就用官方原生底座。具体链:

窗口回退链
AI 助手浮窗copilot_background → window_background → overlay_background
对话框 / 模态dialog_background → window_background → overlay_background
设置中心 / 历史窗window_background → overlay_background

因此只写 overlay_background 时,其它窗口也可能复用你的底板风格—— 反过来说,写了专用槽就不必再担心别的窗口忘了改。

插槽决议优先级 ​

同一个插槽同时有多个候选时,按下面顺序决议:

  1. 局部专用 UI 扩展(如已启用的独立波形条插件)优先接管该插槽;
  2. 未声明局部扩展 → 回退到当前活跃全量主题自带的插槽组件;
  3. 都没有 → 回退到官方原生默认组件(停用局部扩展后自动无感回退)。

声明 ​

json
{
  "type": "theme",
  "style_layer": "effects",
  "ui_extensions": {
    "audio_level": "CustomWaveform.qml",
    "overlay_background": "MyBackground.qml"
  }
}

路径是相对插件目录。


背景插槽准则 ​

声明了 overlay_background / settings_background / history_background / dialog_background / window_background 任一,必须遵守:

1) 边框绘制责任(必须自绘) ​

宿主加载插件背景时,会自动隐去官方原生的 1px 晶体高光外边框(防双重叠线)。 所以插件背景必须自己画窗口外边缘 / 边框 / 外发光(双色霓虹渐变框、金属倒角、高光描边…)。 只填纯色不画边框 → 窗口会变成光秃秃的无边框矩形。

2) 圆角自适应 ​

宿主通过 customRadius 注入目标窗口的原生圆角(设置中心 16、历史窗 16、通用弹窗 12…)。 组件应声明 property bool enforceCustomRadius: false,并在 customRadius 变化时自适应; 不要硬编码极小圆角(如 customRadius: 2)——会出现突兀生硬的直角切边。

3) 上下文属性透传 ​

属性内容
window / targetWindow目标窗体实例(可探测 window.activeFocus / window.hovered)
appState全局应用状态(appState.bgColor / bgOpacity / neonBorderColor…)
hostContext悬浮窗专用上下文(style / subtitle / audio / invoke)
hovered悬浮窗当前是否鼠标悬停

4) 配置项热响应(最容易踩的坑) ​

⚠️ bridge.getPluginConfig(pluginId) 是瞬态函数调用,不是 QML 响应式属性。 你在 mod.json 定义了 neon_glow / hud_brackets 这种开关,必须监听 bridge.pluginConfigChanged,否则用户在设置面板切开关时运行中的窗口毫无反应。

qml
import QtQuick 2.15

Item {
    id: root
    anchors.fill: parent

    readonly property string myPluginId: "community.theme.my_theme"

    property var cfg: (typeof bridge !== "undefined" && bridge && bridge.getPluginConfig)
        ? bridge.getPluginConfig(root.myPluginId) : ({})

    readonly property bool enableGlow: (cfg && typeof cfg.neon_glow !== "undefined") ? cfg.neon_glow : true
    readonly property bool enableBrackets: (cfg && typeof cfg.hud_brackets !== "undefined") ? cfg.hud_brackets : true

    Connections {
        target: (typeof bridge !== "undefined") ? bridge : null
        function onPluginConfigChanged(pid) {
            if (pid === root.myPluginId) {
                root.cfg = bridge.getPluginConfig(root.myPluginId) || ({})
            }
        }
    }

    Rectangle {
        anchors.fill: parent
        visible: root.enableGlow
        border.color: "#00f0ff"
        border.width: 1.5
    }
}

窗口材质 window_backdrop ​

仅 theme.json 顶层(写进 mod.json 会被忽略):acrylic | mica | mica_alt | blur | none。 见 theme。


参考实现 ​

目录演示
extensions/example_theme_cyberpunk/full 主题 + 5 个插槽(含 decorations)
extensions/community_theme_glassmorphism/玻璃质感全套背景
extensions/example_custom_waveform_ui/只换 audio_level 的局部扩展(style_layer: effects)

相关 ​

TransBox - 赋能全人类无界限跨语言交流