agpu/layout/
responsive.rs1use crate::core::Rect;
4use crate::layout::flex::FlexLayout;
5use crate::layout::{DesiredSize, Layout, SizeConstraints};
6
7pub struct Breakpoint {
9 pub min_width: f32,
10 pub layout: FlexLayout,
11}
12
13impl Breakpoint {
14 pub fn new(min_width: f32, layout: FlexLayout) -> Self {
15 Self { min_width, layout }
16 }
17}
18
19pub struct ResponsiveLayout {
24 breakpoints: Vec<Breakpoint>,
25}
26
27impl ResponsiveLayout {
28 pub fn new() -> Self {
29 Self {
30 breakpoints: Vec::new(),
31 }
32 }
33
34 pub fn breakpoint(mut self, bp: Breakpoint) -> Self {
35 self.breakpoints.push(bp);
36 self.breakpoints
38 .sort_by(|a, b| b.min_width.partial_cmp(&a.min_width).unwrap());
39 self
40 }
41
42 fn active_layout(&self, width: f32) -> Option<&FlexLayout> {
43 self.breakpoints
44 .iter()
45 .find(|bp| width >= bp.min_width)
46 .map(|bp| &bp.layout)
47 }
48}
49
50impl Default for ResponsiveLayout {
51 fn default() -> Self {
52 Self::new()
53 }
54}
55
56impl Layout for ResponsiveLayout {
57 fn measure(&self, children: &[DesiredSize], constraints: SizeConstraints) -> DesiredSize {
58 if let Some(bp) = self.breakpoints.last() {
60 bp.layout.measure(children, constraints)
61 } else {
62 DesiredSize::zero()
63 }
64 }
65
66 fn arrange(&self, children: &[DesiredSize], area: Rect) -> Vec<Rect> {
67 if let Some(layout) = self.active_layout(area.width) {
68 layout.arrange(children, area)
69 } else {
70 let mut rects = Vec::with_capacity(children.len());
72 let mut y = area.y;
73 for child in children {
74 rects.push(Rect::new(area.x, y, child.width, child.height));
75 y += child.height;
76 }
77 rects
78 }
79 }
80}