veloren_voxygen/menu/main/ui/
credits.rs1use 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
12pub 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}