rat_widget/clipper/mod.rs
1//!
2//! An alternative view widget.
3//!
4//! > The extra requirement for this one is that you can create
5//! > a Layout that defines the bounds of all widgets that can
6//! > be rendered.
7//!
8//! It works in 4 phases:
9//!
10//! ```rust no_run
11//! # use rat_widget::clipper::{Clipper, ClipperState};
12//! # use rat_widget::checkbox::{Checkbox, CheckboxState};
13//! # use ratatui::prelude::*;
14//! use rat_focus::FocusFlag;
15//! use rat_widget::layout::GenericLayout;
16//! #
17//! # let l2 = [Rect::ZERO, Rect::ZERO];
18//! # struct State {
19//! # check_states: Vec<CheckboxState>,
20//! # clipper: ClipperState<FocusFlag>
21//! # }
22//! # let mut state = State {
23//! # clipper: Default::default(),
24//! # check_states: Vec::default()
25//! # };
26//! # let mut buf = Buffer::default();
27//! ///
28//! /// Create the layout. The layout can be stored long-term
29//! /// and needs to be rebuilt only if your widget layout changes.
30//! ///
31//! ///> __Note__: add() returns a handle for the area. Can be used later
32//! ///> to refer to the stored area.
33//!
34//! let clipper = Clipper::new();
35//! let layout_size = clipper.layout_size(l2[1], &mut state.clipper);
36//!
37//! if !state.clipper.valid_layout(layout_size) {
38//! let mut cl = GenericLayout::new();
39//! for i in 0..100 {
40//! cl.add(state.check_states[i].focus.clone(),
41//! Rect::new(10, i as u16 *11, 15, 10),
42//! None,
43//! Rect::default()
44//! );
45//! }
46//! state.clipper.set_layout(cl);
47//! }
48//!
49//! /// The given area plus the current scroll offset define the
50//! /// view area. With the view area a temporary buffer is created
51//! /// that is big enough to fit all widgets that are at least
52//! /// partially visible.
53//!
54//! let mut clip_buf = clipper
55//! .into_buffer(l2[1], &mut state.clipper);
56//!
57//! ///
58//! /// The widgets are rendered to that buffer.
59//! ///
60//! for i in 0..100 {
61//! // refer by handle
62//! clip_buf.render(
63//! state.check_states[i].focus.clone(),
64//! || {
65//! Checkbox::new()
66//! .text(format!("{:?}", i))
67//! },
68//! &mut state.check_states[i],
69//! );
70//! }
71//!
72//! ///
73//! /// The last step clips and copies the buffer to the frame buffer.
74//! ///
75//!
76//! clip_buf
77//! .into_widget()
78//! .render(l2[1], &mut buf, &mut state.clipper);
79//!
80//! ```
81//!
82//! __StatefulWidget__
83//!
84//! For this to work with StatefulWidgets they must cooperate
85//! by implementing the [RelocatableState](crate::reloc::RelocatableState)
86//! trait. With this trait the widget can clip/hide all areas that
87//! it stores in its state.
88//!
89//! __See__
90//!
91//! [example](https://github.com/thscharler/rat-widget/blob/master/examples/clipper1.rs)
92//!
93
94#[allow(clippy::module_inception)]
95mod clipper;
96mod clipper_style;
97
98pub use clipper::*;
99pub use clipper_style::*;