old school music tracker
at main 91 lines 2.4 kB view raw
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}