use winit::keyboard::{Key, NamedKey}; use crate::{ EventQueue, coordinates::{CharPosition, CharRect, WINDOW_SIZE_CHARS}, draw_buffer::DrawBuffer, }; use super::{NextWidget, Widget, WidgetResponse}; pub struct Toggle { pos: CharPosition, width: u8, state: usize, next_widget: NextWidget, variants: &'static [(T, &'static str)], } impl Widget for Toggle { fn draw(&self, draw_buffer: &mut DrawBuffer, selected: bool) { let str = self.variants[self.state].1; draw_buffer.draw_rect( 0, CharRect::new( self.pos.y(), self.pos.y(), self.pos.x() + u8::try_from(str.len()).unwrap(), self.pos.x() + self.width, ), ); let (fg_color, bg_color) = match selected { true => (0, 3), false => (2, 0), }; draw_buffer.draw_string(str, self.pos, fg_color, bg_color); } fn process_input( &mut self, modifiers: &winit::event::Modifiers, key_event: &winit::event::KeyEvent, _: &mut EventQueue<'_>, ) -> WidgetResponse { if key_event.logical_key == Key::Named(NamedKey::Space) && modifiers.state().is_empty() && key_event.state.is_pressed() { self.next(); WidgetResponse::RequestRedraw(true) } else { self.next_widget.process_key_event(key_event, modifiers) } } #[cfg(feature = "accesskit")] fn build_tree(&self, tree: &mut Vec<(accesskit::NodeId, accesskit::Node)>) { todo!() } } impl Toggle { pub fn new( pos: CharPosition, width: u8, next_widget: NextWidget, variants: &'static [(T, &'static str)], ) -> Self { assert!(pos.x() + width < WINDOW_SIZE_CHARS.0); Self { pos, width, state: 0, next_widget, variants, } } pub fn next(&mut self) { self.state += 1; if self.state >= self.variants.len() { self.state = 0; } } pub fn get_variant(&self) -> T { self.variants[self.state].0 } }