内置属性和 FatObj
Ribir 提供了一个强大的内置属性系统,让您可以为任何 Widget 添加常用功能,如布局控制(margin、alignment)、视觉效果(background、border、opacity、transform)和交互事件(on_tap、on_hover)。这些功能并非由每个 Widget 单独实现,而是通过一个称为 FatObj 的通用包装器统一提供。
@ 实例化过程
当您在 fn_widget! 中使用 @ 语法通过类型来声明(例如 @Text { ... })时,Ribir 会执行以下步骤来构建 Widget:
- 获取 Builder: 调用
Declaretrait 的declarer()方法来获取该 Widget 的 Builder。 - 初始化字段: 对于
{ ... }块中指定的每个字段,调用 Builder 上相应的with_xxx()方法(例如with_text(...))。 - 完成构建: 最后,调用 Builder 的
finish()方法(Builder 实现了ObjDeclarertrait)来完成构建并返回已声明的 Widget。
#[derive(Declare)] 的作用
为了支持上述过程,#[derive(Declare)] 宏会自动为您的 Widget 生成必要的代码:
-
它创建了一个 Builder 结构体(例如
Text的TextBuilder)。 -
它为您的 Widget 实现了
Declaretrait,将其与构建器关联。 -
它生成了
with_xxx方法,让您可以流畅地设置值。 -
它为 Builder 实现了
ObjDeclarer,这处理了最终的构建步骤finish()并返回FatObj<Stateful<T>>(其中T是正在构建的 Widget 类型)。 -
它还会生成一个方便的宏以便简单使用。例如,在用
#[derive(Declare)]定义Text之后,它还会生成text! { ... }宏,这在fn_widget!中相当于fn_widget! { @Text { ... } }。注意因为它是通过fn_widget!生成的,这个宏在语义上是一个惰性的函数。如果你用@text! {}而不是@Text {},就无法在外部访问Text的结构 字段。
注意: Ribir 还提供了 #[simple_declare] 宏,该宏会为您的 Widget 生成一个简化的 Builder,该 Builder 最终将返回 T。这适用于不需要内置属性或复杂状态管理的简单 Widget。
什么是 FatObj?
FatObj<T> 是 Ribir 核心库中的一个泛型结构体,其作用是在构建阶段临时包装一个 Widget,并为其附加各种内置属性,例如 margin、background、on_tap 等。
工作原理
- 惰性初始化:
FatObj在内部维护所有内置属性(如margin、padding等)的状态,但它们默认为空。只有在您显式使用某个属性时,相关的 Widget 才会被初始化。这确保了未使用的功能不会产生额外的性能开销。 - 组合: 在 Widget 构建的最后阶段,
FatObj会将它包装的 Widget 与已启用的内置功能(如Padding、Container、MixBuiltin等)组合成最终的 Widget 树。
例如:Margin(MixBuiltin(Text))
常见内置属性
内置属性主要分为两类:属性和事件。
1. 属性
这些属性用于控制 Widget 的外观和布局。
-
布局:
margin: 设置外边距。padding: 设置内边距。h_align/v_align: 设置水平/垂直对齐。anchor: 用于Stack布局中的绝对定位。global_anchor_x/global_anchor_y: 用于相对于全局窗口的定位。clamp: 强制对 Widget 大小范围的约束(布局约束)。box_fit: 控制子元素如何适应容器空间(如填充、包含等)。scrollable: 控制 Widget 的滚动行为(X轴、Y轴或两者)。layout_box: 控制布局框行为。
-
视觉:
background: 设置背景(颜色或图像)。foreground: 设置前景(通常覆盖在内容之上)。border: 设置边框。box_shadow: 设置盒阴影(围绕盒子的外部阴影效果)。radius: 设置边框半径。backdrop: 设置背景效果。opacity: 设置不透明度。visible: 控制可见性。transform: 应用图形变换(平移、旋转、缩放)。cursor: 设置悬停时的光标样式。backdrop_filter: 应用背景滤镜效果(如模糊)。filter: 应用视觉滤镜效果(模糊、灰度、亮度等)。clip_boundary: 是否裁剪边界之外的内容。painting_style: 设置绘画样式(填充或描边)。
-
文本(通常由子节点继承):
text_style: 设置字体样式。text_align: 设置文本对齐。text_line_height: 设置行高。font_size: 设置字体大小。font_face: 设置字体系列。
-
其他:
keep_alive: 保持 Widget 状态即使从视图中移除。tooltips: 设置工具提示文本。disabled: 禁用 Widget 及其子项的交互。providers: 为 Widget 设置提供者上下文。class: 应用样式类。reuse: 通过设置 reuse 属性,可以重用 Widget。如果是局部的复用,可结合LocalWidgets使用。
2. 事件
这些属性用于处理用户交互。所有事件回调都会接收一个事件对象。
-
指针事件:
on_pointer_down: 在指针(鼠标按钮、触摸接触、笔)按下时触发。on_pointer_move: 在指针移动时触发。on_pointer_up: 在指针释放时触发。on_pointer_cancel: 在指针事件被取消时触发(例如,触摸中断)。on_pointer_enter: 在指针进入 Widget 区域时触发。on_pointer_leave: 在指针离开 Widget 区域时触发。on_tap: 在点击或轻触(按下和释放序 列)时触发。on_tap_capture:on_tap的捕获阶段版本。on_double_tap: 在双击时触发。on_triple_tap: 在三击时触发。on_x_times_tap: 在指定次数的点击时触发。
-
滚轮事件:
on_wheel: 在鼠标滚轮滚动时触发。on_wheel_capture:on_wheel的捕获阶段版本。on_wheel_changed: 在滚轮增量变化时触发。
-
键盘事件:
on_key_down: 在按键按下时触发。on_key_down_capture:on_key_down的捕获阶段版本。on_key_up: 在按键释放时触发。on_key_up_capture:on_key_up的捕获阶段版本。
-
焦点事件:
on_focus: 在 Widget 获得焦点时触发。on_blur: 在 Widget 失去焦点时触发。on_focus_in: 在 Widget 或其后代之一获得焦点时触发(冒泡)。on_focus_out: 在 Widget 或其后代之一失去焦点时触发(冒泡)。
-
生命周期事件:
on_mounted: 在 Widget 挂载到 Widget 树时触发。on_performed_layout: 在 Widget 布局完成后触发。on_disposed: 在 Widget 从 Widget 树中移除时触发。
-
IME 事件:
on_ime_pre_edit: 在 IME 预编辑期间触发(例如,组成文本)。on_chars: 在接收文本字符时触发。