# `osui::extensions` The `extensions` module defines the core traits and types for extending OSUI's functionality. It provides a global event bus and lifecycle hooks that allow custom logic to interact with the entire UI application. ## `Extension` Trait The central trait for adding global behaviors to an OSUI application. Any struct implementing this trait can be registered with the `Screen` to receive lifecycle and event callbacks. ```rust pub trait Extension { /// Called once when the extension is registered with the `Screen`. #[allow(unused)] fn init(&mut self, _ctx: &Context) {} /// Called when any `Event` is dispatched across the system. #[allow(unused)] fn event(&mut self, _ctx: &Context, _event: &dyn Event) {} /// Called when `Screen::close()` is invoked, before the application terminates. #[allow(unused)] fn on_close(&mut self) {} /// Called before any widgets are rendered in a frame, with a scope for the entire screen. #[allow(unused)] fn render(&mut self, _ctx: &Context, _scope: &mut RenderScope) {} /// Called before a specific widget's `Element::render` method is invoked. #[allow(unused)] fn render_widget(&mut self, _ctx: &Context, _scope: &mut RenderScope, _widget: &Arc) {} /// Called after a specific widget's `Element::after_render` method is invoked. #[allow(unused)] fn after_render_widget( &mut self, _ctx: &Context, _scope: &mut RenderScope, _widget: &Arc, ) {} } ``` ## `Event` Trait A marker trait for types that can be dispatched as events within the OSUI system. Events are type-erased (`dyn Event`) when dispatched, requiring downcasting to retrieve their specific type. ```rust pub trait Event: Send + Sync { /// Returns a type-erased reference to this object, enabling downcasting. fn as_any(&self) -> &dyn Any; } impl<'a> dyn Event + 'a { /// Attempts to downcast a dynamic `Event` trait object to a concrete type `T`. /// /// # Type Parameters /// * `T`: The concrete event type to downcast to. Must also implement `Event`. /// /// # Returns /// `Some(&T)` if the downcast is successful, `None` otherwise. pub fn get(&self) -> Option<&T> { self.as_any().downcast_ref() } } ``` ## `Context` The `Context` struct provides a way for extensions and widgets to interact with the global OSUI `Screen` instance. It holds an `Arc` and offers convenience methods for dispatching events, querying widgets, and accessing components. ```rust #[derive(Clone)] pub struct Context { screen: Arc, } ``` ### Associated Methods #### `Context::new(screen: Arc) -> Self` Creates a new `Context` instance. **Arguments:** * `screen`: An `Arc` to the `Screen` instance that this context will operate on. #### `Context::event(&self, e: &E)` Dispatches an event `e` throughout the OSUI system. This will: 1. Call the `event` method on all widgets (specifically, on any `Handler` components attached to them, and on the `Element::event` method of focused widgets). 2. Call the `event` method on all registered `Extension`s. **Arguments:** * `e`: A reference to the event to dispatch. **Example:** ```rust use osui::prelude::*; // Inside an extension or a component: // self.ctx.event(&MyCustomEvent { /* ... */ }); ``` #### `Context::get_widgets(&self) -> MutexGuard>>` Returns a `MutexGuard` to the `Vec` of `Arc` that the `Screen` is currently managing. This allows extensions to iterate over and manipulate the global list of widgets. **Returns:** A `MutexGuard` providing mutable access to the list of root widgets. #### `Context::iter_components, Option)>(&self, mut iterator: F)` Iterates over all widgets managed by the `Screen` and applies a provided closure to each widget, along with an `Option` of a cloned component of type `C` if the widget has one. **Type Parameters:** * `C`: The `Component` type to look for. * `F`: The closure to execute for each widget. **Arguments:** * `iterator`: A closure that takes an `Arc` and an `Option`. #### `Context::get_components(&self) -> Vec` Collects all instances of a specific `Component` type from all widgets managed by the `Screen` into a `Vec`. **Type Parameters:** * `C`: The `Component` type to collect. **Returns:** A `Vec` containing cloned instances of component `C`. #### `Context::render_root(&self, scope: &mut RenderScope)` Calls the `render` hook for all registered `Extension`s, allowing them to draw global elements that span the entire screen. This is typically called once per frame before individual widgets are rendered. **Arguments:** * `scope`: The `RenderScope` representing the entire screen. #### `Context::render(&self, w: &Arc, scope: &mut RenderScope)` Calls the `render_widget` hook for all registered `Extension`s for a specific `widget`. This is invoked during the rendering of each individual widget. **Arguments:** * `w`: The `Arc` currently being rendered. * `scope`: The `RenderScope` for `w`. #### `Context::after_render(&self, w: &Arc, scope: &mut RenderScope)` Calls the `after_render_widget` hook for all registered `Extension`s for a specific `widget`. This is invoked after a widget's `Element::after_render` method has completed. **Arguments:** * `w`: The `Arc` that has just finished its `after_render` phase. * `scope`: The `RenderScope` for `w`. ## `Handler` (Component) A component that allows a widget to listen for and react to specific `Event` types `E`. ```rust #[derive(Clone)] pub struct Handler(Arc, &E) + Send + Sync>>); ``` ### Implementations #### `impl Component for Handler` `Handler` implements the `Component` trait, allowing it to be attached to any `Widget`. #### `impl Handler` #### `Handler::new, &E) + Send + Sync + 'static>(f: F) -> Handler` Creates a new `Handler` with the given mutable closure `f`. This closure will be called when an event of type `E` is dispatched. **Arguments:** * `f`: The closure to execute when the event occurs. It receives the `Arc` it's attached to and a reference to the event. **Example:** ```rust use osui::prelude::*; event!(ButtonClicked); rsx! { @Handler::new(|widget_arc, event: &ButtonClicked| { println!("Button clicked on widget: {:?}", widget_arc); }); Div { "My Button" } } ``` #### `Handler::call(&self, w: &Arc, e: &E)` Invokes the internal closure with the provided widget and event. This method is called internally by `Widget::event`. **Arguments:** * `w`: The `Arc` that owns this handler. * `e`: The event to process.