Files
docs/versioned_docs/version-0.1.1/reference/frontend.md
T
2025-08-10 14:14:04 -05:00

87 lines
4.5 KiB
Markdown

# `osui::frontend`
The `frontend` module defines the internal structures that represent the declarative UI tree parsed by the `rsx!` macro. This tree is then used to construct the actual `Widget` hierarchy managed by the `Screen`.
## `RsxElement` Enum
Represents a single node in the RSX tree before it's converted into a `Widget`.
```rust
pub enum RsxElement {
/// A static widget with its children.
/// Used when the `rsx!` macro detects a `static` element or a string literal without dependencies.
Element(StaticWidget, Rsx),
/// A dynamically generated widget with its dependencies and children.
/// Used when the `rsx!` macro detects a `%dependency` or a non-static string literal.
DynElement(
Box<dyn FnMut() -> WidgetLoad + Send + Sync>,
Vec<Box<dyn DependencyHandler>>,
Rsx,
),
}
```
* **`Element(StaticWidget, Rsx)`**: Holds a pre-constructed `StaticWidget` and its child `Rsx` tree. This variant is for UI parts that do not change dynamically.
* **`DynElement(Box<dyn FnMut() -> WidgetLoad + Send + Sync>, Vec<Box<dyn DependencyHandler>>, Rsx)`**:
* The `Box<dyn FnMut() -> WidgetLoad + Send + Sync>` is a closure that, when executed, will create the `WidgetLoad` for this dynamic widget. This allows deferring the widget's construction until it's actually needed or when it needs to be rebuilt.
* `Vec<Box<dyn DependencyHandler>>`: A list of reactive dependencies (like `State<T>`) that, when changed, will trigger this dynamic widget to rebuild itself by re-executing its `FnMut() -> WidgetLoad` closure.
* `Rsx`: The child RSX tree for this dynamic widget.
## `Rsx` Struct
A container representing a collection (a list or a group) of `RsxElement`s. This is the top-level type generated by the `rsx!` macro.
```rust
pub struct Rsx(pub Vec<RsxElement>);
```
### Associated Methods
#### `Rsx::draw(self, screen: &Arc<Screen>)`
Draws the `Rsx` tree onto the given `Screen` as root-level widgets.
This is the entry point for rendering the UI defined by an `rsx!` block. It effectively calls `draw_parent` with no parent.
**Arguments:**
* `screen`: An `Arc` to the `Screen` instance.
**Example:**
```rust
use osui::prelude::*;
let screen = Screen::new();
rsx! { "Hello, OSUI!" }.draw(&screen);
```
#### `Rsx::draw_parent(self, screen: &Arc<Screen>, parent: Option<Arc<Widget>>)`
Recursively draws the `Rsx` tree with an optional parent widget.
This method iterates through the `RsxElement`s:
* For `DynElement`s, it calls the internal `FnMut()` to create a `WidgetLoad`, then creates an `Arc<Widget::Dynamic>` via `screen.draw_box_dyn`. It registers all the element's dependencies with this new dynamic widget.
* For `Element`s (static), it creates an `Arc<Widget::Static>` via `screen.draw_widget`.
* If a `parent` `Arc<Widget>` is provided, the newly created child widget is registered with the parent's `Element` via `parent.get_elem().draw_child(&new_widget)`. This is how the parent-child relationships are established in the runtime widget tree.
* It then recursively calls `draw_parent` for the child `Rsx` tree, passing the newly created widget as the `parent`.
**Arguments:**
* `screen`: An `Arc` to the `Screen` instance.
* `parent`: An `Option<Arc<Widget>>` representing the parent widget. `None` for root widgets.
#### `Rsx::create_element<F: FnMut() -> WidgetLoad + Send + Sync + 'static>(&mut self, load: F, dependencies: Vec<Box<dyn DependencyHandler>>, children: Rsx)`
Adds a dynamically constructed `RsxElement::DynElement` to this `Rsx` container. This method is primarily used internally by the `rsx!` macro.
**Arguments:**
* `load`: A closure that generates the `WidgetLoad` for the dynamic element.
* `dependencies`: A `Vec` of boxed `DependencyHandler`s that this element depends on.
* `children`: The `Rsx` tree representing the children of this element.
#### `Rsx::create_element_static(&mut self, element: StaticWidget, children: Rsx)`
Adds a statically defined `RsxElement::Element` to this `Rsx` container. This method is primarily used internally by the `rsx!` macro.
**Arguments:**
* `element`: A pre-constructed `StaticWidget`.
* `children`: The `Rsx` tree representing the children of this element.
#### `Rsx::expand(&mut self, other: &mut Rsx)`
Appends the elements from another `Rsx` tree into this one. This is used by the `rsx!` macro when handling the `$expand => (...args)` syntax.
**Arguments:**
* `other`: A mutable reference to another `Rsx` container whose elements will be moved into `self`.