16 KiB
FloatButton 桌面版架构设计
本文档定义 FloatButton 桌面版的最新设计定位、公共契约、状态模型、视觉主题关系和兼容边界。通用控件研发约束见 控件研发标准,内部实现原理见 FloatButton 桌面版实现原理,FloatButton Token 的专项设计见 FloatButton Token 设计,设计和契约变化记录见 FloatButton Changelog。
1. 控件定位
| 项 | 值 |
|---|---|
| NuGet 包 | AtomUI.Desktop.Controls |
| .NET 命名空间 | AtomUI.Desktop.Controls |
| AXAML 命名空间 | https://atomui.net |
| Gallery 页面 | controlgallery/AtomUIGallery/ShowCases/General/FloatButton |
| 控件状态 | Stable |
FloatButton 是 AtomUI 桌面控件体系中的悬浮动作按钮,用于页面或窗口边缘提供全局快捷操作、回到顶部、帮助和工具入口。
FloatButton 不负责普通表单提交按钮、菜单导航或复杂工具栏。这些职责应由业务层、组合控件或更专用的 AtomUI 控件承担。
主要源码入口:
src/AtomUI.Desktop.Controls/FloatButtonsrc/AtomUI.Controls/FloatButton
2. 设计语言
FloatButton 的设计语言围绕控件职责、可观察状态和主题契约组织,而不是围绕模板节点组织。
| 维度 | 含义 | FloatButton 中的表达 |
|---|---|---|
| 产品语义 | 控件在界面中承担的稳定职责。 | FloatButton 是 AtomUI 桌面控件体系中的悬浮动作按钮,用于页面或窗口边缘提供全局快捷操作、回到顶部、帮助和工具入口。 |
| 内容承载 | 用户数据、展示内容、集合项或操作入口如何进入控件。 | CloseIcon、Description、DescriptionTemplate、Icon。 |
| 状态反馈 | public API、内部状态和伪类如何形成用户可感知反馈。 | open/close、motion、visual option。 |
| 主题语义 | ControlTheme、SharedToken、控件 Token 和模板绑定如何表达视觉。 | FloatButton Token + ControlTheme。 |
3. API 与契约模型
FloatButton 的公共契约由 public/protected 类型成员、Avalonia 属性、事件、命令、template part、伪类、ControlTheme key 和资源 key 共同组成。维护时应先确认这些契约是否已经被源码、Gallery 示例或文档暴露。
核心 public surface 按语义分组维护:
| 契约组 | 代表成员 | 维护含义 |
|---|---|---|
| 内容与数据 | CloseIcon、Description、DescriptionTemplate、Icon |
定义控件展示内容、输入数据、模板或业务对象入口。 |
| 选择与集合 | BadgeCount、BadgeOverflowCount、IsTriggerMode |
维护选择、展开、过滤、分页、分组或集合状态。 |
| 命令与动作 | Command、CommandParameter、Href |
通过 Avalonia Button 命令语义触发业务动作;host 只做投影转发,不自行执行命令。 |
| 交互与状态 | IsBadgeEnabled、IsDotBadge、IsMotionEnabled、IsOpen |
表达用户可观察状态、可用性、清除、加载或反馈语义;FloatButtonGroup.IsOpen 与 FloatButtonGroupHost.IsOpen 默认双向绑定。 |
| 视觉与布局 | BadgeColor、BadgeOffset、BoxShadow、FloatOffsetX、FloatOffsetY、MenuPlacement、Orientation、Placement、SeparatorBrush、Shape 等 12 项 |
影响尺寸、位置、颜色、形状、密度和模板视觉变量。 |
| 动效与异步 | MenuMotionDuration、MotionDuration、ToTopDuration |
约束动效开关、异步加载、播放速度、超时和任务边界。 |
| 其他稳定入口 | ButtonType、Target、Tooltip、Trigger |
保留为 public surface,变更前需确认 Gallery 和用户 XAML 依赖。 |
稳定事件包括 Clicked、Closed、Opened。事件触发顺序属于兼容契约,不能因内部状态重排而改变。
FloatButton 本体继承 Avalonia Button 命令契约,Command、CommandParameter、CanExecute 和禁用状态必须遵循 Avalonia 原生按钮语义。FloatButtonHost 与 BackTopFloatButtonHost 是 overlay host/adaptor,公开的 Command 和 CommandParameter 必须投影到运行时创建的真实按钮;host 不直接调用 ICommand.Execute,也不复制一套命令状态机。
FloatButtonGroupHost 的 Trigger 是展开/收起语义,不默认承载业务 Command。业务动作应绑定在 group 内部的 FloatButton 子项上;这些子项必须能继承 host 的 DataContext,同时不得覆盖子项显式设置的本地 DataContext。
IsOpen 是用户可拥有的受控打开状态,Avalonia Binding 默认使用 TwoWay;hover、click 和 host 转接触发的打开/关闭都必须回写同一 public 属性。该状态不是 Form value,不写入 DataValidationErrors。
主要公开类型与枚举:
- 类型:
AbstractBackTopFloatButton、AbstractBackTopFloatButtonHost、AbstractFloatButton、AbstractFloatButtonHost、BackTopFloatButton、BackTopFloatButtonHost、FloatButton、FloatButtonGroup、FloatButtonGroupHost、FloatButtonHost、FloatButtonItemsControl、FloatButtonSeparatorLayer。 - 枚举:
FloatButtonGroupMenuPlacement、FloatButtonGroupTrigger、FloatButtonPlacement、FloatButtonShape、FloatButtonType。
稳定 template part:
| Template Part | 类型 | 职责 |
|---|---|---|
PART_BadgeLayout |
Canvas |
稳定模板协作入口,重命名前必须同步主题和实现。 |
PART_ItemsLayout |
? |
承载集合项、布局面板或虚拟化内容。 |
控件专属或内部伪类包括 ButtonPseudoClass.IconOnly。这些伪类属于主题 selector 可观察契约,不能在未同步主题和 Gallery 的情况下重命名或删除。
4. 行为与状态模型
FloatButton 的状态流按以下路径收敛:
Public API / inherited command / item source / user input
-> 控件实例状态
-> effective state / pseudo-class / template property
-> ControlTheme selector / presenter / renderer
-> Gallery 可观察行为
状态维护规则:
- Disabled 或不可交互状态优先屏蔽 pointer、keyboard、motion 和提交类反馈。
Command.CanExecute=false必须通过 Avalonia Button 语义反映为不可执行状态;BackTop 场景下不可执行命令也应阻止回到顶部动作。- open/close、motion、visual option 状态由控件实例或明确的数据 owner 推导,不能在 template part 之间双向竞争。
IsOpen是默认TwoWay的受控状态;交互路径应使用 current value 语义更新,不得用样式优先级写入破坏用户绑定。- Host 创建的 overlay 按钮只能接收 host 公共属性投影;命令执行、
CanExecute、事件顺序和禁用状态仍由真实FloatButton作为交互 owner。 - Group host 搬移子按钮到 overlay group 时必须保留原有绑定语义,使未设置本地
DataContext的子项继承 host 数据上下文。 - 模板重套用时必须把 public API 对应状态回放到新的 part、伪类和主题变量。
- 集合、弹层、异步、动效或窗口相关状态必须能处理 reset、close、cancel、detach 和 owner 释放。
5. 视觉与主题模型
FloatButton 的视觉模型由控件模板、ControlTheme、SharedToken 和必要的控件 Token 共同构成。
| 主题文件 | 职责 |
|---|---|
AbstractFloatButtonTheme.axaml |
定义局部操作入口、按钮或 handle 的状态视觉。 |
BackTopFloatButtonHostTheme.axaml |
定义局部操作入口、按钮或 handle 的状态视觉。 |
BackTopFloatButtonTheme.axaml |
定义局部操作入口、按钮或 handle 的状态视觉。 |
FloatButtonGroupHostTheme.axaml |
定义局部操作入口、按钮或 handle 的状态视觉。 |
FloatButtonGroupTheme.axaml |
定义局部操作入口、按钮或 handle 的状态视觉。 |
FloatButtonHostTheme.axaml |
定义局部操作入口、按钮或 handle 的状态视觉。 |
FloatButtonItemsControlTheme.axaml |
定义集合项、容器项或局部单元的状态视觉。 |
FloatButtonTheme.axaml |
定义局部操作入口、按钮或 handle 的状态视觉。 |
FloatButton 使用 FloatButtonToken 作为控件 Token scope。Token 只表达组件视觉语义,不承载 open/close、motion、visual option 运行时状态。
主题维护规则:
- 不删除或重命名已经稳定的 ControlTheme key、template part、伪类和资源 key。
- 不把可由 AXAML 表达的模板状态迁移为 C# 动态创建视觉。
- 不把 hover、pressed、selected、expanded、loading、filter、popup open 等运行时状态写入 Token。
- Browser 或平台特化主题必须保持同一 API 的语义一致。
6. 控件家族或集成关系
FloatButton 与同分类控件共享尺寸、状态、Token、Gallery 展示和验证规则。组合或派生控件应显式说明哪些 API 被继承、覆盖或不支持。
主要协作类型:
AbstractBackTopFloatButton:跨平台或共享基类,承载公共 API、状态归一和模板生命周期。AbstractBackTopFloatButtonHost:跨平台或共享基类,承载公共 API、状态归一和模板生命周期。AbstractFloatButton:跨平台或共享基类,承载公共 API、状态归一和模板生命周期。AbstractFloatButtonHost:跨平台或共享基类,承载公共 API、状态归一和模板生命周期。AbstractFloatButtonTheme:ControlTheme 类型入口,连接主题资源和控件类型。BackTopFloatButton:动作触发类型,负责点击、导航或局部操作状态。BackTopFloatButtonHost:模板协作类型,承载内容展示、宿主或视觉边界。FloatButton:动作触发类型,负责点击、导航或局部操作状态。FloatButtonGroup:控件核心或内部协作类型,维护 public surface 与主题可观察行为。FloatButtonGroupHost:模板协作类型,承载内容展示、宿主或视觉边界。FloatButtonHost:模板协作类型,承载内容展示、宿主或视觉边界。FloatButtonItemsControl:控件核心或内部协作类型,维护 public surface 与主题可观察行为。FloatButtonSeparatorLayer:控件核心或内部协作类型,维护 public surface 与主题可观察行为。FloatButtonToken:控件 Token scope,负责从全局 token 派生控件语义变量。
集成关系:
- 与 ThemeManager、SharedToken、ControlTheme、控件文档和 Gallery ShowCase 示例保持一致。
- 涉及 ItemsSource、Popup、Flyout、Window、Form 或 CompactSpace 的路径必须保持生命周期释放和数据状态同步。
- 源码目录中的共享基类和内部协作类型形成维护边界,不能只修改桌面包装类而忽略共享状态 owner。
- Host 家族负责把 public API 投影到 overlay 中真实交互控件;交互控件本体仍是命令、点击、禁用和焦点语义 owner。
7. 兼容性不变量
维护 FloatButton 时必须保持以下不变量:
- 不擅自新增、删除、重命名或改变 public/protected API、Avalonia 属性、事件和默认值。
- 不破坏 template part、伪类、ControlTheme key、Token 名称和资源 key。
- 不改变 Gallery 已展示的 XAML 用法、默认外观、交互顺序和状态优先级。
- 不手动绕过 Avalonia Button 命令机制执行
ICommand;所有命令状态必须由真实FloatButton统一承载。 - 不让 overlay 搬移破坏 group 子按钮的
DataContext继承,也不覆盖子项显式设置的本地数据上下文。 - Template part 重新应用、集合替换、弹层关闭、窗口失活和控件 detach 时必须释放旧订阅和资源宿主。
- 不通过隐藏延迟、强制刷新或吞异常掩盖状态同步问题。
- 不引入运行时反射扫描作为 API、Token 或数据路径发现机制。
- 文档只描述当前稳定设计;历史变化记录在
changelog.md。
8. 专项模型
8.1 选择与当前项模型
FloatButton 的当前项状态必须由单一 owner 推导。public 选择属性、集合项容器和伪类之间只能做单向同步,集合替换、清空和模板重套用时必须回放当前状态。
8.2 弹层与宿主模型
FloatButton 涉及弹层、窗口或 overlay 宿主时,打开状态、取消事件、定位和宿主释放必须保持一致。重复打开、关闭、窗口失活和 template reapply 都必须释放旧宿主引用。
8.3 动效模型
FloatButton 的动效只表达状态变化反馈,不应改变 public API 语义。初始加载、禁用态和卸载路径应能抑制或取消动效,避免保留旧控件实例。
8.4 视觉选项模型
FloatButton 的视觉选项通过 public API 归一为 theme variables、伪类或模板绑定。Token 保存组件语义值,不能保存实例运行时状态或业务色值。
8.5 命令与 overlay 投影模型
FloatButton 家族的业务命令只属于真实交互按钮。普通 FloatButton 直接使用 Avalonia Button 命令模型;host 类型只负责把 Command、CommandParameter、视觉属性和数据上下文投影给 overlay 中创建的真实按钮。FloatButtonGroupHost 的 trigger 负责展开/收起,不默认表达业务动作命令;group 内部子 FloatButton 通过继承 host DataContext 绑定业务命令。
该模型保证 host、overlay 和 group 搬移不会形成第二套命令系统,也不会让 CanExecute、禁用状态、点击事件顺序和 BackTop 行为出现分裂。
9. 文档导航、LLMS 导出与验证策略
关联文档:
LLMS 语义区域:
| Part | AtomUI 节点 | 职责 | 相关 API | 相关 Token | 稳定性 |
|---|---|---|---|---|---|
root |
FloatButton |
控件根语义区域,承载 public API、状态归一、主题入口和 Gallery 可观察行为。 | 见 API 与契约模型 | 见视觉与主题模型 | stable |
content |
内容区域 |
承载用户内容、图标、文本或装饰性展示。 | 见 API 与契约模型 | 见视觉与主题模型 | stable |
command |
真实 FloatButton |
承载 Command、CommandParameter、CanExecute、点击和禁用语义;host 只做投影。 |
Command、CommandParameter、Href |
见视觉与主题模型 | stable |
state |
状态区域 |
表达 hover、pressed、disabled、loading、selected 或控件专属状态。 | 见 API 与契约模型 | 见视觉与主题模型 | stable |
theme |
主题区域 |
连接 ControlTheme、SharedToken、控件 Token 和资源键。 | 见 API 与契约模型 | 见视觉与主题模型 | stable |
LLMS 导出来源:
| LLMS 内容 | 来源 | 说明 |
|---|---|---|
| 单控件完整文档 | overview.md + implementation.md + token.md + Gallery ShowCase |
生成 controls/float-button/index-cn.md |
| 单控件语义文档 | overview.md + implementation.md + theme/template 信息 |
生成 controls/float-button/semantic-cn.md |
| API 表 | overview.md 语义摘要 + 源码 public surface | 不在 overview.md 中复制完整 API 表 |
| Design Token 表 | token.md、Token 类型或第 5 节主题模型 | 不在生成产物中手工维护第二份 Token 表 |
| 示例 | Gallery ShowCase + source snippet catalog | 只引用稳定示例 |
| 源码索引 | implementation.md |
用于定位控件源码、主题和测试 |
验证策略:
| 改动类型 | 验证要求 |
|---|---|
| 文档改动 | 运行 git diff --check,检查相对链接存在。 |
| Public API | 覆盖属性默认值、事件触发、命令和继承语义。 |
| 状态模型 | 覆盖 open/close、motion、visual option、disabled、hover、pressed、focus 以及控件特有状态。 |
| AXAML/Theme | 检查 template part、伪类、资源 key、Light/Dark 主题和 Browser 主题。 |
| Token | 检查 TokenKind、AXAML token resource、Token 类型、生成数据和 token.md和文档同步。 |
| Gallery | 走查对应 ShowCase 示例和源码片段入口。 |