rig_tui/screen.rs
1//! The default screen, built from the view's public widgets only: a
2//! [`TranscriptPane`] over the shown agent, which takes what the other
3//! panels leave, the [`InlineStrip`] of a question asked beside the work,
4//! and the input, an [`Editor`] with the shown agent's [`StatusLine`] in
5//! its bottom row. An app
6//! that builds its own screen adds [`TuiViewPlugin`](crate::TuiViewPlugin)
7//! without this one and spawns its own, marking the transcript and the
8//! editor the keys go to [`MainPane`] and [`MainEditor`].
9
10use bevy_app::prelude::*;
11use bevy_ecs::prelude::*;
12use ratatui::layout::Constraint;
13
14use crate::{
15 Editor, InlineStrip, MainEditor, MainPane, PaneKeys, Placement, StatusLine, TranscriptPane,
16 TranscriptSource, TuiPanel,
17};
18
19/// Spawns the default screen's widgets, as ordinary entities, first, so
20/// the panels other plugins add go above the input or beside the
21/// transcript. The [`TuiPlugin`](crate::TuiPlugin) adds it.
22#[derive(Default)]
23pub struct DefaultScreenPlugin;
24
25impl Plugin for DefaultScreenPlugin {
26 fn build(&self, app: &mut App) {
27 let bottom = |rows| TuiPanel::new(Placement::Bottom(Constraint::Length(rows)));
28 let world = app.world_mut();
29 // Laid out in this order from the bottom: the input, the strip
30 // above it.
31 world.spawn((
32 Name::new("tui:input"),
33 Editor::default(),
34 MainEditor,
35 StatusLine::default(),
36 bottom(3),
37 ));
38 world.spawn((Name::new("tui:strip"), InlineStrip));
39 world.spawn((
40 Name::new("tui:transcript"),
41 TranscriptPane::new(TranscriptSource::Shown),
42 MainPane,
43 PaneKeys,
44 ));
45 }
46}