mirror of
https://github.com/bevyengine/bevy
synced 2024-11-25 14:10:19 +00:00
Move TextureAtlas into UiImage and remove impl Component for TextureAtlas (#16072)
# Objective Fixes #16064 ## Solution - Add TextureAtlas to `UiImage::texture_atlas` - Add `TextureAtlas::from_atlas_image` for parity with `Sprite` - Rename `UiImage::texture` to `UiImage::image` for parity with `Sprite` - Port relevant implementations and uses - Remove `derive(Component)` for `TextureAtlas` --- ## Migration Guide Before: ```rust commands.spawn(( UiImage::new(image), TextureAtlas { index, layout }, )); ``` After: ```rust commands.spawn(UiImage::from_atlas_image(image, TextureAtlas { index, layout })); ``` Before: ```rust commands.spawn(UiImage { texture: some_image, ..default() }) ``` After: ```rust commands.spawn(UiImage { image: some_image, ..default() }) ```
This commit is contained in:
parent
2cdad48b30
commit
9274bfed27
10 changed files with 71 additions and 70 deletions
|
@ -1,5 +1,4 @@
|
||||||
use bevy_asset::{Asset, AssetId, Assets, Handle};
|
use bevy_asset::{Asset, AssetId, Assets, Handle};
|
||||||
use bevy_ecs::{component::Component, reflect::ReflectComponent};
|
|
||||||
use bevy_math::{URect, UVec2};
|
use bevy_math::{URect, UVec2};
|
||||||
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
|
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
|
||||||
#[cfg(feature = "serialize")]
|
#[cfg(feature = "serialize")]
|
||||||
|
@ -152,7 +151,7 @@ impl TextureAtlasLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component used to draw a specific section of a texture.
|
/// An index into a [`TextureAtlasLayout`], which corresponds to a specific section of a texture.
|
||||||
///
|
///
|
||||||
/// It stores a handle to [`TextureAtlasLayout`] and the index of the current section of the atlas.
|
/// It stores a handle to [`TextureAtlasLayout`] and the index of the current section of the atlas.
|
||||||
/// The texture atlas contains various *sections* of a given texture, allowing users to have a single
|
/// The texture atlas contains various *sections* of a given texture, allowing users to have a single
|
||||||
|
@ -164,8 +163,8 @@ impl TextureAtlasLayout {
|
||||||
/// - [`animated sprite sheet example`](https://github.com/bevyengine/bevy/blob/latest/examples/2d/sprite_sheet.rs)
|
/// - [`animated sprite sheet example`](https://github.com/bevyengine/bevy/blob/latest/examples/2d/sprite_sheet.rs)
|
||||||
/// - [`sprite animation event example`](https://github.com/bevyengine/bevy/blob/latest/examples/2d/sprite_animation.rs)
|
/// - [`sprite animation event example`](https://github.com/bevyengine/bevy/blob/latest/examples/2d/sprite_animation.rs)
|
||||||
/// - [`texture atlas example`](https://github.com/bevyengine/bevy/blob/latest/examples/2d/texture_atlas.rs)
|
/// - [`texture atlas example`](https://github.com/bevyengine/bevy/blob/latest/examples/2d/texture_atlas.rs)
|
||||||
#[derive(Component, Default, Debug, Clone, Reflect)]
|
#[derive(Default, Debug, Clone, Reflect)]
|
||||||
#[reflect(Component, Default, Debug)]
|
#[reflect(Default, Debug)]
|
||||||
pub struct TextureAtlas {
|
pub struct TextureAtlas {
|
||||||
/// Texture atlas layout handle
|
/// Texture atlas layout handle
|
||||||
pub layout: Handle<TextureAtlasLayout>,
|
pub layout: Handle<TextureAtlasLayout>,
|
||||||
|
|
|
@ -40,7 +40,7 @@ use bevy_render::{
|
||||||
ExtractSchedule, Render,
|
ExtractSchedule, Render,
|
||||||
};
|
};
|
||||||
use bevy_sprite::TextureAtlasLayout;
|
use bevy_sprite::TextureAtlasLayout;
|
||||||
use bevy_sprite::{BorderRect, ImageScaleMode, SpriteAssetEvents, TextureAtlas};
|
use bevy_sprite::{BorderRect, ImageScaleMode, SpriteAssetEvents};
|
||||||
|
|
||||||
use crate::{Display, Node};
|
use crate::{Display, Node};
|
||||||
use bevy_text::{ComputedTextBlock, PositionedGlyph, TextColor, TextLayoutInfo};
|
use bevy_text::{ComputedTextBlock, PositionedGlyph, TextColor, TextLayoutInfo};
|
||||||
|
@ -317,14 +317,13 @@ pub fn extract_uinode_images(
|
||||||
Option<&CalculatedClip>,
|
Option<&CalculatedClip>,
|
||||||
Option<&TargetCamera>,
|
Option<&TargetCamera>,
|
||||||
&UiImage,
|
&UiImage,
|
||||||
Option<&TextureAtlas>,
|
|
||||||
),
|
),
|
||||||
Without<ImageScaleMode>,
|
Without<ImageScaleMode>,
|
||||||
>,
|
>,
|
||||||
>,
|
>,
|
||||||
mapping: Extract<Query<RenderEntity>>,
|
mapping: Extract<Query<RenderEntity>>,
|
||||||
) {
|
) {
|
||||||
for (entity, uinode, transform, view_visibility, clip, camera, image, atlas) in &uinode_query {
|
for (entity, uinode, transform, view_visibility, clip, camera, image) in &uinode_query {
|
||||||
let Some(camera_entity) = camera.map(TargetCamera::entity).or(default_ui_camera.get())
|
let Some(camera_entity) = camera.map(TargetCamera::entity).or(default_ui_camera.get())
|
||||||
else {
|
else {
|
||||||
continue;
|
continue;
|
||||||
|
@ -337,12 +336,14 @@ pub fn extract_uinode_images(
|
||||||
// Skip invisible images
|
// Skip invisible images
|
||||||
if !view_visibility.get()
|
if !view_visibility.get()
|
||||||
|| image.color.is_fully_transparent()
|
|| image.color.is_fully_transparent()
|
||||||
|| image.texture.id() == TRANSPARENT_IMAGE_HANDLE.id()
|
|| image.image.id() == TRANSPARENT_IMAGE_HANDLE.id()
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let atlas_rect = atlas
|
let atlas_rect = image
|
||||||
|
.texture_atlas
|
||||||
|
.as_ref()
|
||||||
.and_then(|s| s.texture_rect(&texture_atlases))
|
.and_then(|s| s.texture_rect(&texture_atlases))
|
||||||
.map(|r| r.as_rect());
|
.map(|r| r.as_rect());
|
||||||
|
|
||||||
|
@ -376,7 +377,7 @@ pub fn extract_uinode_images(
|
||||||
color: image.color.into(),
|
color: image.color.into(),
|
||||||
rect,
|
rect,
|
||||||
clip: clip.map(|clip| clip.clip),
|
clip: clip.map(|clip| clip.clip),
|
||||||
image: image.texture.id(),
|
image: image.image.id(),
|
||||||
camera_entity: render_camera_entity,
|
camera_entity: render_camera_entity,
|
||||||
item: ExtractedUiItem::Node {
|
item: ExtractedUiItem::Node {
|
||||||
atlas_scaling,
|
atlas_scaling,
|
||||||
|
|
|
@ -24,8 +24,7 @@ use bevy_render::{
|
||||||
Extract, ExtractSchedule, Render, RenderSet,
|
Extract, ExtractSchedule, Render, RenderSet,
|
||||||
};
|
};
|
||||||
use bevy_sprite::{
|
use bevy_sprite::{
|
||||||
ImageScaleMode, SliceScaleMode, SpriteAssetEvents, TextureAtlas, TextureAtlasLayout,
|
ImageScaleMode, SliceScaleMode, SpriteAssetEvents, TextureAtlasLayout, TextureSlicer,
|
||||||
TextureSlicer,
|
|
||||||
};
|
};
|
||||||
use bevy_transform::prelude::GlobalTransform;
|
use bevy_transform::prelude::GlobalTransform;
|
||||||
use bevy_utils::HashMap;
|
use bevy_utils::HashMap;
|
||||||
|
@ -258,22 +257,12 @@ pub fn extract_ui_texture_slices(
|
||||||
Option<&TargetCamera>,
|
Option<&TargetCamera>,
|
||||||
&UiImage,
|
&UiImage,
|
||||||
&ImageScaleMode,
|
&ImageScaleMode,
|
||||||
Option<&TextureAtlas>,
|
|
||||||
)>,
|
)>,
|
||||||
>,
|
>,
|
||||||
mapping: Extract<Query<RenderEntity>>,
|
mapping: Extract<Query<RenderEntity>>,
|
||||||
) {
|
) {
|
||||||
for (
|
for (entity, uinode, transform, view_visibility, clip, camera, image, image_scale_mode) in
|
||||||
entity,
|
&slicers_query
|
||||||
uinode,
|
|
||||||
transform,
|
|
||||||
view_visibility,
|
|
||||||
clip,
|
|
||||||
camera,
|
|
||||||
image,
|
|
||||||
image_scale_mode,
|
|
||||||
atlas,
|
|
||||||
) in &slicers_query
|
|
||||||
{
|
{
|
||||||
let Some(camera_entity) = camera.map(TargetCamera::entity).or(default_ui_camera.get())
|
let Some(camera_entity) = camera.map(TargetCamera::entity).or(default_ui_camera.get())
|
||||||
else {
|
else {
|
||||||
|
@ -287,12 +276,14 @@ pub fn extract_ui_texture_slices(
|
||||||
// Skip invisible images
|
// Skip invisible images
|
||||||
if !view_visibility.get()
|
if !view_visibility.get()
|
||||||
|| image.color.is_fully_transparent()
|
|| image.color.is_fully_transparent()
|
||||||
|| image.texture.id() == TRANSPARENT_IMAGE_HANDLE.id()
|
|| image.image.id() == TRANSPARENT_IMAGE_HANDLE.id()
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let atlas_rect = atlas
|
let atlas_rect = image
|
||||||
|
.texture_atlas
|
||||||
|
.as_ref()
|
||||||
.and_then(|s| s.texture_rect(&texture_atlases))
|
.and_then(|s| s.texture_rect(&texture_atlases))
|
||||||
.map(|r| r.as_rect());
|
.map(|r| r.as_rect());
|
||||||
|
|
||||||
|
@ -318,7 +309,7 @@ pub fn extract_ui_texture_slices(
|
||||||
max: uinode.calculated_size,
|
max: uinode.calculated_size,
|
||||||
},
|
},
|
||||||
clip: clip.map(|clip| clip.clip),
|
clip: clip.map(|clip| clip.clip),
|
||||||
image: image.texture.id(),
|
image: image.image.id(),
|
||||||
camera_entity,
|
camera_entity,
|
||||||
image_scale_mode: image_scale_mode.clone(),
|
image_scale_mode: image_scale_mode.clone(),
|
||||||
atlas_rect,
|
atlas_rect,
|
||||||
|
|
|
@ -9,7 +9,7 @@ use bevy_render::{
|
||||||
texture::{Image, TRANSPARENT_IMAGE_HANDLE},
|
texture::{Image, TRANSPARENT_IMAGE_HANDLE},
|
||||||
view::Visibility,
|
view::Visibility,
|
||||||
};
|
};
|
||||||
use bevy_sprite::BorderRect;
|
use bevy_sprite::{BorderRect, TextureAtlas};
|
||||||
use bevy_transform::components::Transform;
|
use bevy_transform::components::Transform;
|
||||||
use bevy_utils::warn_once;
|
use bevy_utils::warn_once;
|
||||||
use bevy_window::{PrimaryWindow, WindowRef};
|
use bevy_window::{PrimaryWindow, WindowRef};
|
||||||
|
@ -2053,15 +2053,17 @@ pub struct UiImage {
|
||||||
/// Handle to the texture.
|
/// Handle to the texture.
|
||||||
///
|
///
|
||||||
/// This defaults to a [`TRANSPARENT_IMAGE_HANDLE`], which points to a fully transparent 1x1 texture.
|
/// This defaults to a [`TRANSPARENT_IMAGE_HANDLE`], which points to a fully transparent 1x1 texture.
|
||||||
pub texture: Handle<Image>,
|
pub image: Handle<Image>,
|
||||||
|
/// The (optional) texture atlas used to render the image
|
||||||
|
pub texture_atlas: Option<TextureAtlas>,
|
||||||
/// Whether the image should be flipped along its x-axis
|
/// Whether the image should be flipped along its x-axis
|
||||||
pub flip_x: bool,
|
pub flip_x: bool,
|
||||||
/// Whether the image should be flipped along its y-axis
|
/// Whether the image should be flipped along its y-axis
|
||||||
pub flip_y: bool,
|
pub flip_y: bool,
|
||||||
/// An optional rectangle representing the region of the image to render, instead of rendering
|
/// An optional rectangle representing the region of the image to render, instead of rendering
|
||||||
/// the full image. This is an easy one-off alternative to using a [`TextureAtlas`](bevy_sprite::TextureAtlas).
|
/// the full image. This is an easy one-off alternative to using a [`TextureAtlas`].
|
||||||
///
|
///
|
||||||
/// When used with a [`TextureAtlas`](bevy_sprite::TextureAtlas), the rect
|
/// When used with a [`TextureAtlas`], the rect
|
||||||
/// is offset by the atlas's minimal (top-left) corner position.
|
/// is offset by the atlas's minimal (top-left) corner position.
|
||||||
pub rect: Option<Rect>,
|
pub rect: Option<Rect>,
|
||||||
}
|
}
|
||||||
|
@ -2079,8 +2081,9 @@ impl Default for UiImage {
|
||||||
// This should be white because the tint is multiplied with the image,
|
// This should be white because the tint is multiplied with the image,
|
||||||
// so if you set an actual image with default tint you'd want its original colors
|
// so if you set an actual image with default tint you'd want its original colors
|
||||||
color: Color::WHITE,
|
color: Color::WHITE,
|
||||||
|
texture_atlas: None,
|
||||||
// This texture needs to be transparent by default, to avoid covering the background color
|
// This texture needs to be transparent by default, to avoid covering the background color
|
||||||
texture: TRANSPARENT_IMAGE_HANDLE,
|
image: TRANSPARENT_IMAGE_HANDLE,
|
||||||
flip_x: false,
|
flip_x: false,
|
||||||
flip_y: false,
|
flip_y: false,
|
||||||
rect: None,
|
rect: None,
|
||||||
|
@ -2092,7 +2095,7 @@ impl UiImage {
|
||||||
/// Create a new [`UiImage`] with the given texture.
|
/// Create a new [`UiImage`] with the given texture.
|
||||||
pub fn new(texture: Handle<Image>) -> Self {
|
pub fn new(texture: Handle<Image>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
texture,
|
image: texture,
|
||||||
color: Color::WHITE,
|
color: Color::WHITE,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
|
@ -2103,14 +2106,24 @@ impl UiImage {
|
||||||
/// This is primarily useful for debugging / mocking the extents of your image.
|
/// This is primarily useful for debugging / mocking the extents of your image.
|
||||||
pub fn solid_color(color: Color) -> Self {
|
pub fn solid_color(color: Color) -> Self {
|
||||||
Self {
|
Self {
|
||||||
texture: Handle::default(),
|
image: Handle::default(),
|
||||||
color,
|
color,
|
||||||
flip_x: false,
|
flip_x: false,
|
||||||
flip_y: false,
|
flip_y: false,
|
||||||
|
texture_atlas: None,
|
||||||
rect: None,
|
rect: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a [`UiImage`] from an image, with an associated texture atlas
|
||||||
|
pub fn from_atlas_image(image: Handle<Image>, atlas: TextureAtlas) -> Self {
|
||||||
|
Self {
|
||||||
|
image,
|
||||||
|
texture_atlas: Some(atlas),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Set the color tint
|
/// Set the color tint
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn with_color(mut self, color: Color) -> Self {
|
pub const fn with_color(mut self, color: Color) -> Self {
|
||||||
|
|
|
@ -4,7 +4,7 @@ use bevy_ecs::prelude::*;
|
||||||
use bevy_math::{UVec2, Vec2};
|
use bevy_math::{UVec2, Vec2};
|
||||||
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
|
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
|
||||||
use bevy_render::texture::Image;
|
use bevy_render::texture::Image;
|
||||||
use bevy_sprite::{TextureAtlas, TextureAtlasLayout};
|
use bevy_sprite::TextureAtlasLayout;
|
||||||
use bevy_window::{PrimaryWindow, Window};
|
use bevy_window::{PrimaryWindow, Window};
|
||||||
use taffy::{MaybeMath, MaybeResolve};
|
use taffy::{MaybeMath, MaybeResolve};
|
||||||
|
|
||||||
|
@ -97,15 +97,7 @@ pub fn update_image_content_size_system(
|
||||||
textures: Res<Assets<Image>>,
|
textures: Res<Assets<Image>>,
|
||||||
|
|
||||||
atlases: Res<Assets<TextureAtlasLayout>>,
|
atlases: Res<Assets<TextureAtlasLayout>>,
|
||||||
mut query: Query<
|
mut query: Query<(&mut ContentSize, &UiImage, &mut UiImageSize), UpdateImageFilter>,
|
||||||
(
|
|
||||||
&mut ContentSize,
|
|
||||||
&UiImage,
|
|
||||||
&mut UiImageSize,
|
|
||||||
Option<&TextureAtlas>,
|
|
||||||
),
|
|
||||||
UpdateImageFilter,
|
|
||||||
>,
|
|
||||||
) {
|
) {
|
||||||
let combined_scale_factor = windows
|
let combined_scale_factor = windows
|
||||||
.get_single()
|
.get_single()
|
||||||
|
@ -113,10 +105,10 @@ pub fn update_image_content_size_system(
|
||||||
.unwrap_or(1.)
|
.unwrap_or(1.)
|
||||||
* ui_scale.0;
|
* ui_scale.0;
|
||||||
|
|
||||||
for (mut content_size, image, mut image_size, atlas_image) in &mut query {
|
for (mut content_size, image, mut image_size) in &mut query {
|
||||||
if let Some(size) = match atlas_image {
|
if let Some(size) = match &image.texture_atlas {
|
||||||
Some(atlas) => atlas.texture_rect(&atlases).map(|t| t.size()),
|
Some(atlas) => atlas.texture_rect(&atlases).map(|t| t.size()),
|
||||||
None => textures.get(&image.texture).map(Image::size),
|
None => textures.get(&image.image).map(Image::size),
|
||||||
} {
|
} {
|
||||||
// Update only if size or scale factor has changed to avoid needless layout calculations
|
// Update only if size or scale factor has changed to avoid needless layout calculations
|
||||||
if size != image_size.size
|
if size != image_size.size
|
||||||
|
|
|
@ -116,7 +116,7 @@ fn setup(
|
||||||
|
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
UiImage {
|
UiImage {
|
||||||
texture: metering_mask,
|
image: metering_mask,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
Node {
|
Node {
|
||||||
|
|
|
@ -84,6 +84,7 @@ fn setup(
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Sprite {
|
Sprite {
|
||||||
image: texture_handle.clone(),
|
image: texture_handle.clone(),
|
||||||
|
texture_atlas: Some(TextureAtlas::from(texture_atlas_handle.clone())),
|
||||||
custom_size: Some(tile_size),
|
custom_size: Some(tile_size),
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
|
@ -92,7 +93,6 @@ fn setup(
|
||||||
rotation,
|
rotation,
|
||||||
scale,
|
scale,
|
||||||
},
|
},
|
||||||
TextureAtlas::from(texture_atlas_handle.clone()),
|
|
||||||
AnimationTimer(timer),
|
AnimationTimer(timer),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -112,13 +112,16 @@ struct AnimationTimer(Timer);
|
||||||
fn animate_sprite(
|
fn animate_sprite(
|
||||||
time: Res<Time>,
|
time: Res<Time>,
|
||||||
texture_atlases: Res<Assets<TextureAtlasLayout>>,
|
texture_atlases: Res<Assets<TextureAtlasLayout>>,
|
||||||
mut query: Query<(&mut AnimationTimer, &mut TextureAtlas)>,
|
mut query: Query<(&mut AnimationTimer, &mut Sprite)>,
|
||||||
) {
|
) {
|
||||||
for (mut timer, mut sheet) in query.iter_mut() {
|
for (mut timer, mut sprite) in query.iter_mut() {
|
||||||
timer.tick(time.delta());
|
timer.tick(time.delta());
|
||||||
if timer.just_finished() {
|
if timer.just_finished() {
|
||||||
let texture_atlas = texture_atlases.get(&sheet.layout).unwrap();
|
let Some(atlas) = &mut sprite.texture_atlas else {
|
||||||
sheet.index = (sheet.index + 1) % texture_atlas.textures.len();
|
continue;
|
||||||
|
};
|
||||||
|
let texture_atlas = texture_atlases.get(&atlas.layout).unwrap();
|
||||||
|
atlas.index = (atlas.index + 1) % texture_atlas.textures.len();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,14 +44,13 @@ fn setup(
|
||||||
})
|
})
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
parent.spawn((
|
parent.spawn((
|
||||||
UiImage::new(texture_handle),
|
UiImage::from_atlas_image(texture_handle, TextureAtlas::from(texture_atlas_handle)),
|
||||||
Node {
|
Node {
|
||||||
width: Val::Px(256.),
|
width: Val::Px(256.),
|
||||||
height: Val::Px(256.),
|
height: Val::Px(256.),
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
BackgroundColor(ANTIQUE_WHITE.into()),
|
BackgroundColor(ANTIQUE_WHITE.into()),
|
||||||
TextureAtlas::from(texture_atlas_handle),
|
|
||||||
Outline::new(Val::Px(8.0), Val::ZERO, CRIMSON.into()),
|
Outline::new(Val::Px(8.0), Val::ZERO, CRIMSON.into()),
|
||||||
));
|
));
|
||||||
parent
|
parent
|
||||||
|
@ -65,13 +64,12 @@ fn setup(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn increment_atlas_index(
|
fn increment_atlas_index(mut ui_images: Query<&mut UiImage>, keyboard: Res<ButtonInput<KeyCode>>) {
|
||||||
mut atlas_images: Query<&mut TextureAtlas>,
|
|
||||||
keyboard: Res<ButtonInput<KeyCode>>,
|
|
||||||
) {
|
|
||||||
if keyboard.just_pressed(KeyCode::Space) {
|
if keyboard.just_pressed(KeyCode::Space) {
|
||||||
for mut atlas_image in &mut atlas_images {
|
for mut ui_image in &mut ui_images {
|
||||||
atlas_image.index = (atlas_image.index + 1) % 6;
|
if let Some(atlas) = &mut ui_image.texture_atlas {
|
||||||
|
atlas.index = (atlas.index + 1) % 6;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,17 +19,19 @@ fn main() {
|
||||||
|
|
||||||
fn button_system(
|
fn button_system(
|
||||||
mut interaction_query: Query<
|
mut interaction_query: Query<
|
||||||
(&Interaction, &mut TextureAtlas, &Children, &mut UiImage),
|
(&Interaction, &Children, &mut UiImage),
|
||||||
(Changed<Interaction>, With<Button>),
|
(Changed<Interaction>, With<Button>),
|
||||||
>,
|
>,
|
||||||
mut text_query: Query<&mut Text>,
|
mut text_query: Query<&mut Text>,
|
||||||
) {
|
) {
|
||||||
for (interaction, mut atlas, children, mut image) in &mut interaction_query {
|
for (interaction, children, mut image) in &mut interaction_query {
|
||||||
let mut text = text_query.get_mut(children[0]).unwrap();
|
let mut text = text_query.get_mut(children[0]).unwrap();
|
||||||
match *interaction {
|
match *interaction {
|
||||||
Interaction::Pressed => {
|
Interaction::Pressed => {
|
||||||
**text = "Press".to_string();
|
**text = "Press".to_string();
|
||||||
|
if let Some(atlas) = &mut image.texture_atlas {
|
||||||
atlas.index = (atlas.index + 1) % 30;
|
atlas.index = (atlas.index + 1) % 30;
|
||||||
|
}
|
||||||
image.color = GOLD.into();
|
image.color = GOLD.into();
|
||||||
}
|
}
|
||||||
Interaction::Hovered => {
|
Interaction::Hovered => {
|
||||||
|
@ -79,7 +81,13 @@ fn setup(
|
||||||
parent
|
parent
|
||||||
.spawn((
|
.spawn((
|
||||||
Button,
|
Button,
|
||||||
UiImage::new(texture_handle.clone()),
|
UiImage::from_atlas_image(
|
||||||
|
texture_handle.clone(),
|
||||||
|
TextureAtlas {
|
||||||
|
index: idx,
|
||||||
|
layout: atlas_layout_handle.clone(),
|
||||||
|
},
|
||||||
|
),
|
||||||
Node {
|
Node {
|
||||||
width: Val::Px(w),
|
width: Val::Px(w),
|
||||||
height: Val::Px(h),
|
height: Val::Px(h),
|
||||||
|
@ -91,10 +99,6 @@ fn setup(
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
ImageScaleMode::Sliced(slicer.clone()),
|
ImageScaleMode::Sliced(slicer.clone()),
|
||||||
TextureAtlas {
|
|
||||||
index: idx,
|
|
||||||
layout: atlas_layout_handle.clone(),
|
|
||||||
},
|
|
||||||
))
|
))
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
parent.spawn((
|
parent.spawn((
|
||||||
|
|
|
@ -58,7 +58,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
] {
|
] {
|
||||||
parent.spawn((
|
parent.spawn((
|
||||||
UiImage {
|
UiImage {
|
||||||
texture: image.clone(),
|
image: image.clone(),
|
||||||
flip_x,
|
flip_x,
|
||||||
flip_y,
|
flip_y,
|
||||||
..default()
|
..default()
|
||||||
|
|
Loading…
Reference in a new issue