pixel_widgets/widget/
frame.rs1use crate::draw::Primitive;
2use crate::layout::{Rectangle, Size};
3use crate::node::{IntoNode, Node};
4use crate::style::Stylesheet;
5use crate::widget::*;
6
7pub struct Frame<'a, T> {
9 content: Option<Node<'a, T>>,
10}
11
12impl<'a, T: 'a> Frame<'a, T> {
13 pub fn new(content: impl IntoNode<'a, T>) -> Self {
15 Self {
16 content: Some(content.into_node()),
17 }
18 }
19
20 pub fn extend<I: IntoIterator<Item = N>, N: IntoNode<'a, T>>(mut self, iter: I) -> Self {
22 if self.content.is_none() {
23 self.content = iter.into_iter().next().map(IntoNode::into_node);
24 }
25 self
26 }
27
28 fn content(&self) -> &Node<'a, T> {
29 self.content.as_ref().expect("content of `Frame` must be set")
30 }
31
32 fn content_mut(&mut self) -> &mut Node<'a, T> {
33 self.content.as_mut().expect("content of `Frame` must be set")
34 }
35}
36
37impl<'a, T: 'a> Default for Frame<'a, T> {
38 fn default() -> Self {
39 Self { content: None }
40 }
41}
42
43impl<'a, T: 'a> Widget<'a, T> for Frame<'a, T> {
44 type State = ();
45
46 fn mount(&self) {}
47
48 fn widget(&self) -> &'static str {
49 "frame"
50 }
51
52 fn len(&self) -> usize {
53 1
54 }
55
56 fn visit_children(&mut self, visitor: &mut dyn FnMut(&mut dyn GenericNode<'a, T>)) {
57 visitor(&mut **self.content_mut());
58 }
59
60 fn size(&self, _: &(), style: &Stylesheet) -> (Size, Size) {
61 style
62 .background
63 .resolve_size((style.width, style.height), self.content().size(), style.padding)
64 }
65
66 fn event(
67 &mut self,
68 _: &mut (),
69 layout: Rectangle,
70 clip: Rectangle,
71 style: &Stylesheet,
72 event: Event,
73 context: &mut Context<T>,
74 ) {
75 self.content_mut().event(
76 style.background.content_rect(layout, style.padding),
77 clip,
78 event,
79 context,
80 );
81 }
82
83 fn draw(&mut self, _: &mut (), layout: Rectangle, clip: Rectangle, style: &Stylesheet) -> Vec<Primitive<'a>> {
84 let content_rect = style.background.content_rect(layout, style.padding);
85
86 style
87 .background
88 .render(layout)
89 .into_iter()
90 .chain(self.content_mut().draw(content_rect, clip).into_iter())
91 .collect()
92 }
93}
94
95impl<'a, T: 'a> IntoNode<'a, T> for Frame<'a, T> {
96 fn into_node(self) -> Node<'a, T> {
97 Node::from_widget(self)
98 }
99}