 fe37ba5360
			
		
	
	
		fe37ba5360
		
			
		
	
	
	
	
		
			
			# Objective The default for `ContentSize` should have the `measure_func` field set to `None`, instead of a fixed size of zero. This means that until a measure func is set the size of the UI node will be determined by its `Style` constraints. This is preferable as it allows users to specify the space the Node should take up in the layout while waiting for content to load. ## Solution Derive `Default` for `ContentSize`. The PR also adds a `fixed_size` helper function to make it a bit easier to access the old behaviour. ## Changelog * Derived `Default` for `ContentSize` * Added a `fixed_size` helper function to `ContentSize` that creates a new `ContentSize` with a `MeasureFunc` that always returns the same value, regardless of layout constraints. ## Migration Guide The default for `ContentSize` now sets its `measure_func` to `None`, instead of a fixed size measure that returns `Vec2::ZERO`. The helper function `fixed_size` can be called with `ContentSize::fixed_size(Vec2::ZERO)` to get the previous behaviour.
		
			
				
	
	
		
			77 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			77 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| use bevy_ecs::prelude::Component;
 | |
| use bevy_ecs::reflect::ReflectComponent;
 | |
| use bevy_math::Vec2;
 | |
| use bevy_reflect::{std_traits::ReflectDefault, Reflect};
 | |
| use std::fmt::Formatter;
 | |
| pub use taffy::style::AvailableSpace;
 | |
| use taffy::{node::MeasureFunc, prelude::Size as TaffySize};
 | |
| 
 | |
| impl std::fmt::Debug for ContentSize {
 | |
|     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
 | |
|         f.debug_struct("ContentSize").finish()
 | |
|     }
 | |
| }
 | |
| 
 | |
| /// A `Measure` is used to compute the size of a ui node
 | |
| /// when the size of that node is based on its content.
 | |
| pub trait Measure: Send + Sync + 'static {
 | |
|     /// Calculate the size of the node given the constraints.
 | |
|     fn measure(
 | |
|         &self,
 | |
|         width: Option<f32>,
 | |
|         height: Option<f32>,
 | |
|         available_width: AvailableSpace,
 | |
|         available_height: AvailableSpace,
 | |
|     ) -> Vec2;
 | |
| }
 | |
| 
 | |
| /// A `FixedMeasure` is a `Measure` that ignores all constraints and
 | |
| /// always returns the same size.
 | |
| #[derive(Default, Clone)]
 | |
| pub struct FixedMeasure {
 | |
|     pub size: Vec2,
 | |
| }
 | |
| 
 | |
| impl Measure for FixedMeasure {
 | |
|     fn measure(
 | |
|         &self,
 | |
|         _: Option<f32>,
 | |
|         _: Option<f32>,
 | |
|         _: AvailableSpace,
 | |
|         _: AvailableSpace,
 | |
|     ) -> Vec2 {
 | |
|         self.size
 | |
|     }
 | |
| }
 | |
| 
 | |
| /// A node with a `ContentSize` component is a node where its size
 | |
| /// is based on its content.
 | |
| #[derive(Component, Reflect, Default)]
 | |
| #[reflect(Component, Default)]
 | |
| pub struct ContentSize {
 | |
|     /// The `Measure` used to compute the intrinsic size
 | |
|     #[reflect(ignore)]
 | |
|     pub(crate) measure_func: Option<MeasureFunc>,
 | |
| }
 | |
| 
 | |
| impl ContentSize {
 | |
|     /// Set a `Measure` for the UI node entity with this component
 | |
|     pub fn set(&mut self, measure: impl Measure) {
 | |
|         let measure_func = move |size: TaffySize<_>, available: TaffySize<_>| {
 | |
|             let size = measure.measure(size.width, size.height, available.width, available.height);
 | |
|             TaffySize {
 | |
|                 width: size.x,
 | |
|                 height: size.y,
 | |
|             }
 | |
|         };
 | |
|         self.measure_func = Some(MeasureFunc::Boxed(Box::new(measure_func)));
 | |
|     }
 | |
| 
 | |
|     /// Creates a `ContentSize` with a `Measure` that always returns given `size` argument, regardless of the UI layout's constraints.
 | |
|     pub fn fixed_size(size: Vec2) -> ContentSize {
 | |
|         let mut content_size = Self::default();
 | |
|         content_size.set(FixedMeasure { size });
 | |
|         content_size
 | |
|     }
 | |
| }
 |