launchkey_sdk/launchkey/surface/
pads.rs

1use crate::bidirectional_enum_mappings_with_mode;
2use strum::IntoEnumIterator;
3use strum_macros::EnumIter;
4
5#[derive(Debug, Clone, Copy)]
6pub enum LEDMode {
7    Stationary,
8    Flashing,
9    Pulsing,
10}
11
12impl LEDMode {
13    pub(crate) fn to_midi_channel(self, pad_in_mode: PadInMode) -> u8 {
14        let base_channel = match self {
15            LEDMode::Stationary => 0x90, // Channel 1
16            LEDMode::Flashing => 0x91,   // Channel 2
17            LEDMode::Pulsing => 0x92,    // Channel 3
18        };
19        match pad_in_mode {
20            PadInMode::DAW(_) => base_channel, // DAW Pads always use default channels
21            PadInMode::Drum(_) => base_channel + 9, // Offset for Drum pads in DAW mode
22        }
23    }
24}
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumIter)]
27pub enum Pad {
28    PlugIn,
29    Mixer,
30    Sends,
31    Transport,
32    EncoderCustom1,
33    EncoderCustom2,
34    EncoderCustom3,
35    EncoderCustom4,
36    DAW,
37    Drum,
38    UserChord,
39    ChordMap,
40    PadCustom1,
41    PadCustom2,
42    PadCustom3,
43    PadCustom4,
44}
45
46bidirectional_enum_mappings_with_mode!(
47    Pad, u8, PadCCIndex,
48    {
49        DAW => {
50            PlugIn => 0x60,
51            Mixer => 0x61,
52            Sends => 0x62,
53            Transport => 0x63,
54            EncoderCustom1 => 0x64,
55            EncoderCustom2 => 0x65,
56            EncoderCustom3 => 0x66,
57            EncoderCustom4 => 0x67,
58            DAW => 0x70,
59            Drum => 0x71,
60            UserChord => 0x72,
61            ChordMap => 0x73,
62            PadCustom1 => 0x74,
63            PadCustom2 => 0x75,
64            PadCustom3 => 0x76,
65            PadCustom4 => 0x77
66        },
67        Drum => {
68            PlugIn => 0x28,
69            Mixer => 0x29,
70            Sends => 0x2A,
71            Transport => 0x2B,
72            EncoderCustom1 => 0x30,
73            EncoderCustom2 => 0x31,
74            EncoderCustom3 => 0x32,
75            EncoderCustom4 => 0x33,
76            DAW => 0x24,
77            Drum => 0x25,
78            UserChord => 0x26,
79            ChordMap => 0x27,
80            PadCustom1 => 0x2C,
81            PadCustom2 => 0x2D,
82            PadCustom3 => 0x2E,
83            PadCustom4 => 0x2F
84        }
85    }
86);
87
88impl Pad {
89    /// Get all possible variants of `Pad`.
90    pub fn all() -> impl Iterator<Item = Self> {
91        Self::iter()
92    }
93
94    /// Get the count of all variants.
95    pub fn count() -> usize {
96        Self::all().count()
97    }
98
99    /// Safely get a variant by its index.
100    pub fn from_index(index: usize) -> Option<Self> {
101        Self::all().nth(index)
102    }
103}
104
105/// This enum ensures a Pad is explicitly either from DAW mode or Drum mode.
106#[derive(Debug, Clone, Copy, PartialEq, Eq)]
107pub enum PadInMode {
108    DAW(Pad),
109    Drum(Pad),
110}
111
112impl PadInMode {
113    /// Get the correct MIDI index based on whether it's in DAW or Drum mode
114    pub fn to_index(self) -> u8 {
115        match self {
116            PadInMode::DAW(pad) => pad.to_value_mode(PadCCIndex::DAW),
117            PadInMode::Drum(pad) => pad.to_value_mode(PadCCIndex::Drum),
118        }
119    }
120}