veloren_voxygen/hud/settings_window/
networking.rs

1use crate::{
2    GlobalState,
3    hud::{MENU_BG, TEXT_COLOR, img_ids::Imgs},
4    session::settings_change::{Networking as NetworkingChange, Networking::*},
5    ui::{ImageSlider, ToggleButton, fonts::Fonts},
6};
7use conrod_core::{
8    Colorable, Labelable, Positionable, Sizeable, Widget, WidgetCommon, color,
9    widget::{self, DropDownList, Rectangle, Text},
10    widget_ids,
11};
12use i18n::Localization;
13
14widget_ids! {
15    struct Ids {
16        window,
17        window_r,
18        terrain_vd_text,
19        terrain_vd_slider,
20        terrain_vd_value,
21        entity_vd_text,
22        entity_vd_slider,
23        entity_vd_value,
24        player_physics_behavior_text,
25        player_physics_behavior_list,
26        lossy_terrain_compression_button,
27        lossy_terrain_compression_label,
28        third_party_integrations_title,
29        enable_discord_integration_text,
30        enable_discord_integration_button
31    }
32}
33
34#[derive(WidgetCommon)]
35pub struct Networking<'a> {
36    global_state: &'a GlobalState,
37    imgs: &'a Imgs,
38    fonts: &'a Fonts,
39    localized_strings: &'a Localization,
40    server_view_distance_limit: Option<u32>,
41    #[conrod(common_builder)]
42    common: widget::CommonBuilder,
43}
44impl<'a> Networking<'a> {
45    pub fn new(
46        global_state: &'a GlobalState,
47        imgs: &'a Imgs,
48        fonts: &'a Fonts,
49        localized_strings: &'a Localization,
50        server_view_distance_limit: Option<u32>,
51    ) -> Self {
52        Self {
53            global_state,
54            imgs,
55            fonts,
56            localized_strings,
57            server_view_distance_limit,
58            common: widget::CommonBuilder::default(),
59        }
60    }
61}
62
63pub struct State {
64    ids: Ids,
65}
66
67impl Widget for Networking<'_> {
68    type Event = Vec<NetworkingChange>;
69    type State = State;
70    type Style = ();
71
72    fn init_state(&self, id_gen: widget::id::Generator) -> Self::State {
73        State {
74            ids: Ids::new(id_gen),
75        }
76    }
77
78    fn style(&self) -> Self::Style {}
79
80    fn update(self, args: widget::UpdateArgs<Self>) -> Self::Event {
81        common_base::prof_span!("Networking::update");
82        let widget::UpdateArgs { state, ui, .. } = args;
83
84        let mut events = Vec::new();
85
86        Rectangle::fill_with(args.rect.dim(), color::TRANSPARENT)
87            .xy(args.rect.xy())
88            .graphics_for(args.id)
89            .scroll_kids()
90            .scroll_kids_vertically()
91            .set(state.ids.window, ui);
92        Rectangle::fill_with([args.rect.w() / 2.0, args.rect.h()], color::TRANSPARENT)
93            .top_right()
94            .parent(state.ids.window)
95            .set(state.ids.window_r, ui);
96
97        // View Distance
98        Text::new(&self.localized_strings.get_msg("hud-settings-view_distance"))
99            .top_left_with_margins_on(state.ids.window, 10.0, 10.0)
100            .font_size(self.fonts.cyri.scale(14))
101            .font_id(self.fonts.cyri.conrod_id)
102            .color(TEXT_COLOR)
103            .set(state.ids.terrain_vd_text, ui);
104
105        let terrain_view_distance = self.global_state.settings.graphics.terrain_view_distance;
106        let server_view_distance_limit = self.server_view_distance_limit.unwrap_or(u32::MAX);
107        if let Some(new_val) = ImageSlider::discrete(
108            terrain_view_distance,
109            1,
110            client::MAX_SELECTABLE_VIEW_DISTANCE,
111            self.imgs.slider_indicator,
112            self.imgs.slider,
113        )
114        .w_h(104.0, 22.0)
115        .down_from(state.ids.terrain_vd_text, 8.0)
116        .track_breadth(12.0)
117        .slider_length(10.0)
118        .soft_max(server_view_distance_limit)
119        .pad_track((5.0, 5.0))
120        .set(state.ids.terrain_vd_slider, ui)
121        {
122            events.push(NetworkingChange::AdjustTerrainViewDistance(new_val));
123        }
124
125        Text::new(&if terrain_view_distance <= server_view_distance_limit {
126            format!("{terrain_view_distance}")
127        } else {
128            format!("{terrain_view_distance} ({server_view_distance_limit})")
129        })
130        .right_from(state.ids.terrain_vd_slider, 8.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.terrain_vd_value, ui);
135
136        // Entity View Distance
137        Text::new(
138            &self
139                .localized_strings
140                .get_msg("hud-settings-entity_view_distance"),
141        )
142        .down_from(state.ids.terrain_vd_slider, 10.0)
143        .font_size(self.fonts.cyri.scale(14))
144        .font_id(self.fonts.cyri.conrod_id)
145        .color(TEXT_COLOR)
146        .set(state.ids.entity_vd_text, ui);
147
148        let soft_entity_vd_max = self
149            .server_view_distance_limit
150            .unwrap_or(u32::MAX)
151            .min(terrain_view_distance);
152        let entity_view_distance = self.global_state.settings.graphics.entity_view_distance;
153        if let Some(new_val) = ImageSlider::discrete(
154            entity_view_distance,
155            1,
156            client::MAX_SELECTABLE_VIEW_DISTANCE,
157            self.imgs.slider_indicator,
158            self.imgs.slider,
159        )
160        .w_h(104.0, 22.0)
161        .down_from(state.ids.entity_vd_text, 8.0)
162        .track_breadth(12.0)
163        .slider_length(10.0)
164        .soft_max(soft_entity_vd_max)
165        .pad_track((5.0, 5.0))
166        .set(state.ids.entity_vd_slider, ui)
167        {
168            events.push(NetworkingChange::AdjustEntityViewDistance(new_val));
169        }
170
171        Text::new(&if entity_view_distance <= soft_entity_vd_max {
172            format!("{entity_view_distance}")
173        } else {
174            format!("{entity_view_distance} ({soft_entity_vd_max})")
175        })
176        .right_from(state.ids.entity_vd_slider, 8.0)
177        .font_size(self.fonts.cyri.scale(14))
178        .font_id(self.fonts.cyri.conrod_id)
179        .color(TEXT_COLOR)
180        .set(state.ids.entity_vd_value, ui);
181
182        // Player physics behavior
183        Text::new(
184            &self
185                .localized_strings
186                .get_msg("hud-settings-player_physics_behavior"),
187        )
188        .down_from(state.ids.entity_vd_slider, 8.0)
189        .font_size(self.fonts.cyri.scale(14))
190        .font_id(self.fonts.cyri.conrod_id)
191        .color(TEXT_COLOR)
192        .set(state.ids.player_physics_behavior_text, ui);
193
194        let player_physics_selected = self
195            .global_state
196            .settings
197            .networking
198            .player_physics_behavior as usize;
199
200        if let Some(clicked) = DropDownList::new(
201            &["Client-authoritative", "Server-authoritative"],
202            Some(player_physics_selected),
203        )
204        .w_h(200.0, 30.0)
205        .color(MENU_BG)
206        .label_color(TEXT_COLOR)
207        .label_font_id(self.fonts.cyri.conrod_id)
208        .down_from(state.ids.player_physics_behavior_text, 8.0)
209        .set(state.ids.player_physics_behavior_list, ui)
210        {
211            match clicked {
212                0 => events.push(ChangePlayerPhysicsBehavior {
213                    server_authoritative: false,
214                }),
215                _ => events.push(ChangePlayerPhysicsBehavior {
216                    server_authoritative: true,
217                }),
218            }
219        }
220
221        // Lossy terrain compression
222        Text::new(
223            &self
224                .localized_strings
225                .get_msg("hud-settings-lossy_terrain_compression"),
226        )
227        .font_size(self.fonts.cyri.scale(14))
228        .font_id(self.fonts.cyri.conrod_id)
229        .right_from(state.ids.player_physics_behavior_text, 64.0)
230        .color(TEXT_COLOR)
231        .set(state.ids.lossy_terrain_compression_label, ui);
232
233        let lossy_terrain_compression = ToggleButton::new(
234            self.global_state
235                .settings
236                .networking
237                .lossy_terrain_compression,
238            self.imgs.checkbox,
239            self.imgs.checkbox_checked,
240        )
241        .w_h(18.0, 18.0)
242        .right_from(state.ids.lossy_terrain_compression_label, 10.0)
243        .hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
244        .press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
245        .set(state.ids.lossy_terrain_compression_button, ui);
246
247        if self
248            .global_state
249            .settings
250            .networking
251            .lossy_terrain_compression
252            != lossy_terrain_compression
253        {
254            events.push(NetworkingChange::ToggleLossyTerrainCompression(
255                lossy_terrain_compression,
256            ));
257        }
258
259        #[cfg(feature = "discord")]
260        {
261            // Third party integrations
262            Text::new(
263                &self
264                    .localized_strings
265                    .get_msg("hud-settings-third_party_integrations"),
266            )
267            .down_from(state.ids.player_physics_behavior_list, 16.0)
268            .font_size(self.fonts.cyri.scale(18))
269            .font_id(self.fonts.cyri.conrod_id)
270            .color(TEXT_COLOR)
271            .set(state.ids.third_party_integrations_title, ui);
272
273            // Toggle Discord integration
274            let enable_discord_integration = ToggleButton::new(
275                self.global_state
276                    .settings
277                    .networking
278                    .enable_discord_integration,
279                self.imgs.checkbox,
280                self.imgs.checkbox_checked,
281            )
282            .w_h(18.0, 18.0)
283            .down_from(state.ids.third_party_integrations_title, 8.0)
284            .hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
285            .press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
286            .set(state.ids.enable_discord_integration_button, ui);
287
288            if self
289                .global_state
290                .settings
291                .networking
292                .enable_discord_integration
293                != enable_discord_integration
294            {
295                events.push(ToggleDiscordIntegration(
296                    !self
297                        .global_state
298                        .settings
299                        .networking
300                        .enable_discord_integration,
301                ));
302            }
303
304            Text::new(
305                &self
306                    .localized_strings
307                    .get_msg("hud-settings-enable_discord_integration"),
308            )
309            .right_from(state.ids.enable_discord_integration_button, 10.0)
310            .font_size(self.fonts.cyri.scale(14))
311            .font_id(self.fonts.cyri.conrod_id)
312            .graphics_for(state.ids.enable_discord_integration_button)
313            .color(TEXT_COLOR)
314            .set(state.ids.enable_discord_integration_text, ui);
315        }
316
317        events
318    }
319}