1 //! Key (or legend) 2 3 use std::borrow::Cow; 4 5 use crate::traits::Set; 6 use crate::{Default, Display, Script, Title}; 7 8 /// Properties of the key 9 #[derive(Clone)] 10 pub struct Properties { 11 boxed: bool, 12 hidden: bool, 13 justification: Option<Justification>, 14 order: Option<Order>, 15 position: Option<Position>, 16 stacked: Option<Stacked>, 17 title: Option<Cow<'static, str>>, 18 } 19 20 impl Default for Properties { default() -> Properties21 fn default() -> Properties { 22 Properties { 23 boxed: false, 24 hidden: false, 25 justification: None, 26 order: None, 27 position: None, 28 stacked: None, 29 title: None, 30 } 31 } 32 } 33 34 impl Properties { 35 /// Hides the key hide(&mut self) -> &mut Properties36 pub fn hide(&mut self) -> &mut Properties { 37 self.hidden = true; 38 self 39 } 40 41 /// Shows the key 42 /// 43 /// **Note** The key is shown by default show(&mut self) -> &mut Properties44 pub fn show(&mut self) -> &mut Properties { 45 self.hidden = false; 46 self 47 } 48 } 49 50 impl Script for Properties { 51 // Allow clippy::format_push_string even with older versions of rust (<1.62) which 52 // don't have it defined. 53 #[allow(clippy::all)] script(&self) -> String54 fn script(&self) -> String { 55 let mut script = if self.hidden { 56 return String::from("set key off\n"); 57 } else { 58 String::from("set key on ") 59 }; 60 61 match self.position { 62 None => {} 63 Some(Position::Inside(v, h)) => { 64 script.push_str(&format!("inside {} {} ", v.display(), h.display())) 65 } 66 Some(Position::Outside(v, h)) => { 67 script.push_str(&format!("outside {} {} ", v.display(), h.display())) 68 } 69 } 70 71 if let Some(stacked) = self.stacked { 72 script.push_str(stacked.display()); 73 script.push(' '); 74 } 75 76 if let Some(justification) = self.justification { 77 script.push_str(justification.display()); 78 script.push(' '); 79 } 80 81 if let Some(order) = self.order { 82 script.push_str(order.display()); 83 script.push(' '); 84 } 85 86 if let Some(ref title) = self.title { 87 script.push_str(&format!("title '{}' ", title)) 88 } 89 90 if self.boxed { 91 script.push_str("box ") 92 } 93 94 script.push('\n'); 95 script 96 } 97 } 98 99 impl Set<Boxed> for Properties { 100 /// Select if the key will be surrounded with a box or not 101 /// 102 /// **Note** The key is not boxed by default set(&mut self, boxed: Boxed) -> &mut Properties103 fn set(&mut self, boxed: Boxed) -> &mut Properties { 104 match boxed { 105 Boxed::No => self.boxed = false, 106 Boxed::Yes => self.boxed = true, 107 } 108 109 self 110 } 111 } 112 113 impl Set<Justification> for Properties { 114 /// Changes the justification of the text of each entry 115 /// 116 /// **Note** The text is `RightJustified` by default set(&mut self, justification: Justification) -> &mut Properties117 fn set(&mut self, justification: Justification) -> &mut Properties { 118 self.justification = Some(justification); 119 self 120 } 121 } 122 123 impl Set<Order> for Properties { 124 /// How to order each entry 125 /// 126 /// **Note** The default order is `TextSample` set(&mut self, order: Order) -> &mut Properties127 fn set(&mut self, order: Order) -> &mut Properties { 128 self.order = Some(order); 129 self 130 } 131 } 132 133 impl Set<Position> for Properties { 134 /// Selects where to place the key 135 /// 136 /// **Note** By default, the key is placed `Inside(Vertical::Top, Horizontal::Right)` set(&mut self, position: Position) -> &mut Properties137 fn set(&mut self, position: Position) -> &mut Properties { 138 self.position = Some(position); 139 self 140 } 141 } 142 143 impl Set<Stacked> for Properties { 144 /// Changes how the entries of the key are stacked set(&mut self, stacked: Stacked) -> &mut Properties145 fn set(&mut self, stacked: Stacked) -> &mut Properties { 146 self.stacked = Some(stacked); 147 self 148 } 149 } 150 151 impl Set<Title> for Properties { set(&mut self, title: Title) -> &mut Properties152 fn set(&mut self, title: Title) -> &mut Properties { 153 self.title = Some(title.0); 154 self 155 } 156 } 157 158 /// Whether the key is surrounded by a box or not 159 #[allow(missing_docs)] 160 #[derive(Clone, Copy)] 161 pub enum Boxed { 162 No, 163 Yes, 164 } 165 166 /// Horizontal position of the key 167 #[derive(Clone, Copy)] 168 pub enum Horizontal { 169 /// Center of the figure 170 Center, 171 /// Left border of the figure 172 Left, 173 /// Right border of the figure 174 Right, 175 } 176 177 /// Text justification of the key 178 #[allow(missing_docs)] 179 #[derive(Clone, Copy)] 180 pub enum Justification { 181 Left, 182 Right, 183 } 184 185 /// Order of the elements of the key 186 #[derive(Clone, Copy)] 187 pub enum Order { 188 /// Sample first, then text 189 SampleText, 190 /// Text first, then sample 191 TextSample, 192 } 193 194 /// Position of the key 195 // TODO XY position 196 #[derive(Clone, Copy)] 197 pub enum Position { 198 /// Inside the area surrounded by the four (BottomX, TopX, LeftY and RightY) axes 199 Inside(Vertical, Horizontal), 200 /// Outside of that area 201 Outside(Vertical, Horizontal), 202 } 203 204 /// How the entries of the key are stacked 205 #[allow(missing_docs)] 206 #[derive(Clone, Copy)] 207 pub enum Stacked { 208 Horizontally, 209 Vertically, 210 } 211 212 /// Vertical position of the key 213 #[derive(Clone, Copy)] 214 pub enum Vertical { 215 /// Bottom border of the figure 216 Bottom, 217 /// Center of the figure 218 Center, 219 /// Top border of the figure 220 Top, 221 } 222