mirror of
https://github.com/bevyengine/bevy.git
synced 2026-06-29 23:35:35 -04:00
6dca76afcf
# Objective Allow UI elements to be positioned relative to the viewport rather than their parent element. Fixes #9564 ## Solution - New UI marker component `FixedNode`. Requires `Node` and `OverrideClip`. - `FixedNode` entities are treated as UI roots in layout, even if they have a parent. - `FixedNode`s don't inherit their parent's layout, clipping or transform context. - During the taffy layout updates children with `FixedNode` are skipped. - Added a couple of basic helper functions to `UiSurface`, mainly there to make the tests a little less painful. - Added a fairly comprehensive range of new tests, including tests with `GhostNode`s. - In the Taffy layout (stored in `UiSurface`) there is nothing to distinguish `FixedNode`s and root nodes, so they are treated identically during updates. -- The original suggestion was to implement it as a `PositionType::Fixed` variant that could used with `Node`, but I think that would be much more complicated without support from Taffy. Being able to just directly query for and filter out `FixedNode` entities directly makes the implementation much simpler and more efficient. ## Testing Basic example which shows events bubbling up to the parent from the fixed node: ``` cargo run --example fixed_node ``` There are also a number of new tests in the `layout` module. ``` cargo test -p bevy_ui --lib --features ghost_nodes ``` --------- Co-authored-by: François Mockers <francois.mockers@vleue.com>
50 lines
1.4 KiB
Rust
50 lines
1.4 KiB
Rust
//! Demonstrates how to use `FixedNode` to lay out a UI node as a root node
|
|
|
|
use bevy::color::palettes::css::BLUE;
|
|
use bevy::color::palettes::css::RED;
|
|
use bevy::color::palettes::css::YELLOW;
|
|
use bevy::prelude::*;
|
|
|
|
fn main() {
|
|
App::new()
|
|
.add_plugins(DefaultPlugins)
|
|
.add_systems(Startup, setup)
|
|
.run();
|
|
}
|
|
|
|
fn setup(mut commands: Commands) {
|
|
commands.spawn(Camera2d);
|
|
|
|
commands
|
|
.spawn((
|
|
Node {
|
|
width: percent(100),
|
|
height: percent(100),
|
|
align_items: AlignItems::Center,
|
|
justify_content: JustifyContent::Center,
|
|
..default()
|
|
},
|
|
BackgroundColor(BLUE.into()),
|
|
Pickable::IGNORE,
|
|
children![(
|
|
FixedNode,
|
|
Node {
|
|
width: px(100),
|
|
height: px(100),
|
|
..default()
|
|
},
|
|
BackgroundColor(YELLOW.into()),
|
|
)],
|
|
))
|
|
.observe(
|
|
|over: On<Pointer<Over>>, mut colors: Query<&mut BackgroundColor>| {
|
|
colors.get_mut(over.entity).unwrap().0 = RED.into();
|
|
},
|
|
)
|
|
.observe(
|
|
|over: On<Pointer<Leave>>, mut colors: Query<&mut BackgroundColor>| {
|
|
colors.get_mut(over.entity).unwrap().0 = BLUE.into();
|
|
},
|
|
);
|
|
}
|