Skip to main content

tui/
tui.rs

1//! Example showing ratatui integration with colors.
2
3use ascii_petgraph::{BoxBorder, RenderedGraph};
4use petgraph::graph::DiGraph;
5use ratatui::{
6    DefaultTerminal,
7    crossterm::event::{self, Event, KeyCode},
8    style::Color,
9};
10use std::io;
11
12fn main() -> io::Result<()> {
13    // Create a state machine graph
14    let mut graph: DiGraph<&str, &str> = DiGraph::new();
15
16    let idle = graph.add_node("Idle");
17    let running = graph.add_node("Running");
18    let paused = graph.add_node("Paused");
19    let complete = graph.add_node("Complete");
20    let failed = graph.add_node("Failed");
21
22    let e_start = graph.add_edge(idle, running, "start");
23    let e_pause = graph.add_edge(running, paused, "pause");
24    let e_resume = graph.add_edge(paused, running, "resume");
25    let e_finish = graph.add_edge(running, complete, "finish");
26    let e_fail = graph.add_edge(running, failed, "error");
27    let e_reset = graph.add_edge(complete, idle, "reset");
28    let e_retry = graph.add_edge(failed, idle, "retry");
29
30    // Create rendered graph
31    let mut rendered = RenderedGraph::builder()
32        .graph(graph)
33        .border_style(BoxBorder::Rounded)
34        .gravity(0.8)
35        .spring_constant(0.05)
36        .repulsion_constant(8000.0)
37        .build();
38
39    // Run physics simulation
40    rendered.run_simulation();
41
42    // Apply colors based on state meaning
43    rendered.set_node_border_color(idle, Color::Gray);
44    rendered.set_node_border_color(running, Color::Green);
45    rendered.set_node_text_color(running, Color::Green);
46    rendered.set_node_border_color(paused, Color::Yellow);
47    rendered.set_node_text_color(paused, Color::Yellow);
48    rendered.set_node_border_color(complete, Color::Blue);
49    rendered.set_node_text_color(complete, Color::Blue);
50    rendered.set_node_border_color(failed, Color::Red);
51    rendered.set_node_text_color(failed, Color::Red);
52
53    // Color edges
54    rendered.set_edge_color(e_start, Color::Green);
55    rendered.set_edge_color(e_pause, Color::Yellow);
56    rendered.set_edge_color(e_resume, Color::Green);
57    rendered.set_edge_color(e_finish, Color::Blue);
58    rendered.set_edge_color(e_fail, Color::Red);
59    rendered.set_edge_color(e_reset, Color::Gray);
60    rendered.set_edge_color(e_retry, Color::Yellow);
61
62    // Run TUI
63    let mut terminal = ratatui::init();
64    let result = run_app(&mut terminal, &mut rendered);
65    ratatui::restore();
66    result
67}
68
69fn run_app<N, E>(
70    terminal: &mut DefaultTerminal,
71    rendered: &mut RenderedGraph<N, E>,
72) -> io::Result<()>
73where
74    N: std::fmt::Display + Clone,
75    E: std::fmt::Display + Clone,
76{
77    loop {
78        terminal.draw(|frame| {
79            let area = frame.area();
80            frame.render_widget(rendered.widget(), area);
81        })?;
82
83        if let Event::Key(key) = event::read()? {
84            if key.code == KeyCode::Char('q') || key.code == KeyCode::Esc {
85                break;
86            }
87        }
88    }
89    Ok(())
90}