1//! Key (or legend)
2
3use std::borrow::Cow;
4
5use crate::traits::Set;
6use crate::{Default, Display, Script, Title};
7
8/// Properties of the key
9#[derive(Clone)]
10pub 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
20impl 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
34impl 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
50impl 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
99impl 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
113impl 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
123impl 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
133impl 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
143impl 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
151impl 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)]
161pub enum Boxed {
162 No,
163 Yes,
164}
165
166/// Horizontal position of the key
167#[derive(Clone, Copy)]
168pub 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)]
180pub enum Justification {
181 Left,
182 Right,
183}
184
185/// Order of the elements of the key
186#[derive(Clone, Copy)]
187pub 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)]
197pub 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)]
207pub enum Stacked {
208 Horizontally,
209 Vertically,
210}
211
212/// Vertical position of the key
213#[derive(Clone, Copy)]
214pub 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