veloren_voxygen/menu/main/ui/
credits.rs

1use super::Message;
2use crate::{
3    credits::Credits,
4    ui::{
5        fonts::IcedFonts as Fonts,
6        ice::{Element, component::neat_button, style},
7    },
8};
9use i18n::Localization;
10use iced::{Column, Container, HorizontalAlignment, Length, Scrollable, Space, button, scrollable};
11
12/// Connecting screen for the main menu
13pub struct Screen {
14    back_button: button::State,
15    scroll: scrollable::State,
16}
17
18impl Screen {
19    pub fn new() -> Self {
20        Self {
21            back_button: Default::default(),
22            scroll: Default::default(),
23        }
24    }
25
26    pub(super) fn view(
27        &mut self,
28        fonts: &Fonts,
29        i18n: &Localization,
30        credits: &Credits,
31        button_style: style::button::Style,
32    ) -> Element<'_, Message> {
33        use core::fmt::Write;
34        let format_art_credit = |credit: &crate::credits::Art| -> Result<String, core::fmt::Error> {
35            let mut text = String::new();
36            write!(&mut text, "\"{}\"", &credit.name)?;
37
38            let mut authors = credit.authors.iter();
39            if let Some(author) = authors.next() {
40                write!(
41                    &mut text,
42                    " {} {}",
43                    i18n.get_msg("main-credits-created_by"),
44                    author
45                )?;
46            }
47            authors.try_for_each(|author| write!(&mut text, ", {}", author))?;
48
49            if !credit.license.is_empty() {
50                write!(&mut text, " ({})", &credit.license)?;
51            }
52
53            Ok::<_, core::fmt::Error>(text)
54        };
55        let format_sounds_credit =
56            |credit: &crate::credits::Sounds| -> Result<String, core::fmt::Error> {
57                let mut text = String::new();
58                let mut authors = credit.authors.iter();
59
60                if let Some(author) = authors.next() {
61                    write!(&mut text, "{}", author)?;
62                }
63                authors.try_for_each(|author| write!(&mut text, ", {}", author))?;
64
65                if !credit.license.is_empty() {
66                    write!(&mut text, " ({})", &credit.license)?;
67                }
68
69                Ok::<_, core::fmt::Error>(text)
70            };
71        let format_contributor_credit =
72            |credit: &crate::credits::Contributor| -> Result<String, core::fmt::Error> {
73                let mut text = String::new();
74                text.push_str(&credit.name);
75
76                if !credit.contributions.is_empty() {
77                    write!(&mut text, "- {}", &credit.contributions)?;
78                }
79
80                Ok(text)
81            };
82
83        let music_header_color = iced::Color::from_rgb8(0xfc, 0x71, 0x76);
84        let fonts_header_color = iced::Color::from_rgb8(0xf7, 0xd1, 0x81);
85        let other_art_header_color = iced::Color::from_rgb8(0xc5, 0xe9, 0x80);
86        let contributors_header_color = iced::Color::from_rgb8(0x4a, 0xa6, 0x7b);
87
88        fn credit_section<'a, T>(
89            header_i18n_key: &str,
90            header_color: iced::Color,
91            credit_iter: impl Iterator<Item = T>,
92            format_credit: impl Fn(T) -> Result<String, core::fmt::Error>,
93            fonts: &Fonts,
94            i18n: &Localization,
95        ) -> Element<'a, Message> {
96            Column::with_children(
97                core::iter::once(
98                    iced::Text::new(i18n.get_msg(header_i18n_key))
99                        .font(fonts.cyri.id)
100                        .size(fonts.cyri.scale(30))
101                        .color(header_color)
102                        .width(Length::Fill)
103                        .horizontal_alignment(HorizontalAlignment::Center)
104                        .into(),
105                )
106                .chain(credit_iter.map(|credit| {
107                    let text = format_credit(credit).expect("Formatting failed!!!");
108                    iced::Text::new(text)
109                        .font(fonts.cyri.id)
110                        .size(fonts.cyri.scale(23))
111                        .width(Length::Fill)
112                        .horizontal_alignment(HorizontalAlignment::Center)
113                        .into()
114                }))
115                .chain(core::iter::once(
116                    Space::new(Length::Fill, Length::Units(15)).into(),
117                ))
118                .collect(),
119            )
120            .width(Length::Fill)
121            .into()
122        }
123
124        let art_section = |header_i18n_key, header_color, art: &[_]| {
125            credit_section(
126                header_i18n_key,
127                header_color,
128                art.iter(),
129                format_art_credit,
130                fonts,
131                i18n,
132            )
133        };
134
135        let sounds_section = |header_i18n_key, header_color, art: &[_]| {
136            credit_section(
137                header_i18n_key,
138                header_color,
139                art.iter(),
140                format_sounds_credit,
141                fonts,
142                i18n,
143            )
144        };
145
146        Container::new(
147            Container::new(
148                Column::with_children(vec![
149                    iced::Text::new(i18n.get_msg("main-credits"))
150                        .font(fonts.cyri.id)
151                        .size(fonts.cyri.scale(35))
152                        .width(Length::Fill)
153                        .horizontal_alignment(HorizontalAlignment::Center)
154                        .into(),
155                    Space::new(Length::Fill, Length::Units(25)).into(),
156                    Scrollable::new(&mut self.scroll)
157                        .push(art_section(
158                            "main-credits-music",
159                            music_header_color,
160                            &credits.music,
161                        ))
162                        .push(sounds_section(
163                            "main-credits-sound",
164                            music_header_color,
165                            &credits.sounds,
166                        ))
167                        .push(art_section(
168                            "main-credits-fonts",
169                            fonts_header_color,
170                            &credits.fonts,
171                        ))
172                        .push(art_section(
173                            "main-credits-other_art",
174                            other_art_header_color,
175                            &credits.other_art,
176                        ))
177                        .push(credit_section(
178                            "main-credits-contributors",
179                            contributors_header_color,
180                            credits.contributors.iter(),
181                            format_contributor_credit,
182                            fonts,
183                            i18n,
184                        ))
185                        .height(Length::FillPortion(1))
186                        .width(Length::Fill)
187                        .into(),
188                    Container::new(
189                        Container::new(neat_button(
190                            &mut self.back_button,
191                            i18n.get_msg("common-back"),
192                            0.7,
193                            button_style,
194                            Some(Message::Back),
195                        ))
196                        .height(Length::Units(fonts.cyri.scale(50))),
197                    )
198                    .center_x()
199                    .height(Length::Shrink)
200                    .width(Length::Fill)
201                    .into(),
202                ])
203                .spacing(5)
204                .padding(20)
205                .width(Length::Fill)
206                .height(Length::Fill),
207            )
208            .style(
209                style::container::Style::color_with_double_cornerless_border(
210                    (22, 19, 17, 255).into(),
211                    (11, 11, 11, 255).into(),
212                    (54, 46, 38, 255).into(),
213                ),
214            ),
215        )
216        .center_x()
217        .center_y()
218        .padding(70)
219        .width(Length::Fill)
220        .height(Length::Fill)
221        .into()
222    }
223}