Skip to main content

term_wm_layout_engine/
orientation.rs

1use crate::rect::{LayoutRect, Orientation};
2
3/// Decides which orientation to use when splitting an area.
4pub trait OrientationHeuristic {
5    fn choose(&mut self, area: LayoutRect, depth: usize) -> Orientation;
6}
7
8/// Splits along the longer side of the area (width ≥ height → Horizontal).
9#[derive(Debug, Clone)]
10pub struct LongestSide;
11
12impl OrientationHeuristic for LongestSide {
13    fn choose(&mut self, area: LayoutRect, _depth: usize) -> Orientation {
14        if area.width >= area.height {
15            Orientation::Horizontal
16        } else {
17            Orientation::Vertical
18        }
19    }
20}
21
22/// Cycles `Horizontal, Vertical, Horizontal, Vertical, …` based on depth.
23#[derive(Debug, Clone)]
24pub struct Spiral;
25
26impl OrientationHeuristic for Spiral {
27    fn choose(&mut self, _area: LayoutRect, depth: usize) -> Orientation {
28        if depth.is_multiple_of(2) {
29            Orientation::Horizontal
30        } else {
31            Orientation::Vertical
32        }
33    }
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39
40    #[test]
41    fn longest_side_wide_space() {
42        let mut h = LongestSide;
43        let area = LayoutRect {
44            x: 0,
45            y: 0,
46            width: 100,
47            height: 50,
48        };
49        assert_eq!(h.choose(area, 0), Orientation::Horizontal);
50    }
51
52    #[test]
53    fn longest_side_tall_space() {
54        let mut h = LongestSide;
55        let area = LayoutRect {
56            x: 0,
57            y: 0,
58            width: 50,
59            height: 100,
60        };
61        assert_eq!(h.choose(area, 0), Orientation::Vertical);
62    }
63
64    #[test]
65    fn longest_side_square() {
66        let mut h = LongestSide;
67        let area = LayoutRect {
68            x: 0,
69            y: 0,
70            width: 80,
71            height: 80,
72        };
73        assert_eq!(h.choose(area, 0), Orientation::Horizontal);
74    }
75
76    #[test]
77    fn spiral_alternates() {
78        let mut h = Spiral;
79        let area = LayoutRect {
80            x: 0,
81            y: 0,
82            width: 80,
83            height: 24,
84        };
85        assert_eq!(h.choose(area, 0), Orientation::Horizontal);
86        assert_eq!(h.choose(area, 1), Orientation::Vertical);
87        assert_eq!(h.choose(area, 2), Orientation::Horizontal);
88        assert_eq!(h.choose(area, 3), Orientation::Vertical);
89    }
90}