Skip to main content

30_image/
30_image.rs

1//! Example 30: Image Widget
2//!
3//! Demonstrates the image widget for displaying images using the Kitty
4//! graphics protocol.
5//!
6//! Features:
7//! - Display PNG, JPEG, and GIF images
8//! - Embed images at compile time with include_bytes!
9//! - Load images from file path at runtime
10//!
11//! NOTE: Requires a Kitty-protocol compatible terminal:
12//! - Kitty
13//! - Ghostty
14//! - WezTerm
15//!
16//! Run with: cargo run -p telex-tui --example 30_image
17
18use crossterm::event::KeyCode;
19use telex::prelude::*;
20
21telex::require_api!(0, 2);
22
23fn main() {
24    telex::run_with_theme(App, telex::theme::Theme::nord()).unwrap();
25}
26
27struct App;
28
29impl Component for App {
30    fn render(&self, cx: Scope) -> View {
31        let show_help = state!(cx, || false);
32
33        // F1 toggles help
34        cx.use_command(
35            KeyBinding::key(KeyCode::F(1)),
36            with!(show_help => move || show_help.update(|v| *v = !*v)),
37        );
38        View::vstack()
39            .spacing(1)
40            .child(
41                View::styled_text("Image Widget Demo (Kitty Graphics)")
42                    .bold()
43                    .build(),
44            )
45            .child(View::text("Requires Kitty, Ghostty, or WezTerm terminal"))
46            .child(View::text(""))
47            // Load image from file path
48            .child(View::text("Logo (from file path):"))
49            .child(View::image().file("assets/telex-tui.png").build())
50            .child(View::text(""))
51            .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
52            .child(
53                View::modal()
54                    .visible(show_help.get())
55                    .title("Example 30: Image")
56                    .on_dismiss(with!(show_help => move || show_help.set(false)))
57                    .child(
58                        View::vstack()
59                            .child(View::styled_text("What you're seeing").bold().build())
60                            .child(View::text("• Image display via Kitty protocol"))
61                            .child(View::text("• PNG/JPEG/GIF support"))
62                            .child(View::text("• Loaded from file path"))
63                            .child(View::gap(1))
64                            .child(View::styled_text("Key concepts").bold().build())
65                            .child(View::text("• View::image() displays images"))
66                            .child(View::text("• .file(\"path\") loads from disk"))
67                            .child(View::text("• .bytes(data) for embedded images"))
68                            .child(View::text("• Works in Kitty/Ghostty/WezTerm"))
69                            .child(View::gap(1))
70                            .child(View::styled_text("Try this").bold().build())
71                            .child(View::text("• Run in compatible terminal"))
72                            .child(View::text("• See the Telex logo rendered"))
73                            .child(View::gap(1))
74                            .child(View::styled_text("Next up").bold().build())
75                            .child(View::text("→ 31_animated_canvas: animations"))
76                            .child(View::gap(1))
77                            .child(View::styled_text("Press Escape to close").dim().build())
78                            .build(),
79                    )
80                    .build(),
81            )
82            .build()
83    }
84}