mirror of
https://github.com/ratatui/ratatui.git
synced 2025-10-02 15:25:54 +00:00

Added comprehensive state management examples covering both immutable and mutable patterns and documentation to help developers choose the right approach for their applications.
97 lines
3.2 KiB
Rust
97 lines
3.2 KiB
Rust
//! # 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);
|
|
}
|
|
}
|