gpui_component/plot/
grid.rs

1use gpui::{px, Bounds, Hsla, PathBuilder, Pixels, Point, Window};
2
3use super::origin_point;
4
5pub struct Grid {
6    x: Vec<Pixels>,
7    y: Vec<Pixels>,
8    stroke: Hsla,
9    dash_array: Option<Vec<Pixels>>,
10}
11
12impl Grid {
13    #[allow(clippy::new_without_default)]
14    pub fn new() -> Self {
15        Self {
16            x: vec![],
17            y: vec![],
18            stroke: Default::default(),
19            dash_array: None,
20        }
21    }
22
23    /// Set the x of the Grid.
24    pub fn x(mut self, x: Vec<impl Into<Pixels>>) -> Self {
25        self.x = x.into_iter().map(|v| v.into()).collect();
26        self
27    }
28
29    /// Set the y of the Grid.
30    pub fn y(mut self, y: Vec<impl Into<Pixels>>) -> Self {
31        self.y = y.into_iter().map(|v| v.into()).collect();
32        self
33    }
34
35    /// Set the stroke color of the Grid.
36    pub fn stroke(mut self, stroke: impl Into<Hsla>) -> Self {
37        self.stroke = stroke.into();
38        self
39    }
40
41    /// Set the dash array of the Grid.
42    pub fn dash_array(mut self, dash_array: &[Pixels]) -> Self {
43        self.dash_array = Some(dash_array.to_vec());
44        self
45    }
46
47    fn points(&self, bounds: &Bounds<Pixels>) -> Vec<(Point<Pixels>, Point<Pixels>)> {
48        let size = bounds.size;
49        let origin = bounds.origin;
50
51        let mut x = self
52            .x
53            .iter()
54            .map(|x| {
55                (
56                    origin_point(*x, px(0.), origin),
57                    origin_point(*x, size.height, origin),
58                )
59            })
60            .collect::<Vec<_>>();
61
62        let y = self
63            .y
64            .iter()
65            .map(|y| {
66                (
67                    origin_point(px(0.), *y, origin),
68                    origin_point(size.width, *y, origin),
69                )
70            })
71            .collect::<Vec<_>>();
72
73        x.extend(y);
74        x
75    }
76
77    /// Paint the Grid.
78    pub fn paint(&self, bounds: &Bounds<Pixels>, window: &mut Window) {
79        let points = self.points(bounds);
80
81        for (start, end) in points {
82            let mut builder = PathBuilder::stroke(px(1.));
83
84            if let Some(dash_array) = &self.dash_array {
85                builder = builder.dash_array(&dash_array);
86            }
87
88            builder.move_to(start);
89            builder.line_to(end);
90            if let Ok(line) = builder.build() {
91                window.paint_path(line, self.stroke);
92            }
93        }
94    }
95}