Skip to main content

menu_drawable/
menu_drawable.rs

1use ascii_assets::{Color, TerminalChar};
2use common_stdx::Rect;
3use crossterm::{event::MouseButton, terminal::size};
4use ltrender::{
5    DrawObject, Renderer,
6    display_screen::AreaRect,
7    draw_object_builder::{CircleDrawableBuilder, RectDrawableBuilder},
8    drawable_register::ObjectLifetime,
9    error::AppError,
10    init_logger, init_terminal,
11    input_handler::hook::InputButton,
12    rendering::{render_thread::start_renderer_with_input, renderer::Instant},
13    terminal_buffer::{
14        RectDrawable,
15        buffer_and_celldrawer::{CrosstermCellDrawer, DefaultScreenBuffer},
16        standard_drawables::{
17            rect_drawable::BorderStyle,
18            select_menu_drawable::{SelectMenuDrawable, SelectMenuFitting},
19        },
20    },
21};
22
23fn main() -> Result<(), AppError> {
24    init_terminal!();
25    init_logger("./menu_drawable_example.log")?;
26    let (cols, rows) = size()?;
27    let renderer = Renderer::<DefaultScreenBuffer<CrosstermCellDrawer>, Instant>::create_renderer(
28        (cols, rows),
29    );
30    let (r, ev_handler, _ev_manager) = start_renderer_with_input(renderer);
31    r.set_update_interval(1)?;
32
33    let hook = ev_handler.create_hook();
34
35    let inside_rect1 = RectDrawableBuilder::new()
36        .border_style(BorderStyle::Basic)
37        .fill_style(' ')
38        .rect(Rect::from_coords(0, 0, 3, 3))
39        .build()?;
40    let inside_rect2 = RectDrawableBuilder::new()
41        .border_style(BorderStyle::AllRound(TerminalChar::from_char('~')))
42        .fill_style(' ')
43        .rect(Rect::from_coords(0, 0, 3, 3))
44        .build()?;
45    let inside_circle = CircleDrawableBuilder::new()
46        .border_style(TerminalChar::from_char('O').set_bg(Color::Maroon))
47        .radius(4)
48        .build()?;
49    let border_rect = RectDrawable {
50        rect: Rect::from_coords(0, 0, 0, 0),
51        border_thickness: 1,
52        border_style: BorderStyle::AllRound(TerminalChar::from_char('+').set_fg(Color::Fuchsia)),
53        fill_style: Some(TerminalChar::from_char(' ')),
54        screen_fit: None,
55    };
56
57    let menu_screen = r.create_screen(AreaRect::FullScreen, 0)?;
58
59    let menu_drawable = SelectMenuDrawable::new(
60        vec![inside_rect1, inside_rect2, inside_circle],
61        border_rect,
62        SelectMenuFitting::FitToContents,
63        menu_screen,
64        hook,
65        r.clone(),
66    )?;
67
68    let drawable_id = r.register_drawable(
69        menu_screen,
70        DrawObject {
71            creation_time: std::time::Instant::now(),
72            drawable: Box::new(menu_drawable),
73            layer: 0,
74            lifetime: ObjectLifetime::ExplicitRemove,
75            shaders: Vec::new(),
76        },
77    )?;
78    r.render_drawable(drawable_id)?;
79    let hook = ev_handler.create_hook();
80    loop {
81        if hook.is_pressed(InputButton::Mouse(MouseButton::Right)) {
82            break;
83        }
84    }
85    let _ = restore_terminal();
86    Ok(())
87}