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_contributor_credit =
56            |credit: &crate::credits::Contributor| -> Result<String, core::fmt::Error> {
57                let mut text = String::new();
58                text.push_str(&credit.name);
59
60                if !credit.contributions.is_empty() {
61                    write!(&mut text, "- {}", &credit.contributions)?;
62                }
63
64                Ok(text)
65            };
66
67        let music_header_color = iced::Color::from_rgb8(0xfc, 0x71, 0x76);
68        let fonts_header_color = iced::Color::from_rgb8(0xf7, 0xd1, 0x81);
69        let other_art_header_color = iced::Color::from_rgb8(0xc5, 0xe9, 0x80);
70        let contributors_header_color = iced::Color::from_rgb8(0x4a, 0xa6, 0x7b);
71
72        fn credit_section<'a, T>(
73            header_i18n_key: &str,
74            header_color: iced::Color,
75            credit_iter: impl Iterator<Item = T>,
76            format_credit: impl Fn(T) -> Result<String, core::fmt::Error>,
77            fonts: &Fonts,
78            i18n: &Localization,
79        ) -> Element<'a, Message> {
80            Column::with_children(
81                core::iter::once(
82                    iced::Text::new(i18n.get_msg(header_i18n_key))
83                        .font(fonts.cyri.id)
84                        .size(fonts.cyri.scale(30))
85                        .color(header_color)
86                        .width(Length::Fill)
87                        .horizontal_alignment(HorizontalAlignment::Center)
88                        .into(),
89                )
90                .chain(credit_iter.map(|credit| {
91                    let text = format_credit(credit).expect("Formatting failed!!!");
92                    iced::Text::new(text)
93                        .font(fonts.cyri.id)
94                        .size(fonts.cyri.scale(23))
95                        .width(Length::Fill)
96                        .horizontal_alignment(HorizontalAlignment::Center)
97                        .into()
98                }))
99                .chain(core::iter::once(
100                    Space::new(Length::Fill, Length::Units(15)).into(),
101                ))
102                .collect(),
103            )
104            .width(Length::Fill)
105            .into()
106        }
107
108        let art_section = |header_i18n_key, header_color, art: &[_]| {
109            credit_section(
110                header_i18n_key,
111                header_color,
112                art.iter(),
113                format_art_credit,
114                fonts,
115                i18n,
116            )
117        };
118
119        Container::new(
120            Container::new(
121                Column::with_children(vec![
122                    iced::Text::new(i18n.get_msg("main-credits"))
123                        .font(fonts.alkhemi.id)
124                        .size(fonts.alkhemi.scale(35))
125                        .width(Length::Fill)
126                        .horizontal_alignment(HorizontalAlignment::Center)
127                        .into(),
128                    Space::new(Length::Fill, Length::Units(25)).into(),
129                    Scrollable::new(&mut self.scroll)
130                        .push(art_section(
131                            "main-credits-music",
132                            music_header_color,
133                            &credits.music,
134                        ))
135                        .push(art_section(
136                            "main-credits-fonts",
137                            fonts_header_color,
138                            &credits.fonts,
139                        ))
140                        .push(art_section(
141                            "main-credits-other_art",
142                            other_art_header_color,
143                            &credits.other_art,
144                        ))
145                        .push(credit_section(
146                            "main-credits-contributors",
147                            contributors_header_color,
148                            credits.contributors.iter(),
149                            format_contributor_credit,
150                            fonts,
151                            i18n,
152                        ))
153                        .height(Length::FillPortion(1))
154                        .width(Length::Fill)
155                        .into(),
156                    Container::new(
157                        Container::new(neat_button(
158                            &mut self.back_button,
159                            i18n.get_msg("common-back"),
160                            0.7,
161                            button_style,
162                            Some(Message::Back),
163                        ))
164                        .height(Length::Units(fonts.cyri.scale(50))),
165                    )
166                    .center_x()
167                    .height(Length::Shrink)
168                    .width(Length::Fill)
169                    .into(),
170                ])
171                .spacing(5)
172                .padding(20)
173                .width(Length::Fill)
174                .height(Length::Fill),
175            )
176            .style(
177                style::container::Style::color_with_double_cornerless_border(
178                    (22, 19, 17, 255).into(),
179                    (11, 11, 11, 255).into(),
180                    (54, 46, 38, 255).into(),
181                ),
182            ),
183        )
184        .center_x()
185        .center_y()
186        .padding(70)
187        .width(Length::Fill)
188        .height(Length::Fill)
189        .into()
190    }
191}