mirror of
https://github.com/bevyengine/bevy
synced 2024-11-25 06:00:20 +00:00
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(); } } ```
This commit is contained in:
parent
624f573443
commit
015f2c69ca
149 changed files with 1258 additions and 1616 deletions
|
@ -15,10 +15,9 @@ use bevy_ecs::{
|
||||||
use bevy_hierarchy::{BuildChildren, ChildBuild};
|
use bevy_hierarchy::{BuildChildren, ChildBuild};
|
||||||
use bevy_render::view::Visibility;
|
use bevy_render::view::Visibility;
|
||||||
use bevy_text::{Font, TextColor, TextFont, TextSpan};
|
use bevy_text::{Font, TextColor, TextFont, TextSpan};
|
||||||
use bevy_ui::Node;
|
|
||||||
use bevy_ui::{
|
use bevy_ui::{
|
||||||
widget::{Text, TextUiWriter},
|
widget::{Text, TextUiWriter},
|
||||||
GlobalZIndex, PositionType, Style,
|
GlobalZIndex, Node, PositionType,
|
||||||
};
|
};
|
||||||
use bevy_utils::default;
|
use bevy_utils::default;
|
||||||
|
|
||||||
|
@ -89,8 +88,7 @@ struct FpsText;
|
||||||
fn setup(mut commands: Commands, overlay_config: Res<FpsOverlayConfig>) {
|
fn setup(mut commands: Commands, overlay_config: Res<FpsOverlayConfig>) {
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
// We need to make sure the overlay doesn't affect the position of other UI nodes
|
// We need to make sure the overlay doesn't affect the position of other UI nodes
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
..default()
|
..default()
|
||||||
|
|
|
@ -15,7 +15,7 @@ use bevy_render::{
|
||||||
view::{RenderLayers, VisibilitySystems},
|
view::{RenderLayers, VisibilitySystems},
|
||||||
};
|
};
|
||||||
use bevy_transform::{prelude::GlobalTransform, TransformSystem};
|
use bevy_transform::{prelude::GlobalTransform, TransformSystem};
|
||||||
use bevy_ui::{DefaultUiCamera, Display, Node, Style, TargetCamera, UiScale};
|
use bevy_ui::{ComputedNode, DefaultUiCamera, Display, Node, TargetCamera, UiScale};
|
||||||
use bevy_utils::{default, warn_once};
|
use bevy_utils::{default, warn_once};
|
||||||
use bevy_window::{PrimaryWindow, Window, WindowRef};
|
use bevy_window::{PrimaryWindow, Window, WindowRef};
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ struct LayoutRect {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LayoutRect {
|
impl LayoutRect {
|
||||||
fn new(trans: &GlobalTransform, node: &Node, scale: f32) -> Self {
|
fn new(trans: &GlobalTransform, node: &ComputedNode, scale: f32) -> Self {
|
||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
pos: trans.translation().xy() * scale,
|
pos: trans.translation().xy() * scale,
|
||||||
size: node.size() * scale,
|
size: node.size() * scale,
|
||||||
|
@ -123,8 +123,8 @@ fn outline_nodes(outline: &OutlineParam, draw: &mut InsetGizmo, this_entity: Ent
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
for (entity, trans, node, style, children) in outline.nodes.iter_many(to_iter) {
|
for (entity, trans, node, computed_node, children) in outline.nodes.iter_many(to_iter) {
|
||||||
if style.is_none() || style.is_some_and(|s| matches!(s.display, Display::None)) {
|
if matches!(node.display, Display::None) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ fn outline_nodes(outline: &OutlineParam, draw: &mut InsetGizmo, this_entity: Ent
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let rect = LayoutRect::new(trans, node, scale);
|
let rect = LayoutRect::new(trans, computed_node, scale);
|
||||||
outline_node(entity, rect, draw);
|
outline_node(entity, rect, draw);
|
||||||
if children.is_some() {
|
if children.is_some() {
|
||||||
outline_nodes(outline, draw, entity, scale);
|
outline_nodes(outline, draw, entity, scale);
|
||||||
|
@ -146,7 +146,7 @@ type NodesQuery = (
|
||||||
Entity,
|
Entity,
|
||||||
&'static GlobalTransform,
|
&'static GlobalTransform,
|
||||||
&'static Node,
|
&'static Node,
|
||||||
Option<&'static Style>,
|
&'static ComputedNode,
|
||||||
Option<&'static Children>,
|
Option<&'static Children>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ fn outline_roots(
|
||||||
(
|
(
|
||||||
Entity,
|
Entity,
|
||||||
&GlobalTransform,
|
&GlobalTransform,
|
||||||
&Node,
|
&ComputedNode,
|
||||||
Option<&ViewVisibility>,
|
Option<&ViewVisibility>,
|
||||||
Option<&TargetCamera>,
|
Option<&TargetCamera>,
|
||||||
),
|
),
|
||||||
|
|
|
@ -352,9 +352,9 @@ unsafe impl<T: Component> QueryFilter for Without<T> {
|
||||||
/// # #[derive(Component, Debug)]
|
/// # #[derive(Component, Debug)]
|
||||||
/// # struct Color {};
|
/// # struct Color {};
|
||||||
/// # #[derive(Component)]
|
/// # #[derive(Component)]
|
||||||
/// # struct Style {};
|
/// # struct Node {};
|
||||||
/// #
|
/// #
|
||||||
/// fn print_cool_entity_system(query: Query<Entity, Or<(Changed<Color>, Changed<Style>)>>) {
|
/// fn print_cool_entity_system(query: Query<Entity, Or<(Changed<Color>, Changed<Node>)>>) {
|
||||||
/// for entity in &query {
|
/// for entity in &query {
|
||||||
/// println!("Entity {:?} got a new style or color", entity);
|
/// println!("Entity {:?} got a new style or color", entity);
|
||||||
/// }
|
/// }
|
||||||
|
|
|
@ -171,11 +171,11 @@ impl<'a, R: TextRoot> Iterator for TextSpanIter<'a, R> {
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
// Root
|
// Root
|
||||||
if let Some(root_entity) = self.root_entity.take() {
|
if let Some(root_entity) = self.root_entity.take() {
|
||||||
if let Ok((text, style, color, maybe_children)) = self.roots.get(root_entity) {
|
if let Ok((text, text_font, color, maybe_children)) = self.roots.get(root_entity) {
|
||||||
if let Some(children) = maybe_children {
|
if let Some(children) = maybe_children {
|
||||||
self.stack.push((children, 0));
|
self.stack.push((children, 0));
|
||||||
}
|
}
|
||||||
return Some((root_entity, 0, text.read_span(), style, color.0));
|
return Some((root_entity, 0, text.read_span(), text_font, color.0));
|
||||||
}
|
}
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -193,7 +193,7 @@ impl<'a, R: TextRoot> Iterator for TextSpanIter<'a, R> {
|
||||||
*idx += 1;
|
*idx += 1;
|
||||||
|
|
||||||
let entity = *child;
|
let entity = *child;
|
||||||
let Ok((span, style, color, maybe_children)) = self.spans.get(entity) else {
|
let Ok((span, text_font, color, maybe_children)) = self.spans.get(entity) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -201,7 +201,7 @@ impl<'a, R: TextRoot> Iterator for TextSpanIter<'a, R> {
|
||||||
if let Some(children) = maybe_children {
|
if let Some(children) = maybe_children {
|
||||||
self.stack.push((children, 0));
|
self.stack.push((children, 0));
|
||||||
}
|
}
|
||||||
return Some((entity, depth, span.read_span(), style, color.0));
|
return Some((entity, depth, span.read_span(), text_font, color.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// All children at this stack entry have been iterated.
|
// All children at this stack entry have been iterated.
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::{
|
||||||
experimental::UiChildren,
|
experimental::UiChildren,
|
||||||
prelude::{Button, Label},
|
prelude::{Button, Label},
|
||||||
widget::TextUiReader,
|
widget::TextUiReader,
|
||||||
Node, UiImage,
|
ComputedNode, UiImage,
|
||||||
};
|
};
|
||||||
use bevy_a11y::{
|
use bevy_a11y::{
|
||||||
accesskit::{NodeBuilder, Rect, Role},
|
accesskit::{NodeBuilder, Rect, Role},
|
||||||
|
@ -38,7 +38,11 @@ fn calc_name(
|
||||||
|
|
||||||
fn calc_bounds(
|
fn calc_bounds(
|
||||||
camera: Query<(&Camera, &GlobalTransform)>,
|
camera: Query<(&Camera, &GlobalTransform)>,
|
||||||
mut nodes: Query<(&mut AccessibilityNode, Ref<Node>, Ref<GlobalTransform>)>,
|
mut nodes: Query<(
|
||||||
|
&mut AccessibilityNode,
|
||||||
|
Ref<ComputedNode>,
|
||||||
|
Ref<GlobalTransform>,
|
||||||
|
)>,
|
||||||
) {
|
) {
|
||||||
if let Ok((camera, camera_transform)) = camera.get_single() {
|
if let Ok((camera, camera_transform)) = camera.get_single() {
|
||||||
for (mut accessible, node, transform) in &mut nodes {
|
for (mut accessible, node, transform) in &mut nodes {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
CalculatedClip, DefaultUiCamera, Node, ResolvedBorderRadius, TargetCamera, UiScale, UiStack,
|
CalculatedClip, ComputedNode, DefaultUiCamera, ResolvedBorderRadius, TargetCamera, UiScale,
|
||||||
|
UiStack,
|
||||||
};
|
};
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
change_detection::DetectChangesMut,
|
change_detection::DetectChangesMut,
|
||||||
|
@ -74,7 +75,7 @@ impl Default for Interaction {
|
||||||
///
|
///
|
||||||
/// It can be used alongside [`Interaction`] to get the position of the press.
|
/// It can be used alongside [`Interaction`] to get the position of the press.
|
||||||
///
|
///
|
||||||
/// The component is updated when it is in the same entity with [`Node`].
|
/// The component is updated when it is in the same entity with [`Node`](crate::Node).
|
||||||
#[derive(Component, Copy, Clone, Default, PartialEq, Debug, Reflect)]
|
#[derive(Component, Copy, Clone, Default, PartialEq, Debug, Reflect)]
|
||||||
#[reflect(Component, Default, PartialEq, Debug)]
|
#[reflect(Component, Default, PartialEq, Debug)]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
|
@ -135,7 +136,7 @@ pub struct State {
|
||||||
#[query_data(mutable)]
|
#[query_data(mutable)]
|
||||||
pub struct NodeQuery {
|
pub struct NodeQuery {
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
node: &'static Node,
|
node: &'static ComputedNode,
|
||||||
global_transform: &'static GlobalTransform,
|
global_transform: &'static GlobalTransform,
|
||||||
interaction: Option<&'static mut Interaction>,
|
interaction: Option<&'static mut Interaction>,
|
||||||
relative_cursor_position: Option<&'static mut RelativeCursorPosition>,
|
relative_cursor_position: Option<&'static mut RelativeCursorPosition>,
|
||||||
|
|
|
@ -8,7 +8,7 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
|
||||||
|
|
||||||
/// Represents the possible value types for layout properties.
|
/// Represents the possible value types for layout properties.
|
||||||
///
|
///
|
||||||
/// This enum allows specifying values for various [`Style`](crate::Style) properties in different units,
|
/// This enum allows specifying values for various [`Node`](crate::Node) properties in different units,
|
||||||
/// such as logical pixels, percentages, or automatically determined values.
|
/// such as logical pixels, percentages, or automatically determined values.
|
||||||
#[derive(Copy, Clone, Debug, Reflect)]
|
#[derive(Copy, Clone, Debug, Reflect)]
|
||||||
#[reflect(Default, PartialEq, Debug)]
|
#[reflect(Default, PartialEq, Debug)]
|
||||||
|
@ -18,7 +18,7 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
|
||||||
reflect(Serialize, Deserialize)
|
reflect(Serialize, Deserialize)
|
||||||
)]
|
)]
|
||||||
pub enum Val {
|
pub enum Val {
|
||||||
/// Automatically determine the value based on the context and other [`Style`](crate::Style) properties.
|
/// Automatically determine the value based on the context and other [`Node`](crate::Node) properties.
|
||||||
Auto,
|
Auto,
|
||||||
/// Set this value in logical pixels.
|
/// Set this value in logical pixels.
|
||||||
Px(f32),
|
Px(f32),
|
||||||
|
@ -27,7 +27,7 @@ pub enum Val {
|
||||||
/// If the UI node has no parent, the percentage is calculated based on the window's length
|
/// If the UI node has no parent, the percentage is calculated based on the window's length
|
||||||
/// along the corresponding axis.
|
/// along the corresponding axis.
|
||||||
///
|
///
|
||||||
/// The chosen axis depends on the [`Style`](crate::Style) field set:
|
/// The chosen axis depends on the [`Node`](crate::Node) field set:
|
||||||
/// * For `flex_basis`, the percentage is relative to the main-axis length determined by the `flex_direction`.
|
/// * For `flex_basis`, the percentage is relative to the main-axis length determined by the `flex_direction`.
|
||||||
/// * For `gap`, `min_size`, `size`, and `max_size`:
|
/// * For `gap`, `min_size`, `size`, and `max_size`:
|
||||||
/// - `width` is relative to the parent's width.
|
/// - `width` is relative to the parent's width.
|
||||||
|
|
|
@ -3,8 +3,8 @@ use taffy::style_helpers;
|
||||||
use crate::{
|
use crate::{
|
||||||
AlignContent, AlignItems, AlignSelf, Display, FlexDirection, FlexWrap, GridAutoFlow,
|
AlignContent, AlignItems, AlignSelf, Display, FlexDirection, FlexWrap, GridAutoFlow,
|
||||||
GridPlacement, GridTrack, GridTrackRepetition, JustifyContent, JustifyItems, JustifySelf,
|
GridPlacement, GridTrack, GridTrackRepetition, JustifyContent, JustifyItems, JustifySelf,
|
||||||
MaxTrackSizingFunction, MinTrackSizingFunction, OverflowAxis, PositionType, RepeatedGridTrack,
|
MaxTrackSizingFunction, MinTrackSizingFunction, Node, OverflowAxis, PositionType,
|
||||||
Style, UiRect, Val,
|
RepeatedGridTrack, UiRect, Val,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::LayoutContext;
|
use super::LayoutContext;
|
||||||
|
@ -63,37 +63,33 @@ impl UiRect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_style(
|
pub fn from_node(node: &Node, context: &LayoutContext, ignore_border: bool) -> taffy::style::Style {
|
||||||
context: &LayoutContext,
|
|
||||||
style: &Style,
|
|
||||||
ignore_border: bool,
|
|
||||||
) -> taffy::style::Style {
|
|
||||||
taffy::style::Style {
|
taffy::style::Style {
|
||||||
display: style.display.into(),
|
display: node.display.into(),
|
||||||
overflow: taffy::Point {
|
overflow: taffy::Point {
|
||||||
x: style.overflow.x.into(),
|
x: node.overflow.x.into(),
|
||||||
y: style.overflow.y.into(),
|
y: node.overflow.y.into(),
|
||||||
},
|
},
|
||||||
scrollbar_width: 0.0,
|
scrollbar_width: 0.0,
|
||||||
position: style.position_type.into(),
|
position: node.position_type.into(),
|
||||||
flex_direction: style.flex_direction.into(),
|
flex_direction: node.flex_direction.into(),
|
||||||
flex_wrap: style.flex_wrap.into(),
|
flex_wrap: node.flex_wrap.into(),
|
||||||
align_items: style.align_items.into(),
|
align_items: node.align_items.into(),
|
||||||
justify_items: style.justify_items.into(),
|
justify_items: node.justify_items.into(),
|
||||||
align_self: style.align_self.into(),
|
align_self: node.align_self.into(),
|
||||||
justify_self: style.justify_self.into(),
|
justify_self: node.justify_self.into(),
|
||||||
align_content: style.align_content.into(),
|
align_content: node.align_content.into(),
|
||||||
justify_content: style.justify_content.into(),
|
justify_content: node.justify_content.into(),
|
||||||
inset: taffy::Rect {
|
inset: taffy::Rect {
|
||||||
left: style.left.into_length_percentage_auto(context),
|
left: node.left.into_length_percentage_auto(context),
|
||||||
right: style.right.into_length_percentage_auto(context),
|
right: node.right.into_length_percentage_auto(context),
|
||||||
top: style.top.into_length_percentage_auto(context),
|
top: node.top.into_length_percentage_auto(context),
|
||||||
bottom: style.bottom.into_length_percentage_auto(context),
|
bottom: node.bottom.into_length_percentage_auto(context),
|
||||||
},
|
},
|
||||||
margin: style
|
margin: node
|
||||||
.margin
|
.margin
|
||||||
.map_to_taffy_rect(|m| m.into_length_percentage_auto(context)),
|
.map_to_taffy_rect(|m| m.into_length_percentage_auto(context)),
|
||||||
padding: style
|
padding: node
|
||||||
.padding
|
.padding
|
||||||
.map_to_taffy_rect(|m| m.into_length_percentage(context)),
|
.map_to_taffy_rect(|m| m.into_length_percentage(context)),
|
||||||
// Ignore border for leaf nodes as it isn't implemented in the rendering engine.
|
// Ignore border for leaf nodes as it isn't implemented in the rendering engine.
|
||||||
|
@ -101,53 +97,52 @@ pub fn from_style(
|
||||||
border: if ignore_border {
|
border: if ignore_border {
|
||||||
taffy::Rect::zero()
|
taffy::Rect::zero()
|
||||||
} else {
|
} else {
|
||||||
style
|
node.border
|
||||||
.border
|
|
||||||
.map_to_taffy_rect(|m| m.into_length_percentage(context))
|
.map_to_taffy_rect(|m| m.into_length_percentage(context))
|
||||||
},
|
},
|
||||||
flex_grow: style.flex_grow,
|
flex_grow: node.flex_grow,
|
||||||
flex_shrink: style.flex_shrink,
|
flex_shrink: node.flex_shrink,
|
||||||
flex_basis: style.flex_basis.into_dimension(context),
|
flex_basis: node.flex_basis.into_dimension(context),
|
||||||
size: taffy::Size {
|
size: taffy::Size {
|
||||||
width: style.width.into_dimension(context),
|
width: node.width.into_dimension(context),
|
||||||
height: style.height.into_dimension(context),
|
height: node.height.into_dimension(context),
|
||||||
},
|
},
|
||||||
min_size: taffy::Size {
|
min_size: taffy::Size {
|
||||||
width: style.min_width.into_dimension(context),
|
width: node.min_width.into_dimension(context),
|
||||||
height: style.min_height.into_dimension(context),
|
height: node.min_height.into_dimension(context),
|
||||||
},
|
},
|
||||||
max_size: taffy::Size {
|
max_size: taffy::Size {
|
||||||
width: style.max_width.into_dimension(context),
|
width: node.max_width.into_dimension(context),
|
||||||
height: style.max_height.into_dimension(context),
|
height: node.max_height.into_dimension(context),
|
||||||
},
|
},
|
||||||
aspect_ratio: style.aspect_ratio,
|
aspect_ratio: node.aspect_ratio,
|
||||||
gap: taffy::Size {
|
gap: taffy::Size {
|
||||||
width: style.column_gap.into_length_percentage(context),
|
width: node.column_gap.into_length_percentage(context),
|
||||||
height: style.row_gap.into_length_percentage(context),
|
height: node.row_gap.into_length_percentage(context),
|
||||||
},
|
},
|
||||||
grid_auto_flow: style.grid_auto_flow.into(),
|
grid_auto_flow: node.grid_auto_flow.into(),
|
||||||
grid_template_rows: style
|
grid_template_rows: node
|
||||||
.grid_template_rows
|
.grid_template_rows
|
||||||
.iter()
|
.iter()
|
||||||
.map(|track| track.clone_into_repeated_taffy_track(context))
|
.map(|track| track.clone_into_repeated_taffy_track(context))
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
grid_template_columns: style
|
grid_template_columns: node
|
||||||
.grid_template_columns
|
.grid_template_columns
|
||||||
.iter()
|
.iter()
|
||||||
.map(|track| track.clone_into_repeated_taffy_track(context))
|
.map(|track| track.clone_into_repeated_taffy_track(context))
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
grid_auto_rows: style
|
grid_auto_rows: node
|
||||||
.grid_auto_rows
|
.grid_auto_rows
|
||||||
.iter()
|
.iter()
|
||||||
.map(|track| track.into_taffy_track(context))
|
.map(|track| track.into_taffy_track(context))
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
grid_auto_columns: style
|
grid_auto_columns: node
|
||||||
.grid_auto_columns
|
.grid_auto_columns
|
||||||
.iter()
|
.iter()
|
||||||
.map(|track| track.into_taffy_track(context))
|
.map(|track| track.into_taffy_track(context))
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
grid_row: style.grid_row.into(),
|
grid_row: node.grid_row.into(),
|
||||||
grid_column: style.grid_column.into(),
|
grid_column: node.grid_column.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -448,7 +443,7 @@ mod tests {
|
||||||
use sh::TaffyZero;
|
use sh::TaffyZero;
|
||||||
use taffy::style_helpers as sh;
|
use taffy::style_helpers as sh;
|
||||||
|
|
||||||
let bevy_style = Style {
|
let node = Node {
|
||||||
display: Display::Flex,
|
display: Display::Flex,
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
left: Val::ZERO,
|
left: Val::ZERO,
|
||||||
|
@ -516,7 +511,7 @@ mod tests {
|
||||||
grid_row: GridPlacement::span(3),
|
grid_row: GridPlacement::span(3),
|
||||||
};
|
};
|
||||||
let viewport_values = LayoutContext::new(1.0, bevy_math::Vec2::new(800., 600.));
|
let viewport_values = LayoutContext::new(1.0, bevy_math::Vec2::new(800., 600.));
|
||||||
let taffy_style = from_style(&viewport_values, &bevy_style, false);
|
let taffy_style = from_node(&node, &viewport_values, false);
|
||||||
assert_eq!(taffy_style.display, taffy::style::Display::Flex);
|
assert_eq!(taffy_style.display, taffy::style::Display::Flex);
|
||||||
assert_eq!(taffy_style.position, taffy::style::Position::Absolute);
|
assert_eq!(taffy_style.position, taffy::style::Position::Absolute);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
experimental::{UiChildren, UiRootNodes},
|
experimental::{UiChildren, UiRootNodes},
|
||||||
BorderRadius, ContentSize, DefaultUiCamera, Display, Node, Outline, OverflowAxis,
|
BorderRadius, ComputedNode, ContentSize, DefaultUiCamera, Display, Node, Outline, OverflowAxis,
|
||||||
ScrollPosition, Style, TargetCamera, UiScale,
|
ScrollPosition, TargetCamera, UiScale,
|
||||||
};
|
};
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
change_detection::{DetectChanges, DetectChangesMut},
|
change_detection::{DetectChanges, DetectChangesMut},
|
||||||
|
@ -115,22 +115,19 @@ pub fn ui_layout_system(
|
||||||
mut resize_events: EventReader<bevy_window::WindowResized>,
|
mut resize_events: EventReader<bevy_window::WindowResized>,
|
||||||
mut ui_surface: ResMut<UiSurface>,
|
mut ui_surface: ResMut<UiSurface>,
|
||||||
root_nodes: UiRootNodes,
|
root_nodes: UiRootNodes,
|
||||||
mut style_query: Query<
|
mut node_query: Query<(
|
||||||
(
|
Entity,
|
||||||
Entity,
|
Ref<Node>,
|
||||||
Ref<Style>,
|
Option<&mut ContentSize>,
|
||||||
Option<&mut ContentSize>,
|
Option<&TargetCamera>,
|
||||||
Option<&TargetCamera>,
|
)>,
|
||||||
),
|
computed_node_query: Query<(Entity, Option<Ref<Parent>>), With<ComputedNode>>,
|
||||||
With<Node>,
|
|
||||||
>,
|
|
||||||
node_query: Query<(Entity, Option<Ref<Parent>>), With<Node>>,
|
|
||||||
ui_children: UiChildren,
|
ui_children: UiChildren,
|
||||||
mut removed_components: UiLayoutSystemRemovedComponentParam,
|
mut removed_components: UiLayoutSystemRemovedComponentParam,
|
||||||
mut node_transform_query: Query<(
|
mut node_transform_query: Query<(
|
||||||
&mut Node,
|
&mut ComputedNode,
|
||||||
&mut Transform,
|
&mut Transform,
|
||||||
&Style,
|
&Node,
|
||||||
Option<&BorderRadius>,
|
Option<&BorderRadius>,
|
||||||
Option<&Outline>,
|
Option<&Outline>,
|
||||||
Option<&ScrollPosition>,
|
Option<&ScrollPosition>,
|
||||||
|
@ -173,7 +170,7 @@ pub fn ui_layout_system(
|
||||||
// Precalculate the layout info for each camera, so we have fast access to it for each node
|
// Precalculate the layout info for each camera, so we have fast access to it for each node
|
||||||
camera_layout_info.clear();
|
camera_layout_info.clear();
|
||||||
|
|
||||||
style_query
|
node_query
|
||||||
.iter_many(root_nodes.iter())
|
.iter_many(root_nodes.iter())
|
||||||
.for_each(|(entity, _, _, target_camera)| {
|
.for_each(|(entity, _, _, target_camera)| {
|
||||||
match camera_with_default(target_camera) {
|
match camera_with_default(target_camera) {
|
||||||
|
@ -211,17 +208,17 @@ pub fn ui_layout_system(
|
||||||
ui_surface.try_remove_node_context(entity);
|
ui_surface.try_remove_node_context(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync Style and ContentSize to Taffy for all nodes
|
// Sync Node and ContentSize to Taffy for all nodes
|
||||||
style_query
|
node_query
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.for_each(|(entity, style, content_size, target_camera)| {
|
.for_each(|(entity, node, content_size, target_camera)| {
|
||||||
if let Some(camera) =
|
if let Some(camera) =
|
||||||
camera_with_default(target_camera).and_then(|c| camera_layout_info.get(&c))
|
camera_with_default(target_camera).and_then(|c| camera_layout_info.get(&c))
|
||||||
{
|
{
|
||||||
if camera.resized
|
if camera.resized
|
||||||
|| !scale_factor_events.is_empty()
|
|| !scale_factor_events.is_empty()
|
||||||
|| ui_scale.is_changed()
|
|| ui_scale.is_changed()
|
||||||
|| style.is_changed()
|
|| node.is_changed()
|
||||||
|| content_size
|
|| content_size
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|c| c.measure.is_some())
|
.map(|c| c.measure.is_some())
|
||||||
|
@ -232,10 +229,10 @@ pub fn ui_layout_system(
|
||||||
[camera.size.x as f32, camera.size.y as f32].into(),
|
[camera.size.x as f32, camera.size.y as f32].into(),
|
||||||
);
|
);
|
||||||
let measure = content_size.and_then(|mut c| c.measure.take());
|
let measure = content_size.and_then(|mut c| c.measure.take());
|
||||||
ui_surface.upsert_node(&layout_context, entity, &style, measure);
|
ui_surface.upsert_node(&layout_context, entity, &node, measure);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ui_surface.upsert_node(&LayoutContext::DEFAULT, entity, &Style::default(), None);
|
ui_surface.upsert_node(&LayoutContext::DEFAULT, entity, &Node::default(), None);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
scale_factor_events.clear();
|
scale_factor_events.clear();
|
||||||
|
@ -259,30 +256,32 @@ pub fn ui_layout_system(
|
||||||
ui_surface.try_remove_children(entity);
|
ui_surface.try_remove_children(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
node_query.iter().for_each(|(entity, maybe_parent)| {
|
computed_node_query
|
||||||
if let Some(parent) = maybe_parent {
|
.iter()
|
||||||
// Note: This does not cover the case where a parent's Node component was removed.
|
.for_each(|(entity, maybe_parent)| {
|
||||||
// Users are responsible for fixing hierarchies if they do that (it is not recommended).
|
if let Some(parent) = maybe_parent {
|
||||||
// Detecting it here would be a permanent perf burden on the hot path.
|
// Note: This does not cover the case where a parent's Node component was removed.
|
||||||
if parent.is_changed() && !ui_children.is_ui_node(parent.get()) {
|
// Users are responsible for fixing hierarchies if they do that (it is not recommended).
|
||||||
warn!(
|
// Detecting it here would be a permanent perf burden on the hot path.
|
||||||
"Styled child ({entity}) in a non-UI entity hierarchy. You are using an entity \
|
if parent.is_changed() && !ui_children.is_ui_node(parent.get()) {
|
||||||
|
warn!(
|
||||||
|
"Node ({entity}) is in a non-UI entity hierarchy. You are using an entity \
|
||||||
with UI components as a child of an entity without UI components, your UI layout may be broken."
|
with UI components as a child of an entity without UI components, your UI layout may be broken."
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ui_children.is_changed(entity) {
|
if ui_children.is_changed(entity) {
|
||||||
ui_surface.update_children(entity, ui_children.iter_ui_children(entity));
|
ui_surface.update_children(entity, ui_children.iter_ui_children(entity));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let text_buffers = &mut buffer_query;
|
let text_buffers = &mut buffer_query;
|
||||||
// clean up removed nodes after syncing children to avoid potential panic (invalid SlotMap key used)
|
// clean up removed nodes after syncing children to avoid potential panic (invalid SlotMap key used)
|
||||||
ui_surface.remove_entities(removed_components.removed_nodes.read());
|
ui_surface.remove_entities(removed_components.removed_nodes.read());
|
||||||
|
|
||||||
// Re-sync changed children: avoid layout glitches caused by removed nodes that are still set as a child of another node
|
// Re-sync changed children: avoid layout glitches caused by removed nodes that are still set as a child of another node
|
||||||
node_query.iter().for_each(|(entity, _)| {
|
computed_node_query.iter().for_each(|(entity, _)| {
|
||||||
if ui_children.is_changed(entity) {
|
if ui_children.is_changed(entity) {
|
||||||
ui_surface.update_children(entity, ui_children.iter_ui_children(entity));
|
ui_surface.update_children(entity, ui_children.iter_ui_children(entity));
|
||||||
}
|
}
|
||||||
|
@ -319,9 +318,9 @@ with UI components as a child of an entity without UI components, your UI layout
|
||||||
ui_surface: &UiSurface,
|
ui_surface: &UiSurface,
|
||||||
root_size: Option<Vec2>,
|
root_size: Option<Vec2>,
|
||||||
node_transform_query: &mut Query<(
|
node_transform_query: &mut Query<(
|
||||||
&mut Node,
|
&mut ComputedNode,
|
||||||
&mut Transform,
|
&mut Transform,
|
||||||
&Style,
|
&Node,
|
||||||
Option<&BorderRadius>,
|
Option<&BorderRadius>,
|
||||||
Option<&Outline>,
|
Option<&Outline>,
|
||||||
Option<&ScrollPosition>,
|
Option<&ScrollPosition>,
|
||||||
|
@ -581,25 +580,19 @@ mod tests {
|
||||||
|
|
||||||
// spawn a root entity with width and height set to fill 100% of its parent
|
// spawn a root entity with width and height set to fill 100% of its parent
|
||||||
let ui_root = world
|
let ui_root = world
|
||||||
.spawn((
|
.spawn(Node {
|
||||||
Node::default(),
|
width: Val::Percent(100.),
|
||||||
Style {
|
height: Val::Percent(100.),
|
||||||
width: Val::Percent(100.),
|
..default()
|
||||||
height: Val::Percent(100.),
|
})
|
||||||
..default()
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.id();
|
.id();
|
||||||
|
|
||||||
let ui_child = world
|
let ui_child = world
|
||||||
.spawn((
|
.spawn(Node {
|
||||||
Node::default(),
|
width: Val::Percent(100.),
|
||||||
Style {
|
height: Val::Percent(100.),
|
||||||
width: Val::Percent(100.),
|
..default()
|
||||||
height: Val::Percent(100.),
|
})
|
||||||
..default()
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.id();
|
.id();
|
||||||
|
|
||||||
world.entity_mut(ui_root).add_child(ui_child);
|
world.entity_mut(ui_root).add_child(ui_child);
|
||||||
|
@ -828,45 +821,36 @@ mod tests {
|
||||||
|
|
||||||
let mut size = 150.;
|
let mut size = 150.;
|
||||||
|
|
||||||
world.spawn((
|
world.spawn(Node {
|
||||||
Node::default(),
|
// test should pass without explicitly requiring position_type to be set to Absolute
|
||||||
Style {
|
// position_type: PositionType::Absolute,
|
||||||
// test should pass without explicitly requiring position_type to be set to Absolute
|
width: Val::Px(size),
|
||||||
// position_type: PositionType::Absolute,
|
height: Val::Px(size),
|
||||||
width: Val::Px(size),
|
..default()
|
||||||
height: Val::Px(size),
|
});
|
||||||
..default()
|
|
||||||
},
|
|
||||||
));
|
|
||||||
|
|
||||||
size -= 50.;
|
size -= 50.;
|
||||||
|
|
||||||
world.spawn((
|
world.spawn(Node {
|
||||||
Node::default(),
|
// position_type: PositionType::Absolute,
|
||||||
Style {
|
width: Val::Px(size),
|
||||||
// position_type: PositionType::Absolute,
|
height: Val::Px(size),
|
||||||
width: Val::Px(size),
|
..default()
|
||||||
height: Val::Px(size),
|
});
|
||||||
..default()
|
|
||||||
},
|
|
||||||
));
|
|
||||||
|
|
||||||
size -= 50.;
|
size -= 50.;
|
||||||
|
|
||||||
world.spawn((
|
world.spawn(Node {
|
||||||
Node::default(),
|
// position_type: PositionType::Absolute,
|
||||||
Style {
|
width: Val::Px(size),
|
||||||
// position_type: PositionType::Absolute,
|
height: Val::Px(size),
|
||||||
width: Val::Px(size),
|
..default()
|
||||||
height: Val::Px(size),
|
});
|
||||||
..default()
|
|
||||||
},
|
|
||||||
));
|
|
||||||
|
|
||||||
ui_schedule.run(&mut world);
|
ui_schedule.run(&mut world);
|
||||||
|
|
||||||
let overlap_check = world
|
let overlap_check = world
|
||||||
.query_filtered::<(Entity, &Node, &GlobalTransform), Without<Parent>>()
|
.query_filtered::<(Entity, &ComputedNode, &GlobalTransform), Without<Parent>>()
|
||||||
.iter(&world)
|
.iter(&world)
|
||||||
.fold(
|
.fold(
|
||||||
Option::<(Rect, bool)>::None,
|
Option::<(Rect, bool)>::None,
|
||||||
|
@ -949,7 +933,7 @@ mod tests {
|
||||||
commands
|
commands
|
||||||
.entity(moving_ui_entity)
|
.entity(moving_ui_entity)
|
||||||
.insert(TargetCamera(target_camera_entity))
|
.insert(TargetCamera(target_camera_entity))
|
||||||
.insert(Style {
|
.insert(Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(pos.y),
|
top: Val::Px(pos.y),
|
||||||
left: Val::Px(pos.x),
|
left: Val::Px(pos.x),
|
||||||
|
@ -996,8 +980,7 @@ mod tests {
|
||||||
));
|
));
|
||||||
|
|
||||||
world.spawn((
|
world.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(0.),
|
top: Val::Px(0.),
|
||||||
left: Val::Px(0.),
|
left: Val::Px(0.),
|
||||||
|
@ -1050,8 +1033,7 @@ mod tests {
|
||||||
|
|
||||||
let ui_entity = world
|
let ui_entity = world
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
align_self: AlignSelf::Start,
|
align_self: AlignSelf::Start,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
|
@ -1076,8 +1058,7 @@ mod tests {
|
||||||
let content_size = Vec2::new(50., 25.);
|
let content_size = Vec2::new(50., 25.);
|
||||||
let ui_entity = world
|
let ui_entity = world
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
align_self: AlignSelf::Start,
|
align_self: AlignSelf::Start,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
@ -1115,26 +1096,20 @@ mod tests {
|
||||||
let (mut world, mut ui_schedule) = setup_ui_test_world();
|
let (mut world, mut ui_schedule) = setup_ui_test_world();
|
||||||
|
|
||||||
let parent = world
|
let parent = world
|
||||||
.spawn((
|
.spawn(Node {
|
||||||
Node::default(),
|
display: Display::Grid,
|
||||||
Style {
|
grid_template_columns: RepeatedGridTrack::min_content(2),
|
||||||
display: Display::Grid,
|
margin: UiRect::all(Val::Px(4.0)),
|
||||||
grid_template_columns: RepeatedGridTrack::min_content(2),
|
..default()
|
||||||
margin: UiRect::all(Val::Px(4.0)),
|
})
|
||||||
..default()
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.with_children(|commands| {
|
.with_children(|commands| {
|
||||||
for _ in 0..2 {
|
for _ in 0..2 {
|
||||||
commands.spawn((
|
commands.spawn(Node {
|
||||||
Node::default(),
|
display: Display::Grid,
|
||||||
Style {
|
width: Val::Px(160.),
|
||||||
display: Display::Grid,
|
height: Val::Px(160.),
|
||||||
width: Val::Px(160.),
|
..default()
|
||||||
height: Val::Px(160.),
|
});
|
||||||
..default()
|
|
||||||
},
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.id();
|
.id();
|
||||||
|
@ -1154,9 +1129,9 @@ mod tests {
|
||||||
ui_schedule.run(&mut world);
|
ui_schedule.run(&mut world);
|
||||||
let width_sum: f32 = children
|
let width_sum: f32 = children
|
||||||
.iter()
|
.iter()
|
||||||
.map(|child| world.get::<Node>(*child).unwrap().calculated_size.x)
|
.map(|child| world.get::<ComputedNode>(*child).unwrap().calculated_size.x)
|
||||||
.sum();
|
.sum();
|
||||||
let parent_width = world.get::<Node>(parent).unwrap().calculated_size.x;
|
let parent_width = world.get::<ComputedNode>(parent).unwrap().calculated_size.x;
|
||||||
assert!((width_sum - parent_width).abs() < 0.001);
|
assert!((width_sum - parent_width).abs() < 0.001);
|
||||||
assert!((width_sum - 320.).abs() <= 1.);
|
assert!((width_sum - 320.).abs() <= 1.);
|
||||||
s += r;
|
s += r;
|
||||||
|
@ -1205,25 +1180,19 @@ mod tests {
|
||||||
);
|
);
|
||||||
|
|
||||||
let ui_root = world
|
let ui_root = world
|
||||||
.spawn((
|
.spawn(Node {
|
||||||
Node::default(),
|
width: Val::Percent(100.),
|
||||||
Style {
|
height: Val::Percent(100.),
|
||||||
width: Val::Percent(100.),
|
..default()
|
||||||
height: Val::Percent(100.),
|
})
|
||||||
..default()
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.id();
|
.id();
|
||||||
|
|
||||||
let ui_child = world
|
let ui_child = world
|
||||||
.spawn((
|
.spawn(Node {
|
||||||
Node::default(),
|
width: Val::Percent(100.),
|
||||||
Style {
|
height: Val::Percent(100.),
|
||||||
width: Val::Percent(100.),
|
..default()
|
||||||
height: Val::Percent(100.),
|
})
|
||||||
..default()
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.id();
|
.id();
|
||||||
|
|
||||||
world.entity_mut(ui_root).add_child(ui_child);
|
world.entity_mut(ui_root).add_child(ui_child);
|
||||||
|
@ -1254,7 +1223,7 @@ mod tests {
|
||||||
ui_surface.upsert_node(
|
ui_surface.upsert_node(
|
||||||
&LayoutContext::TEST_CONTEXT,
|
&LayoutContext::TEST_CONTEXT,
|
||||||
params.root_node_entity,
|
params.root_node_entity,
|
||||||
&Style::default(),
|
&Node::default(),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,7 @@ use bevy_ecs::{
|
||||||
use bevy_math::UVec2;
|
use bevy_math::UVec2;
|
||||||
use bevy_utils::default;
|
use bevy_utils::default;
|
||||||
|
|
||||||
use crate::{
|
use crate::{layout::convert, LayoutContext, LayoutError, Measure, MeasureArgs, Node, NodeMeasure};
|
||||||
layout::convert, LayoutContext, LayoutError, Measure, MeasureArgs, NodeMeasure, Style,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct RootNodePair {
|
pub struct RootNodePair {
|
||||||
|
@ -71,7 +69,7 @@ impl UiSurface {
|
||||||
&mut self,
|
&mut self,
|
||||||
layout_context: &LayoutContext,
|
layout_context: &LayoutContext,
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
style: &Style,
|
node: &Node,
|
||||||
mut new_node_context: Option<NodeMeasure>,
|
mut new_node_context: Option<NodeMeasure>,
|
||||||
) {
|
) {
|
||||||
let taffy = &mut self.taffy;
|
let taffy = &mut self.taffy;
|
||||||
|
@ -81,14 +79,11 @@ impl UiSurface {
|
||||||
added = true;
|
added = true;
|
||||||
if let Some(measure) = new_node_context.take() {
|
if let Some(measure) = new_node_context.take() {
|
||||||
taffy
|
taffy
|
||||||
.new_leaf_with_context(
|
.new_leaf_with_context(convert::from_node(node, layout_context, true), measure)
|
||||||
convert::from_style(layout_context, style, true),
|
|
||||||
measure,
|
|
||||||
)
|
|
||||||
.unwrap()
|
.unwrap()
|
||||||
} else {
|
} else {
|
||||||
taffy
|
taffy
|
||||||
.new_leaf(convert::from_style(layout_context, style, false))
|
.new_leaf(convert::from_node(node, layout_context, false))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -106,7 +101,7 @@ impl UiSurface {
|
||||||
taffy
|
taffy
|
||||||
.set_style(
|
.set_style(
|
||||||
taffy_node_id,
|
taffy_node_id,
|
||||||
convert::from_style(layout_context, style, has_measure),
|
convert::from_node(node, layout_context, has_measure),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
@ -353,17 +348,17 @@ mod tests {
|
||||||
let mut ui_surface = UiSurface::default();
|
let mut ui_surface = UiSurface::default();
|
||||||
let camera_entity = Entity::from_raw(0);
|
let camera_entity = Entity::from_raw(0);
|
||||||
let root_node_entity = Entity::from_raw(1);
|
let root_node_entity = Entity::from_raw(1);
|
||||||
let style = Style::default();
|
let node = Node::default();
|
||||||
|
|
||||||
// standard upsert
|
// standard upsert
|
||||||
ui_surface.upsert_node(&LayoutContext::TEST_CONTEXT, root_node_entity, &style, None);
|
ui_surface.upsert_node(&LayoutContext::TEST_CONTEXT, root_node_entity, &node, None);
|
||||||
|
|
||||||
// should be inserted into taffy
|
// should be inserted into taffy
|
||||||
assert_eq!(ui_surface.taffy.total_node_count(), 1);
|
assert_eq!(ui_surface.taffy.total_node_count(), 1);
|
||||||
assert!(ui_surface.entity_to_taffy.contains_key(&root_node_entity));
|
assert!(ui_surface.entity_to_taffy.contains_key(&root_node_entity));
|
||||||
|
|
||||||
// test duplicate insert 1
|
// test duplicate insert 1
|
||||||
ui_surface.upsert_node(&LayoutContext::TEST_CONTEXT, root_node_entity, &style, None);
|
ui_surface.upsert_node(&LayoutContext::TEST_CONTEXT, root_node_entity, &node, None);
|
||||||
|
|
||||||
// node count should not have increased
|
// node count should not have increased
|
||||||
assert_eq!(ui_surface.taffy.total_node_count(), 1);
|
assert_eq!(ui_surface.taffy.total_node_count(), 1);
|
||||||
|
@ -380,7 +375,7 @@ mod tests {
|
||||||
assert!(is_root_node_pair_valid(&ui_surface.taffy, root_node_pair));
|
assert!(is_root_node_pair_valid(&ui_surface.taffy, root_node_pair));
|
||||||
|
|
||||||
// test duplicate insert 2
|
// test duplicate insert 2
|
||||||
ui_surface.upsert_node(&LayoutContext::TEST_CONTEXT, root_node_entity, &style, None);
|
ui_surface.upsert_node(&LayoutContext::TEST_CONTEXT, root_node_entity, &node, None);
|
||||||
|
|
||||||
// node count should not have increased
|
// node count should not have increased
|
||||||
assert_eq!(ui_surface.taffy.total_node_count(), 2);
|
assert_eq!(ui_surface.taffy.total_node_count(), 2);
|
||||||
|
@ -418,9 +413,9 @@ mod tests {
|
||||||
let mut ui_surface = UiSurface::default();
|
let mut ui_surface = UiSurface::default();
|
||||||
let camera_entity = Entity::from_raw(0);
|
let camera_entity = Entity::from_raw(0);
|
||||||
let root_node_entity = Entity::from_raw(1);
|
let root_node_entity = Entity::from_raw(1);
|
||||||
let style = Style::default();
|
let node = Node::default();
|
||||||
|
|
||||||
ui_surface.upsert_node(&LayoutContext::TEST_CONTEXT, root_node_entity, &style, None);
|
ui_surface.upsert_node(&LayoutContext::TEST_CONTEXT, root_node_entity, &node, None);
|
||||||
|
|
||||||
// assign root node to camera
|
// assign root node to camera
|
||||||
ui_surface.set_camera_children(camera_entity, [root_node_entity].into_iter());
|
ui_surface.set_camera_children(camera_entity, [root_node_entity].into_iter());
|
||||||
|
@ -453,9 +448,9 @@ mod tests {
|
||||||
let mut ui_surface = UiSurface::default();
|
let mut ui_surface = UiSurface::default();
|
||||||
let camera_entity = Entity::from_raw(0);
|
let camera_entity = Entity::from_raw(0);
|
||||||
let root_node_entity = Entity::from_raw(1);
|
let root_node_entity = Entity::from_raw(1);
|
||||||
let style = Style::default();
|
let node = Node::default();
|
||||||
|
|
||||||
ui_surface.upsert_node(&LayoutContext::TEST_CONTEXT, root_node_entity, &style, None);
|
ui_surface.upsert_node(&LayoutContext::TEST_CONTEXT, root_node_entity, &node, None);
|
||||||
|
|
||||||
// assign root node to camera
|
// assign root node to camera
|
||||||
ui_surface.set_camera_children(camera_entity, [root_node_entity].into_iter());
|
ui_surface.set_camera_children(camera_entity, [root_node_entity].into_iter());
|
||||||
|
@ -502,9 +497,9 @@ mod tests {
|
||||||
let mut ui_surface = UiSurface::default();
|
let mut ui_surface = UiSurface::default();
|
||||||
let camera_entity = Entity::from_raw(0);
|
let camera_entity = Entity::from_raw(0);
|
||||||
let root_node_entity = Entity::from_raw(1);
|
let root_node_entity = Entity::from_raw(1);
|
||||||
let style = Style::default();
|
let node = Node::default();
|
||||||
|
|
||||||
ui_surface.upsert_node(&LayoutContext::TEST_CONTEXT, root_node_entity, &style, None);
|
ui_surface.upsert_node(&LayoutContext::TEST_CONTEXT, root_node_entity, &node, None);
|
||||||
|
|
||||||
ui_surface.set_camera_children(camera_entity, [root_node_entity].into_iter());
|
ui_surface.set_camera_children(camera_entity, [root_node_entity].into_iter());
|
||||||
|
|
||||||
|
@ -548,9 +543,9 @@ mod tests {
|
||||||
fn test_try_update_measure() {
|
fn test_try_update_measure() {
|
||||||
let mut ui_surface = UiSurface::default();
|
let mut ui_surface = UiSurface::default();
|
||||||
let root_node_entity = Entity::from_raw(1);
|
let root_node_entity = Entity::from_raw(1);
|
||||||
let style = Style::default();
|
let node = Node::default();
|
||||||
|
|
||||||
ui_surface.upsert_node(&LayoutContext::TEST_CONTEXT, root_node_entity, &style, None);
|
ui_surface.upsert_node(&LayoutContext::TEST_CONTEXT, root_node_entity, &node, None);
|
||||||
let mut content_size = ContentSize::default();
|
let mut content_size = ContentSize::default();
|
||||||
content_size.set(NodeMeasure::Fixed(FixedMeasure { size: Vec2::ONE }));
|
content_size.set(NodeMeasure::Fixed(FixedMeasure { size: Vec2::ONE }));
|
||||||
let measure_func = content_size.measure.take().unwrap();
|
let measure_func = content_size.measure.take().unwrap();
|
||||||
|
@ -564,10 +559,10 @@ mod tests {
|
||||||
let mut ui_surface = UiSurface::default();
|
let mut ui_surface = UiSurface::default();
|
||||||
let root_node_entity = Entity::from_raw(1);
|
let root_node_entity = Entity::from_raw(1);
|
||||||
let child_entity = Entity::from_raw(2);
|
let child_entity = Entity::from_raw(2);
|
||||||
let style = Style::default();
|
let node = Node::default();
|
||||||
|
|
||||||
ui_surface.upsert_node(&LayoutContext::TEST_CONTEXT, root_node_entity, &style, None);
|
ui_surface.upsert_node(&LayoutContext::TEST_CONTEXT, root_node_entity, &node, None);
|
||||||
ui_surface.upsert_node(&LayoutContext::TEST_CONTEXT, child_entity, &style, None);
|
ui_surface.upsert_node(&LayoutContext::TEST_CONTEXT, child_entity, &node, None);
|
||||||
|
|
||||||
ui_surface.update_children(root_node_entity, vec![child_entity].into_iter());
|
ui_surface.update_children(root_node_entity, vec![child_entity].into_iter());
|
||||||
|
|
||||||
|
@ -583,10 +578,10 @@ mod tests {
|
||||||
let camera_entity = Entity::from_raw(0);
|
let camera_entity = Entity::from_raw(0);
|
||||||
let root_node_entity = Entity::from_raw(1);
|
let root_node_entity = Entity::from_raw(1);
|
||||||
let child_entity = Entity::from_raw(2);
|
let child_entity = Entity::from_raw(2);
|
||||||
let style = Style::default();
|
let node = Node::default();
|
||||||
|
|
||||||
ui_surface.upsert_node(&LayoutContext::TEST_CONTEXT, root_node_entity, &style, None);
|
ui_surface.upsert_node(&LayoutContext::TEST_CONTEXT, root_node_entity, &node, None);
|
||||||
ui_surface.upsert_node(&LayoutContext::TEST_CONTEXT, child_entity, &style, None);
|
ui_surface.upsert_node(&LayoutContext::TEST_CONTEXT, child_entity, &node, None);
|
||||||
|
|
||||||
let root_taffy_node = *ui_surface.entity_to_taffy.get(&root_node_entity).unwrap();
|
let root_taffy_node = *ui_surface.entity_to_taffy.get(&root_node_entity).unwrap();
|
||||||
let child_taffy = *ui_surface.entity_to_taffy.get(&child_entity).unwrap();
|
let child_taffy = *ui_surface.entity_to_taffy.get(&child_entity).unwrap();
|
||||||
|
|
|
@ -129,10 +129,6 @@ struct AmbiguousWithTextSystem;
|
||||||
#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
|
#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
|
||||||
struct AmbiguousWithUpdateText2DLayout;
|
struct AmbiguousWithUpdateText2DLayout;
|
||||||
|
|
||||||
/// A convenient alias for `With<Node>`, for use with
|
|
||||||
/// [`bevy_render::view::VisibleEntities`].
|
|
||||||
pub type WithNode = With<Node>;
|
|
||||||
|
|
||||||
impl Plugin for UiPlugin {
|
impl Plugin for UiPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.init_resource::<UiSurface>()
|
app.init_resource::<UiSurface>()
|
||||||
|
@ -140,13 +136,13 @@ impl Plugin for UiPlugin {
|
||||||
.init_resource::<UiStack>()
|
.init_resource::<UiStack>()
|
||||||
.register_type::<BackgroundColor>()
|
.register_type::<BackgroundColor>()
|
||||||
.register_type::<CalculatedClip>()
|
.register_type::<CalculatedClip>()
|
||||||
|
.register_type::<ComputedNode>()
|
||||||
.register_type::<ContentSize>()
|
.register_type::<ContentSize>()
|
||||||
.register_type::<FocusPolicy>()
|
.register_type::<FocusPolicy>()
|
||||||
.register_type::<Interaction>()
|
.register_type::<Interaction>()
|
||||||
.register_type::<Node>()
|
.register_type::<Node>()
|
||||||
.register_type::<RelativeCursorPosition>()
|
.register_type::<RelativeCursorPosition>()
|
||||||
.register_type::<ScrollPosition>()
|
.register_type::<ScrollPosition>()
|
||||||
.register_type::<Style>()
|
|
||||||
.register_type::<TargetCamera>()
|
.register_type::<TargetCamera>()
|
||||||
.register_type::<UiImage>()
|
.register_type::<UiImage>()
|
||||||
.register_type::<UiImageSize>()
|
.register_type::<UiImageSize>()
|
||||||
|
@ -189,7 +185,7 @@ impl Plugin for UiPlugin {
|
||||||
app.add_systems(
|
app.add_systems(
|
||||||
PostUpdate,
|
PostUpdate,
|
||||||
(
|
(
|
||||||
check_visibility::<WithNode>.in_set(VisibilitySystems::CheckVisibility),
|
check_visibility::<With<Node>>.in_set(VisibilitySystems::CheckVisibility),
|
||||||
update_target_camera_system.in_set(UiSystem::Prepare),
|
update_target_camera_system.in_set(UiSystem::Prepare),
|
||||||
ui_layout_system_config,
|
ui_layout_system_config,
|
||||||
ui_stack_system
|
ui_stack_system
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
widget::{Button, UiImageSize},
|
widget::{Button, UiImageSize},
|
||||||
BackgroundColor, BorderColor, BorderRadius, ContentSize, FocusPolicy, Interaction,
|
BackgroundColor, BorderColor, BorderRadius, ComputedNode, ContentSize, FocusPolicy,
|
||||||
MaterialNode, Node, ScrollPosition, Style, UiImage, UiMaterial, ZIndex,
|
Interaction, MaterialNode, Node, ScrollPosition, UiImage, UiMaterial, ZIndex,
|
||||||
};
|
};
|
||||||
use bevy_ecs::bundle::Bundle;
|
use bevy_ecs::bundle::Bundle;
|
||||||
use bevy_render::view::{InheritedVisibility, ViewVisibility, Visibility};
|
use bevy_render::view::{InheritedVisibility, ViewVisibility, Visibility};
|
||||||
|
@ -21,11 +21,11 @@ use bevy_transform::prelude::{GlobalTransform, Transform};
|
||||||
note = "Use the `Node` component instead. Inserting `Node` will also insert the other components required automatically."
|
note = "Use the `Node` component instead. Inserting `Node` will also insert the other components required automatically."
|
||||||
)]
|
)]
|
||||||
pub struct NodeBundle {
|
pub struct NodeBundle {
|
||||||
/// Describes the logical size of the node
|
/// Controls the layout (size and position) of the node and its children
|
||||||
|
/// This also affect how the node is drawn/painted.
|
||||||
pub node: Node,
|
pub node: Node,
|
||||||
/// Styles which control the layout (size and position) of the node and its children
|
/// Describes the logical size of the node
|
||||||
/// In some cases these styles also affect how the node drawn/painted.
|
pub computed_node: ComputedNode,
|
||||||
pub style: Style,
|
|
||||||
/// The background color, which serves as a "fill" for this node
|
/// The background color, which serves as a "fill" for this node
|
||||||
pub background_color: BackgroundColor,
|
pub background_color: BackgroundColor,
|
||||||
/// The color of the Node's border
|
/// The color of the Node's border
|
||||||
|
@ -39,12 +39,12 @@ pub struct NodeBundle {
|
||||||
/// The transform of the node
|
/// The transform of the node
|
||||||
///
|
///
|
||||||
/// This component is automatically managed by the UI layout system.
|
/// This component is automatically managed by the UI layout system.
|
||||||
/// To alter the position of the `NodeBundle`, use the properties of the [`Style`] component.
|
/// To alter the position of the `NodeBundle`, use the properties of the [`Node`] component.
|
||||||
pub transform: Transform,
|
pub transform: Transform,
|
||||||
/// The global transform of the node
|
/// The global transform of the node
|
||||||
///
|
///
|
||||||
/// This component is automatically updated by the [`TransformPropagate`](`bevy_transform::TransformSystem::TransformPropagate`) systems.
|
/// This component is automatically updated by the [`TransformPropagate`](`bevy_transform::TransformSystem::TransformPropagate`) systems.
|
||||||
/// To alter the position of the `NodeBundle`, use the properties of the [`Style`] component.
|
/// To alter the position of the `NodeBundle`, use the properties of the [`Node`] component.
|
||||||
pub global_transform: GlobalTransform,
|
pub global_transform: GlobalTransform,
|
||||||
/// Describes the visibility properties of the node
|
/// Describes the visibility properties of the node
|
||||||
pub visibility: Visibility,
|
pub visibility: Visibility,
|
||||||
|
@ -70,10 +70,10 @@ pub struct NodeBundle {
|
||||||
)]
|
)]
|
||||||
pub struct ImageBundle {
|
pub struct ImageBundle {
|
||||||
/// Describes the logical size of the node
|
/// Describes the logical size of the node
|
||||||
|
pub computed_node: ComputedNode,
|
||||||
|
/// Controls the layout (size and position) of the node and its children
|
||||||
|
/// This also affects how the node is drawn/painted.
|
||||||
pub node: Node,
|
pub node: Node,
|
||||||
/// Styles which control the layout (size and position) of the node and its children
|
|
||||||
/// In some cases these styles also affect how the node drawn/painted.
|
|
||||||
pub style: Style,
|
|
||||||
/// The calculated size based on the given image
|
/// The calculated size based on the given image
|
||||||
pub calculated_size: ContentSize,
|
pub calculated_size: ContentSize,
|
||||||
/// The image of the node.
|
/// The image of the node.
|
||||||
|
@ -93,7 +93,7 @@ pub struct ImageBundle {
|
||||||
/// The transform of the node
|
/// The transform of the node
|
||||||
///
|
///
|
||||||
/// This component is automatically managed by the UI layout system.
|
/// This component is automatically managed by the UI layout system.
|
||||||
/// To alter the position of the `ImageBundle`, use the properties of the [`Style`] component.
|
/// To alter the position of the `ImageBundle`, use the properties of the [`Node`] component.
|
||||||
pub transform: Transform,
|
pub transform: Transform,
|
||||||
/// The global transform of the node
|
/// The global transform of the node
|
||||||
///
|
///
|
||||||
|
@ -123,12 +123,12 @@ pub struct ImageBundle {
|
||||||
)]
|
)]
|
||||||
pub struct ButtonBundle {
|
pub struct ButtonBundle {
|
||||||
/// Describes the logical size of the node
|
/// Describes the logical size of the node
|
||||||
pub node: Node,
|
pub computed_node: ComputedNode,
|
||||||
/// Marker component that signals this node is a button
|
/// Marker component that signals this node is a button
|
||||||
pub button: Button,
|
pub button: Button,
|
||||||
/// Styles which control the layout (size and position) of the node and its children
|
/// Controls the layout (size and position) of the node and its children
|
||||||
/// In some cases these styles also affect how the node drawn/painted.
|
/// Also affect how the node is drawn/painted.
|
||||||
pub style: Style,
|
pub node: Node,
|
||||||
/// Describes whether and how the button has been interacted with by the input
|
/// Describes whether and how the button has been interacted with by the input
|
||||||
pub interaction: Interaction,
|
pub interaction: Interaction,
|
||||||
/// Whether this node should block interaction with lower nodes
|
/// Whether this node should block interaction with lower nodes
|
||||||
|
@ -144,7 +144,7 @@ pub struct ButtonBundle {
|
||||||
/// The transform of the node
|
/// The transform of the node
|
||||||
///
|
///
|
||||||
/// This component is automatically managed by the UI layout system.
|
/// This component is automatically managed by the UI layout system.
|
||||||
/// To alter the position of the `ButtonBundle`, use the properties of the [`Style`] component.
|
/// To alter the position of the `ButtonBundle`, use the properties of the [`Node`] component.
|
||||||
pub transform: Transform,
|
pub transform: Transform,
|
||||||
/// The global transform of the node
|
/// The global transform of the node
|
||||||
///
|
///
|
||||||
|
@ -164,8 +164,8 @@ impl Default for ButtonBundle {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
node: Default::default(),
|
node: Default::default(),
|
||||||
|
computed_node: Default::default(),
|
||||||
button: Default::default(),
|
button: Default::default(),
|
||||||
style: Default::default(),
|
|
||||||
interaction: Default::default(),
|
interaction: Default::default(),
|
||||||
focus_policy: FocusPolicy::Block,
|
focus_policy: FocusPolicy::Block,
|
||||||
border_color: Default::default(),
|
border_color: Default::default(),
|
||||||
|
@ -193,10 +193,10 @@ impl Default for ButtonBundle {
|
||||||
)]
|
)]
|
||||||
pub struct MaterialNodeBundle<M: UiMaterial> {
|
pub struct MaterialNodeBundle<M: UiMaterial> {
|
||||||
/// Describes the logical size of the node
|
/// Describes the logical size of the node
|
||||||
|
pub computed_node: ComputedNode,
|
||||||
|
/// Controls the layout (size and position) of the node and its children
|
||||||
|
/// Also affects how the node is drawn/painted.
|
||||||
pub node: Node,
|
pub node: Node,
|
||||||
/// Styles which control the layout (size and position) of the node and its children
|
|
||||||
/// In some cases these styles also affect how the node drawn/painted.
|
|
||||||
pub style: Style,
|
|
||||||
/// The [`UiMaterial`] used to render the node.
|
/// The [`UiMaterial`] used to render the node.
|
||||||
pub material: MaterialNode<M>,
|
pub material: MaterialNode<M>,
|
||||||
/// Whether this node should block interaction with lower nodes
|
/// Whether this node should block interaction with lower nodes
|
||||||
|
@ -204,12 +204,12 @@ pub struct MaterialNodeBundle<M: UiMaterial> {
|
||||||
/// The transform of the node
|
/// The transform of the node
|
||||||
///
|
///
|
||||||
/// This field is automatically managed by the UI layout system.
|
/// This field is automatically managed by the UI layout system.
|
||||||
/// To alter the position of the `NodeBundle`, use the properties of the [`Style`] component.
|
/// To alter the position of the `NodeBundle`, use the properties of the [`Node`] component.
|
||||||
pub transform: Transform,
|
pub transform: Transform,
|
||||||
/// The global transform of the node
|
/// The global transform of the node
|
||||||
///
|
///
|
||||||
/// This field is automatically managed by the UI layout system.
|
/// This field is automatically managed by the UI layout system.
|
||||||
/// To alter the position of the `NodeBundle`, use the properties of the [`Style`] component.
|
/// To alter the position of the `NodeBundle`, use the properties of the [`Node`] component.
|
||||||
pub global_transform: GlobalTransform,
|
pub global_transform: GlobalTransform,
|
||||||
/// Describes the visibility properties of the node
|
/// Describes the visibility properties of the node
|
||||||
pub visibility: Visibility,
|
pub visibility: Visibility,
|
||||||
|
@ -225,7 +225,7 @@ impl<M: UiMaterial> Default for MaterialNodeBundle<M> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
node: Default::default(),
|
node: Default::default(),
|
||||||
style: Default::default(),
|
computed_node: Default::default(),
|
||||||
material: Default::default(),
|
material: Default::default(),
|
||||||
focus_policy: Default::default(),
|
focus_policy: Default::default(),
|
||||||
transform: Default::default(),
|
transform: Default::default(),
|
||||||
|
|
|
@ -48,7 +48,7 @@ impl Plugin for UiPickingBackendPlugin {
|
||||||
#[query_data(mutable)]
|
#[query_data(mutable)]
|
||||||
pub struct NodeQuery {
|
pub struct NodeQuery {
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
node: &'static Node,
|
node: &'static ComputedNode,
|
||||||
global_transform: &'static GlobalTransform,
|
global_transform: &'static GlobalTransform,
|
||||||
picking_behavior: Option<&'static PickingBehavior>,
|
picking_behavior: Option<&'static PickingBehavior>,
|
||||||
calculated_clip: Option<&'static CalculatedClip>,
|
calculated_clip: Option<&'static CalculatedClip>,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use core::{hash::Hash, ops::Range};
|
use core::{hash::Hash, ops::Range};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
BoxShadow, CalculatedClip, DefaultUiCamera, Node, RenderUiSystem, ResolvedBorderRadius,
|
BoxShadow, CalculatedClip, ComputedNode, DefaultUiCamera, RenderUiSystem, ResolvedBorderRadius,
|
||||||
TargetCamera, TransparentUi, UiBoxShadowSamples, UiScale, Val,
|
TargetCamera, TransparentUi, UiBoxShadowSamples, UiScale, Val,
|
||||||
};
|
};
|
||||||
use bevy_app::prelude::*;
|
use bevy_app::prelude::*;
|
||||||
|
@ -239,7 +239,7 @@ pub fn extract_shadows(
|
||||||
box_shadow_query: Extract<
|
box_shadow_query: Extract<
|
||||||
Query<(
|
Query<(
|
||||||
Entity,
|
Entity,
|
||||||
&Node,
|
&ComputedNode,
|
||||||
&GlobalTransform,
|
&GlobalTransform,
|
||||||
&ViewVisibility,
|
&ViewVisibility,
|
||||||
&BoxShadow,
|
&BoxShadow,
|
||||||
|
|
|
@ -5,7 +5,7 @@ mod ui_material_pipeline;
|
||||||
pub mod ui_texture_slice_pipeline;
|
pub mod ui_texture_slice_pipeline;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
BackgroundColor, BorderColor, CalculatedClip, DefaultUiCamera, Node, Outline,
|
BackgroundColor, BorderColor, CalculatedClip, ComputedNode, DefaultUiCamera, Outline,
|
||||||
ResolvedBorderRadius, TargetCamera, UiAntiAlias, UiBoxShadowSamples, UiImage, UiScale,
|
ResolvedBorderRadius, TargetCamera, UiAntiAlias, UiBoxShadowSamples, UiImage, UiScale,
|
||||||
};
|
};
|
||||||
use bevy_app::prelude::*;
|
use bevy_app::prelude::*;
|
||||||
|
@ -245,7 +245,7 @@ pub fn extract_uinode_background_colors(
|
||||||
uinode_query: Extract<
|
uinode_query: Extract<
|
||||||
Query<(
|
Query<(
|
||||||
Entity,
|
Entity,
|
||||||
&Node,
|
&ComputedNode,
|
||||||
&GlobalTransform,
|
&GlobalTransform,
|
||||||
&ViewVisibility,
|
&ViewVisibility,
|
||||||
Option<&CalculatedClip>,
|
Option<&CalculatedClip>,
|
||||||
|
@ -309,7 +309,7 @@ pub fn extract_uinode_images(
|
||||||
Query<
|
Query<
|
||||||
(
|
(
|
||||||
Entity,
|
Entity,
|
||||||
&Node,
|
&ComputedNode,
|
||||||
&GlobalTransform,
|
&GlobalTransform,
|
||||||
&ViewVisibility,
|
&ViewVisibility,
|
||||||
Option<&CalculatedClip>,
|
Option<&CalculatedClip>,
|
||||||
|
@ -398,7 +398,7 @@ pub fn extract_uinode_borders(
|
||||||
uinode_query: Extract<
|
uinode_query: Extract<
|
||||||
Query<(
|
Query<(
|
||||||
Entity,
|
Entity,
|
||||||
&Node,
|
&ComputedNode,
|
||||||
&GlobalTransform,
|
&GlobalTransform,
|
||||||
&ViewVisibility,
|
&ViewVisibility,
|
||||||
Option<&CalculatedClip>,
|
Option<&CalculatedClip>,
|
||||||
|
@ -613,7 +613,7 @@ pub fn extract_text_sections(
|
||||||
uinode_query: Extract<
|
uinode_query: Extract<
|
||||||
Query<(
|
Query<(
|
||||||
Entity,
|
Entity,
|
||||||
&Node,
|
&ComputedNode,
|
||||||
&GlobalTransform,
|
&GlobalTransform,
|
||||||
&ViewVisibility,
|
&ViewVisibility,
|
||||||
Option<&CalculatedClip>,
|
Option<&CalculatedClip>,
|
||||||
|
|
|
@ -365,7 +365,7 @@ pub fn extract_ui_material_nodes<M: UiMaterial>(
|
||||||
uinode_query: Extract<
|
uinode_query: Extract<
|
||||||
Query<(
|
Query<(
|
||||||
Entity,
|
Entity,
|
||||||
&Node,
|
&ComputedNode,
|
||||||
&GlobalTransform,
|
&GlobalTransform,
|
||||||
&MaterialNode<M>,
|
&MaterialNode<M>,
|
||||||
&ViewVisibility,
|
&ViewVisibility,
|
||||||
|
|
|
@ -251,7 +251,7 @@ pub fn extract_ui_texture_slices(
|
||||||
slicers_query: Extract<
|
slicers_query: Extract<
|
||||||
Query<(
|
Query<(
|
||||||
Entity,
|
Entity,
|
||||||
&Node,
|
&ComputedNode,
|
||||||
&GlobalTransform,
|
&GlobalTransform,
|
||||||
&ViewVisibility,
|
&ViewVisibility,
|
||||||
Option<&CalculatedClip>,
|
Option<&CalculatedClip>,
|
||||||
|
|
|
@ -5,7 +5,7 @@ use bevy_utils::HashSet;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
experimental::{UiChildren, UiRootNodes},
|
experimental::{UiChildren, UiRootNodes},
|
||||||
GlobalZIndex, Node, ZIndex,
|
ComputedNode, GlobalZIndex, ZIndex,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The current UI stack, which contains all UI nodes ordered by their depth (back-to-front).
|
/// The current UI stack, which contains all UI nodes ordered by their depth (back-to-front).
|
||||||
|
@ -46,10 +46,10 @@ pub fn ui_stack_system(
|
||||||
mut ui_stack: ResMut<UiStack>,
|
mut ui_stack: ResMut<UiStack>,
|
||||||
ui_root_nodes: UiRootNodes,
|
ui_root_nodes: UiRootNodes,
|
||||||
root_node_query: Query<(Entity, Option<&GlobalZIndex>, Option<&ZIndex>)>,
|
root_node_query: Query<(Entity, Option<&GlobalZIndex>, Option<&ZIndex>)>,
|
||||||
zindex_global_node_query: Query<(Entity, &GlobalZIndex, Option<&ZIndex>), With<Node>>,
|
zindex_global_node_query: Query<(Entity, &GlobalZIndex, Option<&ZIndex>), With<ComputedNode>>,
|
||||||
ui_children: UiChildren,
|
ui_children: UiChildren,
|
||||||
zindex_query: Query<Option<&ZIndex>, (With<Node>, Without<GlobalZIndex>)>,
|
zindex_query: Query<Option<&ZIndex>, (With<ComputedNode>, Without<GlobalZIndex>)>,
|
||||||
mut update_query: Query<&mut Node>,
|
mut update_query: Query<&mut ComputedNode>,
|
||||||
) {
|
) {
|
||||||
ui_stack.uinodes.clear();
|
ui_stack.uinodes.clear();
|
||||||
visited_root_nodes.clear();
|
visited_root_nodes.clear();
|
||||||
|
@ -102,7 +102,7 @@ fn update_uistack_recursive(
|
||||||
cache: &mut ChildBufferCache,
|
cache: &mut ChildBufferCache,
|
||||||
node_entity: Entity,
|
node_entity: Entity,
|
||||||
ui_children: &UiChildren,
|
ui_children: &UiChildren,
|
||||||
zindex_query: &Query<Option<&ZIndex>, (With<Node>, Without<GlobalZIndex>)>,
|
zindex_query: &Query<Option<&ZIndex>, (With<ComputedNode>, Without<GlobalZIndex>)>,
|
||||||
ui_stack: &mut Vec<Entity>,
|
ui_stack: &mut Vec<Entity>,
|
||||||
) {
|
) {
|
||||||
ui_stack.push(node_entity);
|
ui_stack.push(node_entity);
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use core::hash::Hash;
|
|
||||||
|
|
||||||
use crate::Node;
|
use crate::Node;
|
||||||
use bevy_asset::{Asset, AssetId, Handle};
|
use bevy_asset::{Asset, AssetId, Handle};
|
||||||
use bevy_derive::{Deref, DerefMut};
|
use bevy_derive::{Deref, DerefMut};
|
||||||
|
@ -9,6 +7,7 @@ use bevy_render::{
|
||||||
extract_component::ExtractComponent,
|
extract_component::ExtractComponent,
|
||||||
render_resource::{AsBindGroup, RenderPipelineDescriptor, ShaderRef},
|
render_resource::{AsBindGroup, RenderPipelineDescriptor, ShaderRef},
|
||||||
};
|
};
|
||||||
|
use core::hash::Hash;
|
||||||
use derive_more::derive::From;
|
use derive_more::derive::From;
|
||||||
|
|
||||||
/// Materials are used alongside [`UiMaterialPlugin`](crate::UiMaterialPlugin) and [`MaterialNode`]
|
/// Materials are used alongside [`UiMaterialPlugin`](crate::UiMaterialPlugin) and [`MaterialNode`]
|
||||||
|
@ -64,7 +63,7 @@ use derive_more::derive::From;
|
||||||
/// color: LinearRgba::RED,
|
/// color: LinearRgba::RED,
|
||||||
/// color_texture: asset_server.load("some_image.png"),
|
/// color_texture: asset_server.load("some_image.png"),
|
||||||
/// })),
|
/// })),
|
||||||
/// Style {
|
/// Node {
|
||||||
/// width: Val::Percent(100.0),
|
/// width: Val::Percent(100.0),
|
||||||
/// ..Default::default()
|
/// ..Default::default()
|
||||||
/// },
|
/// },
|
||||||
|
|
|
@ -17,29 +17,10 @@ use core::num::NonZero;
|
||||||
use derive_more::derive::{Display, Error, From};
|
use derive_more::derive::{Display, Error, From};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
/// Base component for a UI node, which also provides the computed size of the node.
|
/// Provides the computed size and layout properties of the node.
|
||||||
///
|
|
||||||
/// # See also
|
|
||||||
///
|
|
||||||
/// - [`node_bundles`](crate::node_bundles) for the list of built-in bundles that set up UI node
|
|
||||||
/// - [`RelativeCursorPosition`](crate::RelativeCursorPosition)
|
|
||||||
/// to obtain the cursor position relative to this node
|
|
||||||
/// - [`Interaction`](crate::Interaction) to obtain the interaction state of this node
|
|
||||||
#[derive(Component, Debug, Copy, Clone, PartialEq, Reflect)]
|
#[derive(Component, Debug, Copy, Clone, PartialEq, Reflect)]
|
||||||
#[reflect(Component, Default, Debug)]
|
#[reflect(Component, Default, Debug)]
|
||||||
#[require(
|
pub struct ComputedNode {
|
||||||
Style,
|
|
||||||
BackgroundColor,
|
|
||||||
BorderColor,
|
|
||||||
BorderRadius,
|
|
||||||
ContentSize,
|
|
||||||
FocusPolicy,
|
|
||||||
ScrollPosition,
|
|
||||||
Transform,
|
|
||||||
Visibility,
|
|
||||||
ZIndex
|
|
||||||
)]
|
|
||||||
pub struct Node {
|
|
||||||
/// The order of the node in the UI layout.
|
/// The order of the node in the UI layout.
|
||||||
/// Nodes with a higher stack index are drawn on top of and receive interactions before nodes with lower stack indices.
|
/// Nodes with a higher stack index are drawn on top of and receive interactions before nodes with lower stack indices.
|
||||||
pub(crate) stack_index: u32,
|
pub(crate) stack_index: u32,
|
||||||
|
@ -79,7 +60,7 @@ pub struct Node {
|
||||||
pub(crate) padding: BorderRect,
|
pub(crate) padding: BorderRect,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Node {
|
impl ComputedNode {
|
||||||
/// The calculated node size as width and height in logical pixels.
|
/// The calculated node size as width and height in logical pixels.
|
||||||
///
|
///
|
||||||
/// Automatically calculated by [`super::layout::ui_layout_system`].
|
/// Automatically calculated by [`super::layout::ui_layout_system`].
|
||||||
|
@ -215,7 +196,7 @@ impl Node {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Node {
|
impl ComputedNode {
|
||||||
pub const DEFAULT: Self = Self {
|
pub const DEFAULT: Self = Self {
|
||||||
stack_index: 0,
|
stack_index: 0,
|
||||||
calculated_size: Vec2::ZERO,
|
calculated_size: Vec2::ZERO,
|
||||||
|
@ -228,7 +209,7 @@ impl Node {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Node {
|
impl Default for ComputedNode {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::DEFAULT
|
Self::DEFAULT
|
||||||
}
|
}
|
||||||
|
@ -238,7 +219,7 @@ impl Default for Node {
|
||||||
///
|
///
|
||||||
/// Updating the values of `ScrollPosition` will reposition the children of the node by the offset amount.
|
/// Updating the values of `ScrollPosition` will reposition the children of the node by the offset amount.
|
||||||
/// `ScrollPosition` may be updated by the layout system when a layout change makes a previously valid `ScrollPosition` invalid.
|
/// `ScrollPosition` may be updated by the layout system when a layout change makes a previously valid `ScrollPosition` invalid.
|
||||||
/// Changing this does nothing on a `Node` without a `Style` setting at least one `OverflowAxis` to `OverflowAxis::Scroll`.
|
/// Changing this does nothing on a `Node` without setting at least one `OverflowAxis` to `OverflowAxis::Scroll`.
|
||||||
#[derive(Component, Debug, Clone, Reflect)]
|
#[derive(Component, Debug, Clone, Reflect)]
|
||||||
#[reflect(Component, Default)]
|
#[reflect(Component, Default)]
|
||||||
pub struct ScrollPosition {
|
pub struct ScrollPosition {
|
||||||
|
@ -276,7 +257,9 @@ impl From<&Vec2> for ScrollPosition {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Describes the style of a UI container node
|
/// The base component for UI entities. It describes UI layout and style properties.
|
||||||
|
///
|
||||||
|
/// When defining new types of UI entities, require [`Node`] to make them behave like UI nodes.
|
||||||
///
|
///
|
||||||
/// Nodes can be laid out using either Flexbox or CSS Grid Layout.
|
/// Nodes can be laid out using either Flexbox or CSS Grid Layout.
|
||||||
///
|
///
|
||||||
|
@ -293,15 +276,32 @@ impl From<&Vec2> for ScrollPosition {
|
||||||
/// - [MDN: Basic Concepts of Grid Layout](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Basic_Concepts_of_Grid_Layout)
|
/// - [MDN: Basic Concepts of Grid Layout](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Basic_Concepts_of_Grid_Layout)
|
||||||
/// - [A Complete Guide To CSS Grid](https://css-tricks.com/snippets/css/complete-guide-grid/) by CSS Tricks. This is detailed guide with illustrations and comprehensive written explanation of the different CSS Grid properties and how they work.
|
/// - [A Complete Guide To CSS Grid](https://css-tricks.com/snippets/css/complete-guide-grid/) by CSS Tricks. This is detailed guide with illustrations and comprehensive written explanation of the different CSS Grid properties and how they work.
|
||||||
/// - [CSS Grid Garden](https://cssgridgarden.com/). An interactive tutorial/game that teaches the essential parts of CSS Grid in a fun engaging way.
|
/// - [CSS Grid Garden](https://cssgridgarden.com/). An interactive tutorial/game that teaches the essential parts of CSS Grid in a fun engaging way.
|
||||||
|
///
|
||||||
|
/// # See also
|
||||||
|
///
|
||||||
|
/// - [`RelativeCursorPosition`](crate::RelativeCursorPosition) to obtain the cursor position relative to this node
|
||||||
|
/// - [`Interaction`](crate::Interaction) to obtain the interaction state of this node
|
||||||
|
|
||||||
#[derive(Component, Clone, PartialEq, Debug, Reflect)]
|
#[derive(Component, Clone, PartialEq, Debug, Reflect)]
|
||||||
|
#[require(
|
||||||
|
ComputedNode,
|
||||||
|
BackgroundColor,
|
||||||
|
BorderColor,
|
||||||
|
BorderRadius,
|
||||||
|
ContentSize,
|
||||||
|
FocusPolicy,
|
||||||
|
ScrollPosition,
|
||||||
|
Transform,
|
||||||
|
Visibility,
|
||||||
|
ZIndex
|
||||||
|
)]
|
||||||
#[reflect(Component, Default, PartialEq, Debug)]
|
#[reflect(Component, Default, PartialEq, Debug)]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "serialize",
|
feature = "serialize",
|
||||||
derive(serde::Serialize, serde::Deserialize),
|
derive(serde::Serialize, serde::Deserialize),
|
||||||
reflect(Serialize, Deserialize)
|
reflect(Serialize, Deserialize)
|
||||||
)]
|
)]
|
||||||
pub struct Style {
|
pub struct Node {
|
||||||
/// Which layout algorithm to use when laying out this node's contents:
|
/// Which layout algorithm to use when laying out this node's contents:
|
||||||
/// - [`Display::Flex`]: Use the Flexbox layout algorithm
|
/// - [`Display::Flex`]: Use the Flexbox layout algorithm
|
||||||
/// - [`Display::Grid`]: Use the CSS Grid layout algorithm
|
/// - [`Display::Grid`]: Use the CSS Grid layout algorithm
|
||||||
|
@ -446,8 +446,8 @@ pub struct Style {
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
/// ```
|
/// ```
|
||||||
/// # use bevy_ui::{Style, UiRect, Val};
|
/// # use bevy_ui::{Node, UiRect, Val};
|
||||||
/// let style = Style {
|
/// let node = Node {
|
||||||
/// margin: UiRect {
|
/// margin: UiRect {
|
||||||
/// left: Val::Percent(10.),
|
/// left: Val::Percent(10.),
|
||||||
/// right: Val::Percent(10.),
|
/// right: Val::Percent(10.),
|
||||||
|
@ -468,8 +468,8 @@ pub struct Style {
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
/// ```
|
/// ```
|
||||||
/// # use bevy_ui::{Style, UiRect, Val};
|
/// # use bevy_ui::{Node, UiRect, Val};
|
||||||
/// let style = Style {
|
/// let node = Node {
|
||||||
/// padding: UiRect {
|
/// padding: UiRect {
|
||||||
/// left: Val::Percent(1.),
|
/// left: Val::Percent(1.),
|
||||||
/// right: Val::Percent(2.),
|
/// right: Val::Percent(2.),
|
||||||
|
@ -574,7 +574,7 @@ pub struct Style {
|
||||||
pub grid_column: GridPlacement,
|
pub grid_column: GridPlacement,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Style {
|
impl Node {
|
||||||
pub const DEFAULT: Self = Self {
|
pub const DEFAULT: Self = Self {
|
||||||
display: Display::DEFAULT,
|
display: Display::DEFAULT,
|
||||||
position_type: PositionType::DEFAULT,
|
position_type: PositionType::DEFAULT,
|
||||||
|
@ -617,7 +617,7 @@ impl Style {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Style {
|
impl Default for Node {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::DEFAULT
|
Self::DEFAULT
|
||||||
}
|
}
|
||||||
|
@ -879,7 +879,7 @@ impl Default for JustifyContent {
|
||||||
|
|
||||||
/// Defines the layout model used by this node.
|
/// Defines the layout model used by this node.
|
||||||
///
|
///
|
||||||
/// Part of the [`Style`] component.
|
/// Part of the [`Node`] component.
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Reflect)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug, Reflect)]
|
||||||
#[reflect(Default, PartialEq)]
|
#[reflect(Default, PartialEq)]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
|
@ -1976,8 +1976,7 @@ impl Default for BorderColor {
|
||||||
/// # use bevy_color::palettes::basic::{RED, BLUE};
|
/// # use bevy_color::palettes::basic::{RED, BLUE};
|
||||||
/// fn setup_ui(mut commands: Commands) {
|
/// fn setup_ui(mut commands: Commands) {
|
||||||
/// commands.spawn((
|
/// commands.spawn((
|
||||||
/// Node::default(),
|
/// Node {
|
||||||
/// Style {
|
|
||||||
/// width: Val::Px(100.),
|
/// width: Val::Px(100.),
|
||||||
/// height: Val::Px(100.),
|
/// height: Val::Px(100.),
|
||||||
/// ..Default::default()
|
/// ..Default::default()
|
||||||
|
@ -2192,8 +2191,7 @@ pub struct GlobalZIndex(pub i32);
|
||||||
/// # use bevy_color::palettes::basic::{BLUE};
|
/// # use bevy_color::palettes::basic::{BLUE};
|
||||||
/// fn setup_ui(mut commands: Commands) {
|
/// fn setup_ui(mut commands: Commands) {
|
||||||
/// commands.spawn((
|
/// commands.spawn((
|
||||||
/// Node::default(),
|
/// Node {
|
||||||
/// Style {
|
|
||||||
/// width: Val::Px(100.),
|
/// width: Val::Px(100.),
|
||||||
/// height: Val::Px(100.),
|
/// height: Val::Px(100.),
|
||||||
/// border: UiRect::all(Val::Px(2.)),
|
/// border: UiRect::all(Val::Px(2.)),
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
experimental::{UiChildren, UiRootNodes},
|
experimental::{UiChildren, UiRootNodes},
|
||||||
CalculatedClip, Display, OverflowAxis, Style, TargetCamera,
|
CalculatedClip, Display, Node, OverflowAxis, TargetCamera,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::Node;
|
use super::ComputedNode;
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
entity::Entity,
|
entity::Entity,
|
||||||
query::{Changed, With},
|
query::{Changed, With},
|
||||||
|
@ -20,7 +20,12 @@ use bevy_utils::HashSet;
|
||||||
pub fn update_clipping_system(
|
pub fn update_clipping_system(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
root_nodes: UiRootNodes,
|
root_nodes: UiRootNodes,
|
||||||
mut node_query: Query<(&Node, &GlobalTransform, &Style, Option<&mut CalculatedClip>)>,
|
mut node_query: Query<(
|
||||||
|
&Node,
|
||||||
|
&ComputedNode,
|
||||||
|
&GlobalTransform,
|
||||||
|
Option<&mut CalculatedClip>,
|
||||||
|
)>,
|
||||||
ui_children: UiChildren,
|
ui_children: UiChildren,
|
||||||
) {
|
) {
|
||||||
for root_node in root_nodes.iter() {
|
for root_node in root_nodes.iter() {
|
||||||
|
@ -37,17 +42,23 @@ pub fn update_clipping_system(
|
||||||
fn update_clipping(
|
fn update_clipping(
|
||||||
commands: &mut Commands,
|
commands: &mut Commands,
|
||||||
ui_children: &UiChildren,
|
ui_children: &UiChildren,
|
||||||
node_query: &mut Query<(&Node, &GlobalTransform, &Style, Option<&mut CalculatedClip>)>,
|
node_query: &mut Query<(
|
||||||
|
&Node,
|
||||||
|
&ComputedNode,
|
||||||
|
&GlobalTransform,
|
||||||
|
Option<&mut CalculatedClip>,
|
||||||
|
)>,
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
mut maybe_inherited_clip: Option<Rect>,
|
mut maybe_inherited_clip: Option<Rect>,
|
||||||
) {
|
) {
|
||||||
let Ok((node, global_transform, style, maybe_calculated_clip)) = node_query.get_mut(entity)
|
let Ok((node, computed_node, global_transform, maybe_calculated_clip)) =
|
||||||
|
node_query.get_mut(entity)
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
// If `display` is None, clip the entire node and all its descendants by replacing the inherited clip with a default rect (which is empty)
|
// If `display` is None, clip the entire node and all its descendants by replacing the inherited clip with a default rect (which is empty)
|
||||||
if style.display == Display::None {
|
if node.display == Display::None {
|
||||||
maybe_inherited_clip = Some(Rect::default());
|
maybe_inherited_clip = Some(Rect::default());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +83,7 @@ fn update_clipping(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate new clip rectangle for children nodes
|
// Calculate new clip rectangle for children nodes
|
||||||
let children_clip = if style.overflow.is_visible() {
|
let children_clip = if node.overflow.is_visible() {
|
||||||
// When `Visible`, children might be visible even when they are outside
|
// When `Visible`, children might be visible even when they are outside
|
||||||
// the current node's boundaries. In this case they inherit the current
|
// the current node's boundaries. In this case they inherit the current
|
||||||
// node's parent clip. If an ancestor is set as `Hidden`, that clip will
|
// node's parent clip. If an ancestor is set as `Hidden`, that clip will
|
||||||
|
@ -84,17 +95,19 @@ fn update_clipping(
|
||||||
// of nested `Overflow::Hidden` nodes. If parent `clip` is not
|
// of nested `Overflow::Hidden` nodes. If parent `clip` is not
|
||||||
// defined, use the current node's clip.
|
// defined, use the current node's clip.
|
||||||
|
|
||||||
let mut clip_rect =
|
let mut clip_rect = Rect::from_center_size(
|
||||||
Rect::from_center_size(global_transform.translation().truncate(), node.size());
|
global_transform.translation().truncate(),
|
||||||
|
computed_node.size(),
|
||||||
|
);
|
||||||
|
|
||||||
// Content isn't clipped at the edges of the node but at the edges of the region specified by [`Style::overflow_clip_margin`].
|
// Content isn't clipped at the edges of the node but at the edges of the region specified by [`Node::overflow_clip_margin`].
|
||||||
//
|
//
|
||||||
// `clip_inset` should always fit inside `node_rect`.
|
// `clip_inset` should always fit inside `node_rect`.
|
||||||
// Even if `clip_inset` were to overflow, we won't return a degenerate result as `Rect::intersect` will clamp the intersection, leaving it empty.
|
// Even if `clip_inset` were to overflow, we won't return a degenerate result as `Rect::intersect` will clamp the intersection, leaving it empty.
|
||||||
let clip_inset = match style.overflow_clip_margin.visual_box {
|
let clip_inset = match node.overflow_clip_margin.visual_box {
|
||||||
crate::OverflowClipBox::BorderBox => BorderRect::ZERO,
|
crate::OverflowClipBox::BorderBox => BorderRect::ZERO,
|
||||||
crate::OverflowClipBox::ContentBox => node.content_inset(),
|
crate::OverflowClipBox::ContentBox => computed_node.content_inset(),
|
||||||
crate::OverflowClipBox::PaddingBox => node.border(),
|
crate::OverflowClipBox::PaddingBox => computed_node.border(),
|
||||||
};
|
};
|
||||||
|
|
||||||
clip_rect.min.x += clip_inset.left;
|
clip_rect.min.x += clip_inset.left;
|
||||||
|
@ -102,13 +115,13 @@ fn update_clipping(
|
||||||
clip_rect.max.x -= clip_inset.right;
|
clip_rect.max.x -= clip_inset.right;
|
||||||
clip_rect.max.y -= clip_inset.bottom;
|
clip_rect.max.y -= clip_inset.bottom;
|
||||||
|
|
||||||
clip_rect = clip_rect.inflate(style.overflow_clip_margin.margin.max(0.));
|
clip_rect = clip_rect.inflate(node.overflow_clip_margin.margin.max(0.));
|
||||||
|
|
||||||
if style.overflow.x == OverflowAxis::Visible {
|
if node.overflow.x == OverflowAxis::Visible {
|
||||||
clip_rect.min.x = -f32::INFINITY;
|
clip_rect.min.x = -f32::INFINITY;
|
||||||
clip_rect.max.x = f32::INFINITY;
|
clip_rect.max.x = f32::INFINITY;
|
||||||
}
|
}
|
||||||
if style.overflow.y == OverflowAxis::Visible {
|
if node.overflow.y == OverflowAxis::Visible {
|
||||||
clip_rect.min.y = -f32::INFINITY;
|
clip_rect.min.y = -f32::INFINITY;
|
||||||
clip_rect.max.y = f32::INFINITY;
|
clip_rect.max.y = f32::INFINITY;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
ContentSize, DefaultUiCamera, FixedMeasure, Measure, MeasureArgs, Node, NodeMeasure,
|
ComputedNode, ContentSize, DefaultUiCamera, FixedMeasure, Measure, MeasureArgs, Node,
|
||||||
TargetCamera, UiScale,
|
NodeMeasure, TargetCamera, UiScale,
|
||||||
};
|
};
|
||||||
use bevy_asset::Assets;
|
use bevy_asset::Assets;
|
||||||
use bevy_color::Color;
|
use bevy_color::Color;
|
||||||
|
@ -102,7 +102,7 @@ pub struct TextBundle {}
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Component, Debug, Default, Clone, Deref, DerefMut, Reflect)]
|
#[derive(Component, Debug, Default, Clone, Deref, DerefMut, Reflect)]
|
||||||
#[reflect(Component, Default, Debug)]
|
#[reflect(Component, Default, Debug)]
|
||||||
#[require(TextLayout, TextFont, TextColor, TextNodeFlags, Node)]
|
#[require(Node, TextLayout, TextFont, TextColor, TextNodeFlags)]
|
||||||
pub struct Text(pub String);
|
pub struct Text(pub String);
|
||||||
|
|
||||||
impl Text {
|
impl Text {
|
||||||
|
@ -331,7 +331,7 @@ fn queue_text(
|
||||||
scale_factor: f32,
|
scale_factor: f32,
|
||||||
inverse_scale_factor: f32,
|
inverse_scale_factor: f32,
|
||||||
block: &TextLayout,
|
block: &TextLayout,
|
||||||
node: Ref<Node>,
|
node: Ref<ComputedNode>,
|
||||||
mut text_flags: Mut<TextNodeFlags>,
|
mut text_flags: Mut<TextNodeFlags>,
|
||||||
text_layout_info: Mut<TextLayoutInfo>,
|
text_layout_info: Mut<TextLayoutInfo>,
|
||||||
computed: &mut ComputedTextBlock,
|
computed: &mut ComputedTextBlock,
|
||||||
|
@ -408,7 +408,7 @@ pub fn text_system(
|
||||||
mut text_pipeline: ResMut<TextPipeline>,
|
mut text_pipeline: ResMut<TextPipeline>,
|
||||||
mut text_query: Query<(
|
mut text_query: Query<(
|
||||||
Entity,
|
Entity,
|
||||||
Ref<Node>,
|
Ref<ComputedNode>,
|
||||||
&TextLayout,
|
&TextLayout,
|
||||||
&mut TextLayoutInfo,
|
&mut TextLayoutInfo,
|
||||||
&mut TextNodeFlags,
|
&mut TextNodeFlags,
|
||||||
|
|
|
@ -66,7 +66,7 @@ fn setup(
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::new("Press space to toggle wireframes"),
|
Text::new("Press space to toggle wireframes"),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -59,7 +59,7 @@ fn setup(
|
||||||
// UI
|
// UI
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::default(),
|
Text::default(),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(12.0),
|
bottom: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -254,7 +254,7 @@ fn setup(mut commands: Commands) {
|
||||||
|
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::default(),
|
Text::default(),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(12.0),
|
bottom: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -135,7 +135,7 @@ fn setup(
|
||||||
// create a minimal UI explaining how to interact with the example
|
// create a minimal UI explaining how to interact with the example
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::new("Left Arrow Key: Animate Left Sprite\nRight Arrow Key: Animate Right Sprite"),
|
Text::new("Left Arrow Key: Animate Left Sprite\nRight Arrow Key: Animate Right Sprite"),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -90,7 +90,7 @@ fn setup(
|
||||||
// Text used to show controls
|
// Text used to show controls
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::default(),
|
Text::default(),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -135,7 +135,7 @@ fn setup(
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::new("Press space to toggle wireframes"),
|
Text::new("Press space to toggle wireframes"),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -83,7 +83,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>, app_status: Res
|
||||||
fn spawn_text(commands: &mut Commands, app_status: &AppStatus) {
|
fn spawn_text(commands: &mut Commands, app_status: &AppStatus) {
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
app_status.create_help_text(),
|
app_status.create_help_text(),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(12.0),
|
bottom: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -328,7 +328,7 @@ fn setup(
|
||||||
// example instructions
|
// example instructions
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::default(),
|
Text::default(),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -86,7 +86,7 @@ fn setup_terrain_scene(
|
||||||
|
|
||||||
fn setup_instructions(mut commands: Commands) {
|
fn setup_instructions(mut commands: Commands) {
|
||||||
commands.spawn((Text::new("Press Spacebar to Toggle Atmospheric Fog.\nPress S to Toggle Directional Light Fog Influence."),
|
commands.spawn((Text::new("Press Spacebar to Toggle Atmospheric Fog.\nPress S to Toggle Directional Light Fog Influence."),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(12.0),
|
bottom: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -119,17 +119,17 @@ fn setup(
|
||||||
texture: metering_mask,
|
texture: metering_mask,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
Style {
|
Node {
|
||||||
width: Val::Percent(100.0),
|
width: Val::Percent(100.0),
|
||||||
height: Val::Percent(100.0),
|
height: Val::Percent(100.0),
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
||||||
let text_style = TextFont::default();
|
let text_font = TextFont::default();
|
||||||
|
|
||||||
commands.spawn((Text::new("Left / Right - Rotate Camera\nC - Toggle Compensation Curve\nM - Toggle Metering Mask\nV - Visualize Metering Mask"),
|
commands.spawn((Text::new("Left / Right - Rotate Camera\nC - Toggle Compensation Curve\nM - Toggle Metering Mask\nV - Visualize Metering Mask"),
|
||||||
text_style.clone(), Style {
|
text_font.clone(), Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
@ -139,8 +139,8 @@ fn setup(
|
||||||
|
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::default(),
|
Text::default(),
|
||||||
text_style,
|
text_font,
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
right: Val::Px(12.0),
|
right: Val::Px(12.0),
|
||||||
|
@ -162,7 +162,7 @@ struct ExampleResources {
|
||||||
fn example_control_system(
|
fn example_control_system(
|
||||||
camera: Single<(&mut Transform, &mut AutoExposure), With<Camera3d>>,
|
camera: Single<(&mut Transform, &mut AutoExposure), With<Camera3d>>,
|
||||||
mut display: Single<&mut Text, With<ExampleDisplay>>,
|
mut display: Single<&mut Text, With<ExampleDisplay>>,
|
||||||
mut mask_image: Single<&mut Style, With<UiImage>>,
|
mut mask_image: Single<&mut Node, With<UiImage>>,
|
||||||
time: Res<Time>,
|
time: Res<Time>,
|
||||||
input: Res<ButtonInput<KeyCode>>,
|
input: Res<ButtonInput<KeyCode>>,
|
||||||
resources: Res<ExampleResources>,
|
resources: Res<ExampleResources>,
|
||||||
|
|
|
@ -169,7 +169,7 @@ fn setup(
|
||||||
|
|
||||||
commands.spawn((Text::new("Up / Down — Increase / Decrease Alpha\nLeft / Right — Rotate Camera\nH - Toggle HDR\nSpacebar — Toggle Unlit\nC — Randomize Colors"),
|
commands.spawn((Text::new("Up / Down — Increase / Decrease Alpha\nLeft / Right — Rotate Camera\nH - Toggle HDR\nSpacebar — Toggle Unlit\nC — Randomize Colors"),
|
||||||
text_style.clone(),
|
text_style.clone(),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
@ -180,7 +180,7 @@ fn setup(
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::default(),
|
Text::default(),
|
||||||
text_style,
|
text_style,
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
right: Val::Px(12.0),
|
right: Val::Px(12.0),
|
||||||
|
@ -192,8 +192,7 @@ fn setup(
|
||||||
let mut label = |entity: Entity, label: &str| {
|
let mut label = |entity: Entity, label: &str| {
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
|
@ -203,7 +202,7 @@ fn setup(
|
||||||
parent.spawn((
|
parent.spawn((
|
||||||
Text::new(label),
|
Text::new(label),
|
||||||
label_text_style.clone(),
|
label_text_style.clone(),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::ZERO,
|
bottom: Val::ZERO,
|
||||||
..default()
|
..default()
|
||||||
|
@ -253,7 +252,7 @@ fn example_control_system(
|
||||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||||
controllable: Query<(&MeshMaterial3d<StandardMaterial>, &ExampleControls)>,
|
controllable: Query<(&MeshMaterial3d<StandardMaterial>, &ExampleControls)>,
|
||||||
camera: Single<(&mut Camera, &mut Transform, &GlobalTransform), With<Camera3d>>,
|
camera: Single<(&mut Camera, &mut Transform, &GlobalTransform), With<Camera3d>>,
|
||||||
mut labels: Query<(&mut Style, &ExampleLabel)>,
|
mut labels: Query<(&mut Node, &ExampleLabel)>,
|
||||||
mut display: Single<&mut Text, With<ExampleDisplay>>,
|
mut display: Single<&mut Text, With<ExampleDisplay>>,
|
||||||
labelled: Query<&GlobalTransform>,
|
labelled: Query<&GlobalTransform>,
|
||||||
mut state: Local<ExampleState>,
|
mut state: Local<ExampleState>,
|
||||||
|
@ -308,15 +307,15 @@ fn example_control_system(
|
||||||
|
|
||||||
camera_transform.rotate_around(Vec3::ZERO, Quat::from_rotation_y(rotation));
|
camera_transform.rotate_around(Vec3::ZERO, Quat::from_rotation_y(rotation));
|
||||||
|
|
||||||
for (mut style, label) in &mut labels {
|
for (mut node, label) in &mut labels {
|
||||||
let world_position = labelled.get(label.entity).unwrap().translation() + Vec3::Y;
|
let world_position = labelled.get(label.entity).unwrap().translation() + Vec3::Y;
|
||||||
|
|
||||||
let viewport_position = camera
|
let viewport_position = camera
|
||||||
.world_to_viewport(camera_global_transform, world_position)
|
.world_to_viewport(camera_global_transform, world_position)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
style.top = Val::Px(viewport_position.y);
|
node.top = Val::Px(viewport_position.y);
|
||||||
style.left = Val::Px(viewport_position.x);
|
node.left = Val::Px(viewport_position.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
display.0 = format!(
|
display.0 = format!(
|
||||||
|
|
|
@ -86,7 +86,7 @@ fn setup_scene(
|
||||||
// example instructions
|
// example instructions
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::default(),
|
Text::default(),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(12.0),
|
bottom: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -219,7 +219,7 @@ fn spawn_camera(commands: &mut Commands, asset_server: &AssetServer) {
|
||||||
fn spawn_text(commands: &mut Commands, light_mode: &LightMode) {
|
fn spawn_text(commands: &mut Commands, light_mode: &LightMode) {
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
light_mode.create_help_text(),
|
light_mode.create_help_text(),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(12.0),
|
bottom: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -138,17 +138,14 @@ fn setup(
|
||||||
fn add_buttons(commands: &mut Commands, font: &Handle<Font>, color_grading: &ColorGrading) {
|
fn add_buttons(commands: &mut Commands, font: &Handle<Font>, color_grading: &ColorGrading) {
|
||||||
// Spawn the parent node that contains all the buttons.
|
// Spawn the parent node that contains all the buttons.
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn(Node {
|
||||||
Node::default(),
|
flex_direction: FlexDirection::Column,
|
||||||
Style {
|
position_type: PositionType::Absolute,
|
||||||
flex_direction: FlexDirection::Column,
|
row_gap: Val::Px(6.0),
|
||||||
position_type: PositionType::Absolute,
|
left: Val::Px(12.0),
|
||||||
row_gap: Val::Px(6.0),
|
bottom: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
..default()
|
||||||
bottom: Val::Px(12.0),
|
})
|
||||||
..default()
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
// Create the first row, which contains the global controls.
|
// Create the first row, which contains the global controls.
|
||||||
add_buttons_for_global_controls(parent, color_grading, font);
|
add_buttons_for_global_controls(parent, color_grading, font);
|
||||||
|
@ -174,13 +171,10 @@ fn add_buttons_for_global_controls(
|
||||||
// Add the parent node for the row.
|
// Add the parent node for the row.
|
||||||
parent.spawn(Node::default()).with_children(|parent| {
|
parent.spawn(Node::default()).with_children(|parent| {
|
||||||
// Add some placeholder text to fill this column.
|
// Add some placeholder text to fill this column.
|
||||||
parent.spawn((
|
parent.spawn(Node {
|
||||||
Node::default(),
|
width: Val::Px(125.0),
|
||||||
Style {
|
..default()
|
||||||
width: Val::Px(125.0),
|
});
|
||||||
..default()
|
|
||||||
},
|
|
||||||
));
|
|
||||||
|
|
||||||
// Add each global color grading option button.
|
// Add each global color grading option button.
|
||||||
for option in [
|
for option in [
|
||||||
|
@ -209,16 +203,13 @@ fn add_buttons_for_section(
|
||||||
) {
|
) {
|
||||||
// Spawn the row container.
|
// Spawn the row container.
|
||||||
parent
|
parent
|
||||||
.spawn((
|
.spawn(Node {
|
||||||
Node::default(),
|
align_items: AlignItems::Center,
|
||||||
Style {
|
..default()
|
||||||
align_items: AlignItems::Center,
|
})
|
||||||
..default()
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
// Spawn the label ("Highlights", etc.)
|
// Spawn the label ("Highlights", etc.)
|
||||||
add_text(parent, §ion.to_string(), font, Color::WHITE).insert(Style {
|
add_text(parent, §ion.to_string(), font, Color::WHITE).insert(Node {
|
||||||
width: Val::Px(125.0),
|
width: Val::Px(125.0),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
@ -252,7 +243,7 @@ fn add_button_for_value(
|
||||||
parent
|
parent
|
||||||
.spawn((
|
.spawn((
|
||||||
Button,
|
Button,
|
||||||
Style {
|
Node {
|
||||||
border: UiRect::all(Val::Px(1.0)),
|
border: UiRect::all(Val::Px(1.0)),
|
||||||
width: Val::Px(200.0),
|
width: Val::Px(200.0),
|
||||||
justify_content: JustifyContent::Center,
|
justify_content: JustifyContent::Center,
|
||||||
|
@ -281,13 +272,10 @@ fn add_button_for_value(
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add a spacer.
|
// Add a spacer.
|
||||||
parent.spawn((
|
parent.spawn(Node {
|
||||||
Node::default(),
|
flex_grow: 1.0,
|
||||||
Style {
|
..default()
|
||||||
flex_grow: 1.0,
|
});
|
||||||
..default()
|
|
||||||
},
|
|
||||||
));
|
|
||||||
|
|
||||||
// Add the value text.
|
// Add the value text.
|
||||||
add_text(
|
add_text(
|
||||||
|
@ -315,7 +303,7 @@ fn add_help_text(
|
||||||
font: font.clone(),
|
font: font.clone(),
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
|
|
|
@ -190,7 +190,7 @@ fn setup(
|
||||||
// Example instructions
|
// Example instructions
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::default(),
|
Text::default(),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -94,7 +94,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>, app_settings: R
|
||||||
// Spawn the help text.
|
// Spawn the help text.
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
create_text(&app_settings),
|
create_text(&app_settings),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(12.0),
|
bottom: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -118,7 +118,7 @@ fn setup_pyramid_scene(
|
||||||
fn setup_instructions(mut commands: Commands) {
|
fn setup_instructions(mut commands: Commands) {
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::default(),
|
Text::default(),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -59,7 +59,7 @@ fn setup(
|
||||||
// Text to describe the controls.
|
// Text to describe the controls.
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::new("Controls:\nSpace: Change UVs\nX/Y/Z: Rotate\nR: Reset orientation"),
|
Text::new("Controls:\nSpace: Change UVs\nX/Y/Z: Rotate\nR: Reset orientation"),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -290,7 +290,7 @@ fn spawn_fox(commands: &mut Commands, assets: &ExampleAssets) {
|
||||||
fn spawn_text(commands: &mut Commands, app_status: &AppStatus) {
|
fn spawn_text(commands: &mut Commands, app_status: &AppStatus) {
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
app_status.create_text(),
|
app_status.create_text(),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(12.0),
|
bottom: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -211,7 +211,7 @@ fn setup(
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Text::default(),
|
Text::default(),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -39,7 +39,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
font_size: 15.,
|
font_size: 15.,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -234,7 +234,7 @@ fn setup_ui(mut commands: Commands) {
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Text::default(),
|
Text::default(),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -53,7 +53,7 @@ fn setup(
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Text::default(),
|
Text::default(),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -298,7 +298,7 @@ fn setup(
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Text::default(),
|
Text::default(),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -65,7 +65,7 @@ fn setup(
|
||||||
font_size: 30.0,
|
font_size: 30.0,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(20.0),
|
top: Val::Px(20.0),
|
||||||
left: Val::Px(100.0),
|
left: Val::Px(100.0),
|
||||||
|
@ -79,7 +79,7 @@ fn setup(
|
||||||
font_size: 30.0,
|
font_size: 30.0,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(130.0),
|
top: Val::Px(130.0),
|
||||||
right: Val::ZERO,
|
right: Val::ZERO,
|
||||||
|
@ -97,7 +97,7 @@ fn setup(
|
||||||
font_size: 30.0,
|
font_size: 30.0,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(20.0),
|
bottom: Val::Px(20.0),
|
||||||
right: Val::Px(20.0),
|
right: Val::Px(20.0),
|
||||||
|
|
|
@ -209,7 +209,7 @@ fn spawn_gltf_scene(commands: &mut Commands, asset_server: &AssetServer) {
|
||||||
/// Spawns all the buttons at the bottom of the screen.
|
/// Spawns all the buttons at the bottom of the screen.
|
||||||
fn spawn_buttons(commands: &mut Commands) {
|
fn spawn_buttons(commands: &mut Commands) {
|
||||||
commands
|
commands
|
||||||
.spawn((Node::default(), widgets::main_ui_style()))
|
.spawn(widgets::main_ui_node())
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
widgets::spawn_option_buttons(
|
widgets::spawn_option_buttons(
|
||||||
parent,
|
parent,
|
||||||
|
|
|
@ -124,7 +124,7 @@ fn spawn_scene(commands: &mut Commands, asset_server: &AssetServer) {
|
||||||
fn spawn_text(commands: &mut Commands, app_settings: &AppSettings) {
|
fn spawn_text(commands: &mut Commands, app_settings: &AppSettings) {
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
create_help_text(app_settings),
|
create_help_text(app_settings),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(12.0),
|
bottom: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -154,7 +154,7 @@ fn spawn_text(commands: &mut Commands, app_status: &AppStatus) {
|
||||||
// Create the text.
|
// Create the text.
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
app_status.create_text(),
|
app_status.create_text(),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(12.0),
|
bottom: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -98,8 +98,7 @@ fn setup(
|
||||||
|
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
padding: UiRect::all(Val::Px(5.0)),
|
padding: UiRect::all(Val::Px(5.0)),
|
||||||
..default()
|
..default()
|
||||||
|
|
|
@ -85,8 +85,7 @@ fn setup(
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
TargetCamera(camera),
|
TargetCamera(camera),
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
width: Val::Percent(100.),
|
width: Val::Percent(100.),
|
||||||
height: Val::Percent(100.),
|
height: Val::Percent(100.),
|
||||||
..default()
|
..default()
|
||||||
|
@ -95,7 +94,7 @@ fn setup(
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
parent.spawn((
|
parent.spawn((
|
||||||
Text::new(*camera_name),
|
Text::new(*camera_name),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.),
|
top: Val::Px(12.),
|
||||||
left: Val::Px(12.),
|
left: Val::Px(12.),
|
||||||
|
@ -108,20 +107,17 @@ fn setup(
|
||||||
|
|
||||||
fn buttons_panel(parent: &mut ChildBuilder) {
|
fn buttons_panel(parent: &mut ChildBuilder) {
|
||||||
parent
|
parent
|
||||||
.spawn((
|
.spawn(Node {
|
||||||
Node::default(),
|
position_type: PositionType::Absolute,
|
||||||
Style {
|
width: Val::Percent(100.),
|
||||||
position_type: PositionType::Absolute,
|
height: Val::Percent(100.),
|
||||||
width: Val::Percent(100.),
|
display: Display::Flex,
|
||||||
height: Val::Percent(100.),
|
flex_direction: FlexDirection::Row,
|
||||||
display: Display::Flex,
|
justify_content: JustifyContent::SpaceBetween,
|
||||||
flex_direction: FlexDirection::Row,
|
align_items: AlignItems::Center,
|
||||||
justify_content: JustifyContent::SpaceBetween,
|
padding: UiRect::all(Val::Px(20.)),
|
||||||
align_items: AlignItems::Center,
|
..default()
|
||||||
padding: UiRect::all(Val::Px(20.)),
|
})
|
||||||
..default()
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
rotate_button(parent, "<", Direction::Left);
|
rotate_button(parent, "<", Direction::Left);
|
||||||
rotate_button(parent, ">", Direction::Right);
|
rotate_button(parent, ">", Direction::Right);
|
||||||
|
@ -133,7 +129,7 @@ fn setup(
|
||||||
.spawn((
|
.spawn((
|
||||||
RotateCamera(direction),
|
RotateCamera(direction),
|
||||||
Button,
|
Button,
|
||||||
Style {
|
Node {
|
||||||
width: Val::Px(40.),
|
width: Val::Px(40.),
|
||||||
height: Val::Px(40.),
|
height: Val::Px(40.),
|
||||||
border: UiRect::all(Val::Px(2.)),
|
border: UiRect::all(Val::Px(2.)),
|
||||||
|
|
|
@ -128,7 +128,7 @@ fn setup(
|
||||||
|
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::new(INSTRUCTIONS),
|
Text::new(INSTRUCTIONS),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -80,7 +80,7 @@ fn setup(
|
||||||
|
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::default(),
|
Text::default(),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(12.0),
|
bottom: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -253,7 +253,7 @@ fn spawn_camera(commands: &mut Commands, asset_server: &AssetServer) {
|
||||||
fn spawn_text(commands: &mut Commands, app_settings: &AppSettings) {
|
fn spawn_text(commands: &mut Commands, app_settings: &AppSettings) {
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
create_text(app_settings),
|
create_text(app_settings),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(12.0),
|
bottom: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -83,7 +83,7 @@ fn setup(
|
||||||
// ui
|
// ui
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::default(),
|
Text::default(),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
@ -178,7 +178,7 @@ fn setup_image_viewer_scene(
|
||||||
},
|
},
|
||||||
TextColor(Color::BLACK),
|
TextColor(Color::BLACK),
|
||||||
TextLayout::new_with_justify(JustifyText::Center),
|
TextLayout::new_with_justify(JustifyText::Center),
|
||||||
Style {
|
Node {
|
||||||
align_self: AlignSelf::Center,
|
align_self: AlignSelf::Center,
|
||||||
margin: UiRect::all(Val::Auto),
|
margin: UiRect::all(Val::Auto),
|
||||||
..default()
|
..default()
|
||||||
|
|
|
@ -333,7 +333,7 @@ fn setup(
|
||||||
// Controls Text
|
// Controls Text
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::default(),
|
Text::default(),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -151,7 +151,7 @@ fn setup(
|
||||||
// Create the text.
|
// Create the text.
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
app_status.create_text(),
|
app_status.create_text(),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(12.0),
|
bottom: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -125,7 +125,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>, app_settings: R
|
||||||
// Add the help text.
|
// Add the help text.
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
create_text(&app_settings),
|
create_text(&app_settings),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -101,7 +101,7 @@ fn setup(
|
||||||
// Text used to show controls
|
// Text used to show controls
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::default(),
|
Text::default(),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -151,9 +151,8 @@ fn setup(
|
||||||
// text to be animated.
|
// text to be animated.
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
|
||||||
// Cover the whole screen, and center contents.
|
// Cover the whole screen, and center contents.
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(0.0),
|
top: Val::Px(0.0),
|
||||||
left: Val::Px(0.0),
|
left: Val::Px(0.0),
|
||||||
|
@ -163,9 +162,9 @@ fn setup(
|
||||||
align_items: AlignItems::Center,
|
align_items: AlignItems::Center,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
|
animation_player,
|
||||||
|
AnimationGraphHandle(animation_graph),
|
||||||
))
|
))
|
||||||
.insert(animation_player)
|
|
||||||
.insert(AnimationGraphHandle(animation_graph))
|
|
||||||
.with_children(|builder| {
|
.with_children(|builder| {
|
||||||
// Build the text node.
|
// Build the text node.
|
||||||
let player = builder.parent_entity();
|
let player = builder.parent_entity();
|
||||||
|
|
|
@ -252,7 +252,7 @@ fn setup_scene(
|
||||||
fn setup_help_text(commands: &mut Commands) {
|
fn setup_help_text(commands: &mut Commands) {
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::new(HELP_TEXT),
|
Text::new(HELP_TEXT),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
@ -283,8 +283,7 @@ fn setup_node_rects(commands: &mut Commands) {
|
||||||
|
|
||||||
let container = {
|
let container = {
|
||||||
let mut container = commands.spawn((
|
let mut container = commands.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(node_rect.bottom),
|
bottom: Val::Px(node_rect.bottom),
|
||||||
left: Val::Px(node_rect.left),
|
left: Val::Px(node_rect.left),
|
||||||
|
@ -315,8 +314,7 @@ fn setup_node_rects(commands: &mut Commands) {
|
||||||
if let NodeType::Clip(_) = node_type {
|
if let NodeType::Clip(_) = node_type {
|
||||||
let background = commands
|
let background = commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(0.),
|
top: Val::Px(0.),
|
||||||
left: Val::Px(0.),
|
left: Val::Px(0.),
|
||||||
|
@ -342,8 +340,7 @@ fn setup_node_rects(commands: &mut Commands) {
|
||||||
fn setup_node_lines(commands: &mut Commands) {
|
fn setup_node_lines(commands: &mut Commands) {
|
||||||
for line in &HORIZONTAL_LINES {
|
for line in &HORIZONTAL_LINES {
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(line.bottom),
|
bottom: Val::Px(line.bottom),
|
||||||
left: Val::Px(line.left),
|
left: Val::Px(line.left),
|
||||||
|
@ -358,8 +355,7 @@ fn setup_node_lines(commands: &mut Commands) {
|
||||||
|
|
||||||
for line in &VERTICAL_LINES {
|
for line in &VERTICAL_LINES {
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(line.bottom),
|
bottom: Val::Px(line.bottom),
|
||||||
left: Val::Px(line.left),
|
left: Val::Px(line.left),
|
||||||
|
@ -421,7 +417,7 @@ fn handle_weight_drag(
|
||||||
// Updates the UI based on the weights that the user has chosen.
|
// Updates the UI based on the weights that the user has chosen.
|
||||||
fn update_ui(
|
fn update_ui(
|
||||||
mut text_query: Query<&mut Text>,
|
mut text_query: Query<&mut Text>,
|
||||||
mut background_query: Query<&mut Style, Without<Text>>,
|
mut background_query: Query<&mut Node, Without<Text>>,
|
||||||
container_query: Query<(&Children, &ClipNode)>,
|
container_query: Query<(&Children, &ClipNode)>,
|
||||||
animation_weights_query: Query<&ExampleAnimationWeights, Changed<ExampleAnimationWeights>>,
|
animation_weights_query: Query<&ExampleAnimationWeights, Changed<ExampleAnimationWeights>>,
|
||||||
) {
|
) {
|
||||||
|
@ -429,9 +425,9 @@ fn update_ui(
|
||||||
for (children, clip_node) in &container_query {
|
for (children, clip_node) in &container_query {
|
||||||
// Draw the green background color to visually indicate the weight.
|
// Draw the green background color to visually indicate the weight.
|
||||||
let mut bg_iter = background_query.iter_many_mut(children);
|
let mut bg_iter = background_query.iter_many_mut(children);
|
||||||
if let Some(mut style) = bg_iter.fetch_next() {
|
if let Some(mut node) = bg_iter.fetch_next() {
|
||||||
// All nodes are the same width, so `NODE_RECTS[0]` is as good as any other.
|
// All nodes are the same width, so `NODE_RECTS[0]` is as good as any other.
|
||||||
style.width =
|
node.width =
|
||||||
Val::Px(NODE_RECTS[0].width * animation_weights.weights[clip_node.index]);
|
Val::Px(NODE_RECTS[0].width * animation_weights.weights[clip_node.index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -158,7 +158,7 @@ fn setup_ui(mut commands: Commands) {
|
||||||
// Add help text.
|
// Add help text.
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::new("Click on a button to toggle animations for its associated bones"),
|
Text::new("Click on a button to toggle animations for its associated bones"),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
|
@ -168,19 +168,16 @@ fn setup_ui(mut commands: Commands) {
|
||||||
|
|
||||||
// Add the buttons that allow the user to toggle mask groups on and off.
|
// Add the buttons that allow the user to toggle mask groups on and off.
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn(Node {
|
||||||
Node::default(),
|
flex_direction: FlexDirection::Column,
|
||||||
Style {
|
position_type: PositionType::Absolute,
|
||||||
flex_direction: FlexDirection::Column,
|
row_gap: Val::Px(6.0),
|
||||||
position_type: PositionType::Absolute,
|
left: Val::Px(12.0),
|
||||||
row_gap: Val::Px(6.0),
|
bottom: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
..default()
|
||||||
bottom: Val::Px(12.0),
|
})
|
||||||
..default()
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
let row_style = Style {
|
let row_node = Node {
|
||||||
flex_direction: FlexDirection::Row,
|
flex_direction: FlexDirection::Row,
|
||||||
column_gap: Val::Px(6.0),
|
column_gap: Val::Px(6.0),
|
||||||
..default()
|
..default()
|
||||||
|
@ -188,39 +185,35 @@ fn setup_ui(mut commands: Commands) {
|
||||||
|
|
||||||
add_mask_group_control(parent, "Head", Val::Auto, MASK_GROUP_HEAD);
|
add_mask_group_control(parent, "Head", Val::Auto, MASK_GROUP_HEAD);
|
||||||
|
|
||||||
parent
|
parent.spawn(row_node.clone()).with_children(|parent| {
|
||||||
.spawn((Node::default(), row_style.clone()))
|
add_mask_group_control(
|
||||||
.with_children(|parent| {
|
parent,
|
||||||
add_mask_group_control(
|
"Left Front Leg",
|
||||||
parent,
|
Val::Px(MASK_GROUP_BUTTON_WIDTH),
|
||||||
"Left Front Leg",
|
MASK_GROUP_LEFT_FRONT_LEG,
|
||||||
Val::Px(MASK_GROUP_BUTTON_WIDTH),
|
);
|
||||||
MASK_GROUP_LEFT_FRONT_LEG,
|
add_mask_group_control(
|
||||||
);
|
parent,
|
||||||
add_mask_group_control(
|
"Right Front Leg",
|
||||||
parent,
|
Val::Px(MASK_GROUP_BUTTON_WIDTH),
|
||||||
"Right Front Leg",
|
MASK_GROUP_RIGHT_FRONT_LEG,
|
||||||
Val::Px(MASK_GROUP_BUTTON_WIDTH),
|
);
|
||||||
MASK_GROUP_RIGHT_FRONT_LEG,
|
});
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
parent
|
parent.spawn(row_node).with_children(|parent| {
|
||||||
.spawn((Node::default(), row_style))
|
add_mask_group_control(
|
||||||
.with_children(|parent| {
|
parent,
|
||||||
add_mask_group_control(
|
"Left Hind Leg",
|
||||||
parent,
|
Val::Px(MASK_GROUP_BUTTON_WIDTH),
|
||||||
"Left Hind Leg",
|
MASK_GROUP_LEFT_HIND_LEG,
|
||||||
Val::Px(MASK_GROUP_BUTTON_WIDTH),
|
);
|
||||||
MASK_GROUP_LEFT_HIND_LEG,
|
add_mask_group_control(
|
||||||
);
|
parent,
|
||||||
add_mask_group_control(
|
"Right Hind Leg",
|
||||||
parent,
|
Val::Px(MASK_GROUP_BUTTON_WIDTH),
|
||||||
"Right Hind Leg",
|
MASK_GROUP_RIGHT_HIND_LEG,
|
||||||
Val::Px(MASK_GROUP_BUTTON_WIDTH),
|
);
|
||||||
MASK_GROUP_RIGHT_HIND_LEG,
|
});
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
add_mask_group_control(parent, "Tail", Val::Auto, MASK_GROUP_TAIL);
|
add_mask_group_control(parent, "Tail", Val::Auto, MASK_GROUP_TAIL);
|
||||||
});
|
});
|
||||||
|
@ -246,8 +239,7 @@ fn add_mask_group_control(parent: &mut ChildBuilder, label: &str, width: Val, ma
|
||||||
|
|
||||||
parent
|
parent
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
border: UiRect::all(Val::Px(1.0)),
|
border: UiRect::all(Val::Px(1.0)),
|
||||||
width,
|
width,
|
||||||
flex_direction: FlexDirection::Column,
|
flex_direction: FlexDirection::Column,
|
||||||
|
@ -264,8 +256,7 @@ fn add_mask_group_control(parent: &mut ChildBuilder, label: &str, width: Val, ma
|
||||||
.with_children(|builder| {
|
.with_children(|builder| {
|
||||||
builder
|
builder
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
border: UiRect::ZERO,
|
border: UiRect::ZERO,
|
||||||
width: Val::Percent(100.0),
|
width: Val::Percent(100.0),
|
||||||
justify_content: JustifyContent::Center,
|
justify_content: JustifyContent::Center,
|
||||||
|
@ -279,7 +270,7 @@ fn add_mask_group_control(parent: &mut ChildBuilder, label: &str, width: Val, ma
|
||||||
.with_child((
|
.with_child((
|
||||||
Text::new(label),
|
Text::new(label),
|
||||||
label_text_style.clone(),
|
label_text_style.clone(),
|
||||||
Style {
|
Node {
|
||||||
margin: UiRect::vertical(Val::Px(3.0)),
|
margin: UiRect::vertical(Val::Px(3.0)),
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
|
@ -287,8 +278,7 @@ fn add_mask_group_control(parent: &mut ChildBuilder, label: &str, width: Val, ma
|
||||||
|
|
||||||
builder
|
builder
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
width: Val::Percent(100.0),
|
width: Val::Percent(100.0),
|
||||||
flex_direction: FlexDirection::Row,
|
flex_direction: FlexDirection::Row,
|
||||||
justify_content: JustifyContent::Center,
|
justify_content: JustifyContent::Center,
|
||||||
|
@ -316,7 +306,7 @@ fn add_mask_group_control(parent: &mut ChildBuilder, label: &str, width: Val, ma
|
||||||
} else {
|
} else {
|
||||||
Color::WHITE
|
Color::WHITE
|
||||||
}),
|
}),
|
||||||
Style {
|
Node {
|
||||||
flex_grow: 1.0,
|
flex_grow: 1.0,
|
||||||
border: if index > 0 {
|
border: if index > 0 {
|
||||||
UiRect::left(Val::Px(1.0))
|
UiRect::left(Val::Px(1.0))
|
||||||
|
@ -335,7 +325,7 @@ fn add_mask_group_control(parent: &mut ChildBuilder, label: &str, width: Val, ma
|
||||||
selected_button_text_style.clone()
|
selected_button_text_style.clone()
|
||||||
},
|
},
|
||||||
TextLayout::new_with_justify(JustifyText::Center),
|
TextLayout::new_with_justify(JustifyText::Center),
|
||||||
Style {
|
Node {
|
||||||
flex_grow: 1.0,
|
flex_grow: 1.0,
|
||||||
margin: UiRect::vertical(Val::Px(3.0)),
|
margin: UiRect::vertical(Val::Px(3.0)),
|
||||||
..default()
|
..default()
|
||||||
|
|
|
@ -88,7 +88,7 @@ fn setup(mut commands: Commands) {
|
||||||
}
|
}
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::default(),
|
Text::default(),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(12.0),
|
bottom: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -126,8 +126,7 @@ fn setup(mut commands: Commands) {
|
||||||
commands.spawn(Camera2d);
|
commands.spawn(Camera2d);
|
||||||
|
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
width: Val::Vw(100.0),
|
width: Val::Vw(100.0),
|
||||||
height: Val::Vh(100.0),
|
height: Val::Vh(100.0),
|
||||||
flex_direction: FlexDirection::Column,
|
flex_direction: FlexDirection::Column,
|
||||||
|
|
|
@ -21,7 +21,7 @@ fn setup(mut commands: Commands) {
|
||||||
commands.spawn(Camera2d);
|
commands.spawn(Camera2d);
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::new("Press P to panic"),
|
Text::new("Press P to panic"),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -138,7 +138,7 @@ fn spawn_text(mut commands: Commands) {
|
||||||
"Space: swap meshes by mutating a Handle<Mesh>\n\
|
"Space: swap meshes by mutating a Handle<Mesh>\n\
|
||||||
Return: mutate the mesh itself, changing all copies of it",
|
Return: mutate the mesh itself, changing all copies of it",
|
||||||
),
|
),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.),
|
top: Val::Px(12.),
|
||||||
left: Val::Px(12.),
|
left: Val::Px(12.),
|
||||||
|
|
|
@ -96,7 +96,7 @@ fn spawn_text(mut commands: Commands) {
|
||||||
"Space: swap the right sprite's image handle\n\
|
"Space: swap the right sprite's image handle\n\
|
||||||
Return: modify the image Asset of the left sprite, affecting all uses of it",
|
Return: modify the image Asset of the left sprite, affecting all uses of it",
|
||||||
),
|
),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.),
|
top: Val::Px(12.),
|
||||||
left: Val::Px(12.),
|
left: Val::Px(12.),
|
||||||
|
|
|
@ -172,7 +172,7 @@ fn setup_ui(mut commands: Commands) {
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
LoadingText,
|
LoadingText,
|
||||||
Text::new("Loading...".to_owned()),
|
Text::new("Loading...".to_owned()),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
|
|
|
@ -66,7 +66,7 @@ fn setup(
|
||||||
// example instructions
|
// example instructions
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::new("Up/Down/Left/Right: Move Listener\nSpace: Toggle Emitter Movement"),
|
Text::new("Up/Down/Left/Right: Move Listener\nSpace: Toggle Emitter Movement"),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(12.0),
|
bottom: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -65,7 +65,7 @@ fn setup(
|
||||||
// example instructions
|
// example instructions
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::new("Up/Down/Left/Right: Move Listener\nSpace: Toggle Emitter Movement"),
|
Text::new("Up/Down/Left/Right: Move Listener\nSpace: Toggle Emitter Movement"),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(12.0),
|
bottom: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -65,7 +65,7 @@ fn setup_scene(
|
||||||
fn setup_instructions(mut commands: Commands) {
|
fn setup_instructions(mut commands: Commands) {
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::new("Hold space to trigger a screen shake"),
|
Text::new("Hold space to trigger a screen shake"),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(12.0),
|
bottom: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -51,7 +51,7 @@ fn setup_scene(
|
||||||
fn setup_instructions(mut commands: Commands) {
|
fn setup_instructions(mut commands: Commands) {
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::new("Move the light with WASD.\nThe camera will smoothly track the light."),
|
Text::new("Move the light with WASD.\nThe camera will smoothly track the light."),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(12.0),
|
bottom: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -87,7 +87,7 @@ fn instructions(mut commands: Commands) {
|
||||||
Mouse left or right: yaw\n\
|
Mouse left or right: yaw\n\
|
||||||
Mouse buttons: roll",
|
Mouse buttons: roll",
|
||||||
),
|
),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.),
|
top: Val::Px(12.),
|
||||||
left: Val::Px(12.),
|
left: Val::Px(12.),
|
||||||
|
|
|
@ -192,15 +192,12 @@ fn spawn_lights(mut commands: Commands) {
|
||||||
|
|
||||||
fn spawn_text(mut commands: Commands) {
|
fn spawn_text(mut commands: Commands) {
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn(Node {
|
||||||
Node::default(),
|
position_type: PositionType::Absolute,
|
||||||
Style {
|
bottom: Val::Px(12.0),
|
||||||
position_type: PositionType::Absolute,
|
left: Val::Px(12.0),
|
||||||
bottom: Val::Px(12.0),
|
..default()
|
||||||
left: Val::Px(12.0),
|
})
|
||||||
..default()
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.with_child(Text::new(concat!(
|
.with_child(Text::new(concat!(
|
||||||
"Move the camera with your mouse.\n",
|
"Move the camera with your mouse.\n",
|
||||||
"Press arrow up to decrease the FOV of the world model.\n",
|
"Press arrow up to decrease the FOV of the world model.\n",
|
||||||
|
|
|
@ -99,7 +99,7 @@ fn instructions(mut commands: Commands) {
|
||||||
"Scroll mouse wheel to zoom in/out\n\
|
"Scroll mouse wheel to zoom in/out\n\
|
||||||
Space: switch between orthographic and perspective projections",
|
Space: switch between orthographic and perspective projections",
|
||||||
),
|
),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.),
|
top: Val::Px(12.),
|
||||||
left: Val::Px(12.),
|
left: Val::Px(12.),
|
||||||
|
|
|
@ -51,7 +51,7 @@ fn setup(mut commands: Commands) {
|
||||||
"Press 3 to increase the overlay size.\n",
|
"Press 3 to increase the overlay size.\n",
|
||||||
"Press 4 to toggle the overlay visibility."
|
"Press 4 to toggle the overlay visibility."
|
||||||
)),
|
)),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(12.),
|
bottom: Val::Px(12.),
|
||||||
left: Val::Px(12.),
|
left: Val::Px(12.),
|
||||||
|
|
|
@ -76,7 +76,7 @@ fn setup(mut commands: Commands) {
|
||||||
"Click on a \"Mine\" to trigger it.\n\
|
"Click on a \"Mine\" to trigger it.\n\
|
||||||
When it explodes it will trigger all overlapping mines.",
|
When it explodes it will trigger all overlapping mines.",
|
||||||
),
|
),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.),
|
top: Val::Px(12.),
|
||||||
left: Val::Px(12.),
|
left: Val::Px(12.),
|
||||||
|
|
|
@ -95,7 +95,7 @@ fn setup_ui(mut commands: Commands) {
|
||||||
.spawn((
|
.spawn((
|
||||||
Text::default(),
|
Text::default(),
|
||||||
TextLayout::new_with_justify(JustifyText::Center),
|
TextLayout::new_with_justify(JustifyText::Center),
|
||||||
Style {
|
Node {
|
||||||
align_self: AlignSelf::Center,
|
align_self: AlignSelf::Center,
|
||||||
justify_self: JustifySelf::Center,
|
justify_self: JustifySelf::Center,
|
||||||
..default()
|
..default()
|
||||||
|
|
|
@ -182,7 +182,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>, mut game: ResMu
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
TextColor(Color::srgb(0.5, 0.5, 1.0)),
|
TextColor(Color::srgb(0.5, 0.5, 1.0)),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(5.0),
|
top: Val::Px(5.0),
|
||||||
left: Val::Px(5.0),
|
left: Val::Px(5.0),
|
||||||
|
@ -393,15 +393,12 @@ fn gameover_keyboard(
|
||||||
// display the number of cake eaten before losing
|
// display the number of cake eaten before losing
|
||||||
fn display_score(mut commands: Commands, game: Res<Game>) {
|
fn display_score(mut commands: Commands, game: Res<Game>) {
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn(Node {
|
||||||
Node::default(),
|
width: Val::Percent(100.),
|
||||||
Style {
|
align_items: AlignItems::Center,
|
||||||
width: Val::Percent(100.),
|
justify_content: JustifyContent::Center,
|
||||||
align_items: AlignItems::Center,
|
..default()
|
||||||
justify_content: JustifyContent::Center,
|
})
|
||||||
..default()
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.with_child((
|
.with_child((
|
||||||
Text::new(format!("Cake eaten: {}", game.cake_eaten)),
|
Text::new(format!("Cake eaten: {}", game.cake_eaten)),
|
||||||
TextFont {
|
TextFont {
|
||||||
|
|
|
@ -225,7 +225,7 @@ fn setup(
|
||||||
},
|
},
|
||||||
TextColor(TEXT_COLOR),
|
TextColor(TEXT_COLOR),
|
||||||
ScoreboardUi,
|
ScoreboardUi,
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: SCOREBOARD_TEXT_PADDING,
|
top: SCOREBOARD_TEXT_PADDING,
|
||||||
left: SCOREBOARD_TEXT_PADDING,
|
left: SCOREBOARD_TEXT_PADDING,
|
||||||
|
|
|
@ -148,7 +148,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
Text::new("Contributor showcase"),
|
Text::new("Contributor showcase"),
|
||||||
text_style.clone(),
|
text_style.clone(),
|
||||||
ContributorDisplay,
|
ContributorDisplay,
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.),
|
top: Val::Px(12.),
|
||||||
left: Val::Px(12.),
|
left: Val::Px(12.),
|
||||||
|
|
|
@ -75,8 +75,7 @@ mod splash {
|
||||||
// Display the logo
|
// Display the logo
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
align_items: AlignItems::Center,
|
align_items: AlignItems::Center,
|
||||||
justify_content: JustifyContent::Center,
|
justify_content: JustifyContent::Center,
|
||||||
width: Val::Percent(100.0),
|
width: Val::Percent(100.0),
|
||||||
|
@ -88,7 +87,7 @@ mod splash {
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
parent.spawn((
|
parent.spawn((
|
||||||
UiImage::new(icon),
|
UiImage::new(icon),
|
||||||
Style {
|
Node {
|
||||||
// This will set the logo to be 200px wide, and auto adjust its height
|
// This will set the logo to be 200px wide, and auto adjust its height
|
||||||
width: Val::Px(200.0),
|
width: Val::Px(200.0),
|
||||||
..default()
|
..default()
|
||||||
|
@ -141,8 +140,7 @@ mod game {
|
||||||
) {
|
) {
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
width: Val::Percent(100.0),
|
width: Val::Percent(100.0),
|
||||||
height: Val::Percent(100.0),
|
height: Val::Percent(100.0),
|
||||||
// center children
|
// center children
|
||||||
|
@ -153,11 +151,10 @@ mod game {
|
||||||
OnGameScreen,
|
OnGameScreen,
|
||||||
))
|
))
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
// First create a `Node` and `Style` for centering what we want to display
|
// First create a `Node` for centering what we want to display
|
||||||
parent
|
parent
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
// This will display its children in a column, from top to bottom
|
// This will display its children in a column, from top to bottom
|
||||||
flex_direction: FlexDirection::Column,
|
flex_direction: FlexDirection::Column,
|
||||||
// `align_items` will align children on the cross axis. Here the main axis is
|
// `align_items` will align children on the cross axis. Here the main axis is
|
||||||
|
@ -176,14 +173,14 @@ mod game {
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
TextColor(TEXT_COLOR),
|
TextColor(TEXT_COLOR),
|
||||||
Style {
|
Node {
|
||||||
margin: UiRect::all(Val::Px(50.0)),
|
margin: UiRect::all(Val::Px(50.0)),
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
p.spawn((
|
p.spawn((
|
||||||
Text::default(),
|
Text::default(),
|
||||||
Style {
|
Node {
|
||||||
margin: UiRect::all(Val::Px(50.0)),
|
margin: UiRect::all(Val::Px(50.0)),
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
|
@ -377,7 +374,7 @@ mod menu {
|
||||||
|
|
||||||
fn main_menu_setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
fn main_menu_setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
// Common style for all buttons on the screen
|
// Common style for all buttons on the screen
|
||||||
let button_style = Style {
|
let button_node = Node {
|
||||||
width: Val::Px(300.0),
|
width: Val::Px(300.0),
|
||||||
height: Val::Px(65.0),
|
height: Val::Px(65.0),
|
||||||
margin: UiRect::all(Val::Px(20.0)),
|
margin: UiRect::all(Val::Px(20.0)),
|
||||||
|
@ -385,7 +382,7 @@ mod menu {
|
||||||
align_items: AlignItems::Center,
|
align_items: AlignItems::Center,
|
||||||
..default()
|
..default()
|
||||||
};
|
};
|
||||||
let button_icon_style = Style {
|
let button_icon_node = Node {
|
||||||
width: Val::Px(30.0),
|
width: Val::Px(30.0),
|
||||||
// This takes the icons out of the flexbox flow, to be positioned exactly
|
// This takes the icons out of the flexbox flow, to be positioned exactly
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
|
@ -400,8 +397,7 @@ mod menu {
|
||||||
|
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
width: Val::Percent(100.0),
|
width: Val::Percent(100.0),
|
||||||
height: Val::Percent(100.0),
|
height: Val::Percent(100.0),
|
||||||
align_items: AlignItems::Center,
|
align_items: AlignItems::Center,
|
||||||
|
@ -413,8 +409,7 @@ mod menu {
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
parent
|
parent
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
flex_direction: FlexDirection::Column,
|
flex_direction: FlexDirection::Column,
|
||||||
align_items: AlignItems::Center,
|
align_items: AlignItems::Center,
|
||||||
..default()
|
..default()
|
||||||
|
@ -430,7 +425,7 @@ mod menu {
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
TextColor(TEXT_COLOR),
|
TextColor(TEXT_COLOR),
|
||||||
Style {
|
Node {
|
||||||
margin: UiRect::all(Val::Px(50.0)),
|
margin: UiRect::all(Val::Px(50.0)),
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
|
@ -443,13 +438,13 @@ mod menu {
|
||||||
parent
|
parent
|
||||||
.spawn((
|
.spawn((
|
||||||
Button,
|
Button,
|
||||||
button_style.clone(),
|
button_node.clone(),
|
||||||
BackgroundColor(NORMAL_BUTTON),
|
BackgroundColor(NORMAL_BUTTON),
|
||||||
MenuButtonAction::Play,
|
MenuButtonAction::Play,
|
||||||
))
|
))
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
let icon = asset_server.load("textures/Game Icons/right.png");
|
let icon = asset_server.load("textures/Game Icons/right.png");
|
||||||
parent.spawn((UiImage::new(icon), button_icon_style.clone()));
|
parent.spawn((UiImage::new(icon), button_icon_node.clone()));
|
||||||
parent.spawn((
|
parent.spawn((
|
||||||
Text::new("New Game"),
|
Text::new("New Game"),
|
||||||
button_text_font.clone(),
|
button_text_font.clone(),
|
||||||
|
@ -459,13 +454,13 @@ mod menu {
|
||||||
parent
|
parent
|
||||||
.spawn((
|
.spawn((
|
||||||
Button,
|
Button,
|
||||||
button_style.clone(),
|
button_node.clone(),
|
||||||
BackgroundColor(NORMAL_BUTTON),
|
BackgroundColor(NORMAL_BUTTON),
|
||||||
MenuButtonAction::Settings,
|
MenuButtonAction::Settings,
|
||||||
))
|
))
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
let icon = asset_server.load("textures/Game Icons/wrench.png");
|
let icon = asset_server.load("textures/Game Icons/wrench.png");
|
||||||
parent.spawn((UiImage::new(icon), button_icon_style.clone()));
|
parent.spawn((UiImage::new(icon), button_icon_node.clone()));
|
||||||
parent.spawn((
|
parent.spawn((
|
||||||
Text::new("Settings"),
|
Text::new("Settings"),
|
||||||
button_text_font.clone(),
|
button_text_font.clone(),
|
||||||
|
@ -475,13 +470,13 @@ mod menu {
|
||||||
parent
|
parent
|
||||||
.spawn((
|
.spawn((
|
||||||
Button,
|
Button,
|
||||||
button_style,
|
button_node,
|
||||||
BackgroundColor(NORMAL_BUTTON),
|
BackgroundColor(NORMAL_BUTTON),
|
||||||
MenuButtonAction::Quit,
|
MenuButtonAction::Quit,
|
||||||
))
|
))
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
let icon = asset_server.load("textures/Game Icons/exitRight.png");
|
let icon = asset_server.load("textures/Game Icons/exitRight.png");
|
||||||
parent.spawn((UiImage::new(icon), button_icon_style));
|
parent.spawn((UiImage::new(icon), button_icon_node));
|
||||||
parent.spawn((
|
parent.spawn((
|
||||||
Text::new("Quit"),
|
Text::new("Quit"),
|
||||||
button_text_font,
|
button_text_font,
|
||||||
|
@ -493,7 +488,7 @@ mod menu {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn settings_menu_setup(mut commands: Commands) {
|
fn settings_menu_setup(mut commands: Commands) {
|
||||||
let button_style = Style {
|
let button_node = Node {
|
||||||
width: Val::Px(200.0),
|
width: Val::Px(200.0),
|
||||||
height: Val::Px(65.0),
|
height: Val::Px(65.0),
|
||||||
margin: UiRect::all(Val::Px(20.0)),
|
margin: UiRect::all(Val::Px(20.0)),
|
||||||
|
@ -512,8 +507,7 @@ mod menu {
|
||||||
|
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
width: Val::Percent(100.0),
|
width: Val::Percent(100.0),
|
||||||
height: Val::Percent(100.0),
|
height: Val::Percent(100.0),
|
||||||
align_items: AlignItems::Center,
|
align_items: AlignItems::Center,
|
||||||
|
@ -525,8 +519,7 @@ mod menu {
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
parent
|
parent
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
flex_direction: FlexDirection::Column,
|
flex_direction: FlexDirection::Column,
|
||||||
align_items: AlignItems::Center,
|
align_items: AlignItems::Center,
|
||||||
..default()
|
..default()
|
||||||
|
@ -542,7 +535,7 @@ mod menu {
|
||||||
parent
|
parent
|
||||||
.spawn((
|
.spawn((
|
||||||
Button,
|
Button,
|
||||||
button_style.clone(),
|
button_node.clone(),
|
||||||
BackgroundColor(NORMAL_BUTTON),
|
BackgroundColor(NORMAL_BUTTON),
|
||||||
action,
|
action,
|
||||||
))
|
))
|
||||||
|
@ -555,7 +548,7 @@ mod menu {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn display_settings_menu_setup(mut commands: Commands, display_quality: Res<DisplayQuality>) {
|
fn display_settings_menu_setup(mut commands: Commands, display_quality: Res<DisplayQuality>) {
|
||||||
let button_style = Style {
|
let button_node = Node {
|
||||||
width: Val::Px(200.0),
|
width: Val::Px(200.0),
|
||||||
height: Val::Px(65.0),
|
height: Val::Px(65.0),
|
||||||
margin: UiRect::all(Val::Px(20.0)),
|
margin: UiRect::all(Val::Px(20.0)),
|
||||||
|
@ -573,8 +566,7 @@ mod menu {
|
||||||
|
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
width: Val::Percent(100.0),
|
width: Val::Percent(100.0),
|
||||||
height: Val::Percent(100.0),
|
height: Val::Percent(100.0),
|
||||||
align_items: AlignItems::Center,
|
align_items: AlignItems::Center,
|
||||||
|
@ -586,8 +578,7 @@ mod menu {
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
parent
|
parent
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
flex_direction: FlexDirection::Column,
|
flex_direction: FlexDirection::Column,
|
||||||
align_items: AlignItems::Center,
|
align_items: AlignItems::Center,
|
||||||
..default()
|
..default()
|
||||||
|
@ -595,12 +586,11 @@ mod menu {
|
||||||
BackgroundColor(CRIMSON.into()),
|
BackgroundColor(CRIMSON.into()),
|
||||||
))
|
))
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
// Create a new `Node` and `Style` , this time not setting its `flex_direction`. It will
|
// Create a new `Node`, this time not setting its `flex_direction`. It will
|
||||||
// use the default value, `FlexDirection::Row`, from left to right.
|
// use the default value, `FlexDirection::Row`, from left to right.
|
||||||
parent
|
parent
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
align_items: AlignItems::Center,
|
align_items: AlignItems::Center,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
|
@ -620,10 +610,10 @@ mod menu {
|
||||||
] {
|
] {
|
||||||
let mut entity = parent.spawn((
|
let mut entity = parent.spawn((
|
||||||
Button,
|
Button,
|
||||||
Style {
|
Node {
|
||||||
width: Val::Px(150.0),
|
width: Val::Px(150.0),
|
||||||
height: Val::Px(65.0),
|
height: Val::Px(65.0),
|
||||||
..button_style.clone()
|
..button_node.clone()
|
||||||
},
|
},
|
||||||
BackgroundColor(NORMAL_BUTTON),
|
BackgroundColor(NORMAL_BUTTON),
|
||||||
quality_setting,
|
quality_setting,
|
||||||
|
@ -643,7 +633,7 @@ mod menu {
|
||||||
parent
|
parent
|
||||||
.spawn((
|
.spawn((
|
||||||
Button,
|
Button,
|
||||||
button_style,
|
button_node,
|
||||||
BackgroundColor(NORMAL_BUTTON),
|
BackgroundColor(NORMAL_BUTTON),
|
||||||
MenuButtonAction::BackToSettings,
|
MenuButtonAction::BackToSettings,
|
||||||
))
|
))
|
||||||
|
@ -655,7 +645,7 @@ mod menu {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sound_settings_menu_setup(mut commands: Commands, volume: Res<Volume>) {
|
fn sound_settings_menu_setup(mut commands: Commands, volume: Res<Volume>) {
|
||||||
let button_style = Style {
|
let button_node = Node {
|
||||||
width: Val::Px(200.0),
|
width: Val::Px(200.0),
|
||||||
height: Val::Px(65.0),
|
height: Val::Px(65.0),
|
||||||
margin: UiRect::all(Val::Px(20.0)),
|
margin: UiRect::all(Val::Px(20.0)),
|
||||||
|
@ -673,8 +663,7 @@ mod menu {
|
||||||
|
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
width: Val::Percent(100.0),
|
width: Val::Percent(100.0),
|
||||||
height: Val::Percent(100.0),
|
height: Val::Percent(100.0),
|
||||||
align_items: AlignItems::Center,
|
align_items: AlignItems::Center,
|
||||||
|
@ -686,8 +675,7 @@ mod menu {
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
parent
|
parent
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
flex_direction: FlexDirection::Column,
|
flex_direction: FlexDirection::Column,
|
||||||
align_items: AlignItems::Center,
|
align_items: AlignItems::Center,
|
||||||
..default()
|
..default()
|
||||||
|
@ -697,8 +685,7 @@ mod menu {
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
parent
|
parent
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
align_items: AlignItems::Center,
|
align_items: AlignItems::Center,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
|
@ -709,10 +696,10 @@ mod menu {
|
||||||
for volume_setting in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] {
|
for volume_setting in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] {
|
||||||
let mut entity = parent.spawn((
|
let mut entity = parent.spawn((
|
||||||
Button,
|
Button,
|
||||||
Style {
|
Node {
|
||||||
width: Val::Px(30.0),
|
width: Val::Px(30.0),
|
||||||
height: Val::Px(65.0),
|
height: Val::Px(65.0),
|
||||||
..button_style.clone()
|
..button_node.clone()
|
||||||
},
|
},
|
||||||
BackgroundColor(NORMAL_BUTTON),
|
BackgroundColor(NORMAL_BUTTON),
|
||||||
Volume(volume_setting),
|
Volume(volume_setting),
|
||||||
|
@ -725,7 +712,7 @@ mod menu {
|
||||||
parent
|
parent
|
||||||
.spawn((
|
.spawn((
|
||||||
Button,
|
Button,
|
||||||
button_style,
|
button_node,
|
||||||
BackgroundColor(NORMAL_BUTTON),
|
BackgroundColor(NORMAL_BUTTON),
|
||||||
MenuButtonAction::BackToSettings,
|
MenuButtonAction::BackToSettings,
|
||||||
))
|
))
|
||||||
|
|
|
@ -83,13 +83,12 @@ fn setup(mut commands: Commands) {
|
||||||
};
|
};
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
BackgroundColor(Color::NONE),
|
|
||||||
Style {
|
|
||||||
justify_self: JustifySelf::Center,
|
justify_self: JustifySelf::Center,
|
||||||
align_self: AlignSelf::FlexEnd,
|
align_self: AlignSelf::FlexEnd,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
|
BackgroundColor(Color::NONE),
|
||||||
))
|
))
|
||||||
.with_child((Text::new("Press 1 or 2 to load a new scene."), text_style));
|
.with_child((Text::new("Press 1 or 2 to load a new scene."), text_style));
|
||||||
}
|
}
|
||||||
|
@ -257,15 +256,14 @@ fn load_loading_screen(mut commands: Commands) {
|
||||||
// Spawn the UI that will make up the loading screen.
|
// Spawn the UI that will make up the loading screen.
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Node::default(),
|
Node {
|
||||||
BackgroundColor(Color::BLACK),
|
|
||||||
Style {
|
|
||||||
height: Val::Percent(100.0),
|
height: Val::Percent(100.0),
|
||||||
width: Val::Percent(100.0),
|
width: Val::Percent(100.0),
|
||||||
justify_content: JustifyContent::Center,
|
justify_content: JustifyContent::Center,
|
||||||
align_items: AlignItems::Center,
|
align_items: AlignItems::Center,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
|
BackgroundColor(Color::BLACK),
|
||||||
LoadingScreen,
|
LoadingScreen,
|
||||||
))
|
))
|
||||||
.with_child((Text::new("Loading..."), text_style.clone()));
|
.with_child((Text::new("Loading..."), text_style.clone()));
|
||||||
|
|
|
@ -165,7 +165,7 @@ fn build_ui(
|
||||||
.spawn((
|
.spawn((
|
||||||
Text::default(),
|
Text::default(),
|
||||||
SteppingUi,
|
SteppingUi,
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: state.ui_top,
|
top: state.ui_top,
|
||||||
left: state.ui_left,
|
left: state.ui_left,
|
||||||
|
@ -197,7 +197,7 @@ fn build_stepping_hint(mut commands: Commands) {
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
TextColor(FONT_COLOR),
|
TextColor(FONT_COLOR),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(5.0),
|
bottom: Val::Px(5.0),
|
||||||
left: Val::Px(5.0),
|
left: Val::Px(5.0),
|
||||||
|
|
|
@ -28,7 +28,7 @@ fn setup(mut commands: Commands) {
|
||||||
Press 'U' / 'I' to cycle through line styles\n\
|
Press 'U' / 'I' to cycle through line styles\n\
|
||||||
Press 'J' / 'K' to cycle through line joins",
|
Press 'J' / 'K' to cycle through line joins",
|
||||||
),
|
),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.),
|
top: Val::Px(12.),
|
||||||
left: Val::Px(12.),
|
left: Val::Px(12.),
|
||||||
|
|
|
@ -62,7 +62,7 @@ fn setup(
|
||||||
Press 'U' or 'I' to cycle through line styles for straight or round gizmos\n\
|
Press 'U' or 'I' to cycle through line styles for straight or round gizmos\n\
|
||||||
Press 'J' or 'K' to cycle through line joins for straight or round gizmos",
|
Press 'J' or 'K' to cycle through line joins for straight or round gizmos",
|
||||||
),
|
),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -109,7 +109,7 @@ fn setup(
|
||||||
Press 'A' to toggle drawing of the light gizmos\n\
|
Press 'A' to toggle drawing of the light gizmos\n\
|
||||||
Press 'C' to cycle between the light gizmos coloring modes",
|
Press 'C' to cycle between the light gizmos coloring modes",
|
||||||
),
|
),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
@ -125,7 +125,7 @@ fn setup(
|
||||||
.spawn((
|
.spawn((
|
||||||
Text::new("Gizmo color mode: "),
|
Text::new("Gizmo color mode: "),
|
||||||
GizmoColorText,
|
GizmoColorText,
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
bottom: Val::Px(12.0),
|
bottom: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -22,11 +22,11 @@ pub struct RadioButton;
|
||||||
#[derive(Clone, Copy, Component)]
|
#[derive(Clone, Copy, Component)]
|
||||||
pub struct RadioButtonText;
|
pub struct RadioButtonText;
|
||||||
|
|
||||||
/// Returns a [`Style`] appropriate for the outer main UI node.
|
/// Returns a [`Node`] appropriate for the outer main UI node.
|
||||||
///
|
///
|
||||||
/// This UI is in the bottom left corner and has flex column support
|
/// This UI is in the bottom left corner and has flex column support
|
||||||
pub fn main_ui_style() -> Style {
|
pub fn main_ui_node() -> Node {
|
||||||
Style {
|
Node {
|
||||||
flex_direction: FlexDirection::Column,
|
flex_direction: FlexDirection::Column,
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
row_gap: Val::Px(6.0),
|
row_gap: Val::Px(6.0),
|
||||||
|
@ -60,7 +60,7 @@ pub fn spawn_option_button<T>(
|
||||||
parent
|
parent
|
||||||
.spawn((
|
.spawn((
|
||||||
Button,
|
Button,
|
||||||
Style {
|
Node {
|
||||||
border: UiRect::all(Val::Px(1.0)).with_left(if is_first {
|
border: UiRect::all(Val::Px(1.0)).with_left(if is_first {
|
||||||
Val::Px(1.0)
|
Val::Px(1.0)
|
||||||
} else {
|
} else {
|
||||||
|
@ -97,15 +97,12 @@ where
|
||||||
{
|
{
|
||||||
// Add the parent node for the row.
|
// Add the parent node for the row.
|
||||||
parent
|
parent
|
||||||
.spawn((
|
.spawn(Node {
|
||||||
Node::default(),
|
align_items: AlignItems::Center,
|
||||||
Style {
|
..default()
|
||||||
align_items: AlignItems::Center,
|
})
|
||||||
..default()
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
spawn_ui_text(parent, title, Color::BLACK).insert(Style {
|
spawn_ui_text(parent, title, Color::BLACK).insert(Node {
|
||||||
width: Val::Px(125.0),
|
width: Val::Px(125.0),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
|
@ -37,7 +37,7 @@ fn setup_scene(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Text::default(),
|
Text::default(),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -78,17 +78,14 @@ fn setup(mut commands: Commands) {
|
||||||
let style = TextFont::default();
|
let style = TextFont::default();
|
||||||
|
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn(Node {
|
||||||
Node::default(),
|
position_type: PositionType::Absolute,
|
||||||
Style {
|
top: Val::Px(12.0),
|
||||||
position_type: PositionType::Absolute,
|
left: Val::Px(12.0),
|
||||||
top: Val::Px(12.0),
|
flex_direction: FlexDirection::Column,
|
||||||
left: Val::Px(12.0),
|
row_gap: Val::Px(20.0),
|
||||||
flex_direction: FlexDirection::Column,
|
..default()
|
||||||
row_gap: Val::Px(20.0),
|
})
|
||||||
..default()
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
parent.spawn((Text::new(instructions_text), style.clone()));
|
parent.spawn((Text::new(instructions_text), style.clone()));
|
||||||
parent.spawn((SplineModeText, Text(spline_mode_text), style.clone()));
|
parent.spawn((SplineModeText, Text(spline_mode_text), style.clone()));
|
||||||
|
|
|
@ -157,14 +157,16 @@ fn setup(
|
||||||
));
|
));
|
||||||
|
|
||||||
// Example instructions
|
// Example instructions
|
||||||
commands.spawn((Text::new("Press 'B' to toggle between no bounding shapes, bounding boxes (AABBs) and bounding spheres / circles\n\
|
commands.spawn((
|
||||||
|
Text::new("Press 'B' to toggle between no bounding shapes, bounding boxes (AABBs) and bounding spheres / circles\n\
|
||||||
Press 'Space' to switch between 3D and 2D"),
|
Press 'Space' to switch between 3D and 2D"),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
..default()
|
..default()
|
||||||
}));
|
},
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rotate the 2D shapes.
|
// Rotate the 2D shapes.
|
||||||
|
|
|
@ -118,7 +118,7 @@ fn setup(
|
||||||
D: Add 100 random samples.\n\
|
D: Add 100 random samples.\n\
|
||||||
Rotate camera by holding left mouse and panning left/right.",
|
Rotate camera by holding left mouse and panning left/right.",
|
||||||
),
|
),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -370,8 +370,7 @@ fn setup_text(mut commands: Commands, cameras: Query<(Entity, &Camera)>) {
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
HeaderNode,
|
HeaderNode,
|
||||||
Node::default(),
|
Node {
|
||||||
Style {
|
|
||||||
justify_self: JustifySelf::Center,
|
justify_self: JustifySelf::Center,
|
||||||
top: Val::Px(5.0),
|
top: Val::Px(5.0),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
|
@ -388,7 +388,7 @@ fn setup(
|
||||||
Move camera by L/R arrow keys.\n\
|
Move camera by L/R arrow keys.\n\
|
||||||
Tab: Toggle this text",
|
Tab: Toggle this text",
|
||||||
),
|
),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -116,7 +116,7 @@ fn setup_scene(
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Button,
|
Button,
|
||||||
Style {
|
Node {
|
||||||
justify_content: JustifyContent::Center,
|
justify_content: JustifyContent::Center,
|
||||||
align_items: AlignItems::Center,
|
align_items: AlignItems::Center,
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
|
|
|
@ -145,15 +145,12 @@ fn spawn_player(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
/// Spawn a bit of UI text to explain how to move the player.
|
/// Spawn a bit of UI text to explain how to move the player.
|
||||||
fn spawn_text(mut commands: Commands) {
|
fn spawn_text(mut commands: Commands) {
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn(Node {
|
||||||
Node::default(),
|
position_type: PositionType::Absolute,
|
||||||
Style {
|
bottom: Val::Px(12.0),
|
||||||
position_type: PositionType::Absolute,
|
left: Val::Px(12.0),
|
||||||
bottom: Val::Px(12.0),
|
..default()
|
||||||
left: Val::Px(12.0),
|
})
|
||||||
..default()
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.with_child((
|
.with_child((
|
||||||
Text::new("Move the player with WASD"),
|
Text::new("Move the player with WASD"),
|
||||||
TextFont {
|
TextFont {
|
||||||
|
|
|
@ -149,7 +149,7 @@ fn setup(
|
||||||
// Instructions
|
// Instructions
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::new("Hover over the shapes to pick them"),
|
Text::new("Hover over the shapes to pick them"),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Px(12.0),
|
top: Val::Px(12.0),
|
||||||
left: Val::Px(12.0),
|
left: Val::Px(12.0),
|
||||||
|
|
|
@ -20,7 +20,7 @@ fn setup(
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Text::new("Click Me to get a box"),
|
Text::new("Click Me to get a box"),
|
||||||
Style {
|
Node {
|
||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
top: Val::Percent(12.0),
|
top: Val::Percent(12.0),
|
||||||
left: Val::Percent(12.0),
|
left: Val::Percent(12.0),
|
||||||
|
|
|
@ -152,7 +152,7 @@ fn infotext_system(mut commands: Commands) {
|
||||||
font_size: 42.0,
|
font_size: 42.0,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
Style {
|
Node {
|
||||||
align_self: AlignSelf::FlexEnd,
|
align_self: AlignSelf::FlexEnd,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue