Skip to content

Commit

Permalink
ContentSize
Browse files Browse the repository at this point in the history
If you remove a `ContentSize` component from a Bevy UI entity and then immediately replace it `ui_layout_system` will remove the measure func from the internal Taffy layout tree but no new measure func will be generated to replace it since it's the widget systems that are responsible for creating their respective measure funcs not `ui_layout_system`. The widget systems only perform updates on changes to their content, and don't check `ContentSize` for changes. This means that until the content is changed in some way, no content will be displayed by the node.

This commit fixes this by performing `ui_layout_system`'s `ContentSize` removal detection and resolution first, before measure func updates and in the widget systems generating a new `Measure` when a  `ContentSize` component is added to a widget entity.
  • Loading branch information
ickshonpe committed Sep 10, 2023
1 parent 1980ac8 commit e99c2b1
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 8 deletions.
10 changes: 5 additions & 5 deletions crates/bevy_ui/src/layout/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,11 @@ pub fn ui_layout_system(
}
}

// When a `ContentSize` component is removed from an entity, we need to remove the measure from the corresponding taffy node.
for entity in removed_content_sizes.iter() {
ui_surface.try_remove_measure(entity);
}

for (entity, mut content_size) in measure_query.iter_mut() {
if let Some(measure_func) = content_size.measure_func.take() {
ui_surface.update_measure(entity, measure_func);
Expand All @@ -283,11 +288,6 @@ pub fn ui_layout_system(
// clean up removed nodes
ui_surface.remove_entities(removed_nodes.iter());

// When a `ContentSize` component is removed from an entity, we need to remove the measure from the corresponding taffy node.
for entity in removed_content_sizes.iter() {
ui_surface.try_remove_measure(entity);
}

// update window children (for now assuming all Nodes live in the primary window)
ui_surface.set_window_children(primary_window_entity, root_node_query.iter());

Expand Down
5 changes: 3 additions & 2 deletions crates/bevy_ui/src/widget/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::{
};
use bevy_asset::{Assets, Handle};

use bevy_ecs::change_detection::DetectChanges;
use bevy_ecs::query::Without;
use bevy_ecs::{
prelude::Component,
Expand Down Expand Up @@ -96,7 +97,7 @@ pub fn update_image_content_size_system(
texture.texture_descriptor.size.height as f32,
);
// Update only if size or scale factor has changed to avoid needless layout calculations
if size != image_size.size || combined_scale_factor != *previous_combined_scale_factor {
if size != image_size.size || combined_scale_factor != *previous_combined_scale_factor || content_size.is_added() {
image_size.size = size;
content_size.set(ImageMeasure {
// multiply the image size by the scale factor to get the physical size
Expand Down Expand Up @@ -135,7 +136,7 @@ pub fn update_atlas_content_size_system(
if let Some(atlas) = atlases.get(atlas) {
let size = atlas.textures[atlas_image.index].size();
// Update only if size or scale factor has changed to avoid needless layout calculations
if size != image_size.size || combined_scale_factor != *previous_combined_scale_factor {
if size != image_size.size || combined_scale_factor != *previous_combined_scale_factor || content_size.is_added() {
image_size.size = size;
content_size.set(ImageMeasure {
// multiply the image size by the scale factor to get the physical size
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ui/src/widget/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ pub fn measure_text_system(
if *last_scale_factor == scale_factor {
// scale factor unchanged, only create new measure funcs for modified text
for (text, content_size, text_flags) in text_query.iter_mut() {
if text.is_changed() || text_flags.needs_new_measure_func {
if text.is_changed() || text_flags.needs_new_measure_func || content_size.is_added() {
create_text_measure(&fonts, scale_factor, text, content_size, text_flags);
}
}
Expand Down

0 comments on commit e99c2b1

Please sign in to comment.