konnektoren_bevy/settings/
builders.rs1use super::components::*;
2use bevy::prelude::*;
3
4#[derive(Resource, Default)]
6pub struct SettingsRegistry {
7 pub categories: Vec<SettingsCategory>,
8}
9
10#[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#[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 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 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 pub fn game_settings() -> Self {
131 Self::new()
132 .add_category(Self::audio_category())
133 .add_category(Self::graphics_category())
134 }
135}
136
137#[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 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
196pub trait SettingsExt {
198 fn spawn_audio_settings(&mut self) -> Vec<Entity>;
200
201 fn spawn_graphics_settings(&mut self) -> Vec<Entity>;
203
204 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}