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