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 {
script(&self) -> String51     fn script(&self) -> String {
52         let mut script = if self.hidden {
53             return String::from("set key off\n");
54         } else {
55             String::from("set key on ")
56         };
57 
58         match self.position {
59             None => {}
60             Some(Position::Inside(v, h)) => {
61                 script.push_str(&format!("inside {} {} ", v.display(), h.display()))
62             }
63             Some(Position::Outside(v, h)) => {
64                 script.push_str(&format!("outside {} {} ", v.display(), h.display()))
65             }
66         }
67 
68         if let Some(stacked) = self.stacked {
69             script.push_str(stacked.display());
70             script.push(' ');
71         }
72 
73         if let Some(justification) = self.justification {
74             script.push_str(justification.display());
75             script.push(' ');
76         }
77 
78         if let Some(order) = self.order {
79             script.push_str(order.display());
80             script.push(' ');
81         }
82 
83         if let Some(ref title) = self.title {
84             script.push_str(&format!("title '{}' ", title))
85         }
86 
87         if self.boxed {
88             script.push_str("box ")
89         }
90 
91         script.push('\n');
92         script
93     }
94 }
95 
96 impl Set<Boxed> for Properties {
97     /// Select if the key will be surrounded with a box or not
98     ///
99     /// **Note** The key is not boxed by default
set(&mut self, boxed: Boxed) -> &mut Properties100     fn set(&mut self, boxed: Boxed) -> &mut Properties {
101         match boxed {
102             Boxed::No => self.boxed = false,
103             Boxed::Yes => self.boxed = true,
104         }
105 
106         self
107     }
108 }
109 
110 impl Set<Justification> for Properties {
111     /// Changes the justification of the text of each entry
112     ///
113     /// **Note** The text is `RightJustified` by default
set(&mut self, justification: Justification) -> &mut Properties114     fn set(&mut self, justification: Justification) -> &mut Properties {
115         self.justification = Some(justification);
116         self
117     }
118 }
119 
120 impl Set<Order> for Properties {
121     /// How to order each entry
122     ///
123     /// **Note** The default order is `TextSample`
set(&mut self, order: Order) -> &mut Properties124     fn set(&mut self, order: Order) -> &mut Properties {
125         self.order = Some(order);
126         self
127     }
128 }
129 
130 impl Set<Position> for Properties {
131     /// Selects where to place the key
132     ///
133     /// **Note** By default, the key is placed `Inside(Vertical::Top, Horizontal::Right)`
set(&mut self, position: Position) -> &mut Properties134     fn set(&mut self, position: Position) -> &mut Properties {
135         self.position = Some(position);
136         self
137     }
138 }
139 
140 impl Set<Stacked> for Properties {
141     /// Changes how the entries of the key are stacked
set(&mut self, stacked: Stacked) -> &mut Properties142     fn set(&mut self, stacked: Stacked) -> &mut Properties {
143         self.stacked = Some(stacked);
144         self
145     }
146 }
147 
148 impl Set<Title> for Properties {
set(&mut self, title: Title) -> &mut Properties149     fn set(&mut self, title: Title) -> &mut Properties {
150         self.title = Some(title.0);
151         self
152     }
153 }
154 
155 /// Whether the key is surrounded by a box or not
156 #[allow(missing_docs)]
157 #[derive(Clone, Copy)]
158 pub enum Boxed {
159     No,
160     Yes,
161 }
162 
163 /// Horizontal position of the key
164 #[derive(Clone, Copy)]
165 pub enum Horizontal {
166     /// Center of the figure
167     Center,
168     /// Left border of the figure
169     Left,
170     /// Right border of the figure
171     Right,
172 }
173 
174 /// Text justification of the key
175 #[allow(missing_docs)]
176 #[derive(Clone, Copy)]
177 pub enum Justification {
178     Left,
179     Right,
180 }
181 
182 /// Order of the elements of the key
183 #[derive(Clone, Copy)]
184 pub enum Order {
185     /// Sample first, then text
186     SampleText,
187     /// Text first, then sample
188     TextSample,
189 }
190 
191 /// Position of the key
192 // TODO XY position
193 #[derive(Clone, Copy)]
194 pub enum Position {
195     /// Inside the area surrounded by the four (BottomX, TopX, LeftY and RightY) axes
196     Inside(Vertical, Horizontal),
197     /// Outside of that area
198     Outside(Vertical, Horizontal),
199 }
200 
201 /// How the entries of the key are stacked
202 #[allow(missing_docs)]
203 #[derive(Clone, Copy)]
204 pub enum Stacked {
205     Horizontally,
206     Vertically,
207 }
208 
209 /// Vertical position of the key
210 #[derive(Clone, Copy)]
211 pub enum Vertical {
212     /// Bottom border of the figure
213     Bottom,
214     /// Center of the figure
215     Center,
216     /// Top border of the figure
217     Top,
218 }
219