beamer_core/
parameter_info.rs

1//! Parameter metadata types.
2//!
3//! This module provides types for describing parameter metadata:
4//! - [`ParameterInfo`] - Complete parameter description (name, range, flags, etc.)
5//! - [`ParameterFlags`] - Behavioral flags (automation, bypass, list, etc.)
6
7use crate::parameter_groups::{GroupId, ROOT_GROUP_ID};
8use crate::types::{ParameterId, ParameterValue};
9
10/// Flags controlling parameter behavior.
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub struct ParameterFlags {
13    /// Parameter can be automated by the host.
14    pub can_automate: bool,
15    /// Parameter is read-only (display only).
16    pub is_readonly: bool,
17    /// Parameter is the bypass switch.
18    pub is_bypass: bool,
19    /// Parameter should be displayed as a dropdown list (for enums).
20    /// When true, host shows text labels from getParameterStringByValue().
21    pub is_list: bool,
22    /// Parameter is hidden from the DAW's parameter list.
23    /// Used for internal parameters like MIDI CC emulation.
24    pub is_hidden: bool,
25}
26
27impl Default for ParameterFlags {
28    fn default() -> Self {
29        Self {
30            can_automate: true,
31            is_readonly: false,
32            is_bypass: false,
33            is_list: false,
34            is_hidden: false,
35        }
36    }
37}
38
39/// Metadata describing a single parameter.
40#[derive(Debug, Clone)]
41pub struct ParameterInfo {
42    /// Unique parameter identifier.
43    pub id: ParameterId,
44    /// Full parameter name (e.g., "Master Volume").
45    pub name: &'static str,
46    /// Short parameter name for constrained UIs (e.g., "Vol").
47    pub short_name: &'static str,
48    /// Unit label (e.g., "dB", "%", "Hz").
49    pub units: &'static str,
50    /// Default value in normalized form (0.0 to 1.0).
51    pub default_normalized: ParameterValue,
52    /// Number of discrete steps. 0 = continuous, 1 = toggle, >1 = discrete.
53    pub step_count: i32,
54    /// Behavioral flags.
55    pub flags: ParameterFlags,
56    /// Parameter group ID. ROOT_GROUP_ID (0) for ungrouped parameters.
57    pub group_id: GroupId,
58}
59
60impl ParameterInfo {
61    /// Create a new continuous parameter with default flags.
62    pub const fn new(id: ParameterId, name: &'static str) -> Self {
63        Self {
64            id,
65            name,
66            short_name: name,
67            units: "",
68            default_normalized: 0.5,
69            step_count: 0,
70            flags: ParameterFlags {
71                can_automate: true,
72                is_readonly: false,
73                is_bypass: false,
74                is_list: false,
75                is_hidden: false,
76            },
77            group_id: ROOT_GROUP_ID,
78        }
79    }
80
81    /// Set the short name.
82    pub const fn with_short_name(mut self, short_name: &'static str) -> Self {
83        self.short_name = short_name;
84        self
85    }
86
87    /// Set the unit label.
88    pub const fn with_units(mut self, units: &'static str) -> Self {
89        self.units = units;
90        self
91    }
92
93    /// Set the default normalized value.
94    pub const fn with_default(mut self, default: ParameterValue) -> Self {
95        self.default_normalized = default;
96        self
97    }
98
99    /// Set the step count (0 = continuous).
100    pub const fn with_steps(mut self, steps: i32) -> Self {
101        self.step_count = steps;
102        self
103    }
104
105    /// Set parameter flags.
106    pub const fn with_flags(mut self, flags: ParameterFlags) -> Self {
107        self.flags = flags;
108        self
109    }
110
111    /// Create a bypass toggle parameter with standard configuration.
112    ///
113    /// This creates a parameter pre-configured as a bypass switch:
114    /// - Toggle (step_count = 1)
115    /// - Automatable
116    /// - Marked with `is_bypass = true` flag
117    /// - Default value = 0.0 (not bypassed)
118    ///
119    /// # Example
120    ///
121    /// ```ignore
122    /// const PARAM_BYPASS: u32 = 0;
123    ///
124    /// struct MyParameters {
125    ///     bypass: AtomicU64,
126    ///     bypass_info: ParameterInfo,
127    /// }
128    ///
129    /// impl MyParameters {
130    ///     fn new() -> Self {
131    ///         Self {
132    ///             bypass: AtomicU64::new(0.0f64.to_bits()),
133    ///             bypass_info: ParameterInfo::bypass(PARAM_BYPASS),
134    ///         }
135    ///     }
136    /// }
137    /// ```
138    pub const fn bypass(id: ParameterId) -> Self {
139        Self {
140            id,
141            name: "Bypass",
142            short_name: "Byp",
143            units: "",
144            default_normalized: 0.0,
145            step_count: 1,
146            flags: ParameterFlags {
147                can_automate: true,
148                is_readonly: false,
149                is_bypass: true,
150                is_list: false,
151                is_hidden: false,
152            },
153            group_id: ROOT_GROUP_ID,
154        }
155    }
156
157    /// Set the group ID (parameter group).
158    pub const fn with_group(mut self, group_id: GroupId) -> Self {
159        self.group_id = group_id;
160        self
161    }
162}