Document Size and UiRect (#5381)
# Objective - Migrate changes from #3503. ## Solution - Document `Size` and `UiRect`. - I also removed the type alias from the `size_ops` test since it's unnecessary. ## Follow Up After this change is merged I'd follow up with removing the generics from `Size` and `UiRect` since `Val` should be extensible enough. This was also discussed and decided on in #3503. let me know if this is not needed or wanted anymore!
This commit is contained in:
parent
ee3368b201
commit
60c6934f32
@ -2,17 +2,179 @@ use bevy_math::Vec2;
|
||||
use bevy_reflect::Reflect;
|
||||
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
|
||||
|
||||
/// A rect, as defined by its "side" locations
|
||||
/// A type which is commonly used to define positions, margins, paddings and borders.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ## Position
|
||||
///
|
||||
/// A position is used to determine where to place a UI element.
|
||||
///
|
||||
/// ```
|
||||
/// # use bevy_ui::{UiRect, Val};
|
||||
/// # use bevy_utils::default;
|
||||
/// #
|
||||
/// let position = UiRect {
|
||||
/// left: Val::Px(100.0),
|
||||
/// top: Val::Px(50.0),
|
||||
/// ..default()
|
||||
/// };
|
||||
/// ```
|
||||
///
|
||||
/// If you define opposite sides of the position, the size of the UI element will automatically be calculated
|
||||
/// if not explicitly specified. This means that if you have a [`Size`] that uses [`Val::Undefined`](crate::Val::Undefined)
|
||||
/// as a width and height, the size would be determined by the window size and the values specified in the position.
|
||||
///
|
||||
/// ```
|
||||
/// # use bevy_ui::{UiRect, Val};
|
||||
/// #
|
||||
/// let position = UiRect {
|
||||
/// left: Val::Px(100.0),
|
||||
/// right: Val::Px(200.0),
|
||||
/// top: Val::Px(300.0),
|
||||
/// bottom: Val::Px(400.0),
|
||||
/// };
|
||||
/// ```
|
||||
///
|
||||
/// To determine the width of the UI element you have to take the width of the window and subtract it by the
|
||||
/// left and right values of the position. To determine the height of the UI element you have to take the height
|
||||
/// of the window and subtract it by the top and bottom values of the position. If we had a window with a width
|
||||
/// and height of 1000px, the UI element declared above would have a width of 700px and a height of 300px.
|
||||
///
|
||||
/// ```
|
||||
/// // Size of the window
|
||||
/// let window_width = 1000.0;
|
||||
/// let window_height = 1000.0;
|
||||
///
|
||||
/// // Values of the position
|
||||
/// let left = 100.0;
|
||||
/// let right = 200.0;
|
||||
/// let top = 300.0;
|
||||
/// let bottom = 400.0;
|
||||
///
|
||||
/// // Calculation to get the size of the UI element
|
||||
/// let ui_element_width = window_width - left - right;
|
||||
/// let ui_element_height = window_height - top - bottom;
|
||||
///
|
||||
/// assert_eq!(ui_element_width, 700.0);
|
||||
/// assert_eq!(ui_element_height, 300.0);
|
||||
/// ```
|
||||
///
|
||||
/// If you define a [`Size`] and also all four sides of the position, the top and left values of the position
|
||||
/// are used to determine where to place the UI element. The size will not be calculated using the bottom and
|
||||
/// 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_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.
|
||||
///
|
||||
/// ```
|
||||
/// # 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)]
|
||||
#[reflect(PartialEq)]
|
||||
pub struct UiRect<T: Reflect + PartialEq> {
|
||||
/// The value corresponding to the left side of the UI rect.
|
||||
pub left: T,
|
||||
/// The value corresponding to the right side of the UI rect.
|
||||
pub right: T,
|
||||
/// The value corresponding to the top side of the UI rect.
|
||||
pub top: T,
|
||||
/// The value corresponding to the bottom side of the UI rect.
|
||||
pub bottom: T,
|
||||
}
|
||||
|
||||
impl<T: Reflect + PartialEq> UiRect<T> {
|
||||
/// Creates a new [`UiRect`] from the values specified.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use bevy_ui::{UiRect, Val};
|
||||
/// #
|
||||
/// let ui_rect = UiRect::new(
|
||||
/// Val::Px(10.0),
|
||||
/// Val::Px(20.0),
|
||||
/// Val::Px(30.0),
|
||||
/// Val::Px(40.0),
|
||||
/// );
|
||||
///
|
||||
/// assert_eq!(ui_rect.left, Val::Px(10.0));
|
||||
/// assert_eq!(ui_rect.right, Val::Px(20.0));
|
||||
/// assert_eq!(ui_rect.top, Val::Px(30.0));
|
||||
/// assert_eq!(ui_rect.bottom, Val::Px(40.0));
|
||||
/// ```
|
||||
pub fn new(left: T, right: T, top: T, bottom: T) -> Self {
|
||||
UiRect {
|
||||
left,
|
||||
right,
|
||||
top,
|
||||
bottom,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new [`UiRect`] where all sides have the same value.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use bevy_ui::{UiRect, Val};
|
||||
/// #
|
||||
/// let ui_rect = UiRect::all(Val::Px(10.0));
|
||||
///
|
||||
/// assert_eq!(ui_rect.left, Val::Px(10.0));
|
||||
/// assert_eq!(ui_rect.right, Val::Px(10.0));
|
||||
/// assert_eq!(ui_rect.top, Val::Px(10.0));
|
||||
/// assert_eq!(ui_rect.bottom, Val::Px(10.0));
|
||||
/// ```
|
||||
pub fn all(value: T) -> Self
|
||||
where
|
||||
T: Clone,
|
||||
@ -37,15 +199,31 @@ impl<T: Default + Reflect + PartialEq> Default for UiRect<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A two dimensional "size" as defined by a width and height
|
||||
/// 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)]
|
||||
#[reflect(PartialEq)]
|
||||
pub struct Size<T: Reflect + PartialEq = f32> {
|
||||
/// The width of the 2-dimensional area.
|
||||
pub width: T,
|
||||
/// The height of the 2-dimensional area.
|
||||
pub height: T,
|
||||
}
|
||||
|
||||
impl<T: Reflect + PartialEq> Size<T> {
|
||||
/// Creates a new [`Size`] from a width and a height.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use bevy_ui::{Size, Val};
|
||||
/// #
|
||||
/// let size = Size::new(Val::Px(100.0), Val::Px(200.0));
|
||||
///
|
||||
/// assert_eq!(size.width, Val::Px(100.0));
|
||||
/// assert_eq!(size.height, Val::Px(200.0));
|
||||
/// ```
|
||||
pub fn new(width: T, height: T) -> Self {
|
||||
Size { width, height }
|
||||
}
|
||||
@ -162,23 +340,21 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn size_ops() {
|
||||
type SizeF = Size<f32>;
|
||||
|
||||
assert_eq!(
|
||||
SizeF::new(10., 10.) + Vec2::new(10., 10.),
|
||||
SizeF::new(20., 20.)
|
||||
Size::new(10., 10.) + Vec2::new(10., 10.),
|
||||
Size::new(20., 20.)
|
||||
);
|
||||
assert_eq!(
|
||||
SizeF::new(20., 20.) - Vec2::new(10., 10.),
|
||||
SizeF::new(10., 10.)
|
||||
Size::new(20., 20.) - Vec2::new(10., 10.),
|
||||
Size::new(10., 10.)
|
||||
);
|
||||
assert_eq!(SizeF::new(10., 10.) * 2., SizeF::new(20., 20.));
|
||||
assert_eq!(SizeF::new(20., 20.) / 2., SizeF::new(10., 10.));
|
||||
assert_eq!(Size::new(10., 10.) * 2., Size::new(20., 20.));
|
||||
assert_eq!(Size::new(20., 20.) / 2., Size::new(10., 10.));
|
||||
|
||||
let mut size = SizeF::new(10., 10.);
|
||||
let mut size = Size::new(10., 10.);
|
||||
|
||||
size += Vec2::new(10., 10.);
|
||||
|
||||
assert_eq!(size, SizeF::new(20., 20.));
|
||||
assert_eq!(size, Size::new(20., 20.));
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user