voicemeeter\interface/
macro_buttons.rs1use crate::{bindings::VBVMR_MACROBUTTON_MODE, types::LogicalButton};
11
12use super::VoicemeeterRemote;
13
14#[repr(transparent)]
16pub struct MacroButtonStatus(pub bool);
17
18impl std::ops::Deref for MacroButtonStatus {
19 type Target = bool;
20
21 fn deref(&self) -> &Self::Target {
22 &self.0
23 }
24}
25
26impl std::fmt::Display for MacroButtonStatus {
27 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28 if self.0 {
29 f.write_str("🟢")
30 } else {
31 f.write_str("🔴")
32 }
33 }
34}
35
36impl VoicemeeterRemote {
37 pub fn is_macrobutton_dirty(&self) -> Result<bool, IsMacroButtonDirtyError> {
46 let res = unsafe { self.raw.VBVMR_MacroButton_IsDirty() };
47 match res {
48 0 => Ok(false),
49 s if s > 0 => Ok(true),
50 -1 => Err(IsMacroButtonDirtyError::CannotGetClient),
51 -2 => Err(IsMacroButtonDirtyError::NoServer),
52 s => Err(IsMacroButtonDirtyError::Other(s)),
53 }
54 }
55
56 pub fn get_macrobutton_state(
58 &self,
59 button: impl Into<LogicalButton>,
60 ) -> Result<MacroButtonStatus, GetMacroButtonStatusError> {
61 let mut f = 0.0f32;
62 let button = button.into();
63 let res = unsafe { self.raw.VBVMR_MacroButton_GetStatus(button.0 .0, &mut f, 0) };
64 match res {
65 0 => Ok(MacroButtonStatus(f == 1.)),
66 -1 => Err(GetMacroButtonStatusError::CannotGetClient),
67 -2 => Err(GetMacroButtonStatusError::NoServer),
68 -3 => Err(GetMacroButtonStatusError::UnknownParameter(button)), -5 => Err(GetMacroButtonStatusError::StructureMismatch(button, 1)),
70 s => Err(GetMacroButtonStatusError::Other(s)),
71 }
72 }
73
74 pub fn set_macrobutton_state(
78 &self,
79 button: impl Into<LogicalButton>,
80 state: bool,
81 displayed_state_only: bool,
82 ) -> Result<(), SetMacroButtonStatusError> {
83 let _f = 0.0f32;
84 let button = button.into();
85 let bitmode = if displayed_state_only {
86 VBVMR_MACROBUTTON_MODE::STATEONLY
87 } else {
88 VBVMR_MACROBUTTON_MODE::DEFAULT
89 };
90 let res = unsafe {
91 self.raw
92 .VBVMR_MacroButton_SetStatus(button.0 .0, (state as u32) as f32, bitmode.0)
93 };
94 match res {
95 0 => Ok(()),
96 -1 => Err(SetMacroButtonStatusError::CannotGetClient),
97 -2 => Err(SetMacroButtonStatusError::NoServer),
98 -3 => Err(SetMacroButtonStatusError::UnknownParameter(button)), -5 => Err(SetMacroButtonStatusError::StructureMismatch(button, 1)),
100 s => Err(SetMacroButtonStatusError::Other(s)),
101 }
102 }
103
104 pub fn get_macrobutton_trigger_state(
106 &self,
107 button: impl Into<LogicalButton>,
108 ) -> Result<MacroButtonStatus, GetMacroButtonStatusError> {
109 let mut f = 0.0f32;
110 let button = button.into();
111 let res = unsafe { self.raw.VBVMR_MacroButton_GetStatus(button.0 .0, &mut f, 3) };
112 match res {
113 0 => Ok(MacroButtonStatus(f == 1.)),
114 -1 => Err(GetMacroButtonStatusError::CannotGetClient),
115 -2 => Err(GetMacroButtonStatusError::NoServer),
116 -3 => Err(GetMacroButtonStatusError::UnknownParameter(button)), -5 => Err(GetMacroButtonStatusError::StructureMismatch(button, 3)),
118 s => Err(GetMacroButtonStatusError::Other(s)),
119 }
120 }
121
122 pub fn set_macrobutton_trigger_state(
124 &self,
125 button: impl Into<LogicalButton>,
126 state: bool,
127 ) -> Result<(), SetMacroButtonStatusError> {
128 let button = button.into();
129 let res = unsafe {
130 self.raw
131 .VBVMR_MacroButton_SetStatus(button.0 .0, (state as u32) as f32, 3)
132 };
133 match res {
134 0 => Ok(()),
135 -1 => Err(SetMacroButtonStatusError::CannotGetClient),
136 -2 => Err(SetMacroButtonStatusError::NoServer),
137 -3 => Err(SetMacroButtonStatusError::UnknownParameter(button)), -5 => Err(SetMacroButtonStatusError::StructureMismatch(button, 3)),
139 s => Err(SetMacroButtonStatusError::Other(s)),
140 }
141 }
142}
143
144#[derive(Debug, thiserror::Error, Clone)]
146#[non_exhaustive]
147pub enum IsMacroButtonDirtyError {
148 #[error("cannot get client (unexpected)")]
151 CannotGetClient,
152 #[error("no server")]
154 NoServer,
155 #[error("unexpected error occurred: error code {0}")]
157 Other(i32),
158}
159
160#[derive(Debug, thiserror::Error, Clone)]
162#[non_exhaustive]
163pub enum GetMacroButtonStatusError {
164 #[error("cannot get client (unexpected)")]
167 CannotGetClient,
168 #[error("no server")]
170 NoServer,
171 #[error("unknown button: {}", 0.0)]
173 UnknownParameter(LogicalButton),
174 #[error("tried to parse parameter {0:?} as a {1} but it is not")]
176 StructureMismatch(LogicalButton, i32),
177 #[error("unexpected error occurred: error code {0}")]
179 Other(i32),
180}
181
182#[derive(Debug, thiserror::Error, Clone)]
184#[non_exhaustive]
185pub enum SetMacroButtonStatusError {
186 #[error("cannot get client (unexpected)")]
189 CannotGetClient,
190 #[error("no server")]
192 NoServer,
193 #[error("unknown button: {}", 0.0)]
195 UnknownParameter(LogicalButton),
196 #[error("tried to parse parameter {0:?} as a {1} but it is not")]
198 StructureMismatch(LogicalButton, i32),
199 #[error("unexpected error occurred: error code {0}")]
201 Other(i32),
202}