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} 12 13impl Layer { 14 pub fn new(name: impl Display) -> Self { 15 Layer { 16 object_sizes: ObjectSizes::default(), 17 objects: HashMap::new(), 18 name: format!("{}", name), 19 hidden: false, 20 } 21 } 22 23 pub fn hide(&mut self) { 24 self.hidden = true; 25 } 26 27 pub fn show(&mut self) { 28 self.hidden = false; 29 } 30 31 pub fn toggle(&mut self) { 32 self.hidden.toggle(); 33 } 34 35 pub fn object(&mut self, name: &str) -> &mut ColoredObject { 36 self.safe_object(name).unwrap() 37 } 38 39 pub fn safe_object(&mut self, name: &str) -> Option<&mut ColoredObject> { 40 self.objects.get_mut(name) 41 } 42 43 // Flush the render cache. 44 pub fn flush(&mut self) { 45 // nothing 46 } 47 48 // Remove all objects. 49 pub fn clear(&mut self) { 50 self.objects.clear(); 51 self.flush(); 52 } 53 54 pub fn replace(&mut self, with: Layer) { 55 self.objects.clone_from(&with.objects); 56 self.flush(); 57 } 58 59 pub fn remove_all_objects_in(&mut self, region: &Region) { 60 self.objects.retain(|_, ColoredObject { object, .. }| { 61 !object.region().within(region) 62 }) 63 } 64 65 pub fn paint_all_objects(&mut self, fill: Fill) { 66 for obj in self.objects.values_mut() { 67 obj.fill = Some(fill); 68 } 69 self.flush(); 70 } 71 72 pub fn filter_all_objects(&mut self, filter: Filter) { 73 for obj in self.objects.values_mut() { 74 obj.filters.push(filter) 75 } 76 self.flush(); 77 } 78 79 pub fn move_all_objects(&mut self, dx: i32, dy: i32) { 80 self.objects 81 .iter_mut() 82 .for_each(|(_, ColoredObject { object, .. })| { 83 object.translate(dx, dy) 84 }); 85 self.flush(); 86 } 87 88 pub fn add(&mut self, name: impl Display, object: impl Into<ColoredObject>) { 89 let name_str = format!("{}", name); 90 91 if self.objects.contains_key(&name_str) { 92 panic!("object {} already exists in layer {}", name_str, self.name); 93 } 94 95 self.set(name_str, object); 96 } 97 98 pub fn add_anon(&mut self, object: impl Into<ColoredObject>) { 99 self.add(format!("anon-{}", self.objects.len()), object); 100 } 101 102 pub fn set(&mut self, name: impl Display, object: impl Into<ColoredObject>) { 103 let name_str = format!("{}", name); 104 105 self.objects.insert(name_str, object.into()); 106 self.flush(); 107 } 108 109 pub fn filter_object( 110 &mut self, 111 name: &str, 112 filter: Filter, 113 ) -> Result<(), String> { 114 self.objects 115 .get_mut(name) 116 .ok_or(format!("Object '{}' not found", name))? 117 .filters 118 .push(filter); 119 120 self.flush(); 121 Ok(()) 122 } 123 124 pub fn remove_object(&mut self, name: &str) { 125 self.objects.remove(name); 126 self.flush(); 127 } 128 129 pub fn replace_object(&mut self, name: &str, object: ColoredObject) { 130 self.remove_object(name); 131 self.add(name, object); 132 } 133 134 pub fn add_objects( 135 &mut self, 136 objects: impl IntoIterator<Item = ColoredObject>, 137 ) { 138 for obj in objects { 139 self.add_anon(obj); 140 } 141 } 142 143 /// Returns the effective region the layer occupies, by merging all its objects' regions. 144 pub fn region(&self) -> Region { 145 self.objects 146 .values() 147 .map(|object| object.region()) 148 .fold(Region::default(), |acc, region| acc.merge(&region)) 149 } 150} 151 152impl ColoredObject { 153 pub fn add_to(self, layer: &mut Layer) { 154 layer.add_anon(self); 155 } 156 157 pub fn set_in(self, layer: &mut Layer, name: impl Display) { 158 layer.set(name, self); 159 } 160}