返回 CodeWhale
surface.rs
1 //! Gallery: depth (panels), the horizon rule, a dialog and a sheet.
2
3 use ratatui::{
4 buffer::Buffer,
5 layout::Rect,
6 text::{Line, Span},
7 widgets::{Paragraph, Widget, Wrap},
8 };
9
10 use super::Entry;
11 use crate::{
12 Depth, Dialog, DialogWidth, HorizonRule, KeyHint, KeyHints, Paint, Panel, Role, Sheet,
13 SheetEdge, Theme, glyphs,
14 };
15
16 fn depths(area: Rect, buf: &mut Buffer, theme: &Theme) {
17 let w = area.width / 4;
18 for (i, (depth, title, body)) in [
19 (Depth::Deep, "Deep", "Put away"),
20 (Depth::Stage, "Stage", "Where work sits"),
21 (Depth::Raised, "Raised", "A card"),
22 (Depth::Overlay, "Overlay", "A decision"),
23 ]
24 .into_iter()
25 .enumerate()
26 {
27 let rect = Rect {
28 x: area.x + w * i as u16,
29 width: w,
30 ..area
31 };
32 let inner = Panel::new(depth).title(title).draw(rect, buf, theme);
33 Line::from(Span::styled(body, theme.fg(Role::Muted))).render(inner, buf);
34 }
35 }
36
37 fn horizon(area: Rect, buf: &mut Buffer, theme: &Theme) {
38 let row = |n: u16| {
39 Rect {
40 y: area.y.saturating_add(n),
41 height: 1,
42 ..area
43 }
44 .intersection(area)
45 };
46 Line::from(Span::styled(
47 "Edited summary.md",
48 theme.fg(Role::Foreground),
49 ))
50 .render(row(0), buf);
51 HorizonRule::new()
52 .aside("12% of context used")
53 .paint(row(1), buf, theme);
54 Line::from(vec![
55 Span::styled(
56 format!("{} ", glyphs::pick("›", theme.ascii())),
57 theme.fg(Role::Primary),
58 ),
59 Span::styled("Ask Codewhale to do something", theme.fg(Role::Muted)),
60 ])
61 .render(row(2), buf);
62 }
63
64 /// Work on the stage, for a dialog or a sheet to sit over.
65 fn backdrop(area: Rect, buf: &mut Buffer, theme: &Theme) {
66 let area = area.intersection(buf.area);
67 let lines = [
68 "Edited summary.md",
69 "Ran cargo test: 212 passed",
70 "Read crates/tui/src/tui/views/mod.rs",
71 "Searched the web for ratatui tabs",
72 "Edited settings.rs",
73 ];
74 for (row, line) in lines
75 .iter()
76 .cycle()
77 .take(usize::from(area.height))
78 .enumerate()
79 {
80 buf.set_stringn(
81 area.x,
82 area.y + row as u16,
83 line,
84 usize::from(area.width),
85 theme.fg(Role::Muted),
86 );
87 }
88 }
89
90 fn dialog(area: Rect, buf: &mut Buffer, theme: &Theme) {
91 backdrop(area, buf, theme);
92 let hints = KeyHints::new(vec![
93 KeyHint::new("y", "stop"),
94 KeyHint::new("n", "keep running"),
95 ]);
96 let body = Dialog::new()
97 .title("Stop the running workflow?")
98 .width(DialogWidth::Narrow)
99 .body_rows(2)
100 .hints(&hints)
101 .draw(area, buf, theme);
102 Paragraph::new("2 agents are still working. Their edits so far are kept.")
103 .style(theme.fg(Role::Foreground))
104 .wrap(Wrap { trim: true })
105 .render(body, buf);
106 }
107
108 fn sheet(area: Rect, buf: &mut Buffer, theme: &Theme) {
109 backdrop(area, buf, theme);
110 let arrows = super::arrows(theme);
111 let hints = KeyHints::new(vec![
112 KeyHint::new(arrows, "move"),
113 KeyHint::new("Enter", "change"),
114 KeyHint::new("Esc", "close"),
115 ]);
116 let body = Sheet::new()
117 .edge(SheetEdge::Bottom)
118 .title("Settings")
119 .aside("3 changed")
120 .size(10)
121 .max_size(9)
122 .hints(&hints)
123 .draw(area, buf, theme);
124 Paragraph::new(vec![
125 Line::from("Theme Shoreline"),
126 Line::from("Motion Reduced"),
127 Line::from("Tool detail Collapsed"),
128 ])
129 .style(theme.fg(Role::Foreground))
130 .render(body, buf);
131 }
132
133 pub(crate) fn entries() -> Vec<Entry> {
134 vec![
135 Entry {
136 name: "dialog",
137 width: 80,
138 height: 12,
139 draw: dialog,
140 },
141 Entry {
142 name: "sheet",
143 width: 80,
144 height: 12,
145 draw: sheet,
146 },
147 Entry {
148 name: "depth",
149 width: 80,
150 height: 6,
151 draw: depths,
152 },
153 Entry {
154 name: "horizon",
155 width: 60,
156 height: 3,
157 draw: horizon,
158 },
159 ]
160 }
161
161 lines RUST