leptos_chartistry/
padding.rs

1use super::bounds::Bounds;
2
3/// Represents padding around the edges of a component.
4#[derive(Copy, Clone, Debug, Default, PartialEq)]
5pub struct Padding {
6    pub(crate) top: f64,
7    pub(crate) right: f64,
8    pub(crate) bottom: f64,
9    pub(crate) left: f64,
10}
11
12/// Represents padding around a component. Note that the context matters on how it's applied. For example, padding applied to the whole chart will shrink the available space whereas padding applied to a label will increase the size used.
13impl Padding {
14    /// Creates a new zero / empty / none padding.
15    pub fn zero() -> Self {
16        Self::sides(0.0, 0.0, 0.0, 0.0)
17    }
18
19    /// Creates a new padding with the given top, right, bottom, and left values. This is CSS style: clockwise from the top.
20    pub fn sides(top: f64, right: f64, bottom: f64, left: f64) -> Self {
21        Self {
22            top,
23            right,
24            bottom,
25            left,
26        }
27    }
28
29    /// Creates a new padding with the given horizontal (top and bottom) and vertical (left and right) values.
30    pub fn hv(h: f64, v: f64) -> Self {
31        Self::sides(h, v, h, v)
32    }
33
34    /// Returns the total height of the padding.
35    pub(crate) fn height(&self) -> f64 {
36        self.top + self.bottom
37    }
38
39    /// Returns the total width of the padding.
40    pub(crate) fn width(&self) -> f64 {
41        self.left + self.right
42    }
43
44    /// Applies the padding to the given bounds. Shrinks the bounds by the padding.
45    pub(crate) fn apply(self, outer: Bounds) -> Bounds {
46        outer.shrink(self.top, self.right, self.bottom, self.left)
47    }
48
49    /// Converts the padding to a CSS style string.
50    pub(crate) fn to_css_style(self) -> String {
51        format!(
52            "{}px {}px {}px {}px",
53            self.top, self.right, self.bottom, self.left
54        )
55    }
56}
57
58impl From<f64> for Padding {
59    fn from(v: f64) -> Self {
60        Padding::sides(v, v, v, v)
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67
68    #[test]
69    fn test_padding() {
70        let p = Padding::sides(1.1, 2.2, 3.3, 4.4);
71        assert_eq!(p.top, 1.1);
72        assert_eq!(p.right, 2.2);
73        assert_eq!(p.bottom, 3.3);
74        assert_eq!(p.left, 4.4);
75        assert_eq!(p.height(), 1.1 + 3.3);
76        assert_eq!(p.width(), 2.2 + 4.4);
77        assert_eq!(
78            p.apply(Bounds::new(100.0, 200.0)),
79            Bounds::from_points(4.4, 1.1, 97.8, 196.7)
80        );
81        assert_eq!(p.to_css_style(), "1.1px 2.2px 3.3px 4.4px");
82        assert_eq!(Padding::zero().to_css_style(), "0px 0px 0px 0px");
83        assert_eq!(
84            Padding::hv(1.1, 2.2).to_css_style(),
85            "1.1px 2.2px 1.1px 2.2px"
86        );
87        assert_eq!(Padding::from(1.1).to_css_style(), "1.1px 1.1px 1.1px 1.1px");
88    }
89}