Skip to content

Conversation

@ickshonpe
Copy link
Contributor

@ickshonpe ickshonpe commented Oct 24, 2024

Objective

  1. UI texture slicing chops and scales an image to fit the size of a node and isn't meant to place any constraints on the size of the node itself, but because the required components changes required ImageSize and ContentSize for nodes with UiImage, texture sliced nodes are laid out using an ImageMeasure.

  2. In 0.14 users could spawn a (UiImage, NodeBundle) which would display an image stretched to fill the UI node's bounds ignoring the image's instrinsic size. Now that UiImage requires ContentSize, there's no option to display an image without its size placing constrains on the UI layout (unless you force the Node to a fixed size, but that's not a solution).

  3. It's desirable that the Sprite and UiImage share similar APIs.

Fixes #16109

Solution

  • Remove the Component impl from ImageScaleMode.
  • Add a Stretch variant to ImageScaleMode.
  • Add a field scale_mode: ImageScaleMode to Sprite.
  • Add a field mode: UiImageMode to UiImage.
  • Add an enum UiImageMode similar to ImageScaleMode but with additional UI specific variants.
  • Remove the queries for ImageScaleMode from Sprite and UI extraction, and refer to the new fields instead.
  • Change ui_layout_system to update measure funcs on any change to ContentSizes to enable manual clearing without removing the component.
  • Don't add a measure unless UiImageMode::Auto is set in update_image_content_size_system. Mutably deref the Mut<ContentSize> if the UiImage is changed to force removal of any existing measure func.

Testing

Remove all the constraints from the ui_texture_slice example:

//! This example illustrates how to create buttons with their textures 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, &Children, &mut UiImage),
        (Changed<Interaction>, With<Button>),
    >,
    mut text_query: Query<&mut Text>,
) {
    for (interaction, 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();
                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>) {
    let image = asset_server.load("textures/fantasy_ui_borders/panel-border-010.png");

    let slicer = TextureSlicer {
        border: BorderRect::square(22.0),
        center_scale_mode: SliceScaleMode::Stretch,
        sides_scale_mode: SliceScaleMode::Stretch,
        max_corner_scale: 1.0,
    };
    // ui camera
    commands.spawn(Camera2d);
    commands
        .spawn(Node {
            width: Val::Percent(100.0),
            height: Val::Percent(100.0),
            align_items: AlignItems::Center,
            justify_content: JustifyContent::Center,
            ..default()
        })
        .with_children(|parent| {
            for [w, h] in [[150.0, 150.0], [300.0, 150.0], [150.0, 300.0]] {
                parent
                    .spawn((
                        Button,
                        Node {
                            // 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::new(image.clone()),
                        ImageScaleMode::Sliced(slicer.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)),
                        // ));
                    });
            }
        });
}

This should result in a blank window, since without any constraints the texture slice image nodes should be zero-sized. But in main the image nodes are given the size of the underlying unsliced source image textures/fantasy_ui_borders/panel-border-010.png:

slicing

For this PR need to change the lines:

                        UiImage::new(image.clone()),
                        ImageScaleMode::Sliced(slicer.clone()),

to

                        UiImage::new(image.clone()).with_mode(UiImageMode::Sliced(slicer.clone()),

and then nothing should be rendered, as desired.

@ickshonpe ickshonpe requested a review from cart October 24, 2024 16:55
@ickshonpe ickshonpe added the A-UI Graphical user interfaces, styles, layouts, and widgets label Oct 24, 2024
@ickshonpe ickshonpe changed the title Add image scale mode to uiimage Add ImageScaleMode to UiImage Oct 24, 2024
@ickshonpe ickshonpe added C-Bug An unexpected or incorrect behavior A-Rendering Drawing game state to the screen S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Oct 24, 2024
…n `update_imnage_content_size_system` to ensure that `ui_layout_system` will remove the old measure func if present.
@alice-i-cecile alice-i-cecile added this to the 0.15 milestone Oct 27, 2024
@BenjaminBrienen BenjaminBrienen added S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged D-Straightforward Simple bug fixes and API improvements, docs, test and examples and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Oct 28, 2024
@cart
Copy link
Member

cart commented Oct 29, 2024

I'm on board for the general angle, but I think we should take this a couple of steps further:

  1. Port this pattern to Sprite for consistency.
  2. Remove the Component impl for ImageScaleMode.
  3. Make the "default" / None scale mode an ImageScaleMode variant (ex: ImageScaleMode::Standard). This makes the ergonomics better and also allows us to more easily express ideas like scale_mode.defines_size() (Standard) and scale_mode.uses_slices() (Sliced and Tiled). This also opens the doors to new scale modes in the future that aren't "sliced".

@cart
Copy link
Member

cart commented Oct 29, 2024

I've put those changes together. Pushing now for consideration (not dictating this solution, just pushing for convenience of discussion).

@ickshonpe
Copy link
Contributor Author

ickshonpe commented Oct 29, 2024

I'm on board for the general angle, but I think we should take this a couple of steps further:

  1. Port this pattern to Sprite for consistency.
  2. Remove the Component impl for ImageScaleMode.
  3. Make the "default" / None scale mode an ImageScaleMode variant (ex: ImageScaleMode::Standard). This makes the ergonomics better and also allows us to more easily express ideas like scale_mode.defines_size() (Standard) and scale_mode.uses_slices() (Sliced and Tiled). This also opens the doors to new scale modes in the future that aren't "sliced".

Yeah I've just been working on this PR the last hour as well and didn't notice this until I came to merge my changes. But I've been working in the same the direction, agree that ImageScaleMode should be non-optional and that it needs another variant for the default behaviour.

The main difference though is that I don't think Sprite and UiImage can share the ImageScaleMode enum since a UiImage also has to work within the constraints of the UI layout. Initially I think we need at least two extra variants, one that uses a measure func to preserve the image's aspect ratio and one that just fills the node without applying any constraints.

@ickshonpe
Copy link
Contributor Author

ickshonpe commented Oct 30, 2024

The name ImageScaleMode seems misleading as well for the same reasons, since for UiImage it wouldn't just control how an image is scaled but also how the layout algorithm rearranges the layout to make room for the image.

@cart
Copy link
Member

cart commented Oct 30, 2024

The main difference though is that I don't think Sprite and UiImage can share the ImageScaleMode enum

Yeah a split here seems reasonable. Also open to name alternatives.

@cart
Copy link
Member

cart commented Oct 31, 2024

(just pushed that change)

Copy link
Member

@mnmaita mnmaita left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, although there are still mentions of ImageScaleMode in the doc comments.

@BenjaminBrienen BenjaminBrienen added D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Oct 31, 2024
@mnmaita mnmaita added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged labels Nov 1, 2024
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Nov 4, 2024
Merged via the queue into bevyengine:main with commit 4e02d3c Nov 4, 2024
30 checks passed
mockersf pushed a commit that referenced this pull request Nov 5, 2024
1. UI texture slicing chops and scales an image to fit the size of a
node and isn't meant to place any constraints on the size of the node
itself, but because the required components changes required `ImageSize`
and `ContentSize` for nodes with `UiImage`, texture sliced nodes are
laid out using an `ImageMeasure`.

2. In 0.14 users could spawn a `(UiImage, NodeBundle)` which would
display an image stretched to fill the UI node's bounds ignoring the
image's instrinsic size. Now that `UiImage` requires `ContentSize`,
there's no option to display an image without its size placing
constrains on the UI layout (unless you force the `Node` to a fixed
size, but that's not a solution).

3. It's desirable that the `Sprite` and `UiImage` share similar APIs.

Fixes #16109

* Remove the `Component` impl from `ImageScaleMode`.
* Add a `Stretch` variant to `ImageScaleMode`.
* Add a field `scale_mode: ImageScaleMode` to `Sprite`.
* Add a field `mode: UiImageMode` to `UiImage`.
* Add an enum `UiImageMode` similar to `ImageScaleMode` but with
additional UI specific variants.
* Remove the queries for `ImageScaleMode` from Sprite and UI extraction,
and refer to the new fields instead.
* Change `ui_layout_system` to update measure funcs on any change to
`ContentSize`s to enable manual clearing without removing the component.
* Don't add a measure unless `UiImageMode::Auto` is set in
`update_image_content_size_system`. Mutably deref the `Mut<ContentSize>`
if the `UiImage` is changed to force removal of any existing measure
func.

Remove all the constraints from the ui_texture_slice example:

```rust
//! This example illustrates how to create buttons with their textures 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, &Children, &mut UiImage),
        (Changed<Interaction>, With<Button>),
    >,
    mut text_query: Query<&mut Text>,
) {
    for (interaction, 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();
                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>) {
    let image = asset_server.load("textures/fantasy_ui_borders/panel-border-010.png");

    let slicer = TextureSlicer {
        border: BorderRect::square(22.0),
        center_scale_mode: SliceScaleMode::Stretch,
        sides_scale_mode: SliceScaleMode::Stretch,
        max_corner_scale: 1.0,
    };
    // ui camera
    commands.spawn(Camera2d);
    commands
        .spawn(Node {
            width: Val::Percent(100.0),
            height: Val::Percent(100.0),
            align_items: AlignItems::Center,
            justify_content: JustifyContent::Center,
            ..default()
        })
        .with_children(|parent| {
            for [w, h] in [[150.0, 150.0], [300.0, 150.0], [150.0, 300.0]] {
                parent
                    .spawn((
                        Button,
                        Node {
                            // 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::new(image.clone()),
                        ImageScaleMode::Sliced(slicer.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)),
                        // ));
                    });
            }
        });
}
```

This should result in a blank window, since without any constraints the
texture slice image nodes should be zero-sized. But in main the image
nodes are given the size of the underlying unsliced source image
`textures/fantasy_ui_borders/panel-border-010.png`:

<img width="321" alt="slicing"
src="https://github.com/user-attachments/assets/cbd74c9c-14cd-4b4d-93c6-7c0152bb05ee">

For this PR need to change the lines:
```
                        UiImage::new(image.clone()),
                        ImageScaleMode::Sliced(slicer.clone()),
```
to
```
                        UiImage::new(image.clone()).with_mode(UiImageMode::Sliced(slicer.clone()),
```
and then nothing should be rendered, as desired.

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
ecoskey pushed a commit to ecoskey/bevy that referenced this pull request Dec 2, 2024
…16088)

# Objective

1. UI texture slicing chops and scales an image to fit the size of a
node and isn't meant to place any constraints on the size of the node
itself, but because the required components changes required `ImageSize`
and `ContentSize` for nodes with `UiImage`, texture sliced nodes are
laid out using an `ImageMeasure`.

2. In 0.14 users could spawn a `(UiImage, NodeBundle)` which would
display an image stretched to fill the UI node's bounds ignoring the
image's instrinsic size. Now that `UiImage` requires `ContentSize`,
there's no option to display an image without its size placing
constrains on the UI layout (unless you force the `Node` to a fixed
size, but that's not a solution).

3. It's desirable that the `Sprite` and `UiImage` share similar APIs.

Fixes bevyengine#16109

## Solution

* Remove the `Component` impl from `ImageScaleMode`.
* Add a `Stretch` variant to `ImageScaleMode`.
* Add a field `scale_mode: ImageScaleMode` to `Sprite`.
* Add a field `mode: UiImageMode` to `UiImage`. 
* Add an enum `UiImageMode` similar to `ImageScaleMode` but with
additional UI specific variants.
* Remove the queries for `ImageScaleMode` from Sprite and UI extraction,
and refer to the new fields instead.
* Change `ui_layout_system` to update measure funcs on any change to
`ContentSize`s to enable manual clearing without removing the component.
* Don't add a measure unless `UiImageMode::Auto` is set in
`update_image_content_size_system`. Mutably deref the `Mut<ContentSize>`
if the `UiImage` is changed to force removal of any existing measure
func.

## Testing
Remove all the constraints from the ui_texture_slice example:

```rust
//! This example illustrates how to create buttons with their textures 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, &Children, &mut UiImage),
        (Changed<Interaction>, With<Button>),
    >,
    mut text_query: Query<&mut Text>,
) {
    for (interaction, 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();
                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>) {
    let image = asset_server.load("textures/fantasy_ui_borders/panel-border-010.png");

    let slicer = TextureSlicer {
        border: BorderRect::square(22.0),
        center_scale_mode: SliceScaleMode::Stretch,
        sides_scale_mode: SliceScaleMode::Stretch,
        max_corner_scale: 1.0,
    };
    // ui camera
    commands.spawn(Camera2d);
    commands
        .spawn(Node {
            width: Val::Percent(100.0),
            height: Val::Percent(100.0),
            align_items: AlignItems::Center,
            justify_content: JustifyContent::Center,
            ..default()
        })
        .with_children(|parent| {
            for [w, h] in [[150.0, 150.0], [300.0, 150.0], [150.0, 300.0]] {
                parent
                    .spawn((
                        Button,
                        Node {
                            // 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::new(image.clone()),
                        ImageScaleMode::Sliced(slicer.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)),
                        // ));
                    });
            }
        });
}
```

This should result in a blank window, since without any constraints the
texture slice image nodes should be zero-sized. But in main the image
nodes are given the size of the underlying unsliced source image
`textures/fantasy_ui_borders/panel-border-010.png`:

<img width="321" alt="slicing"
src="https://github.com/user-attachments/assets/cbd74c9c-14cd-4b4d-93c6-7c0152bb05ee">

For this PR need to change the lines:
```
                        UiImage::new(image.clone()),
                        ImageScaleMode::Sliced(slicer.clone()),
```
to
```
                        UiImage::new(image.clone()).with_mode(UiImageMode::Sliced(slicer.clone()),
```
and then nothing should be rendered, as desired.

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
@rparrett rparrett added the M-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide label Dec 3, 2024
@github-actions
Copy link
Contributor

github-actions bot commented Dec 3, 2024

It looks like your PR is a breaking change, but you didn't provide a migration guide.

Could you add some context on what users should update when this change get released in a new version of Bevy?
It will be used to help writing the migration guide for the version. Putting it after a ## Migration Guide will help it get automatically picked up by our tooling.

ecoskey pushed a commit to ecoskey/bevy that referenced this pull request Jan 6, 2025
…16088)

# Objective

1. UI texture slicing chops and scales an image to fit the size of a
node and isn't meant to place any constraints on the size of the node
itself, but because the required components changes required `ImageSize`
and `ContentSize` for nodes with `UiImage`, texture sliced nodes are
laid out using an `ImageMeasure`.

2. In 0.14 users could spawn a `(UiImage, NodeBundle)` which would
display an image stretched to fill the UI node's bounds ignoring the
image's instrinsic size. Now that `UiImage` requires `ContentSize`,
there's no option to display an image without its size placing
constrains on the UI layout (unless you force the `Node` to a fixed
size, but that's not a solution).

3. It's desirable that the `Sprite` and `UiImage` share similar APIs.

Fixes bevyengine#16109

## Solution

* Remove the `Component` impl from `ImageScaleMode`.
* Add a `Stretch` variant to `ImageScaleMode`.
* Add a field `scale_mode: ImageScaleMode` to `Sprite`.
* Add a field `mode: UiImageMode` to `UiImage`. 
* Add an enum `UiImageMode` similar to `ImageScaleMode` but with
additional UI specific variants.
* Remove the queries for `ImageScaleMode` from Sprite and UI extraction,
and refer to the new fields instead.
* Change `ui_layout_system` to update measure funcs on any change to
`ContentSize`s to enable manual clearing without removing the component.
* Don't add a measure unless `UiImageMode::Auto` is set in
`update_image_content_size_system`. Mutably deref the `Mut<ContentSize>`
if the `UiImage` is changed to force removal of any existing measure
func.

## Testing
Remove all the constraints from the ui_texture_slice example:

```rust
//! This example illustrates how to create buttons with their textures 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, &Children, &mut UiImage),
        (Changed<Interaction>, With<Button>),
    >,
    mut text_query: Query<&mut Text>,
) {
    for (interaction, 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();
                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>) {
    let image = asset_server.load("textures/fantasy_ui_borders/panel-border-010.png");

    let slicer = TextureSlicer {
        border: BorderRect::square(22.0),
        center_scale_mode: SliceScaleMode::Stretch,
        sides_scale_mode: SliceScaleMode::Stretch,
        max_corner_scale: 1.0,
    };
    // ui camera
    commands.spawn(Camera2d);
    commands
        .spawn(Node {
            width: Val::Percent(100.0),
            height: Val::Percent(100.0),
            align_items: AlignItems::Center,
            justify_content: JustifyContent::Center,
            ..default()
        })
        .with_children(|parent| {
            for [w, h] in [[150.0, 150.0], [300.0, 150.0], [150.0, 300.0]] {
                parent
                    .spawn((
                        Button,
                        Node {
                            // 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::new(image.clone()),
                        ImageScaleMode::Sliced(slicer.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)),
                        // ));
                    });
            }
        });
}
```

This should result in a blank window, since without any constraints the
texture slice image nodes should be zero-sized. But in main the image
nodes are given the size of the underlying unsliced source image
`textures/fantasy_ui_borders/panel-border-010.png`:

<img width="321" alt="slicing"
src="https://github.com/user-attachments/assets/cbd74c9c-14cd-4b4d-93c6-7c0152bb05ee">

For this PR need to change the lines:
```
                        UiImage::new(image.clone()),
                        ImageScaleMode::Sliced(slicer.clone()),
```
to
```
                        UiImage::new(image.clone()).with_mode(UiImageMode::Sliced(slicer.clone()),
```
and then nothing should be rendered, as desired.

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Rendering Drawing game state to the screen A-UI Graphical user interfaces, styles, layouts, and widgets C-Bug An unexpected or incorrect behavior D-Straightforward Simple bug fixes and API improvements, docs, test and examples M-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

texture sliced UI nodes are sized intrinsically since required components changes

6 participants