A step sequencer for Adafruit's RP2040-based macropad
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}