bevy/crates/bevy_ui/src/widget/image.rs
ickshonpe 8545580214 text aspect ratio bug fix (#6825)
## Objective 

Bevy UI uses a `MeasureFunc` that preserves the aspect ratio of text, not just images. This means that the extent of flex-items containing text may be calculated incorrectly depending on the ratio of the text size compared to the size of its containing node.

Fixes #6748 
Related to #6724

with Bevy 0.9:

![Capture_cols_0 9](https://user-images.githubusercontent.com/27962798/205435999-386d3400-fe9b-475a-aab1-18e61c4c074f.PNG)

with this PR (accurately matching the behavior of Flexbox):

![Capture_fixed](https://user-images.githubusercontent.com/27962798/205436005-6bafbcc2-cd87-4eb7-b5c6-9dbcb30fc795.PNG)

## Solution
Only perform the aspect ratio calculations if the uinode contains an image.

## Changelog
* Added a field `preserve_aspect_ratio` to `CalculatedSize`
* The `MeasureFunc` only preserves the aspect ratio when `preserve_aspect_ratio` is true.
* `update_image_calculated_size_system` sets `preserve_aspect_ratio` to true for nodes with images.
2022-12-20 16:44:12 +00:00

28 lines
1,001 B
Rust

use crate::{CalculatedSize, Size, UiImage, Val};
use bevy_asset::Assets;
use bevy_ecs::{
query::Without,
system::{Query, Res},
};
use bevy_render::texture::Image;
use bevy_text::Text;
/// Updates calculated size of the node based on the image provided
pub fn update_image_calculated_size_system(
textures: Res<Assets<Image>>,
mut query: Query<(&mut CalculatedSize, &UiImage), Without<Text>>,
) {
for (mut calculated_size, image) in &mut query {
if let Some(texture) = textures.get(&image.texture) {
let size = Size {
width: Val::Px(texture.texture_descriptor.size.width as f32),
height: Val::Px(texture.texture_descriptor.size.height as f32),
};
// Update only if size has changed to avoid needless layout calculations
if size != calculated_size.size {
calculated_size.size = size;
calculated_size.preserve_aspect_ratio = true;
}
}
}
}