Skip to main content

gled_model/asset/midi_controller/
output.rs

1//! What a controller is sent back: values that follow gled's state, and
2//! scene colors through a mapping to the controller's own color messages.
3
4use super::MidiSceneTarget;
5use serde::{Deserialize, Serialize};
6use strum::{Display, EnumDiscriminants, EnumIter};
7
8use crate::asset::scene::color::SceneInstanceColor;
9
10#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
11pub struct MidiOutputBinding {
12    pub name: String,
13    pub kind: MidiOutputBindingKind,
14}
15
16impl Default for MidiOutputBinding {
17    fn default() -> Self {
18        Self {
19            name: "Output".to_owned(),
20            kind: MidiOutputBindingKind::Value(MidiValueOutput::default()),
21        }
22    }
23}
24
25/// `MidiOutputBindingSelector` is the kind without its settings; it reads as
26/// the label the controller window shows.
27#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, EnumDiscriminants)]
28#[strum_discriminants(name(MidiOutputBindingSelector), derive(Display, EnumIter))]
29pub enum MidiOutputBindingKind {
30    #[strum_discriminants(strum(serialize = "Single Value"))]
31    Value(MidiValueOutput),
32    #[strum_discriminants(strum(serialize = "Scene Color Mapping"))]
33    SceneColorValue(MidiSceneColorValueOutput),
34}
35
36impl Default for MidiOutputBindingKind {
37    fn default() -> Self {
38        Self::Value(MidiValueOutput::default())
39    }
40}
41
42#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
43pub struct MidiValueOutput {
44    pub status: u8,
45    pub data1: u8,
46    pub min: u8,
47    pub max: u8,
48    pub active_value: u8,
49    pub source: MidiValueSource,
50}
51
52impl Default for MidiValueOutput {
53    fn default() -> Self {
54        Self {
55            status: 176,
56            data1: 0,
57            min: 0,
58            max: 127,
59            active_value: 127,
60            source: MidiValueSource::SelectedSceneOpacity,
61        }
62    }
63}
64
65/// `MidiValueSourceKind` is the source without its settings; it reads as
66/// the label the controller window shows.
67#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default, EnumDiscriminants)]
68#[strum_discriminants(
69    name(MidiValueSourceKind),
70    derive(Display, EnumIter),
71    strum(serialize_all = "title_case")
72)]
73pub enum MidiValueSource {
74    #[default]
75    SelectedSceneOpacity,
76    #[strum_discriminants(strum(serialize = "Selected Scene (Distributed 0-127)"))]
77    SelectedSceneDistributed,
78    SelectedSceneInputDimmer,
79    SelectedSceneBeatOffset,
80    SelectedSceneIgnoreMainDimmer,
81    SelectedSceneSetOffsetOnFlash,
82    MainDimmer,
83    #[strum_discriminants(strum(serialize = "Beat Flank"))]
84    BeatFlankPulse {
85        start_beat: f32,
86        end_beat: f32,
87        blackout_blink_value: Option<u8>,
88    },
89    Blackout {
90        inverted: bool,
91        blink: bool,
92    },
93    SceneOpacity {
94        target: MidiSceneTarget,
95    },
96    SceneInputDimmer {
97        target: MidiSceneTarget,
98    },
99    SceneBeatOffset {
100        target: MidiSceneTarget,
101    },
102    SceneIgnoreMainDimmer {
103        target: MidiSceneTarget,
104    },
105    SceneSetOffsetOnFlash {
106        target: MidiSceneTarget,
107    },
108    SceneActive {
109        target: MidiSceneTarget,
110    },
111    SceneFlashed {
112        target: MidiSceneTarget,
113    },
114    #[strum_discriminants(strum(serialize = "Scene Effect Setting (n,n) f32"))]
115    SceneEffectSettingF32 {
116        target: MidiSceneTarget,
117        effect_index: u8,
118        setting_index: u8,
119    },
120    #[strum_discriminants(strum(serialize = "Effect Opacity"))]
121    SceneEffectOpacity {
122        target: MidiSceneTarget,
123        effect_index: u8,
124    },
125    #[strum_discriminants(strum(serialize = "Effect Color Shift"))]
126    SceneEffectColorShift {
127        target: MidiSceneTarget,
128        effect_index: u8,
129    },
130    #[strum_discriminants(strum(serialize = "Effect Beat Progression"))]
131    SceneEffectBeatProgression {
132        target: MidiSceneTarget,
133        effect_index: u8,
134    },
135    #[strum_discriminants(strum(serialize = "Effect Beat Offset"))]
136    SceneEffectBeatOffset {
137        target: MidiSceneTarget,
138        effect_index: u8,
139    },
140    #[strum_discriminants(strum(serialize = "Effect Speed Exponent"))]
141    SceneEffectSpeedExponent {
142        target: MidiSceneTarget,
143        effect_index: u8,
144    },
145    /// The effect's layout, encoded as `SetSceneEffectLayout` takes it: 0
146    /// inherits the tile's layout, 1 is the topology, 2… the layouts in stack
147    /// order. Was the effect's group index before the patch.
148    #[serde(alias = "SceneEffectGroupIndex")]
149    #[strum_discriminants(strum(serialize = "Effect Layout"))]
150    SceneEffectLayout {
151        target: MidiSceneTarget,
152        effect_index: u8,
153    },
154}
155
156impl Eq for MidiValueSource {}
157
158#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Display)]
159pub enum MidiColorSource {
160    #[strum(serialize = "Scene Color")]
161    SceneColor { target: MidiSceneTarget },
162}
163
164impl Default for MidiColorSource {
165    fn default() -> Self {
166        Self::SceneColor {
167            target: MidiSceneTarget::Selected,
168        }
169    }
170}
171
172#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
173pub struct MidiSceneColorValueOutput {
174    pub source: MidiColorSource,
175    pub mapping_name: String,
176    pub status: u8,
177    pub data1: u8,
178}
179
180impl Default for MidiSceneColorValueOutput {
181    fn default() -> Self {
182        Self {
183            source: MidiColorSource::default(),
184            mapping_name: String::new(),
185            status: 144,
186            data1: 0,
187        }
188    }
189}
190
191#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
192pub struct MidiNamedSceneColorMapping {
193    pub name: String,
194    pub active: MidiSceneColorMessageMap,
195    pub inactive: MidiSceneColorMessageMap,
196    pub flashed: MidiSceneColorMessageMap,
197}
198
199impl Default for MidiNamedSceneColorMapping {
200    fn default() -> Self {
201        let default_map = MidiSceneColorMessageMap::default();
202        Self {
203            name: "Color Mapping".to_owned(),
204            active: default_map.clone(),
205            inactive: default_map.clone(),
206            flashed: default_map,
207        }
208    }
209}
210
211#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Default)]
212pub struct MidiSceneColorMessage {
213    pub value: u8,
214}
215
216#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
217pub struct MidiSceneColorMessageMap {
218    pub red: MidiSceneColorMessage,
219    pub green: MidiSceneColorMessage,
220    pub blue: MidiSceneColorMessage,
221    pub white: MidiSceneColorMessage,
222    pub orange: MidiSceneColorMessage,
223    pub yellow: MidiSceneColorMessage,
224    pub purple: MidiSceneColorMessage,
225    pub pink: MidiSceneColorMessage,
226    pub black: MidiSceneColorMessage,
227}
228
229impl Default for MidiSceneColorMessageMap {
230    fn default() -> Self {
231        Self {
232            red: MidiSceneColorMessage { value: 5 },
233            green: MidiSceneColorMessage { value: 21 },
234            blue: MidiSceneColorMessage { value: 45 },
235            white: MidiSceneColorMessage { value: 3 },
236            orange: MidiSceneColorMessage { value: 9 },
237            yellow: MidiSceneColorMessage { value: 13 },
238            purple: MidiSceneColorMessage { value: 49 },
239            pink: MidiSceneColorMessage { value: 53 },
240            black: MidiSceneColorMessage { value: 0 },
241        }
242    }
243}
244
245impl MidiSceneColorMessageMap {
246    pub fn message_for_color(&self, color: SceneInstanceColor) -> &MidiSceneColorMessage {
247        match color {
248            SceneInstanceColor::Red => &self.red,
249            SceneInstanceColor::Green => &self.green,
250            SceneInstanceColor::Blue => &self.blue,
251            SceneInstanceColor::White => &self.white,
252            SceneInstanceColor::Orange => &self.orange,
253            SceneInstanceColor::Yellow => &self.yellow,
254            SceneInstanceColor::Purple => &self.purple,
255            SceneInstanceColor::Pink => &self.pink,
256            SceneInstanceColor::Black => &self.black,
257        }
258    }
259}