Skip to content

Commit

Permalink
This reverts commit fb50589.
Browse files Browse the repository at this point in the history
  • Loading branch information
ickshonpe committed Apr 20, 2023
1 parent 6385799 commit 3849a09
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 37 deletions.
32 changes: 23 additions & 9 deletions crates/bevy_ui/src/layout/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use bevy_utils::HashMap;
use bevy_window::{PrimaryWindow, Window, WindowResolution, WindowScaleFactorChanged};
use std::fmt;
use taffy::{
prelude::Size,
prelude::{AvailableSpace, Size},
style_helpers::TaffyMaxContent,
Taffy,
};
Expand Down Expand Up @@ -91,11 +91,25 @@ impl UiSurface {
}
}

pub fn update_measure(&mut self, entity: Entity, content_size: &mut ContentSize) {
if let Some(measure_func) = content_size.measure_func.take() {
let taffy_node = self.entity_to_taffy.get(&entity).unwrap();
self.taffy.set_measure(*taffy_node, Some(taffy::node::MeasureFunc::Boxed(measure_func))).ok();
}
pub fn update_measure(&mut self, entity: Entity, content_size: &ContentSize) {
let measure = content_size.measure.dyn_clone();
let measure_func = taffy::node::MeasureFunc::Boxed(Box::new(
move |constraints: Size<Option<f32>>, available: Size<AvailableSpace>| {
let size = measure.measure(
constraints.width,
constraints.height,
available.width,
available.height,
);
taffy::geometry::Size {
width: size.x,
height: size.y,
}
},
));

let taffy_node = self.entity_to_taffy.get(&entity).unwrap();
self.taffy.set_measure(*taffy_node, Some(measure_func)).ok();
}

pub fn update_children(&mut self, entity: Entity, children: &Children) {
Expand Down Expand Up @@ -216,7 +230,7 @@ pub fn ui_layout_system(
mut ui_surface: ResMut<UiSurface>,
root_node_query: Query<Entity, (With<Node>, Without<Parent>)>,
style_query: Query<(Entity, Ref<Style>), With<Node>>,
mut measure_query: Query<(Entity, &mut ContentSize)>,
measure_query: Query<(Entity, Ref<ContentSize>)>,
children_query: Query<(Entity, &Children), (With<Node>, Changed<Children>)>,
mut removed_children: RemovedComponents<Children>,
mut removed_content_sizes: RemovedComponents<ContentSize>,
Expand Down Expand Up @@ -266,9 +280,9 @@ pub fn ui_layout_system(
}
}

for (entity, mut content_size) in measure_query.iter_mut() {
for (entity, content_size) in measure_query.iter() {
if content_size.is_changed() {
ui_surface.update_measure(entity, &mut content_size);
ui_surface.update_measure(entity, &content_size);
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ impl Plugin for UiPlugin {
#[cfg(feature = "bevy_text")]
app.add_plugin(accessibility::AccessibilityPlugin);
app.add_systems(PostUpdate, {
let system = widget::update_image_content_size_system.before(UiSystem::Layout);
let system = widget::update_image_calculated_size_system.before(UiSystem::Layout);
// Potential conflicts: `Assets<Image>`
// They run independently since `widget::image_node_system` will only ever observe
// its own UiImage, and `widget::text_system` & `bevy_text::update_text2d_layout`
Expand Down
37 changes: 18 additions & 19 deletions crates/bevy_ui/src/measurement.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use bevy_ecs::prelude::Component;
use bevy_ecs::reflect::ReflectComponent;
use bevy_math::Vec2;
use bevy_reflect::Reflect;
use taffy::node::Measurable;
use std::fmt::Formatter;
pub use taffy::style::AvailableSpace;

Expand All @@ -23,6 +21,9 @@ pub trait Measure: Send + Sync + 'static {
available_width: AvailableSpace,
available_height: AvailableSpace,
) -> Vec2;

/// Clone and box self.
fn dyn_clone(&self) -> Box<dyn Measure>;
}

/// A `FixedMeasure` is a `Measure` that ignores all constraints and
Expand All @@ -42,37 +43,35 @@ impl Measure for FixedMeasure {
) -> Vec2 {
self.size
}

fn dyn_clone(&self) -> Box<dyn Measure> {
Box::new(self.clone())
}
}

/// A node with a `ContentSize` component is a node where its size
/// is based on its content.
#[derive(Component, Reflect)]
#[reflect(Component)]
pub struct ContentSize {
/// The `Measure` used to compute the intrinsic size
#[reflect(ignore)]
pub (crate) measure_func: Option<Box<dyn Measurable>>,
pub measure: Box<dyn Measure>,
}

impl ContentSize {
pub fn new(measure: impl Measure) -> Self {
let measure_func = move |size: taffy::prelude::Size<Option<f32>>, available: taffy::prelude::Size<AvailableSpace>| {
let size = measure.measure(size.width, size.height, available.width, available.height);
taffy::prelude::Size {
width: size.x,
height: size.y,
}
};
#[allow(clippy::derivable_impls)]
impl Default for ContentSize {
fn default() -> Self {
Self {
measure_func: Some(Box::new(measure_func))
// Default `FixedMeasure` always returns zero size.
measure: Box::<FixedMeasure>::default(),
}
}
}

#[allow(clippy::derivable_impls)]
impl Default for ContentSize {
fn default() -> Self {
Self::new(FixedMeasure::default())
impl Clone for ContentSize {
fn clone(&self) -> Self {
Self {
measure: self.measure.dyn_clone(),
}
}
}

4 changes: 2 additions & 2 deletions crates/bevy_ui/src/node_bundles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl Default for NodeBundle {
}

/// A UI node that is an image
#[derive(Bundle, Debug, Default)]
#[derive(Bundle, Clone, Debug, Default)]
pub struct ImageBundle {
/// Describes the logical size of the node
///
Expand Down Expand Up @@ -107,7 +107,7 @@ pub struct ImageBundle {

#[cfg(feature = "bevy_text")]
/// A UI node that is text
#[derive(Bundle, Debug)]
#[derive(Bundle, Clone, Debug)]
pub struct TextBundle {
/// Describes the logical size of the node
pub node: Node,
Expand Down
12 changes: 8 additions & 4 deletions crates/bevy_ui/src/widget/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,14 @@ impl Measure for ImageMeasure {
}
size
}

fn dyn_clone(&self) -> Box<dyn Measure> {
Box::new(self.clone())
}
}

/// Updates content size of the node based on the image provided
pub fn update_image_content_size_system(
/// Updates calculated size of the node based on the image provided
pub fn update_image_calculated_size_system(
textures: Res<Assets<Image>>,
#[cfg(feature = "bevy_text")] mut query: Query<
(&mut ContentSize, &UiImage, &mut UiImageSize),
Expand All @@ -72,7 +76,7 @@ pub fn update_image_content_size_system(
With<Node>,
>,
) {
for (mut content_size, image, mut image_size) in &mut query {
for (mut calculated_size, image, mut image_size) in &mut query {
if let Some(texture) = textures.get(&image.texture) {
let size = Vec2::new(
texture.texture_descriptor.size.width as f32,
Expand All @@ -81,7 +85,7 @@ pub fn update_image_content_size_system(
// Update only if size has changed to avoid needless layout calculations
if size != image_size.size {
image_size.size = size;
*content_size = ContentSize::new(ImageMeasure { size });
calculated_size.measure = Box::new(ImageMeasure { size });
}
}
}
Expand Down
8 changes: 6 additions & 2 deletions crates/bevy_ui/src/widget/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ impl Measure for TextMeasure {
)
.ceil()
}

fn dyn_clone(&self) -> Box<dyn Measure> {
Box::new(self.clone())
}
}

/// Creates a `Measure` for text nodes that allows the UI to determine the appropriate amount of space
Expand Down Expand Up @@ -99,7 +103,7 @@ pub fn measure_text_system(
let mut new_queue = Vec::new();
let mut query = text_queries.p2();
for entity in queued_text.drain(..) {
if let Ok((text, mut content_size)) = query.get_mut(entity) {
if let Ok((text, mut calculated_size)) = query.get_mut(entity) {
match text_pipeline.create_text_measure(
&fonts,
&text.sections,
Expand All @@ -108,7 +112,7 @@ pub fn measure_text_system(
text.linebreak_behavior,
) {
Ok(measure) => {
*content_size = ContentSize::new(TextMeasure { info: measure });
calculated_size.measure = Box::new(TextMeasure { info: measure });
}
Err(TextError::NoSuchFont) => {
new_queue.push(entity);
Expand Down

0 comments on commit 3849a09

Please sign in to comment.