name: gpui-element description: 使用 GPUI 的低级 Element API(相对于高级 Render/RenderOnce API)实现自定义元素。当您需要对布局、预绘制和绘制阶段进行最大控制,以实现复杂、性能关键的自定义 UI 组件,而 Render/RenderOnce 特性无法实现时使用。
何时使用
使用低级 Element 特性时:
- 需要对布局计算进行细粒度控制
- 构建复杂、性能关键的组件
- 实现自定义布局算法(如 masonry、circular 等)
- 高级
Render/RenderOnceAPI 不足时
优先使用 Render/RenderOnce 用于: 简单组件、标准布局、声明式 UI
快速入门
Element 特性提供对三个渲染阶段的直接控制:
impl Element for MyElement {
type RequestLayoutState = MyLayoutState; // 传递给后续阶段的数据
type PrepaintState = MyPaintState; // 用于绘制的数据
fn id(&self) -> Option<ElementId> {
Some(self.id.clone())
}
fn source_location(&self) -> Option<&'static std::panic::Location<'static>> {
None
}
// 阶段 1: 计算大小和位置
fn request_layout(&mut self, .., window: &mut Window, cx: &mut App)
-> (LayoutId, Self::RequestLayoutState)
{
let layout_id = window.request_layout(
Style { size: size(px(200.), px(100.)), ..default() },
vec![],
cx
);
(layout_id, MyLayoutState { /* ... */ })
}
// 阶段 2: 创建命中框,准备绘制
fn prepaint(&mut self, .., bounds: Bounds<Pixels>, layout: &mut Self::RequestLayoutState,
window: &mut Window, cx: &mut App) -> Self::PrepaintState
{
let hitbox = window.insert_hitbox(bounds, HitboxBehavior::Normal);
MyPaintState { hitbox }
}
// 阶段 3: 渲染和处理交互
fn paint(&mut self, .., bounds: Bounds<Pixels>, layout: &mut Self::RequestLayoutState,
paint_state: &mut Self::PrepaintState, window: &mut Window, cx: &mut App)
{
window.paint_quad(paint_quad(bounds, Corners::all(px(4.)), cx.theme().background));
window.on_mouse_event({
let hitbox = paint_state.hitbox.clone();
move |event: &MouseDownEvent, phase, window, cx| {
if hitbox.is_hovered(window) && phase.bubble() {
// 处理交互
cx.stop_propagation();
}
}
});
}
}
// 使元素可用作子元素
impl IntoElement for MyElement {
type Element = Self;
fn into_element(self) -> Self::Element { self }
}
核心概念
三阶段渲染
- request_layout: 计算大小和位置,返回布局 ID 和状态
- prepaint: 创建命中框,计算最终边界,准备绘制
- paint: 渲染元素,设置交互(鼠标事件、光标样式)
状态流
RequestLayoutState → PrepaintState → paint
状态通过关联类型单向流动,在阶段之间作为可变引用传递。
关键操作
- 布局:
window.request_layout(style, children, cx)- 创建布局节点 - 命中框:
window.insert_hitbox(bounds, behavior)- 创建交互区域 - 绘制:
window.paint_quad(...)- 渲染视觉内容 - 事件:
window.on_mouse_event(handler)- 处理用户输入
参考文档
完整 API 文档
- Element Trait API: 参见 api-reference.md
- 关联类型、方法、参数、返回值
- 命中框系统、事件处理、光标样式
实现指南
-
示例: 参见 examples.md
- 带高亮的简单文本元素
- 带选择的交互式元素
- 带子元素管理的复杂元素
-
最佳实践: 参见 best-practices.md
- 状态管理、性能优化
- 交互处理、布局策略
- 错误处理、测试、常见陷阱
-
常见模式: 参见 patterns.md
- 文本渲染、容器、交互式、复合、可滚动模式
- 模式选择指南
-
高级模式: 参见 advanced-patterns.md
- 自定义布局算法(如 masonry、circular)
- 使用特性的元素组合
- 异步更新、记忆化、虚拟列表