03_element/
03_element.rs

1//! Uses elements to divide the screen into segments.
2
3use crossterm::event::{Event, KeyCode, KeyEvent, KeyEventKind};
4use milk_tea::{
5    area::{Area, Element},
6    draw_call::{DrawCall, DrawCallKind},
7    rect::Rect,
8    run,
9    text_size::UnicodeSize,
10};
11
12fn main() {
13    run(Model::default(), view, update).unwrap();
14}
15
16fn view(_model: &Model, area: &mut Area) {
17    // Split the screen into three sections, one upper and two lower.
18    let upper = area.size().map_y(|y| y / 2).as_rect();
19
20    let lower_size = area.size().map(|xy| xy / 2);
21    let lower_left = Rect::new(lower_size.with_x(0).into(), lower_size);
22    let lower_right = Rect::new(lower_size.into(), lower_size);
23
24    area.push_element(upper, Box::new(center("top text".to_owned())));
25    area.push_element(lower_left, Box::new(center("lower left text".to_owned())));
26    area.push_element(lower_right, Box::new(center("lower right text".to_owned())));
27}
28
29/// Returns an `Element` with centered text. `Element`s are just closures that take in an `&mut
30/// Area` to push draw calls to.
31fn center(text: String) -> Element {
32    Box::new(move |area| {
33        area.push_all(vec![DrawCall::new(
34            area.center_rect(text.rect()).pos,
35            DrawCallKind::PrintLine(text.limit_size(area.size())),
36        )]);
37    })
38}
39
40fn update(event: Event, app: &mut Model) {
41    if let Event::Key(KeyEvent {
42        code: KeyCode::Esc,
43        kind: KeyEventKind::Press,
44        ..
45    }) = event
46    {
47        app.0 = true;
48    }
49}
50
51#[derive(Default, Clone, PartialEq, Eq)]
52struct Model(bool);
53
54impl milk_tea::Model for Model {
55    fn should_exit(&self) -> bool {
56        self.0
57    }
58}