1use crate::gui::{Message, State};
2use crate::theme;
3use iced::{
4 widget::{button, column, container, row, text, Space},
5 Alignment, Element, Length,
6};
7
8#[derive(Debug, Clone)]
9pub struct KeypadButton {
10 pub id: String,
11 pub label: String,
12 pub row: usize,
13 #[allow(dead_code)]
14 pub col: usize,
15 pub current_remap: Option<String>,
16}
17
18pub fn azeron_keypad_layout() -> Vec<KeypadButton> {
19 vec![
20 KeypadButton {
21 id: "JOY_BTN_0".to_string(),
22 label: "1".to_string(),
23 row: 0,
24 col: 0,
25 current_remap: None,
26 },
27 KeypadButton {
28 id: "JOY_BTN_1".to_string(),
29 label: "2".to_string(),
30 row: 0,
31 col: 1,
32 current_remap: None,
33 },
34 KeypadButton {
35 id: "JOY_BTN_2".to_string(),
36 label: "3".to_string(),
37 row: 0,
38 col: 2,
39 current_remap: None,
40 },
41 KeypadButton {
42 id: "JOY_BTN_3".to_string(),
43 label: "4".to_string(),
44 row: 0,
45 col: 3,
46 current_remap: None,
47 },
48 KeypadButton {
49 id: "JOY_BTN_4".to_string(),
50 label: "5".to_string(),
51 row: 0,
52 col: 4,
53 current_remap: None,
54 },
55 KeypadButton {
56 id: "JOY_BTN_5".to_string(),
57 label: "Q".to_string(),
58 row: 2,
59 col: 0,
60 current_remap: None,
61 },
62 KeypadButton {
63 id: "JOY_BTN_6".to_string(),
64 label: "W".to_string(),
65 row: 2,
66 col: 1,
67 current_remap: None,
68 },
69 KeypadButton {
70 id: "JOY_BTN_7".to_string(),
71 label: "E".to_string(),
72 row: 2,
73 col: 2,
74 current_remap: None,
75 },
76 KeypadButton {
77 id: "JOY_BTN_8".to_string(),
78 label: "R".to_string(),
79 row: 2,
80 col: 3,
81 current_remap: None,
82 },
83 KeypadButton {
84 id: "JOY_BTN_9".to_string(),
85 label: "A".to_string(),
86 row: 3,
87 col: 0,
88 current_remap: None,
89 },
90 KeypadButton {
91 id: "JOY_BTN_10".to_string(),
92 label: "S".to_string(),
93 row: 3,
94 col: 1,
95 current_remap: None,
96 },
97 KeypadButton {
98 id: "JOY_BTN_11".to_string(),
99 label: "D".to_string(),
100 row: 3,
101 col: 2,
102 current_remap: None,
103 },
104 KeypadButton {
105 id: "JOY_BTN_12".to_string(),
106 label: "F".to_string(),
107 row: 3,
108 col: 3,
109 current_remap: None,
110 },
111 KeypadButton {
112 id: "JOY_BTN_13".to_string(),
113 label: "Z".to_string(),
114 row: 4,
115 col: 0,
116 current_remap: None,
117 },
118 KeypadButton {
119 id: "JOY_BTN_14".to_string(),
120 label: "X".to_string(),
121 row: 4,
122 col: 1,
123 current_remap: None,
124 },
125 KeypadButton {
126 id: "JOY_BTN_15".to_string(),
127 label: "C".to_string(),
128 row: 4,
129 col: 2,
130 current_remap: None,
131 },
132 KeypadButton {
133 id: "JOY_BTN_16".to_string(),
134 label: "V".to_string(),
135 row: 4,
136 col: 3,
137 current_remap: None,
138 },
139 KeypadButton {
140 id: "JOY_BTN_17".to_string(),
141 label: "6".to_string(),
142 row: 0,
143 col: 5,
144 current_remap: None,
145 },
146 KeypadButton {
147 id: "JOY_BTN_18".to_string(),
148 label: "7".to_string(),
149 row: 1,
150 col: 5,
151 current_remap: None,
152 },
153 KeypadButton {
154 id: "JOY_BTN_19".to_string(),
155 label: "8".to_string(),
156 row: 2,
157 col: 5,
158 current_remap: None,
159 },
160 KeypadButton {
161 id: "JOY_BTN_20".to_string(),
162 label: "9".to_string(),
163 row: 3,
164 col: 5,
165 current_remap: None,
166 },
167 KeypadButton {
168 id: "JOY_BTN_21".to_string(),
169 label: "0".to_string(),
170 row: 4,
171 col: 5,
172 current_remap: None,
173 },
174 KeypadButton {
175 id: "JOY_BTN_22".to_string(),
176 label: "TL".to_string(),
177 row: 6,
178 col: 0,
179 current_remap: None,
180 },
181 KeypadButton {
182 id: "JOY_BTN_23".to_string(),
183 label: "TM".to_string(),
184 row: 6,
185 col: 1,
186 current_remap: None,
187 },
188 KeypadButton {
189 id: "JOY_BTN_24".to_string(),
190 label: "TR".to_string(),
191 row: 6,
192 col: 2,
193 current_remap: None,
194 },
195 KeypadButton {
196 id: "JOY_BTN_25".to_string(),
197 label: "BL".to_string(),
198 row: 7,
199 col: 0,
200 current_remap: None,
201 },
202 KeypadButton {
203 id: "JOY_BTN_26".to_string(),
204 label: "BR".to_string(),
205 row: 7,
206 col: 1,
207 current_remap: None,
208 },
209 ]
210}
211
212pub fn format_remap_target(target: &str) -> String {
213 if let Some(rest) = target.strip_prefix("KEY_") {
214 match rest {
215 "LEFTCTRL" => "LCtrl".to_string(),
216 "RIGHTCTRL" => "RCtrl".to_string(),
217 "LEFTSHIFT" => "LShft".to_string(),
218 "RIGHTSHIFT" => "RShft".to_string(),
219 "LEFTALT" => "LAlt".to_string(),
220 "RIGHTALT" => "RAlt".to_string(),
221 "LEFTMETA" => "LMeta".to_string(),
222 "RIGHTMETA" => "RMeta".to_string(),
223 "SPACE" => "Space".to_string(),
224 "TAB" => "Tab".to_string(),
225 "ENTER" => "Enter".to_string(),
226 "ESC" => "Esc".to_string(),
227 "BACKSPACE" => "Bksp".to_string(),
228 "DELETE" => "Del".to_string(),
229 "INSERT" => "Ins".to_string(),
230 "HOME" => "Home".to_string(),
231 "END" => "End".to_string(),
232 "PAGEUP" => "PgUp".to_string(),
233 "PAGEDOWN" => "PgDn".to_string(),
234 "UP" => "\u{2191}".to_string(),
235 "DOWN" => "\u{2193}".to_string(),
236 "LEFT" => "\u{2190}".to_string(),
237 "RIGHT" => "\u{2192}".to_string(),
238 s if s.len() == 1 => s.to_uppercase(),
239 s if s.starts_with('F') => format!("F{}", &s[1..]),
240 _ => rest.to_string(),
241 }
242 } else if let Some(rest) = target.strip_prefix("BTN_") {
243 match rest {
244 "LEFT" => "LMB".to_string(),
245 "RIGHT" => "RMB".to_string(),
246 "MIDDLE" => "Mid".to_string(),
247 "SIDE" => "Side".to_string(),
248 "EXTRA" => "Extra".to_string(),
249 "FORWARD" => "Fwd".to_string(),
250 "BACK" => "Back".to_string(),
251 _ => rest.to_string(),
252 }
253 } else if let Some(rest) = target.strip_prefix("REL_") {
254 match rest {
255 "WHEEL" => "Wheel".to_string(),
256 "HWHEEL" => "HWheel".to_string(),
257 _ => rest.to_string(),
258 }
259 } else {
260 if target.len() > 6 {
261 format!("{}...", &target[..6])
262 } else {
263 target.to_string()
264 }
265 }
266}
267
268pub fn view(state: &State) -> Element<'_, Message> {
269 let layout = azeron_keypad_layout();
270
271 let mut rows: Vec<Vec<Element<'_, Message>>> = Vec::with_capacity(10);
272 for _ in 0..10 {
273 rows.push(Vec::new());
274 }
275
276 for keypad_button in &layout {
277 let button_id = keypad_button.id.clone();
278 let label = keypad_button.label.clone();
279 let remap = keypad_button.current_remap.clone();
280 let is_selected = state.selected_button
281 == Some(
282 layout
283 .iter()
284 .position(|b| b.id == keypad_button.id)
285 .unwrap_or(usize::MAX),
286 );
287
288 let button_style = if is_selected {
289 iced::theme::Button::Primary
290 } else if remap.is_some() {
291 iced::theme::Button::Secondary
292 } else {
293 iced::theme::Button::Text
294 };
295
296 let button_content: Element<'_, Message> = if let Some(ref target) = remap {
297 let display_name = format_remap_target(target);
298 container(
299 column![
300 text(label)
301 .size(8)
302 .style(iced::theme::Text::Color(iced::Color::from_rgb(
303 0.5, 0.5, 0.5
304 ))),
305 text(display_name).size(11).width(Length::Fixed(45.0)),
306 ]
307 .spacing(2)
308 .align_items(Alignment::Center),
309 )
310 .center_x()
311 .center_y()
312 .into()
313 } else {
314 container(text(label).size(12)).center_x().center_y().into()
315 };
316
317 let btn = button(button_content)
318 .on_press(Message::SelectKeypadButton(button_id.clone()))
319 .style(button_style)
320 .padding([6, 8])
321 .width(iced::Length::Fixed(54.0))
322 .height(iced::Length::Fixed(54.0))
323 .into();
324
325 if rows.get_mut(keypad_button.row).is_some() {
326 rows[keypad_button.row].push(btn);
327 }
328 }
329
330 let hat_switch = container(text("Hat\n\u{2195}").size(10))
331 .width(iced::Length::Fixed(54.0))
332 .height(iced::Length::Fixed(54.0))
333 .center_x()
334 .center_y()
335 .style(theme::styles::card)
336 .into();
337
338 if rows.get_mut(5).is_some() {
339 rows[5].push(hat_switch);
340 }
341
342 let keypad_rows: Vec<Element<'_, Message>> = rows
343 .into_iter()
344 .filter(|r| !r.is_empty())
345 .map(|row_elements| {
346 row(row_elements)
347 .spacing(4)
348 .align_items(Alignment::Center)
349 .into()
350 })
351 .collect();
352
353 let keypad_content = column![
354 text("Azeron Keypad Layout").size(20),
355 Space::with_height(10),
356 text("Click a button to configure remapping").size(12),
357 Space::with_height(20),
358 ]
359 .spacing(10)
360 .align_items(Alignment::Center)
361 .push(
362 column(keypad_rows)
363 .spacing(4)
364 .align_items(Alignment::Center),
365 );
366
367 container(keypad_content)
368 .padding(24)
369 .width(Length::Fill)
370 .center_x()
371 .into()
372}