use bevy::prelude::*; fn main() { App::build() .add_default_plugins() .init_resource::() .add_startup_system(setup.system()) .add_system(button_system.system()) .run(); } struct ButtonMaterials { normal: Handle, hovered: Handle, pressed: Handle, } impl FromResources for ButtonMaterials { fn from_resources(resources: &Resources) -> Self { let mut materials = resources.get_mut::>().unwrap(); ButtonMaterials { normal: materials.add(Color::rgb(0.02, 0.02, 0.02).into()), hovered: materials.add(Color::rgb(0.05, 0.05, 0.05).into()), pressed: materials.add(Color::rgb(0.1, 0.5, 0.1).into()), } } } fn button_system( button_materials: Res, mut click_query: Query<( &Button, Mutated, Option<&Hover>, &mut Handle, &Children, )>, mut hover_query: Query<( &Button, Mutated, Option<&Click>, &mut Handle, &Children, )>, text_query: Query<&mut Text>, ) { for (_button, hover, click, mut material, children) in &mut hover_query.iter() { let mut text = text_query.get_mut::(children[0]).unwrap(); match *hover { Hover::Hovered => { if let Some(Click::Released) = click { text.value = "Hover".to_string(); *material = button_materials.hovered; } } Hover::NotHovered => { if let Some(Click::Pressed) = click { text.value = "Press".to_string(); *material = button_materials.pressed; } else { text.value = "Button".to_string(); *material = button_materials.normal; } } } } for (_button, click, hover, mut material, children) in &mut click_query.iter() { let mut text = text_query.get_mut::(children[0]).unwrap(); match *click { Click::Pressed => { text.value = "Press".to_string(); *material = button_materials.pressed; } Click::Released => { if let Some(Hover::Hovered) = hover { text.value = "Hover".to_string(); *material = button_materials.hovered; } else { text.value = "Button".to_string(); *material = button_materials.normal; } } } } } fn setup( mut commands: Commands, asset_server: Res, button_materials: Res, ) { commands // ui camera .spawn(Camera2dComponents::default()) .spawn(ButtonComponents { node: Node::new(Anchors::CENTER, Margins::new(-75.0, 75.0, -35.0, 35.0)), material: button_materials.normal, ..Default::default() }) .with_children(|parent| { parent.spawn(TextComponents { node: Node::new(Anchors::FULL, Margins::new(0.0, 0.0, 12.0, 0.0)), text: Text { value: "Button".to_string(), font: asset_server.load("assets/fonts/FiraSans-Bold.ttf").unwrap(), style: TextStyle { font_size: 40.0, color: Color::rgb(0.8, 0.8, 0.8), align: TextAlign::Center, }, }, ..Default::default() }); }); }