1a6b94c5e8
				
			
			
		
	
	
		
			4 Commits
		
	
	
	| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|  ickshonpe | 56d5591028 | Multiple box shadow support (#16502) # Objective Add support for multiple box shadows on a single `Node`. ## Solution * Rename `BoxShadow` to `ShadowStyle` and remove its `Component` derive. * Create a new `BoxShadow` component that newtypes a `Vec<ShadowStyle>`. * Add a `new` constructor method to `BoxShadow` for single shadows. * Change `extract_shadows` to iterate through a list of shadows per node. Render order is determined implicitly from the order of the shadows stored in the `BoxShadow` component, back-to-front. Might be more efficient to use a `SmallVec<[ShadowStyle; 1]>` for the list of shadows but not sure if the extra friction is worth it. ## Testing Added a node with four differently coloured shadows to the `box_shadow` example. --- ## Showcase ``` cargo run --example box_shadow ``` <img width="460" alt="four-shadow" src="https://github.com/user-attachments/assets/2f728c47-33b4-42e1-96ba-28a774b94b24"> ## Migration Guide Bevy UI now supports multiple shadows per node. A new struct `ShadowStyle` is used to set the style for each shadow. And the `BoxShadow` component is changed to a tuple struct wrapping a vector containing a list of `ShadowStyle`s. To spawn a node with a single shadow you can use the `new` constructor function: ```rust commands.spawn(( Node::default(), BoxShadow::new( Color::BLACK.with_alpha(0.8), Val::Percent(offset.x), Val::Percent(offset.y), Val::Percent(spread), Val::Px(blur), ) )); ``` --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> | ||
|  Carter Anderson | 015f2c69ca | Merge Style properties into Node. Use ComputedNode for computed properties. (#15975) # Objective Continue improving the user experience of our UI Node API in the direction specified by [Bevy's Next Generation Scene / UI System](https://github.com/bevyengine/bevy/discussions/14437) ## Solution As specified in the document above, merge `Style` fields into `Node`, and move "computed Node fields" into `ComputedNode` (I chose this name over something like `ComputedNodeLayout` because it currently contains more than just layout info. If we want to break this up / rename these concepts, lets do that in a separate PR). `Style` has been removed. This accomplishes a number of goals: ## Ergonomics wins Specifying both `Node` and `Style` is now no longer required for non-default styles Before: ```rust commands.spawn(( Node::default(), Style { width: Val::Px(100.), ..default() }, )); ``` After: ```rust commands.spawn(Node { width: Val::Px(100.), ..default() }); ``` ## Conceptual clarity `Style` was never a comprehensive "style sheet". It only defined "core" style properties that all `Nodes` shared. Any "styled property" that couldn't fit that mold had to be in a separate component. A "real" style system would style properties _across_ components (`Node`, `Button`, etc). We have plans to build a true style system (see the doc linked above). By moving the `Style` fields to `Node`, we fully embrace `Node` as the driving concept and remove the "style system" confusion. ## Next Steps * Consider identifying and splitting out "style properties that aren't core to Node". This should not happen for Bevy 0.15. --- ## Migration Guide Move any fields set on `Style` into `Node` and replace all `Style` component usage with `Node`. Before: ```rust commands.spawn(( Node::default(), Style { width: Val::Px(100.), ..default() }, )); ``` After: ```rust commands.spawn(Node { width: Val::Px(100.), ..default() }); ``` For any usage of the "computed node properties" that used to live on `Node`, use `ComputedNode` instead: Before: ```rust fn system(nodes: Query<&Node>) { for node in &nodes { let computed_size = node.size(); } } ``` After: ```rust fn system(computed_nodes: Query<&ComputedNode>) { for computed_node in &computed_nodes { let computed_size = computed_node.size(); } } ``` | ||
|  VitalyR | eb19a9ea0b | Migrate UI bundles to required components (#15898) # Objective - Migrate UI bundles to required components, fixes #15889 ## Solution - deprecate `NodeBundle` in favor of `Node` - deprecate `ImageBundle` in favor of `UiImage` - deprecate `ButtonBundle` in favor of `Button` ## Testing CI. ## Migration Guide - Replace all uses of `NodeBundle` with `Node`. e.g. ```diff commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node::default(), + Style { width: Val::Percent(100.), align_items: AlignItems::Center, justify_content: JustifyContent::Center, ..default() }, - ..default() - }) + )) ``` - Replace all uses of `ButtonBundle` with `Button`. e.g. ```diff .spawn(( - ButtonBundle { - style: Style { - width: Val::Px(w), - height: Val::Px(h), - // horizontally center child text - justify_content: JustifyContent::Center, - // vertically center child text - align_items: AlignItems::Center, - margin: UiRect::all(Val::Px(20.0)), - ..default() - }, - image: image.clone().into(), + Button, + Style { + width: Val::Px(w), + height: Val::Px(h), + // horizontally center child text + justify_content: JustifyContent::Center, + // vertically center child text + align_items: AlignItems::Center, + margin: UiRect::all(Val::Px(20.0)), ..default() }, + UiImage::from(image.clone()), ImageScaleMode::Sliced(slicer.clone()), )) ``` - Replace all uses of `ImageBundle` with `UiImage`. e.g. ```diff - commands.spawn(ImageBundle { - image: UiImage { + commands.spawn(( + UiImage { texture: metering_mask, ..default() }, - style: Style { + Style { width: Val::Percent(100.0), height: Val::Percent(100.0), ..default() }, - ..default() - }); + )); ``` --------- Co-authored-by: Carter Anderson <mcanders1@gmail.com> | ||
|  ickshonpe | 99b9a2fcd7 | box shadow (#15204) # Objective
UI box shadow support
Adds a new component `BoxShadow`:
```rust
pub struct BoxShadow {
    /// The shadow's color
    pub color: Color,
    /// Horizontal offset
    pub x_offset: Val,
    /// Vertical offset
    pub y_offset: Val,
    /// Horizontal difference in size from the occluding uninode
    pub spread_radius: Val,
    /// Blurriness of the shadow
    pub blur_radius: Val,
}
```
To use `BoxShadow`, add the component to any Bevy UI node and a shadow
will be drawn beneath that node.
Also adds a resource `BoxShadowSamples` that can be used to adjust the
shadow quality.
#### Notes
* I'm not super happy with the field names. Maybe we need a `struct Size
{ width: Val, height: Val }` type or something.
* The shader isn't very optimised but I don't see that it's too
important for now as the number of shadows being rendered is not going
to be massive most of the time. I think it's more important to get the
API and geometry correct with this PR.
* I didn't implement an inset property, it's not essential and can
easily be added in a follow up.
* Shadows are only rendered for uinodes, not for images or text.
* Batching isn't supported, it would need out-of-the-scope-of-this-pr
changes to the way the UI handles z-ordering for it to be effective.
# Showcase
```cargo run --example box_shadow -- --samples 4```
<img width="391" alt="br" src="https://github.com/user-attachments/assets/4e8add96-dc93-46e0-9e35-d995eb0943ad">
```cargo run --example box_shadow -- --samples 10```
<img width="391" alt="s10"
src="https://github.com/user-attachments/assets/ecb384c9-4012-4cd6-9dea-5180904bf28e"> |