1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//! Cocotte provides a convenient way to build Ratatui terminal applications by composing independent sub-apps.
//!
//! Define:
//! - an `Event` type to represent application inputs such as keys, ticks, or setup events
//! - a `State` type to hold shared application data
//! - several [`SubApp`]s for input handling and rendering. Each subapp handles the `Event`s and renders
//!
//! Then use the [`define_sub_apps`] macro to combine them all into a single app. The macro provides the `make_app` function that creates your app for you.
//!
//! # Example
//!
//! ```no_run
//! use cocotte::eyre::Result;
//! use cocotte::ratatui::layout::{Constraint, Rect};
//! use cocotte::ratatui::widgets::{Block, Borders};
//! use cocotte::ratatui::Frame;
//! use cocotte::{define_sub_apps, SubApp};
//! use crossterm::event::{self, Event, KeyCode, KeyEvent};
//!
//! #[derive(Clone, Debug)]
//! enum AppEvent {
//! Tick,
//! Key(KeyEvent),
//! }
//!
//! #[derive(Default)]
//! struct State {
//! should_quit: bool,
//! }
//!
//! struct Pane;
//!
//! impl Pane {
//! fn new() -> Self {
//! Self
//! }
//! }
//!
//! impl SubApp<AppEvent, State> for Pane {
//! fn handle_input(&mut self, event: &mut AppEvent, state: &mut State) {
//! if let AppEvent::Key(KeyEvent {
//! code: KeyCode::Char('q') | KeyCode::Esc,
//! ..
//! }) = event
//! {
//! state.should_quit = true;
//! }
//! }
//!
//! fn render(&self, frame: &mut Frame, area: Rect, _state: &mut State) {
//! let block = Block::default().borders(Borders::ALL).title("Pane");
//! frame.render_widget(block, area);
//! }
//!
//! fn constraints(&self) -> Constraint {
//! Constraint::Fill(1)
//! }
//! }
//!
//! define_sub_apps! {
//! event = AppEvent;
//! state = State;
//! Pane(Pane) => Pane::new(),
//! }
//!
//! fn main() -> Result<()> {
//! let mut app = make_app()?;
//! let mut state = State::default();
//! let mut setup = AppEvent::Tick;
//! app.handle_input(&mut setup, &mut state);
//!
//! while !state.should_quit {
//! app.draw(&mut state)?;
//!
//! if let Event::Key(key) = event::read()? {
//! let mut event = AppEvent::Key(key);
//! app.handle_input(&mut event, &mut state);
//! }
//! }
//!
//! Ok(())
//! }
//! ```
pub use App;
pub use eyre;
pub use ratatui;
pub use SubApp;