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