This repository has no description
0

Configure Feed

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

1use crate::{ColoredObject, Fill, Filter, ObjectSizes, Region, Toggleable}; 2use std::{collections::HashMap, fmt::Display}; 3 4#[derive(Debug, Clone, Default)] 5// #[wasm_bindgen(getter_with_clone)] 6pub struct Layer { 7 pub object_sizes: ObjectSizes, 8 pub objects: HashMap<String, ColoredObject>, 9 pub name: String, 10 pub hidden: bool, 11 pub _render_cache: Option<svg::node::element::Group>, 12} 13 14impl Layer { 15 pub fn new(name: impl Display) -> Self { 16 Layer { 17 object_sizes: ObjectSizes::default(), 18 objects: HashMap::new(), 19 name: format!("{}", name), 20 _render_cache: None, 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 // Flush the render cache. 46 pub fn flush(&mut self) { 47 self._render_cache = None; 48 } 49 50 // Remove all objects. 51 pub fn clear(&mut self) { 52 self.objects.clear(); 53 self.flush(); 54 } 55 56 pub fn replace(&mut self, with: Layer) { 57 self.objects.clone_from(&with.objects); 58 self.flush(); 59 } 60 61 pub fn remove_all_objects_in(&mut self, region: &Region) { 62 self.objects.retain(|_, ColoredObject { object, .. }| { 63 !object.region().within(region) 64 }) 65 } 66 67 pub fn paint_all_objects(&mut self, fill: Fill) { 68 for obj in self.objects.values_mut() { 69 obj.fill = Some(fill); 70 } 71 self.flush(); 72 } 73 74 pub fn filter_all_objects(&mut self, filter: Filter) { 75 for obj in self.objects.values_mut() { 76 obj.filters.push(filter) 77 } 78 self.flush(); 79 } 80 81 pub fn move_all_objects(&mut self, dx: i32, dy: i32) { 82 self.objects 83 .iter_mut() 84 .for_each(|(_, ColoredObject { object, .. })| { 85 object.translate(dx, dy) 86 }); 87 self.flush(); 88 } 89 90 pub fn add(&mut self, name: impl Display, object: impl Into<ColoredObject>) { 91 let name_str = format!("{}", name); 92 93 if self.objects.contains_key(&name_str) { 94 panic!("object {} already exists in layer {}", name_str, self.name); 95 } 96 97 self.set(name_str, object); 98 } 99 100 pub fn add_anon(&mut self, object: impl Into<ColoredObject>) { 101 self.add(format!("anon-{}", self.objects.len()), object); 102 } 103 104 pub fn set(&mut self, name: impl Display, object: impl Into<ColoredObject>) { 105 let name_str = format!("{}", name); 106 107 self.objects.insert(name_str, object.into()); 108 self.flush(); 109 } 110 111 pub fn filter_object( 112 &mut self, 113 name: &str, 114 filter: Filter, 115 ) -> Result<(), String> { 116 self.objects 117 .get_mut(name) 118 .ok_or(format!("Object '{}' not found", name))? 119 .filters 120 .push(filter); 121 122 self.flush(); 123 Ok(()) 124 } 125 126 pub fn remove_object(&mut self, name: &str) { 127 self.objects.remove(name); 128 self.flush(); 129 } 130 131 pub fn replace_object(&mut self, name: &str, object: ColoredObject) { 132 self.remove_object(name); 133 self.add(name, object); 134 } 135 136 pub fn add_objects( 137 &mut self, 138 objects: impl IntoIterator<Item = ColoredObject>, 139 ) { 140 for obj in objects { 141 self.add_anon(obj); 142 } 143 } 144 145 /// Returns the effective region the layer occupies, by merging all its objects' regions. 146 pub fn region(&self) -> Region { 147 self.objects 148 .values() 149 .map(|object| object.region()) 150 .fold(Region::default(), |acc, region| acc.merge(&region)) 151 } 152} 153 154impl ColoredObject { 155 pub fn add_to(self, layer: &mut Layer) { 156 layer.add_anon(self); 157 } 158 159 pub fn set_in(self, layer: &mut Layer, name: impl Display) { 160 layer.set(name, self); 161 } 162}