gpui-element

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

When to Use

使用场景

Use the low-level
Element
trait when:
  • Need fine-grained control over layout calculation
  • Building complex, performance-critical components
  • Implementing custom layout algorithms (masonry, circular, etc.)
  • High-level
    Render
    /
    RenderOnce
    APIs are insufficient
Prefer
Render
/
RenderOnce
for:
Simple components, standard layouts, declarative UI
当以下情况时使用低级
Element
trait:
  • 需要对布局计算进行细粒度控制
  • 构建复杂、性能关键的组件
  • 实现自定义布局算法(瀑布流、环形布局等)
  • 高级
    Render
    /
    RenderOnce
    API无法满足需求
优先使用
Render
/
RenderOnce
的场景:
简单组件、标准布局、声明式UI

Quick Start

快速开始

The
Element
trait provides direct control over three rendering phases:
rust
impl Element for MyElement {
    type RequestLayoutState = MyLayoutState;  // Data passed to later phases
    type PrepaintState = MyPaintState;        // Data for painting

    fn id(&self) -> Option<ElementId> {
        Some(self.id.clone())
    }

    fn source_location(&self) -> Option<&'static std::panic::Location<'static>> {
        None
    }

    // Phase 1: Calculate sizes and positions
    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 { /* ... */ })
    }

    // Phase 2: Create hitboxes, prepare for painting
    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 }
    }

    // Phase 3: Render and handle interactions
    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() {
                    // Handle interaction
                    cx.stop_propagation();
                }
            }
        });
    }
}

// Enable element to be used as child
impl IntoElement for MyElement {
    type Element = Self;
    fn into_element(self) -> Self::Element { self }
}
Element
trait提供对三个渲染阶段的直接控制:
rust
impl Element for MyElement {
    type RequestLayoutState = MyLayoutState;  // Data passed to later phases
    type PrepaintState = MyPaintState;        // Data for painting

    fn id(&self) -> Option<ElementId> {
        Some(self.id.clone())
    }

    fn source_location(&self) -> Option<&'static std::panic::Location<'static>> {
        None
    }

    // Phase 1: Calculate sizes and positions
    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 { /* ... */ })
    }

    // Phase 2: Create hitboxes, prepare for painting
    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 }
    }

    // Phase 3: Render and handle interactions
    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() {
                    // Handle interaction
                    cx.stop_propagation();
                }
            }
        });
    }
}

// Enable element to be used as child
impl IntoElement for MyElement {
    type Element = Self;
    fn into_element(self) -> Self::Element { self }
}

Core Concepts

核心概念

Three-Phase Rendering

三阶段渲染

  1. request_layout: Calculate sizes and positions, return layout ID and state
  2. prepaint: Create hitboxes, compute final bounds, prepare for painting
  3. paint: Render element, set up interactions (mouse events, cursor styles)
  1. request_layout:计算尺寸和位置,返回布局ID和状态
  2. prepaint:创建命中区域,计算最终边界,为绘制做准备
  3. paint:渲染元素,设置交互(鼠标事件、光标样式)

State Flow

状态流转

RequestLayoutState → PrepaintState → paint
State flows in one direction through associated types, passed as mutable references between phases.
RequestLayoutState → PrepaintState → paint
状态通过关联类型单向流转,在各阶段之间以可变引用的形式传递。

Key Operations

关键操作

  • Layout:
    window.request_layout(style, children, cx)
    - Create layout node
  • Hitboxes:
    window.insert_hitbox(bounds, behavior)
    - Create interaction area
  • Painting:
    window.paint_quad(...)
    - Render visual content
  • Events:
    window.on_mouse_event(handler)
    - Handle user input
  • 布局
    window.request_layout(style, children, cx)
    - 创建布局节点
  • 命中区域
    window.insert_hitbox(bounds, behavior)
    - 创建交互区域
  • 绘制
    window.paint_quad(...)
    - 渲染视觉内容
  • 事件
    window.on_mouse_event(handler)
    - 处理用户输入

Reference Documentation

参考文档

Complete API Documentation

完整API文档

  • Element Trait API: See api-reference.md
    • Associated types, methods, parameters, return values
    • Hitbox system, event handling, cursor styles
  • Element Trait API:参见api-reference.md
    • 关联类型、方法、参数、返回值
    • 命中区域系统、事件处理、光标样式

Implementation Guides

实现指南

  • Examples: See examples.md
    • Simple text element with highlighting
    • Interactive element with selection
    • Complex element with child management
  • Best Practices: See best-practices.md
    • State management, performance optimization
    • Interaction handling, layout strategies
    • Error handling, testing, common pitfalls
  • Common Patterns: See patterns.md
    • Text rendering, container, interactive, composite, scrollable patterns
    • Pattern selection guide
  • Advanced Patterns: See advanced-patterns.md
    • Custom layout algorithms (masonry, circular)
    • Element composition with traits
    • Async updates, memoization, virtual lists
  • 示例:参见examples.md
    • 带高亮的简单文本元素
    • 带选择功能的交互元素
    • 带子元素管理的复杂元素
  • 最佳实践:参见best-practices.md
    • 状态管理、性能优化
    • 交互处理、布局策略
    • 错误处理、测试、常见陷阱
  • 常见模式:参见patterns.md
    • 文本渲染、容器、交互、复合、可滚动模式
    • 模式选择指南
  • 高级模式:参见advanced-patterns.md
    • 自定义布局算法(瀑布流、环形布局)
    • 基于trait的元素组合
    • 异步更新、记忆化、虚拟列表