Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default button material behavior #1857

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions crates/bevy_ui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use bevy_math::{Rect, Size};
use bevy_render::RenderStage;
use bevy_transform::TransformSystem;
use update::ui_z_system;
use widget::DefaultButtonMaterials;

#[derive(Default)]
pub struct UiPlugin;
Expand All @@ -43,6 +44,7 @@ pub enum UiSystem {
impl Plugin for UiPlugin {
fn build(&self, app: &mut AppBuilder) {
app.init_resource::<FlexSurface>()
.init_resource::<DefaultButtonMaterials>()
.register_type::<AlignContent>()
.register_type::<AlignItems>()
.register_type::<AlignSelf>()
Expand Down Expand Up @@ -85,6 +87,14 @@ impl Plugin for UiPlugin {
.after(UiSystem::Flex)
.before(TransformSystem::TransformPropagate),
)
.add_system_to_stage(
CoreStage::PostUpdate,
widget::button_default_materials_system.system(),
)
.add_system_to_stage(
CoreStage::PostUpdate,
widget::button_materials_system.system(),
)
.add_system_to_stage(RenderStage::Draw, widget::draw_text_system.system());

crate::render::add_ui_graph(app.world_mut());
Expand Down
88 changes: 88 additions & 0 deletions crates/bevy_ui/src/widget/button.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,90 @@
use bevy_asset::{Assets, Handle};
use bevy_ecs::prelude::{Changed, FromWorld, Query, Res, With, Without, World};
use bevy_render::prelude::Color;
use bevy_sprite::ColorMaterial;

use crate::Interaction;

#[derive(Debug, Clone)]
pub struct Button;

#[derive(Debug, Clone)]
pub struct DefaultButtonMaterials {
pub normal: Handle<ColorMaterial>,
pub hovered: Handle<ColorMaterial>,
pub pressed: Handle<ColorMaterial>,
}

impl FromWorld for DefaultButtonMaterials {
fn from_world(world: &mut World) -> Self {
let mut materials = world.get_resource_mut::<Assets<ColorMaterial>>().unwrap();

DefaultButtonMaterials {
normal: materials.add(Color::rgb(0.15, 0.15, 0.15).into()),
hovered: materials.add(Color::rgb(0.25, 0.25, 0.25).into()),
pressed: materials.add(Color::rgb(0.35, 0.75, 0.35).into()),
}
}
}

#[derive(Debug, Clone)]
pub struct ButtonMaterials {
pub normal: Handle<ColorMaterial>,
pub hovered: Handle<ColorMaterial>,
pub pressed: Handle<ColorMaterial>,
}

#[derive(Debug, Clone)]
pub struct CustomButtonMaterialBehavior;

pub fn button_default_materials_system(
default_materials: Res<DefaultButtonMaterials>,
mut query: Query<
(&Interaction, &mut Handle<ColorMaterial>),
(
Changed<Interaction>,
With<Button>,
Without<ButtonMaterials>,
Without<CustomButtonMaterialBehavior>,
),
>,
) {
for (interaction, mut material) in query.iter_mut() {
match *interaction {
Interaction::None => {
*material = default_materials.normal.clone();
}
Interaction::Hovered => {
*material = default_materials.hovered.clone();
}
Interaction::Clicked => {
*material = default_materials.pressed.clone();
}
}
}
}

pub fn button_materials_system(
mut query: Query<
(&Interaction, &mut Handle<ColorMaterial>, &ButtonMaterials),
(
Changed<Interaction>,
With<Button>,
Without<CustomButtonMaterialBehavior>,
),
>,
) {
for (interaction, mut material, materials) in query.iter_mut() {
match *interaction {
Interaction::None => {
*material = materials.normal.clone();
}
Interaction::Hovered => {
*material = materials.hovered.clone();
}
Interaction::Clicked => {
*material = materials.pressed.clone();
}
}
}
}
43 changes: 6 additions & 37 deletions examples/ecs/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use bevy::prelude::*;
fn main() {
App::build()
.add_plugins(DefaultPlugins)
.init_resource::<ButtonMaterials>()
.add_state(AppState::Menu)
.add_system_set(SystemSet::on_enter(AppState::Menu).with_system(setup_menu.system()))
.add_system_set(SystemSet::on_update(AppState::Menu).with_system(menu.system()))
Expand All @@ -32,7 +31,7 @@ struct MenuData {
fn setup_menu(
mut commands: Commands,
asset_server: Res<AssetServer>,
button_materials: Res<ButtonMaterials>,
mut materials: ResMut<Assets<ColorMaterial>>,
) {
// ui camera
commands.spawn_bundle(UiCameraBundle::default());
Expand All @@ -48,7 +47,7 @@ fn setup_menu(
align_items: AlignItems::Center,
..Default::default()
},
material: button_materials.normal.clone(),
material: materials.add(Color::WHITE.into()),
..Default::default()
})
.with_children(|parent| {
Expand All @@ -71,24 +70,11 @@ fn setup_menu(

fn menu(
mut state: ResMut<State<AppState>>,
button_materials: Res<ButtonMaterials>,
mut interaction_query: Query<
(&Interaction, &mut Handle<ColorMaterial>),
(Changed<Interaction>, With<Button>),
>,
mut interaction_query: Query<&Interaction, (Changed<Interaction>, With<Button>)>,
) {
for (interaction, mut material) in interaction_query.iter_mut() {
match *interaction {
Interaction::Clicked => {
*material = button_materials.pressed.clone();
state.set(AppState::InGame).unwrap();
}
Interaction::Hovered => {
*material = button_materials.hovered.clone();
}
Interaction::None => {
*material = button_materials.normal.clone();
}
for interaction in interaction_query.iter_mut() {
if *interaction == Interaction::Clicked {
state.set(AppState::InGame).unwrap();
}
}
}
Expand Down Expand Up @@ -149,20 +135,3 @@ fn change_color(
.set_b((time.seconds_since_startup() * 5.0).sin() as f32 + 2.0);
}
}

struct ButtonMaterials {
normal: Handle<ColorMaterial>,
hovered: Handle<ColorMaterial>,
pressed: Handle<ColorMaterial>,
}

impl FromWorld for ButtonMaterials {
fn from_world(world: &mut World) -> Self {
let mut materials = world.get_resource_mut::<Assets<ColorMaterial>>().unwrap();
ButtonMaterials {
normal: materials.add(Color::rgb(0.15, 0.15, 0.15).into()),
hovered: materials.add(Color::rgb(0.25, 0.25, 0.25).into()),
pressed: materials.add(Color::rgb(0.35, 0.75, 0.35).into()),
}
}
}
Loading