PC Music Generator - a Virtual Modular Synthesizer
at main 112 lines 2.4 kB view raw
1use egui::{ 2 InnerResponse, 3 Sense, 4 Ui, 5}; 6use emath::{ 7 Pos2, 8 Vec2, 9}; 10 11use crate::{ 12 module_description::{ 13 ToggleKind, 14 WidgetKind, 15 }, 16 visuals::{ 17 templates::WidgetTemplate, 18 VisualComponent, 19 VisualTheme, 20 }, 21}; 22 23use super::WidgetResponse; 24 25pub struct Toggle { 26 pub(crate) name: String, 27 pub(crate) pos: Pos2, 28 pub(crate) size: Vec2, 29 30 on: f32, 31 off: f32, 32 state: bool, 33 34 visuals: Vec<VisualComponent>, 35} 36 37impl Toggle { 38 pub fn new( 39 name: String, 40 pos: Pos2, 41 size: Vec2, 42 on: f32, 43 off: f32, 44 visuals: Vec<VisualComponent>, 45 ) -> Self { 46 Self { 47 name, 48 pos, 49 size, 50 on, 51 off, 52 state: false, 53 visuals, 54 } 55 } 56 57 pub fn value(&self) -> f32 { 58 if self.state { 59 self.on 60 } else { 61 self.off 62 } 63 } 64 65 pub fn show(&mut self, ui: &mut Ui, theme: VisualTheme) -> InnerResponse<WidgetResponse> { 66 let old_state = self.state; 67 let mut res = ui.allocate_response(self.size, Sense::click()); 68 69 if res.clicked() { 70 self.state = !self.state; 71 } 72 73 let rect = res.rect; 74 let center = rect.center(); 75 if ui.is_rect_visible(rect) { 76 for visual in &self.visuals { 77 let value = if self.state { 1. } else { 0. }; 78 visual.show_with_value(ui, center, theme, value); 79 } 80 } 81 82 let wr = if old_state == self.state { 83 res.changed = false; 84 WidgetResponse::None 85 } else { 86 res.changed = true; 87 WidgetResponse::Changed 88 }; 89 90 InnerResponse::new(wr, res) 91 } 92 93 pub(crate) fn from_template(template: WidgetTemplate) -> Option<Self> { 94 let WidgetTemplate { 95 kind: WidgetKind::Toggle(ToggleKind { on, off }), 96 uuid: _, 97 name, 98 position: pos, 99 size, 100 components: visuals, 101 } = template 102 else { 103 return None; 104 }; 105 106 let visuals = visuals 107 .into_values() 108 .filter_map(|v| v.try_into().ok()) 109 .collect(); 110 Some(Self::new(name, pos, size, on, off, visuals)) 111 } 112}