diff --git a/src/frontpanel.rs b/src/frontpanel.rs index 5be79dd..6909006 100644 --- a/src/frontpanel.rs +++ b/src/frontpanel.rs @@ -1,16 +1,17 @@ -use std::path::Path; +use std::{path::Path, sync::mpsc::Sender}; use eframe::{ egui::{self, TextureOptions, Ui, Widget, Id, Painter}, epaint::{vec2, Pos2, Rect, TextureHandle, pos2, Color32}, }; +use crate::audio::AudioMessage; + use self::switch::SwitchState; pub mod led; pub mod switch; - const NULL_UV: Rect = Rect::from_min_max(pos2(0.0, 0.0), pos2(1.0, 1.0)); const NULL_TINT: Color32 = Color32::WHITE; @@ -31,13 +32,15 @@ struct FrontpanelState { pub struct Frontpanel<'a> { id: Id, textures: &'a Textures, + audio_tx: Sender, } impl<'a> Frontpanel<'a> { - pub fn new(id: Id, textures: &'a Textures) -> Self { + pub fn new(id: Id, textures: &'a Textures, audio_tx: Sender) -> Self { Self { id, textures, + audio_tx, } } } @@ -73,13 +76,10 @@ impl Widget for Frontpanel<'_> { pos += fp_rect.left_top().to_vec2(); let led_data = 0xAAAA; let led_on = (led_data & led.mask) > 0; - ui.allocate_ui_at_rect( - Rect::from_center_size(pos, vec2(16.0, 16.0)), - |ui| { - ui.add(led::Led::new(led_on, &led_textures)); - }, - ); - }; + ui.allocate_ui_at_rect(Rect::from_center_size(pos, vec2(16.0, 16.0)), |ui| { + ui.add(led::Led::new(led_on, &led_textures)); + }); + } // 0: Power // 1..17: A/D left to right // 17..25: Action left to right @@ -89,22 +89,28 @@ impl Widget for Frontpanel<'_> { pos.y *= y_scale; pos += fp_rect.left_top().to_vec2(); if i == 0 { - ui.allocate_ui_at_rect( - Rect::from_center_size(pos, vec2(32.0, 32.0)), - |ui| { - ui.add(switch::ToggleSwitch::new(&mut state.power, &sw_textures)); - }, - ); + ui.allocate_ui_at_rect(Rect::from_center_size(pos, vec2(32.0, 32.0)), |ui| { + if ui + .add(switch::ToggleSwitch::new(&mut state.power, &sw_textures)) + .drag_started() + { + if state.power { + self.audio_tx.send(AudioMessage::FanOn).unwrap(); + } else { + self.audio_tx.send(AudioMessage::FanOff).unwrap(); + } + self.audio_tx.send(AudioMessage::PlaySwitchClick).unwrap(); + }; + }); } if (1..17).contains(&i) { let bit_mask = 1 << (16 - i); let mut sw_state = state.ad_sws & bit_mask > 0; - ui.allocate_ui_at_rect( - Rect::from_center_size(pos, vec2(32.0, 32.0)), - |ui| { - ui.add(switch::ToggleSwitch::new(&mut sw_state, &sw_textures)); - }, - ); + ui.allocate_ui_at_rect(Rect::from_center_size(pos, vec2(32.0, 32.0)), |ui| { + if ui.add(switch::ToggleSwitch::new(&mut sw_state, &sw_textures)).drag_started() { + self.audio_tx.send(AudioMessage::PlaySwitchClick).unwrap(); + }; + }); state.ad_sws = (state.ad_sws & !(bit_mask)) | ((sw_state as u16) << (16 - i)); } if (17..25).contains(&i) { @@ -119,16 +125,17 @@ impl Widget for Frontpanel<'_> { 24 => &mut state.aux2, _ => unreachable!(), }; - ui.allocate_ui_at_rect( - Rect::from_center_size(pos, vec2(32.0, 32.0)), - |ui| { - ui.add(switch::ThreePosSwitch::new(state, &sw_textures)); - }, - ); + ui.allocate_ui_at_rect(Rect::from_center_size(pos, vec2(32.0, 32.0)), |ui| { + if ui.add(switch::ThreePosSwitch::new(state, &sw_textures)).drag_started() { + self.audio_tx.send(AudioMessage::PlaySwitchClick).unwrap(); + }; + }); } - // todo!(); } ui.data_mut(|data| data.insert_temp(self.id, state)); + if resp.drag_started() { + dbg!(self.id, resp.interact_pointer_pos()); + } resp } } diff --git a/src/main.rs b/src/main.rs index ca78c50..9eaf2e0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -227,8 +227,16 @@ impl eframe::App for AltairEmulator { }); egui::CentralPanel::default().show(ctx, |ui| { ui.add(Label::new("Hello")); - ui.add(Frontpanel::new(Id::new("frontpanel"), &self.textures)); - ui.add(Frontpanel::new(Id::new("frontpanel2"), &self.textures)); + ui.add(Frontpanel::new( + Id::new("frontpanel"), + &self.textures, + self.audio_tx.clone(), + )); + ui.add(Frontpanel::new( + Id::new("frontpanel2"), + &self.textures, + self.audio_tx.clone(), + )); // dbg!(ui.input(|input| input.pointer.latest_pos())); // dbg!(ui.input(|input| input.pointer.latest_pos())); // let (_, fp_rect) = ui.allocate_space((800.0, 333.0).into());