veloren_voxygen/menu/main/ui/
servers.rs

1use super::{FILL_FRAC_ONE, Imgs, Message};
2use crate::ui::{
3    fonts::IcedFonts as Fonts,
4    ice::{Element, component::neat_button, style},
5};
6use i18n::Localization;
7use iced::{
8    Align, Button, Column, Container, Length, Row, Scrollable, Space, Text, button, scrollable,
9};
10
11pub struct Screen {
12    back_button: button::State,
13    delete_button: button::State,
14    server_buttons: Vec<button::State>,
15    servers_list: scrollable::State,
16}
17
18impl Screen {
19    pub fn new() -> Self {
20        Self {
21            back_button: Default::default(),
22            delete_button: Default::default(),
23            server_buttons: vec![],
24            servers_list: Default::default(),
25        }
26    }
27
28    pub(super) fn view(
29        &mut self,
30        fonts: &Fonts,
31        imgs: &Imgs,
32        servers: &[impl AsRef<str>],
33        selected_server_index: Option<usize>,
34        i18n: &Localization,
35        button_style: style::button::Style,
36    ) -> Element<Message> {
37        let title = Text::new(i18n.get_msg("main-servers-select_server"))
38            .size(fonts.cyri.scale(35))
39            .width(Length::Fill)
40            .horizontal_alignment(iced::HorizontalAlignment::Center);
41
42        let back_button = Container::new(
43            Container::new(neat_button(
44                &mut self.back_button,
45                i18n.get_msg("common-back"),
46                FILL_FRAC_ONE,
47                button_style,
48                Some(Message::Back),
49            ))
50            .max_width(200),
51        )
52        .width(Length::Fill)
53        .align_x(Align::Center);
54
55        let delete_button = Container::new(
56            Container::new(neat_button(
57                &mut self.delete_button,
58                i18n.get_msg("common-delete_server"),
59                FILL_FRAC_ONE,
60                button_style,
61                Some(Message::DeleteServer),
62            ))
63            .max_width(200),
64        )
65        .width(Length::Fill)
66        .align_x(Align::Center);
67
68        let mut list = Scrollable::new(&mut self.servers_list)
69            .spacing(8)
70            .align_items(Align::Start)
71            .width(Length::Fill)
72            .height(Length::Fill);
73
74        // Reset button states if servers were added / removed
75        if self.server_buttons.len() != servers.len() {
76            self.server_buttons = vec![Default::default(); servers.len()];
77        }
78
79        let list_items =
80            self.server_buttons
81                .iter_mut()
82                .zip(servers)
83                .enumerate()
84                .map(|(i, (state, server))| {
85                    let color = if Some(i) == selected_server_index {
86                        (97, 255, 18)
87                    } else {
88                        (97, 97, 25)
89                    };
90                    let button = Button::new(
91                        state,
92                        Row::with_children(vec![
93                            Space::new(Length::FillPortion(5), Length::Units(0)).into(),
94                            Text::new(server.as_ref())
95                                .size(fonts.cyri.scale(30))
96                                .width(Length::FillPortion(95))
97                                .vertical_alignment(iced::VerticalAlignment::Center)
98                                .into(),
99                        ]),
100                    )
101                    .style(
102                        style::button::Style::new(imgs.selection)
103                            .hover_image(imgs.selection_hover)
104                            .press_image(imgs.selection_press)
105                            .image_color(vek::Rgba::new(color.0, color.1, color.2, 255)),
106                    )
107                    .min_height(100)
108                    .on_press(Message::ServerChanged(i));
109                    Row::with_children(vec![
110                        Space::new(Length::FillPortion(3), Length::Units(0)).into(),
111                        button.width(Length::FillPortion(92)).into(),
112                        Space::new(Length::FillPortion(5), Length::Units(0)).into(),
113                    ])
114                });
115
116        for item in list_items {
117            list = list.push(item);
118        }
119
120        Container::new(
121            Container::new(
122                Column::with_children(vec![
123                    title.into(),
124                    list.into(),
125                    Row::with_children(vec![delete_button.into(), back_button.into()])
126                        .width(Length::Fill)
127                        .into(),
128                ])
129                .width(Length::Fill)
130                .height(Length::Fill)
131                .spacing(10)
132                .padding(20),
133            )
134            .style(
135                style::container::Style::color_with_double_cornerless_border(
136                    (22, 18, 16, 255).into(),
137                    (11, 11, 11, 255).into(),
138                    (54, 46, 38, 255).into(),
139                ),
140            )
141            .max_width(500),
142        )
143        .width(Length::Fill)
144        .align_x(Align::Center)
145        .padding(80)
146        .into()
147    }
148}