GPUI Book
repository·main·Indexed 42 days ago
https://github.com/matinaniss/gpui-bookAn educational resource for building applications with the GPUI framework. Covers core architecture including the App and Application abstractions, Context management, Window handling, and asynchronous task execution via Foreground and Background Executors. Includes guides on UI elements like Div, Deferred, and Img, as well as creating animations using Animation::new and with_animation.
What's inside GPUI
- GPUI is a GPU-accelerated UI framework for Rust designed for high performance and versatility. It features a hybrid rendering API that combines both immediate and retained mode paradigms. GPUI is the underlying framework used to power the Zed editor.
Use primitive elements in GPUI
mainGPUI provides a set of primitive elements that serve as the building blocks for user interfaces. This chapter covers the various built-in primitive elements available for use in your application. For instructions on how to define and create custom UI components from scratch, refer to the 'Implementing Element' guide.What is the Foreground Executor?
mainThe Foreground Executor is a mechanism used to spawn asynchronous tasks that run specifically on the main thread.
Critical Warning: Because these tasks run on the main thread, you must never perform operations that block for a non-trivial duration. Blocking the foreground executor will block the main thread and cause the entire application to hang.
What is the Application abstraction in GPUI?
mainTheApplicationis the primary entry point for any GPUI-based program. It manages the lifecycle of the application process and serves as the foundation upon which windows and other application-level components are built.Understand the Window abstraction
mainIn GPUI, aWindowrepresents a platform-native window. It serves as the primary interface for controlling various aspects of a window's functionality, including its dimensions and input state.Use SharedString to avoid heap allocations during re-renders
mainIn GPUI, using a
Stringinside arenderfunction causes a heap allocation on every re-render. To optimize performance, useSharedString.SharedStringis an immutable string that can be cheaply cloned. The recommended pattern is to store theSharedStringin yourEntitystate, where it can be accessed by therenderfunction without re-allocating memory.// Example pattern: Store SharedString in Entity state to avoid re-allocation in render struct MyEntity { text: SharedString, } impl Element for MyEntity { fn render(&self, cx: &mut ViewContext<Self>) -> impl IntoElement { // Accessing self.text here is cheap because it is a SharedString text(&self.text) } }What are Globals in GPUI
mainIn GPUI,Globals are used to share state across an entire application (e.g., application settings). Any type that implements theGlobalmarker trait can be stored as a global. LikeEntitys,Globals are owned by GPUI.Render an image using the Img element
mainTheimgelement is used to render images within a GPUI application. It accepts any type that implementsInto<ImageSource>. Common sources include file system paths or otherImageSourceimplementations. For information on how to apply styles to an image, refer to the styling documentation.Implement the Render trait to create views
mainIn GPUI, the
Rendertrait is used to define how a type draws elements to the screen. ImplementingRenderfor a typeTeffectively turns anEntity<T>into a view.GPUI uses retained mode rendering for views, meaning a view will not re-render automatically unless it is explicitly notified of a change.
Views can contain components that implement
RenderOnce, which provides immediate mode rendering capabilities within the retained mode view structure.// Note: The specific implementation details are provided in the snippets/render.rs file. // Implementing Render allows your type to be displayed as a view in GPUI.Understand the two ways to render elements in GPUI
mainGPUI provides two primary trait implementations for rendering elements within an application:
Render: The standard way to render elements that may need to update or re-render based on state changes.RenderOnce: A specialized way to render elements that are intended to be rendered only once.
Use the Div element as a container
mainTheDivelement is the primary container in GPUI. It is used to group other elements and serves as the foundation for building UI components. You can apply styling and interactivity to aDivto create complex interfaces. For detailed guidance on customization, refer to the Styling and Interactivity sections of the GPUI Book.Use the RenderOnce trait for immediate mode components
mainThe
RenderOncetrait is used to create components rather than views. Unlike theRendertrait, which is used for retained mode views,RenderOncefollows an immediate mode rendering pattern: components are constructed, rendered, and then immediately dropped.Key characteristics:
- Lifecycle: Rendered exactly once per construction.
- Ownership: The
renderfunction takes ownership ofself(unlikeRender, which provides a mutable reference&mut self). - Use Case: Ideal for components that do not need to store mutable application state and are intended to be rendered inside retained mode views.
// Note: The actual implementation snippet is provided via a template include in the source. // A typical implementation would look like this: impl RenderOnce for MyComponent { fn render(self) -> impl Renderable { // Implementation logic } }