hadrone_core/
collision.rs1use crate::LayoutItem;
4
5pub trait CollisionResolver: Send + Sync {
7 fn resolve_collisions(&self, layout: &mut Vec<LayoutItem>, moved_id: &str);
8}
9
10#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
12pub struct PushDownResolver;
13
14impl CollisionResolver for PushDownResolver {
15 fn resolve_collisions(&self, layout: &mut Vec<LayoutItem>, moved_id: &str) {
16 let Some(moved_item) = layout.iter().find(|i| i.id == moved_id).cloned() else {
17 return;
18 };
19
20 let mut items_to_move = Vec::new();
21 for item in layout.iter() {
22 if item.id != moved_id && crate::collides(&moved_item, item) {
23 items_to_move.push(item.id.clone());
24 }
25 }
26
27 for id in items_to_move {
28 if let Some(index) = layout.iter().position(|i| i.id == id)
29 && !layout[index].is_static
30 {
31 layout[index].y = moved_item.y + moved_item.h;
32 let next_id = layout[index].id.clone();
33 self.resolve_collisions(layout, &next_id);
34 }
35 }
36 }
37}
38
39#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
41pub struct NoopCollisionResolver;
42
43impl CollisionResolver for NoopCollisionResolver {
44 fn resolve_collisions(&self, _layout: &mut Vec<LayoutItem>, _moved_id: &str) {}
45}
46
47#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
49pub enum CollisionStrategy {
50 #[default]
51 PushDown,
52 None,
54}
55
56impl CollisionStrategy {
57 pub fn build(self) -> Box<dyn CollisionResolver> {
58 match self {
59 CollisionStrategy::PushDown => Box::new(PushDownResolver),
60 CollisionStrategy::None => Box::new(NoopCollisionResolver),
61 }
62 }
63}