Skip to main content

ferroui_base/visual_tree/
transformed_bounds.rs

1use crate::{Matrix, Point, Rect};
2use std::fmt;
3
4/// Holds information about the bounds of a control, together with a
5/// transform and a clip.
6#[derive(Clone, Copy, Debug, PartialEq)]
7pub struct TransformedBounds {
8    /// The control's bounds.
9    pub bounds: Rect,
10    /// The clip rectangle, in global coordinates.
11    pub clip: Rect,
12    /// The transform that maps the control's bounds to global coordinates.
13    pub transform: Matrix,
14}
15
16impl TransformedBounds {
17    /// Creates transformed bounds.
18    pub const fn new(bounds: Rect, clip: Rect, transform: Matrix) -> Self {
19        Self { bounds, clip, transform }
20    }
21
22    /// Whether the transformed bounds contain a point given in global
23    /// coordinates.
24    pub fn contains(&self, point: Point) -> bool {
25        if self.transform.has_inverse() {
26            let tr_point = point * self.transform.invert();
27            self.bounds.contains(tr_point)
28        } else {
29            self.bounds.contains(point)
30        }
31    }
32}
33
34impl fmt::Display for TransformedBounds {
35    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36        write!(f, "Bounds: {} Clip: {} Transform {}", self.bounds, self.clip, self.transform)
37    }
38}
39
40#[cfg(test)]
41mod tests {
42    use super::*;
43
44    #[test]
45    fn contains_uses_inverse_transform() {
46        let bounds = TransformedBounds::new(
47            Rect::new(0.0, 0.0, 10.0, 10.0),
48            Rect::new(0.0, 0.0, 100.0, 100.0),
49            Matrix::create_translation(50.0, 50.0),
50        );
51
52        assert!(bounds.contains(Point::new(55.0, 55.0)));
53        assert!(!bounds.contains(Point::new(5.0, 5.0)));
54    }
55}