Skip to content

Commit

Permalink
Re-add ControlNode for UI
Browse files Browse the repository at this point in the history
`ControlNode`s where added in bevyengine#2908 in main, while bevy_ui2 was being developped in the pipelined-rendering branch.
  • Loading branch information
Davier committed Dec 3, 2021
1 parent 336d2f2 commit 3819bc5
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 15 deletions.
12 changes: 11 additions & 1 deletion pipelined/bevy_ui2/src/entity.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::{
widget::{Button, ImageMode},
CalculatedSize, FocusPolicy, Interaction, Node, Style, UiColor, UiImage, CAMERA_UI,
CalculatedSize, ControlNode, FocusPolicy, Interaction, Node, Style, UiColor, UiImage,
CAMERA_UI,
};
use bevy_ecs::bundle::Bundle;
use bevy_render2::{
Expand All @@ -10,6 +11,15 @@ use bevy_render2::{
use bevy_text2::Text;
use bevy_transform::prelude::{GlobalTransform, Transform};

/// If you add this to an entity, it should be the *only* bundle on it from bevy_ui.
/// This bundle will mark the entity as transparent to the UI layout system, meaning the
/// children of this entity will be treated as the children of this entity s parent by the layout system.
pub struct ControlBundle {
pub control_node: ControlNode,
pub transform: Transform,
pub global_transform: GlobalTransform,
}

#[derive(Bundle, Clone, Debug, Default)]
pub struct NodeBundle {
pub node: Node,
Expand Down
96 changes: 83 additions & 13 deletions pipelined/bevy_ui2/src/flex/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mod convert;

use crate::{CalculatedSize, Node, Style};
use crate::{CalculatedSize, ControlNode, Node, Style};
use bevy_app::EventReader;
use bevy_ecs::{
entity::Entity,
Expand Down Expand Up @@ -111,19 +111,62 @@ impl FlexSurface {
}
}

pub fn update_children(&mut self, entity: Entity, children: &Children) {
pub fn update_children(
&mut self,
entity: Entity,
children: &Children,
control_node_query: &mut Query<&mut ControlNode>,
unfiltered_children_query: &Query<&Children>,
) {
let mut stretch_children = Vec::with_capacity(children.len());
for child in children.iter() {
if let Some(stretch_node) = self.entity_to_stretch.get(child) {
stretch_children.push(*stretch_node);
fn inner(
true_parent: Entity,
child: Entity,
control_node_query: &mut Query<&mut ControlNode>,
unfiltered_children_query: &Query<&Children>,
do_on_real: &mut impl FnMut(Entity),
) {
if let Ok(mut control_node) = control_node_query.get_mut(child) {
control_node.true_parent = Some(true_parent);
for &child in unfiltered_children_query
.get(child)
.ok()
.into_iter()
.map(|c| &**c)
.flatten()
{
inner(
true_parent,
child,
control_node_query,
unfiltered_children_query,
do_on_real,
);
}
} else {
warn!(
"Unstyled child in a UI entity hierarchy. You are using an entity \
without UI components as a child of an entity with UI components, results may be unexpected."
);
do_on_real(child);
}
}

for &child in children.iter() {
inner(
entity,
child,
control_node_query,
unfiltered_children_query,
&mut |e| {
if let Some(stretch_node) = self.entity_to_stretch.get(&e) {
stretch_children.push(*stretch_node);
} else {
warn!(
"Unstyled child in a UI entity hierarchy. You are using an entity \
without UI components as a child of an entity with UI components, results may be unexpected."
);
}
},
);
}

let stretch_node = self.entity_to_stretch.get(&entity).unwrap();
self.stretch
.set_children(*stretch_node, stretch_children)
Expand Down Expand Up @@ -207,7 +250,10 @@ pub fn flex_node_system(
(Entity, &Style, &CalculatedSize),
(With<Node>, Changed<CalculatedSize>),
>,
children_query: Query<(Entity, &Children), (With<Node>, Changed<Children>)>,
changed_children_query: Query<(Entity, &Children), (With<Node>, Changed<Children>)>,
unfiltered_children_query: Query<&Children>,
mut control_node_query: Query<&mut ControlNode>,
changed_cnc_query: Query<Entity, (Changed<Children>, With<ControlNode>)>,
mut node_transform_query: Query<(Entity, &mut Node, &mut Transform, Option<&Parent>)>,
) {
// update window root nodes
Expand Down Expand Up @@ -262,8 +308,28 @@ pub fn flex_node_system(
}

// update children
for (entity, children) in children_query.iter() {
flex_surface.update_children(entity, children);
for (entity, children) in changed_children_query.iter() {
flex_surface.update_children(
entity,
children,
&mut control_node_query,
&unfiltered_children_query,
);
}

for entity in changed_cnc_query.iter() {
let true_parent = if let Some(e) = control_node_query.get_mut(entity).unwrap().true_parent {
e
} else {
continue;
};
let children = unfiltered_children_query.get(true_parent).unwrap();
flex_surface.update_children(
true_parent,
children,
&mut control_node_query,
&unfiltered_children_query,
);
}

// compute layouts
Expand All @@ -284,7 +350,11 @@ pub fn flex_node_system(
position.x = to_logical(layout.location.x + layout.size.width / 2.0);
position.y = to_logical(layout.location.y + layout.size.height / 2.0);
if let Some(parent) = parent {
if let Ok(parent_layout) = flex_surface.get_layout(parent.0) {
let parent = control_node_query
.get_mut(parent.0)
.map(|cn| cn.true_parent.unwrap())
.unwrap_or(parent.0);
if let Ok(parent_layout) = flex_surface.get_layout(parent) {
position.x -= to_logical(parent_layout.size.width / 2.0);
position.y -= to_logical(parent_layout.size.height / 2.0);
}
Expand Down
10 changes: 9 additions & 1 deletion pipelined/bevy_ui2/src/ui_node.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use bevy_asset::Handle;
use bevy_ecs::{prelude::Component, reflect::ReflectComponent};
use bevy_ecs::{prelude::*, reflect::ReflectComponent};
use bevy_math::{Rect, Size, Vec2};
use bevy_reflect::{Reflect, ReflectDeserialize};
use bevy_render2::{color::Color, texture::Image};
Expand All @@ -12,6 +12,14 @@ pub struct Node {
pub size: Vec2,
}

/// If you add this to an entity, it should be the *only* component on it from bevy_ui.
/// This component marks an entity as "transparent" to the UI layout system, meaning the
/// children of this entity will be treated as the children of this entity s parent by the layout system.
#[derive(Clone, Default, Component)]
pub struct ControlNode {
pub(crate) true_parent: Option<Entity>,
}

#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize, Reflect)]
#[reflect_value(PartialEq, Serialize, Deserialize)]
pub enum Val {
Expand Down

0 comments on commit 3819bc5

Please sign in to comment.