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