use bevy::{color::palettes::css::WHITE, prelude::*};
pub struct ButtonTransitionsPlugin;
impl Plugin for ButtonTransitionsPlugin {
fn build(&self, app: &mut bevy::prelude::App) {
app.register_type::<ButtonTransition>()
.register_type::<Interactable>()
.add_systems(Update, update_button_interactions);
}
}
#[derive(Component, Reflect)]
#[reflect(Component)]
#[require(Button, Interactable, ImageNode)]
pub enum ButtonTransition {
ColorTint(ColorTint),
ImageSwap(ImageSwap),
}
#[derive(Reflect)]
pub struct ColorTint {
pub normal_color: Color,
pub hovered_color: Color,
pub pressed_color: Color,
pub disabled_color: Color,
}
impl Default for ColorTint {
fn default() -> Self {
ColorTint {
normal_color: WHITE.into(),
hovered_color: Color::srgba(0.9607843, 0.9607843, 0.9607843, 1.0),
pressed_color: Color::srgba(0.7843137, 0.7843137, 0.7843137, 1.0),
disabled_color: Color::srgba(0.7843137, 0.7843137, 0.7843137, 0.5019608),
}
}
}
#[derive(Reflect)]
pub struct ImageSwap {
pub normal_image: Handle<Image>,
pub hovered_image: Handle<Image>,
pub pressed_image: Handle<Image>,
pub disabled_image: Handle<Image>,
}
#[derive(Component, Deref, DerefMut, Reflect)]
#[reflect(Component)]
pub struct Interactable(pub bool);
impl Default for Interactable {
fn default() -> Self {
Interactable(true)
}
}
fn update_button_interactions(
mut query: Query<(
&mut ImageNode,
&Interactable,
&ButtonTransition,
&Interaction,
)>,
) {
for (mut image_node, interactable, transition, interaction) in &mut query {
match transition {
ButtonTransition::ColorTint(tint) => {
let color = if !interactable.0 {
tint.disabled_color
} else {
match interaction {
Interaction::Hovered => tint.hovered_color,
Interaction::Pressed => tint.pressed_color,
Interaction::None => tint.normal_color,
}
};
image_node.color = color;
}
ButtonTransition::ImageSwap(swap) => {
let image = if !interactable.0 {
swap.disabled_image.clone()
} else {
match interaction {
Interaction::Hovered => swap.hovered_image.clone(),
Interaction::Pressed => swap.pressed_image.clone(),
Interaction::None => swap.normal_image.clone(),
}
};
image_node.image = image;
}
}
}
}