 0dfb6cf89b
			
		
	
	
		0dfb6cf89b
		
			
		
	
	
	
	
		
			
			# Objective - Revert #10296 ## Solution - Avoid implementing `Display` without a justification - `Display` implementation is a guarantee without a direct use, takes additional time to compile and require work to maintain - `Debug`, `Reflect` or `Serialize` should cover all needs
		
			
				
	
	
		
			660 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			660 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| use bevy_math::Vec2;
 | |
| use bevy_reflect::Reflect;
 | |
| use bevy_reflect::ReflectDeserialize;
 | |
| use bevy_reflect::ReflectSerialize;
 | |
| use serde::Deserialize;
 | |
| use serde::Serialize;
 | |
| use std::ops::Neg;
 | |
| use std::ops::{Div, DivAssign, Mul, MulAssign};
 | |
| use thiserror::Error;
 | |
| 
 | |
| /// Represents the possible value types for layout properties.
 | |
| ///
 | |
| /// This enum allows specifying values for various [`Style`](crate::Style) properties in different units,
 | |
| /// such as logical pixels, percentages, or automatically determined values.
 | |
| #[derive(Copy, Clone, Debug, Serialize, Deserialize, Reflect)]
 | |
| #[reflect(PartialEq, Serialize, Deserialize)]
 | |
| pub enum Val {
 | |
|     /// Automatically determine the value based on the context and other [`Style`](crate::Style) properties.
 | |
|     Auto,
 | |
|     /// Set this value in logical pixels.
 | |
|     Px(f32),
 | |
|     /// Set the value as a percentage of its parent node's length along a specific axis.
 | |
|     ///
 | |
|     /// If the UI node has no parent, the percentage is calculated based on the window's length
 | |
|     /// along the corresponding axis.
 | |
|     ///
 | |
|     /// The chosen axis depends on the [`Style`](crate::Style) field set:
 | |
|     /// * 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`:
 | |
|     ///   - `width` is relative to the parent's width.
 | |
|     ///   - `height` is relative to the parent's height.
 | |
|     /// * For `margin`, `padding`, and `border` values: the percentage is relative to the parent node's width.
 | |
|     /// * For positions, `left` and `right` are relative to the parent's width, while `bottom` and `top` are relative to the parent's height.
 | |
|     Percent(f32),
 | |
|     /// Set this value in percent of the viewport width
 | |
|     Vw(f32),
 | |
|     /// Set this value in percent of the viewport height
 | |
|     Vh(f32),
 | |
|     /// Set this value in percent of the viewport's smaller dimension.
 | |
|     VMin(f32),
 | |
|     /// Set this value in percent of the viewport's larger dimension.
 | |
|     VMax(f32),
 | |
| }
 | |
| 
 | |
| impl PartialEq for Val {
 | |
|     fn eq(&self, other: &Self) -> bool {
 | |
|         let same_unit = matches!(
 | |
|             (self, other),
 | |
|             (Self::Auto, Self::Auto)
 | |
|                 | (Self::Px(_), Self::Px(_))
 | |
|                 | (Self::Percent(_), Self::Percent(_))
 | |
|                 | (Self::Vw(_), Self::Vw(_))
 | |
|                 | (Self::Vh(_), Self::Vh(_))
 | |
|                 | (Self::VMin(_), Self::VMin(_))
 | |
|                 | (Self::VMax(_), Self::VMax(_))
 | |
|         );
 | |
| 
 | |
|         let left = match self {
 | |
|             Self::Auto => None,
 | |
|             Self::Px(v)
 | |
|             | Self::Percent(v)
 | |
|             | Self::Vw(v)
 | |
|             | Self::Vh(v)
 | |
|             | Self::VMin(v)
 | |
|             | Self::VMax(v) => Some(v),
 | |
|         };
 | |
| 
 | |
|         let right = match other {
 | |
|             Self::Auto => None,
 | |
|             Self::Px(v)
 | |
|             | Self::Percent(v)
 | |
|             | Self::Vw(v)
 | |
|             | Self::Vh(v)
 | |
|             | Self::VMin(v)
 | |
|             | Self::VMax(v) => Some(v),
 | |
|         };
 | |
| 
 | |
|         match (same_unit, left, right) {
 | |
|             (true, a, b) => a == b,
 | |
|             // All zero-value variants are considered equal.
 | |
|             (false, Some(&a), Some(&b)) => a == 0. && b == 0.,
 | |
|             _ => false,
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl Val {
 | |
|     pub const DEFAULT: Self = Self::Auto;
 | |
|     pub const ZERO: Self = Self::Px(0.0);
 | |
| }
 | |
| 
 | |
| impl Default for Val {
 | |
|     fn default() -> Self {
 | |
|         Self::DEFAULT
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl Mul<f32> for Val {
 | |
|     type Output = Val;
 | |
| 
 | |
|     fn mul(self, rhs: f32) -> Self::Output {
 | |
|         match self {
 | |
|             Val::Auto => Val::Auto,
 | |
|             Val::Px(value) => Val::Px(value * rhs),
 | |
|             Val::Percent(value) => Val::Percent(value * rhs),
 | |
|             Val::Vw(value) => Val::Vw(value * rhs),
 | |
|             Val::Vh(value) => Val::Vh(value * rhs),
 | |
|             Val::VMin(value) => Val::VMin(value * rhs),
 | |
|             Val::VMax(value) => Val::VMax(value * rhs),
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl MulAssign<f32> for Val {
 | |
|     fn mul_assign(&mut self, rhs: f32) {
 | |
|         match self {
 | |
|             Val::Auto => {}
 | |
|             Val::Px(value)
 | |
|             | Val::Percent(value)
 | |
|             | Val::Vw(value)
 | |
|             | Val::Vh(value)
 | |
|             | Val::VMin(value)
 | |
|             | Val::VMax(value) => *value *= rhs,
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl Div<f32> for Val {
 | |
|     type Output = Val;
 | |
| 
 | |
|     fn div(self, rhs: f32) -> Self::Output {
 | |
|         match self {
 | |
|             Val::Auto => Val::Auto,
 | |
|             Val::Px(value) => Val::Px(value / rhs),
 | |
|             Val::Percent(value) => Val::Percent(value / rhs),
 | |
|             Val::Vw(value) => Val::Vw(value / rhs),
 | |
|             Val::Vh(value) => Val::Vh(value / rhs),
 | |
|             Val::VMin(value) => Val::VMin(value / rhs),
 | |
|             Val::VMax(value) => Val::VMax(value / rhs),
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl DivAssign<f32> for Val {
 | |
|     fn div_assign(&mut self, rhs: f32) {
 | |
|         match self {
 | |
|             Val::Auto => {}
 | |
|             Val::Px(value)
 | |
|             | Val::Percent(value)
 | |
|             | Val::Vw(value)
 | |
|             | Val::Vh(value)
 | |
|             | Val::VMin(value)
 | |
|             | Val::VMax(value) => *value /= rhs,
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl Neg for Val {
 | |
|     type Output = Val;
 | |
| 
 | |
|     fn neg(self) -> Self::Output {
 | |
|         match self {
 | |
|             Val::Px(value) => Val::Px(-value),
 | |
|             Val::Percent(value) => Val::Percent(-value),
 | |
|             Val::Vw(value) => Val::Vw(-value),
 | |
|             Val::Vh(value) => Val::Vh(-value),
 | |
|             Val::VMin(value) => Val::VMin(-value),
 | |
|             Val::VMax(value) => Val::VMax(-value),
 | |
|             _ => self,
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| #[derive(Debug, Eq, PartialEq, Clone, Copy, Error)]
 | |
| pub enum ValArithmeticError {
 | |
|     #[error("the variants of the Vals don't match")]
 | |
|     NonIdenticalVariants,
 | |
|     #[error("the given variant of Val is not evaluateable (non-numeric)")]
 | |
|     NonEvaluateable,
 | |
| }
 | |
| 
 | |
| impl Val {
 | |
|     /// Resolves a [`Val`] to its value in logical pixels and returns this as an [`f32`].
 | |
|     /// Returns a [`ValArithmeticError::NonEvaluateable`] if the [`Val`] is impossible to resolve into a concrete value.
 | |
|     ///
 | |
|     /// **Note:** If a [`Val::Px`] is resolved, it's inner value is returned unchanged.
 | |
|     pub fn resolve(self, parent_size: f32, viewport_size: Vec2) -> Result<f32, ValArithmeticError> {
 | |
|         match self {
 | |
|             Val::Percent(value) => Ok(parent_size * value / 100.0),
 | |
|             Val::Px(value) => Ok(value),
 | |
|             Val::Vw(value) => Ok(viewport_size.x * value / 100.0),
 | |
|             Val::Vh(value) => Ok(viewport_size.y * value / 100.0),
 | |
|             Val::VMin(value) => Ok(viewport_size.min_element() * value / 100.0),
 | |
|             Val::VMax(value) => Ok(viewport_size.max_element() * value / 100.0),
 | |
|             Val::Auto => Err(ValArithmeticError::NonEvaluateable),
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| /// A type which is commonly used to define margins, paddings and borders.
 | |
| ///
 | |
| /// # Examples
 | |
| 
 | |
| ///
 | |
| /// ## 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, Serialize, Deserialize, Reflect)]
 | |
| #[reflect(PartialEq, Serialize, Deserialize)]
 | |
| pub struct UiRect {
 | |
|     /// The value corresponding to the left side of the UI rect.
 | |
|     pub left: Val,
 | |
|     /// The value corresponding to the right side of the UI rect.
 | |
|     pub right: Val,
 | |
|     /// The value corresponding to the top side of the UI rect.
 | |
|     pub top: Val,
 | |
|     /// The value corresponding to the bottom side of the UI rect.
 | |
|     pub bottom: Val,
 | |
| }
 | |
| 
 | |
| impl UiRect {
 | |
|     pub const DEFAULT: Self = Self {
 | |
|         left: Val::ZERO,
 | |
|         right: Val::ZERO,
 | |
|         top: Val::ZERO,
 | |
|         bottom: Val::ZERO,
 | |
|     };
 | |
| 
 | |
|     pub const ZERO: Self = Self {
 | |
|         left: Val::ZERO,
 | |
|         right: Val::ZERO,
 | |
|         top: Val::ZERO,
 | |
|         bottom: Val::ZERO,
 | |
|     };
 | |
| 
 | |
|     /// 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 const fn new(left: Val, right: Val, top: Val, bottom: Val) -> 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 const fn all(value: Val) -> Self {
 | |
|         UiRect {
 | |
|             left: value,
 | |
|             right: value,
 | |
|             top: value,
 | |
|             bottom: value,
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /// Creates a new [`UiRect`] from the values specified in logical pixels.
 | |
|     ///
 | |
|     /// This is a shortcut for [`UiRect::new()`], applying [`Val::Px`] to all arguments.
 | |
|     ///
 | |
|     /// # Example
 | |
|     ///
 | |
|     /// ```
 | |
|     /// # use bevy_ui::{UiRect, Val};
 | |
|     /// #
 | |
|     /// let ui_rect = UiRect::px(10., 20., 30., 40.);
 | |
|     /// assert_eq!(ui_rect.left, Val::Px(10.));
 | |
|     /// assert_eq!(ui_rect.right, Val::Px(20.));
 | |
|     /// assert_eq!(ui_rect.top, Val::Px(30.));
 | |
|     /// assert_eq!(ui_rect.bottom, Val::Px(40.));
 | |
|     /// ```
 | |
|     pub const fn px(left: f32, right: f32, top: f32, bottom: f32) -> Self {
 | |
|         UiRect {
 | |
|             left: Val::Px(left),
 | |
|             right: Val::Px(right),
 | |
|             top: Val::Px(top),
 | |
|             bottom: Val::Px(bottom),
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /// Creates a new [`UiRect`] from the values specified in percentages.
 | |
|     ///
 | |
|     /// This is a shortcut for [`UiRect::new()`], applying [`Val::Percent`] to all arguments.
 | |
|     ///
 | |
|     /// # Example
 | |
|     ///
 | |
|     /// ```
 | |
|     /// # use bevy_ui::{UiRect, Val};
 | |
|     /// #
 | |
|     /// let ui_rect = UiRect::percent(5., 10., 2., 1.);
 | |
|     /// assert_eq!(ui_rect.left, Val::Percent(5.));
 | |
|     /// assert_eq!(ui_rect.right, Val::Percent(10.));
 | |
|     /// assert_eq!(ui_rect.top, Val::Percent(2.));
 | |
|     /// assert_eq!(ui_rect.bottom, Val::Percent(1.));
 | |
|     /// ```
 | |
|     pub const fn percent(left: f32, right: f32, top: f32, bottom: f32) -> Self {
 | |
|         UiRect {
 | |
|             left: Val::Percent(left),
 | |
|             right: Val::Percent(right),
 | |
|             top: Val::Percent(top),
 | |
|             bottom: Val::Percent(bottom),
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /// Creates a new [`UiRect`] where `left` and `right` take the given value,
 | |
|     /// and `top` and `bottom` set to zero `Val::ZERO`.
 | |
|     ///
 | |
|     /// # Example
 | |
|     ///
 | |
|     /// ```
 | |
|     /// # use bevy_ui::{UiRect, Val};
 | |
|     /// #
 | |
|     /// let ui_rect = UiRect::horizontal(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::ZERO);
 | |
|     /// assert_eq!(ui_rect.bottom, Val::ZERO);
 | |
|     /// ```
 | |
|     pub fn horizontal(value: Val) -> Self {
 | |
|         UiRect {
 | |
|             left: value,
 | |
|             right: value,
 | |
|             ..Default::default()
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /// Creates a new [`UiRect`] where `top` and `bottom` take the given value,
 | |
|     /// and `left` and `right` are set to `Val::ZERO`.
 | |
|     ///
 | |
|     /// # Example
 | |
|     ///
 | |
|     /// ```
 | |
|     /// # use bevy_ui::{UiRect, Val};
 | |
|     /// #
 | |
|     /// let ui_rect = UiRect::vertical(Val::Px(10.0));
 | |
|     ///
 | |
|     /// assert_eq!(ui_rect.left, Val::ZERO);
 | |
|     /// assert_eq!(ui_rect.right, Val::ZERO);
 | |
|     /// assert_eq!(ui_rect.top, Val::Px(10.0));
 | |
|     /// assert_eq!(ui_rect.bottom, Val::Px(10.0));
 | |
|     /// ```
 | |
|     pub fn vertical(value: Val) -> Self {
 | |
|         UiRect {
 | |
|             top: value,
 | |
|             bottom: value,
 | |
|             ..Default::default()
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /// Creates a new [`UiRect`] where both `left` and `right` take the value of `horizontal`, and both `top` and `bottom` take the value of `vertical`.
 | |
|     ///
 | |
|     /// # Example
 | |
|     ///
 | |
|     /// ```
 | |
|     /// # use bevy_ui::{UiRect, Val};
 | |
|     /// #
 | |
|     /// let ui_rect = UiRect::axes(Val::Px(10.0), Val::Percent(15.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::Percent(15.0));
 | |
|     /// assert_eq!(ui_rect.bottom, Val::Percent(15.0));
 | |
|     /// ```
 | |
|     pub fn axes(horizontal: Val, vertical: Val) -> Self {
 | |
|         UiRect {
 | |
|             left: horizontal,
 | |
|             right: horizontal,
 | |
|             top: vertical,
 | |
|             bottom: vertical,
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /// Creates a new [`UiRect`] where `left` takes the given value, and
 | |
|     /// the other fields are set to `Val::ZERO`.
 | |
|     ///
 | |
|     /// # Example
 | |
|     ///
 | |
|     /// ```
 | |
|     /// # use bevy_ui::{UiRect, Val};
 | |
|     /// #
 | |
|     /// let ui_rect = UiRect::left(Val::Px(10.0));
 | |
|     ///
 | |
|     /// assert_eq!(ui_rect.left, Val::Px(10.0));
 | |
|     /// assert_eq!(ui_rect.right, Val::ZERO);
 | |
|     /// assert_eq!(ui_rect.top, Val::ZERO);
 | |
|     /// assert_eq!(ui_rect.bottom, Val::ZERO);
 | |
|     /// ```
 | |
|     pub fn left(value: Val) -> Self {
 | |
|         UiRect {
 | |
|             left: value,
 | |
|             ..Default::default()
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /// Creates a new [`UiRect`] where `right` takes the given value,
 | |
|     /// and the other fields are set to `Val::ZERO`.
 | |
|     ///
 | |
|     /// # Example
 | |
|     ///
 | |
|     /// ```
 | |
|     /// # use bevy_ui::{UiRect, Val};
 | |
|     /// #
 | |
|     /// let ui_rect = UiRect::right(Val::Px(10.0));
 | |
|     ///
 | |
|     /// assert_eq!(ui_rect.left, Val::ZERO);
 | |
|     /// assert_eq!(ui_rect.right, Val::Px(10.0));
 | |
|     /// assert_eq!(ui_rect.top, Val::ZERO);
 | |
|     /// assert_eq!(ui_rect.bottom, Val::ZERO);
 | |
|     /// ```
 | |
|     pub fn right(value: Val) -> Self {
 | |
|         UiRect {
 | |
|             right: value,
 | |
|             ..Default::default()
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /// Creates a new [`UiRect`] where `top` takes the given value,
 | |
|     /// and the other fields are set to `Val::ZERO`.
 | |
|     ///
 | |
|     /// # Example
 | |
|     ///
 | |
|     /// ```
 | |
|     /// # use bevy_ui::{UiRect, Val};
 | |
|     /// #
 | |
|     /// let ui_rect = UiRect::top(Val::Px(10.0));
 | |
|     ///
 | |
|     /// assert_eq!(ui_rect.left, Val::ZERO);
 | |
|     /// assert_eq!(ui_rect.right, Val::ZERO);
 | |
|     /// assert_eq!(ui_rect.top, Val::Px(10.0));
 | |
|     /// assert_eq!(ui_rect.bottom, Val::ZERO);
 | |
|     /// ```
 | |
|     pub fn top(value: Val) -> Self {
 | |
|         UiRect {
 | |
|             top: value,
 | |
|             ..Default::default()
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /// Creates a new [`UiRect`] where `bottom` takes the given value,
 | |
|     /// and the other fields are set to `Val::ZERO`.
 | |
|     ///
 | |
|     /// # Example
 | |
|     ///
 | |
|     /// ```
 | |
|     /// # use bevy_ui::{UiRect, Val};
 | |
|     /// #
 | |
|     /// let ui_rect = UiRect::bottom(Val::Px(10.0));
 | |
|     ///
 | |
|     /// assert_eq!(ui_rect.left, Val::ZERO);
 | |
|     /// assert_eq!(ui_rect.right, Val::ZERO);
 | |
|     /// assert_eq!(ui_rect.top, Val::ZERO);
 | |
|     /// assert_eq!(ui_rect.bottom, Val::Px(10.0));
 | |
|     /// ```
 | |
|     pub fn bottom(value: Val) -> Self {
 | |
|         UiRect {
 | |
|             bottom: value,
 | |
|             ..Default::default()
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl Default for UiRect {
 | |
|     fn default() -> Self {
 | |
|         Self::DEFAULT
 | |
|     }
 | |
| }
 | |
| 
 | |
| #[cfg(test)]
 | |
| mod tests {
 | |
|     use crate::geometry::*;
 | |
|     use bevy_math::vec2;
 | |
| 
 | |
|     #[test]
 | |
|     fn val_evaluate() {
 | |
|         let size = 250.;
 | |
|         let viewport_size = vec2(1000., 500.);
 | |
|         let result = Val::Percent(80.).resolve(size, viewport_size).unwrap();
 | |
| 
 | |
|         assert_eq!(result, size * 0.8);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn val_resolve_px() {
 | |
|         let size = 250.;
 | |
|         let viewport_size = vec2(1000., 500.);
 | |
|         let result = Val::Px(10.).resolve(size, viewport_size).unwrap();
 | |
| 
 | |
|         assert_eq!(result, 10.);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn val_resolve_viewport_coords() {
 | |
|         let size = 250.;
 | |
|         let viewport_size = vec2(500., 500.);
 | |
| 
 | |
|         for value in (-10..10).map(|value| value as f32) {
 | |
|             // for a square viewport there should be no difference between `Vw` and `Vh` and between `Vmin` and `Vmax`.
 | |
|             assert_eq!(
 | |
|                 Val::Vw(value).resolve(size, viewport_size),
 | |
|                 Val::Vh(value).resolve(size, viewport_size)
 | |
|             );
 | |
|             assert_eq!(
 | |
|                 Val::VMin(value).resolve(size, viewport_size),
 | |
|                 Val::VMax(value).resolve(size, viewport_size)
 | |
|             );
 | |
|             assert_eq!(
 | |
|                 Val::VMin(value).resolve(size, viewport_size),
 | |
|                 Val::Vw(value).resolve(size, viewport_size)
 | |
|             );
 | |
|         }
 | |
| 
 | |
|         let viewport_size = vec2(1000., 500.);
 | |
|         assert_eq!(Val::Vw(100.).resolve(size, viewport_size).unwrap(), 1000.);
 | |
|         assert_eq!(Val::Vh(100.).resolve(size, viewport_size).unwrap(), 500.);
 | |
|         assert_eq!(Val::Vw(60.).resolve(size, viewport_size).unwrap(), 600.);
 | |
|         assert_eq!(Val::Vh(40.).resolve(size, viewport_size).unwrap(), 200.);
 | |
|         assert_eq!(Val::VMin(50.).resolve(size, viewport_size).unwrap(), 250.);
 | |
|         assert_eq!(Val::VMax(75.).resolve(size, viewport_size).unwrap(), 750.);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn val_auto_is_non_resolveable() {
 | |
|         let size = 250.;
 | |
|         let viewport_size = vec2(1000., 500.);
 | |
|         let resolve_auto = Val::Auto.resolve(size, viewport_size);
 | |
| 
 | |
|         assert_eq!(resolve_auto, Err(ValArithmeticError::NonEvaluateable));
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn val_arithmetic_error_messages() {
 | |
|         assert_eq!(
 | |
|             format!("{}", ValArithmeticError::NonIdenticalVariants),
 | |
|             "the variants of the Vals don't match"
 | |
|         );
 | |
|         assert_eq!(
 | |
|             format!("{}", ValArithmeticError::NonEvaluateable),
 | |
|             "the given variant of Val is not evaluateable (non-numeric)"
 | |
|         );
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn default_val_equals_const_default_val() {
 | |
|         assert_eq!(Val::default(), Val::DEFAULT);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn uirect_default_equals_const_default() {
 | |
|         assert_eq!(
 | |
|             UiRect::default(),
 | |
|             UiRect {
 | |
|                 left: Val::ZERO,
 | |
|                 right: Val::ZERO,
 | |
|                 top: Val::ZERO,
 | |
|                 bottom: Val::ZERO
 | |
|             }
 | |
|         );
 | |
|         assert_eq!(UiRect::default(), UiRect::DEFAULT);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn test_uirect_axes() {
 | |
|         let x = Val::Px(1.);
 | |
|         let y = Val::Vw(4.);
 | |
|         let r = UiRect::axes(x, y);
 | |
|         let h = UiRect::horizontal(x);
 | |
|         let v = UiRect::vertical(y);
 | |
| 
 | |
|         assert_eq!(r.top, v.top);
 | |
|         assert_eq!(r.bottom, v.bottom);
 | |
|         assert_eq!(r.left, h.left);
 | |
|         assert_eq!(r.right, h.right);
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn uirect_px() {
 | |
|         let r = UiRect::px(3., 5., 20., 999.);
 | |
|         assert_eq!(r.left, Val::Px(3.));
 | |
|         assert_eq!(r.right, Val::Px(5.));
 | |
|         assert_eq!(r.top, Val::Px(20.));
 | |
|         assert_eq!(r.bottom, Val::Px(999.));
 | |
|     }
 | |
| 
 | |
|     #[test]
 | |
|     fn uirect_percent() {
 | |
|         let r = UiRect::percent(3., 5., 20., 99.);
 | |
|         assert_eq!(r.left, Val::Percent(3.));
 | |
|         assert_eq!(r.right, Val::Percent(5.));
 | |
|         assert_eq!(r.top, Val::Percent(20.));
 | |
|         assert_eq!(r.bottom, Val::Percent(99.));
 | |
|     }
 | |
| }
 |