Skip to main content

launchy/protocols/
mod.rs

1pub(crate) mod double_buffering;
2pub(crate) mod query;
3
4#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
5/// The button type used for Launchpads with 80 buttons
6pub enum Button80 {
7    ControlButton { index: u8 },
8    GridButton { x: u8, y: u8 },
9}
10
11impl Button80 {
12    pub const UP: Self = Button80::ControlButton { index: 0 };
13    pub const DOWN: Self = Button80::ControlButton { index: 1 };
14    pub const LEFT: Self = Button80::ControlButton { index: 2 };
15    pub const RIGHT: Self = Button80::ControlButton { index: 3 };
16    pub const SESSION: Self = Button80::ControlButton { index: 4 };
17
18    /**
19     * The 6th top-row button
20     *
21     * On the MK2 and the S, this button is called "User 1".
22     *
23     * On the MK3 Mini, this button is called "Drums".
24     */
25    pub const USER_1: Self = Button80::ControlButton { index: 5 };
26
27    /**
28     * The 7th top-row button
29     *
30     * On the MK2 and the S, this button is called "User 2".
31     *
32     * On the MK3 Mini, this button is called "Keys".
33     */
34    pub const USER_2: Self = Button80::ControlButton { index: 6 };
35
36    /**
37     * The 8th top-row button
38     *
39     * On the MK2 and the S, this button is called "Mixer".
40     *
41     * On the MK3 Mini, this button is called "User".
42     */
43    pub const MIXER: Self = Button80::ControlButton { index: 7 };
44    pub const VOLUME: Self = Button80::GridButton { x: 8, y: 0 };
45    pub const PAN: Self = Button80::GridButton { x: 8, y: 1 };
46    pub const SEND_A: Self = Button80::GridButton { x: 8, y: 2 };
47    pub const SEND_B: Self = Button80::GridButton { x: 8, y: 3 };
48    pub const STOP: Self = Button80::GridButton { x: 8, y: 4 };
49    pub const MUTE: Self = Button80::GridButton { x: 8, y: 5 };
50    pub const SOLO: Self = Button80::GridButton { x: 8, y: 6 };
51    pub const RECORD_ARM: Self = Button80::GridButton { x: 8, y: 7 };
52
53    /// Creates a new GridButton coordinate
54    pub fn grid(x: u8, y: u8) -> Button80 {
55        Button80::GridButton { x, y }
56    }
57
58    /// Creates a new ControlButton coordinate
59    pub fn control(index: u8) -> Button80 {
60        Button80::ControlButton { index }
61    }
62
63    /// Creates a new button out of absolute coordinates, like the ones returned by `abs_x()` and
64    /// `abs_y()`.
65    pub fn from_abs(x: u8, y: u8) -> Button80 {
66        match y {
67            0 => {
68                assert!(x <= 7);
69                Button80::ControlButton { index: x }
70            }
71            1..=8 => {
72                assert!(x <= 8);
73                Button80::GridButton { x, y: y - 1 }
74            }
75            other => panic!("Unexpected y: {}", other),
76        }
77    }
78
79    /// Returns x coordinate assuming coordinate origin in the leftmost control button
80    pub fn abs_x(&self) -> u8 {
81        match *self {
82            Self::ControlButton { index } => index,
83            Self::GridButton { x, .. } => x,
84        }
85    }
86
87    /// Returns y coordinate assuming coordinate origin in the leftmost control button
88    pub fn abs_y(&self) -> u8 {
89        match *self {
90            Self::ControlButton { .. } => 0,
91            Self::GridButton { y, .. } => y + 1,
92        }
93    }
94
95    /// Returns true if the button is part of the main 8x8 grid (absolute x: 0-7, absolute y: 1-8).
96    pub fn is_main_grid_button(&self) -> bool {
97        match self {
98            Self::GridButton { x, y } => *x <= 7 && *y <= 7, // Internal y is 0-7
99            _ => false,
100        }
101    }
102
103    /// Returns true if the button is part of the top-row control buttons (absolute x: 0-7, absolute
104    /// y: 0).
105    pub fn is_top_control_button(&self) -> bool {
106        match self {
107            Self::ControlButton { index } => *index <= 7,
108            _ => false,
109        }
110    }
111
112    /// Returns true if the button is part of the right-column scene launch buttons (absolute x: 8,
113    /// absolute y: 1-8).
114    pub fn is_scene_launch_button(&self) -> bool {
115        match self {
116            Self::GridButton { x, y } => *x == 8 && *y <= 7, // Internal y is 0-7
117            _ => false,
118        }
119    }
120}