yakui_widgets/widgets/
constrained_box.rs1use yakui_core::geometry::{Constraints, Vec2};
2use yakui_core::widget::{LayoutContext, Widget};
3use yakui_core::Response;
4
5use crate::util::widget_children;
6
7#[derive(Debug, Clone)]
13#[non_exhaustive]
14#[must_use = "yakui widgets do nothing if you don't `show` them"]
15pub struct ConstrainedBox {
16 pub constraints: Constraints,
17}
18
19impl ConstrainedBox {
20 pub fn new(constraints: Constraints) -> Self {
21 Self { constraints }
22 }
23
24 pub fn show<F: FnOnce()>(self, children: F) -> Response<ConstrainedBoxResponse> {
25 widget_children::<ConstrainedBoxWidget, F>(children, self)
26 }
27}
28
29#[derive(Debug)]
30pub struct ConstrainedBoxWidget {
31 props: ConstrainedBox,
32}
33
34pub type ConstrainedBoxResponse = ();
35
36impl Widget for ConstrainedBoxWidget {
37 type Props<'a> = ConstrainedBox;
38 type Response = ConstrainedBoxResponse;
39
40 fn new() -> Self {
41 Self {
42 props: ConstrainedBox::new(Constraints {
43 min: Vec2::ZERO,
44 max: Vec2::ZERO,
45 }),
46 }
47 }
48
49 fn update(&mut self, props: Self::Props<'_>) -> Self::Response {
50 self.props = props;
51 }
52
53 fn layout(&self, mut ctx: LayoutContext<'_>, input: Constraints) -> Vec2 {
54 let node = ctx.dom.get_current();
55 let mut size = Vec2::ZERO;
56 let constraints = Constraints {
57 min: Vec2::max(input.min, self.props.constraints.min),
58 max: Vec2::min(input.max, self.props.constraints.max),
59 };
60
61 for &child in &node.children {
62 let child_size = ctx.calculate_layout(child, constraints);
63 size = size.max(child_size);
64 }
65
66 input.constrain(constraints.constrain(size))
67 }
68}