old school music tracker
at dev 89 lines 2.3 kB view raw
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}