old school music tracker
at main 56 lines 1.6 kB view raw
1use std::{cell::Cell, rc::Rc}; 2 3use crate::{app::EventQueue, coordinates::CharRect, draw_buffer::DrawBuffer}; 4 5use super::{NextWidget, Widget, WidgetResponse, button::Button}; 6 7// dont need to store a callback as it gets pushed into the inner button callback 8pub struct ToggleButton<T: Copy + PartialEq, R> { 9 button: Button<()>, 10 11 variant: T, 12 cb: fn(T) -> R, 13 state: Rc<Cell<T>>, 14} 15 16impl<T: Copy + PartialEq, R> Widget for ToggleButton<T, R> { 17 type Response = R; 18 fn draw(&self, draw_buffer: &mut DrawBuffer, selected: bool) { 19 self.button 20 .draw_overwrite_pressed(draw_buffer, selected, self.variant == self.state.get()) 21 } 22 23 fn process_input( 24 &mut self, 25 modifiers: &winit::event::Modifiers, 26 key_event: &winit::event::KeyEvent, 27 event: &mut EventQueue<'_>, 28 ) -> WidgetResponse<R> { 29 let WidgetResponse { standard, extra } = 30 self.button.process_input(modifiers, key_event, event); 31 let extra = extra.map(|_| { 32 self.state.set(self.variant); 33 (self.cb)(self.variant) 34 }); 35 WidgetResponse { standard, extra } 36 } 37} 38 39impl<T: Copy + PartialEq + 'static, R> ToggleButton<T, R> { 40 pub fn new( 41 text: &'static str, 42 rect: CharRect, 43 next_widget: NextWidget, 44 variant: T, 45 state: Rc<Cell<T>>, 46 cb: fn(T) -> R, 47 ) -> Self { 48 let button = Button::new(text, rect, next_widget, || ()); 49 Self { 50 button, 51 variant, 52 cb, 53 state, 54 } 55 } 56}