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::*;