//! # Nested Mutable Widget Pattern //! //! This example demonstrates nesting widgets that both need mutable access to their state. //! This pattern is useful when you have a parent-child widget relationship where both widgets //! need to maintain and mutate their own state during rendering. //! //! This example runs with the Ratatui library code in the branch that you are currently //! reading. See the [`latest`] branch for the code which works with the most recent Ratatui //! release. //! //! [`latest`]: https://github.com/ratatui/ratatui/tree/latest //! //! ## When to Use This Pattern //! //! - You have hierarchical widget relationships (parent-child) //! - Each widget needs to maintain its own distinct state //! - You prefer the mutable widget pattern over StatefulWidget //! - Widgets have clear ownership of their state //! //! ## Trade-offs //! //! **Pros:** //! - Clear hierarchical organization //! - Each widget encapsulates its own state //! - Intuitive parent-child relationships //! - State ownership is explicit //! //! **Cons:** //! - Complex borrowing scenarios can arise //! - Requires careful lifetime management //! - May lead to borrow checker issues in complex hierarchies //! - Less flexible than StatefulWidget for state sharing //! //! ## Example Usage //! //! The parent `App` widget contains a child `Counter` widget. Both implement `Widget` for //! `&mut Self`, allowing them to mutate their respective states during rendering. The parent //! delegates rendering to the child while maintaining its own state structure. use ratatui::DefaultTerminal; use ratatui::buffer::Buffer; use ratatui::layout::Rect; use ratatui::widgets::Widget; use ratatui_state_examples::is_exit_key_pressed; /// Demonstrates the nested mutable widget pattern for mutable state management. /// /// Creates a parent-child widget hierarchy using mutable widgets and runs the application loop, /// updating the counter on each render cycle until the user exits. fn main() -> color_eyre::Result<()> { color_eyre::install()?; let app = App::default(); ratatui::run(|terminal| app.run(terminal)) } /// The main application widget that contains and manages child widgets. /// /// Demonstrates the parent widget in a nested mutable widget hierarchy. #[derive(Default)] struct App { counter: Counter, } impl App { /// Run the application with the given terminal. fn run(mut self, terminal: &mut DefaultTerminal) -> color_eyre::Result<()> { loop { terminal.draw(|frame| frame.render_widget(&mut self, frame.area()))?; if is_exit_key_pressed()? { break Ok(()); } } } } impl Widget for &mut App { fn render(self, area: Rect, buf: &mut Buffer) { self.counter.render(area, buf); } } /// A counter widget that maintains its own state within a nested hierarchy. /// /// Can be used standalone or as a child within other widgets, demonstrating /// how mutable widgets can be composed together. #[derive(Default)] struct Counter { count: usize, } impl Widget for &mut Counter { fn render(self, area: Rect, buf: &mut Buffer) { self.count += 1; format!("Counter: {count}", count = self.count).render(area, buf); } }