1use super::{
2 BLACK, TEXT_COLOR,
3 img_ids::{Imgs, ImgsRot},
4};
5use crate::{
6 GlobalState,
7 game_input::GameInput,
8 ui::{ImageFrame, Tooltip, TooltipManager, Tooltipable, fonts::Fonts},
9 window::KeyMouse,
10};
11use conrod_core::{
12 Color, Colorable, Positionable, Sizeable, UiCell, Widget, WidgetCommon,
13 widget::{self, Button, Text, UpdateArgs},
14 widget_ids,
15};
16use i18n::Localization;
17widget_ids! {
18 struct Ids {
19 bag_show_map,
20 map_button,
21 map_text,
22 map_text_bg,
23 settings_button,
24 settings_text,
25 settings_text_bg,
26 social_button,
27 social_button_bg,
28 social_text,
29 social_text_bg,
30 spellbook_button,
31 spellbook_button_bg,
32 spellbook_text,
33 spellbook_text_bg,
34 crafting_button,
35 crafting_button_bg,
36 crafting_text,
37 crafting_text_bg,
38 group_button,
39 sp_arrow,
40 sp_arrow_txt_bg,
41 sp_arrow_txt,
42 }
43}
44#[derive(WidgetCommon)]
45pub struct Buttons<'a> {
46 imgs: &'a Imgs,
47 fonts: &'a Fonts,
48 #[conrod(common_builder)]
49 common: widget::CommonBuilder,
50 global_state: &'a GlobalState,
51 rot_imgs: &'a ImgsRot,
52 tooltip_manager: &'a mut TooltipManager,
53 localized_strings: &'a Localization,
54}
55
56impl<'a> Buttons<'a> {
57 pub fn new(
58 imgs: &'a Imgs,
59 fonts: &'a Fonts,
60 global_state: &'a GlobalState,
61 rot_imgs: &'a ImgsRot,
62 tooltip_manager: &'a mut TooltipManager,
63 localized_strings: &'a Localization,
64 ) -> Self {
65 Self {
66 imgs,
67 fonts,
68 common: widget::CommonBuilder::default(),
69 global_state,
70 rot_imgs,
71 tooltip_manager,
72 localized_strings,
73 }
74 }
75}
76
77pub struct State {
78 ids: Ids,
79}
80
81#[expect(clippy::enum_variant_names)] pub enum Event {
83 ToggleSettings,
84 ToggleMap,
85 ToggleSocial,
86 ToggleCrafting,
87}
88
89impl Widget for Buttons<'_> {
90 type Event = Option<Event>;
91 type State = State;
92 type Style = ();
93
94 fn init_state(&self, id_gen: widget::id::Generator) -> Self::State {
95 State {
96 ids: Ids::new(id_gen),
97 }
98 }
99
100 fn style(&self) -> Self::Style {}
101
102 fn update(self, args: UpdateArgs<Self>) -> Self::Event {
103 common_base::prof_span!("Buttons::update");
104 let UpdateArgs { state, ui, .. } = args;
105 let localized_strings = self.localized_strings;
106
107 let button_tooltip = Tooltip::new({
108 let edge = &self.rot_imgs.tt_side;
111 let corner = &self.rot_imgs.tt_corner;
112 ImageFrame::new(
113 [edge.cw180, edge.none, edge.cw270, edge.cw90],
114 [corner.none, corner.cw270, corner.cw90, corner.cw180],
115 Color::Rgba(0.08, 0.07, 0.04, 1.0),
116 5.0,
117 )
118 })
119 .title_font_size(self.fonts.cyri.scale(15))
120 .parent(ui.window)
121 .desc_font_size(self.fonts.cyri.scale(12))
122 .font_id(self.fonts.cyri.conrod_id)
123 .desc_text_color(TEXT_COLOR);
124
125 if Button::image(self.imgs.settings)
127 .w_h(29.0, 25.0)
128 .bottom_right_with_margins_on(ui.window, 5.0, 5.0)
129 .hover_image(self.imgs.settings_hover)
130 .press_image(self.imgs.settings_press)
131 .with_tooltip(
132 self.tooltip_manager,
133 &localized_strings.get_msg("common-settings"),
134 "",
135 &button_tooltip,
136 TEXT_COLOR,
137 )
138 .set(state.ids.settings_button, ui)
139 .was_clicked()
140 {
141 return Some(Event::ToggleSettings);
142 };
143 if let Some(settings) = &self
144 .global_state
145 .settings
146 .controls
147 .get_binding(GameInput::Settings)
148 {
149 self.create_new_button_with_shadow(
150 ui,
151 settings,
152 state.ids.settings_button,
153 state.ids.settings_text_bg,
154 state.ids.settings_text,
155 );
156 };
157
158 if Button::image(self.imgs.social)
160 .w_h(25.0, 25.0)
161 .left_from(state.ids.settings_button, 10.0)
162 .hover_image(self.imgs.social_hover)
163 .press_image(self.imgs.social_press)
164 .with_tooltip(
165 self.tooltip_manager,
166 &localized_strings.get_msg("hud-social"),
167 "",
168 &button_tooltip,
169 TEXT_COLOR,
170 )
171 .set(state.ids.social_button, ui)
172 .was_clicked()
173 {
174 return Some(Event::ToggleSocial);
175 }
176 if let Some(social) = &self
177 .global_state
178 .settings
179 .controls
180 .get_binding(GameInput::Social)
181 {
182 self.create_new_button_with_shadow(
183 ui,
184 social,
185 state.ids.social_button,
186 state.ids.social_text_bg,
187 state.ids.social_text,
188 );
189 };
190 if Button::image(self.imgs.map_button)
192 .w_h(22.0, 25.0)
193 .left_from(state.ids.social_button, 10.0)
194 .hover_image(self.imgs.map_hover)
195 .press_image(self.imgs.map_press)
196 .with_tooltip(
197 self.tooltip_manager,
198 &localized_strings.get_msg("hud-map-map_title"),
199 "",
200 &button_tooltip,
201 TEXT_COLOR,
202 )
203 .set(state.ids.map_button, ui)
204 .was_clicked()
205 {
206 return Some(Event::ToggleMap);
207 };
208 if let Some(map) = &self
209 .global_state
210 .settings
211 .controls
212 .get_binding(GameInput::Map)
213 {
214 self.create_new_button_with_shadow(
215 ui,
216 map,
217 state.ids.map_button,
218 state.ids.map_text_bg,
219 state.ids.map_text,
220 );
221 }
222
223 if Button::image(self.imgs.crafting_icon)
225 .w_h(25.0, 25.0)
226 .left_from(state.ids.map_button, 10.0)
227 .hover_image(self.imgs.crafting_icon_hover)
228 .press_image(self.imgs.crafting_icon_press)
229 .with_tooltip(
230 self.tooltip_manager,
231 &localized_strings.get_msg("hud-crafting"),
232 "",
233 &button_tooltip,
234 TEXT_COLOR,
235 )
236 .set(state.ids.crafting_button, ui)
237 .was_clicked()
238 {
239 return Some(Event::ToggleCrafting);
240 }
241 if let Some(crafting) = &self
242 .global_state
243 .settings
244 .controls
245 .get_binding(GameInput::Crafting)
246 {
247 self.create_new_button_with_shadow(
248 ui,
249 crafting,
250 state.ids.crafting_button,
251 state.ids.crafting_text_bg,
252 state.ids.crafting_text,
253 );
254 }
255
256 None
257 }
258}
259
260impl Buttons<'_> {
261 fn create_new_button_with_shadow(
262 &self,
263 ui: &mut UiCell,
264 key_mouse: &KeyMouse,
265 button_identifier: widget::Id,
266 text_background: widget::Id,
267 text: widget::Id,
268 ) {
269 let key_layout = &self.global_state.window.key_layout;
270 let key_desc = key_mouse.display_shortest(key_layout);
271
272 Text::new(&key_desc)
274 .bottom_right_with_margins_on(button_identifier, 0.0, 0.0)
275 .font_size(10)
276 .font_id(self.fonts.cyri.conrod_id)
277 .color(BLACK)
278 .set(text_background, ui);
279
280 Text::new(&key_desc)
282 .bottom_right_with_margins_on(text_background, 1.0, 1.0)
283 .font_size(10)
284 .font_id(self.fonts.cyri.conrod_id)
285 .color(TEXT_COLOR)
286 .set(text, ui);
287 }
288}