ui_texture_slice/
ui_texture_slice.rs

1//! This example illustrates how to create buttons with their textures sliced
2//! and kept in proportion instead of being stretched by the button dimensions
3
4use bevy::{
5    color::palettes::css::{GOLD, ORANGE},
6    prelude::*,
7    ui::widget::NodeImageMode,
8};
9
10fn main() {
11    App::new()
12        .add_plugins(DefaultPlugins)
13        .add_systems(Startup, setup)
14        .add_systems(Update, button_system)
15        .run();
16}
17
18fn button_system(
19    mut interaction_query: Query<
20        (&Interaction, &Children, &mut ImageNode),
21        (Changed<Interaction>, With<Button>),
22    >,
23    mut text_query: Query<&mut Text>,
24) {
25    for (interaction, children, mut image) in &mut interaction_query {
26        let mut text = text_query.get_mut(children[0]).unwrap();
27        match *interaction {
28            Interaction::Pressed => {
29                **text = "Press".to_string();
30                image.color = GOLD.into();
31            }
32            Interaction::Hovered => {
33                **text = "Hover".to_string();
34                image.color = ORANGE.into();
35            }
36            Interaction::None => {
37                **text = "Button".to_string();
38                image.color = Color::WHITE;
39            }
40        }
41    }
42}
43
44fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
45    let image = asset_server.load("textures/fantasy_ui_borders/panel-border-010.png");
46
47    let slicer = TextureSlicer {
48        border: BorderRect::all(22.0),
49        center_scale_mode: SliceScaleMode::Stretch,
50        sides_scale_mode: SliceScaleMode::Stretch,
51        max_corner_scale: 1.0,
52    };
53    // ui camera
54    commands.spawn(Camera2d);
55    commands
56        .spawn(Node {
57            width: percent(100),
58            height: percent(100),
59            align_items: AlignItems::Center,
60            justify_content: JustifyContent::Center,
61            ..default()
62        })
63        .with_children(|parent| {
64            for [w, h] in [[150.0, 150.0], [300.0, 150.0], [150.0, 300.0]] {
65                parent
66                    .spawn((
67                        Button,
68                        ImageNode {
69                            image: image.clone(),
70                            image_mode: NodeImageMode::Sliced(slicer.clone()),
71                            ..default()
72                        },
73                        Node {
74                            width: px(w),
75                            height: px(h),
76                            // horizontally center child text
77                            justify_content: JustifyContent::Center,
78                            // vertically center child text
79                            align_items: AlignItems::Center,
80                            margin: UiRect::all(px(20)),
81                            ..default()
82                        },
83                    ))
84                    .with_child((
85                        Text::new("Button"),
86                        TextFont {
87                            font: asset_server.load("fonts/FiraSans-Bold.ttf"),
88                            font_size: 33.0,
89                            ..default()
90                        },
91                        TextColor(Color::srgb(0.9, 0.9, 0.9)),
92                    ));
93            }
94        });
95}