konnektoren_bevy/settings/
builders.rs

1use super::components::*;
2use bevy::prelude::*;
3
4/// Resource that provides default settings configurations
5#[derive(Resource, Default)]
6pub struct SettingsRegistry {
7    pub categories: Vec<SettingsCategory>,
8}
9
10/// A category of settings
11#[derive(Debug, Clone)]
12pub struct SettingsCategory {
13    pub name: String,
14    pub display_name: String,
15    pub description: Option<String>,
16    pub settings: Vec<SettingDefinition>,
17}
18
19/// Definition for creating a setting
20#[derive(Debug, Clone)]
21pub struct SettingDefinition {
22    pub id: String,
23    pub label: String,
24    pub description: Option<String>,
25    pub default_value: SettingValue,
26    pub setting_type: SettingType,
27    pub tab_index: Option<usize>,
28}
29
30impl SettingsRegistry {
31    pub fn new() -> Self {
32        Self::default()
33    }
34
35    pub fn add_category(mut self, category: SettingsCategory) -> Self {
36        self.categories.push(category);
37        self
38    }
39
40    /// Create default audio settings category
41    pub fn audio_category() -> SettingsCategory {
42        SettingsCategory {
43            name: "audio".to_string(),
44            display_name: "Audio".to_string(),
45            description: Some("Audio and sound settings".to_string()),
46            settings: vec![
47                SettingDefinition {
48                    id: "master_volume".to_string(),
49                    label: "Master Volume".to_string(),
50                    description: Some("Overall audio volume".to_string()),
51                    default_value: SettingValue::Float(1.0),
52                    setting_type: SettingType::FloatRange {
53                        min: 0.0,
54                        max: 1.0,
55                        step: 0.1,
56                    },
57                    tab_index: Some(0),
58                },
59                SettingDefinition {
60                    id: "music_volume".to_string(),
61                    label: "Music Volume".to_string(),
62                    description: Some("Background music volume".to_string()),
63                    default_value: SettingValue::Float(0.8),
64                    setting_type: SettingType::FloatRange {
65                        min: 0.0,
66                        max: 1.0,
67                        step: 0.1,
68                    },
69                    tab_index: Some(1),
70                },
71                SettingDefinition {
72                    id: "sfx_volume".to_string(),
73                    label: "Sound Effects".to_string(),
74                    description: Some("Sound effects volume".to_string()),
75                    default_value: SettingValue::Float(1.0),
76                    setting_type: SettingType::FloatRange {
77                        min: 0.0,
78                        max: 1.0,
79                        step: 0.1,
80                    },
81                    tab_index: Some(2),
82                },
83                SettingDefinition {
84                    id: "audio_enabled".to_string(),
85                    label: "Enable Audio".to_string(),
86                    description: Some("Enable or disable all audio".to_string()),
87                    default_value: SettingValue::Bool(true),
88                    setting_type: SettingType::Toggle,
89                    tab_index: Some(3),
90                },
91            ],
92        }
93    }
94
95    /// Create default graphics settings category
96    pub fn graphics_category() -> SettingsCategory {
97        SettingsCategory {
98            name: "graphics".to_string(),
99            display_name: "Graphics".to_string(),
100            description: Some("Visual and display settings".to_string()),
101            settings: vec![
102                SettingDefinition {
103                    id: "vsync".to_string(),
104                    label: "V-Sync".to_string(),
105                    description: Some("Vertical synchronization".to_string()),
106                    default_value: SettingValue::Bool(true),
107                    setting_type: SettingType::Toggle,
108                    tab_index: Some(0),
109                },
110                SettingDefinition {
111                    id: "resolution".to_string(),
112                    label: "Resolution".to_string(),
113                    description: Some("Screen resolution".to_string()),
114                    default_value: SettingValue::Selection(0),
115                    setting_type: SettingType::Selection {
116                        options: vec![
117                            "1920x1080".to_string(),
118                            "1680x1050".to_string(),
119                            "1440x900".to_string(),
120                            "1280x720".to_string(),
121                        ],
122                    },
123                    tab_index: Some(1),
124                },
125            ],
126        }
127    }
128
129    /// Create a complete game settings registry
130    pub fn game_settings() -> Self {
131        Self::new()
132            .add_category(Self::audio_category())
133            .add_category(Self::graphics_category())
134    }
135}
136
137/// Builder for creating settings entities
138#[derive(Default)]
139pub struct SettingsBuilder {
140    pub categories: Vec<SettingsCategory>,
141}
142
143impl SettingsBuilder {
144    pub fn new() -> Self {
145        Self::default()
146    }
147
148    pub fn add_category(mut self, category: SettingsCategory) -> Self {
149        self.categories.push(category);
150        self
151    }
152
153    pub fn with_audio_settings(self) -> Self {
154        self.add_category(SettingsRegistry::audio_category())
155    }
156
157    pub fn with_graphics_settings(self) -> Self {
158        self.add_category(SettingsRegistry::graphics_category())
159    }
160
161    /// Spawn setting entities from this builder
162    pub fn spawn_settings(self, commands: &mut Commands) -> Vec<Entity> {
163        let mut entities = Vec::new();
164
165        for category in &self.categories {
166            for setting_def in &category.settings {
167                let setting = Setting::new(
168                    setting_def.id.clone(),
169                    setting_def.label.clone(),
170                    setting_def.default_value.clone(),
171                    setting_def.setting_type.clone(),
172                )
173                .with_category(category.name.clone());
174
175                let entity = if let Some(tab_index) = setting_def.tab_index {
176                    commands
177                        .spawn((
178                            Name::new(format!("Setting: {}", setting_def.id)),
179                            setting.with_tab_index(tab_index),
180                        ))
181                        .id()
182                } else {
183                    commands
184                        .spawn((Name::new(format!("Setting: {}", setting_def.id)), setting))
185                        .id()
186                };
187
188                entities.push(entity);
189            }
190        }
191
192        entities
193    }
194}
195
196/// Helper trait for easy settings creation
197pub trait SettingsExt {
198    /// Spawn basic audio settings
199    fn spawn_audio_settings(&mut self) -> Vec<Entity>;
200
201    /// Spawn basic graphics settings
202    fn spawn_graphics_settings(&mut self) -> Vec<Entity>;
203
204    /// Spawn complete game settings
205    fn spawn_game_settings(&mut self) -> Vec<Entity>;
206}
207
208impl SettingsExt for Commands<'_, '_> {
209    fn spawn_audio_settings(&mut self) -> Vec<Entity> {
210        SettingsBuilder::new()
211            .with_audio_settings()
212            .spawn_settings(self)
213    }
214
215    fn spawn_graphics_settings(&mut self) -> Vec<Entity> {
216        SettingsBuilder::new()
217            .with_graphics_settings()
218            .spawn_settings(self)
219    }
220
221    fn spawn_game_settings(&mut self) -> Vec<Entity> {
222        SettingsBuilder::new()
223            .with_audio_settings()
224            .with_graphics_settings()
225            .spawn_settings(self)
226    }
227}