Skip to content

Commit

Permalink
Fracture style into multiple components
Browse files Browse the repository at this point in the history
  • Loading branch information
Weibye committed Jan 19, 2023
1 parent 519f6f4 commit fbb7c67
Show file tree
Hide file tree
Showing 34 changed files with 1,652 additions and 1,247 deletions.
83 changes: 45 additions & 38 deletions crates/bevy_ui/src/flex/convert.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
use crate::{
AlignContent, AlignItems, AlignSelf, Display, FlexDirection, FlexWrap, JustifyContent,
PositionType, Size, Style, UiRect, Val,
layout_components::{
flex::{
AlignContent, AlignItems, AlignSelf, Direction, FlexLayoutQueryItem, JustifyContent,
Wrap,
},
Position,
},
Display,
};
use crate::{Size, UiRect, Val};

pub fn from_rect(
scale_factor: f64,
Expand Down Expand Up @@ -32,28 +39,28 @@ pub fn from_val_size(
}
}

pub fn from_style(scale_factor: f64, value: &Style) -> taffy::style::Style {
pub fn from_flex_layout(scale_factor: f64, value: FlexLayoutQueryItem<'_>) -> taffy::style::Style {
taffy::style::Style {
display: value.display.into(),
position_type: value.position_type.into(),
flex_direction: value.flex_direction.into(),
flex_wrap: value.flex_wrap.into(),
align_items: value.align_items.into(),
align_self: value.align_self.into(),
align_content: value.align_content.into(),
justify_content: value.justify_content.into(),
position: from_rect(scale_factor, value.position),
margin: from_rect(scale_factor, value.margin),
padding: from_rect(scale_factor, value.padding),
border: from_rect(scale_factor, value.border),
flex_grow: value.flex_grow,
flex_shrink: value.flex_shrink,
flex_basis: from_val(scale_factor, value.flex_basis),
size: from_val_size(scale_factor, value.size),
min_size: from_val_size(scale_factor, value.min_size),
max_size: from_val_size(scale_factor, value.max_size),
aspect_ratio: value.aspect_ratio,
gap: from_val_size(scale_factor, value.gap),
display: (value.control.display).into(),
position_type: (value.control.position).into(),
flex_direction: value.layout.direction.into(),
flex_wrap: value.layout.wrap.into(),
align_items: value.layout.align_items.into(),
align_self: value.child_layout.align_self.into(),
align_content: value.layout.align_content.into(),
justify_content: value.layout.justify_content.into(),
position: from_rect(scale_factor, value.control.inset.0),
margin: from_rect(scale_factor, value.spacing.margin),
padding: from_rect(scale_factor, value.spacing.padding),
border: from_rect(scale_factor, value.spacing.border),
flex_grow: value.child_layout.grow,
flex_shrink: value.child_layout.shrink,
flex_basis: from_val(scale_factor, value.child_layout.basis),
size: from_val_size(scale_factor, value.size_constraints.suggested),
min_size: from_val_size(scale_factor, value.size_constraints.min),
max_size: from_val_size(scale_factor, value.size_constraints.max),
aspect_ratio: value.size_constraints.aspect_ratio,
gap: from_val_size(scale_factor, value.layout.gap),
}
}

Expand Down Expand Up @@ -122,13 +129,13 @@ impl From<Display> for taffy::style::Display {
}
}

impl From<FlexDirection> for taffy::style::FlexDirection {
fn from(value: FlexDirection) -> Self {
impl From<Direction> for taffy::style::FlexDirection {
fn from(value: Direction) -> Self {
match value {
FlexDirection::Row => taffy::style::FlexDirection::Row,
FlexDirection::Column => taffy::style::FlexDirection::Column,
FlexDirection::RowReverse => taffy::style::FlexDirection::RowReverse,
FlexDirection::ColumnReverse => taffy::style::FlexDirection::ColumnReverse,
Direction::Row => taffy::style::FlexDirection::Row,
Direction::Column => taffy::style::FlexDirection::Column,
Direction::RowReverse => taffy::style::FlexDirection::RowReverse,
Direction::ColumnReverse => taffy::style::FlexDirection::ColumnReverse,
}
}
}
Expand All @@ -146,21 +153,21 @@ impl From<JustifyContent> for taffy::style::JustifyContent {
}
}

impl From<PositionType> for taffy::style::PositionType {
fn from(value: PositionType) -> Self {
impl From<Position> for taffy::style::PositionType {
fn from(value: Position) -> Self {
match value {
PositionType::Relative => taffy::style::PositionType::Relative,
PositionType::Absolute => taffy::style::PositionType::Absolute,
Position::Relative => taffy::style::PositionType::Relative,
Position::Absolute => taffy::style::PositionType::Absolute,
}
}
}

impl From<FlexWrap> for taffy::style::FlexWrap {
fn from(value: FlexWrap) -> Self {
impl From<Wrap> for taffy::style::FlexWrap {
fn from(value: Wrap) -> Self {
match value {
FlexWrap::NoWrap => taffy::style::FlexWrap::NoWrap,
FlexWrap::Wrap => taffy::style::FlexWrap::Wrap,
FlexWrap::WrapReverse => taffy::style::FlexWrap::WrapReverse,
Wrap::NoWrap => taffy::style::FlexWrap::NoWrap,
Wrap::Wrap => taffy::style::FlexWrap::Wrap,
Wrap::WrapReverse => taffy::style::FlexWrap::WrapReverse,
}
}
}
41 changes: 27 additions & 14 deletions crates/bevy_ui/src/flex/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
mod convert;

use crate::{CalculatedSize, Node, Style, UiScale};
use crate::{
layout_components::flex::{FlexLayoutChanged, FlexLayoutQuery, FlexLayoutQueryItem},
CalculatedSize, Node, UiScale,
};
use bevy_ecs::{
change_detection::DetectChanges,
entity::Entity,
Expand Down Expand Up @@ -60,10 +63,17 @@ impl Default for FlexSurface {
}

impl FlexSurface {
pub fn upsert_node(&mut self, entity: Entity, style: &Style, scale_factor: f64) {
/// Inserts the node into the hashmap if they don't already exist,
/// or update the contents if they already to exist.
pub fn upsert_node(
&mut self,
entity: Entity,
layout: FlexLayoutQueryItem<'_>,
scale_factor: f64,
) {
let mut added = false;
let taffy = &mut self.taffy;
let taffy_style = convert::from_style(scale_factor, style);
let taffy_style = convert::from_flex_layout(scale_factor, layout);
let taffy_node = self.entity_to_taffy.entry(entity).or_insert_with(|| {
added = true;
taffy.new_leaf(taffy_style).unwrap()
Expand All @@ -77,12 +87,12 @@ impl FlexSurface {
pub fn upsert_leaf(
&mut self,
entity: Entity,
style: &Style,
layout: FlexLayoutQueryItem<'_>,
calculated_size: CalculatedSize,
scale_factor: f64,
) {
let taffy = &mut self.taffy;
let taffy_style = convert::from_style(scale_factor, style);
let taffy_style = convert::from_flex_layout(scale_factor, layout);
let measure = taffy::node::MeasureFunc::Boxed(Box::new(
move |constraints: Size<Option<f32>>, _available: Size<AvailableSpace>| {
let mut size = convert::from_f32_size(scale_factor, calculated_size.size);
Expand Down Expand Up @@ -227,10 +237,13 @@ pub fn flex_node_system(
mut scale_factor_events: EventReader<WindowScaleFactorChanged>,
mut flex_surface: ResMut<FlexSurface>,
root_node_query: Query<Entity, (With<Node>, Without<Parent>)>,
node_query: Query<(Entity, &Style, Option<&CalculatedSize>), (With<Node>, Changed<Style>)>,
full_node_query: Query<(Entity, &Style, Option<&CalculatedSize>), With<Node>>,
node_query: Query<
(Entity, FlexLayoutQuery, Option<&CalculatedSize>),
(With<Node>, FlexLayoutChanged),
>,
full_node_query: Query<(Entity, FlexLayoutQuery, Option<&CalculatedSize>), With<Node>>,
changed_size_query: Query<
(Entity, &Style, &CalculatedSize),
(Entity, FlexLayoutQuery, &CalculatedSize),
(With<Node>, Changed<CalculatedSize>),
>,
children_query: Query<(Entity, &Children), (With<Node>, Changed<Children>)>,
Expand All @@ -257,15 +270,15 @@ pub fn flex_node_system(
fn update_changed<F: ReadOnlyWorldQuery>(
flex_surface: &mut FlexSurface,
scaling_factor: f64,
query: Query<(Entity, &Style, Option<&CalculatedSize>), F>,
query: Query<(Entity, FlexLayoutQuery, Option<&CalculatedSize>), F>,
) {
// update changed nodes
for (entity, style, calculated_size) in &query {
for (entity, layout, calculated_size) in &query {
// TODO: remove node from old hierarchy if its root has changed
if let Some(calculated_size) = calculated_size {
flex_surface.upsert_leaf(entity, style, *calculated_size, scaling_factor);
flex_surface.upsert_leaf(entity, layout, *calculated_size, scaling_factor);
} else {
flex_surface.upsert_node(entity, style, scaling_factor);
flex_surface.upsert_node(entity, layout, scaling_factor);
}
}
}
Expand All @@ -276,8 +289,8 @@ pub fn flex_node_system(
update_changed(&mut flex_surface, scale_factor, node_query);
}

for (entity, style, calculated_size) in &changed_size_query {
flex_surface.upsert_leaf(entity, style, *calculated_size, scale_factor);
for (entity, layout, calculated_size) in &changed_size_query {
flex_surface.upsert_leaf(entity, layout, *calculated_size, scale_factor);
}

// clean up removed nodes
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ui/src/focus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use smallvec::SmallVec;
/// This ensures that hidden UI nodes are not interactable,
/// and do not end up stuck in an active state if hidden at the wrong time.
///
/// Note that you can also control the visibility of a node using the [`Display`](crate::ui_node::Display) property,
/// Note that you can also control the visibility of a node using the [`Display`](crate::layout_components::Display) property,
/// which fully collapses it during layout calculations.
#[derive(Component, Copy, Clone, Eq, PartialEq, Debug, Reflect, Serialize, Deserialize)]
#[reflect(Component, Serialize, Deserialize, PartialEq)]
Expand Down
115 changes: 47 additions & 68 deletions crates/bevy_ui/src/geometry.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::Val;
use bevy_reflect::Reflect;
use serde::{Deserialize, Serialize};
use std::ops::{Div, DivAssign, Mul, MulAssign};

/// A type which is commonly used to define positions, margins, paddings and borders.
/// A type which is commonly used throughout UI and layouting, commonly used to define inset, margins, paddings and borders.
///
/// # Examples
///
Expand Down Expand Up @@ -65,61 +66,17 @@ use std::ops::{Div, DivAssign, Mul, MulAssign};
/// right values of the position because the size of the UI element is already explicitly specified.
///
/// ```
/// # use bevy_ui::{UiRect, Size, Val, Style};
/// # use bevy_ui::{UiRect, Size, Val, SizeConstraints, Inset};
/// # use bevy_utils::default;
/// #
/// let style = Style {
/// position: UiRect { // Defining all four sides
/// left: Val::Px(100.0),
/// right: Val::Px(200.0),
/// top: Val::Px(300.0),
/// bottom: Val::Px(400.0),
/// },
/// size: Size::new(Val::Percent(100.0), Val::Percent(50.0)), // but also explicitly specifying a size
/// ..default()
/// };
/// ```
///
/// ## Margin
///
/// A margin is used to create space around UI elements, outside of any defined borders.
///
/// ```
/// # use bevy_ui::{UiRect, Val};
/// #
/// let margin = UiRect::all(Val::Auto); // Centers the UI element
/// ```
///
/// ## Padding
///
/// A padding is used to create space around UI elements, inside of any defined borders.
///
/// ```
/// # use bevy_ui::{UiRect, Val};
/// #
/// let padding = UiRect {
/// left: Val::Px(10.0),
/// right: Val::Px(20.0),
/// top: Val::Px(30.0),
/// bottom: Val::Px(40.0),
/// };
/// ```
///
/// ## Borders
///
/// A border is used to define the width of the border of a UI element.
/// let inset = Inset(UiRect {
/// left: Val::Px(100.0),
/// right: Val::Px(200.0),
/// top: Val::Px(300.0),
/// bottom: Val::Px(400.0),
/// });
///
/// ```
/// # use bevy_ui::{UiRect, Val};
/// #
/// let border = UiRect {
/// left: Val::Px(10.0),
/// right: Val::Px(20.0),
/// top: Val::Px(30.0),
/// bottom: Val::Px(40.0),
/// };
/// ```
#[derive(Copy, Clone, PartialEq, Debug, Reflect)]
#[derive(Copy, Clone, PartialEq, Debug, Reflect, Serialize, Deserialize)]
#[reflect(PartialEq)]
pub struct UiRect {
/// The value corresponding to the left side of the UI rect.
Expand All @@ -133,13 +90,6 @@ pub struct UiRect {
}

impl UiRect {
pub const DEFAULT: Self = Self {
left: Val::DEFAULT,
right: Val::DEFAULT,
top: Val::DEFAULT,
bottom: Val::DEFAULT,
};

/// Creates a new [`UiRect`] from the values specified.
///
/// # Example
Expand Down Expand Up @@ -318,6 +268,15 @@ impl UiRect {
..Default::default()
}
}

/// Alias of [`UiRect::UNDEFINED`]
pub const DEFAULT: UiRect = UiRect::UNDEFINED;

/// Creates a [`UiRect`] where all sides are [`Val::Undefined`]
pub const UNDEFINED: UiRect = UiRect::all(Val::Undefined);

/// Creates a [`UiRect`] where all sides are [`Val::Auto`]
pub const AUTO: UiRect = UiRect::all(Val::Auto);
}

impl Default for UiRect {
Expand All @@ -329,7 +288,7 @@ impl Default for UiRect {
/// A 2-dimensional area defined by a width and height.
///
/// It is commonly used to define the size of a text or UI element.
#[derive(Copy, Clone, PartialEq, Debug, Reflect)]
#[derive(Copy, Clone, PartialEq, Debug, Reflect, Serialize, Deserialize)]
#[reflect(PartialEq)]
pub struct Size {
/// The width of the 2-dimensional area.
Expand All @@ -339,11 +298,6 @@ pub struct Size {
}

impl Size {
pub const DEFAULT: Self = Self {
width: Val::DEFAULT,
height: Val::DEFAULT,
};

/// Creates a new [`Size`] from a width and a height.
///
/// # Example
Expand All @@ -360,17 +314,42 @@ impl Size {
Size { width, height }
}

/// Creates a Size where both values are [`Val::Auto`].
/// Creates a new [`Size`] where both values are given in [`Val::Px`].
pub const fn px(width: f32, height: f32) -> Self {
Size {
width: Val::Px(width),
height: Val::Px(height),
}
}

/// Creates a new [`Size`] where both values are given in [`Val::Percent`].
pub const fn percent(width: f32, height: f32) -> Self {
Size {
width: Val::Percent(width),
height: Val::Percent(height),
}
}

/// Alias of [`Size::UNDEFINED`]
pub const DEFAULT: Size = Size::UNDEFINED;

/// Creates a new [`Size`] where both values are [`Val::Auto`].
pub const AUTO: Size = Size {
width: Val::Auto,
height: Val::Auto,
};

/// Creates a Size where both values are [`Val::Undefined`].
/// Creates a new [`Size`] where both values are [`Val::Undefined`].
pub const UNDEFINED: Size = Size {
width: Val::Undefined,
height: Val::Undefined,
};

/// Creates a new [`Size`] where both values are 100 percent.
pub const FULL: Size = Size {
width: Val::FULL,
height: Val::FULL,
};
}

impl Default for Size {
Expand Down
Loading

0 comments on commit fbb7c67

Please sign in to comment.