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 { |
21 | 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 |
36 | 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 |
44 | 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)] |
54 | 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 |
103 | 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 |
117 | 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` |
127 | 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)` |
137 | 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 |
145 | fn set(&mut self, stacked: Stacked) -> &mut Properties { |
146 | self.stacked = Some(stacked); |
147 | self |
148 | } |
149 | } |
150 | |
151 | impl Set<Title> for Properties { |
152 | 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 | |