cognitive_frames/
searching.rs1use qualia::{Direction, Position, SurfaceId};
9use frame::{Frame, Geometry, Mode};
10
11pub trait Searching {
15 fn find(&self, matcher: &Fn(&Frame) -> bool) -> Option<Frame>;
17
18 fn find_buildable(&self) -> Option<Frame>;
21
22 fn find_top(&self) -> Option<Frame>;
24
25 fn find_with_sid(&self, sid: SurfaceId) -> Option<Frame>;
27
28 fn find_pointed(&self, point: Position) -> Frame;
31
32 fn find_neighbouring(&self, direction: Direction) -> Option<Frame>;
35
36 fn find_contiguous(&self, direction: Direction, distance: u32) -> Option<Frame>;
38
39 fn find_adjacent(&self, direction: Direction, distance: u32) -> Option<Frame>;
41}
42
43impl Searching for Frame {
46 fn find(&self, matcher: &Fn(&Frame) -> bool) -> Option<Frame> {
47 if matcher(self) {
48 Some(self.clone())
49 } else {
50 for subsurface in self.space_iter() {
51 let result = subsurface.find(matcher);
52 if result.is_some() {
53 return result;
54 }
55 }
56 None
57 }
58 }
59
60 fn find_buildable(&self) -> Option<Frame> {
61 if self.get_sid().is_valid() {
62 self.get_parent()
63 } else {
64 Some(self.clone())
65 }
66 }
67
68 fn find_top(&self) -> Option<Frame> {
69 let mut current = Some(self.clone());
70 loop {
71 current = if let Some(ref frame) = current {
72 if frame.is_top() {
73 return current.clone();
74 }
75 frame.get_parent()
76 } else {
77 return None;
78 }
79 }
80 }
81
82 fn find_with_sid(&self, sid: SurfaceId) -> Option<Frame> {
83 if self.get_sid() == sid {
84 Some(self.clone())
85 } else {
86 for subsurface in self.time_iter() {
87 let result = subsurface.find_with_sid(sid);
88 if result.is_some() {
89 return result;
90 }
91 }
92 None
93 }
94 }
95
96 fn find_pointed(&self, mut point: Position) -> Frame {
97 let area = self.get_area().rebased();
98 if self.get_mode() != Mode::Root {
99 point = point.casted(&area);
100 }
101
102 for ref frame in self.time_iter() {
103 let area = frame.get_area();
104 if area.contains(&point) {
105 return if self.get_mode().is_leaf() {
106 frame.clone()
107 } else {
108 frame.find_pointed(point - area.pos)
109 };
110 }
111 }
112 self.clone()
113 }
114
115 fn find_neighbouring(&self, direction: Direction) -> Option<Frame> {
116 if let Some(parent) = self.get_parent() {
117 if parent.get_geometry() == Geometry::Vertical {
118 if direction == Direction::North {
119 self.get_prev_space()
120 } else if direction == Direction::South {
121 self.get_next_space()
122 } else {
123 None
124 }
125 } else if parent.get_geometry() == Geometry::Horizontal {
126 if direction == Direction::West {
127 self.get_prev_space()
128 } else if direction == Direction::East {
129 self.get_next_space()
130 } else {
131 None
132 }
133 } else if parent.get_geometry() == Geometry::Stacked {
134 if direction == Direction::Begin {
135 self.get_prev_space()
136 } else if direction == Direction::End {
137 self.get_next_space()
138 } else {
139 None
140 }
141 } else {
142 None
143 }
144 } else {
145 None
146 }
147 }
148
149 fn find_contiguous(&self, direction: Direction, distance: u32) -> Option<Frame> {
150 if distance == 0 {
152 return Some(self.clone());
153 }
154
155 let mut frame = self.find_neighbouring(direction);
157
158 let new_distance = if frame.is_some() || (direction == Direction::Up) {
160 distance - 1
161 } else {
162 distance
163 };
164 if frame.is_none() {
165 frame = self.get_parent();
166 }
167
168 if let Some(frame) = frame {
169 if frame.is_top() {
171 None
172 } else {
173 frame.find_contiguous(direction, new_distance)
174 }
175 } else {
176 None
177 }
178 }
179
180 fn find_adjacent(&self, direction: Direction, distance: u32) -> Option<Frame> {
181 let point = self.get_area().calculate_center();
183
184 let mut frame = Some(self.clone());
186 for _ in 0..distance {
187 frame = if let Some(ref frame) = frame {
188 frame.find_contiguous(direction, 1)
189 } else {
190 break;
191 };
192 if direction != Direction::Begin || direction != Direction::End {
193 frame = if let Some(ref frame) = frame {
194 Some(frame.find_pointed(point - frame.get_area().pos))
195 } else {
196 break;
197 };
198 }
199 }
200 frame
201 }
202}
203
204