old school music tracker
1use winit::keyboard::{Key, NamedKey};
2
3use crate::{
4 EventQueue,
5 coordinates::{CharPosition, CharRect, WINDOW_SIZE_CHARS},
6 draw_buffer::DrawBuffer,
7};
8
9use super::{NextWidget, Widget, WidgetResponse};
10
11pub struct Toggle<T: Copy + 'static> {
12 pos: CharPosition,
13 width: u8,
14 state: usize,
15 next_widget: NextWidget,
16 variants: &'static [(T, &'static str)],
17}
18
19impl<T: Copy> Widget for Toggle<T> {
20 fn draw(&self, draw_buffer: &mut DrawBuffer, selected: bool) {
21 let str = self.variants[self.state].1;
22 draw_buffer.draw_rect(
23 0,
24 CharRect::new(
25 self.pos.y(),
26 self.pos.y(),
27 self.pos.x() + u8::try_from(str.len()).unwrap(),
28 self.pos.x() + self.width,
29 ),
30 );
31 let (fg_color, bg_color) = match selected {
32 true => (0, 3),
33 false => (2, 0),
34 };
35 draw_buffer.draw_string(str, self.pos, fg_color, bg_color);
36 }
37
38 fn process_input(
39 &mut self,
40 modifiers: &winit::event::Modifiers,
41 key_event: &winit::event::KeyEvent,
42 _: &mut EventQueue<'_>,
43 ) -> WidgetResponse {
44 if key_event.logical_key == Key::Named(NamedKey::Space)
45 && modifiers.state().is_empty()
46 && key_event.state.is_pressed()
47 {
48 self.next();
49 WidgetResponse::RequestRedraw(true)
50 } else {
51 self.next_widget.process_key_event(key_event, modifiers)
52 }
53 }
54
55 #[cfg(feature = "accesskit")]
56 fn build_tree(&self, tree: &mut Vec<(accesskit::NodeId, accesskit::Node)>) {
57 todo!()
58 }
59}
60
61impl<T: Copy + 'static> Toggle<T> {
62 pub fn new(
63 pos: CharPosition,
64 width: u8,
65 next_widget: NextWidget,
66 variants: &'static [(T, &'static str)],
67 ) -> Self {
68 assert!(pos.x() + width < WINDOW_SIZE_CHARS.0);
69
70 Self {
71 pos,
72 width,
73 state: 0,
74 next_widget,
75 variants,
76 }
77 }
78
79 pub fn next(&mut self) {
80 self.state += 1;
81 if self.state >= self.variants.len() {
82 self.state = 0;
83 }
84 }
85
86 pub fn get_variant(&self) -> T {
87 self.variants[self.state].0
88 }
89}