A step sequencer for Adafruit's RP2040-based macropad
at main 113 lines 2.5 kB view raw
1use crate::menus::{EnumMenuItem, NumericMenuItem, Stringable}; 2 3#[derive(Clone, Copy, PartialEq)] 4pub enum Note { 5 A, 6 BFlat, 7 B, 8 C, 9 CSharp, 10 D, 11 EFlat, 12 E, 13 F, 14 FSharp, 15 G, 16 AFlat, 17} 18 19impl Stringable for Note { 20 fn as_str(&self) -> &str { 21 match self { 22 Note::A => "A", 23 Note::BFlat => "Bb", 24 Note::B => "B", 25 Note::C => "C", 26 Note::CSharp => "C#", 27 Note::D => "D", 28 Note::EFlat => "Eb", 29 Note::E => "E", 30 Note::F => "F", 31 Note::FSharp => "F#", 32 Note::G => "G", 33 Note::AFlat => "Ab", 34 } 35 } 36} 37 38#[derive(Clone, Copy)] 39pub struct StepMenuValue { 40 pub note: Note, 41 pub octave: u32, 42 pub velocity: u32, 43} 44 45impl Default for StepMenuValue { 46 fn default() -> Self { 47 Self { 48 note: Note::C, 49 octave: 1, 50 velocity: 100, 51 } 52 } 53} 54 55pub struct StepMenuItems<'a> { 56 pub note_menu: EnumMenuItem<'a, StepMenuValue, 12, Note>, 57 pub octave_menu: NumericMenuItem<'a, StepMenuValue>, 58 pub velocity_menu: NumericMenuItem<'a, StepMenuValue>, 59} 60 61impl<'a> StepMenuItems<'a> { 62 pub fn new() -> Self { 63 let defaults = StepMenuValue::default(); 64 65 let note_menu = EnumMenuItem::<'_, StepMenuValue, 12, Note>::new( 66 "NOTE", 67 [ 68 Note::A, 69 Note::BFlat, 70 Note::B, 71 Note::C, 72 Note::CSharp, 73 Note::D, 74 Note::EFlat, 75 Note::E, 76 Note::F, 77 Note::FSharp, 78 Note::G, 79 Note::AFlat, 80 ], 81 defaults.note, 82 &|menu_value, value| { 83 menu_value.note = value; 84 }, 85 ); 86 87 let octave_menu = NumericMenuItem::<StepMenuValue>::new( 88 "OCTAVE", 89 defaults.octave, 90 0, 91 9, 92 &|menu_value, value| { 93 menu_value.octave = value; 94 }, 95 ); 96 97 let velocity_menu = NumericMenuItem::<StepMenuValue>::new( 98 "VELOCITY", 99 defaults.velocity, 100 0, 101 128, 102 &|menu_value, value| { 103 menu_value.velocity = value; 104 }, 105 ); 106 107 Self { 108 note_menu, 109 octave_menu, 110 velocity_menu, 111 } 112 } 113}