diff --git a/src/envelope.rs b/src/envelope.rs new file mode 100644 index 0000000..e1d2456 --- /dev/null +++ b/src/envelope.rs @@ -0,0 +1,54 @@ +use std::ops::RangeInclusive; +use eframe::egui; +use eframe::egui::{Context, Id, Label, Slider, Window}; +use serde::{Deserialize, Serialize}; +use crate::gui::Showable; + +#[derive(Copy, Clone, PartialEq, Debug, Deserialize, Serialize)] +pub struct Envelope { + pub attack: f32, + pub decay: f32, + pub sustain: f32, + pub release: f32 +} + +impl Default for Envelope { + fn default() -> Self { + Self { + attack: 0.0, + decay: 0.0, + sustain: 1.0, + release: 0.0, + } + } +} + +impl Showable<(Id, String)> for (&mut Envelope, &mut bool) { + fn show(&mut self, ctx: &Context, (id, title): &(Id, String)) { + let mut open = true; + let window = Window::new(title) + .id(*id) + .open(&mut open) + .resizable([false, false]) + .scroll([false, false]); + + window.show(ctx, |ui| { + egui::Grid::new(id).show(ui, |ui| { + ui.add(Label::new("Attack")); + ui.add(Slider::new(&mut self.0.attack, RangeInclusive::new(0.0, 1.0))); + ui.end_row(); + ui.add(Label::new("Decay")); + ui.add(Slider::new(&mut self.0.decay, RangeInclusive::new(0.0, 1.0))); + ui.end_row(); + ui.add(Label::new("Sustain")); + ui.add(Slider::new(&mut self.0.sustain, RangeInclusive::new(0.0, 1.0))); + ui.end_row(); + ui.add(Label::new("Release")); + ui.add(Slider::new(&mut self.0.release, RangeInclusive::new(0.0, 1.0))); + ui.end_row(); + }); + }); + + *self.1 = open; + } +} \ No newline at end of file diff --git a/src/grid.rs b/src/grid.rs index a80adf5..9dd3339 100644 --- a/src/grid.rs +++ b/src/grid.rs @@ -1,6 +1,7 @@ use std::ops::RangeInclusive; use eframe::egui; use eframe::egui::{Color32, Context, Id, PointerButton, Pos2, Rangef, Sense, Ui, Vec2}; +use crate::envelope::Envelope; use crate::gui::Showable; use crate::noise::NoteType; use crate::scale::Scale; @@ -37,7 +38,9 @@ pub struct Grid { pub notes: Vec, pub id: Id, pub name: String, - pub open: bool + pub open: bool, + pub envelope: Envelope, + pub envelope_open: bool } impl Grid { @@ -50,6 +53,8 @@ impl Grid { scale: Scale::CMajor, notes: vec![false; (LOOP_LENGTH * LOOP_LENGTH) as usize], name: format!("{} Track", note_type.name()), + envelope: Envelope::default(), + envelope_open: false, id } } @@ -129,8 +134,11 @@ impl Showable for Grid { if ui.button(Scale::Pentatonic.label_text(self.scale)).clicked() { self.scale = Scale::Pentatonic } + }); - }) + if ui.button("Envelope...").clicked() { + self.envelope_open = !self.envelope_open; + } }); egui::MenuBar::new().ui(ui, |ui| { @@ -147,6 +155,13 @@ impl Showable for Grid { }); }); + if self.envelope_open { + let mut eopen = true; + let (id, title) = (format!("{} envelope", self.id.value()).into(), format!("{} Envelope", self.name)); + (&mut self.envelope, &mut eopen).show(ctx, &(id, title)); + self.envelope_open = eopen; + } + self.open = open; } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 479d6c2..489b19d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ mod noise; mod scale; mod saveload; mod dialog; +mod envelope; use std::time::Duration; use eframe::{App, Frame}; diff --git a/src/saveload.rs b/src/saveload.rs index ca03d7a..28f5462 100644 --- a/src/saveload.rs +++ b/src/saveload.rs @@ -1,5 +1,6 @@ use eframe::egui::Id; use serde::{Deserialize, Serialize}; +use crate::envelope::Envelope; use crate::grid::Grid; use crate::noise::NoteType; use crate::scale::Scale; @@ -36,7 +37,8 @@ struct PersistedGrid { length: u64, scale: Scale, notes: String, - name: String + name: String, + envelope: Envelope, } impl From<&Grid> for PersistedGrid { @@ -48,6 +50,7 @@ impl From<&Grid> for PersistedGrid { length: value.length, scale: value.scale, name: value.name.clone(), + envelope: value.envelope, notes } } @@ -62,7 +65,9 @@ impl PersistedGrid { length: self.length, scale: self.scale, name: self.name, + envelope: self.envelope, open: true, + envelope_open: false, notes, id }