veloren_voxygen/hud/settings_window/
gameplay.rs

1use super::{RESET_BUTTONS_HEIGHT, RESET_BUTTONS_WIDTH};
2
3use crate::{
4    GlobalState,
5    hud::{AutoPressBehavior, MENU_BG, PressBehavior, TEXT_COLOR, img_ids::Imgs},
6    session::settings_change::{Gameplay as GameplayChange, Gameplay::*},
7    ui::{ImageSlider, ToggleButton, fonts::Fonts},
8};
9use conrod_core::{
10    Colorable, Labelable, Positionable, Sizeable, Widget, WidgetCommon, color,
11    position::Relative,
12    widget::{self, Button, DropDownList, Rectangle, Scrollbar, Text},
13    widget_ids,
14};
15use i18n::Localization;
16
17widget_ids! {
18    struct Ids {
19        window,
20        window_r,
21        window_scrollbar,
22        reset_gameplay_button,
23        mouse_pan_slider,
24        mouse_pan_label,
25        mouse_pan_value,
26        mouse_zoom_slider,
27        mouse_zoom_label,
28        mouse_zoom_value,
29        mouse_zoom_invert_button,
30        mouse_zoom_invert_label,
31        camera_clamp_slider,
32        camera_clamp_label,
33        camera_clamp_value,
34        walking_speed_slider,
35        walking_speed_label,
36        walking_speed_value,
37        mouse_y_invert_button,
38        mouse_y_invert_label,
39        controller_y_invert_button,
40        controller_y_invert_label,
41        smooth_pan_toggle_button,
42        smooth_pan_toggle_label,
43        //
44        free_look_behavior_text,
45        free_look_behavior_list,
46        auto_walk_behavior_text,
47        auto_walk_behavior_list,
48        walking_speed_behavior_text,
49        walking_speed_behavior_list,
50        camera_clamp_behavior_text,
51        camera_clamp_behavior_list,
52        zoom_lock_behavior_text,
53        zoom_lock_behavior_list,
54        //
55        stop_auto_walk_on_input_button,
56        stop_auto_walk_on_input_label,
57        auto_camera_button,
58        auto_camera_label,
59        bow_zoom_button,
60        bow_zoom_label,
61        zoom_lock_button,
62        zoom_lock_label,
63        crafting_all_recipes_button,
64        crafting_all_recipes_label,
65        aim_offset_x_slider,
66        aim_offset_x_label,
67        aim_offset_x_value,
68        aim_offset_y_slider,
69        aim_offset_y_label,
70        aim_offset_y_value,
71    }
72}
73
74#[derive(WidgetCommon)]
75pub struct Gameplay<'a> {
76    global_state: &'a GlobalState,
77    imgs: &'a Imgs,
78    fonts: &'a Fonts,
79    localized_strings: &'a Localization,
80    #[conrod(common_builder)]
81    common: widget::CommonBuilder,
82}
83impl<'a> Gameplay<'a> {
84    pub fn new(
85        global_state: &'a GlobalState,
86        imgs: &'a Imgs,
87        fonts: &'a Fonts,
88        localized_strings: &'a Localization,
89    ) -> Self {
90        Self {
91            global_state,
92            imgs,
93            fonts,
94            localized_strings,
95            common: widget::CommonBuilder::default(),
96        }
97    }
98}
99
100pub struct State {
101    ids: Ids,
102}
103
104impl Widget for Gameplay<'_> {
105    type Event = Vec<GameplayChange>;
106    type State = State;
107    type Style = ();
108
109    fn init_state(&self, id_gen: widget::id::Generator) -> Self::State {
110        State {
111            ids: Ids::new(id_gen),
112        }
113    }
114
115    fn style(&self) -> Self::Style {}
116
117    fn update(self, args: widget::UpdateArgs<Self>) -> Self::Event {
118        common_base::prof_span!("Gameplay::update");
119        let widget::UpdateArgs { state, ui, .. } = args;
120
121        let mut events = Vec::new();
122
123        Rectangle::fill_with(args.rect.dim(), color::TRANSPARENT)
124            .xy(args.rect.xy())
125            .graphics_for(args.id)
126            .scroll_kids()
127            .scroll_kids_vertically()
128            .set(state.ids.window, ui);
129        Rectangle::fill_with([args.rect.w() / 2.0, args.rect.h()], color::TRANSPARENT)
130            .top_right()
131            .parent(state.ids.window)
132            .set(state.ids.window_r, ui);
133        Scrollbar::y_axis(state.ids.window)
134            .thickness(5.0)
135            .rgba(0.33, 0.33, 0.33, 1.0)
136            .set(state.ids.window_scrollbar, ui);
137
138        let display_pan = self.global_state.settings.gameplay.pan_sensitivity;
139        let display_zoom = self.global_state.settings.gameplay.zoom_sensitivity;
140        let display_clamp = self.global_state.settings.gameplay.camera_clamp_angle;
141        let display_walking_speed = self.global_state.settings.gameplay.walking_speed;
142
143        // Mouse Pan Sensitivity
144        Text::new(
145            &self
146                .localized_strings
147                .get_msg("hud-settings-pan_sensitivity"),
148        )
149        .top_left_with_margins_on(state.ids.window, 10.0, 10.0)
150        .font_size(self.fonts.cyri.scale(14))
151        .font_id(self.fonts.cyri.conrod_id)
152        .color(TEXT_COLOR)
153        .set(state.ids.mouse_pan_label, ui);
154
155        if let Some(new_val) = ImageSlider::discrete(
156            display_pan,
157            1,
158            200,
159            self.imgs.slider_indicator,
160            self.imgs.slider,
161        )
162        .w_h(550.0, 22.0)
163        .down_from(state.ids.mouse_pan_label, 10.0)
164        .track_breadth(30.0)
165        .slider_length(10.0)
166        .pad_track((5.0, 5.0))
167        .set(state.ids.mouse_pan_slider, ui)
168        {
169            events.push(AdjustMousePan(new_val));
170        }
171
172        Text::new(&format!("{}", display_pan))
173            .right_from(state.ids.mouse_pan_slider, 8.0)
174            .font_size(self.fonts.cyri.scale(14))
175            .font_id(self.fonts.cyri.conrod_id)
176            .color(TEXT_COLOR)
177            .set(state.ids.mouse_pan_value, ui);
178
179        // Mouse Zoom Sensitivity
180        Text::new(
181            &self
182                .localized_strings
183                .get_msg("hud-settings-zoom_sensitivity"),
184        )
185        .down_from(state.ids.mouse_pan_slider, 10.0)
186        .font_size(self.fonts.cyri.scale(14))
187        .font_id(self.fonts.cyri.conrod_id)
188        .color(TEXT_COLOR)
189        .set(state.ids.mouse_zoom_label, ui);
190
191        if let Some(new_val) = ImageSlider::discrete(
192            display_zoom,
193            1,
194            300,
195            self.imgs.slider_indicator,
196            self.imgs.slider,
197        )
198        .w_h(550.0, 22.0)
199        .down_from(state.ids.mouse_zoom_label, 10.0)
200        .track_breadth(30.0)
201        .slider_length(10.0)
202        .pad_track((5.0, 5.0))
203        .set(state.ids.mouse_zoom_slider, ui)
204        {
205            events.push(AdjustMouseZoom(new_val));
206        }
207
208        Text::new(&format!("{}", display_zoom))
209            .right_from(state.ids.mouse_zoom_slider, 8.0)
210            .font_size(self.fonts.cyri.scale(14))
211            .font_id(self.fonts.cyri.conrod_id)
212            .color(TEXT_COLOR)
213            .set(state.ids.mouse_zoom_value, ui);
214
215        // Camera clamp angle
216        Text::new(
217            &self
218                .localized_strings
219                .get_msg("hud-settings-camera_clamp_angle"),
220        )
221        .down_from(state.ids.mouse_zoom_slider, 10.0)
222        .font_size(self.fonts.cyri.scale(14))
223        .font_id(self.fonts.cyri.conrod_id)
224        .color(TEXT_COLOR)
225        .set(state.ids.camera_clamp_label, ui);
226
227        if let Some(new_val) = ImageSlider::discrete(
228            display_clamp,
229            1,
230            90,
231            self.imgs.slider_indicator,
232            self.imgs.slider,
233        )
234        .w_h(550.0, 22.0)
235        .down_from(state.ids.camera_clamp_label, 10.0)
236        .track_breadth(30.0)
237        .slider_length(10.0)
238        .pad_track((5.0, 5.0))
239        .set(state.ids.camera_clamp_slider, ui)
240        {
241            events.push(AdjustCameraClamp(new_val));
242        }
243
244        Text::new(&format!("{}", display_clamp))
245            .right_from(state.ids.camera_clamp_slider, 8.0)
246            .font_size(self.fonts.cyri.scale(14))
247            .font_id(self.fonts.cyri.conrod_id)
248            .color(TEXT_COLOR)
249            .set(state.ids.camera_clamp_value, ui);
250
251        // Walking speed
252        Text::new(&self.localized_strings.get_msg("hud-settings-walking_speed"))
253            .down_from(state.ids.camera_clamp_slider, 10.0)
254            .font_size(self.fonts.cyri.scale(14))
255            .font_id(self.fonts.cyri.conrod_id)
256            .color(TEXT_COLOR)
257            .set(state.ids.walking_speed_label, ui);
258
259        if let Some(new_val) = ImageSlider::continuous(
260            display_walking_speed,
261            0.0,
262            1.0,
263            self.imgs.slider_indicator,
264            self.imgs.slider,
265        )
266        .w_h(550.0, 22.0)
267        .down_from(state.ids.walking_speed_label, 10.0)
268        .track_breadth(30.0)
269        .slider_length(10.0)
270        .pad_track((5.0, 5.0))
271        .set(state.ids.walking_speed_slider, ui)
272        {
273            events.push(AdjustWalkingSpeed(new_val));
274        }
275
276        Text::new(&format!("{:.2}", display_walking_speed))
277            .right_from(state.ids.walking_speed_slider, 8.0)
278            .font_size(self.fonts.cyri.scale(14))
279            .font_id(self.fonts.cyri.conrod_id)
280            .color(TEXT_COLOR)
281            .set(state.ids.walking_speed_value, ui);
282
283        // Zoom Inversion
284        let zoom_inverted = ToggleButton::new(
285            self.global_state.settings.gameplay.zoom_inversion,
286            self.imgs.checkbox,
287            self.imgs.checkbox_checked,
288        )
289        .w_h(18.0, 18.0)
290        .down_from(state.ids.walking_speed_slider, 20.0)
291        .hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
292        .press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
293        .set(state.ids.mouse_zoom_invert_button, ui);
294
295        if self.global_state.settings.gameplay.zoom_inversion != zoom_inverted {
296            events.push(ToggleZoomInvert(
297                !self.global_state.settings.gameplay.zoom_inversion,
298            ));
299        }
300
301        Text::new(
302            &self
303                .localized_strings
304                .get_msg("hud-settings-invert_scroll_zoom"),
305        )
306        .right_from(state.ids.mouse_zoom_invert_button, 10.0)
307        .font_size(self.fonts.cyri.scale(14))
308        .font_id(self.fonts.cyri.conrod_id)
309        .graphics_for(state.ids.mouse_zoom_invert_button)
310        .color(TEXT_COLOR)
311        .set(state.ids.mouse_zoom_invert_label, ui);
312
313        // Mouse Y Inversion
314        let mouse_y_inverted = ToggleButton::new(
315            self.global_state.settings.gameplay.mouse_y_inversion,
316            self.imgs.checkbox,
317            self.imgs.checkbox_checked,
318        )
319        .w_h(18.0, 18.0)
320        .right_from(state.ids.mouse_zoom_invert_label, 10.0)
321        .hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
322        .press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
323        .set(state.ids.mouse_y_invert_button, ui);
324
325        if self.global_state.settings.gameplay.mouse_y_inversion != mouse_y_inverted {
326            events.push(ToggleMouseYInvert(
327                !self.global_state.settings.gameplay.mouse_y_inversion,
328            ));
329        }
330
331        Text::new(
332            &self
333                .localized_strings
334                .get_msg("hud-settings-invert_mouse_y_axis"),
335        )
336        .right_from(state.ids.mouse_y_invert_button, 10.0)
337        .font_size(self.fonts.cyri.scale(14))
338        .font_id(self.fonts.cyri.conrod_id)
339        .graphics_for(state.ids.mouse_y_invert_button)
340        .color(TEXT_COLOR)
341        .set(state.ids.mouse_y_invert_label, ui);
342
343        // Controller Y Pan Inversion
344        let controller_y_inverted = ToggleButton::new(
345            self.global_state.settings.controller.pan_invert_y,
346            self.imgs.checkbox,
347            self.imgs.checkbox_checked,
348        )
349        .w_h(18.0, 18.0)
350        .right_from(state.ids.mouse_y_invert_label, 10.0)
351        .hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
352        .press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
353        .set(state.ids.controller_y_invert_button, ui);
354
355        if self.global_state.settings.controller.pan_invert_y != controller_y_inverted {
356            events.push(ToggleControllerYInvert(
357                !self.global_state.settings.controller.pan_invert_y,
358            ));
359        }
360
361        Text::new(
362            &self
363                .localized_strings
364                .get_msg("hud-settings-invert_controller_y_axis"),
365        )
366        .right_from(state.ids.controller_y_invert_button, 10.0)
367        .font_size(self.fonts.cyri.scale(14))
368        .font_id(self.fonts.cyri.conrod_id)
369        .graphics_for(state.ids.controller_y_invert_button)
370        .color(TEXT_COLOR)
371        .set(state.ids.controller_y_invert_label, ui);
372
373        // Mouse Smoothing Toggle
374        let smooth_pan_enabled = ToggleButton::new(
375            self.global_state.settings.gameplay.smooth_pan_enable,
376            self.imgs.checkbox,
377            self.imgs.checkbox_checked,
378        )
379        .w_h(18.0, 18.0)
380        .right_from(state.ids.controller_y_invert_label, 10.0)
381        .hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
382        .press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
383        .set(state.ids.smooth_pan_toggle_button, ui);
384
385        if self.global_state.settings.gameplay.smooth_pan_enable != smooth_pan_enabled {
386            events.push(ToggleSmoothPan(
387                !self.global_state.settings.gameplay.smooth_pan_enable,
388            ));
389        }
390
391        Text::new(
392            &self
393                .localized_strings
394                .get_msg("hud-settings-enable_mouse_smoothing"),
395        )
396        .right_from(state.ids.smooth_pan_toggle_button, 10.0)
397        .font_size(self.fonts.cyri.scale(14))
398        .font_id(self.fonts.cyri.conrod_id)
399        .graphics_for(state.ids.smooth_pan_toggle_button)
400        .color(TEXT_COLOR)
401        .set(state.ids.smooth_pan_toggle_label, ui);
402
403        // Free look behaviour
404        Text::new(
405            &self
406                .localized_strings
407                .get_msg("hud-settings-free_look_behavior"),
408        )
409        .down_from(state.ids.mouse_zoom_invert_button, 10.0)
410        .font_size(self.fonts.cyri.scale(14))
411        .font_id(self.fonts.cyri.conrod_id)
412        .color(TEXT_COLOR)
413        .set(state.ids.free_look_behavior_text, ui);
414
415        let mode_label_list = [
416            self.localized_strings
417                .get_msg("hud-settings-press_behavior-toggle"),
418            self.localized_strings
419                .get_msg("hud-settings-press_behavior-hold"),
420        ];
421
422        // Get which free look behavior is currently active
423        let selected = self.global_state.settings.gameplay.free_look_behavior as usize;
424
425        if let Some(clicked) = DropDownList::new(&mode_label_list, Some(selected))
426            .w_h(200.0, 30.0)
427            .color(MENU_BG)
428            .label_color(TEXT_COLOR)
429            .label_font_id(self.fonts.cyri.conrod_id)
430            .down_from(state.ids.free_look_behavior_text, 8.0)
431            .set(state.ids.free_look_behavior_list, ui)
432        {
433            match clicked {
434                0 => events.push(ChangeFreeLookBehavior(PressBehavior::Toggle)),
435                1 => events.push(ChangeFreeLookBehavior(PressBehavior::Hold)),
436                _ => unreachable!(),
437            }
438        }
439
440        // Auto walk behavior
441        Text::new(
442            &self
443                .localized_strings
444                .get_msg("hud-settings-auto_walk_behavior"),
445        )
446        .down_from(state.ids.mouse_zoom_invert_button, 10.0)
447        .right_from(state.ids.free_look_behavior_text, 150.0)
448        .font_size(self.fonts.cyri.scale(14))
449        .font_id(self.fonts.cyri.conrod_id)
450        .color(TEXT_COLOR)
451        .set(state.ids.auto_walk_behavior_text, ui);
452
453        let auto_walk_selected = self.global_state.settings.gameplay.auto_walk_behavior as usize;
454
455        if let Some(clicked) = DropDownList::new(&mode_label_list, Some(auto_walk_selected))
456            .w_h(200.0, 30.0)
457            .color(MENU_BG)
458            .label_color(TEXT_COLOR)
459            .label_font_id(self.fonts.cyri.conrod_id)
460            .down_from(state.ids.auto_walk_behavior_text, 8.0)
461            .set(state.ids.auto_walk_behavior_list, ui)
462        {
463            match clicked {
464                0 => events.push(ChangeAutoWalkBehavior(PressBehavior::Toggle)),
465                1 => events.push(ChangeAutoWalkBehavior(PressBehavior::Hold)),
466                _ => unreachable!(),
467            }
468        }
469
470        // Walking speed behavior
471        Text::new(
472            &self
473                .localized_strings
474                .get_msg("hud-settings-walking_speed_behavior"),
475        )
476        .down_from(state.ids.free_look_behavior_list, 10.0)
477        .font_size(self.fonts.cyri.scale(14))
478        .font_id(self.fonts.cyri.conrod_id)
479        .color(TEXT_COLOR)
480        .set(state.ids.walking_speed_behavior_text, ui);
481
482        let walking_speed_selected =
483            self.global_state.settings.gameplay.walking_speed_behavior as usize;
484
485        if let Some(clicked) = DropDownList::new(&mode_label_list, Some(walking_speed_selected))
486            .w_h(200.0, 30.0)
487            .color(MENU_BG)
488            .label_color(TEXT_COLOR)
489            .label_font_id(self.fonts.cyri.conrod_id)
490            .down_from(state.ids.walking_speed_behavior_text, 8.0)
491            .set(state.ids.walking_speed_behavior_list, ui)
492        {
493            match clicked {
494                0 => events.push(ChangeWalkingSpeedBehavior(PressBehavior::Toggle)),
495                1 => events.push(ChangeWalkingSpeedBehavior(PressBehavior::Hold)),
496                _ => unreachable!(),
497            }
498        }
499
500        // Camera clamp behavior
501        Text::new(
502            &self
503                .localized_strings
504                .get_msg("hud-settings-camera_clamp_behavior"),
505        )
506        .down_from(state.ids.auto_walk_behavior_list, 10.0)
507        .font_size(self.fonts.cyri.scale(14))
508        .font_id(self.fonts.cyri.conrod_id)
509        .color(TEXT_COLOR)
510        .set(state.ids.camera_clamp_behavior_text, ui);
511
512        let camera_clamp_selected =
513            self.global_state.settings.gameplay.camera_clamp_behavior as usize;
514
515        if let Some(clicked) = DropDownList::new(&mode_label_list, Some(camera_clamp_selected))
516            .w_h(200.0, 30.0)
517            .color(MENU_BG)
518            .label_color(TEXT_COLOR)
519            .label_font_id(self.fonts.cyri.conrod_id)
520            .down_from(state.ids.camera_clamp_behavior_text, 8.0)
521            .set(state.ids.camera_clamp_behavior_list, ui)
522        {
523            match clicked {
524                0 => events.push(ChangeCameraClampBehavior(PressBehavior::Toggle)),
525                1 => events.push(ChangeCameraClampBehavior(PressBehavior::Hold)),
526                _ => unreachable!(),
527            }
528        }
529
530        // Stop autowalk on input toggle
531        let stop_auto_walk_on_input_toggle = ToggleButton::new(
532            self.global_state.settings.gameplay.stop_auto_walk_on_input,
533            self.imgs.checkbox,
534            self.imgs.checkbox_checked,
535        )
536        .w_h(18.0, 18.0)
537        .down_from(state.ids.smooth_pan_toggle_button, 8.0)
538        .hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
539        .press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
540        .set(state.ids.stop_auto_walk_on_input_button, ui);
541
542        if self.global_state.settings.gameplay.stop_auto_walk_on_input
543            != stop_auto_walk_on_input_toggle
544        {
545            events.push(ChangeStopAutoWalkOnInput(
546                !self.global_state.settings.gameplay.stop_auto_walk_on_input,
547            ));
548        }
549
550        Text::new(
551            &self
552                .localized_strings
553                .get_msg("hud-settings-stop_auto_walk_on_input"),
554        )
555        .right_from(state.ids.stop_auto_walk_on_input_button, 10.0)
556        .font_size(self.fonts.cyri.scale(14))
557        .font_id(self.fonts.cyri.conrod_id)
558        .graphics_for(state.ids.stop_auto_walk_on_input_button)
559        .color(TEXT_COLOR)
560        .set(state.ids.stop_auto_walk_on_input_label, ui);
561
562        // Auto-camera toggle
563        let auto_camera_toggle = ToggleButton::new(
564            self.global_state.settings.gameplay.auto_camera,
565            self.imgs.checkbox,
566            self.imgs.checkbox_checked,
567        )
568        .w_h(18.0, 18.0)
569        .down_from(state.ids.stop_auto_walk_on_input_button, 8.0)
570        .hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
571        .press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
572        .set(state.ids.auto_camera_button, ui);
573
574        if self.global_state.settings.gameplay.auto_camera != auto_camera_toggle {
575            events.push(ChangeAutoCamera(
576                !self.global_state.settings.gameplay.auto_camera,
577            ));
578        }
579
580        Text::new(&self.localized_strings.get_msg("hud-settings-auto_camera"))
581            .right_from(state.ids.auto_camera_button, 10.0)
582            .font_size(self.fonts.cyri.scale(14))
583            .font_id(self.fonts.cyri.conrod_id)
584            .graphics_for(state.ids.auto_camera_button)
585            .color(TEXT_COLOR)
586            .set(state.ids.auto_camera_label, ui);
587
588        // Charging bow zoom toggle
589        let bow_zoom_toggle = ToggleButton::new(
590            self.global_state.settings.gameplay.bow_zoom,
591            self.imgs.checkbox,
592            self.imgs.checkbox_checked,
593        )
594        .w_h(18.0, 18.0)
595        .down_from(state.ids.auto_camera_button, 8.0)
596        .hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
597        .press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
598        .set(state.ids.bow_zoom_button, ui);
599
600        if self.global_state.settings.gameplay.bow_zoom != bow_zoom_toggle {
601            events.push(ChangeBowZoom(!self.global_state.settings.gameplay.bow_zoom));
602        }
603
604        Text::new(&self.localized_strings.get_msg("hud-settings-bow_zoom"))
605            .right_from(state.ids.bow_zoom_button, 10.0)
606            .font_size(self.fonts.cyri.scale(14))
607            .font_id(self.fonts.cyri.conrod_id)
608            .graphics_for(state.ids.bow_zoom_button)
609            .color(TEXT_COLOR)
610            .set(state.ids.bow_zoom_label, ui);
611
612        let zoom_lock_label_list = [
613            self.localized_strings
614                .get_msg("hud-settings-autopress_behavior-toggle"),
615            self.localized_strings
616                .get_msg("hud-settings-autopress_behavior-auto"),
617        ];
618
619        // Camera zoom lock behavior
620        Text::new(
621            &self
622                .localized_strings
623                .get_msg("hud-settings-zoom_lock_behavior"),
624        )
625        .down_from(state.ids.walking_speed_behavior_list, 10.0)
626        .font_size(self.fonts.cyri.scale(14))
627        .font_id(self.fonts.cyri.conrod_id)
628        .color(TEXT_COLOR)
629        .set(state.ids.zoom_lock_behavior_text, ui);
630
631        let zoom_lock_selected = self.global_state.settings.gameplay.zoom_lock_behavior as usize;
632
633        if let Some(clicked) = DropDownList::new(&zoom_lock_label_list, Some(zoom_lock_selected))
634            .w_h(200.0, 30.0)
635            .color(MENU_BG)
636            .label_color(TEXT_COLOR)
637            .label_font_id(self.fonts.cyri.conrod_id)
638            .down_from(state.ids.zoom_lock_behavior_text, 8.0)
639            .set(state.ids.zoom_lock_behavior_list, ui)
640        {
641            match clicked {
642                0 => events.push(ChangeZoomLockBehavior(AutoPressBehavior::Toggle)),
643                1 => events.push(ChangeZoomLockBehavior(AutoPressBehavior::Auto)),
644                _ => unreachable!(),
645            }
646        }
647
648        // Camera zoom lock toggle
649        let zoom_lock_toggle = ToggleButton::new(
650            self.global_state.settings.gameplay.zoom_lock,
651            self.imgs.checkbox,
652            self.imgs.checkbox_checked,
653        )
654        .w_h(18.0, 18.0)
655        .down_from(state.ids.bow_zoom_button, 8.0)
656        .hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
657        .press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
658        .set(state.ids.zoom_lock_button, ui);
659
660        if self.global_state.settings.gameplay.zoom_lock != zoom_lock_toggle {
661            events.push(ChangeZoomLock(
662                !self.global_state.settings.gameplay.zoom_lock,
663            ));
664        }
665
666        Text::new(&self.localized_strings.get_msg("hud-settings-zoom_lock"))
667            .right_from(state.ids.zoom_lock_button, 10.0)
668            .font_size(self.fonts.cyri.scale(14))
669            .font_id(self.fonts.cyri.conrod_id)
670            .graphics_for(state.ids.zoom_lock_button)
671            .color(TEXT_COLOR)
672            .set(state.ids.zoom_lock_label, ui);
673
674        // Crafting show all recipes toggle
675        let all_recipes_toggle = ToggleButton::new(
676            self.global_state.settings.gameplay.show_all_recipes,
677            self.imgs.checkbox,
678            self.imgs.checkbox_checked,
679        )
680        .w_h(18.0, 18.0)
681        .down_from(state.ids.zoom_lock_button, 8.0)
682        .hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
683        .press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
684        .set(state.ids.crafting_all_recipes_button, ui);
685
686        if self.global_state.settings.gameplay.show_all_recipes != all_recipes_toggle {
687            events.push(ChangeShowAllRecipes(
688                !self.global_state.settings.gameplay.show_all_recipes,
689            ));
690        }
691
692        Text::new(
693            &self
694                .localized_strings
695                .get_msg("hud-settings-show_all_recipes"),
696        )
697        .right_from(state.ids.crafting_all_recipes_button, 10.0)
698        .font_size(self.fonts.cyri.scale(14))
699        .font_id(self.fonts.cyri.conrod_id)
700        .graphics_for(state.ids.crafting_all_recipes_button)
701        .color(TEXT_COLOR)
702        .set(state.ids.crafting_all_recipes_label, ui);
703
704        // Aim offset x
705        let display_aim_offset_x = self.global_state.settings.gameplay.aim_offset_x;
706        Text::new(&self.localized_strings.get_msg("hud-settings-aim_offset_x"))
707            .down_from(state.ids.zoom_lock_behavior_list, 10.0)
708            .font_size(self.fonts.cyri.scale(14))
709            .font_id(self.fonts.cyri.conrod_id)
710            .color(TEXT_COLOR)
711            .set(state.ids.aim_offset_x_label, ui);
712
713        if let Some(new_val) = ImageSlider::continuous(
714            display_aim_offset_x,
715            -3.0,
716            3.0,
717            self.imgs.slider_indicator,
718            self.imgs.slider,
719        )
720        .w_h(550.0, 22.0)
721        .down_from(state.ids.aim_offset_x_label, 10.0)
722        .track_breadth(30.0)
723        .slider_length(10.0)
724        .pad_track((5.0, 5.0))
725        .set(state.ids.aim_offset_x_slider, ui)
726        {
727            events.push(AdjustAimOffsetX(new_val));
728        }
729
730        Text::new(&format!("{:.2}", display_aim_offset_x))
731            .right_from(state.ids.aim_offset_x_slider, 8.0)
732            .font_size(self.fonts.cyri.scale(14))
733            .font_id(self.fonts.cyri.conrod_id)
734            .color(TEXT_COLOR)
735            .set(state.ids.aim_offset_x_value, ui);
736
737        // Aim offset y
738        let display_aim_offset_y = self.global_state.settings.gameplay.aim_offset_y;
739        Text::new(&self.localized_strings.get_msg("hud-settings-aim_offset_y"))
740            .down_from(state.ids.aim_offset_x_slider, 10.0)
741            .font_size(self.fonts.cyri.scale(14))
742            .font_id(self.fonts.cyri.conrod_id)
743            .color(TEXT_COLOR)
744            .set(state.ids.aim_offset_y_label, ui);
745
746        if let Some(new_val) = ImageSlider::continuous(
747            display_aim_offset_y,
748            -3.0,
749            3.0,
750            self.imgs.slider_indicator,
751            self.imgs.slider,
752        )
753        .w_h(550.0, 22.0)
754        .down_from(state.ids.aim_offset_y_label, 10.0)
755        .track_breadth(30.0)
756        .slider_length(10.0)
757        .pad_track((5.0, 5.0))
758        .set(state.ids.aim_offset_y_slider, ui)
759        {
760            events.push(AdjustAimOffsetY(new_val));
761        }
762
763        Text::new(&format!("{:.2}", display_aim_offset_y))
764            .right_from(state.ids.aim_offset_y_slider, 8.0)
765            .font_size(self.fonts.cyri.scale(14))
766            .font_id(self.fonts.cyri.conrod_id)
767            .color(TEXT_COLOR)
768            .set(state.ids.aim_offset_y_value, ui);
769
770        // Reset the gameplay settings to the default settings
771        if Button::image(self.imgs.button)
772            .w_h(RESET_BUTTONS_WIDTH, RESET_BUTTONS_HEIGHT)
773            .hover_image(self.imgs.button_hover)
774            .press_image(self.imgs.button_press)
775            .down_from(state.ids.aim_offset_y_slider, 12.0)
776            .label(
777                &self
778                    .localized_strings
779                    .get_msg("hud-settings-reset_gameplay"),
780            )
781            .label_font_size(self.fonts.cyri.scale(14))
782            .label_color(TEXT_COLOR)
783            .label_font_id(self.fonts.cyri.conrod_id)
784            .label_y(Relative::Scalar(2.0))
785            .set(state.ids.reset_gameplay_button, ui)
786            .was_clicked()
787        {
788            events.push(ResetGameplaySettings);
789        }
790
791        events
792    }
793}