bevy/examples/ui/ui_texture_atlas_slice.rs
VitalyR eb19a9ea0b
Migrate UI bundles to required components (#15898)
# Objective

- Migrate UI bundles to required components, fixes #15889

## Solution

- deprecate `NodeBundle` in favor of `Node`
- deprecate `ImageBundle` in favor of `UiImage`
- deprecate `ButtonBundle` in favor of `Button`

## Testing

CI.

## Migration Guide

- Replace all uses of `NodeBundle` with `Node`. e.g.
```diff
     commands
-        .spawn(NodeBundle {
-            style: Style {
+        .spawn((
+            Node::default(),
+            Style {
                 width: Val::Percent(100.),
                 align_items: AlignItems::Center,
                 justify_content: JustifyContent::Center,
                 ..default()
             },
-            ..default()
-        })
+        ))
``` 
- Replace all uses of `ButtonBundle` with `Button`. e.g.
```diff
                     .spawn((
-                        ButtonBundle {
-                            style: Style {
-                                width: Val::Px(w),
-                                height: Val::Px(h),
-                                // horizontally center child text
-                                justify_content: JustifyContent::Center,
-                                // vertically center child text
-                                align_items: AlignItems::Center,
-                                margin: UiRect::all(Val::Px(20.0)),
-                                ..default()
-                            },
-                            image: image.clone().into(),
+                        Button,
+                        Style {
+                            width: Val::Px(w),
+                            height: Val::Px(h),
+                            // horizontally center child text
+                            justify_content: JustifyContent::Center,
+                            // vertically center child text
+                            align_items: AlignItems::Center,
+                            margin: UiRect::all(Val::Px(20.0)),
                             ..default()
                         },
+                        UiImage::from(image.clone()),
                         ImageScaleMode::Sliced(slicer.clone()),
                     ))
```
- Replace all uses of `ImageBundle` with `UiImage`. e.g.
```diff
-    commands.spawn(ImageBundle {
-        image: UiImage {
+    commands.spawn((
+        UiImage {
             texture: metering_mask,
             ..default()
         },
-        style: Style {
+        Style {
             width: Val::Percent(100.0),
             height: Val::Percent(100.0),
             ..default()
         },
-        ..default()
-    });
+    ));
 ```

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2024-10-17 21:11:02 +00:00

115 lines
4 KiB
Rust

//! This example illustrates how to create buttons with their texture atlases sliced
//! and kept in proportion instead of being stretched by the button dimensions
use bevy::{
color::palettes::css::{GOLD, ORANGE},
prelude::*,
winit::WinitSettings,
};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
// Only run the app when there is user input. This will significantly reduce CPU/GPU use.
.insert_resource(WinitSettings::desktop_app())
.add_systems(Startup, setup)
.add_systems(Update, button_system)
.run();
}
fn button_system(
mut interaction_query: Query<
(&Interaction, &mut TextureAtlas, &Children, &mut UiImage),
(Changed<Interaction>, With<Button>),
>,
mut text_query: Query<&mut Text>,
) {
for (interaction, mut atlas, children, mut image) in &mut interaction_query {
let mut text = text_query.get_mut(children[0]).unwrap();
match *interaction {
Interaction::Pressed => {
**text = "Press".to_string();
atlas.index = (atlas.index + 1) % 30;
image.color = GOLD.into();
}
Interaction::Hovered => {
**text = "Hover".to_string();
image.color = ORANGE.into();
}
Interaction::None => {
**text = "Button".to_string();
image.color = Color::WHITE;
}
}
}
}
fn setup(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut texture_atlases: ResMut<Assets<TextureAtlasLayout>>,
) {
let texture_handle = asset_server.load("textures/fantasy_ui_borders/border_sheet.png");
let atlas_layout =
TextureAtlasLayout::from_grid(UVec2::new(50, 50), 6, 6, Some(UVec2::splat(2)), None);
let atlas_layout_handle = texture_atlases.add(atlas_layout);
let slicer = TextureSlicer {
border: BorderRect::square(24.0),
center_scale_mode: SliceScaleMode::Stretch,
sides_scale_mode: SliceScaleMode::Stretch,
max_corner_scale: 1.0,
};
// ui camera
commands.spawn(Camera2d);
commands
.spawn((
Node::default(),
Style {
width: Val::Percent(100.0),
height: Val::Percent(100.0),
align_items: AlignItems::Center,
justify_content: JustifyContent::Center,
..default()
},
))
.with_children(|parent| {
for (idx, [w, h]) in [
(0, [150.0, 150.0]),
(7, [300.0, 150.0]),
(13, [150.0, 300.0]),
] {
parent
.spawn((
Button,
UiImage::new(texture_handle.clone()),
Style {
width: Val::Px(w),
height: Val::Px(h),
// horizontally center child text
justify_content: JustifyContent::Center,
// vertically center child text
align_items: AlignItems::Center,
margin: UiRect::all(Val::Px(20.0)),
..default()
},
ImageScaleMode::Sliced(slicer.clone()),
TextureAtlas {
index: idx,
layout: atlas_layout_handle.clone(),
},
))
.with_children(|parent| {
parent.spawn((
Text::new("Button"),
TextFont {
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
font_size: 33.0,
..default()
},
TextColor(Color::srgb(0.9, 0.9, 0.9)),
));
});
}
});
}