veloren_voxygen/hud/settings_window/
sound.rs

1use super::{RESET_BUTTONS_HEIGHT, RESET_BUTTONS_WIDTH};
2
3use crate::{
4    GlobalState,
5    audio::SfxChannelSettings,
6    hud::{MENU_BG, TEXT_COLOR, TEXT_COLOR_GREY, img_ids::Imgs},
7    session::settings_change::Audio::{self as AudioChange, *},
8    ui::{ImageSlider, ToggleButton, fonts::Fonts},
9};
10use conrod_core::{
11    Colorable, Labelable, Positionable, Sizeable, Widget, WidgetCommon, color,
12    position::{Align, Relative},
13    widget::{self, Button, DropDownList, Rectangle, Scrollbar, Text},
14    widget_ids,
15};
16use i18n::Localization;
17
18widget_ids! {
19    struct Ids {
20        window,
21        window_r,
22        window_scrollbar,
23        master_volume_text,
24        master_volume_slider,
25        master_volume_number,
26        master_volume_muted,
27        inactive_master_volume_text,
28        inactive_master_volume_slider,
29        inactive_master_volume_number,
30        inactive_master_volume_muted,
31        music_volume_text,
32        music_volume_slider,
33        music_volume_number,
34        music_volume_muted,
35        sfx_volume_text,
36        sfx_volume_slider,
37        sfx_volume_number,
38        sfx_volume_muted,
39        ambience_volume_text,
40        ambience_volume_slider,
41        ambience_volume_number,
42        ambience_volume_muted,
43        music_spacing_text,
44        music_spacing_slider,
45        music_spacing_number,
46        reset_sound_button,
47        combat_music_toggle_label,
48        combat_music_toggle_button,
49        sfx_channels_label,
50        sfx_channels_list,
51        // audio_device_list,
52        // audio_device_text,
53    }
54}
55
56#[derive(WidgetCommon)]
57pub struct Sound<'a> {
58    global_state: &'a GlobalState,
59    imgs: &'a Imgs,
60    fonts: &'a Fonts,
61    localized_strings: &'a Localization,
62    #[conrod(common_builder)]
63    common: widget::CommonBuilder,
64}
65impl<'a> Sound<'a> {
66    pub fn new(
67        global_state: &'a GlobalState,
68        imgs: &'a Imgs,
69        fonts: &'a Fonts,
70        localized_strings: &'a Localization,
71    ) -> Self {
72        Self {
73            global_state,
74            imgs,
75            fonts,
76            localized_strings,
77            common: widget::CommonBuilder::default(),
78        }
79    }
80}
81
82pub struct State {
83    ids: Ids,
84}
85
86impl Widget for Sound<'_> {
87    type Event = Vec<AudioChange>;
88    type State = State;
89    type Style = ();
90
91    fn init_state(&self, id_gen: widget::id::Generator) -> Self::State {
92        State {
93            ids: Ids::new(id_gen),
94        }
95    }
96
97    fn style(&self) -> Self::Style {}
98
99    fn update(self, args: widget::UpdateArgs<Self>) -> Self::Event {
100        common_base::prof_span!("Sound::update");
101        let widget::UpdateArgs { state, ui, .. } = args;
102
103        let mut events = Vec::new();
104
105        Rectangle::fill_with(args.rect.dim(), color::TRANSPARENT)
106            .xy(args.rect.xy())
107            .graphics_for(args.id)
108            .scroll_kids()
109            .scroll_kids_vertically()
110            .set(state.ids.window, ui);
111        Rectangle::fill_with([args.rect.w() / 2.0, args.rect.h()], color::TRANSPARENT)
112            .top_right()
113            .parent(state.ids.window)
114            .set(state.ids.window_r, ui);
115        Scrollbar::y_axis(state.ids.window)
116            .thickness(5.0)
117            .rgba(0.33, 0.33, 0.33, 1.0)
118            .set(state.ids.window_scrollbar, ui);
119
120        let non_master_volume_text_color =
121            match self.global_state.settings.audio.master_volume.muted {
122                true => TEXT_COLOR_GREY,
123                false => TEXT_COLOR,
124            };
125
126        // Master Volume
127        Text::new(&self.localized_strings.get_msg("hud-settings-master_volume"))
128            .top_left_with_margins_on(state.ids.window, 10.0, 10.0)
129            .font_size(self.fonts.cyri.scale(14))
130            .font_id(self.fonts.cyri.conrod_id)
131            .color(TEXT_COLOR)
132            .set(state.ids.master_volume_text, ui);
133        // Master Volume Muted Indicator
134        let master_muted = ToggleButton::new(
135            self.global_state.settings.audio.master_volume.muted,
136            self.imgs.button_mute,
137            self.imgs.button_muted,
138        )
139        .w_h(24.0, 25.0)
140        .down_from(state.ids.master_volume_text, 10.0)
141        .hover_images(self.imgs.button_mute_hover, self.imgs.button_muted_hover)
142        .press_images(self.imgs.button_mute_press, self.imgs.button_muted_press)
143        .set(state.ids.master_volume_muted, ui);
144        if master_muted != self.global_state.settings.audio.master_volume.muted {
145            events.push(MuteMasterVolume(master_muted));
146        }
147        // Master Volume Slider
148        if let Some(new_val) = ImageSlider::continuous(
149            self.global_state.settings.audio.master_volume.volume,
150            0.0,
151            1.0,
152            self.imgs.slider_indicator,
153            self.imgs.slider,
154        )
155        .w_h(104.0, 22.0)
156        .right_from(state.ids.master_volume_muted, 8.0)
157        .track_breadth(12.0)
158        .slider_length(10.0)
159        .pad_track((5.0, 5.0))
160        .set(state.ids.master_volume_slider, ui)
161        {
162            events.push(AdjustMasterVolume(new_val));
163        }
164        // Master Volume Number
165        Text::new(&format!(
166            "{:2.0}%",
167            self.global_state.settings.audio.master_volume.volume * 100.0
168        ))
169        .right_from(state.ids.master_volume_slider, 8.0)
170        .font_size(self.fonts.cyri.scale(14))
171        .font_id(self.fonts.cyri.conrod_id)
172        .color(TEXT_COLOR)
173        .set(state.ids.master_volume_number, ui);
174
175        // Master Volume (inactive window)
176        Text::new(
177            &self
178                .localized_strings
179                .get_msg("hud-settings-inactive_master_volume_perc"),
180        )
181        .down_from(state.ids.master_volume_muted, 10.0)
182        .font_size(self.fonts.cyri.scale(14))
183        .font_id(self.fonts.cyri.conrod_id)
184        .color(TEXT_COLOR)
185        .set(state.ids.inactive_master_volume_text, ui);
186        // Master Volume (inactive window) Muted Indicator
187        let inactive_master_muted = ToggleButton::new(
188            self.global_state
189                .settings
190                .audio
191                .inactive_master_volume_perc
192                .muted,
193            self.imgs.button_mute,
194            self.imgs.button_muted,
195        )
196        .w_h(24.0, 25.0)
197        .down_from(state.ids.inactive_master_volume_text, 10.0)
198        .hover_images(self.imgs.button_mute_hover, self.imgs.button_muted_hover)
199        .press_images(self.imgs.button_mute_press, self.imgs.button_muted_press)
200        .set(state.ids.inactive_master_volume_muted, ui);
201        if inactive_master_muted
202            != self
203                .global_state
204                .settings
205                .audio
206                .inactive_master_volume_perc
207                .muted
208        {
209            events.push(MuteInactiveMasterVolume(inactive_master_muted));
210        }
211        // Master Volume (inactive window) Slider
212        if let Some(new_val) = ImageSlider::continuous(
213            self.global_state
214                .settings
215                .audio
216                .inactive_master_volume_perc
217                .volume,
218            0.0,
219            1.0,
220            self.imgs.slider_indicator,
221            self.imgs.slider,
222        )
223        .w_h(104.0, 22.0)
224        .right_from(state.ids.inactive_master_volume_muted, 8.0)
225        .track_breadth(12.0)
226        .slider_length(10.0)
227        .pad_track((5.0, 5.0))
228        .set(state.ids.inactive_master_volume_slider, ui)
229        {
230            events.push(AdjustInactiveMasterVolume(new_val));
231        }
232        // Master Volume (inactive window) Number
233        Text::new(&format!(
234            "{:2.0}%",
235            self.global_state
236                .settings
237                .audio
238                .inactive_master_volume_perc
239                .volume
240                * 100.0
241        ))
242        .right_from(state.ids.inactive_master_volume_slider, 8.0)
243        .font_size(self.fonts.cyri.scale(14))
244        .font_id(self.fonts.cyri.conrod_id)
245        .color(non_master_volume_text_color)
246        .set(state.ids.inactive_master_volume_number, ui);
247
248        // Music Volume
249        Text::new(&self.localized_strings.get_msg("hud-settings-music_volume"))
250            .down_from(state.ids.inactive_master_volume_muted, 10.0)
251            .font_size(self.fonts.cyri.scale(14))
252            .font_id(self.fonts.cyri.conrod_id)
253            .color(TEXT_COLOR)
254            .set(state.ids.music_volume_text, ui);
255        // Music Muted Indicator
256        let music_muted = ToggleButton::new(
257            self.global_state.settings.audio.music_volume.muted,
258            self.imgs.button_mute,
259            self.imgs.button_muted,
260        )
261        .w_h(24.0, 25.0)
262        .down_from(state.ids.music_volume_text, 10.0)
263        .hover_images(self.imgs.button_mute_hover, self.imgs.button_muted_hover)
264        .press_images(self.imgs.button_mute_press, self.imgs.button_muted_press)
265        .set(state.ids.music_volume_muted, ui);
266        if music_muted != self.global_state.settings.audio.music_volume.muted {
267            events.push(MuteMusicVolume(music_muted));
268        }
269        // Music Volume Slider
270        if let Some(new_val) = ImageSlider::continuous(
271            self.global_state.settings.audio.music_volume.volume,
272            0.0,
273            1.0,
274            self.imgs.slider_indicator,
275            self.imgs.slider,
276        )
277        .w_h(104.0, 22.0)
278        .right_from(state.ids.music_volume_muted, 8.0)
279        .track_breadth(12.0)
280        .slider_length(10.0)
281        .pad_track((5.0, 5.0))
282        .set(state.ids.music_volume_slider, ui)
283        {
284            events.push(AdjustMusicVolume(new_val));
285        }
286        // Music Volume Number
287        Text::new(&format!(
288            "{:2.0}%",
289            self.global_state.settings.audio.music_volume.volume * 100.0
290        ))
291        .right_from(state.ids.music_volume_slider, 8.0)
292        .font_size(self.fonts.cyri.scale(14))
293        .font_id(self.fonts.cyri.conrod_id)
294        .color(non_master_volume_text_color)
295        .set(state.ids.music_volume_number, ui);
296
297        // SFX Volume
298        Text::new(
299            &self
300                .localized_strings
301                .get_msg("hud-settings-sound_effect_volume"),
302        )
303        .down_from(state.ids.music_volume_muted, 10.0)
304        .font_size(self.fonts.cyri.scale(14))
305        .font_id(self.fonts.cyri.conrod_id)
306        .color(TEXT_COLOR)
307        .set(state.ids.sfx_volume_text, ui);
308        // SFX Volume Muted Indicator
309        let sfx_muted = ToggleButton::new(
310            self.global_state.settings.audio.sfx_volume.muted,
311            self.imgs.button_mute,
312            self.imgs.button_muted,
313        )
314        .w_h(24.0, 25.0)
315        .down_from(state.ids.sfx_volume_text, 10.0)
316        .hover_images(self.imgs.button_mute_hover, self.imgs.button_muted_hover)
317        .press_images(self.imgs.button_mute_press, self.imgs.button_muted_press)
318        .set(state.ids.sfx_volume_muted, ui);
319        if sfx_muted != self.global_state.settings.audio.sfx_volume.muted {
320            events.push(MuteSfxVolume(sfx_muted));
321        }
322        // SFX Volume Slider
323        if let Some(new_val) = ImageSlider::continuous(
324            self.global_state.settings.audio.sfx_volume.volume,
325            0.0,
326            1.0,
327            self.imgs.slider_indicator,
328            self.imgs.slider,
329        )
330        .w_h(104.0, 22.0)
331        .right_from(state.ids.sfx_volume_muted, 8.0)
332        .track_breadth(12.0)
333        .slider_length(10.0)
334        .pad_track((5.0, 5.0))
335        .set(state.ids.sfx_volume_slider, ui)
336        {
337            events.push(AdjustSfxVolume(new_val));
338        }
339        // SFX Volume Number
340        Text::new(&format!(
341            "{:2.0}%",
342            self.global_state.settings.audio.sfx_volume.volume * 100.0
343        ))
344        .right_from(state.ids.sfx_volume_slider, 8.0)
345        .font_size(self.fonts.cyri.scale(14))
346        .font_id(self.fonts.cyri.conrod_id)
347        .color(non_master_volume_text_color)
348        .set(state.ids.sfx_volume_number, ui);
349
350        // Ambience Volume
351        Text::new(
352            &self
353                .localized_strings
354                .get_msg("hud-settings-ambience_volume"),
355        )
356        .down_from(state.ids.sfx_volume_muted, 10.0)
357        .font_size(self.fonts.cyri.scale(14))
358        .font_id(self.fonts.cyri.conrod_id)
359        .color(TEXT_COLOR)
360        .set(state.ids.ambience_volume_text, ui);
361        // Ambience Volume Muted Indicator
362        let ambience_muted = ToggleButton::new(
363            self.global_state.settings.audio.ambience_volume.muted,
364            self.imgs.button_mute,
365            self.imgs.button_muted,
366        )
367        .w_h(24.0, 25.0)
368        .down_from(state.ids.ambience_volume_text, 10.0)
369        .hover_images(self.imgs.button_mute_hover, self.imgs.button_muted_hover)
370        .press_images(self.imgs.button_mute_press, self.imgs.button_muted_press)
371        .set(state.ids.ambience_volume_muted, ui);
372        if ambience_muted != self.global_state.settings.audio.ambience_volume.muted {
373            events.push(MuteAmbienceVolume(ambience_muted));
374        }
375        // Ambience Volume Slider
376        if let Some(new_val) = ImageSlider::continuous(
377            self.global_state.settings.audio.ambience_volume.volume,
378            0.0,
379            1.0,
380            self.imgs.slider_indicator,
381            self.imgs.slider,
382        )
383        .w_h(104.0, 22.0)
384        .right_from(state.ids.ambience_volume_muted, 8.0)
385        .track_breadth(12.0)
386        .slider_length(10.0)
387        .pad_track((5.0, 5.0))
388        .set(state.ids.ambience_volume_slider, ui)
389        {
390            events.push(AdjustAmbienceVolume(new_val));
391        }
392        // Ambience Volume Number
393        Text::new(&format!(
394            "{:2.0}%",
395            self.global_state.settings.audio.ambience_volume.volume * 100.0
396        ))
397        .right_from(state.ids.ambience_volume_slider, 8.0)
398        .font_size(self.fonts.cyri.scale(14))
399        .font_id(self.fonts.cyri.conrod_id)
400        .color(non_master_volume_text_color)
401        .set(state.ids.ambience_volume_number, ui);
402
403        // Music spacing
404        Text::new(&self.localized_strings.get_msg("hud-settings-music_spacing"))
405            .down_from(state.ids.ambience_volume_muted, 10.0)
406            .font_size(self.fonts.cyri.scale(14))
407            .font_id(self.fonts.cyri.conrod_id)
408            .color(TEXT_COLOR)
409            .set(state.ids.music_spacing_text, ui);
410        // Music spacing Slider
411        if let Some(new_val) = ImageSlider::continuous(
412            self.global_state.settings.audio.music_spacing,
413            0.0,
414            2.0,
415            self.imgs.slider_indicator,
416            self.imgs.slider,
417        )
418        .w_h(104.0, 22.0)
419        .down_from(state.ids.music_spacing_text, 10.0)
420        .x_align_to(state.ids.ambience_volume_slider, Align::Start)
421        .track_breadth(12.0)
422        .slider_length(10.0)
423        .pad_track((5.0, 5.0))
424        .set(state.ids.music_spacing_slider, ui)
425        {
426            events.push(AdjustMusicSpacing(new_val));
427        }
428        // Music spacing Number
429        Text::new(&format!(
430            "{:1.2}x",
431            self.global_state.settings.audio.music_spacing
432        ))
433        .right_from(state.ids.music_spacing_slider, 8.0)
434        .font_size(self.fonts.cyri.scale(14))
435        .font_id(self.fonts.cyri.conrod_id)
436        .color(TEXT_COLOR)
437        .set(state.ids.music_spacing_number, ui);
438
439        // Num Sfx Channels
440        // --------------------------------------------
441        Text::new(&self.localized_strings.get_msg("hud-settings-sfx_channels"))
442            .down_from(state.ids.music_spacing_number, 10.0)
443            .x_align_to(state.ids.music_spacing_text, Align::Start)
444            .font_size(self.fonts.cyri.scale(14))
445            .font_id(self.fonts.cyri.conrod_id)
446            .color(TEXT_COLOR)
447            .set(state.ids.sfx_channels_label, ui);
448
449        let current: Option<usize> = match self.global_state.settings.audio.num_sfx_channels {
450            16 => Some(0),
451            32 => Some(1),
452            64 => Some(2),
453            _ => None,
454        };
455
456        let num_sfx_setting_list = [
457            SfxChannelSettings::Low.to_string(),
458            SfxChannelSettings::Medium.to_string(),
459            SfxChannelSettings::High.to_string(),
460        ];
461
462        let num_sfx_setting_list_shown = vec![
463            format!(
464                "{} ({})",
465                &SfxChannelSettings::Low.to_string(),
466                &SfxChannelSettings::Low.to_usize().to_string()
467            ),
468            format!(
469                "{} ({})",
470                &SfxChannelSettings::Medium.to_string(),
471                &SfxChannelSettings::Medium.to_usize().to_string()
472            ),
473            format!(
474                "{} ({})",
475                &SfxChannelSettings::High.to_string(),
476                &SfxChannelSettings::High.to_usize().to_string()
477            ),
478        ];
479
480        if let Some(clicked) = DropDownList::new(&num_sfx_setting_list_shown, current)
481            .w_h(150.0, 22.0)
482            .color(MENU_BG)
483            .label_color(TEXT_COLOR)
484            .label_font_id(self.fonts.cyri.conrod_id)
485            .down_from(state.ids.sfx_channels_label, 10.0)
486            .set(state.ids.sfx_channels_list, ui)
487        {
488            let new_val = &num_sfx_setting_list[clicked];
489
490            events.push(SetNumSfxChannels(SfxChannelSettings::from_str_slice(
491                new_val,
492            )));
493        }
494
495        // Combat music toggle
496        // let audio = &self.global_state.audio;
497
498        // Text::new(&self.localized_strings.get_msg("hud-settings-combat_music"))
499        //     .font_size(self.fonts.cyri.scale(14))
500        //     .font_id(self.fonts.cyri.conrod_id)
501        //     .down_from(state.ids.music_spacing_slider, 10.0)
502        //     .x_align_to(state.ids.music_spacing_text, Align::Start)
503        //     .color(TEXT_COLOR)
504        //     .set(state.ids.combat_music_toggle_label, ui);
505
506        // let combat_music_enabled = ToggleButton::new(
507        //     audio.combat_music_enabled,
508        //     self.imgs.checkbox,
509        //     self.imgs.checkbox_checked,
510        // )
511        // .w_h(18.0, 18.0)
512        // .right_from(state.ids.combat_music_toggle_label, 10.0)
513        // .hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
514        // .press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
515        // .set(state.ids.combat_music_toggle_button, ui);
516
517        // events.push(ToggleCombatMusic(combat_music_enabled));
518
519        // Audio Device Selector
520        // --------------------------------------------
521        // let device = &self.global_state.audio.current_device;
522        // let device_list = self.global_state.audio.get_device_list();
523        // Text::new(&self.localized_strings.get_msg("hud.settings.audio_device"))
524        //     .down_from(state.ids.music_spacing_number, 10.0)
525        //     .font_size(self.fonts.cyri.scale(14))
526        //     .font_id(self.fonts.cyri.conrod_id)
527        //     .color(TEXT_COLOR)
528        //     .set(state.ids.audio_device_text, ui);
529
530        // // Get which device is currently selected
531        // let selected = device_list.iter().position(|d| d == device);
532
533        //if let Some(clicked) = DropDownList::new(&device_list, selected)
534        //    .w_h(400.0, 22.0)
535        //    .color(MENU_BG)
536        //    .label_color(TEXT_COLOR)
537        //    .label_font_id(self.fonts.universal.conrod_id)
538        //    .down_from(state.ids.audio_device_text, 10.0)
539        //    .set(state.ids.audio_device_list, ui)
540        //{
541        //    let new_val = device_list[clicked].clone();
542        //    events.push(ChangeAudioDevice(new_val));
543        //}
544
545        // Reset the sound settings to the default settings
546        if Button::image(self.imgs.button)
547            .w_h(RESET_BUTTONS_WIDTH, RESET_BUTTONS_HEIGHT)
548            .hover_image(self.imgs.button_hover)
549            .press_image(self.imgs.button_press)
550            .down_from(state.ids.sfx_channels_list, 12.0)
551            .x_align_to(state.ids.ambience_volume_text, Align::Start)
552            .label(&self.localized_strings.get_msg("hud-settings-reset_sound"))
553            .label_font_size(self.fonts.cyri.scale(14))
554            .label_color(TEXT_COLOR)
555            .label_font_id(self.fonts.cyri.conrod_id)
556            .label_y(Relative::Scalar(2.0))
557            .set(state.ids.reset_sound_button, ui)
558            .was_clicked()
559        {
560            events.push(ResetAudioSettings);
561        }
562
563        events
564    }
565}