cotis 0.1.0-alpha

Modular Rust UI framework core
Documentation
//! Layout-side traits for building UI frames and producing per-frame output.
//!
//! Layout integrations are parameterized by two element-related types:
//!
//! - **`ConfigType`** — the configuration payload for each UI element while the tree is
//!   being built. Values of this type are passed through
//!   [`crate::element_configuring::ConfigureElements::set_config`] and the
//!   [`crate::element_configuring`] helpers (for example `OpenElement::set_config`).
//!   Choose a type that represents your layout system's element attributes (size, style,
//!   text content, and so on).
//!
//! - **`RenderCommandType`** — the item type yielded when a frame finishes layout
//!   ([`end`](crate::layout::LayoutFrameManager::end)). These are the layout manager's
//!   per-frame output values. When they already match what your renderer consumes, pass
//!   [`()`] as the pipe in [`crate::cotis_app::CotisApp`]. Otherwise, adapt them through
//!   [`crate::pipes::LayoutRenderPipe`] before drawing.
//!
//! Concrete ecosystems often define their own `ConfigType` and output/command types in
//! integration crates (for example element config structs and render-command enums).

use crate::element_configuring::{ConfigureElements, ConfiguredParentElement};

/// Signals that a type can act as a layout manager companion for a renderer.
///
/// Use `Renderer` to specify which traits a renderer requires to function with this
/// layout manager.
pub trait LayoutManagerCompatible<Renderer> {
    /// Initializes layout manager state against a renderer.
    ///
    /// The default implementation is a no-op.
    fn init(&mut self, _renderer: &mut Renderer) {}

    /// Prepares the layout manager before starting a new frame.
    fn prepare(&mut self, render: &Renderer);
}

/// Produces frame builders that collect UI structure and emit layout output.
///
/// # Type parameters
///
/// - `ConfigType`: element configuration values used while building the UI tree.
/// - `RenderCommandType`: per-item layout output produced at the end of each frame.
pub trait LayoutManager<'frame, ConfigType, RenderCommandType>
where
    ConfigType: 'frame,
    RenderCommandType: 'frame,
{
    /// The configurator type used while constructing one frame.
    type ElementConfigurer<'layout>: ConfigureElements<ConfigType>
    where
        Self: 'layout,
        ConfigType: 'frame,
        RenderCommandType: 'frame;

    /// Starts a new frame and returns a frame manager used to build UI.
    fn begin_frame<'layout>(
        &'layout mut self,
    ) -> impl LayoutFrameManager<'frame, ConfigType, RenderCommandType, Self::ElementConfigurer<'layout>>
    where
        Self: 'layout,
        ConfigType: 'frame,
        RenderCommandType: 'frame;
}

/// Manages one in-progress layout frame.
///
/// A frame manager receives element configuration calls and eventually yields
/// layout output items, which are later transformed and rendered.
///
/// # Type parameters
///
/// - `ConfigType`: configuration payload for each element opened during this frame.
/// - `RenderCommandType`: one layout output item returned by [`Self::end`].
pub trait LayoutFrameManager<
    'frame,
    ConfigType: 'frame,
    RenderCommandType: 'frame,
    ElementConfigurer: ConfigureElements<ConfigType>,
>
{
    /// Begins configuration at the root of the UI tree for this frame.
    fn begin(&'_ mut self) -> ConfiguredParentElement<'_, ElementConfigurer, ConfigType>;

    /// Completes frame construction and returns the frame output iterator.
    fn end(self) -> impl Iterator<Item = RenderCommandType>;
}