Skip to content

Commit dcb65cb

Browse files
committed
docs: simplify tui-big-text examples
1 parent 7e1fc61 commit dcb65cb

10 files changed

+163
-97
lines changed

tui-big-text/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ itertools.workspace = true
1919
ratatui.workspace = true
2020

2121
[dev-dependencies]
22-
anyhow.workspace = true
22+
color-eyre.workspace = true
2323
crossterm = { workspace = true, features = ["event-stream"] }
2424
futures.workspace = true
2525
indoc.workspace = true
26+
ratatui = { workspace = true, features = ["crossterm"] }
2627
strum.workspace = true
2728
tokio = { workspace = true, features = ["full"] }

tui-big-text/examples/alignment.rs

+19-22
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,24 @@
1-
use std::{io::stdout, thread::sleep, time::Duration};
2-
3-
use anyhow::Result;
4-
use crossterm::{
5-
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
6-
ExecutableCommand,
1+
use color_eyre::Result;
2+
use ratatui::{
3+
layout::Offset,
4+
prelude::{Alignment, Frame, Stylize},
5+
text::Line,
76
};
8-
use ratatui::prelude::*;
97
use tui_big_text::{BigText, PixelSize};
108

9+
mod common;
10+
1111
fn main() -> Result<()> {
12-
stdout().execute(EnterAlternateScreen)?;
13-
enable_raw_mode()?;
14-
let backend = CrosstermBackend::new(stdout());
15-
let mut terminal = Terminal::new(backend)?;
16-
terminal.clear()?;
17-
terminal.draw(|frame| render(frame).expect("failed to render"))?;
18-
sleep(Duration::from_secs(5));
19-
terminal.clear()?;
20-
stdout().execute(LeaveAlternateScreen)?;
21-
disable_raw_mode()?;
12+
color_eyre::install()?;
13+
common::run(render)?;
2214
Ok(())
2315
}
2416

2517
fn render(frame: &mut Frame) -> Result<()> {
18+
let title = Line::from("tui-big-text alignment demo. Press 'q' to quit")
19+
.cyan()
20+
.centered();
21+
2622
let left = BigText::builder()
2723
.pixel_size(PixelSize::Quadrant)
2824
.alignment(Alignment::Left)
@@ -41,12 +37,13 @@ fn render(frame: &mut Frame) -> Result<()> {
4137
.lines(vec!["Centered".red().into()])
4238
.build()?;
4339

44-
use Constraint::*;
45-
let [top, middle, bottom] = Layout::vertical([Length(4); 3]).areas(frame.size());
40+
let area = frame.size();
41+
frame.render_widget(title, area);
4642

47-
frame.render_widget(left, top);
48-
frame.render_widget(right, middle);
49-
frame.render_widget(centered, bottom);
43+
let area = area.offset(Offset { x: 0, y: 2 }).intersection(area);
44+
frame.render_widget(left, area);
45+
frame.render_widget(right, area);
46+
frame.render_widget(centered, area);
5047

5148
Ok(())
5249
}

tui-big-text/examples/alignment.tape

+2
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ Sleep 2s
1010
Show
1111
Screenshot "target/alignment.png"
1212
Sleep 1s
13+
Hide
14+
Escape

tui-big-text/examples/big_text.rs

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use color_eyre::Result;
2+
use ratatui::{
3+
layout::Offset,
4+
prelude::{Frame, Style, Stylize},
5+
text::Line,
6+
};
7+
use tui_big_text::BigText;
8+
9+
mod common;
10+
11+
fn main() -> Result<()> {
12+
color_eyre::install()?;
13+
common::run(render)?;
14+
Ok(())
15+
}
16+
17+
fn render(frame: &mut Frame) -> Result<()> {
18+
let title = Line::from("tui-big-text Demo. Press 'q' to quit").cyan();
19+
20+
let big_text = BigText::builder()
21+
.style(Style::new().blue())
22+
.lines(vec![
23+
"Tui-".red().into(),
24+
"big-".white().into(),
25+
"text".into(),
26+
])
27+
.build()?;
28+
29+
let area = frame.size();
30+
frame.render_widget(title, area);
31+
32+
let area = area.offset(Offset { x: 0, y: 2 }).intersection(area);
33+
frame.render_widget(big_text, area);
34+
Ok(())
35+
}
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
# VHS Tape (see https://github.com/charmbracelet/vhs)
2-
Output "target/demo.gif"
2+
Output "target/big_text.gif"
33
Set Theme "Aardvark Blue"
44
Set Width 600
55
Set Height 800
66
Hide
7-
Type@0 "cargo run --example demo --quiet"
7+
Type@0 "cargo run --example big_text --quiet"
88
Enter
99
Sleep 2s
1010
Show
11-
Screenshot "target/demo.png"
11+
Screenshot "target/big_text.png"
1212
Sleep 1s
13+
Hide
14+
Escape

tui-big-text/examples/common/mod.rs

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//! common module for examples
2+
3+
use std::io;
4+
5+
use color_eyre::Result;
6+
use crossterm::{
7+
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
8+
ExecutableCommand,
9+
};
10+
use ratatui::prelude::CrosstermBackend;
11+
12+
/// A type alias for the terminal
13+
type Terminal = ratatui::Terminal<CrosstermBackend<io::Stdout>>;
14+
15+
/// A generic main loop for a TUI example that just renders the given function and exits when the
16+
/// user presses 'q' or 'Esc'
17+
pub fn run<F>(render: F) -> Result<()>
18+
where
19+
F: Fn(&mut ratatui::Frame) -> Result<()>,
20+
{
21+
install_panic_handler();
22+
23+
with_terminal(|mut terminal| loop {
24+
terminal.draw(|frame| render(frame).expect("failed to render"))?;
25+
if let crossterm::event::Event::Key(event) = crossterm::event::read()? {
26+
if matches!(
27+
event.code,
28+
crossterm::event::KeyCode::Char('q') | crossterm::event::KeyCode::Esc
29+
) {
30+
break Ok(());
31+
}
32+
}
33+
})
34+
}
35+
36+
/// Install a panic handler that restores the terminal before panicking
37+
fn install_panic_handler() {
38+
let hook = std::panic::take_hook();
39+
std::panic::set_hook(Box::new(move |panic_info| {
40+
if let Err(err) = restore() {
41+
eprintln!("failed to restore terminal: {}", err);
42+
}
43+
hook(panic_info);
44+
}));
45+
}
46+
47+
/// Run a function with a terminal ensuring that the terminal is restored afterwards
48+
fn with_terminal<F>(f: F) -> color_eyre::Result<()>
49+
where
50+
F: FnOnce(Terminal) -> color_eyre::Result<()>,
51+
{
52+
let terminal = init()?;
53+
let result = f(terminal);
54+
restore()?;
55+
result?;
56+
Ok(())
57+
}
58+
59+
/// Initialize a terminal
60+
fn init() -> io::Result<Terminal> {
61+
io::stdout().execute(EnterAlternateScreen)?;
62+
enable_raw_mode()?;
63+
let backend = CrosstermBackend::new(io::stdout());
64+
let mut terminal = Terminal::new(backend)?;
65+
terminal.clear()?;
66+
Ok(terminal)
67+
}
68+
69+
/// Restore the terminal to its original state
70+
fn restore() -> io::Result<()> {
71+
io::stdout().execute(LeaveAlternateScreen)?;
72+
disable_raw_mode()?;
73+
Ok(())
74+
}

tui-big-text/examples/demo.rs

-44
This file was deleted.

tui-big-text/examples/pixel_size.rs

+14-20
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,20 @@
1-
use std::{io::stdout, thread::sleep, time::Duration};
2-
3-
use anyhow::Result;
4-
use crossterm::{
5-
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
6-
ExecutableCommand,
7-
};
1+
use color_eyre::Result;
82
use ratatui::prelude::*;
93
use tui_big_text::{BigText, PixelSize};
104

5+
mod common;
6+
117
fn main() -> Result<()> {
12-
stdout().execute(EnterAlternateScreen)?;
13-
enable_raw_mode()?;
14-
let backend = CrosstermBackend::new(stdout());
15-
let mut terminal = Terminal::new(backend)?;
16-
terminal.clear()?;
17-
terminal.draw(|frame| render(frame).expect("failed to render"))?;
18-
sleep(Duration::from_secs(5));
19-
terminal.clear()?;
20-
stdout().execute(LeaveAlternateScreen)?;
21-
disable_raw_mode()?;
8+
color_eyre::install()?;
9+
common::run(render)?;
2210
Ok(())
2311
}
2412

2513
fn render(frame: &mut Frame) -> Result<()> {
14+
let title = Line::from("tui-big-text pixel size demo. Press 'q' to quit")
15+
.centered()
16+
.cyan();
17+
2618
let full_size_text = BigText::builder()
2719
.pixel_size(PixelSize::Full)
2820
.lines(vec!["FullSize".white().into()])
@@ -53,13 +45,15 @@ fn render(frame: &mut Frame) -> Result<()> {
5345
.lines(vec!["Sextant".cyan().into(), " 1/2*1/3".cyan().into()])
5446
.build()?;
5547

56-
// Setup layout for 6 blocks
48+
// Setup layout for the title and 6 blocks
5749
use Constraint::*;
58-
let [full, half_height, middle, bottom] =
59-
Layout::vertical([Length(8), Length(4), Length(8), Length(6)]).areas(frame.size());
50+
let [top, full, half_height, middle, bottom] =
51+
Layout::vertical([Length(2), Length(8), Length(4), Length(8), Length(6)])
52+
.areas(frame.size());
6053
let [half_wide, quadrant] = Layout::horizontal([Length(32), Length(32)]).areas(middle);
6154
let [third_height, sextant] = Layout::horizontal([Length(32), Length(32)]).areas(bottom);
6255

56+
frame.render_widget(title, top);
6357
frame.render_widget(full_size_text, full);
6458
frame.render_widget(half_height_text, half_height);
6559
frame.render_widget(half_wide_text, half_wide);

tui-big-text/examples/pixel_size.tape

+2
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ Sleep 2s
1010
Show
1111
Screenshot "target/pixel_size.png"
1212
Sleep 1s
13+
Hide
14+
Escape

tui-big-text/examples/stopwatch.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ use std::{
33
time::{Duration, Instant},
44
};
55

6-
use anyhow::{bail, Context, Result};
6+
use color_eyre::{
7+
eyre::{bail, Context},
8+
Result,
9+
};
710
use crossterm::{
811
event::{self, KeyCode},
912
execute,
@@ -308,17 +311,17 @@ struct Tui {
308311
impl Tui {
309312
fn init() -> Result<Tui> {
310313
let mut stdout = io::stdout();
311-
execute!(stdout, EnterAlternateScreen).context("failed to enter alternate screen")?;
314+
execute!(stdout, EnterAlternateScreen).wrap_err("failed to enter alternate screen")?;
312315
let backend = CrosstermBackend::new(stdout);
313-
let mut terminal = Terminal::new(backend).context("failed to create terminal")?;
314-
enable_raw_mode().context("failed to enable raw mode")?;
315-
terminal.hide_cursor().context("failed to hide cursor")?;
316-
terminal.clear().context("failed to clear console")?;
316+
let mut terminal = Terminal::new(backend).wrap_err("failed to create terminal")?;
317+
enable_raw_mode().wrap_err("failed to enable raw mode")?;
318+
terminal.hide_cursor().wrap_err("failed to hide cursor")?;
319+
terminal.clear().wrap_err("failed to clear console")?;
317320
Ok(Self { terminal })
318321
}
319322

320323
fn draw(&mut self, frame: impl FnOnce(&mut Frame)) -> Result<()> {
321-
self.terminal.draw(frame).context("failed to draw frame")?;
324+
self.terminal.draw(frame).wrap_err("failed to draw frame")?;
322325
Ok(())
323326
}
324327
}

0 commit comments

Comments
 (0)