mirror of
https://github.com/ratatui/ratatui.git
synced 2025-10-02 23:35:49 +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.
93 lines
3.2 KiB
Rust
93 lines
3.2 KiB
Rust
//! # Shared Reference Pattern with Immutable State
|
|
//!
|
|
//! This example demonstrates implementing the `Widget` trait on a shared reference (`&Widget`)
|
|
//! with immutable state. This is the recommended pattern for most widgets in modern Ratatui
|
|
//! applications, as it allows widgets to be reused without being consumed.
|
|
//!
|
|
//! 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 want to reuse widgets across multiple renders
|
|
//! - Your widget doesn't need to modify its state during rendering
|
|
//! - You want the benefits of Ratatui's widget ecosystem
|
|
//! - You're building modern, efficient Ratatui applications
|
|
//!
|
|
//! ## Trade-offs
|
|
//!
|
|
//! **Pros:**
|
|
//! - Reusable - widget can be rendered multiple times without reconstruction
|
|
//! - Efficient - no cloning or reconstruction needed
|
|
//! - Standard - integrates with Ratatui's widget ecosystem
|
|
//! - Modern - follows current Ratatui best practices
|
|
//!
|
|
//! **Cons:**
|
|
//! - Immutable - cannot modify widget state during rendering
|
|
//! - External state - requires external state management for dynamic behavior
|
|
//!
|
|
//! ## Example Usage
|
|
//!
|
|
//! The widget implements `Widget for &Counter`, allowing it to be rendered by reference
|
|
//! while keeping its internal data immutable during rendering.
|
|
|
|
use ratatui::buffer::Buffer;
|
|
use ratatui::layout::Rect;
|
|
use ratatui::widgets::Widget;
|
|
use ratatui_state_examples::is_exit_key_pressed;
|
|
|
|
/// Demonstrates the shared reference pattern for immutable widget rendering.
|
|
///
|
|
/// Creates a counter widget that can be rendered multiple times by reference,
|
|
/// with state updates happening outside the widget's render method.
|
|
fn main() -> color_eyre::Result<()> {
|
|
color_eyre::install()?;
|
|
ratatui::run(|terminal| {
|
|
let mut counter = Counter::new();
|
|
loop {
|
|
terminal.draw(|frame| {
|
|
// Widget is rendered by reference, can be reused
|
|
frame.render_widget(&counter, frame.area());
|
|
})?;
|
|
// State updates happen outside of rendering
|
|
counter.increment();
|
|
if is_exit_key_pressed()? {
|
|
break Ok(());
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
/// A counter widget with immutable rendering behavior.
|
|
///
|
|
/// Implements `Widget` on a shared reference, allowing the widget to be rendered
|
|
/// multiple times without being consumed while keeping its data immutable during rendering.
|
|
struct Counter {
|
|
count: usize,
|
|
}
|
|
|
|
impl Counter {
|
|
/// Create a new counter.
|
|
fn new() -> Self {
|
|
Self { count: 0 }
|
|
}
|
|
|
|
/// Increment the counter value.
|
|
///
|
|
/// This method modifies the counter's state outside of the rendering process,
|
|
/// maintaining the separation between state updates and rendering.
|
|
fn increment(&mut self) {
|
|
self.count += 1;
|
|
}
|
|
}
|
|
|
|
impl Widget for &Counter {
|
|
fn render(self, area: Rect, buf: &mut Buffer) {
|
|
// Rendering is immutable - no state changes occur here
|
|
format!("Counter: {}", self.count).render(area, buf);
|
|
}
|
|
}
|