Skip to content

Commit

Permalink
Remove implicit root nodes from bevy_ui
Browse files Browse the repository at this point in the history
  • Loading branch information
nicoburns committed Aug 29, 2023
1 parent bc8bf34 commit 599d257
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 52 deletions.
22 changes: 12 additions & 10 deletions crates/bevy_ui/src/layout/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,19 @@ pub fn print_ui_layout_tree(ui_surface: &UiSurface) {
.iter()
.map(|(entity, node)| (*node, *entity))
.collect();
for (&entity, &node) in ui_surface.window_nodes.iter() {
for (&entity, nodes) in ui_surface.window_root_nodes.iter() {
let mut out = String::new();
print_node(
ui_surface,
&taffy_to_entity,
entity,
node,
false,
String::new(),
&mut out,
);
for node in nodes {
print_node(
ui_surface,
&taffy_to_entity,
entity,
*node,
false,
String::new(),
&mut out,
);
}
bevy_log::info!("Layout tree for window entity: {entity:?}\n{out}");
}
}
Expand Down
60 changes: 18 additions & 42 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_transform::components::Transform;
use bevy_utils::HashMap;
use bevy_window::{PrimaryWindow, Window, WindowResolution, WindowScaleFactorChanged};
use std::fmt;
use taffy::{prelude::Size, style_helpers::TaffyMaxContent, Taffy};
use taffy::Taffy;

pub struct LayoutContext {
pub scale_factor: f64,
Expand All @@ -42,7 +42,7 @@ impl LayoutContext {
#[derive(Resource)]
pub struct UiSurface {
entity_to_taffy: HashMap<Entity, taffy::node::Node>,
window_nodes: HashMap<Entity, taffy::node::Node>,
window_root_nodes: HashMap<Entity, Vec<taffy::node::Node>>,
taffy: Taffy,
}

Expand All @@ -57,7 +57,7 @@ impl fmt::Debug for UiSurface {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("UiSurface")
.field("entity_to_taffy", &self.entity_to_taffy)
.field("window_nodes", &self.window_nodes)
.field("window_nodes", &self.window_root_nodes)
.finish()
}
}
Expand All @@ -68,7 +68,7 @@ impl Default for UiSurface {
taffy.disable_rounding();
Self {
entity_to_taffy: Default::default(),
window_nodes: Default::default(),
window_root_nodes: Default::default(),
taffy,
}
}
Expand Down Expand Up @@ -132,50 +132,29 @@ without UI components as a child of an entity with UI components, results may be
}
}

/// Retrieve or insert the root layout node and update its size to match the size of the window.
pub fn update_window(&mut self, window: Entity, window_resolution: &WindowResolution) {
let taffy = &mut self.taffy;
let node = self
.window_nodes
.entry(window)
.or_insert_with(|| taffy.new_leaf(taffy::style::Style::default()).unwrap());

taffy
.set_style(
*node,
taffy::style::Style {
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(
window_resolution.physical_width() as f32
),
height: taffy::style::Dimension::Points(
window_resolution.physical_height() as f32,
),
},
..Default::default()
},
)
.unwrap();
}

/// Set the ui node entities without a [`Parent`] as children to the root node in the taffy layout.
pub fn set_window_children(
&mut self,
parent_window: Entity,
children: impl Iterator<Item = Entity>,
) {
let taffy_node = self.window_nodes.get(&parent_window).unwrap();
let child_nodes = children
.map(|e| *self.entity_to_taffy.get(&e).unwrap())
.collect::<Vec<taffy::node::Node>>();
self.taffy.set_children(*taffy_node, &child_nodes).unwrap();
.collect();
self.window_root_nodes.insert(parent_window, child_nodes);
}

/// Compute the layout for each window entity's corresponding root node in the layout.
pub fn compute_window_layouts(&mut self) {
for window_node in self.window_nodes.values() {
pub fn compute_window_layout(&mut self, window: Entity, window_resolution: &WindowResolution) {
let available_space = taffy::geometry::Size {
width: taffy::style::AvailableSpace::Definite(window_resolution.physical_width() as f32),
height: taffy::style::AvailableSpace::Definite(
window_resolution.physical_height() as f32
),
};
for root_node in self.window_root_nodes.get(&window).unwrap() {
self.taffy
.compute_layout(*window_node, Size::MAX_CONTENT)
.compute_layout(*root_node, available_space)
.unwrap();
}
}
Expand Down Expand Up @@ -251,11 +230,6 @@ pub fn ui_layout_system(
.iter()
.any(|resized_window| resized_window.window == primary_window_entity);

// update window root nodes
for (entity, window) in windows.iter() {
ui_surface.update_window(entity, &window.resolution);
}

let scale_factor = logical_to_physical_factor * ui_scale.0;

let layout_context = LayoutContext::new(scale_factor, physical_size);
Expand Down Expand Up @@ -302,7 +276,9 @@ pub fn ui_layout_system(
}

// compute layouts
ui_surface.compute_window_layouts();
for (entity, window) in windows.iter() {
ui_surface.compute_window_layout(entity, &window.resolution);
}

let inverse_target_scale_factor = 1. / scale_factor;

Expand Down
2 changes: 2 additions & 0 deletions examples/games/game_menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ mod splash {
align_items: AlignItems::Center,
justify_content: JustifyContent::Center,
width: Val::Percent(100.0),
height: Val::Percent(100.0),
..default()
},
..default()
Expand Down Expand Up @@ -151,6 +152,7 @@ mod game {
NodeBundle {
style: Style {
width: Val::Percent(100.0),
height: Val::Percent(100.0),
// center children
align_items: AlignItems::Center,
justify_content: JustifyContent::Center,
Expand Down
1 change: 1 addition & 0 deletions examples/ui/relative_cursor_position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
.spawn(NodeBundle {
style: Style {
width: Val::Percent(100.),
height: Val::Percent(100.0),
align_items: AlignItems::Center,
justify_content: JustifyContent::Center,
flex_direction: FlexDirection::Column,
Expand Down
1 change: 1 addition & 0 deletions examples/ui/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
.spawn(NodeBundle {
style: Style {
width: Val::Percent(100.0),
height: Val::Percent(100.0),
justify_content: JustifyContent::SpaceBetween,
..default()
},
Expand Down

0 comments on commit 599d257

Please sign in to comment.