1use std::marker::PhantomData;
2
3use crate::component::Renderer;
4
5use super::component::RenderCtx;
6use super::layout::Bounds;
7use super::{CharmResult, Color, Component};
8
9pub struct Window<Store = ()> {
10 pub(crate) size: (usize, usize),
11 pub(crate) title: Option<String>,
12 pub(crate) background: Option<Color>,
13 pub(crate) root: Option<Box<dyn Component<Store>>>,
14}
15
16impl<Store> Window<Store> {
17 pub fn with_size(size: (usize, usize)) -> Self {
18 Self {
19 size,
20 title: None,
21 background: None,
22 root: None,
23 }
24 }
25
26 pub fn background(mut self, fill: impl Into<Color>) -> Self {
27 self.background = Some(fill.into());
28
29 self
30 }
31
32 pub fn title(mut self, title: impl Into<String>) -> Self {
33 self.title = Some(title.into());
34
35 self
36 }
37
38 pub fn set_root_component<C>(&mut self, component: C) -> &mut Self
39 where
40 C: Component<Store> + 'static,
41 {
42 self.root = Some(Box::new(component));
43
44 self
45 }
46
47 pub(crate) fn render(
48 &self,
49 canvas: &mut sdl2::render::WindowCanvas,
50 store: &Store,
51 ) -> CharmResult<()> {
52 let ctx = RenderCtx {
53 bounds: Bounds {
54 x: 0,
55 y: 0,
56 width: self.size.0,
57 height: self.size.1,
58 },
59 };
60
61 if let Some(ref root) = self.root {
62 let mut renderer = Renderer { canvas };
63 root.render(ctx, &mut renderer, &store)?;
64 }
65
66 Ok(())
67 }
68}