/*
* Copyright (C) 2025 Jonni Liljamo <jonni@liljamo.com>
*
* This file is licensed under MIT, see LICENSE for more information.
*/
use bevy::{color::palettes::tailwind::*, prelude::*};
const THROW_COLOR: Srgba = LIME_400;
const DESPAWN_COLOR: Srgba = RED_400;
pub struct UIPlugin;
impl Plugin for UIPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Startup, setup)
.add_systems(Update, button_interaction);
app.add_event::<ThrowPressed>()
.add_event::<DespawnPressed>();
}
}
#[derive(Component)]
enum ButtonFunction {
Throw,
Despawn,
}
#[derive(Event)]
pub struct ThrowPressed;
#[derive(Event)]
pub struct DespawnPressed;
fn setup(mut commands: Commands) {
commands.spawn((
Node {
width: Val::Percent(100.0),
height: Val::Percent(100.0),
flex_direction: FlexDirection::Row,
align_items: AlignItems::FlexEnd,
justify_content: JustifyContent::SpaceEvenly,
padding: UiRect::all(Val::Px(8.0)),
overflow: Overflow::scroll_y(),
..Default::default()
},
children![
(
ButtonFunction::Throw,
Button,
Node {
width: Val::Px(180.0),
height: Val::Px(60.0),
border: UiRect::all(Val::Px(2.0)),
flex_direction: FlexDirection::Column,
justify_content: JustifyContent::Center,
align_items: AlignItems::Center,
margin: UiRect::bottom(Val::Px(4.0)),
..Default::default()
},
BackgroundColor(Color::from(THROW_COLOR)),
BorderColor(Color::from(LIME_700)),
BorderRadius::all(Val::Px(10.0)),
BoxShadow::new(
Color::BLACK.with_alpha(0.8),
Val::Px(4.0),
Val::Px(4.0),
Val::DEFAULT,
Val::DEFAULT,
),
children![(
Text::new("Throw"),
TextFont {
font_size: 18.0,
..Default::default()
},
TextColor(Color::BLACK),
),],
),
(
ButtonFunction::Despawn,
Button,
Node {
width: Val::Px(180.0),
height: Val::Px(60.0),
border: UiRect::all(Val::Px(2.0)),
flex_direction: FlexDirection::Column,
justify_content: JustifyContent::Center,
align_items: AlignItems::Center,
margin: UiRect::bottom(Val::Px(4.0)),
..Default::default()
},
BackgroundColor(Color::from(DESPAWN_COLOR)),
BorderColor(Color::from(RED_700)),
BorderRadius::all(Val::Px(10.0)),
BoxShadow::new(
Color::BLACK.with_alpha(0.8),
Val::Px(4.0),
Val::Px(4.0),
Val::DEFAULT,
Val::DEFAULT,
),
children![(
Text::new("Despawn Dice"),
TextFont {
font_size: 18.0,
..Default::default()
},
TextColor(Color::BLACK),
),],
),
],
));
}
fn button_interaction(
mut commands: Commands,
q_interaction: Query<
(&Interaction, &mut BackgroundColor, &ButtonFunction),
(Changed<Interaction>, With<Button>),
>,
) {
for (interaction, mut background, function) in q_interaction {
let color = match function {
ButtonFunction::Throw => THROW_COLOR,
ButtonFunction::Despawn => DESPAWN_COLOR,
};
match *interaction {
Interaction::Pressed => {
match function {
ButtonFunction::Throw => commands.trigger(ThrowPressed),
ButtonFunction::Despawn => commands.trigger(DespawnPressed),
};
*background = color.darker(0.3).into();
}
Interaction::Hovered => {
*background = color.darker(0.1).into();
}
Interaction::None => {
*background = color.into();
}
}
}
}