This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

1use crate::{ 2 ColoredObject, Fill, Filter, ObjectSizes, Point, Region, Toggleable, 3}; 4use std::{collections::HashMap, fmt::Display}; 5 6#[derive(Debug, Clone, Default)] 7// #[wasm_bindgen(getter_with_clone)] 8pub struct Layer { 9 pub object_sizes: ObjectSizes, 10 pub objects: HashMap<String, ColoredObject>, 11 pub name: String, 12 pub hidden: bool, 13} 14 15impl Layer { 16 pub fn new(name: impl Display) -> Self { 17 Layer { 18 object_sizes: ObjectSizes::default(), 19 objects: HashMap::new(), 20 name: format!("{}", name), 21 hidden: false, 22 } 23 } 24 25 pub fn hide(&mut self) { 26 self.hidden = true; 27 } 28 29 pub fn show(&mut self) { 30 self.hidden = false; 31 } 32 33 pub fn toggle(&mut self) { 34 self.hidden.toggle(); 35 } 36 37 pub fn object(&mut self, name: &str) -> &mut ColoredObject { 38 self.safe_object(name).unwrap() 39 } 40 41 pub fn safe_object(&mut self, name: &str) -> Option<&mut ColoredObject> { 42 self.objects.get_mut(name) 43 } 44 45 pub fn objects_in( 46 &mut self, 47 region: Region, 48 ) -> impl Iterator<Item = (&String, &mut ColoredObject)> { 49 self.objects 50 .iter_mut() 51 .filter(move |(_, obj)| obj.object.region().within(&region)) 52 } 53 54 pub fn object_at(&mut self, point: Point) -> Option<&mut ColoredObject> { 55 self.objects 56 .values_mut() 57 .find(|obj| obj.object.region().start == point) 58 } 59 60 // Remove all objects. 61 pub fn clear(&mut self) { 62 self.objects.clear(); 63 } 64 65 pub fn replace(&mut self, with: Layer) { 66 self.objects.clone_from(&with.objects); 67 } 68 69 pub fn remove_all_objects_in(&mut self, region: &Region) { 70 self.objects.retain(|_, ColoredObject { object, .. }| { 71 !object.region().within(region) 72 }) 73 } 74 75 pub fn paint_all_objects(&mut self, fill: Fill) { 76 for obj in self.objects.values_mut() { 77 obj.fill = Some(fill); 78 } 79 } 80 81 pub fn filter_all_objects(&mut self, filter: Filter) { 82 for obj in self.objects.values_mut() { 83 obj.filters.push(filter) 84 } 85 } 86 87 pub fn move_all_objects(&mut self, dx: i32, dy: i32) { 88 self.objects 89 .iter_mut() 90 .for_each(|(_, ColoredObject { object, .. })| { 91 object.translate(dx, dy) 92 }); 93 } 94 95 pub fn add(&mut self, name: impl Display, object: impl Into<ColoredObject>) { 96 let name_str = format!("{}", name); 97 98 if self.objects.contains_key(&name_str) { 99 panic!("object {} already exists in layer {}", name_str, self.name); 100 } 101 102 self.set(name_str, object); 103 } 104 105 pub fn add_anon(&mut self, object: impl Into<ColoredObject>) { 106 self.add(format!("anon-{}", self.objects.len()), object); 107 } 108 109 pub fn set(&mut self, name: impl Display, object: impl Into<ColoredObject>) { 110 let name_str = format!("{}", name); 111 112 self.objects.insert(name_str, object.into()); 113 } 114 115 pub fn filter_object( 116 &mut self, 117 name: &str, 118 filter: Filter, 119 ) -> Result<(), String> { 120 self.objects 121 .get_mut(name) 122 .ok_or(format!("Object '{}' not found", name))? 123 .filters 124 .push(filter); 125 126 Ok(()) 127 } 128 129 pub fn remove_object(&mut self, name: &str) { 130 self.objects.remove(name); 131 } 132 133 pub fn replace_object(&mut self, name: &str, object: ColoredObject) { 134 self.remove_object(name); 135 self.add(name, object); 136 } 137 138 pub fn add_objects( 139 &mut self, 140 objects: impl IntoIterator<Item = ColoredObject>, 141 ) { 142 for obj in objects { 143 self.add_anon(obj); 144 } 145 } 146 147 pub fn objects_with_tag( 148 &mut self, 149 tag: impl Display, 150 ) -> impl Iterator<Item = (&String, &mut ColoredObject)> { 151 let tag_str = format!("{}", tag); 152 self.objects 153 .iter_mut() 154 .filter(move |(_, obj)| obj.has_tag(&tag_str)) 155 } 156 157 pub fn tag_objects( 158 &mut self, 159 tag: impl Display, 160 objects: impl Fn(&String, &ColoredObject) -> bool, 161 ) { 162 let tag_str = format!("{}", tag); 163 for (_, obj) in 164 self.objects.iter_mut().filter(|(id, obj)| objects(id, obj)) 165 { 166 obj.tag(&tag_str); 167 } 168 } 169 170 /// Returns the effective region the layer occupies, by merging all its objects' regions. 171 pub fn region(&self) -> Region { 172 self.objects 173 .values() 174 .map(|object| object.region()) 175 .fold(Region::default(), |acc, region| acc.merge(&region)) 176 } 177} 178 179impl ColoredObject { 180 pub fn add_to(self, layer: &mut Layer) { 181 layer.add_anon(self); 182 } 183 184 pub fn set_in(self, layer: &mut Layer, name: impl Display) { 185 layer.set(name, self); 186 } 187}