term_wm_layout_engine/
region_map.rs1use crate::rect::{LayoutRect, rect_contains};
2
3#[cfg(not(feature = "std"))]
4use alloc::collections::BTreeMap;
5#[cfg(feature = "std")]
6use std::collections::BTreeMap;
7
8#[derive(Debug, Clone)]
14pub struct RegionMap<T: Ord> {
15 regions: BTreeMap<T, LayoutRect>,
16}
17
18impl<T: Ord> RegionMap<T> {
19 pub fn new() -> Self {
20 Self {
21 regions: BTreeMap::new(),
22 }
23 }
24
25 pub fn ids(&self) -> Vec<T>
26 where
27 T: Copy,
28 {
29 self.regions.keys().copied().collect()
30 }
31
32 pub fn set(&mut self, id: T, rect: LayoutRect) {
33 self.regions.insert(id, rect);
34 }
35
36 pub fn get(&self, id: &T) -> Option<LayoutRect> {
37 self.regions.get(id).copied()
38 }
39
40 pub fn remove(&mut self, id: &T) {
41 self.regions.remove(id);
42 }
43
44 pub fn is_empty(&self) -> bool {
45 self.regions.is_empty()
46 }
47
48 pub fn contains_key(&self, id: &T) -> bool {
49 self.regions.contains_key(id)
50 }
51
52 pub fn hit_test(&self, col: u16, row: u16, ids: &[T]) -> Option<T>
54 where
55 T: Copy,
56 {
57 for id in ids {
58 if let Some(rect) = self.regions.get(id)
59 && rect_contains(rect, col, row)
60 {
61 return Some(*id);
62 }
63 }
64 None
65 }
66}
67
68impl<T: Ord> Default for RegionMap<T> {
69 fn default() -> Self {
70 Self::new()
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77
78 fn rect(x: i32, y: i32, w: u16, h: u16) -> LayoutRect {
79 LayoutRect {
80 x,
81 y,
82 width: w,
83 height: h,
84 }
85 }
86
87 #[test]
88 fn region_map_set_get_remove() {
89 let mut map: RegionMap<u8> = RegionMap::new();
90 map.set(1, rect(0, 0, 10, 10));
91 assert_eq!(map.get(&1), Some(rect(0, 0, 10, 10)));
92 map.remove(&1);
93 assert_eq!(map.get(&1), None);
94 }
95
96 #[test]
97 fn region_map_hit_test() {
98 let mut map: RegionMap<u8> = RegionMap::new();
99 map.set(1, rect(0, 0, 10, 10));
100 map.set(2, rect(10, 0, 10, 10));
101 assert_eq!(map.hit_test(5, 5, &[1, 2]), Some(1));
102 assert_eq!(map.hit_test(15, 5, &[1, 2]), Some(2));
103 assert_eq!(map.hit_test(50, 50, &[1, 2]), None);
104 }
105
106 #[test]
107 fn region_map_ids() {
108 let mut map: RegionMap<u8> = RegionMap::new();
109 map.set(3, rect(0, 0, 1, 1));
110 map.set(1, rect(0, 0, 1, 1));
111 let mut ids = map.ids();
112 ids.sort();
113 assert_eq!(ids, vec![1, 3]);
114 }
115
116 #[test]
117 fn region_map_is_empty() {
118 let map: RegionMap<u8> = RegionMap::new();
119 assert!(map.is_empty());
120 }
121}