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