mirror of
https://github.com/bevyengine/bevy
synced 2024-12-23 11:33:06 +00:00
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.
76 lines
2.3 KiB
Rust
76 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
|
|
}
|
|
}
|