Files
pomomon-garden/src/features/hud/mod.rs
2025-12-01 15:20:31 +01:00

165 lines
5.6 KiB
Rust

use crate::features::phase::components::TimerSettings;
use crate::features::savegame::messages::SavegameDumpMessage;
use crate::features::{inventory, shop};
use crate::prelude::*;
use components::*;
use ui::*;
pub mod components;
pub mod ui;
pub struct HudPlugin;
impl Plugin for HudPlugin {
fn build(&self, app: &mut App) {
app.add_systems(OnEnter(AppState::GameScreen), setup);
app.add_systems(OnExit(AppState::GameScreen), cleanup);
app.add_systems(
Update,
(update_status, buttons, update_timer_settings).run_if(in_state(AppState::GameScreen)),
);
}
}
fn setup(mut commands: Commands) {
commands.spawn((
RootMarker::Status,
Node {
position_type: PositionType::Absolute,
bottom: px(0),
left: px(0),
width: percent(100),
height: px(50),
justify_content: JustifyContent::SpaceAround,
align_items: AlignItems::Center,
flex_direction: FlexDirection::Row,
..default()
},
BackgroundColor(Color::srgba(0.0, 0.0, 0.0, 0.8)),
children![
text_with_component(TextType::Phase, "...", 16.0, Color::WHITE),
text_with_component(TextType::Timer, "...", 16.0, Color::WHITE),
button(
shop::components::ButtonType::ShopOpen,
ButtonVariant::Secondary,
Node {
padding: UiRect::all(px(10)),
..default()
},
|color| text("Shop [P]", 16.0, color)
),
button(
inventory::components::ButtonType::InventoryOpen,
ButtonVariant::Secondary,
Node {
padding: UiRect::all(px(10)),
..default()
},
|color| text("Inventar", 16.0, color)
),
button(
ButtonType::SettingsOpen,
ButtonVariant::Secondary,
Node {
padding: UiRect::all(px(10)),
..default()
},
|color| text("Einstellungen", 16.0, color)
)
],
));
}
fn update_status(phase_res: Res<CurrentPhase>, mut text_query: Query<(&mut Text, &TextType)>) {
if !phase_res.is_changed() {
return;
}
let current_phase = &phase_res.0;
for (mut text, status_type) in text_query.iter_mut() {
text.0 = match status_type {
TextType::Phase => current_phase.display_name().into(),
TextType::Timer => current_phase.format_duration(),
};
}
}
fn buttons(
mut commands: Commands,
mut interaction_query: Query<(&Interaction, &ButtonType), (Changed<Interaction>, With<Button>)>,
root_query: Query<(Entity, &RootMarker)>,
mut savegame_messages: MessageWriter<SavegameDumpMessage>,
mut next_state: ResMut<NextState<AppState>>,
mut timer_settings: ResMut<TimerSettings>,
) {
for (interaction, button_type) in &mut interaction_query {
match *interaction {
Interaction::Pressed => match button_type {
ButtonType::SettingsOpen => {
open_settings(&mut commands);
}
ButtonType::SettingsClose => {
for (entity, root) in root_query.iter() {
match *root {
RootMarker::Settings => commands.entity(entity).despawn(),
_ => {}
}
}
}
ButtonType::SettingsExit => {
savegame_messages.write(SavegameDumpMessage);
next_state.set(AppState::StartScreen);
}
ButtonType::SettingsSave => {
savegame_messages.write(SavegameDumpMessage);
}
ButtonType::SettingsTimerChange { input, amount } => match input {
SettingsTimerInput::Minutes(timer_type) => {
timer_settings.change(timer_type, 60 * amount)
}
SettingsTimerInput::Seconds(timer_type) => {
timer_settings.change(timer_type, *amount)
}
},
},
_ => {}
}
}
}
fn cleanup(mut commands: Commands, query: Query<Entity, With<RootMarker>>) {
for entity in query.iter() {
commands.entity(entity).despawn();
}
}
fn update_timer_settings(
timer_settings: ResMut<TimerSettings>,
mut query: Query<(&SettingsTimerInput, &mut Text)>,
) {
for (input_type, mut text) in query.iter_mut() {
match input_type {
SettingsTimerInput::Minutes(timer_type) => {
let value = match timer_type {
TimerType::Focus => timer_settings.focus_duration,
TimerType::ShortBreak => timer_settings.short_break_duration,
TimerType::LongBreak => timer_settings.long_break_duration,
} as f32;
text.0 = format!("{:0>2}", (value / 60.0).floor());
}
SettingsTimerInput::Seconds(timer_type) => {
let value = match timer_type {
TimerType::Focus => timer_settings.focus_duration,
TimerType::ShortBreak => timer_settings.short_break_duration,
TimerType::LongBreak => timer_settings.long_break_duration,
};
text.0 = format!("{:0>2}", (value % 60));
}
}
}
}