Skip to main content

bexa_ui_core/widgets/
container.rs

1use taffy::prelude::*;
2use taffy::Overflow;
3
4use crate::framework::{DrawContext, Widget};
5
6pub struct Container {
7    style: Style,
8    background: Option<[f32; 4]>,
9    border_radius: f32,
10    border_width: f32,
11    border_color: [f32; 4],
12    scrollable: bool,
13}
14
15impl Container {
16    pub fn new() -> Self {
17        Self {
18            style: Style {
19                display: Display::Flex,
20                flex_direction: FlexDirection::Column,
21                flex_grow: 1.0,
22                ..Default::default()
23            },
24            background: None,
25            border_radius: 0.0,
26            border_width: 0.0,
27            border_color: [0.0; 4],
28            scrollable: false,
29        }
30    }
31
32    pub fn with_padding(mut self, padding: f32) -> Self {
33        self.style.padding = Rect {
34            left: LengthPercentage::Length(padding),
35            right: LengthPercentage::Length(padding),
36            top: LengthPercentage::Length(padding),
37            bottom: LengthPercentage::Length(padding),
38        };
39        self
40    }
41
42    pub fn with_background(mut self, color: [f32; 3]) -> Self {
43        self.background = Some([color[0], color[1], color[2], 1.0]);
44        self
45    }
46
47    pub fn with_background_alpha(mut self, color: [f32; 4]) -> Self {
48        self.background = Some(color);
49        self
50    }
51
52    pub fn with_border_radius(mut self, radius: f32) -> Self {
53        self.border_radius = radius;
54        self
55    }
56
57    pub fn with_border(mut self, width: f32, color: [f32; 4]) -> Self {
58        self.border_width = width;
59        self.border_color = color;
60        self
61    }
62
63    pub fn with_height(mut self, height: f32) -> Self {
64        self.style.size.height = Dimension::Length(height);
65        self
66    }
67
68    pub fn with_max_height(mut self, height: f32) -> Self {
69        self.style.max_size.height = Dimension::Length(height);
70        self
71    }
72
73    pub fn with_scroll(mut self) -> Self {
74        self.scrollable = true;
75        self.style.overflow.y = Overflow::Hidden;
76        self
77    }
78
79    pub fn with_gap(mut self, gap: f32) -> Self {
80        self.style.gap = Size {
81            width: LengthPercentage::Length(gap),
82            height: LengthPercentage::Length(gap),
83        };
84        self
85    }
86}
87
88impl Widget for Container {
89    fn style(&self) -> Style {
90        self.style.clone()
91    }
92
93    fn is_scrollable(&self) -> bool {
94        self.scrollable
95    }
96
97    fn draw(&self, ctx: &mut DrawContext) {
98        if let Some(color) = self.background {
99            let layout = ctx.layout;
100            ctx.renderer.fill_rect_styled(
101                (
102                    layout.location.x,
103                    layout.location.y,
104                    layout.size.width,
105                    layout.size.height,
106                ),
107                color,
108                self.border_radius,
109                self.border_width,
110                self.border_color,
111            );
112        }
113    }
114}