UiImage -> ImageNode, UiImageSize -> ImageNodeSize (#16271)

# Objective

Align `UiImage` with the new `XNode` naming convention.

## Solution

- Rename `UiImage` to `ImageNode`
- Rename `UiImageSize` to `ImageNodeSize`

---

## Migration Guide

Before:
```rust
commands.spawn(UiImage::new(image));
````

After:
```rust
commands.spawn(ImageNode::new(image));
```
This commit is contained in:
Carter Anderson 2024-11-07 13:52:58 -08:00 committed by GitHub
parent cdc18ee886
commit f754cecb49
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 81 additions and 69 deletions

View file

@ -1,7 +1,7 @@
use crate::{ use crate::{
experimental::UiChildren, experimental::UiChildren,
prelude::{Button, Label}, prelude::{Button, Label},
widget::{TextUiReader, UiImage}, widget::{ImageNode, TextUiReader},
ComputedNode, ComputedNode,
}; };
use bevy_a11y::{ use bevy_a11y::{
@ -92,7 +92,10 @@ fn button_changed(
fn image_changed( fn image_changed(
mut commands: Commands, mut commands: Commands,
mut query: Query<(Entity, Option<&mut AccessibilityNode>), (Changed<UiImage>, Without<Button>)>, mut query: Query<
(Entity, Option<&mut AccessibilityNode>),
(Changed<ImageNode>, Without<Button>),
>,
ui_children: UiChildren, ui_children: UiChildren,
mut text_reader: TextUiReader, mut text_reader: TextUiReader,
) { ) {

View file

@ -8,7 +8,7 @@
//! This crate contains Bevy's UI system, which can be used to create UI for both 2D and 3D games //! This crate contains Bevy's UI system, which can be used to create UI for both 2D and 3D games
//! # Basic usage //! # Basic usage
//! Spawn UI elements with [`widget::Button`], [`UiImage`], [`Text`](prelude::Text) and [`Node`] //! Spawn UI elements with [`widget::Button`], [`ImageNode`], [`Text`](prelude::Text) and [`Node`]
//! This UI is laid out with the Flexbox and CSS Grid layout models (see <https://cssreference.io/flexbox/>) //! This UI is laid out with the Flexbox and CSS Grid layout models (see <https://cssreference.io/flexbox/>)
pub mod measurement; pub mod measurement;
@ -40,7 +40,7 @@ pub use measurement::*;
pub use render::*; pub use render::*;
pub use ui_material::*; pub use ui_material::*;
pub use ui_node::*; pub use ui_node::*;
use widget::{UiImage, UiImageSize}; use widget::{ImageNode, ImageNodeSize};
/// The UI prelude. /// The UI prelude.
/// ///
@ -58,7 +58,7 @@ pub mod prelude {
node_bundles::*, node_bundles::*,
ui_material::*, ui_material::*,
ui_node::*, ui_node::*,
widget::{Button, Label, UiImage}, widget::{Button, ImageNode, Label},
Interaction, MaterialNode, UiMaterialPlugin, UiScale, Interaction, MaterialNode, UiMaterialPlugin, UiScale,
}, },
// `bevy_sprite` re-exports for texture slicing // `bevy_sprite` re-exports for texture slicing
@ -155,8 +155,8 @@ impl Plugin for UiPlugin {
.register_type::<RelativeCursorPosition>() .register_type::<RelativeCursorPosition>()
.register_type::<ScrollPosition>() .register_type::<ScrollPosition>()
.register_type::<TargetCamera>() .register_type::<TargetCamera>()
.register_type::<UiImage>() .register_type::<ImageNode>()
.register_type::<UiImageSize>() .register_type::<ImageNodeSize>()
.register_type::<UiRect>() .register_type::<UiRect>()
.register_type::<UiScale>() .register_type::<UiScale>()
.register_type::<BorderColor>() .register_type::<BorderColor>()
@ -208,7 +208,7 @@ impl Plugin for UiPlugin {
update_clipping_system.after(TransformSystem::TransformPropagate), update_clipping_system.after(TransformSystem::TransformPropagate),
// Potential conflicts: `Assets<Image>` // Potential conflicts: `Assets<Image>`
// They run independently since `widget::image_node_system` will only ever observe // They run independently since `widget::image_node_system` will only ever observe
// its own UiImage, and `widget::text_system` & `bevy_text::update_text2d_layout` // its own ImageNode, and `widget::text_system` & `bevy_text::update_text2d_layout`
// will never modify a pre-existing `Image` asset. // will never modify a pre-existing `Image` asset.
widget::update_image_content_size_system widget::update_image_content_size_system
.in_set(UiSystem::Prepare) .in_set(UiSystem::Prepare)
@ -265,7 +265,7 @@ fn build_text_interop(app: &mut App) {
// Since both systems will only ever insert new [`Image`] assets, // Since both systems will only ever insert new [`Image`] assets,
// they will never observe each other's effects. // they will never observe each other's effects.
.ambiguous_with(bevy_text::update_text2d_layout) .ambiguous_with(bevy_text::update_text2d_layout)
// We assume Text is on disjoint UI entities to UiImage and UiTextureAtlasImage // We assume Text is on disjoint UI entities to ImageNode and UiTextureAtlasImage
// FIXME: Add an archetype invariant for this https://github.com/bevyengine/bevy/issues/1481. // FIXME: Add an archetype invariant for this https://github.com/bevyengine/bevy/issues/1481.
.ambiguous_with(widget::update_image_content_size_system), .ambiguous_with(widget::update_image_content_size_system),
widget::text_system widget::text_system

View file

@ -2,9 +2,9 @@
#![expect(deprecated)] #![expect(deprecated)]
use crate::{ use crate::{
widget::{Button, UiImageSize}, widget::{Button, ImageNodeSize},
BackgroundColor, BorderColor, BorderRadius, ComputedNode, ContentSize, FocusPolicy, BackgroundColor, BorderColor, BorderRadius, ComputedNode, ContentSize, FocusPolicy, ImageNode,
Interaction, MaterialNode, Node, ScrollPosition, UiImage, UiMaterial, ZIndex, Interaction, MaterialNode, Node, ScrollPosition, UiMaterial, ZIndex,
}; };
use bevy_ecs::bundle::Bundle; use bevy_ecs::bundle::Bundle;
use bevy_render::view::{InheritedVisibility, ViewVisibility, Visibility}; use bevy_render::view::{InheritedVisibility, ViewVisibility, Visibility};
@ -60,7 +60,7 @@ pub struct NodeBundle {
#[derive(Bundle, Debug, Default)] #[derive(Bundle, Debug, Default)]
#[deprecated( #[deprecated(
since = "0.15.0", since = "0.15.0",
note = "Use the `UiImage` component instead. Inserting `UiImage` will also insert the other components required automatically." note = "Use the `ImageNode` component instead. Inserting `ImageNode` will also insert the other components required automatically."
)] )]
pub struct ImageBundle { pub struct ImageBundle {
/// Describes the logical size of the node /// Describes the logical size of the node
@ -73,7 +73,7 @@ pub struct ImageBundle {
/// The image of the node. /// The image of the node.
/// ///
/// To tint the image, change the `color` field of this component. /// To tint the image, change the `color` field of this component.
pub image: UiImage, pub image: ImageNode,
/// The color of the background that will fill the containing node. /// The color of the background that will fill the containing node.
pub background_color: BackgroundColor, pub background_color: BackgroundColor,
/// The border radius of the node /// The border radius of the node
@ -81,7 +81,7 @@ pub struct ImageBundle {
/// The size of the image in pixels /// The size of the image in pixels
/// ///
/// This component is set automatically /// This component is set automatically
pub image_size: UiImageSize, pub image_size: ImageNodeSize,
/// Whether this node should block interaction with lower nodes /// Whether this node should block interaction with lower nodes
pub focus_policy: FocusPolicy, pub focus_policy: FocusPolicy,
/// The transform of the node /// The transform of the node
@ -126,7 +126,7 @@ pub struct ButtonBundle {
/// The border radius of the node /// The border radius of the node
pub border_radius: BorderRadius, pub border_radius: BorderRadius,
/// The image of the node /// The image of the node
pub image: UiImage, pub image: ImageNode,
/// The background color that will fill the containing node /// The background color that will fill the containing node
pub background_color: BackgroundColor, pub background_color: BackgroundColor,
/// The transform of the node /// The transform of the node

View file

@ -4,7 +4,7 @@ mod render_pass;
mod ui_material_pipeline; mod ui_material_pipeline;
pub mod ui_texture_slice_pipeline; pub mod ui_texture_slice_pipeline;
use crate::widget::UiImage; use crate::widget::ImageNode;
use crate::{ use crate::{
experimental::UiChildren, BackgroundColor, BorderColor, CalculatedClip, ComputedNode, experimental::UiChildren, BackgroundColor, BorderColor, CalculatedClip, ComputedNode,
DefaultUiCamera, Outline, ResolvedBorderRadius, TargetCamera, UiAntiAlias, UiBoxShadowSamples, DefaultUiCamera, Outline, ResolvedBorderRadius, TargetCamera, UiAntiAlias, UiBoxShadowSamples,
@ -110,7 +110,7 @@ pub fn build_ui_render(app: &mut App) {
render_app render_app
.init_resource::<SpecializedRenderPipelines<UiPipeline>>() .init_resource::<SpecializedRenderPipelines<UiPipeline>>()
.init_resource::<UiImageBindGroups>() .init_resource::<ImageNodeBindGroups>()
.init_resource::<UiMeta>() .init_resource::<UiMeta>()
.init_resource::<ExtractedUiNodes>() .init_resource::<ExtractedUiNodes>()
.allow_ambiguous_resource::<ExtractedUiNodes>() .allow_ambiguous_resource::<ExtractedUiNodes>()
@ -318,7 +318,7 @@ pub fn extract_uinode_images(
&ViewVisibility, &ViewVisibility,
Option<&CalculatedClip>, Option<&CalculatedClip>,
Option<&TargetCamera>, Option<&TargetCamera>,
&UiImage, &ImageNode,
)>, )>,
>, >,
mapping: Extract<Query<RenderEntity>>, mapping: Extract<Query<RenderEntity>>,
@ -874,7 +874,7 @@ pub fn queue_uinodes(
} }
#[derive(Resource, Default)] #[derive(Resource, Default)]
pub struct UiImageBindGroups { pub struct ImageNodeBindGroups {
pub values: HashMap<AssetId<Image>, BindGroup>, pub values: HashMap<AssetId<Image>, BindGroup>,
} }
@ -887,7 +887,7 @@ pub fn prepare_uinodes(
mut extracted_uinodes: ResMut<ExtractedUiNodes>, mut extracted_uinodes: ResMut<ExtractedUiNodes>,
view_uniforms: Res<ViewUniforms>, view_uniforms: Res<ViewUniforms>,
ui_pipeline: Res<UiPipeline>, ui_pipeline: Res<UiPipeline>,
mut image_bind_groups: ResMut<UiImageBindGroups>, mut image_bind_groups: ResMut<ImageNodeBindGroups>,
gpu_images: Res<RenderAssets<GpuImage>>, gpu_images: Res<RenderAssets<GpuImage>>,
mut phases: ResMut<ViewSortedRenderPhases<TransparentUi>>, mut phases: ResMut<ViewSortedRenderPhases<TransparentUi>>,
events: Res<SpriteAssetEvents>, events: Res<SpriteAssetEvents>,

View file

@ -1,6 +1,6 @@
use core::ops::Range; use core::ops::Range;
use super::{UiBatch, UiImageBindGroups, UiMeta}; use super::{ImageNodeBindGroups, UiBatch, UiMeta};
use crate::DefaultCameraView; use crate::DefaultCameraView;
use bevy_ecs::{ use bevy_ecs::{
prelude::*, prelude::*,
@ -185,7 +185,7 @@ impl<P: PhaseItem, const I: usize> RenderCommand<P> for SetUiViewBindGroup<I> {
} }
pub struct SetUiTextureBindGroup<const I: usize>; pub struct SetUiTextureBindGroup<const I: usize>;
impl<P: PhaseItem, const I: usize> RenderCommand<P> for SetUiTextureBindGroup<I> { impl<P: PhaseItem, const I: usize> RenderCommand<P> for SetUiTextureBindGroup<I> {
type Param = SRes<UiImageBindGroups>; type Param = SRes<ImageNodeBindGroups>;
type ViewQuery = (); type ViewQuery = ();
type ItemQuery = Read<UiBatch>; type ItemQuery = Read<UiBatch>;

View file

@ -30,7 +30,7 @@ use bevy_transform::prelude::GlobalTransform;
use bevy_utils::HashMap; use bevy_utils::HashMap;
use binding_types::{sampler, texture_2d}; use binding_types::{sampler, texture_2d};
use bytemuck::{Pod, Zeroable}; use bytemuck::{Pod, Zeroable};
use widget::UiImage; use widget::ImageNode;
pub const UI_SLICER_SHADER_HANDLE: Handle<Shader> = Handle::weak_from_u128(11156288772117983964); pub const UI_SLICER_SHADER_HANDLE: Handle<Shader> = Handle::weak_from_u128(11156288772117983964);
@ -256,7 +256,7 @@ pub fn extract_ui_texture_slices(
&ViewVisibility, &ViewVisibility,
Option<&CalculatedClip>, Option<&CalculatedClip>,
Option<&TargetCamera>, Option<&TargetCamera>,
&UiImage, &ImageNode,
)>, )>,
>, >,
mapping: Extract<Query<RenderEntity>>, mapping: Extract<Query<RenderEntity>>,

View file

@ -9,11 +9,11 @@ use bevy_sprite::{TextureAtlas, TextureAtlasLayout, TextureSlicer};
use bevy_window::{PrimaryWindow, Window}; use bevy_window::{PrimaryWindow, Window};
use taffy::{MaybeMath, MaybeResolve}; use taffy::{MaybeMath, MaybeResolve};
/// The 2D texture displayed for this UI node /// A UI Node that renders an image.
#[derive(Component, Clone, Debug, Reflect)] #[derive(Component, Clone, Debug, Reflect)]
#[reflect(Component, Default, Debug)] #[reflect(Component, Default, Debug)]
#[require(Node, UiImageSize, ContentSize)] #[require(Node, ImageNodeSize, ContentSize)]
pub struct UiImage { pub struct ImageNode {
/// The tint color used to draw the image. /// The tint color used to draw the image.
/// ///
/// This is multiplied by the color of each pixel in the image. /// This is multiplied by the color of each pixel in the image.
@ -39,16 +39,16 @@ pub struct UiImage {
pub image_mode: NodeImageMode, pub image_mode: NodeImageMode,
} }
impl Default for UiImage { impl Default for ImageNode {
/// A transparent 1x1 image with a solid white tint. /// A transparent 1x1 image with a solid white tint.
/// ///
/// # Warning /// # Warning
/// ///
/// This will be invisible by default. /// This will be invisible by default.
/// To set this to a visible image, you need to set the `texture` field to a valid image handle, /// To set this to a visible image, you need to set the `texture` field to a valid image handle,
/// or use [`Handle<Image>`]'s default 1x1 solid white texture (as is done in [`UiImage::solid_color`]). /// or use [`Handle<Image>`]'s default 1x1 solid white texture (as is done in [`ImageNode::solid_color`]).
fn default() -> Self { fn default() -> Self {
UiImage { ImageNode {
// 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,
@ -63,8 +63,8 @@ impl Default for UiImage {
} }
} }
impl UiImage { impl ImageNode {
/// Create a new [`UiImage`] with the given texture. /// Create a new [`ImageNode`] with the given texture.
pub fn new(texture: Handle<Image>) -> Self { pub fn new(texture: Handle<Image>) -> Self {
Self { Self {
image: texture, image: texture,
@ -73,7 +73,7 @@ impl UiImage {
} }
} }
/// Create a solid color [`UiImage`]. /// Create a solid color [`ImageNode`].
/// ///
/// 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 {
@ -88,7 +88,7 @@ impl UiImage {
} }
} }
/// Create a [`UiImage`] from an image, with an associated texture atlas /// Create a [`ImageNode`] from an image, with an associated texture atlas
pub fn from_atlas_image(image: Handle<Image>, atlas: TextureAtlas) -> Self { pub fn from_atlas_image(image: Handle<Image>, atlas: TextureAtlas) -> Self {
Self { Self {
image, image,
@ -131,7 +131,7 @@ impl UiImage {
} }
} }
impl From<Handle<Image>> for UiImage { impl From<Handle<Image>> for ImageNode {
fn from(texture: Handle<Image>) -> Self { fn from(texture: Handle<Image>) -> Self {
Self::new(texture) Self::new(texture)
} }
@ -175,14 +175,14 @@ impl NodeImageMode {
/// This component is updated automatically by [`update_image_content_size_system`] /// This component is updated automatically by [`update_image_content_size_system`]
#[derive(Component, Debug, Copy, Clone, Default, Reflect)] #[derive(Component, Debug, Copy, Clone, Default, Reflect)]
#[reflect(Component, Default, Debug)] #[reflect(Component, Default, Debug)]
pub struct UiImageSize { pub struct ImageNodeSize {
/// The size of the image's texture /// The size of the image's texture
/// ///
/// This field is updated automatically by [`update_image_content_size_system`] /// This field is updated automatically by [`update_image_content_size_system`]
size: UVec2, size: UVec2,
} }
impl UiImageSize { impl ImageNodeSize {
/// The size of the image's texture /// The size of the image's texture
pub fn size(&self) -> UVec2 { pub fn size(&self) -> UVec2 {
self.size self.size
@ -259,7 +259,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 ContentSize, Ref<UiImage>, &mut UiImageSize), UpdateImageFilter>, mut query: Query<(&mut ContentSize, Ref<ImageNode>, &mut ImageNodeSize), UpdateImageFilter>,
) { ) {
let combined_scale_factor = windows let combined_scale_factor = windows
.get_single() .get_single()

View file

@ -115,7 +115,7 @@ fn setup(
)); ));
commands.spawn(( commands.spawn((
UiImage { ImageNode {
image: metering_mask, image: metering_mask,
..default() ..default()
}, },
@ -162,7 +162,7 @@ struct ExampleResources {
fn example_control_system( fn example_control_system(
camera: Single<(&mut Transform, &mut AutoExposure), With<Camera3d>>, camera: Single<(&mut Transform, &mut AutoExposure), With<Camera3d>>,
mut display: Single<&mut Text, With<ExampleDisplay>>, mut display: Single<&mut Text, With<ExampleDisplay>>,
mut mask_image: Single<&mut Node, With<UiImage>>, mut mask_image: Single<&mut Node, With<ImageNode>>,
time: Res<Time>, time: Res<Time>,
input: Res<ButtonInput<KeyCode>>, input: Res<ButtonInput<KeyCode>>,
resources: Res<ExampleResources>, resources: Res<ExampleResources>,

View file

@ -86,7 +86,7 @@ mod splash {
)) ))
.with_children(|parent| { .with_children(|parent| {
parent.spawn(( parent.spawn((
UiImage::new(icon), ImageNode::new(icon),
Node { Node {
// This will set the logo to be 200px wide, and auto adjust its height // This will set the logo to be 200px wide, and auto adjust its height
width: Val::Px(200.0), width: Val::Px(200.0),
@ -444,7 +444,7 @@ mod menu {
)) ))
.with_children(|parent| { .with_children(|parent| {
let icon = asset_server.load("textures/Game Icons/right.png"); let icon = asset_server.load("textures/Game Icons/right.png");
parent.spawn((UiImage::new(icon), button_icon_node.clone())); parent.spawn((ImageNode::new(icon), button_icon_node.clone()));
parent.spawn(( parent.spawn((
Text::new("New Game"), Text::new("New Game"),
button_text_font.clone(), button_text_font.clone(),
@ -460,7 +460,7 @@ mod menu {
)) ))
.with_children(|parent| { .with_children(|parent| {
let icon = asset_server.load("textures/Game Icons/wrench.png"); let icon = asset_server.load("textures/Game Icons/wrench.png");
parent.spawn((UiImage::new(icon), button_icon_node.clone())); parent.spawn((ImageNode::new(icon), button_icon_node.clone()));
parent.spawn(( parent.spawn((
Text::new("Settings"), Text::new("Settings"),
button_text_font.clone(), button_text_font.clone(),
@ -476,7 +476,7 @@ mod menu {
)) ))
.with_children(|parent| { .with_children(|parent| {
let icon = asset_server.load("textures/Game Icons/exitRight.png"); let icon = asset_server.load("textures/Game Icons/exitRight.png");
parent.spawn((UiImage::new(icon), button_icon_node)); parent.spawn((ImageNode::new(icon), button_icon_node));
parent.spawn(( parent.spawn((
Text::new("Quit"), Text::new("Quit"),
button_text_font, button_text_font,

View file

@ -252,7 +252,7 @@ fn spawn_button(
)); ));
if let Some(image) = image { if let Some(image) = image {
builder.insert(UiImage::new(image)); builder.insert(ImageNode::new(image));
} }
if spawn_text { if spawn_text {

View file

@ -182,7 +182,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
)) ))
.with_children(|parent| { .with_children(|parent| {
parent.spawn(( parent.spawn((
UiImage::new(asset_server.load("branding/bevy_logo_light.png")), ImageNode::new(asset_server.load("branding/bevy_logo_light.png")),
// Uses the transform to rotate the logo image by 45 degrees // Uses the transform to rotate the logo image by 45 degrees
Transform::from_rotation(Quat::from_rotation_z(0.25 * PI)), Transform::from_rotation(Quat::from_rotation_z(0.25 * PI)),
BorderRadius::all(Val::Px(10.)), BorderRadius::all(Val::Px(10.)),
@ -294,7 +294,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
// bevy logo (image) // bevy logo (image)
parent parent
.spawn(( .spawn((
UiImage::new(asset_server.load("branding/bevy_logo_dark_big.png")) ImageNode::new(asset_server.load("branding/bevy_logo_dark_big.png"))
.with_mode(NodeImageMode::Stretch), .with_mode(NodeImageMode::Stretch),
Node { Node {
width: Val::Px(500.0), width: Val::Px(500.0),
@ -334,17 +334,17 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
[(false, false), (false, true), (true, true), (true, false)] [(false, false), (false, true), (true, true), (true, false)]
{ {
parent.spawn(( parent.spawn((
Node { ImageNode {
// The height will be chosen automatically to preserve the image's aspect ratio
width: Val::Px(75.),
..default()
},
UiImage {
image: asset_server.load("branding/icon.png"), image: asset_server.load("branding/icon.png"),
flip_x, flip_x,
flip_y, flip_y,
..default() ..default()
}, },
Node {
// The height will be chosen automatically to preserve the image's aspect ratio
width: Val::Px(75.),
..default()
},
)); ));
} }
}); });

View file

@ -49,7 +49,7 @@ fn atlas_render_system(
let font_atlas = &font_atlas[state.atlas_count as usize]; let font_atlas = &font_atlas[state.atlas_count as usize];
state.atlas_count += 1; state.atlas_count += 1;
commands.spawn(( commands.spawn((
UiImage::new(font_atlas.texture.clone()), ImageNode::new(font_atlas.texture.clone()),
Node { Node {
position_type: PositionType::Absolute, position_type: PositionType::Absolute,
top: Val::ZERO, top: Val::ZERO,

View file

@ -77,7 +77,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
)) ))
.with_children(|parent| { .with_children(|parent| {
parent.spawn(( parent.spawn((
UiImage::new(image.clone()), ImageNode::new(image.clone()),
Node { Node {
min_width: Val::Px(100.), min_width: Val::Px(100.),
min_height: Val::Px(100.), min_height: Val::Px(100.),

View file

@ -80,7 +80,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
BackgroundColor(LIGHT_CYAN.into()), BackgroundColor(LIGHT_CYAN.into()),
)) ))
.with_child(( .with_child((
UiImage::new(image.clone()), ImageNode::new(image.clone()),
Node { Node {
min_width: Val::Px(100.), min_width: Val::Px(100.),
min_height: Val::Px(100.), min_height: Val::Px(100.),

View file

@ -141,7 +141,7 @@ fn spawn_image(
) { ) {
spawn_container(parent, update_transform, |parent| { spawn_container(parent, update_transform, |parent| {
parent.spawn(( parent.spawn((
UiImage::new(asset_server.load("branding/bevy_logo_dark_big.png")), ImageNode::new(asset_server.load("branding/bevy_logo_dark_big.png")),
Node { Node {
height: Val::Px(100.), height: Val::Px(100.),
position_type: PositionType::Absolute, position_type: PositionType::Absolute,

View file

@ -64,7 +64,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
BackgroundColor(BLUE.into()), BackgroundColor(BLUE.into()),
)); ));
parent.spawn(( parent.spawn((
UiImage::new(asset_server.load("branding/icon.png")), ImageNode::new(asset_server.load("branding/icon.png")),
Node { Node {
width: Val::Px(30.0), width: Val::Px(30.0),
height: Val::Px(30.0), height: Val::Px(30.0),

View file

@ -44,7 +44,10 @@ fn setup(
}) })
.with_children(|parent| { .with_children(|parent| {
parent.spawn(( parent.spawn((
UiImage::from_atlas_image(texture_handle, TextureAtlas::from(texture_atlas_handle)), ImageNode::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.),
@ -64,10 +67,13 @@ fn setup(
}); });
} }
fn increment_atlas_index(mut ui_images: Query<&mut UiImage>, keyboard: Res<ButtonInput<KeyCode>>) { fn increment_atlas_index(
mut image_nodes: Query<&mut ImageNode>,
keyboard: Res<ButtonInput<KeyCode>>,
) {
if keyboard.just_pressed(KeyCode::Space) { if keyboard.just_pressed(KeyCode::Space) {
for mut ui_image in &mut ui_images { for mut image_node in &mut image_nodes {
if let Some(atlas) = &mut ui_image.texture_atlas { if let Some(atlas) = &mut image_node.texture_atlas {
atlas.index = (atlas.index + 1) % 6; atlas.index = (atlas.index + 1) % 6;
} }
} }

View file

@ -20,7 +20,7 @@ fn main() {
fn button_system( fn button_system(
mut interaction_query: Query< mut interaction_query: Query<
(&Interaction, &Children, &mut UiImage), (&Interaction, &Children, &mut ImageNode),
(Changed<Interaction>, With<Button>), (Changed<Interaction>, With<Button>),
>, >,
mut text_query: Query<&mut Text>, mut text_query: Query<&mut Text>,
@ -82,7 +82,7 @@ fn setup(
parent parent
.spawn(( .spawn((
Button, Button,
UiImage::from_atlas_image( ImageNode::from_atlas_image(
texture_handle.clone(), texture_handle.clone(),
TextureAtlas { TextureAtlas {
index: idx, index: idx,

View file

@ -20,7 +20,7 @@ fn main() {
fn button_system( fn button_system(
mut interaction_query: Query< mut interaction_query: Query<
(&Interaction, &Children, &mut UiImage), (&Interaction, &Children, &mut ImageNode),
(Changed<Interaction>, With<Button>), (Changed<Interaction>, With<Button>),
>, >,
mut text_query: Query<&mut Text>, mut text_query: Query<&mut Text>,
@ -68,6 +68,11 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
parent parent
.spawn(( .spawn((
Button, Button,
ImageNode {
image: image.clone(),
image_mode: NodeImageMode::Sliced(slicer.clone()),
..default()
},
Node { Node {
width: Val::Px(w), width: Val::Px(w),
height: Val::Px(h), height: Val::Px(h),
@ -78,8 +83,6 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
margin: UiRect::all(Val::Px(20.0)), margin: UiRect::all(Val::Px(20.0)),
..default() ..default()
}, },
UiImage::new(image.clone())
.with_mode(NodeImageMode::Sliced(slicer.clone())),
)) ))
.with_child(( .with_child((
Text::new("Button"), Text::new("Button"),

View file

@ -58,7 +58,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
([160., 160.], true, true), ([160., 160.], true, true),
] { ] {
parent.spawn(( parent.spawn((
UiImage { ImageNode {
image: image.clone(), image: image.clone(),
flip_x, flip_x,
flip_y, flip_y,