yakui_widgets/widgets/
window.rs

1use std::fmt;
2
3use yakui_core::geometry::{Color, Constraints, Vec2};
4use yakui_core::widget::Widget;
5use yakui_core::Response;
6
7use crate::colors;
8use crate::util::widget;
9use crate::widgets::Pad;
10
11/**
12A floating window within the application.
13
14Responds with [WindowResponse].
15*/
16#[must_use = "yakui widgets do nothing if you don't `show` them"]
17pub struct Window {
18    pub initial_size: Vec2,
19    children: Option<Box<dyn Fn()>>,
20}
21
22impl Window {
23    pub fn new<S: Into<Vec2>>(initial_size: S) -> Self {
24        Self {
25            initial_size: initial_size.into(),
26            children: None,
27        }
28    }
29
30    pub fn show<F: 'static + Fn()>(mut self, children: F) -> Response<WindowResponse> {
31        self.children = Some(Box::new(children));
32        widget::<WindowWidget>(self)
33    }
34}
35
36#[derive(Debug)]
37pub struct WindowWidget {
38    props: Window,
39}
40
41pub type WindowResponse = ();
42
43impl Widget for WindowWidget {
44    type Props<'a> = Window;
45    type Response = WindowResponse;
46
47    fn new() -> Self {
48        Self {
49            props: Window::new(Vec2::ZERO),
50        }
51    }
52
53    fn update(&mut self, props: Self::Props<'_>) -> Self::Response {
54        self.props = props;
55
56        crate::colored_box_container(colors::BACKGROUND_2, || {
57            crate::column(|| {
58                // Window Title Bar
59                let constraints = Constraints::loose(self.props.initial_size);
60                crate::constrained(constraints, || {
61                    crate::pad(Pad::all(8.0), || {
62                        crate::row(|| {
63                            crate::colored_box(Color::BLUE, [16.0, 16.0]);
64                            crate::expanded(|| {
65                                crate::pad(Pad::balanced(8.0, 0.0), || {
66                                    crate::text(16.0, "Yakui Window");
67                                });
68                            });
69                            crate::colored_box(Color::RED, [16.0, 16.0]);
70                        });
71                    });
72                });
73
74                // Window Contents
75                crate::constrained(constraints, || {
76                    if let Some(children) = &self.props.children {
77                        children();
78                    }
79                });
80            });
81        });
82    }
83}
84
85impl fmt::Debug for Window {
86    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87        f.debug_struct("Window")
88            .field("size", &self.initial_size)
89            .finish_non_exhaustive()
90    }
91}